Changeset: 6e09d66b9963 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/6e09d66b9963
Modified Files:
sql/backends/monet5/vaults/odbc/odbc_loader.c
sql/test/proto_loader/odbc/Tests/monetodbc-Windows.test
sql/test/proto_loader/odbc/Tests/monetodbc.test
sql/test/proto_loader/odbc/Tests/sqlite3odbc.test.in
Branch: Mar2025
Log Message:
Make function getErrMsg() more generic such it can be used in more places.
Added fractions part for the INTERVAL ... SECOND types.
diffs (244 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
@@ -293,21 +293,21 @@ str_to_hge(const char *s) {
/* an ODBC function call returned an error, get the error msg from the ODBC
driver */
static char *
-getErrMsg(SQLHANDLE stmt) {
+getErrMsg(SQLSMALLINT handleType, SQLHANDLE handle) {
SQLRETURN ret = SQL_ERROR;
SQLCHAR state[SQL_SQLSTATE_SIZE +1];
SQLINTEGER errnr;
SQLCHAR msg[4096];
SQLSMALLINT msglen;
- if (stmt == SQL_NULL_HSTMT)
+ if (handle == SQL_NULL_HSTMT)
return NULL;
// TODO use ODBC W function
- ret = SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, state, &errnr, msg,
(sizeof(msg) -1), &msglen);
+ ret = SQLGetDiagRec(handleType, handle, 1, state, &errnr, msg,
(sizeof(msg) -1), &msglen);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
- char * format = "odbc_loader SQLstate %s, Errnr %d, Message %s";
- char * retmsg = (char *) GDKmalloc(strlen(format) + msglen);
+ const char format[] = "SQLSTATE %s, Error code %d, Message %s";
+ char * retmsg = (char *) malloc(sizeof(format) + MIN(msglen,
4096));
if (retmsg != NULL) {
if (state[SQL_SQLSTATE_SIZE] != '\0')
state[SQL_SQLSTATE_SIZE] = '\0';
@@ -473,7 +473,7 @@ odbc_query(int caller, mvc *sql, sql_sub
printf("After SQLGetInfo(dbc, SQL_DBMS_NAME) returned
%d\n", ret);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
if (strcmp("MonetDB", name) == 0) {
- /* let the MonetDB driver enable returning
HUGEINT as column datatype */
+ /* make the MonetDB ODBC driver enable
returning SQL_HUGEINT as column datatype */
ret = SQLGetTypeInfo(stmt, SQL_HUGEINT);
if (trace_enabled)
printf("After SQLGetTypeInfo(stmt,
SQL_HUGEINT) returned %d\n", ret);
@@ -883,11 +883,11 @@ odbc_query(int caller, mvc *sql, sql_sub
ret = SQLGetData(stmt, col+1, targetType,
targetValuePtr, bufferLength, &strLen);
if (ret != SQL_SUCCESS && ret !=
SQL_SUCCESS_WITH_INFO) {
if (trace_enabled) {
- char * ODBCmsg =
getErrMsg(stmt);
+ char * ODBCmsg =
getErrMsg(SQL_HANDLE_STMT, stmt);
printf("Failed to get C_type %d
data for col %u of row %lu. ODBCmsg: %s\n",
- targetType, col+1, row,
(ODBCmsg != NULL) ? ODBCmsg : "");
+ targetType, col+1, row,
(ODBCmsg) ? ODBCmsg : "");
if (ODBCmsg)
- GDKfree(ODBCmsg);
+ free(ODBCmsg);
}
/* as all bats need to be the correct
length, append NULL value */
if (BUNappend(b, ATOMnilptr(b->ttype),
false) != GDK_SUCCEED)
@@ -927,6 +927,7 @@ odbc_query(int caller, mvc *sql, sql_sub
break;
#ifdef HAVE_HGE
case
TYPE_hge:
+
/* HUGEINT values are read as string */
hge_val = str_to_hge(str_val);
gdkret = BUNappend(b, (void *) &hge_val, false);
break;
@@ -964,13 +965,6 @@ odbc_query(int caller, mvc *sql, sql_sub
printf("Data row %lu col %u: %" PRId64 "\n", row, col+1, lng_val);
gdkret =
BUNappend(b, (void *) &lng_val, false);
break;
-#ifdef HAVE_HGE
-// case SQL_HUGEINT:
-// if
(trace_enabled)
-//
printf("Data row %lu col %u: %" PRId128 "\n", row, col+1, hge_val);
-// gdkret =
BUNappend(b, (void *) &hge_val, false);
-// break;
-#endif
case SQL_DECIMAL:
case SQL_NUMERIC:
{
@@ -1103,7 +1097,8 @@ odbc_query(int caller, mvc *sql, sql_sub
}
case
SQL_INTERVAL_SECOND:
{
- lng_val = (lng)
itv_val.intval.day_second.second * 1000;
+ lng_val = (lng)
(itv_val.intval.day_second.second * 1000)
+ +
itv_val.intval.day_second.fraction;
if
(itv_val.interval_sign == SQL_TRUE)
lng_val
= -lng_val;
if
(trace_enabled)
@@ -1136,10 +1131,11 @@ odbc_query(int caller, mvc *sql, sql_sub
}
case
SQL_INTERVAL_DAY_TO_SECOND:
{
- lng_val = (lng)
((((((itv_val.intval.day_second.day *24)
+ lng_val = (lng)
(((((((itv_val.intval.day_second.day *24)
+
itv_val.intval.day_second.hour) *60)
+
itv_val.intval.day_second.minute) *60)
- +
itv_val.intval.day_second.second) *1000;
+ +
itv_val.intval.day_second.second) *1000)
+ +
itv_val.intval.day_second.fraction;
if
(itv_val.interval_sign == SQL_TRUE)
lng_val
= -lng_val;
if
(trace_enabled)
@@ -1160,9 +1156,10 @@ odbc_query(int caller, mvc *sql, sql_sub
}
case
SQL_INTERVAL_HOUR_TO_SECOND:
{
- lng_val = (lng)
((((itv_val.intval.day_second.hour *60)
+ lng_val = (lng)
(((((itv_val.intval.day_second.hour *60)
+
itv_val.intval.day_second.minute) *60)
- +
itv_val.intval.day_second.second) *1000;
+ +
itv_val.intval.day_second.second) *1000)
+ +
itv_val.intval.day_second.fraction;
if
(itv_val.interval_sign == SQL_TRUE)
lng_val
= -lng_val;
if
(trace_enabled)
@@ -1172,8 +1169,9 @@ odbc_query(int caller, mvc *sql, sql_sub
}
case
SQL_INTERVAL_MINUTE_TO_SECOND:
{
- lng_val = (lng)
((itv_val.intval.day_second.minute *60)
- +
itv_val.intval.day_second.second) * 1000;
+ lng_val = (lng)
(((itv_val.intval.day_second.minute *60)
+ +
itv_val.intval.day_second.second) *1000)
+ +
itv_val.intval.day_second.fraction;
if
(itv_val.interval_sign == SQL_TRUE)
lng_val
= -lng_val;
if
(trace_enabled)
@@ -1247,10 +1245,8 @@ odbc_query(int caller, mvc *sql, sql_sub
/* an ODBC function call returned an error, get the error msg
from the ODBC driver */
SQLSMALLINT handleType;
SQLHANDLE handle;
- SQLCHAR state[SQL_SQLSTATE_SIZE +1];
- SQLINTEGER errnr;
- SQLCHAR msg[2048];
- SQLSMALLINT msglen;
+ str retmsg;
+ char * ODBCmsg;
/* get err message(s) from the right handle */
if (stmt != SQL_NULL_HSTMT) {
@@ -1264,20 +1260,16 @@ odbc_query(int caller, mvc *sql, sql_sub
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, errnr, (char*)msg);
- } else {
- 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;
+ ODBCmsg = getErrMsg(handleType, handle);
+ if (errmsg != NULL) {
+ retmsg = sa_message(sql->sa, "odbc_loader" " %s %s",
errmsg, (ODBCmsg) ? ODBCmsg : "");
+ } else {
+ retmsg = sa_message(sql->sa, "odbc_loader" " %s",
(ODBCmsg) ? ODBCmsg : "");
}
+ if (ODBCmsg)
+ free(ODBCmsg);
+ odbc_cleanup(env, dbc, stmt);
+ return retmsg;
}
odbc_cleanup(env, dbc, stmt);
return (errmsg != NULL) ? (str)errmsg : MAL_SUCCEED;
diff --git a/sql/test/proto_loader/odbc/Tests/monetodbc-Windows.test
b/sql/test/proto_loader/odbc/Tests/monetodbc-Windows.test
--- a/sql/test/proto_loader/odbc/Tests/monetodbc-Windows.test
+++ b/sql/test/proto_loader/odbc/Tests/monetodbc-Windows.test
@@ -6,28 +6,28 @@ select * from proto_loader('odbc:Driver=
statement error 42000!CATALOG: no such table returning function 'proto_loader'
select * from proto_loader('odbc:DRIVER=/usr/lib64/libMonetODBC.so',
'monetdb', 'monetdb', 'SELECT * FROM INFORMATION_SCHEMA.TABLES')
---statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate 08001, Errnr 0, Message [MonetDB][ODBC Driver
11.51.5]could not connect: Connection refused'
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate 08001, Errnr 0, Message [MonetDB][ODBC Driver
...
+--statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE 08001, Error code 0, Message [MonetDB][ODBC
Driver 11.51.5]could not connect: Connection refused'
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE 08001, Error code 0, Message [MonetDB][ODBC
Driver ...
select * from proto_loader('odbc:DSN=MonetDB;QUERY=SELECT * FROM
INFORMATION_SCHEMA.TABLES')
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate HY000, Errnr 556, Message General error:
Invalid file dsn '''
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE HY000, Error code 556, Message General error:
Invalid file dsn '''
select * from proto_loader('odbc:FILEDSN=MonetDB;QUERY=SELECT * FROM
INFORMATION_SCHEMA.TABLES')
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate IM002, Errnr 0, Message [Microsoft][ODBC
Driver Manager] Data source name not found and no default driver specified'
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE IM002, Error code 0, Message [Microsoft][ODBC
Driver Manager] Data source name not found and no default driver specified'
select * from proto_loader('odbc:DRIVER=MonetODBC.dll;QUERY=SELECT * FROM
INFORMATION_SCHEMA.TABLES')
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate IM002, Errnr 0, Message [Microsoft][ODBC
Driver Manager] Data source name not found and no default driver specified'
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE IM002, Error code 0, Message [Microsoft][ODBC
Driver Manager] Data source name not found and no default driver specified'
select * from
proto_loader('odbc:DRIVER=/usr/lib64/libMonetODBC.so;UID=monetdb;PWD=monetdb;QUERY=SELECT
* FROM INFORMATION_SCHEMA.TABLES')
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate 08001, Errnr 0, Message [MonetDB][ODBC Driver
...
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE 08001, Error code 0, Message [MonetDB][ODBC
Driver ...
select * from
proto_loader('odbc:DSN=MonetDB;UID=monetdb;PWD=monetdb;QUERY=SELECT * FROM
INFORMATION_SCHEMA.TABLES')
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate 08001, Errnr 0, Message [MonetDB][ODBC Driver
...
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE 08001, Error code 0, Message [MonetDB][ODBC
Driver ...
select * from
proto_loader('odbc:DSN=MonetDB;Database=demo;UID=monetdb;PWD=monetdb;QUERY=SELECT
* FROM INFORMATION_SCHEMA.TABLES')
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate 08001, Errnr 0, Message [MonetDB][ODBC Driver
...
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE 08001, Error code 0, Message [MonetDB][ODBC
Driver ...
select * from
proto_loader('odbc:DSN=MonetDB;Database=mTests_sql_test_proto_loader_odbc;UID=monetdb;PWD=monetdb;QUERY=SELECT
* FROM INFORMATION_SCHEMA.TABLES')
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate 08001, Errnr 0, Message [MonetDB][ODBC Driver
...
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE 08001, Error code 0, Message [MonetDB][ODBC
Driver ...
select * from
proto_loader('odbc:DSN=MonetDB;Database=mTests_sql_test_proto_loader_odbc;Port=40655;UID=monetdb;PWD=monetdb;QUERY=SELECT
* FROM INFORMATION_SCHEMA.TABLES')
diff --git a/sql/test/proto_loader/odbc/Tests/monetodbc.test
b/sql/test/proto_loader/odbc/Tests/monetodbc.test
--- a/sql/test/proto_loader/odbc/Tests/monetodbc.test
+++ b/sql/test/proto_loader/odbc/Tests/monetodbc.test
@@ -6,10 +6,10 @@ select * from proto_loader('odbc:Dsn=Mon
statement error 42000!CATALOG: no such table returning function 'proto_loader'
select * from proto_loader('odbc:DSN=MonetDB-Test', 'monetdb', 'monetdb',
'SELECT * FROM INFORMATION_SCHEMA.TABLES')
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate IM002, Errnr 0, Message [unixODBC][Driver
Manager]Data source name not found and no default driver specified'
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE IM002, Error code 0, Message
[unixODBC][Driver Manager]Data source name not found and no default driver
specified'
select * from proto_loader('odbc:FILEDSN=MonetDB-Test;QUERY=SELECT * FROM
INFORMATION_SCHEMA.TABLES')
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate 01000, Errnr 0, Message [unixODBC][Driver
Manager]Can't open lib 'libMonetODBC' : file not found'
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE 01000, Error code 0, Message
[unixODBC][Driver Manager]Can't open lib 'libMonetODBC' : file not found'
select * from proto_loader('odbc:DRIVER=libMonetODBC;QUERY=SELECT * FROM
INFORMATION_SCHEMA.TABLES')
query TT
diff --git a/sql/test/proto_loader/odbc/Tests/sqlite3odbc.test.in
b/sql/test/proto_loader/odbc/Tests/sqlite3odbc.test.in
--- a/sql/test/proto_loader/odbc/Tests/sqlite3odbc.test.in
+++ b/sql/test/proto_loader/odbc/Tests/sqlite3odbc.test.in
@@ -1,12 +1,12 @@
-- test with 'odbc:DRIVER=/usr/lib64/libsqlite3odbc.so;' protocol specification
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate HY000, Errnr 14, Message [SQLite]connect
failed'
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE HY000, Error code 14, Message [SQLite]connect
failed'
select * from
proto_loader('odbc:DRIVER=/usr/lib64/libsqlite3odbc.so;QUERY=SELECT * FROM
INFORMATION_SCHEMA.TABLES')
-statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLstate HY000, Errnr 14, Message [SQLite]connect
failed'
+statement error 42000!SELECT: proto_loader function failed 'odbc_loader
SQLDriverConnect failed. SQLSTATE HY000, Error code 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
SQLExecDirect 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, Error code 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
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]