Changeset: 390eb7881467 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/390eb7881467 Modified Files: sql/backends/monet5/rel_bin.c Branch: reducedstack Log Message:
merged with default diffs (truncated from 1517 to 300 lines): diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out --- a/clients/Tests/exports.stable.out +++ b/clients/Tests/exports.stable.out @@ -1663,6 +1663,7 @@ list *sa_list(allocator *sa); char *sa_message(allocator *sa, _In_z_ _Printf_format_string_ const char *format, ...) __attribute__((__format__(__printf__, 2, 3))); msettings *sa_msettings_create(allocator *sa); char *sa_msettings_to_string(const msettings *mp, allocator *sa, size_t size_hint); +sql_type *schema_bind_type(mvc *sql, sql_schema *s, const char *name); str sht_dec2_bte(bte *res, const int *s1, const sht *v); str sht_dec2_dbl(dbl *res, const int *s1, const sht *v); str sht_dec2_flt(flt *res, const int *s1, const sht *v); diff --git a/common/stream/monetdb-stream.pc.in b/common/stream/monetdb-stream.pc.in --- a/common/stream/monetdb-stream.pc.in +++ b/common/stream/monetdb-stream.pc.in @@ -16,7 +16,7 @@ Name: monetdb-stream Description: MonetDB streams library URL: https://www.monetdb.org/ Version: @MONETDB_VERSION@ -Requires.private: monetdb-utils = @MONETDB_VERSION@ @PKG_ZLIB@ @PKG_BZIP2@ @PKG_LZMA@ +Requires.private: monetdb-mutils = @MONETDB_VERSION@ @PKG_ZLIB@ @PKG_BZIP2@ @PKG_LZMA@ Libs: -L${libdir} -lstream-@MONETDB_VERSION@ Libs.private: @SOCKET_LIBS@ diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c --- a/gdk/gdk_bbp.c +++ b/gdk/gdk_bbp.c @@ -503,6 +503,19 @@ heapinit(BAT *b, const char *buf, TRC_CRITICAL(GDK, "type wkba (SQL name: GeometryA) has been removed\n"); return -1; } +#ifdef HAVE_GEOM +#if GDKLIBRARY <= 061050U + if (strcmp(type, "wkb") == 0) { + /* don't trust properties having to do with ordering of + * type wkb because of a bug in the wkbCOMP + * implementation; this was fixed during the lifetime of + * BBP version 061050 */ + minpos = maxpos = oid_nil; + nosorted = norevsorted = 0; + properties &= ~0x0081; + } +#endif +#endif if (properties & ~0x1F81) { TRC_CRITICAL(GDK, "unknown properties are set: incompatible database on line %d of BBP.dir\n", lineno); diff --git a/gdk/gdk_project.c b/gdk/gdk_project.c --- a/gdk/gdk_project.c +++ b/gdk/gdk_project.c @@ -745,12 +745,12 @@ BATproject2(BAT *restrict l, BAT *restri bn->tnonil = li.nonil & r1i.nonil; bn->tsorted = li.count <= 1 || (li.sorted & r1i.sorted) - || (li.revsorted & r1i.revsorted) - || r1i.count <= 1; + || (li.revsorted & r1i.revsorted & li.nonil) + || (r1i.count <= 1 && li.nonil); bn->trevsorted = li.count <= 1 - || (li.sorted & r1i.revsorted) + || (li.sorted & r1i.revsorted & li.nonil) || (li.revsorted & r1i.sorted) - || r1i.count <= 1; + || (r1i.count <= 1 && li.nonil); bn->tkey = li.count <= 1 || (li.key & r1i.key); } diff --git a/geom/monetdb5/geom_atoms.c b/geom/monetdb5/geom_atoms.c --- a/geom/monetdb5/geom_atoms.c +++ b/geom/monetdb5/geom_atoms.c @@ -135,7 +135,7 @@ wkbCOMP(const void *L, const void *R) const wkb *l = L, *r = R; if (l->srid != r->srid) - return -1; + return l->srid - r->srid; int len = l->len; diff --git a/sql/ChangeLog.Mar2025 b/sql/ChangeLog.Mar2025 --- a/sql/ChangeLog.Mar2025 +++ b/sql/ChangeLog.Mar2025 @@ -1,3 +1,6 @@ # ChangeLog file for sql # This file is updated with Maddlog +* Thu Mar 20 2025 Martin van Dinther <[email protected]> +- Added scalar functions: dayname(d date) and monthname(d date) returns varchar(10). + diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c --- a/sql/backends/monet5/rel_bin.c +++ b/sql/backends/monet5/rel_bin.c @@ -6760,6 +6760,7 @@ rel2bin_update(backend *be, sql_rel *rel node *m; sql_rel *tr = rel->l, *prel = rel->r; sql_table *t = NULL; + bool needs_returning = rel->returning; if ((rel->flag&UPD_COMP)) { /* special case ! */ idx_ups = 1; @@ -6859,7 +6860,7 @@ rel2bin_update(backend *be, sql_rel *rel } stmt* returning = NULL; - if (rel->returning) { + if (needs_returning) { sql_rel* b = rel->l; int refcnt = b->ref.refcnt; // HACK: forces recalculation of base columns since they are assumed to be updated b->ref.refcnt = 1; 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 @@ -56,6 +56,9 @@ typedef struct { SQLSMALLINT decimalDigits; /* ODBC dec. digits, contains scale for decimals */ int battype; /* MonetDB atom type, used to create the BAT */ BAT * bat; /* MonetDB BAT */ + SQLSMALLINT targetType; /* needed for SQLGetData */ + SQLPOINTER * targetValuePtr; /* needed for SQLGetData */ + SQLLEN bufferLength; /* needed for SQLGetData */ } rescol_t; /* map ODBC SQL datatype to MonetDB SQL datatype */ @@ -104,6 +107,26 @@ map_rescol_type(SQLSMALLINT dataType, SQ // prec = scale; /* make precision large enough to contain all decimal digits */ // return sql_bind_subtype(sql->sa, "decimal", prec, scale); } + case SQL_GUID: + { + /* represents a uuid of length 36, such as: dbe7343c-1f11-4fa9-a9c8-a31cd26f92fe */ + sql_subtype * tp = sql_bind_subtype(sql->sa, "uuid", 0, 0); // this fails to return a valid pointer + if (tp != NULL) + return tp; + // try a different way + sql_schema *syss = mvc_bind_schema(sql, "sys"); + if (syss) { + tp = SA_ZNEW(sql->sa, sql_subtype); + if (tp != NULL) { + tp->digits = tp->scale = 0; + tp->type = schema_bind_type(sql, syss, "uuid"); + if (tp->type != NULL) + return tp; + } + } + /* fall back to map it to a char(36) result column type */ + return sql_bind_subtype(sql->sa, "char", (unsigned int) UUID_STRLEN, 0); + } case SQL_BIT: typenm = "boolean"; @@ -205,11 +228,6 @@ map_rescol_type(SQLSMALLINT dataType, SQ typenm = "sec_interval"; interval_type = 12; break; - - case SQL_GUID: - /* represents a uuid of length 36, such as: dbe7343c-1f11-4fa9-a9c8-a31cd26f92fe */ - typenm = "uuid"; - break; } return sql_bind_subtype(sql->sa, typenm, interval_type, 0); } @@ -323,6 +341,12 @@ getErrMsg(SQLSMALLINT handleType, SQLHAN ret = SQLGetDiagRec(handleType, handle, 1, state, &errnr, msg, SQL_MAX_MESSAGE_LENGTH -1, &msglen); if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) { const char format[] = "SQLSTATE %s, Error code %d, Message %s"; + /* ignore msg when using MS Excel ODBC driver, which does not support setting connection timeout */ + if ((strcmp("IM006", (char *)state) == 0) + && (strcmp("[Microsoft][ODBC Driver Manager] Driver's SQLSetConnectAttr failed", (char *)msg) == 0)) { + return NULL; + } + if (msglen <= 0) { /* e.g SQL_NTS */ msglen = (SQLSMALLINT) strlen((char *)msg); @@ -383,6 +407,35 @@ bat_create(int adt, BUN nr) return b; } +/* convert interval.day_second.fraction values to millisec fractions as needed by MonetDB interval types. + * we need the columns decimalDigits specification to adjust the fractions value to millisec. + */ +static SQLUINTEGER +fraction2msec(SQLUINTEGER fraction, SQLSMALLINT decimaldigits) { + SQLUINTEGER msec = fraction; + if (msec == 0) + return 0; + + switch (decimaldigits) { + case 6: msec = fraction / 1000; break; + case 3: msec = fraction; break; + case 0: msec = fraction * 1000; break; + case 1: msec = fraction * 100; break; + case 2: msec = fraction * 10; break; + case 4: msec = fraction / 10; break; + case 5: msec = fraction / 100; break; + case 7: msec = fraction / 10000; break; + case 8: msec = fraction / 100000; break; + case 9: msec = fraction / 1000000; break; + } + + // millisec value should be no larger than 999 + while (msec > 999) { + msec = msec / 10; + } + return msec; +} + /* * odbc_query() contains the logic for both odbc_relation() and ODBCloader() * the caller argument is ODBC_RELATION when called from odbc_relation and ODBC_LOADER when called from ODBCloader @@ -390,8 +443,6 @@ bat_create(int adt, BUN nr) static str odbc_query(int caller, mvc *sql, sql_subfunc *f, char *url, list *res_exps, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { - bool trace_enabled = false; /* used for development only */ - if (sql == NULL) return "Missing mvc value."; if (f == NULL) @@ -417,8 +468,10 @@ odbc_query(int caller, mvc *sql, sql_sub return "Incomplete ODBC URI string. Missing 'QUERY=' part to specify the SQL SELECT query to execute."; char * query = GDKstrdup(&qry_str[6]); // we expect that QUERY= is at the end of the connection string - if (query == NULL || (query && (strcmp("", query) == 0))) + if (query == NULL || *query == 0) { + GDKfree(query); return "Incomplete ODBC URI string. Missing SQL SELECT query after 'QUERY='."; + } // create a new ODBC connection string without the QUERY= part char * odbc_con_str = GDKstrndup(con_str, qry_str - con_str); @@ -427,9 +480,7 @@ odbc_query(int caller, mvc *sql, sql_sub return "Missing ODBC connection string."; } - // trace_enabled = true; - if (trace_enabled) - printf("\nExtracted ODBC connection string: %s\n and SQL query: %s\n", odbc_con_str, query); + TRC_INFO(LOADER, "\nExtracted ODBC connection string: %s\n and SQL query: %s\n", odbc_con_str, query); /* now we can (try to) connect to the ODBC driver and execute the SQL query */ SQLRETURN ret = SQL_INVALID_HANDLE; @@ -476,11 +527,11 @@ odbc_query(int caller, mvc *sql, sql_sub if (ret == SQL_SUCCESS_WITH_INFO && caller == ODBC_RELATION) { /* show the info warning, but only once */ char * ODBCmsg = getErrMsg(SQL_HANDLE_DBC, dbc); - printf("SQLDriverConnect(%s) returned %s ODBCmsg: %s\n", odbc_con_str, nameOfRetCode(ret), (ODBCmsg) ? ODBCmsg : ""); + TRC_INFO(LOADER, "SQLDriverConnect(%s) returned %s ODBCmsg: %s\n", odbc_con_str, nameOfRetCode(ret), (ODBCmsg) ? ODBCmsg : ""); if (ODBCmsg) GDKfree(ODBCmsg); - } else if (trace_enabled) { - printf("SQLDriverConnect(%s) returned %s\n", odbc_con_str, nameOfRetCode(ret)); + } else { + TRC_DEBUG(LOADER, "SQLDriverConnect(%s) returned %s\n", odbc_con_str, nameOfRetCode(ret)); } if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) { errmsg = "SQLDriverConnect failed."; @@ -501,13 +552,11 @@ odbc_query(int caller, mvc *sql, sql_sub char DBMSname[128]; ret = SQLGetInfo(dbc, SQL_DBMS_NAME, (SQLPOINTER) &DBMSname, 127, NULL); if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) { - if (trace_enabled) - printf("SQLGetInfo(dbc, SQL_DBMS_NAME) returned %s\n", DBMSname); + TRC_DEBUG(LOADER, "SQLGetInfo(dbc, SQL_DBMS_NAME) returned %s\n", DBMSname); if (strcmp("MonetDB", DBMSname) == 0) { - /* enable the MonetDB ODBC driver to return SQL_HUGEINT as column datatype */ + /* instruct the MonetDB ODBC driver to return SQL_HUGEINT as column datatype */ ret = SQLGetTypeInfo(stmt, SQL_HUGEINT); - if (trace_enabled) - printf("SQLGetTypeInfo(stmt, SQL_HUGEINT) returned %s\n", nameOfRetCode(ret)); + TRC_DEBUG(LOADER, "SQLGetTypeInfo(stmt, SQL_HUGEINT) returned %s\n", nameOfRetCode(ret)); if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) { ret = SQLCloseCursor(stmt); } @@ -527,11 +576,11 @@ odbc_query(int caller, mvc *sql, sql_sub if (ret == SQL_SUCCESS_WITH_INFO && caller == ODBC_RELATION) { /* show the info warning, but only once */ char * ODBCmsg = getErrMsg(SQL_HANDLE_STMT, stmt); - printf("SQLExecDirect(%s) returned %s ODBCmsg: %s\n", query, nameOfRetCode(ret), (ODBCmsg) ? ODBCmsg : ""); + TRC_INFO(LOADER, "SQLExecDirect(%s) returned %s ODBCmsg: %s\n", query, nameOfRetCode(ret), (ODBCmsg) ? ODBCmsg : ""); if (ODBCmsg) GDKfree(ODBCmsg); - } else if (trace_enabled) { - printf("SQLExecDirect(%s) returned %s\n", query, nameOfRetCode(ret)); + } else { + TRC_DEBUG(LOADER, "SQLExecDirect(%s) returned %s\n", query, nameOfRetCode(ret)); } if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) { errmsg = "SQLExecDirect query failed."; @@ -551,12 +600,11 @@ odbc_query(int caller, mvc *sql, sql_sub errmsg = "ODBC query did not return a resultset."; goto finish; } - if (trace_enabled) - printf("Query has %d result columns\n", nr_cols); + TRC_INFO(LOADER, "Query has %d result columns\n", nr_cols); if (nr_cols > QUERY_MAX_COLUMNS) { /* limit the number of data columns, as we do not want to block or blow up the mserver */ nr_cols = QUERY_MAX_COLUMNS; - printf("\nODBC_loader limited Query result to first %d columns.\n", nr_cols); + TRC_INFO(LOADER, "ODBC_loader limited Query result to first %d columns.\n", nr_cols); _______________________________________________ checkin-list mailing list -- [email protected] To unsubscribe send an email to [email protected]
