LCOV - code coverage report
Current view: top level - clients/odbc/driver - SQLTables.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 115 0.0 %
Date: 2021-10-13 02:24:04 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : /*
      10             :  * This code was created by Peter Harvey (mostly during Christmas 98/99).
      11             :  * This code is LGPL. Please ensure that this message remains in future
      12             :  * distributions and uses of this code (thats about all I get out of it).
      13             :  * - Peter Harvey pharvey@codebydesign.com
      14             :  *
      15             :  * This file has been modified for the MonetDB project.  See the file
      16             :  * Copyright in this directory for more information.
      17             :  */
      18             : 
      19             : /**********************************************************************
      20             :  * SQLTables()
      21             :  * CLI Compliance: X/Open
      22             :  *
      23             :  * Author: Martin van Dinther, Sjoerd Mullender
      24             :  * Date  : 30 aug 2002
      25             :  *
      26             :  **********************************************************************/
      27             : 
      28             : #include "ODBCGlobal.h"
      29             : #include "ODBCStmt.h"
      30             : #include "ODBCUtil.h"
      31             : 
      32             : static SQLRETURN
      33           0 : MNDBTables(ODBCStmt *stmt,
      34             :            const SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
      35             :            const SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
      36             :            const SQLCHAR *TableName, SQLSMALLINT NameLength3,
      37             :            const SQLCHAR *TableType, SQLSMALLINT NameLength4)
      38             : {
      39             :         RETCODE rc;
      40             :         char *sch = NULL, *tab = NULL;
      41             : 
      42             :         /* buffer for the constructed query to do meta data retrieval */
      43             :         char *query = NULL;
      44             : 
      45             :         /* convert input string parameters to normal null terminated C
      46             :          * strings */
      47           0 :         fixODBCstring(CatalogName, NameLength1, SQLSMALLINT,
      48             :                       addStmtError, stmt, return SQL_ERROR);
      49           0 :         fixODBCstring(SchemaName, NameLength2, SQLSMALLINT,
      50             :                       addStmtError, stmt, return SQL_ERROR);
      51           0 :         fixODBCstring(TableName, NameLength3, SQLSMALLINT,
      52             :                       addStmtError, stmt, return SQL_ERROR);
      53           0 :         fixODBCstring(TableType, NameLength4, SQLSMALLINT,
      54             :                       addStmtError, stmt, return SQL_ERROR);
      55             : 
      56             : #ifdef ODBCDEBUG
      57           0 :         ODBCLOG("\"%.*s\" \"%.*s\" \"%.*s\" \"%.*s\"\n",
      58             :                 (int) NameLength1, CatalogName ? (char *) CatalogName : "",
      59             :                 (int) NameLength2, SchemaName ? (char *) SchemaName : "",
      60             :                 (int) NameLength3, TableName ? (char *) TableName : "",
      61             :                 (int) NameLength4, TableType ? (char *) TableType : "");
      62             : #endif
      63             : 
      64             :         /* SQLTables returns a table with the following columns:
      65             :            VARCHAR      table_cat
      66             :            VARCHAR      table_schem
      67             :            VARCHAR      table_name
      68             :            VARCHAR      table_type
      69             :            VARCHAR      remarks
      70             :          */
      71             : 
      72             :         /* Check first on the special cases */
      73           0 :         if (NameLength2 == 0 &&
      74           0 :             NameLength3 == 0 &&
      75           0 :             CatalogName &&
      76           0 :             strcmp((char *) CatalogName, SQL_ALL_CATALOGS) == 0) {
      77             :                 /* Special case query to fetch all Catalog names. */
      78           0 :                 query = strdup("select e.value as table_cat, "
      79             :                                       "cast(null as varchar(1)) as table_schem, "
      80             :                                       "cast(null as varchar(1)) as table_name, "
      81             :                                       "cast(null as varchar(1)) as table_type, "
      82             :                                       "cast(null as varchar(1)) as remarks "
      83             :                                "from sys.env() e "
      84             :                                "where e.name = 'gdk_dbname'");
      85           0 :                 if (query == NULL)
      86           0 :                         goto nomem;
      87           0 :         } else if (NameLength1 == 0 &&
      88           0 :                    NameLength3 == 0 &&
      89           0 :                    SchemaName &&
      90           0 :                    strcmp((char *) SchemaName, SQL_ALL_SCHEMAS) == 0) {
      91             :                 /* Special case query to fetch all Schema names. */
      92           0 :                 query = strdup("select cast(null as varchar(1)) as table_cat, "
      93             :                                       "name as table_schem, "
      94             :                                       "cast(null as varchar(1)) as table_name, "
      95             :                                       "cast(null as varchar(1)) as table_type, "
      96             :                                /* ODBC says remarks column contains
      97             :                                 * NULL even though MonetDB supports
      98             :                                 * schema remarks */
      99             :                                       "cast(null as varchar(1)) as remarks "
     100             :                                "from sys.schemas order by table_schem");
     101           0 :                 if (query == NULL)
     102           0 :                         goto nomem;
     103           0 :         } else if (NameLength1 == 0 &&
     104           0 :                    NameLength2 == 0 &&
     105           0 :                    NameLength3 == 0 &&
     106           0 :                    TableType &&
     107           0 :                    strcmp((char *) TableType, SQL_ALL_TABLE_TYPES) == 0) {
     108             :                 /* Special case query to fetch all Table type names. */
     109           0 :                 query = strdup("select cast(null as varchar(1)) as table_cat, "
     110             :                                       "cast(null as varchar(1)) as table_schem, "
     111             :                                       "cast(null as varchar(1)) as table_name, "
     112             :                                       "table_type_name as table_type, "
     113             :                                       "cast(null as varchar(1)) as remarks "
     114             :                                "from sys.table_types order by table_type");
     115           0 :                 if (query == NULL)
     116           0 :                         goto nomem;
     117             :         } else {
     118             :                 /* no special case argument values */
     119             :                 size_t querylen;
     120             :                 size_t pos = 0;
     121             : 
     122           0 :                 if (stmt->Dbc->sql_attr_metadata_id == SQL_FALSE) {
     123           0 :                         if (NameLength2 > 0) {
     124           0 :                                 sch = ODBCParsePV("s", "name",
     125             :                                                   (const char *) SchemaName,
     126             :                                                   (size_t) NameLength2);
     127           0 :                                 if (sch == NULL)
     128           0 :                                         goto nomem;
     129             :                         }
     130           0 :                         if (NameLength3 > 0) {
     131           0 :                                 tab = ODBCParsePV("t", "name",
     132             :                                                   (const char *) TableName,
     133             :                                                   (size_t) NameLength3);
     134           0 :                                 if (tab == NULL)
     135           0 :                                         goto nomem;
     136             :                         }
     137             :                 } else {
     138           0 :                         if (NameLength2 > 0) {
     139           0 :                                 sch = ODBCParseID("s", "name",
     140             :                                                   (const char *) SchemaName,
     141             :                                                   (size_t) NameLength2);
     142           0 :                                 if (sch == NULL)
     143           0 :                                         goto nomem;
     144             :                         }
     145           0 :                         if (NameLength3 > 0) {
     146           0 :                                 tab = ODBCParseID("t", "name",
     147             :                                                   (const char *) TableName,
     148             :                                                   (size_t) NameLength3);
     149           0 :                                 if (tab == NULL)
     150           0 :                                         goto nomem;
     151             :                         }
     152             :                 }
     153             : 
     154             :                 /* construct the query now */
     155           0 :                 querylen = 2000 + strlen(stmt->Dbc->dbname) +
     156           0 :                         (sch ? strlen(sch) : 0) + (tab ? strlen(tab) : 0) +
     157           0 :                         ((NameLength4 + 1) / 5) * 67;
     158           0 :                 query = malloc(querylen);
     159           0 :                 if (query == NULL)
     160           0 :                         goto nomem;
     161             : 
     162           0 :                 pos += snprintf(query + pos, querylen - pos,
     163             :                        "select '%s' as table_cat, "
     164             :                               "s.name as table_schem, "
     165             :                               "t.name as table_name, "
     166             :                               "tt.table_type_name as table_type, "
     167             :                               "%s as remarks "
     168             :                        "from sys.schemas s, "
     169             :                             "sys.tables t%s, "
     170             :                             "sys.table_types tt "
     171             :                        "where s.id = t.schema_id and "
     172             :                              "t.type = tt.table_type_id",
     173             :                         stmt->Dbc->dbname,
     174             :                         stmt->Dbc->has_comment ? "c.remark" : "cast(null as varchar(1))",
     175           0 :                         stmt->Dbc->has_comment ? " left outer join sys.comments c on c.id = t.id" : "");
     176           0 :                 assert(pos < 1900);
     177             : 
     178             :                 /* dependent on the input parameter values we must add a
     179             :                    variable selection condition dynamically */
     180             : 
     181             :                 /* Construct the selection condition query part */
     182           0 :                 if (NameLength1 > 0 && CatalogName != NULL) {
     183             :                         /* filtering requested on catalog name */
     184           0 :                         if (strcmp((char *) CatalogName, stmt->Dbc->dbname) != 0) {
     185             :                                 /* catalog name does not match the database name, so return no rows */
     186           0 :                                 pos += snprintf(query + pos, querylen - pos, " and 1=2");
     187             :                         }
     188             :                 }
     189           0 :                 if (sch) {
     190             :                         /* filtering requested on schema name */
     191           0 :                         pos += snprintf(query + pos, querylen - pos, " and %s", sch);
     192           0 :                         free(sch);
     193             :                 }
     194           0 :                 if (tab) {
     195             :                         /* filtering requested on table name */
     196           0 :                         pos += snprintf(query + pos, querylen - pos, " and %s", tab);
     197           0 :                         free(tab);
     198             :                 }
     199             : 
     200           0 :                 if (NameLength4 > 0) {
     201             :                         /* filtering requested on table type */
     202             :                         char buf[32];   /* the longest string is "GLOBAL TEMPORARY TABLE" */
     203             :                         int i;
     204             :                         size_t j;
     205             : 
     206           0 :                         pos += strcpy_len(query + pos, " and tt.table_type_name in (", querylen - pos);
     207           0 :                         for (j = 0, i = 0; i < NameLength4 + 1; i++) {
     208           0 :                                 if (i == NameLength4 || TableType[i] == ',') {
     209           0 :                                         if (j > 0 && buf[j - 1] == ' ')
     210             :                                                 j--;
     211           0 :                                         if (j >= sizeof(buf) || j == 0) {
     212             :                                                 j = 0;
     213           0 :                                                 continue;
     214             :                                         }
     215           0 :                                         buf[j] = 0;
     216           0 :                                         pos += snprintf(query + pos, querylen - pos, "'%s',", buf);
     217           0 :                                         j = 0;
     218           0 :                                 } else if (j < sizeof(buf) &&
     219           0 :                                            TableType[i] != '\'' &&
     220           0 :                                            (TableType[i] != ' ' ||
     221           0 :                                             (j > 0 && buf[j - 1] != ' ')))
     222           0 :                                         buf[j++] = TableType[i];
     223             :                         }
     224           0 :                         if (query[pos - 1] == ',') {
     225           0 :                                 query[pos - 1] = ')';
     226             :                         } else {
     227             :                                 /* no extra tests added, so remove
     228             :                                  * clause completely */
     229           0 :                                 pos -= 28;
     230             :                         }
     231           0 :                         query[pos] = 0;
     232             :                 }
     233             : 
     234             :                 /* add the ordering */
     235           0 :                 pos += strcpy_len(query + pos, " order by table_type, table_schem, table_name", querylen - pos);
     236             :         }
     237             : 
     238             :         /* query the MonetDB data dictionary tables */
     239           0 :         rc = MNDBExecDirect(stmt, (SQLCHAR *) query, SQL_NTS);
     240             : 
     241           0 :         free(query);
     242             : 
     243           0 :         return rc;
     244             : 
     245           0 :   nomem:
     246           0 :         if (sch)
     247           0 :                 free(sch);
     248           0 :         if (tab)
     249           0 :                 free(tab);
     250             :         /* Memory allocation error */
     251           0 :         addStmtError(stmt, "HY001", NULL, 0);
     252           0 :         return SQL_ERROR;
     253             : }
     254             : 
     255             : SQLRETURN SQL_API
     256             : SQLTables(SQLHSTMT StatementHandle,
     257             :           SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
     258             :           SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
     259             :           SQLCHAR *TableName, SQLSMALLINT NameLength3,
     260             :           SQLCHAR *TableType, SQLSMALLINT NameLength4)
     261             : {
     262             :         ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
     263             : 
     264             : #ifdef ODBCDEBUG
     265           0 :         ODBCLOG("SQLTables %p ", StatementHandle);
     266             : #endif
     267             : 
     268           0 :         if (!isValidStmt(stmt))
     269             :                  return SQL_INVALID_HANDLE;
     270             : 
     271           0 :         clearStmtErrors(stmt);
     272             : 
     273           0 :         return MNDBTables(stmt,
     274             :                           CatalogName, NameLength1,
     275             :                           SchemaName, NameLength2,
     276             :                           TableName, NameLength3,
     277             :                           TableType, NameLength4);
     278             : }
     279             : 
     280             : SQLRETURN SQL_API
     281             : SQLTablesA(SQLHSTMT StatementHandle,
     282             :            SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
     283             :            SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
     284             :            SQLCHAR *TableName, SQLSMALLINT NameLength3,
     285             :            SQLCHAR *TableType, SQLSMALLINT NameLength4)
     286             : {
     287           0 :         return SQLTables(StatementHandle,
     288             :                          CatalogName, NameLength1,
     289             :                          SchemaName, NameLength2,
     290             :                          TableName, NameLength3,
     291             :                          TableType, NameLength4);
     292             : }
     293             : 
     294             : SQLRETURN SQL_API
     295             : SQLTablesW(SQLHSTMT StatementHandle,
     296             :            SQLWCHAR *CatalogName, SQLSMALLINT NameLength1,
     297             :            SQLWCHAR *SchemaName, SQLSMALLINT NameLength2,
     298             :            SQLWCHAR *TableName, SQLSMALLINT NameLength3,
     299             :            SQLWCHAR *TableType, SQLSMALLINT NameLength4)
     300             : {
     301             :         ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
     302             :         SQLRETURN rc = SQL_ERROR;
     303             :         SQLCHAR *catalog = NULL, *schema = NULL, *table = NULL, *type = NULL;
     304             : 
     305             : #ifdef ODBCDEBUG
     306           0 :         ODBCLOG("SQLTablesW %p ", StatementHandle);
     307             : #endif
     308             : 
     309           0 :         if (!isValidStmt(stmt))
     310             :                  return SQL_INVALID_HANDLE;
     311             : 
     312           0 :         clearStmtErrors(stmt);
     313             : 
     314           0 :         fixWcharIn(CatalogName, NameLength1, SQLCHAR, catalog,
     315             :                    addStmtError, stmt, goto bailout);
     316           0 :         fixWcharIn(SchemaName, NameLength2, SQLCHAR, schema,
     317             :                    addStmtError, stmt, goto bailout);
     318           0 :         fixWcharIn(TableName, NameLength3, SQLCHAR, table,
     319             :                    addStmtError, stmt, goto bailout);
     320           0 :         fixWcharIn(TableType, NameLength4, SQLCHAR, type,
     321             :                    addStmtError, stmt, goto bailout);
     322             : 
     323           0 :         rc = MNDBTables(stmt,
     324             :                         catalog, SQL_NTS,
     325             :                         schema, SQL_NTS,
     326             :                         table, SQL_NTS,
     327             :                         type, SQL_NTS);
     328             : 
     329           0 :       bailout:
     330           0 :         if (catalog)
     331           0 :                 free(catalog);
     332           0 :         if (schema)
     333           0 :                 free(schema);
     334           0 :         if (table)
     335           0 :                 free(table);
     336           0 :         if (type)
     337           0 :                 free(type);
     338             : 
     339             :         return rc;
     340             : }

Generated by: LCOV version 1.14