Changeset: 9618390bbd6f for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9618390bbd6f
Modified Files:
clients/odbc/driver/SQLColumns.c
Branch: Aug2011
Log Message:
Reimplemented SQLColumns query to let the server do the work.
Before, the server did part of the work and the driver converted the
server's result into something that looks like what the spec wants.
diffs (truncated from 727 to 300 lines):
diff --git a/clients/odbc/driver/SQLColumns.c b/clients/odbc/driver/SQLColumns.c
--- a/clients/odbc/driver/SQLColumns.c
+++ b/clients/odbc/driver/SQLColumns.c
@@ -44,48 +44,6 @@
#define NCOLUMNS 18
-static const char *columnnames[NCOLUMNS] = {
- "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",
-};
-
-static const char *columntypes[NCOLUMNS] = {
- "varchar",
- "varchar",
- "varchar",
- "varchar",
- "smallint",
- "varchar",
- "int",
- "int",
- "smallint",
- "smallint",
- "smallint",
- "varchar",
- "varchar",
- "smallint",
- "smallint",
- "int",
- "int",
- "varchar",
-};
-
static SQLRETURN
SQLColumns_(ODBCStmt *stmt,
SQLCHAR *CatalogName,
@@ -103,6 +61,13 @@ SQLColumns_(ODBCStmt *stmt,
char *query = NULL;
char *query_end = NULL;
+ /* null pointers not allowed if arguments are identifiers */
+ if (stmt->Dbc->sql_attr_metadata_id == SQL_TRUE &&
+ (SchemaName == NULL || TableName == NULL || ColumnName == NULL)) {
+ addStmtError(stmt, "HY090", NULL, 0);
+ return SQL_ERROR;
+ }
+
fixODBCstring(CatalogName, NameLength1, SQLSMALLINT,
addStmtError, stmt, return SQL_ERROR);
fixODBCstring(SchemaName, NameLength2, SQLSMALLINT,
@@ -121,7 +86,7 @@ SQLColumns_(ODBCStmt *stmt,
#endif
/* construct the query now */
- query = (char *) malloc(1200 + NameLength2 + NameLength3 + NameLength4);
+ query = (char *) malloc(12000 + NameLength2 + NameLength3 +
NameLength4);
assert(query);
query_end = query;
@@ -147,70 +112,371 @@ SQLColumns_(ODBCStmt *stmt,
*/
sprintf(query_end,
- "select "
- "cast(NULL as varchar(1)) as table_cat, "
- "s.\"name\" as table_schem, "
- "t.\"name\" as table_name, "
- "c.\"name\" as column_name, "
- "cast(0 as smallint) as data_type, " /* filled in later */
- "c.\"type\" as type_name, "
- "cast(c.\"type_digits\" as integer) as column_size, "
- "cast(c.\"type_digits\" as integer) as buffer_length, "
- "cast(c.\"type_scale\" as smallint) as decimal_digits, "
- "cast(0 as smallint) as num_prec_radix, "
- "case c.\"null\" when true then cast(%d as smallint) "
- /* XXX should this be SQL_NULLABLE_UNKNOWN instead of
- * SQL_NO_NULLS? */
- "when false then cast(%d as smallint) end as nullable, "
- "cast('' as varchar(1)) as remarks, "
- "c.\"default\" as column_def, "
- "cast(0 as smallint) as sql_data_type, " /* filled in later */
- "cast(0 as smallint) as sql_datetime_sub, " /* filled in later
*/
- "case c.\"type\" when 'varchar' then cast(c.\"type_digits\" as
integer) else cast(NULL as integer) end as char_octet_length, "
- "cast(c.\"number\" + 1 as integer) as ordinal_position, "
- "case c.\"null\" when true then cast('yes' as varchar(3)) "
- /* should this be '' instead of 'no'? */
- "when false then cast('no' as varchar(3)) end as is_nullable "
- "from sys.\"schemas\" s, sys.\"tables\" t, sys.\"columns\" c "
- "where s.\"id\" = t.\"schema_id\" and t.\"id\" =
c.\"table_id\"",
- SQL_NULLABLE, SQL_NO_NULLS);
+ "select cast(NULL as varchar(1)) as table_cat,"
+ " s.\"name\" as table_schem,"
+ " t.\"name\" as table_name,"
+ " c.\"name\" as column_name,"
+ " case c.\"type\""
+ " when 'bigint' then %d"
+ " when 'blob' then %d"
+ " when 'boolean' then %d"
+ " when 'char' then %d"
+ " when 'clob' then %d"
+ " when 'date' then %d"
+ " when 'decimal' then %d"
+ " when 'double' then %d"
+ " when 'int' then %d"
+ " when 'month_interval' then"
+ " case c.type_digits"
+ " when 1 then %d"
+ " when 2 then %d"
+ " when 3 then %d"
+ " end"
+ " when 'real' then %d"
+ " when 'sec_interval' then"
+ " case c.type_digits"
+ " when 4 then %d"
+ " when 5 then %d"
+ " when 6 then %d"
+ " when 7 then %d"
+ " when 8 then %d"
+ " when 9 then %d"
+ " when 10 then %d"
+ " when 11 then %d"
+ " when 12 then %d"
+ " when 13 then %d"
+ " end"
+ " when 'smallint' then %d"
+ " when 'timestamp' then %d"
+ " when 'timestamptz' then %d"
+ " when 'time' then %d"
+ " when 'timetz' then %d"
+ " when 'tinyint' then %d"
+ " when 'varchar' then %d"
+ " end as data_type,"
+ " case c.\"type\""
+ " when 'bigint' then 'BIGINT'"
+ " when 'blob' then 'BINARY LARGE OBJECT'"
+ " when 'boolean' then 'BOOLEAN'"
+ " when 'char' then 'CHARACTER'"
+ " when 'clob' then 'CHARACTER LARGE OBJECT'"
+ " when 'date' then 'DATE'"
+ " when 'decimal' then 'DECIMAL'"
+ " when 'double' then 'DOUBLE'"
+ " when 'int' then 'INTEGER'"
+ " when 'month_interval' then"
+ " case c.type_digits"
+ " when 1 then 'INTERVAL YEAR'"
+ " when 2 then 'INTERVAL YEAR TO MONTH'"
+ " when 3 then 'INTERVAL MONTH'"
+ " end"
+ " when 'real' then 'REAL'"
+ " when 'sec_interval' then"
+ " case c.type_digits"
+ " when 4 then 'INTERVAL DAY'"
+ " when 5 then 'INTERVAL DAY TO HOUR'"
+ " when 6 then 'INTERVAL DAY TO MINUTE'"
+ " when 7 then 'INTERVAL DAY TO SECOND'"
+ " when 8 then 'INTERVAL HOUR'"
+ " when 9 then 'INTERVAL HOUR TO MINUTE'"
+ " when 10 then 'INTERVAL HOUR TO SECOND'"
+ " when 11 then 'INTERVAL MINUTE'"
+ " when 12 then 'INTERVAL MINUTE TO SECOND'"
+ " when 13 then 'INTERVAL SECOND'"
+ " end"
+ " when 'smallint' then 'SMALLINT'"
+ " when 'timestamp' then 'TIMESTAMP'"
+ " when 'timestamptz' then 'TIMESTAMP'"
+ " when 'time' then 'TIME'"
+ " when 'timetz' then 'TIME'"
+ " when 'tinyint' then 'TINYINT'"
+ " when 'varchar' then 'VARCHAR'"
+ " end as type_name,"
+ " case c.\"type\""
+ " when 'month_interval' then"
+ " case c.type_digits"
+ " when 1 then 26"
+ " when 2 then 38"
+ " when 3 then 27"
+ " end"
+ " when 'sec_interval' then"
+ " case c.type_digits"
+ " when 4 then 25"
+ " when 5 then 36"
+ " when 6 then 41"
+ " when 7 then 47"
+ " when 8 then 26"
+ " when 9 then 39"
+ " when 10 then 45"
+ " when 11 then 28"
+ " when 12 then 44"
+ " when 13 then 30"
+ " end"
+ " when 'date' then 10"
+ " when 'time' then 12"
+ " when 'timetz' then 12"
+ " when 'timestamp' then 23"
+ " when 'timestamptz' then 23"
+ " else c.type_digits"
+ " end as column_size,"
+ " case c.\"type\""
+ " when 'month_interval' then"
+ " case c.type_digits"
+ " when 1 then 26"
+ " when 2 then 38"
+ " when 3 then 27"
+ " end"
+ " when 'sec_interval' then"
+ " case c.type_digits"
+ " when 4 then 25"
+ " when 5 then 36"
+ " when 6 then 41"
+ " when 7 then 47"
+ " when 8 then 26"
+ " when 9 then 39"
+ " when 10 then 45"
+ " when 11 then 28"
+ " when 12 then 44"
+ " when 13 then 30"
+ " end"
+ " when 'date' then 10"
+ " when 'time' then 12"
+ " when 'timetz' then 12"
+ " when 'timestamp' then 23"
+ " when 'timestamptz' then 23"
+ " when 'bigint' then 20"
+ " when 'int' then 11"
+ " when 'smallint' then 6"
+ " when 'tinyint' then 4"
+ " when 'char' then 6 * c.type_digits"
+ " when 'varchar' then 6 * c.type_digits"
+ " when 'double' then 24"
+ " when 'real' then 14"
+ " else c.type_digits"
+ " end as buffer_length,"
+ " case c.\"type\""
+ " when 'time' then c.type_digits - 1"
+ " when 'timetz' then c.type_digits - 1"
+ " when 'timestamp' then c.type_digits - 1"
+ " when 'timestamptz' then c.type_digits - 1"
+ " when 'sec_interval' then 0"
+ " when 'month_interval' then 0"
+ " when 'real' then"
+ " case when c.type_digits = 24 and c.type_scale
= 0 then 7"
+ " else c.type_digits"
+ " end"
+ " when 'double' then"
+ " case when c.type_digits = 53 and c.type_scale
= 0 then 15"
+ " else c.type_digits"
+ " end"
+ " when 'decimal' then c.type_digits"
+ " when 'bigint' then 19"
+ " when 'int' then 10"
+ " when 'smallint' then 5"
+ " when 'tinyint' then 3"
+ " end as decimal_digits,"
+ " case c.\"type\""
+ " when 'double' then"
+ " case when c.type_digits = 53 and c.type_scale
= 0 then 2"
+ " else 10"
+ " end"
+ " when 'real' then"
+ " case when c.type_digits = 24 and c.type_scale
= 0 then 2"
+ " else 10"
+ " end"
+ " when 'bigint' then 2"
+ " when 'int' then 2"
+ " when 'smallint' then 2"
+ " when 'tinyint' then 2"
+ " when 'decimal' then 10"
+ " else cast(null as smallint)"
+ " end as num_prec_radix,"
+ " case c.\"null\""
+ " when true then cast(%d as smallint)"
+ " when false then cast(%d as smallint)"
+ " end as nullable,"
+ " cast('' as varchar(1)) as remarks,"
+ " c.\"default\" as column_def,"
+ " case c.\"type\""
+ " when 'bigint' then %d"
+ " when 'blob' then %d"
+ " when 'boolean' then %d"
+ " when 'char' then %d"
+ " when 'clob' then %d"
+ " when 'date' then %d"
+ " when 'decimal' then %d"
+ " when 'double' then %d"
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list