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

Reply via email to