Changeset: 45420136cbd6 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/45420136cbd6
Modified Files:
sql/backends/monet5/vaults/odbc/odbc_loader.c
sql/test/proto_loader/odbc/Tests/sqlite3odbc.test
Branch: Mar2025
Log Message:
Calling ODBC SQLPrepare() instead of SQLExecDirect() to get the column names
and types of the query result, resulted in a problem for SQLite system table
sqlite_sequence.
It gave different type (TEXT) for column seq after SQLPrepare(), where it
returned INT after SQLExecDirect().
Hence we must use SQLExecDirect in both calls odbc_relation() and ODBCloader()
to get consistent behavior.
Added querying sqlite_sequence to the test.
diffs (98 lines):
diff --git a/sql/backends/monet5/vaults/odbc/odbc_loader.c
b/sql/backends/monet5/vaults/odbc/odbc_loader.c
--- a/sql/backends/monet5/vaults/odbc/odbc_loader.c
+++ b/sql/backends/monet5/vaults/odbc/odbc_loader.c
@@ -423,14 +423,11 @@ odbc_query(mvc *sql, sql_subfunc *f, cha
}
// TODO convert qry_str from UTF-8 to UCS16, so we can use ODBC W
functions
- if (caller == ODBC_RELATION)
- ret = SQLPrepare(stmt, (SQLCHAR *) query, SQL_NTS);
- else
- ret = SQLExecDirect(stmt, (SQLCHAR *) query, SQL_NTS);
+ ret = SQLExecDirect(stmt, (SQLCHAR *) query, SQL_NTS);
if (trace_enabled)
- printf("After SQL%s(%s) returned %d\n", (caller ==
ODBC_RELATION) ? "Prepare" : "ExecDirect", query, ret);
+ printf("After SQLExecDirect(%s) returned %d\n", query, ret);
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
- errmsg = (caller == ODBC_RELATION) ? "SQLPrepare query failed."
: "SQLExecDirect query failed.";
+ errmsg = "SQLExecDirect query failed.";
goto finish;
}
@@ -746,7 +743,7 @@ odbc_query(mvc *sql, sql_subfunc *f, cha
break;
case TYPE_sht:
if
(trace_enabled)
-
printf("Data row %lu col %u: %d\n", row, col+1, sht_val);
+
printf("Data row %lu col %u: %hd\n", row, col+1, sht_val);
gdkret =
BUNappend(b, (void *) &sht_val, false);
break;
case TYPE_int:
@@ -791,7 +788,7 @@ odbc_query(mvc *sql, sql_subfunc *f, cha
daytime
daytime_val = daytime_create(ts_val.hour, ts_val.minute, ts_val.second,
ts_val.fraction);
timestamp
timestamp_val = timestamp_create(mdate_val, daytime_val);
if
(trace_enabled)
-
printf("Data row %lu col %u: timestamp((%04d-%02u-%02u %02u:%02u:%02u.%06u)\n",
row, col+1,
+
printf("Data row %lu col %u: timestamp(%04d-%02u-%02u %02u:%02u:%02u.%06u)\n",
row, col+1,
ts_val.year, ts_val.month, ts_val.day, ts_val.hour, ts_val.minute,
ts_val.second, ts_val.fraction);
gdkret =
BUNappend(b, (void *) ×tamp_val, false);
break;
@@ -874,15 +871,16 @@ odbc_query(mvc *sql, sql_subfunc *f, cha
handleType = SQL_HANDLE_ENV;
handle = env;
}
+ // TODO use ODBC W function
ret = SQLGetDiagRec(handleType, handle, 1, state, &errnr, msg,
(sizeof(msg) -1), &msglen);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
str retmsg;
if (state[SQL_SQLSTATE_SIZE] != '\0')
state[SQL_SQLSTATE_SIZE] = '\0';
if (errmsg != NULL) {
- retmsg = sa_message(sql->sa, "odbc_loader" " %s
SQLstate %s, Errnr %d, Message %s", errmsg, (char*)state, (int)errnr,
(char*)msg);
+ retmsg = sa_message(sql->sa, "odbc_loader" " %s
SQLstate %s, Errnr %d, Message %s", errmsg, (char*)state, errnr, (char*)msg);
} else {
- retmsg = sa_message(sql->sa, "odbc_loader" "
SQLstate %s, Errnr %d, Message %s", (char*)state, (int)errnr, (char*)msg);
+ retmsg = sa_message(sql->sa, "odbc_loader" "
SQLstate %s, Errnr %d, Message %s", (char*)state, errnr, (char*)msg);
}
odbc_cleanup(env, dbc, stmt);
return retmsg;
diff --git a/sql/test/proto_loader/odbc/Tests/sqlite3odbc.test
b/sql/test/proto_loader/odbc/Tests/sqlite3odbc.test
--- a/sql/test/proto_loader/odbc/Tests/sqlite3odbc.test
+++ b/sql/test/proto_loader/odbc/Tests/sqlite3odbc.test
@@ -6,7 +6,7 @@ select * from proto_loader('odbc:DRIVER=
statement error 42000!SELECT: proto_loader function failed 'odbc_loader Could
not connect. SQLDriverConnect failed. SQLstate HY000, Errnr 14, Message
[SQLite]connect failed'
select * from
proto_loader('odbc:DRIVER=/usr/lib64/libsqlite3odbc.so;Database=~/Downloads/sqlite_dbs/chinook.db;QUERY=SELECT
* FROM INFORMATION_SCHEMA.TABLES')
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLPrepare query failed. SQLstate HY000, Errnr 1, Message [SQLite]no such
table: INFORMATION_SCHEMA.TABLES (1)'
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLExecDirect query failed. SQLstate HY000, Errnr 1, Message [SQLite]no such
table: INFORMATION_SCHEMA.TABLES (1)'
select * from
proto_loader('odbc:DRIVER=/usr/lib64/libsqlite3odbc.so;Database=odbc_loader_test.db;QUERY=SELECT
* FROM INFORMATION_SCHEMA.TABLES')
query TTT
@@ -220,3 +220,27 @@ United Kingdom
N1 5LH
8
+query TI
+select * from
proto_loader('odbc:DRIVER=/usr/lib64/libsqlite3odbc.so;Database=/home/dinther/Downloads/sqlite_dbs/chinook.db;QUERY=SELECT
* FROM sqlite_sequence')
+----
+genres
+25
+media_types
+5
+artists
+275
+albums
+347
+tracks
+3503
+employees
+8
+customers
+59
+invoices
+412
+invoice_items
+2240
+playlists
+18
+
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]