LCOV - code coverage report
Current view: top level - clients/odbc/driver - SQLStatistics.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 92 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             :  * SQLStatistics()
      21             :  * CLI Compliance: ISO 92
      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             : 
      33             : #ifdef ODBCDEBUG
      34             : static char *
      35             : translateUnique(SQLUSMALLINT Unique)
      36             : {
      37           0 :         switch (Unique) {
      38             :         case SQL_INDEX_ALL:
      39             :                 return "SQL_INDEX_ALL";
      40           0 :         case SQL_INDEX_UNIQUE:
      41           0 :                 return "SQL_INDEX_UNIQUE";
      42           0 :         default:
      43           0 :                 return "unknown";
      44             :         }
      45             : }
      46             : 
      47             : static char *
      48             : translateReserved(SQLUSMALLINT Reserved)
      49             : {
      50           0 :         switch (Reserved) {
      51             :         case SQL_ENSURE:
      52             :                 return "SQL_ENSURE";
      53           0 :         case SQL_QUICK:
      54           0 :                 return "SQL_QUICK";
      55           0 :         default:
      56           0 :                 return "unknown";
      57             :         }
      58             : }
      59             : #endif
      60             : 
      61             : static SQLRETURN
      62           0 : MNDBStatistics(ODBCStmt *stmt,
      63             :                const SQLCHAR *CatalogName,
      64             :                SQLSMALLINT NameLength1,
      65             :                const SQLCHAR *SchemaName,
      66             :                SQLSMALLINT NameLength2,
      67             :                const SQLCHAR *TableName,
      68             :                SQLSMALLINT NameLength3,
      69             :                SQLUSMALLINT Unique,
      70             :                SQLUSMALLINT Reserved)
      71             : {
      72             :         RETCODE rc;
      73             : 
      74             :         /* buffer for the constructed query to do meta data retrieval */
      75             :         char *query = NULL;
      76             :         size_t querylen;
      77             :         size_t pos = 0;
      78             :         char *sch = NULL, *tab = NULL;
      79             : 
      80           0 :         fixODBCstring(TableName, NameLength3, SQLSMALLINT,
      81             :                       addStmtError, stmt, return SQL_ERROR);
      82           0 :         fixODBCstring(SchemaName, NameLength2, SQLSMALLINT,
      83             :                       addStmtError, stmt, return SQL_ERROR);
      84           0 :         fixODBCstring(CatalogName, NameLength1, SQLSMALLINT,
      85             :                       addStmtError, stmt, return SQL_ERROR);
      86             : 
      87             : #ifdef ODBCDEBUG
      88           0 :         ODBCLOG("\"%.*s\" \"%.*s\" \"%.*s\" %s %s\n",
      89             :                 (int) NameLength1, CatalogName ? (char *) CatalogName : "",
      90             :                 (int) NameLength2, SchemaName ? (char *) SchemaName : "",
      91             :                 (int) NameLength3, TableName ? (char *) TableName : "",
      92             :                 translateUnique(Unique), translateReserved(Reserved));
      93             : #endif
      94             : 
      95             :         /* check for valid Unique argument */
      96           0 :         switch (Unique) {
      97             :         case SQL_INDEX_ALL:
      98             :         case SQL_INDEX_UNIQUE:
      99             :                 break;
     100           0 :         default:
     101             :                 /* Uniqueness option type out of range */
     102           0 :                 addStmtError(stmt, "HY100", NULL, 0);
     103           0 :                 return SQL_ERROR;
     104             :         }
     105             : 
     106             :         /* check for valid Reserved argument */
     107           0 :         switch (Reserved) {
     108             :         case SQL_ENSURE:
     109             :         case SQL_QUICK:
     110             :                 break;
     111           0 :         default:
     112             :                 /* Accuracy option type out of range */
     113           0 :                 addStmtError(stmt, "HY101", NULL, 0);
     114           0 :                 return SQL_ERROR;
     115             :         }
     116             : 
     117             : 
     118             :         /* check if a valid (non null, not empty) table name is supplied */
     119           0 :         if (TableName == NULL) {
     120             :                 /* Invalid use of null pointer */
     121           0 :                 addStmtError(stmt, "HY009", NULL, 0);
     122           0 :                 return SQL_ERROR;
     123             :         }
     124           0 :         if (NameLength3 == 0) {
     125             :                 /* Invalid string or buffer length */
     126           0 :                 addStmtError(stmt, "HY090", NULL, 0);
     127           0 :                 return SQL_ERROR;
     128             :         }
     129             : 
     130           0 :         if (stmt->Dbc->sql_attr_metadata_id == SQL_FALSE) {
     131           0 :                 if (NameLength2 > 0) {
     132           0 :                         sch = ODBCParseOA("s", "name",
     133             :                                           (const char *) SchemaName,
     134             :                                           (size_t) NameLength2);
     135           0 :                         if (sch == NULL)
     136           0 :                                 goto nomem;
     137             :                 }
     138           0 :                 if (NameLength3 > 0) {
     139           0 :                         tab = ODBCParseOA("t", "name",
     140             :                                           (const char *) TableName,
     141             :                                           (size_t) NameLength3);
     142           0 :                         if (tab == NULL)
     143           0 :                                 goto nomem;
     144             :                 }
     145             :         } else {
     146           0 :                 if (NameLength2 > 0) {
     147           0 :                         sch = ODBCParseID("s", "name",
     148             :                                           (const char *) SchemaName,
     149             :                                           (size_t) NameLength2);
     150           0 :                         if (sch == NULL)
     151           0 :                                 goto nomem;
     152             :                 }
     153           0 :                 if (NameLength3 > 0) {
     154           0 :                         tab = ODBCParseID("t", "name",
     155             :                                           (const char *) TableName,
     156             :                                           (size_t) NameLength3);
     157           0 :                         if (tab == NULL)
     158           0 :                                 goto nomem;
     159             :                 }
     160             :         }
     161             : 
     162             :         /* construct the query now */
     163           0 :         querylen = 1200 + strlen(stmt->Dbc->dbname) +
     164           0 :                 (sch ? strlen(sch) : 0) + (tab ? strlen(tab) : 0);
     165           0 :         query = malloc(querylen);
     166           0 :         if (query == NULL)
     167           0 :                 goto nomem;
     168             : 
     169             :         /* SQLStatistics returns a table with the following columns:
     170             :            VARCHAR      table_cat
     171             :            VARCHAR      table_schem
     172             :            VARCHAR      table_name NOT NULL
     173             :            SMALLINT     non_unique
     174             :            VARCHAR      index_qualifier
     175             :            VARCHAR      index_name
     176             :            SMALLINT     type NOT NULL
     177             :            SMALLINT     ordinal_position
     178             :            VARCHAR      column_name
     179             :            CHAR(1)      asc_or_desc
     180             :            INTEGER      cardinality
     181             :            INTEGER      pages
     182             :            VARCHAR      filter_condition
     183             :          */
     184             :         /* TODO: finish the SQL query */
     185           0 :         pos += snprintf(query + pos, querylen - pos,
     186             :                 "select '%s' as table_cat, "
     187             :                        "s.name as table_schem, "
     188             :                        "t.name as table_name, "
     189             :                        "case when k.name is null then cast(1 as smallint) "
     190             :                             "else cast(0 as smallint) end as non_unique, "
     191             :                        "cast(null as varchar(1)) as index_qualifier, "
     192             :                        "i.name as index_name, "
     193             :                        "case i.type when 0 then cast(%d as smallint) "
     194             :                                    "else cast(%d as smallint) end as type, "
     195             :                        "cast(kc.nr as smallint) as ordinal_position, "
     196             :                        "c.name as column_name, "
     197             :                        "cast(null as char(1)) as asc_or_desc, "
     198             :                        "cast(null as integer) as cardinality, "
     199             :                        "cast(null as integer) as pages, "
     200             :                        "cast(null as varchar(1)) as filter_condition "
     201             :                 "from sys.idxs i, "
     202             :                      "sys.schemas s, "
     203             :                      "sys.tables t, "
     204             :                      "sys.columns c, "
     205             :                      "sys.objects kc, "
     206             :                      "sys.keys k "
     207             :                 "where i.table_id = t.id and "
     208             :                       "t.schema_id = s.id and "
     209             :                       "i.id = kc.id and "
     210             :                       "t.id = c.table_id and "
     211             :                       "kc.name = c.name and "
     212             :                       "(k.type is null or k.type = 1)",
     213             :                 stmt->Dbc->dbname,
     214             :                 SQL_INDEX_HASHED, SQL_INDEX_OTHER);
     215           0 :         assert(pos < 1000);
     216             : 
     217             :         /* Construct the selection condition query part */
     218           0 :         if (NameLength1 > 0 && CatalogName != NULL) {
     219             :                 /* filtering requested on catalog name */
     220           0 :                 if (strcmp((char *) CatalogName, stmt->Dbc->dbname) != 0) {
     221             :                         /* catalog name does not match the database name, so return no rows */
     222           0 :                         pos += snprintf(query + pos, querylen - pos, " and 1=2");
     223             :                 }
     224             :         }
     225           0 :         if (sch) {
     226             :                 /* filtering requested on schema name */
     227           0 :                 pos += snprintf(query + pos, querylen - pos, " and %s", sch);
     228           0 :                 free(sch);
     229             :         }
     230           0 :         if (tab) {
     231             :                 /* filtering requested on table name */
     232           0 :                 pos += snprintf(query + pos, querylen - pos, " and %s", tab);
     233           0 :                 free(tab);
     234             :         }
     235             : 
     236             :         /* add the ordering */
     237           0 :         pos += strcpy_len(query + pos, " order by non_unique, type, index_qualifier, index_name, ordinal_position", querylen - pos);
     238             : 
     239             :         /* query the MonetDB data dictionary tables */
     240           0 :         rc = MNDBExecDirect(stmt, (SQLCHAR *) query, (SQLINTEGER) pos);
     241             : 
     242           0 :         free(query);
     243             : 
     244           0 :         return rc;
     245             : 
     246           0 :   nomem:
     247             :         /* note that query must be NULL when we get here */
     248           0 :         if (sch)
     249           0 :                 free(sch);
     250           0 :         if (tab)
     251           0 :                 free(tab);
     252             :         /* Memory allocation error */
     253           0 :         addStmtError(stmt, "HY001", NULL, 0);
     254           0 :         return SQL_ERROR;
     255             : }
     256             : 
     257             : SQLRETURN SQL_API
     258             : SQLStatistics(SQLHSTMT StatementHandle,
     259             :               SQLCHAR *CatalogName,
     260             :               SQLSMALLINT NameLength1,
     261             :               SQLCHAR *SchemaName,
     262             :               SQLSMALLINT NameLength2,
     263             :               SQLCHAR *TableName,
     264             :               SQLSMALLINT NameLength3,
     265             :               SQLUSMALLINT Unique,
     266             :               SQLUSMALLINT Reserved)
     267             : {
     268             :         ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
     269             : 
     270             : #ifdef ODBCDEBUG
     271           0 :         ODBCLOG("SQLStatistics %p ", StatementHandle);
     272             : #endif
     273             : 
     274           0 :         if (!isValidStmt(stmt))
     275             :                  return SQL_INVALID_HANDLE;
     276             : 
     277           0 :         clearStmtErrors(stmt);
     278             : 
     279           0 :         return MNDBStatistics(stmt,
     280             :                               CatalogName, NameLength1,
     281             :                               SchemaName, NameLength2,
     282             :                               TableName, NameLength3,
     283             :                               Unique,
     284             :                               Reserved);
     285             : }
     286             : 
     287             : SQLRETURN SQL_API
     288             : SQLStatisticsA(SQLHSTMT StatementHandle,
     289             :                SQLCHAR *CatalogName,
     290             :                SQLSMALLINT NameLength1,
     291             :                SQLCHAR *SchemaName,
     292             :                SQLSMALLINT NameLength2,
     293             :                SQLCHAR *TableName,
     294             :                SQLSMALLINT NameLength3,
     295             :                SQLUSMALLINT Unique,
     296             :                SQLUSMALLINT Reserved)
     297             : {
     298           0 :         return SQLStatistics(StatementHandle,
     299             :                              CatalogName, NameLength1,
     300             :                              SchemaName, NameLength2,
     301             :                              TableName, NameLength3,
     302             :                              Unique,
     303             :                              Reserved);
     304             : }
     305             : 
     306             : SQLRETURN SQL_API
     307             : SQLStatisticsW(SQLHSTMT StatementHandle,
     308             :                SQLWCHAR *CatalogName,
     309             :                SQLSMALLINT NameLength1,
     310             :                SQLWCHAR *SchemaName,
     311             :                SQLSMALLINT NameLength2,
     312             :                SQLWCHAR *TableName,
     313             :                SQLSMALLINT NameLength3,
     314             :                SQLUSMALLINT Unique,
     315             :                SQLUSMALLINT Reserved)
     316             : {
     317             :         ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
     318             :         SQLRETURN rc = SQL_ERROR;
     319             :         SQLCHAR *catalog = NULL, *schema = NULL, *table = NULL;
     320             : 
     321             : #ifdef ODBCDEBUG
     322           0 :         ODBCLOG("SQLStatisticsW %p ", StatementHandle);
     323             : #endif
     324             : 
     325           0 :         if (!isValidStmt(stmt))
     326             :                  return SQL_INVALID_HANDLE;
     327             : 
     328           0 :         clearStmtErrors(stmt);
     329             : 
     330           0 :         fixWcharIn(CatalogName, NameLength1, SQLCHAR, catalog,
     331             :                    addStmtError, stmt, goto bailout);
     332           0 :         fixWcharIn(SchemaName, NameLength2, SQLCHAR, schema,
     333             :                    addStmtError, stmt, goto bailout);
     334           0 :         fixWcharIn(TableName, NameLength3, SQLCHAR, table,
     335             :                    addStmtError, stmt, goto bailout);
     336             : 
     337           0 :         rc = MNDBStatistics(stmt,
     338             :                             catalog, SQL_NTS,
     339             :                             schema, SQL_NTS,
     340             :                             table, SQL_NTS,
     341             :                             Unique,
     342             :                             Reserved);
     343             : 
     344           0 :       bailout:
     345           0 :         if (catalog)
     346           0 :                 free(catalog);
     347           0 :         if (schema)
     348           0 :                 free(schema);
     349           0 :         if (table)
     350           0 :                 free(table);
     351             : 
     352             :         return rc;
     353             : }

Generated by: LCOV version 1.14