Changeset: c0bbfa8c3f8f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/c0bbfa8c3f8f
Modified Files:
        ChangeLog
        clients/odbc/tests/ODBCtester.c
        monetdb5/mal/mal_client.c
        monetdb5/mal/mal_client.h
Branch: default
Log Message:

Merge with Mar2025 branch.


diffs (truncated from 375 to 300 lines):

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,12 +1,6 @@
 # ChangeLog file for devel
 # This file is updated with Maddlog
 
-* Thu May  8 2025 Sjoerd Mullender <[email protected]>
-- It is now possible to specify an idle timeout using --set
-  idle_timeout=<seconds> (see mserver5 manual page) which gets triggered
-  if a connection to the server is idle (i.e. does not send any queries
-  to the server) while there is a SQL transaction active.
-
 * Mon Apr 28 2025 Niels Nes <[email protected]>
 - Changed the way complex AND and OR expressions are handled. The new
   expression tree uses 2 new cmp flag (cmp_con/cmp_dis), both expressions
diff --git a/ChangeLog.Mar2025 b/ChangeLog.Mar2025
--- a/ChangeLog.Mar2025
+++ b/ChangeLog.Mar2025
@@ -1,3 +1,9 @@
 # ChangeLog file for devel
 # This file is updated with Maddlog
 
+* Thu May  8 2025 Sjoerd Mullender <[email protected]>
+- It is now possible to specify an idle timeout using --set
+  idle_timeout=<seconds> (see mserver5 manual page) which gets triggered
+  if a connection to the server is idle (i.e. does not send any queries
+  to the server) while there is a SQL transaction active.
+
diff --git a/clients/odbc/driver/ODBCConvert.c 
b/clients/odbc/driver/ODBCConvert.c
--- a/clients/odbc/driver/ODBCConvert.c
+++ b/clients/odbc/driver/ODBCConvert.c
@@ -1019,23 +1019,39 @@ ODBCFetch(ODBCStmt *stmt,
        if (type == SQL_C_DEFAULT)
                type = ODBCDefaultType(irdrec);
 
-       if (precision == UNAFFECTED ||
-           scale == UNAFFECTED ||
-           datetime_interval_precision == UNAFFECTED) {
+       if (precision == UNAFFECTED) {
+               precision = (ardrec) ? ardrec->sql_desc_precision : (type == 
SQL_C_NUMERIC) ? 10 : 6;
+       }
+       if (scale == UNAFFECTED) {
+               scale = (ardrec) ? ardrec->sql_desc_scale : 0;
+       }
+       if (datetime_interval_precision == UNAFFECTED) {
                if (ardrec) {
-                       if (precision == UNAFFECTED)
-                               precision = ardrec->sql_desc_precision;
-                       if (scale == UNAFFECTED)
-                               scale = ardrec->sql_desc_scale;
-                       if (datetime_interval_precision == UNAFFECTED)
-                               datetime_interval_precision = 
ardrec->sql_desc_datetime_interval_precision;
+                       datetime_interval_precision = 
ardrec->sql_desc_datetime_interval_precision;
                } else {
-                       if (precision == UNAFFECTED)
-                               precision = type == SQL_C_NUMERIC ? 10 : 6;
-                       if (scale == UNAFFECTED)
-                               scale = 0;
-                       if (datetime_interval_precision == UNAFFECTED)
+                       switch (type) {
+                       case SQL_C_INTERVAL_YEAR:
+                               datetime_interval_precision = 4;
+                               break;
+                       case SQL_C_INTERVAL_YEAR_TO_MONTH:
+                       case SQL_C_INTERVAL_MONTH:
+                               datetime_interval_precision = 6;
+                               break;
+                       case SQL_C_INTERVAL_DAY:
+                       case SQL_C_INTERVAL_DAY_TO_HOUR:
+                       case SQL_C_INTERVAL_DAY_TO_MINUTE:
+                       case SQL_C_INTERVAL_DAY_TO_SECOND:
+                       case SQL_C_INTERVAL_HOUR:
+                       case SQL_C_INTERVAL_HOUR_TO_MINUTE:
+                       case SQL_C_INTERVAL_HOUR_TO_SECOND:
+                       case SQL_C_INTERVAL_MINUTE:
+                       case SQL_C_INTERVAL_MINUTE_TO_SECOND:
+                       case SQL_C_INTERVAL_SECOND:
+                               datetime_interval_precision = 9;
+                               break;
+                       default:
                                datetime_interval_precision = 2;
+                       }
                }
        }
        i = datetime_interval_precision;
diff --git a/clients/odbc/tests/ODBCtester.c b/clients/odbc/tests/ODBCtester.c
--- a/clients/odbc/tests/ODBCtester.c
+++ b/clients/odbc/tests/ODBCtester.c
@@ -269,7 +269,7 @@ testGetDataGUID(SQLHANDLE stmt)
                        pos += snprintf(outp + pos, outp_len - pos, "NULL\n");
                else
                        pos += snprintf(outp + pos, outp_len - pos, 
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
-                                       (unsigned int) guid_val.Data1, 
guid_val.Data2, guid_val.Data3,
+                               guid_val.Data1, guid_val.Data2, guid_val.Data3,
                                guid_val.Data4[0], guid_val.Data4[1], 
guid_val.Data4[2], guid_val.Data4[3], guid_val.Data4[4], guid_val.Data4[5], 
guid_val.Data4[6], guid_val.Data4[7]);
                check(ret, SQL_HANDLE_STMT, stmt, "SQLGetData(col)");
        }
@@ -297,6 +297,118 @@ testGetDataGUID(SQLHANDLE stmt)
        return ret;
 }
 
