Changeset: 8918eaabdb67 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8918eaabdb67 Modified Files: clients/mapilib/mapi.c common/utils/conversion.c common/utils/conversion.h sql/backends/monet5/sql_result.c Branch: protocol Log Message:
Add support for timestamptz. diffs (179 lines): diff --git a/clients/mapilib/mapi.c b/clients/mapilib/mapi.c --- a/clients/mapilib/mapi.c +++ b/clients/mapilib/mapi.c @@ -833,6 +833,7 @@ struct MapiColumn { int typelen; int digits; int scale; + int timezone; void *null_value; char* buffer_ptr; char *dynamic_write_buf; @@ -944,6 +945,7 @@ struct MapiResultSet { struct MapiStatement *hdl; int tableid; /* SQL id of current result set */ int querytype; /* type of SQL query */ + int timezone; /* timezone of the result set */ mapi_int64 tuple_count; mapi_int64 row_count; mapi_int64 last_id; @@ -4100,7 +4102,15 @@ static char* mapi_convert_time(struct Ma static char* mapi_convert_timestamp(struct MapiColumn *col) { if (*((lng*) col->buffer_ptr) == *((lng*)col->null_value)) return NULL; - if (conversion_epoch_to_string(col->write_buf, COLBUFSIZ, (lng*) col->buffer_ptr, *((lng*)col->null_value), 0) < 0) { + if (conversion_epoch_to_string(col->write_buf, COLBUFSIZ, (lng*) col->buffer_ptr, *((lng*)col->null_value)) < 0) { + return NULL; + } + return (char*) col->write_buf; +} + +static char* mapi_convert_timestamptz(struct MapiColumn *col) { + if (*((lng*) col->buffer_ptr) == *((lng*)col->null_value)) return NULL; + if (conversion_epoch_tz_to_string(col->write_buf, COLBUFSIZ, (lng*) col->buffer_ptr, *((lng*)col->null_value), col->timezone) < 0) { return NULL; } return (char*) col->write_buf; @@ -4140,6 +4150,7 @@ read_into_cache(MapiHdl hdl, int lookahe switch (*line) { case 42: { int result_set_id; + int timezone; lng nr_rows; lng nr_cols; lng i; @@ -4154,7 +4165,8 @@ read_into_cache(MapiHdl hdl, int lookahe } if (!mnstr_readInt(mid->from, &result_set_id) || !mnstr_readLng(mid->from, &nr_rows) || - !mnstr_readLng(mid->from, &nr_cols)) { + !mnstr_readLng(mid->from, &nr_cols) || + !mnstr_readInt(mid->from, &timezone)) { return mid->error; } //fprintf(stderr, "result_set_id=%d, nr_rows=%llu, nr_cols=%lld\n", result_set_id, nr_rows, nr_cols); @@ -4270,6 +4282,9 @@ read_into_cache(MapiHdl hdl, int lookahe result->fields[i].converter = (mapi_converter) mapi_convert_time; } else if (strcasecmp(type_sql_name, "timestamp") == 0) { result->fields[i].converter = (mapi_converter) mapi_convert_timestamp; + } else if (strcasecmp(type_sql_name, "timestamptz") == 0) { + result->fields[i].timezone = timezone; + result->fields[i].converter = (mapi_converter) mapi_convert_timestamptz; } else if (typelen < 0) { /* any type besides the ones shown above should be converted to strings by the server */ result->fields[i].converter = (mapi_converter) mapi_convert_clob; } else { diff --git a/common/utils/conversion.c b/common/utils/conversion.c --- a/common/utils/conversion.c +++ b/common/utils/conversion.c @@ -287,8 +287,9 @@ conversion_time_to_string(char *dst, int static int days_between_zero_and_epoch = 719528; -int -conversion_epoch_to_string(char *dst, int len, const lng *src, lng null_value, int timezone_diff) { + +static int +conversion_epoch_optional_tz_to_string(char *dst, int len, const lng *src, lng null_value, int include_timezone, int timezone_diff) { int ms, sec, min, hour; int days = 0; lng time = *src; @@ -299,7 +300,7 @@ conversion_epoch_to_string(char *dst, in return 3; } // account for the timezone of the client - time += timezone_diff * 1000 * 60 * 60; + time += timezone_diff; ms = time % 1000 * 1000; time /= 1000; @@ -315,5 +316,24 @@ conversion_epoch_to_string(char *dst, in offset = conversion_date_to_string(dst, len, &days, -2147483647); if (offset < 0) return -1; + if (include_timezone) { + int original_diff = timezone_diff; + int diff_hour = timezone_diff / 3600000; + timezone_diff -= diff_hour * 3600000; + int diff_min = timezone_diff / 60000; + return snprintf(dst + offset, len - offset, " %02d:%02d:%02d.%06d%s%02d:%02d", hour, min, sec, ms, original_diff >= 0 ? "+" : "", diff_hour, diff_min); + } return snprintf(dst + offset, len - offset, " %02d:%02d:%02d.%06d", hour, min, sec, ms); } + +int +conversion_epoch_to_string(char *dst, int len, const lng *src, lng null_value) { + return conversion_epoch_optional_tz_to_string(dst, len, src, null_value, 0, 0); +} + +int +conversion_epoch_tz_to_string(char *dst, int len, const lng *src, lng null_value, int timezone_diff) { + return conversion_epoch_optional_tz_to_string(dst, len, src, null_value, 1, timezone_diff); +} + + diff --git a/common/utils/conversion.h b/common/utils/conversion.h --- a/common/utils/conversion.h +++ b/common/utils/conversion.h @@ -65,6 +65,9 @@ numeric_conversion(int, date); int conversion_time_to_string(char *dst, int len, const int *src, int null_value, int timezone_diff); // *src is time since epoch in ms -int conversion_epoch_to_string(char *dst, int len, const lng *src, lng null_value, int timezone_diff); +int conversion_epoch_to_string(char *dst, int len, const lng *src, lng null_value); + +// *src is time since epoch in ms +int conversion_epoch_tz_to_string(char *dst, int len, const lng *src, lng null_value, int timezone_diff); #endif diff --git a/sql/backends/monet5/sql_result.c b/sql/backends/monet5/sql_result.c --- a/sql/backends/monet5/sql_result.c +++ b/sql/backends/monet5/sql_result.c @@ -1819,7 +1819,7 @@ mvc_export_file(backend *b, stream *s, r return res; } -static int write_str_term(stream* s, str val) { +static int write_str_term(stream* s, const str val) { return mnstr_writeStr(s, val) && mnstr_writeBte(s, 0); } @@ -1827,8 +1827,7 @@ static int type_supports_binary_transfer return type->eclass == EC_BIT || type->eclass == EC_CHAR || - type->eclass == EC_STRING || - type->eclass == EC_BLOB || + type->eclass == EC_STRING || type->eclass == EC_DEC || type->eclass == EC_FLT || type->eclass == EC_NUM || @@ -1842,7 +1841,7 @@ static size_t max(size_t a, size_t b) { return a > b ? a : b; } -static int mvc_export_resultset_prot10(res_table* t, stream* s, stream *c, size_t bsize, int compute_lengths) { +static int mvc_export_resultset_prot10(mvc *m, res_table* t, stream* s, stream *c, size_t bsize, int compute_lengths) { BAT *order; lng count; size_t i; @@ -1888,6 +1887,11 @@ static int mvc_export_resultset_prot10(r fres = -1; goto cleanup; } + // write timezone to the client + if (!mnstr_writeInt(s, m->timezone)) { + fres = -1; + goto cleanup; + } for (i = 0; i < (size_t) t->nr_cols; i++) { res_col *c = t->cols + i; @@ -2174,7 +2178,7 @@ mvc_export_result(backend *b, stream *s, return mvc_export_file(b, s, t); if (b->client->protocol == prot10 || b->client->protocol == prot10compressed) { - return mvc_export_resultset_prot10(t, s, b->client->fdin->s, b->client->blocksize, b->client->compute_column_widths); + return mvc_export_resultset_prot10(m, t, s, b->client->fdin->s, b->client->blocksize, b->client->compute_column_widths); } if (!json) { _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list