Changeset: 28dc6e7ba84e for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/28dc6e7ba84e Modified Files: clients/odbc/ChangeLog clients/odbc/driver/SQLForeignKeys.c clients/odbc/samples/metadata.c Branch: default Log Message:
For SQLForeignKeys() corrected the output of columns UPDATE_RULE and DELETE_RULE. These columns used to always return 3 (= SQL_NO_ACTION) but now they will report the action codes as specified in the FOREIGN KEY CONSTRAINT. Added multiple simple and complex pkey and fkey tests to odbc metadata test program. diffs (292 lines): diff --git a/clients/odbc/ChangeLog b/clients/odbc/ChangeLog --- a/clients/odbc/ChangeLog +++ b/clients/odbc/ChangeLog @@ -1,6 +1,12 @@ # ChangeLog file for odbc # This file is updated with Maddlog +* Thu Jun 9 2022 Martin van Dinther <[email protected]> +- For SQLForeignKeys() corrected the output of columns UPDATE_RULE and + DELETE_RULE. These columns used to always return 3 (= SQL_NO_ACTION) + but now they will report the action codes as specified in the FOREIGN KEY + CONSTRAINT construction. + * Thu Jun 2 2022 Martin van Dinther <[email protected]> - Fixed issue in function SQLProcedureColumns(). When the argument ColumnName was not empty it generated an invalid SQL query which failed with error: diff --git a/clients/odbc/driver/SQLForeignKeys.c b/clients/odbc/driver/SQLForeignKeys.c --- a/clients/odbc/driver/SQLForeignKeys.c +++ b/clients/odbc/driver/SQLForeignKeys.c @@ -139,9 +139,9 @@ MNDBForeignKeys(ODBCStmt *stmt, } } - /* first create a string buffer (1200 extra bytes is plenty: - we actually need just over 1000) */ - querylen = 1200 + (2 * strlen(stmt->Dbc->dbname)) + + /* first create a string buffer (1300 extra bytes is plenty: + we actually need just over 1100) */ + querylen = 1300 + (2 * strlen(stmt->Dbc->dbname)) + (psch ? strlen(psch) : 0) + (ptab ? strlen(ptab) : 0) + (fsch ? strlen(fsch) : 0) + (ftab ? strlen(ftab) : 0); query = malloc(querylen); @@ -167,35 +167,44 @@ MNDBForeignKeys(ODBCStmt *stmt, pos += snprintf(query + pos, querylen - pos, "select '%s' as \"PKTABLE_CAT\", " - "pks.name as \"PKTABLE_SCHEM\", " - "pkt.name as \"PKTABLE_NAME\", " - "pkkc.name as \"PKCOLUMN_NAME\", " - "'%s' as \"FKTABLE_CAT\", " - "fks.name as \"FKTABLE_SCHEM\", " - "fkt.name as \"FKTABLE_NAME\", " - "fkkc.name as \"FKCOLUMN_NAME\", " - "cast(fkkc.nr + 1 as smallint) as \"KEY_SEQ\", " - "cast(%d as smallint) as \"UPDATE_RULE\", " - "cast(%d as smallint) as \"DELETE_RULE\", " - "fkk.name as \"FK_NAME\", " - "pkk.name as \"PK_NAME\", " - "cast(%d as smallint) as \"DEFERRABILITY\" " - "from sys.schemas fks, sys.tables fkt, " - "sys.objects fkkc, sys.keys as fkk, " - "sys.schemas pks, sys.tables pkt, " - "sys.objects pkkc, sys.keys as pkk " - "where fkt.id = fkk.table_id and " - "pkt.id = pkk.table_id and " + "pks.name as \"PKTABLE_SCHEM\", " + "pkt.name as \"PKTABLE_NAME\", " + "pkkc.name as \"PKCOLUMN_NAME\", " + "'%s' as \"FKTABLE_CAT\", " + "fks.name as \"FKTABLE_SCHEM\", " + "fkt.name as \"FKTABLE_NAME\", " + "fkkc.name as \"FKCOLUMN_NAME\", " + "cast(fkkc.nr + 1 as smallint) as \"KEY_SEQ\", " + /* logic for "action" value interpretation pulled from clients/mapiclient/dump.c dump_foreign_keys() */ + /* for "action" code values meaning see table: sys.fkey_actions */ + "cast(CASE ((fkk.\"action\" >> 8) & 255)" + " WHEN 0 THEN %d WHEN 1 THEN %d WHEN 2 THEN %d" + " WHEN 3 THEN %d WHEN 4 THEN %d ELSE %d END" + " AS smallint) as \"UPDATE_RULE\", " + "cast(CASE (fkk.\"action\" & 255)" + " WHEN 0 THEN %d WHEN 1 THEN %d WHEN 2 THEN %d" + " WHEN 3 THEN %d WHEN 4 THEN %d ELSE %d END" + " AS smallint) as \"DELETE_RULE\", " + "fkk.name as \"FK_NAME\", " + "pkk.name as \"PK_NAME\", " + "cast(%d as smallint) as \"DEFERRABILITY\" " + "from sys.keys as fkk, sys.objects fkkc, sys.tables fkt, sys.schemas fks, " + "sys.keys as pkk, sys.objects pkkc, sys.tables pkt, sys.schemas pks " + "where fkk.rkey > 0 and " /* exclude invalid rkey references, such as -1 first */ + "fkk.rkey = pkk.id and " "fkk.id = fkkc.id and " "pkk.id = pkkc.id and " + "fkkc.nr = pkkc.nr and " + "fkt.id = fkk.table_id and " + "pkt.id = pkk.table_id and " "fks.id = fkt.schema_id and " - "pks.id = pkt.schema_id and " - "fkk.rkey = pkk.id and " - "fkkc.nr = pkkc.nr", + "pks.id = pkt.schema_id", stmt->Dbc->dbname, stmt->Dbc->dbname, - SQL_NO_ACTION, SQL_NO_ACTION, SQL_NOT_DEFERRABLE); - assert(pos < 1100); + SQL_NO_ACTION, SQL_CASCADE, SQL_RESTRICT, SQL_SET_NULL, SQL_SET_DEFAULT, SQL_NO_ACTION, + SQL_NO_ACTION, SQL_CASCADE, SQL_RESTRICT, SQL_SET_NULL, SQL_SET_DEFAULT, SQL_NO_ACTION, + SQL_NOT_DEFERRABLE); + assert(pos < 1200); /* Construct the selection condition query part */ if (NameLength1 > 0 && PKCatalogName != NULL) { @@ -233,16 +242,19 @@ MNDBForeignKeys(ODBCStmt *stmt, free(ftab); } -/* TODO finish the FROM and WHERE clauses */ - /* add the ordering */ /* if PKTableName != NULL, selection on primary key, order on FK output columns, else order on PK output columns */ + /* MvD: added additional ordering on FK_NAME or PK_NAME to get proper ordering + for multiple multi-column fks to the same multi-column pk from one table */ pos += snprintf(query + pos, querylen - pos, - " order by \"%sTABLE_SCHEM\", \"%sTABLE_NAME\", \"KEY_SEQ\"", + " order by \"%sTABLE_SCHEM\", \"%sTABLE_NAME\", \"%s_NAME\", \"KEY_SEQ\"", + PKTableName != NULL ? "FK" : "PK", PKTableName != NULL ? "FK" : "PK", PKTableName != NULL ? "FK" : "PK"); + /* debug: fprintf(stdout, "SQLForeignKeys SQL (%zu):\n%s\n\n", pos, query); */ + /* query the MonetDB data dictionary tables */ rc = MNDBExecDirect(stmt, (SQLCHAR *) query, (SQLINTEGER) pos); @@ -348,7 +360,7 @@ SQLForeignKeysW(SQLHSTMT StatementHandle #endif if (!isValidStmt(stmt)) - return SQL_INVALID_HANDLE; + return SQL_INVALID_HANDLE; clearStmtErrors(stmt); diff --git a/clients/odbc/samples/metadata.c b/clients/odbc/samples/metadata.c --- a/clients/odbc/samples/metadata.c +++ b/clients/odbc/samples/metadata.c @@ -196,6 +196,15 @@ main(int argc, char **argv) "CREATE TABLE odbctst.nopk_twoucs (id2 INT NOT NULL UNIQUE, name2 VARCHAR(99) UNIQUE);\n" "CREATE LOCAL TEMP TABLE tmp.tmp_nopk_twoucs (id2 INT NOT NULL UNIQUE, name2 VARCHAR(99) UNIQUE);\n" "CREATE GLOBAL TEMP TABLE tmp.glbl_nopk_twoucs (id2 INT NOT NULL UNIQUE, name2 VARCHAR(99) UNIQUE);\n" + /* next 3 tables copied from example in https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlforeignkeys-function?view=sql-server-ver15 */ + "CREATE TABLE \"CUSTOMERS\" (\"CUSTID\" INT PRIMARY KEY, \"NAME\" VARCHAR(60) NOT NULL, \"ADDRESS\" VARCHAR(90), \"PHONE\" VARCHAR(20));\n" + "CREATE TABLE \"ORDERS\" (\"ORDERID\" INT PRIMARY KEY, \"CUSTID\" INT NOT NULL REFERENCES \"CUSTOMERS\" (\"CUSTID\"), \"OPENDATE\" DATE NOT NULL, \"SALESPERSON\" VARCHAR(60), \"STATUS\" VARCHAR(10) NOT NULL);\n" + "CREATE TABLE \"LINES\" (\"ORDERID\" INT NOT NULL REFERENCES \"ORDERS\" (\"ORDERID\"), \"LINES\" INT, PRIMARY KEY (\"ORDERID\", \"LINES\"), \"PARTID\" INT NOT NULL, \"QUANTITY\" DECIMAL(9,3) NOT NULL);\n" + /* also test situation where one table has multiple fks to the same multi column pk */ + "CREATE TABLE odbctst.pk2c (pkc1 INT, pkc2 VARCHAR(99), name1 VARCHAR(99) UNIQUE, PRIMARY KEY (pkc2, pkc1));\n" + "CREATE TABLE odbctst.fk2c (fkc1 INT NOT NULL PRIMARY KEY, fkc2 VARCHAR(99), fkc3 INT" + ", FOREIGN KEY (fkc2, fkc1) REFERENCES odbctst.pk2c (pkc2, pkc1) ON UPDATE CASCADE ON DELETE RESTRICT" + ", FOREIGN KEY (fkc2, fkc3) REFERENCES odbctst.pk2c (pkc2, pkc1) ON UPDATE SET NULL ON DELETE NO ACTION);\n" , SQL_NTS); check(ret, SQL_HANDLE_DBC, dbc, "SQLExecDirect (create tables script)"); @@ -266,7 +275,12 @@ main(int argc, char **argv) compareResult(stmt, ret, "SQLTables (odbctst, %)", "Resultset with 5 columns\n" "TABLE_CAT TABLE_SCHEM TABLE_NAME TABLE_TYPE REMARKS\n" + "mTests_sql_odbc_samples odbctst CUSTOMERS TABLE NULL\n" + "mTests_sql_odbc_samples odbctst LINES TABLE NULL\n" + "mTests_sql_odbc_samples odbctst ORDERS TABLE NULL\n" + "mTests_sql_odbc_samples odbctst fk2c TABLE NULL\n" "mTests_sql_odbc_samples odbctst nopk_twoucs TABLE NULL\n" + "mTests_sql_odbc_samples odbctst pk2c TABLE NULL\n" "mTests_sql_odbc_samples odbctst pk_uc TABLE NULL\n"); // All user tables and views @@ -280,10 +294,15 @@ main(int argc, char **argv) "mTests_sql_odbc_samples tmp glbl_pk_uc GLOBAL TEMPORARY TABLE NULL\n" "mTests_sql_odbc_samples tmp tmp_nopk_twoucs LOCAL TEMPORARY TABLE NULL\n" "mTests_sql_odbc_samples tmp tmp_pk_uc LOCAL TEMPORARY TABLE NULL\n" + "mTests_sql_odbc_samples odbctst CUSTOMERS TABLE NULL\n" + "mTests_sql_odbc_samples odbctst LINES TABLE NULL\n" + "mTests_sql_odbc_samples odbctst ORDERS TABLE NULL\n" + "mTests_sql_odbc_samples odbctst fk2c TABLE NULL\n" "mTests_sql_odbc_samples odbctst nopk_twoucs TABLE NULL\n" + "mTests_sql_odbc_samples odbctst pk2c TABLE NULL\n" "mTests_sql_odbc_samples odbctst pk_uc TABLE NULL\n"); - // All columns of the odbctst tables + // All columns of odbctst tables containg 'pk' in their name ret = SQLColumns(stmt, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"%pk%", SQL_NTS, (SQLCHAR*)"%", SQL_NTS); @@ -292,6 +311,9 @@ main(int argc, char **argv) "TABLE_CAT TABLE_SCHEM TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME COLUMN_SIZE BUFFER_LENGTH DECIMAL_DIGITS NUM_PREC_RADIX NULLABLE REMARKS COLUMN_DEF SQL_DATA_TYPE SQL_DATETIME_SUB CHAR_OCTET_LENGTH ORDINAL_POSITION IS_NULLABLE\n" "mTests_sql_odbc_samples odbctst nopk_twoucs id2 4 INTEGER 32 11 0 2 0 NULL NULL 4 NULL NULL 1 NO\n" "mTests_sql_odbc_samples odbctst nopk_twoucs name2 -9 VARCHAR 99 198 NULL NULL 1 NULL NULL -9 NULL 198 2 YES\n" + "mTests_sql_odbc_samples odbctst pk2c pkc1 4 INTEGER 32 11 0 2 0 NULL NULL 4 NULL NULL 1 NO\n" + "mTests_sql_odbc_samples odbctst pk2c pkc2 -9 VARCHAR 99 198 NULL NULL 0 NULL NULL -9 NULL 198 2 NO\n" + "mTests_sql_odbc_samples odbctst pk2c name1 -9 VARCHAR 99 198 NULL NULL 1 NULL NULL -9 NULL 198 3 YES\n" "mTests_sql_odbc_samples odbctst pk_uc id1 4 INTEGER 32 11 0 2 0 NULL NULL 4 NULL NULL 1 NO\n" "mTests_sql_odbc_samples odbctst pk_uc name1 -9 VARCHAR 99 198 NULL NULL 1 NULL NULL -9 NULL 198 2 YES\n"); @@ -579,16 +601,71 @@ main(int argc, char **argv) "mTests_sql_odbc_samples tmp glbl_nopk_twoucs 1 NULL glbl_nopk_twoucs_i 2 1 id2 NULL NULL NULL NULL\n" "mTests_sql_odbc_samples tmp glbl_nopk_twoucs 1 NULL glbl_nopk_twoucs_i 2 2 name2 NULL NULL NULL NULL\n"); + // odbctst.CUSTOMERS, odbctst.ORDERS and odbctst.LINES + /* next tests are copied from code examples on https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlforeignkeys-function?view=sql-server-ver15 */ + ret = SQLPrimaryKeys(stmt, NULL, 0, NULL, 0, (SQLCHAR*)"ORDERS", SQL_NTS); + compareResult(stmt, ret, "SQLPrimaryKeys (NULL, ORDERS)", + "Resultset with 6 columns\n" + "TABLE_CAT TABLE_SCHEM TABLE_NAME COLUMN_NAME KEY_SEQ PK_NAME\n" + "mTests_sql_odbc_samples odbctst ORDERS ORDERID 1 ORDERS_ORDERID_pkey\n"); - // TODO add tables with fk constraints and procedures such that below calls also return data rows + ret = SQLForeignKeys(stmt, NULL, 0, NULL, 0, (SQLCHAR*)"ORDERS", SQL_NTS, NULL, 0, NULL, 0, NULL, 0); + compareResult(stmt, ret, "SQLForeignKeys (NULL, ORDERS, NULL, NULL)", + "Resultset with 14 columns\n" + "PKTABLE_CAT PKTABLE_SCHEM PKTABLE_NAME PKCOLUMN_NAME FKTABLE_CAT FKTABLE_SCHEM FKTABLE_NAME FKCOLUMN_NAME KEY_SEQ UPDATE_RULE DELETE_RULE FK_NAME PK_NAME DEFERRABILITY\n" + "mTests_sql_odbc_samples odbctst ORDERS ORDERID mTests_sql_odbc_samples odbctst LINES ORDERID 1 1 1 LINES_ORDERID_fkey ORDERS_ORDERID_pkey 7\n"); + + ret = SQLForeignKeys(stmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, (SQLCHAR*)"ORDERS", SQL_NTS); + compareResult(stmt, ret, "SQLForeignKeys (NULL, NULL, NULL, ORDERS)", + "Resultset with 14 columns\n" + "PKTABLE_CAT PKTABLE_SCHEM PKTABLE_NAME PKCOLUMN_NAME FKTABLE_CAT FKTABLE_SCHEM FKTABLE_NAME FKCOLUMN_NAME KEY_SEQ UPDATE_RULE DELETE_RULE FK_NAME PK_NAME DEFERRABILITY\n" + "mTests_sql_odbc_samples odbctst CUSTOMERS CUSTID mTests_sql_odbc_samples odbctst ORDERS CUSTID 1 1 1 ORDERS_CUSTID_fkey CUSTOMERS_CUSTID_pkey 7\n"); + + // odbctst.pk2c and odbctst.fk2c (tests multi-column pks and multiple multi-column fks from one table */ + ret = SQLPrimaryKeys(stmt, NULL, 0, (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk2c", SQL_NTS); + compareResult(stmt, ret, "SQLPrimaryKeys (odbctst, pk2c)", + "Resultset with 6 columns\n" + "TABLE_CAT TABLE_SCHEM TABLE_NAME COLUMN_NAME KEY_SEQ PK_NAME\n" + "mTests_sql_odbc_samples odbctst pk2c pkc2 1 pk2c_pkc2_pkc1_pkey\n" + "mTests_sql_odbc_samples odbctst pk2c pkc1 2 pk2c_pkc2_pkc1_pkey\n"); + ret = SQLForeignKeys(stmt, (SQLCHAR*)"", SQL_NTS, - (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"totbl", SQL_NTS, + (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk2c", SQL_NTS, (SQLCHAR*)"", SQL_NTS, - (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"fromtbl", SQL_NTS); - compareResult(stmt, ret, "SQLForeignKeys (odbctst, totbl, odbctst, fromtbl)", + (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS); + compareResult(stmt, ret, "SQLForeignKeys (odbctst, pk2c, , )", + "Resultset with 14 columns\n" + "PKTABLE_CAT PKTABLE_SCHEM PKTABLE_NAME PKCOLUMN_NAME FKTABLE_CAT FKTABLE_SCHEM FKTABLE_NAME FKCOLUMN_NAME KEY_SEQ UPDATE_RULE DELETE_RULE FK_NAME PK_NAME DEFERRABILITY\n" + "mTests_sql_odbc_samples odbctst pk2c pkc2 mTests_sql_odbc_samples odbctst fk2c fkc2 1 0 1 fk2c_fkc2_fkc1_fkey pk2c_pkc2_pkc1_pkey 7\n" + "mTests_sql_odbc_samples odbctst pk2c pkc1 mTests_sql_odbc_samples odbctst fk2c fkc1 2 0 1 fk2c_fkc2_fkc1_fkey pk2c_pkc2_pkc1_pkey 7\n" + "mTests_sql_odbc_samples odbctst pk2c pkc2 mTests_sql_odbc_samples odbctst fk2c fkc2 1 2 3 fk2c_fkc2_fkc3_fkey pk2c_pkc2_pkc1_pkey 7\n" + "mTests_sql_odbc_samples odbctst pk2c pkc1 mTests_sql_odbc_samples odbctst fk2c fkc3 2 2 3 fk2c_fkc2_fkc3_fkey pk2c_pkc2_pkc1_pkey 7\n"); + + ret = SQLForeignKeys(stmt, (SQLCHAR*)"", SQL_NTS, + (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS, + (SQLCHAR*)"", SQL_NTS, + (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"fk2c", SQL_NTS); + compareResult(stmt, ret, "SQLForeignKeys (, , odbctst, fk2c)", "Resultset with 14 columns\n" - "PKTABLE_CAT PKTABLE_SCHEM PKTABLE_NAME PKCOLUMN_NAME FKTABLE_CAT FKTABLE_SCHEM FKTABLE_NAME FKCOLUMN_NAME KEY_SEQ UPDATE_RULE DELETE_RULE FK_NAME PK_NAME DEFERRABILITY\n"); + "PKTABLE_CAT PKTABLE_SCHEM PKTABLE_NAME PKCOLUMN_NAME FKTABLE_CAT FKTABLE_SCHEM FKTABLE_NAME FKCOLUMN_NAME KEY_SEQ UPDATE_RULE DELETE_RULE FK_NAME PK_NAME DEFERRABILITY\n" + "mTests_sql_odbc_samples odbctst pk2c pkc2 mTests_sql_odbc_samples odbctst fk2c fkc2 1 0 1 fk2c_fkc2_fkc1_fkey pk2c_pkc2_pkc1_pkey 7\n" + "mTests_sql_odbc_samples odbctst pk2c pkc1 mTests_sql_odbc_samples odbctst fk2c fkc1 2 0 1 fk2c_fkc2_fkc1_fkey pk2c_pkc2_pkc1_pkey 7\n" + "mTests_sql_odbc_samples odbctst pk2c pkc2 mTests_sql_odbc_samples odbctst fk2c fkc2 1 2 3 fk2c_fkc2_fkc3_fkey pk2c_pkc2_pkc1_pkey 7\n" + "mTests_sql_odbc_samples odbctst pk2c pkc1 mTests_sql_odbc_samples odbctst fk2c fkc3 2 2 3 fk2c_fkc2_fkc3_fkey pk2c_pkc2_pkc1_pkey 7\n"); + ret = SQLForeignKeys(stmt, (SQLCHAR*)"", SQL_NTS, + (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"pk2c", SQL_NTS, + (SQLCHAR*)"", SQL_NTS, + (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"fk2c", SQL_NTS); + compareResult(stmt, ret, "SQLForeignKeys (odbctst, pk2c, odbctst, fk2c)", + "Resultset with 14 columns\n" + "PKTABLE_CAT PKTABLE_SCHEM PKTABLE_NAME PKCOLUMN_NAME FKTABLE_CAT FKTABLE_SCHEM FKTABLE_NAME FKCOLUMN_NAME KEY_SEQ UPDATE_RULE DELETE_RULE FK_NAME PK_NAME DEFERRABILITY\n" + "mTests_sql_odbc_samples odbctst pk2c pkc2 mTests_sql_odbc_samples odbctst fk2c fkc2 1 0 1 fk2c_fkc2_fkc1_fkey pk2c_pkc2_pkc1_pkey 7\n" + "mTests_sql_odbc_samples odbctst pk2c pkc1 mTests_sql_odbc_samples odbctst fk2c fkc1 2 0 1 fk2c_fkc2_fkc1_fkey pk2c_pkc2_pkc1_pkey 7\n" + "mTests_sql_odbc_samples odbctst pk2c pkc2 mTests_sql_odbc_samples odbctst fk2c fkc2 1 2 3 fk2c_fkc2_fkc3_fkey pk2c_pkc2_pkc1_pkey 7\n" + "mTests_sql_odbc_samples odbctst pk2c pkc1 mTests_sql_odbc_samples odbctst fk2c fkc3 2 2 3 fk2c_fkc2_fkc3_fkey pk2c_pkc2_pkc1_pkey 7\n"); + + // TODO add tables with procedures such that below calls also return data rows ret = SQLProcedures(stmt, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"myproc", SQL_NTS); compareResult(stmt, ret, "SQLProcedures (odbctst, myproc)", @@ -620,9 +697,22 @@ main(int argc, char **argv) "DROP TABLE odbctst.nopk_twoucs;\n" "DROP TABLE tmp.tmp_nopk_twoucs;\n" "DROP TABLE tmp.glbl_nopk_twoucs;\n" + "DROP TABLE odbctst.\"LINES\";\n" + "DROP TABLE odbctst.\"ORDERS\";\n" + "DROP TABLE odbctst.\"CUSTOMERS\";\n" + "DROP TABLE odbctst.fk2c;\n" + "DROP TABLE odbctst.pk2c;\n" , SQL_NTS); check(ret, SQL_HANDLE_DBC, dbc, "SQLExecDirect (drop tables script)"); + // All tables in schema odbctst should be empty now, else we missed some DROP statements + ret = SQLTables(stmt, NULL, 0, + (SQLCHAR*)"odbctst", SQL_NTS, (SQLCHAR*)"%", SQL_NTS, + NULL, 0); + compareResult(stmt, ret, "SQLTables (odbctst, %, NULL)", + "Resultset with 5 columns\n" + "TABLE_CAT TABLE_SCHEM TABLE_NAME TABLE_TYPE REMARKS\n"); + ret = SQLExecDirect(stmt, (SQLCHAR *) "SET SCHEMA sys;\n" "DROP SCHEMA odbctst;\n" _______________________________________________ checkin-list mailing list -- [email protected] To unsubscribe send an email to [email protected]