+static SQLRETURN
+testGetDataIntervalDay(SQLHANDLE stmt, int sqlquery)
+{
+       SQLRETURN ret;
+       SQLLEN RowCount = 0;
+       SWORD NumResultCols = 0;
+
+       size_t outp_len = 1800;
+       char * outp = malloc(outp_len);
+       size_t pos = 0;
+
+       char * sql1 = "select cast(NULL as interval day) as valnil, cast('99' 
as interval day) as val1, cast('-99' as interval day) as val2;";
+       char * sql2 = "select cast(NULL as interval day) as valnil, cast('101' 
as interval day) as val1, cast('-102' as interval day) as val2;";        /* 
Interval field overflow */
+       ret = SQLExecDirect(stmt, (sqlquery == 1) ? (SQLCHAR *) sql1 : (SQLCHAR 
*) sql2, SQL_NTS);
+       pos += snprintf(outp + pos, outp_len - pos, "SQLExecDirect query %d\n", 
sqlquery);
+       check(ret, SQL_HANDLE_STMT, stmt, "SQLExecDirect");
+
+       ret = SQLRowCount(stmt, &RowCount);
+       pos += snprintf(outp + pos, outp_len - pos, "SQLRowCount is " LLFMT 
"\n", (int64_t) RowCount);
+       check(ret, SQL_HANDLE_STMT, stmt, "SQLRowCount");
+
+       ret = SQLNumResultCols(stmt, &NumResultCols);
+       pos += snprintf(outp + pos, outp_len - pos, "SQLNumResultCols is %d\n", 
NumResultCols);
+       check(ret, SQL_HANDLE_STMT, stmt, "SQLNumResultCols");
+
+       ret = SQLFetch(stmt);
+       pos += snprintf(outp + pos, outp_len - pos, "SQLFetch\n");
+       check(ret, SQL_HANDLE_STMT, stmt, "SQLFetch");
+
+       for (SWORD col = 1; col <= NumResultCols; col++) {
+               char buf[99];
+               char str_val[42];
+               int int_val;
+               SQL_INTERVAL_STRUCT itv_val;
+               SQLLEN vallen = 0;
+               SQLLEN NumAttr = 0;
+
+               /* retrieve query result column metadata */
+               ret = SQLColAttribute(stmt, (UWORD)col, SQL_DESC_CONCISE_TYPE, 
(PTR)&buf, (SQLLEN)20, NULL, &NumAttr);
+               pos += snprintf(outp + pos, outp_len - pos, 
"SQLColAttribute(%d, SQL_DESC_CONCISE_TYPE) returns %d, NumAttr " LLFMT "\n", 
col, ret, (int64_t) NumAttr);
+               ret = SQLColAttribute(stmt, (UWORD)col, SQL_DESC_DISPLAY_SIZE, 
(PTR)&buf, (SQLLEN)20, NULL, &NumAttr);
+               pos += snprintf(outp + pos, outp_len - pos, 
"SQLColAttribute(%d, SQL_DESC_DISPLAY_SIZE) returns %d, NumAttr " LLFMT "\n", 
col, ret, (int64_t) NumAttr);
+
+               /* test SQLGetData(SQL_C_CHAR) */
+               ret = SQLGetData(stmt, (UWORD)col, (SWORD)SQL_C_CHAR, 
(PTR)&str_val, (SQLLEN)41, &vallen);
+               pos += snprintf(outp + pos, outp_len - pos, "SQLGetData(%d, 
SQL_C_CHAR, 41) returns %d, vallen " LLFMT ", str_val: '%s'\n",
+                       col, ret, (int64_t) vallen, (vallen == SQL_NULL_DATA) ? 
"NULL" : str_val);
+               check(ret, SQL_HANDLE_STMT, stmt, "SQLGetData(col) as str");
+
+               /* test SQLGetData(SQL_C_SLONG) */
+               ret = SQLGetData(stmt, (UWORD)col, (SWORD)SQL_C_SLONG, 
(PTR)&int_val, (SQLLEN)4, &vallen);
+               pos += snprintf(outp + pos, outp_len - pos, "SQLGetData(%d, 
SQL_C_SLONG) returns %d, vallen " LLFMT ", int_val: ", col, ret, (int64_t) 
vallen);
+               if (vallen == SQL_NULL_DATA)
+                       pos += snprintf(outp + pos, outp_len - pos, "NULL\n");
+               else
+                       pos += snprintf(outp + pos, outp_len - pos, "%d\n", 
int_val);
+               check(ret, SQL_HANDLE_STMT, stmt, "SQLGetData(col) as int");    
/* SQLstate 07006 Restricted data type attribute violation */
+
+               /* test SQLGetData(SQL_C_INTERVAL_DAY) */
+               ret = SQLGetData(stmt, (UWORD)col, (SWORD)SQL_C_INTERVAL_DAY, 
(PTR)&itv_val, (SQLLEN)sizeof(SQL_INTERVAL_STRUCT), &vallen);
+               pos += snprintf(outp + pos, outp_len - pos, "SQLGetData(%d, 
SQL_C_INTERVAL_DAY) returns %d, vallen " LLFMT ", itv_day_val: ", col, ret, 
(int64_t) vallen);
+               if (vallen == SQL_NULL_DATA)
+                       pos += snprintf(outp + pos, outp_len - pos, "NULL\n");
+               else
+                       pos += snprintf(outp + pos, outp_len - pos, "%d (type 
%d, sign %d)\n", itv_val.intval.day_second.day, itv_val.interval_type, 
itv_val.interval_sign);
+               check(ret, SQL_HANDLE_STMT, stmt, "SQLGetData(col) as int");
+       }
+
+       compareResult("testGetDataIntervalDay()", outp,
+               (sqlquery == 1)
+               ?       "SQLExecDirect query 1\nSQLRowCount is 
1\nSQLNumResultCols is 3\nSQLFetch\n"
+                       "SQLColAttribute(1, SQL_DESC_CONCISE_TYPE) returns 0, 
NumAttr 103\n"
+                       "SQLColAttribute(1, SQL_DESC_DISPLAY_SIZE) returns 0, 
NumAttr 21\n"
+                       "SQLGetData(1, SQL_C_CHAR, 41) returns 0, vallen -1, 
str_val: 'NULL'\n"
+                       "SQLGetData(1, SQL_C_SLONG) returns 0, vallen -1, 
int_val: NULL\n"
+                       "SQLGetData(1, SQL_C_INTERVAL_DAY) returns 0, vallen 
-1, itv_day_val: NULL\n"
+                       "SQLColAttribute(2, SQL_DESC_CONCISE_TYPE) returns 0, 
NumAttr 103\n"
+                       "SQLColAttribute(2, SQL_DESC_DISPLAY_SIZE) returns 0, 
NumAttr 21\n"
+                       "SQLGetData(2, SQL_C_CHAR, 41) returns 0, vallen 17, 
str_val: 'INTERVAL '99' DAY'\n"
+                       "SQLGetData(2, SQL_C_SLONG) returns 0, vallen 4, 
int_val: 99\n" /* SQLstate 07006 Restricted data type attribute violation */
+                       "SQLGetData(2, SQL_C_INTERVAL_DAY) returns 0, vallen 
28, itv_day_val: 99 (type 3, sign 0)\n"
+                       "SQLColAttribute(3, SQL_DESC_CONCISE_TYPE) returns 0, 
NumAttr 103\n"
+                       "SQLColAttribute(3, SQL_DESC_DISPLAY_SIZE) returns 0, 
NumAttr 21\n"
+                       "SQLGetData(3, SQL_C_CHAR, 41) returns 0, vallen 18, 
str_val: 'INTERVAL -'99' DAY'\n"
+                       "SQLGetData(3, SQL_C_SLONG) returns 0, vallen 4, 
int_val: -99\n"        /* SQLstate 07006 Restricted data type attribute 
violation */
+                       "SQLGetData(3, SQL_C_INTERVAL_DAY) returns 0, vallen 
28, itv_day_val: 99 (type 3, sign 1)\n"
+               :       "SQLExecDirect query 2\nSQLRowCount is 
1\nSQLNumResultCols is 3\nSQLFetch\n"
+                       "SQLColAttribute(1, SQL_DESC_CONCISE_TYPE) returns 0, 
NumAttr 103\n"
+                       "SQLColAttribute(1, SQL_DESC_DISPLAY_SIZE) returns 0, 
NumAttr 21\n"
+                       "SQLGetData(1, SQL_C_CHAR, 41) returns 0, vallen -1, 
str_val: 'NULL'\n"
+                       "SQLGetData(1, SQL_C_SLONG) returns 0, vallen -1, 
int_val: NULL\n"
+                       "SQLGetData(1, SQL_C_INTERVAL_DAY) returns 0, vallen 
-1, itv_day_val: NULL\n"
+                       "SQLColAttribute(2, SQL_DESC_CONCISE_TYPE) returns 0, 
NumAttr 103\n"
+                       "SQLColAttribute(2, SQL_DESC_DISPLAY_SIZE) returns 0, 
NumAttr 21\n"
+                       "SQLGetData(2, SQL_C_CHAR, 41) returns 0, vallen 18, 
str_val: 'INTERVAL '101' DAY'\n"
+                       "SQLGetData(2, SQL_C_SLONG) returns 0, vallen 4, 
int_val: 101\n"        /* SQLstate 07006 Restricted data type attribute 
violation */
+                       "SQLGetData(2, SQL_C_INTERVAL_DAY) returns 0, vallen 
28, itv_day_val: 101 (type 3, sign 0)\n"   /* SQLstate 22015 Interval field 
overflow */
+                       "SQLColAttribute(3, SQL_DESC_CONCISE_TYPE) returns 0, 
NumAttr 103\n"
+                       "SQLColAttribute(3, SQL_DESC_DISPLAY_SIZE) returns 0, 
NumAttr 21\n"
+                       "SQLGetData(3, SQL_C_CHAR, 41) returns 0, vallen 19, 
str_val: 'INTERVAL -'102' DAY'\n"
+                       "SQLGetData(3, SQL_C_SLONG) returns 0, vallen 4, 
int_val: -102\n"       /* SQLstate 07006 Restricted data type attribute 
violation */
+                       "SQLGetData(3, SQL_C_INTERVAL_DAY) returns 0, vallen 
28, itv_day_val: 102 (type 3, sign 1)\n"   /* SQLstate 22015 Interval field 
overflow */
+               );
+
+       ret = SQLCloseCursor(stmt);
+       check(ret, SQL_HANDLE_STMT, stmt, "SQLCloseCursor");
+
+       /* cleanup */
+       free(outp);
+       return ret;
+}
+
 int
 main(int argc, char **argv)
 {
@@ -351,6 +463,12 @@ main(int argc, char **argv)
        ret = testGetDataGUID(stmt);
        check(ret, SQL_HANDLE_STMT, stmt, "testGetDataGUID(STMT)");
 
+       ret = testGetDataIntervalDay(stmt, 1);
+       check(ret, SQL_HANDLE_STMT, stmt, "testGetDataIntervalDay(STMT, 99, 
-99)");
+
+       ret = testGetDataIntervalDay(stmt, 2);
+       check(ret, SQL_HANDLE_STMT, stmt, "testGetDataIntervalDay(STMT, 101, 
-102)");
+
        /* cleanup */
        ret = SQLFreeHandle(SQL_HANDLE_STMT, stmt);
        check(ret, SQL_HANDLE_STMT, stmt, "SQLFreeHandle (STMT)");
diff --git a/sql/test/proto_loader/odbc/Tests/monetodbc_datatypes.test 
b/sql/test/proto_loader/odbc/Tests/monetodbc_datatypes.test
--- a/sql/test/proto_loader/odbc/Tests/monetodbc_datatypes.test
+++ b/sql/test/proto_loader/odbc/Tests/monetodbc_datatypes.test
@@ -137,14 +137,14 @@ 12345678901234567890.123456789
 
 onlyif has-hugeint
 query I
-select cast(-92345678901234567890123456789.123456789 as decimal(38,9)) as 
dec16_val
+select cast(-923456789012345678901234567890.12345678 as decimal(38,8)) as 
dec16_val
 ----
--92345678901234567890123456789
+-923456789012345678901234567890
 
 --query T
---select * from 'odbc:DSN=MonetDB-Test;QUERY=select 
cast(-92345678901234567890123456789.123456789 as decimal(38,9)) as dec16_val'
+--select * from 'odbc:DSN=MonetDB-Test;QUERY=select 
cast(-923456789012345678901234567890.12345678 as decimal(38,8)) as dec16_val'
 ----
--- -92345678901234567890123456789.123456789
+-- -923456789012345678901234567890.12345678
 
 ---- REAL ----
 
@@ -308,6 +308,48 @@ select * from 'odbc:DSN=MonetDB-Test;QUE
 99
 -99
 
+query TT
+select * from 'odbc:DSN=MonetDB-Test;QUERY=select cast(''99'' as interval day) 
as val1, cast(''-99'' as interval day) as val2'
+----
+99
+-99
+
+query II
+select * from 'odbc:DSN=MonetDB-Test;QUERY=select cast(''101'' as interval 
day) as val1, cast(''-102'' as interval day) as val2'
+----
+101
+-102
+
+query RR
+select * from 'odbc:DSN=MonetDB-Test;QUERY=select cast(''101'' as interval 
day) as val1, cast(''-102'' as interval day) as val2'
+----
+101.000
+-102.000
+
+query TT
+select * from 'odbc:DSN=MonetDB-Test;QUERY=select cast(''101'' as interval 
day) as val1, cast(''-102'' as interval day) as val2'
+----
+101
+-102
+
+query II
+select * from 'odbc:DSN=MonetDB-Test;QUERY=select cast(''9101'' as interval 
day) as val1, cast(''-9102'' as interval day) as val2'
+----
+9101
+-9102
+
+query RR
+select * from 'odbc:DSN=MonetDB-Test;QUERY=select cast(''9101'' as interval 
day) as val1, cast(''-9102'' as interval day) as val2'
+----
+9101.000
+-9102.000
+
+query TT
+select * from 'odbc:DSN=MonetDB-Test;QUERY=select cast(''9101'' as interval 
day) as val1, cast(''-9102'' as interval day) as val2'
+----
+9101
+-9102
+
 query TTTT
 select cast('32' as interval hour) as val1, cast('-32' as interval hour) as 
val2, cast('0' as interval hour) as val0, cast(NULL as interval hour) as valnil
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to