Changeset: 0a5e42d415dd for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0a5e42d415dd Modified Files: clients/mapiclient/mclient.c clients/mapilib/mapi.c clients/mapilib/mapi.h sql/backends/monet5/sql_scenario.c Branch: mapihandshake Log Message:
Also pass the time zone diffs (231 lines): diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c --- a/clients/mapiclient/mclient.c +++ b/clients/mapiclient/mclient.c @@ -2893,75 +2893,6 @@ doFile(Mapi mid, stream *fp, bool useins return errseen; } -static void -set_timezone(Mapi mid) -{ - char buf[128]; - int tzone; - MapiHdl hdl; - - /* figure out our current timezone */ -#if defined HAVE_GETDYNAMICTIMEZONEINFORMATION - DYNAMIC_TIME_ZONE_INFORMATION tzinf; - - /* documentation says: UTC = localtime + Bias (in minutes), - * but experimentation during DST period says, UTC = localtime - * + Bias + DaylightBias, and presumably during non DST - * period, UTC = localtime + Bias */ - switch (GetDynamicTimeZoneInformation(&tzinf)) { - case TIME_ZONE_ID_STANDARD: - case TIME_ZONE_ID_UNKNOWN: - tzone = (int) tzinf.Bias * 60; - break; - case TIME_ZONE_ID_DAYLIGHT: - tzone = (int) (tzinf.Bias + tzinf.DaylightBias) * 60; - break; - default: - /* call failed, we don't know the time zone */ - tzone = 0; - break; - } -#elif defined HAVE_STRUCT_TM_TM_ZONE - time_t t; - struct tm *tmp; - - t = time(NULL); - tmp = localtime(&t); - tzone = (int) -tmp->tm_gmtoff; -#else - time_t t, lt, gt; - struct tm *tmp; - - t = time(NULL); - tmp = gmtime(&t); - gt = mktime(tmp); - tmp = localtime(&t); - tmp->tm_isdst=0; /* We need the difference without dst */ - lt = mktime(tmp); - assert((int64_t) gt - (int64_t) lt >= (int64_t) INT_MIN && (int64_t) gt - (int64_t) lt <= (int64_t) INT_MAX); - tzone = (int) (gt - lt); -#endif - if (tzone < 0) - snprintf(buf, sizeof(buf), - "SET TIME ZONE INTERVAL '+%02d:%02d' HOUR TO MINUTE", - -tzone / 3600, (-tzone % 3600) / 60); - else - snprintf(buf, sizeof(buf), - "SET TIME ZONE INTERVAL '-%02d:%02d' HOUR TO MINUTE", - tzone / 3600, (tzone % 3600) / 60); - if ((hdl = mapi_query(mid, buf)) == NULL) { - if (formatter == TABLEformatter) { - mapi_noexplain(mid, ""); - } else { - mapi_noexplain(mid, NULL); - } - mapi_explain(mid, stderr); - errseen = true; - return; - } - mapi_close_handle(hdl); -} - struct privdata { stream *f; char *buf; @@ -3541,6 +3472,8 @@ main(int argc, char **argv) mapi_cache_limit(mid, -1); mapi_setAutocommit(mid, autocommit); + if (mode == SQL && !settz) + mapi_set_time_zone(mid, 0); if (mid && mapi_error(mid) == MOK) mapi_reconnect(mid); /* actually, initial connect */ @@ -3616,9 +3549,6 @@ main(int argc, char **argv) mapi_get_autocommit(mid) ? "on" : "off"); } - if (mode == SQL && settz) - set_timezone(mid); - if (command != NULL) { #if !defined(_MSC_VER) && defined(HAVE_ICONV) /* no need on Windows: using wmain interface */ diff --git a/clients/mapilib/mapi.c b/clients/mapilib/mapi.c --- a/clients/mapilib/mapi.c +++ b/clients/mapilib/mapi.c @@ -883,6 +883,7 @@ struct MapiStruct { bool auto_commit; bool columnar_protocol; bool sizeheader; + int time_zone; /* seconds EAST of UTC */ MapiHdl first; /* start of doubly-linked list */ MapiHdl active; /* set when not all rows have been received */ @@ -1382,6 +1383,13 @@ mapi_get_columnar_protocol(Mapi mid) return mid->columnar_protocol; } +int +mapi_get_time_zone(Mapi mid) +{ + mapi_check0(mid); + return mid->time_zone; +} + static int64_t usec(void) { @@ -1898,6 +1906,16 @@ mapi_new(void) mid->blk.buf[0] = 0; mid->blk.buf[mid->blk.lim] = 0; + /* also the current timezone, seconds EAST of UTC */ + time_t t = time(NULL); + struct tm *gm_tm = gmtime_r(&t, &(struct tm){0}); + time_t gt = mktime(gm_tm); + struct tm *local_tm = localtime_r(&t, &(struct tm){0}); + local_tm->tm_isdst=0; /* We need the difference without dst */ + time_t lt = mktime(local_tm); + assert((int64_t) gt - (int64_t) lt >= (int64_t) INT_MIN && (int64_t) gt - (int64_t) lt <= (int64_t) INT_MAX); + mid->time_zone = (int) (lt - gt); + return mid; } @@ -2786,6 +2804,8 @@ mapi_reconnect(Mapi mid) if (mid->handshake_options > MAPI_HANDSHAKE_SIZE_HEADER) { CHECK_SNPRINTF(",size_header=%d", mid->sizeheader); // with underscore, despite X command without } + if (mid->handshake_options > MAPI_HANDSHAKE_TIME_ZONE) { + CHECK_SNPRINTF(",time_zone=%d", mid->time_zone); } if (mid->handshake_options > 0) { CHECK_SNPRINTF(":"); @@ -3009,6 +3029,9 @@ mapi_reconnect(Mapi mid) if (result != MOK) return mid->error; } + if (mid->handshake_options <= MAPI_HANDSHAKE_TIME_ZONE) { + mapi_set_time_zone(mid, mid->time_zone); + } return mid->error; } @@ -3705,6 +3728,31 @@ mapi_setAutocommit(Mapi mid, bool autoco } MapiMsg +mapi_set_time_zone(Mapi mid, int time_zone) +{ + mid->time_zone = time_zone; + if (!mid->connected) + return MOK; + + char buf[100]; + if (time_zone < 0) + snprintf(buf, sizeof(buf), + "SET TIME ZONE INTERVAL '-%02d:%02d' HOUR TO MINUTE", + -time_zone / 3600, (-time_zone % 3600) / 60); + else + snprintf(buf, sizeof(buf), + "SET TIME ZONE INTERVAL '+%02d:%02d' HOUR TO MINUTE", + time_zone / 3600, (time_zone % 3600) / 60); + + MapiHdl hdl = mapi_query(mid, buf); + if (hdl == NULL) + return mid->error; + mapi_close_handle(hdl); + + return MOK; +} + +MapiMsg mapi_set_columnar_protocol(Mapi mid, bool columnar_protocol) { if (mid->columnar_protocol == columnar_protocol) diff --git a/clients/mapilib/mapi.h b/clients/mapilib/mapi.h --- a/clients/mapilib/mapi.h +++ b/clients/mapilib/mapi.h @@ -31,6 +31,7 @@ enum mapi_handshake_options_levels { MAPI_HANDSHAKE_AUTOCOMMIT = 1, MAPI_HANDSHAKE_REPLY_SIZE, MAPI_HANDSHAKE_SIZE_HEADER, + MAPI_HANDSHAKE_TIME_ZONE, // this must always be the last one: MAPI_HANDSHAKE_OPTIONS_LEVEL, }; @@ -111,12 +112,16 @@ mapi_export stream *mapi_get_to(Mapi mid #endif mapi_export bool mapi_get_trace(Mapi mid) __attribute__((__nonnull__(1))); +mapi_export int mapi_get_time_zone(Mapi mid) + __attribute__((__nonnull__(1))); mapi_export bool mapi_get_autocommit(Mapi mid) __attribute__((__nonnull__(1))); mapi_export bool mapi_get_columnar_protocol(Mapi mid) __attribute__((__nonnull__(1))); mapi_export MapiMsg mapi_log(Mapi mid, const char *nme) __attribute__((__nonnull__(1))); +mapi_export MapiMsg mapi_set_time_zone(Mapi mid, int seconds_east_of_utc) + __attribute__((__nonnull__(1))); mapi_export MapiMsg mapi_setAutocommit(Mapi mid, bool autocommit) __attribute__((__nonnull__(1))); mapi_export MapiMsg mapi_set_columnar_protocol(Mapi mid, bool columnar_protocol) diff --git a/sql/backends/monet5/sql_scenario.c b/sql/backends/monet5/sql_scenario.c --- a/sql/backends/monet5/sql_scenario.c +++ b/sql/backends/monet5/sql_scenario.c @@ -296,6 +296,8 @@ SQLprepareClient(Client c, int login) m->reply_size = value; } else if (sscanf(tok, "size_header=%d", &value) == 1) { be->sizeheader = value != 0; + } else if (sscanf(tok, "time_zone=%d", &value) == 1) { + m->timezone = 1000 * value; } else { msg = createException(SQL, "SQLprepareClient", SQLSTATE(42000) "unexpected handshake option: %s", tok); goto bailout; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list