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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list