Changeset: ac9b3124d8e0 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ac9b3124d8e0
Modified Files:
sql/backends/monet5/sql_result.c
sql/backends/monet5/sql_statement.c
sql/common/sql_types.c
sql/include/sql_catalog.h
sql/server/rel_planner.c
sql/server/rel_select.c
Branch: timezone
Log Message:
add 2 more ec's (EC_TIME_TZ and EC_TIMESTAMP_TZ)
now EC_TIME <-> EC_TIME_TZ conversions are (sofar partialy) handled
diffs (284 lines):
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
@@ -1283,14 +1283,14 @@ convert2str(mvc *m, sql_class eclass, in
(*buf)[1] = 0;
} else if (eclass == EC_DEC) {
l = dec_tostr((void *) (ptrdiff_t) sc, buf, &len2, mtype, p);
- } else if (eclass == EC_TIME) {
+ } else if (eclass == EC_TIME || eclass == EC_TIME_TZ) {
struct time_res ts_res;
ts_res.has_tz = has_tz;
ts_res.fraction = d ? d - 1 : 0;
ts_res.timezone = m->timezone;
l = sql_time_tostr((void *) &ts_res, buf, &len2, mtype, p);
- } else if (eclass == EC_TIMESTAMP) {
+ } else if (eclass == EC_TIMESTAMP || eclass == EC_TIMESTAMP_TZ) {
struct time_res ts_res;
ts_res.has_tz = has_tz;
ts_res.fraction = d ? d - 1 : 0;
@@ -1326,7 +1326,7 @@ export_value(mvc *m, stream *s, sql_clas
l = dec_tostr((void *) (ptrdiff_t) sc, buf, len, mtype, p);
if (l > 0)
ok = (mnstr_write(s, *buf, l, 1) == 1);
- } else if (eclass == EC_TIME) {
+ } else if (eclass == EC_TIME || eclass == EC_TIME_TZ) {
struct time_res ts_res;
ts_res.has_tz = (strcmp(sqlname, "timetz") == 0);
ts_res.fraction = d ? d - 1 : 0;
@@ -1334,7 +1334,7 @@ export_value(mvc *m, stream *s, sql_clas
l = sql_time_tostr((void *) &ts_res, buf, len, mtype, p);
if (l >= 0)
ok = (mnstr_write(s, *buf, l, 1) == 1);
- } else if (eclass == EC_TIMESTAMP) {
+ } else if (eclass == EC_TIMESTAMP || eclass == EC_TIMESTAMP_TZ) {
struct time_res ts_res;
ts_res.has_tz = (strcmp(sqlname, "timestamptz") == 0);
ts_res.fraction = d ? d - 1 : 0;
@@ -1428,9 +1428,11 @@ static int type_supports_binary_transfer
type->eclass == EC_NUM ||
type->eclass == EC_DATE ||
type->eclass == EC_TIME ||
+ type->eclass == EC_TIME_TZ ||
type->eclass == EC_SEC ||
type->eclass == EC_MONTH ||
- type->eclass == EC_TIMESTAMP;
+ type->eclass == EC_TIMESTAMP ||
+ type->eclass == EC_TIMESTAMP_TZ;
}
static int write_str_term(stream* s, const char* const val) {
@@ -1490,7 +1492,7 @@ mvc_export_table_prot10(backend *b, stre
typelen = ATOMsize(mtype);
iterators[i] = bat_iterator(b);
- if (type->eclass == EC_TIMESTAMP || type->eclass == EC_DATE) {
+ if (type->eclass == EC_TIMESTAMP || type->eclass ==
EC_TIMESTAMP_TZ || type->eclass == EC_DATE) {
// dates and timestamps are converted to Unix Timestamps
mtype = TYPE_lng;
typelen = sizeof(lng);
@@ -1654,7 +1656,7 @@ mvc_export_table_prot10(backend *b, stre
if (c->type.type->eclass == EC_DEC) {
atom_size = ATOMsize(mtype);
}
- if (c->type.type->eclass == EC_TIMESTAMP) {
+ if (c->type.type->eclass == EC_TIMESTAMP ||
c->type.type->eclass == EC_TIMESTAMP_TZ) {
// convert timestamp values to epoch
lng time;
size_t j = 0;
@@ -1859,16 +1861,16 @@ mvc_export_table(backend *b, stream *s,
fmt[i].tostr = &dec_tostr;
fmt[i].frstr = &dec_frstr;
fmt[i].extra = (void *) (ptrdiff_t) c->type.scale;
- } else if (c->type.type->eclass == EC_TIMESTAMP) {
+ } else if (c->type.type->eclass == EC_TIMESTAMP ||
c->type.type->eclass == EC_TIMESTAMP_TZ) {
struct time_res *ts_res = tres + (i - 1);
- ts_res->has_tz = (strcmp(c->type.type->sqlname,
"timestamptz") == 0);
+ ts_res->has_tz = EC_TEMP_TZ(c->type.type->eclass);
ts_res->fraction = c->type.digits ? c->type.digits - 1
: 0;
ts_res->timezone = m->timezone;
fmt[i].tostr = &sql_timestamp_tostr;
fmt[i].frstr = NULL;
fmt[i].extra = ts_res;
- } else if (c->type.type->eclass == EC_TIME) {
+ } else if (c->type.type->eclass == EC_TIME ||
c->type.type->eclass == EC_TIME_TZ) {
struct time_res *ts_res = tres + (i - 1);
ts_res->has_tz = (strcmp(c->type.type->sqlname,
"timetz") == 0);
ts_res->fraction = c->type.digits ? c->type.digits - 1
: 0;
@@ -2039,14 +2041,14 @@ get_print_width(int mtype, sql_class ecl
return count;
} else if (eclass == EC_DATE) {
return 10;
- } else if (eclass == EC_TIME) {
+ } else if (eclass == EC_TIME || eclass == EC_TIME_TZ) {
count = 8;
if (tz) /* time zone */
count += 6; /* +03:30 */
if (digits > 1) /* fractional seconds precision (including dot)
*/
count += digits;
return count;
- } else if (eclass == EC_TIMESTAMP) {
+ } else if (eclass == EC_TIMESTAMP || eclass == EC_TIMESTAMP_TZ) {
count = 10 + 1 + 8;
if (tz) /* time zone */
count += 6; /* +03:30 */
@@ -2204,7 +2206,7 @@ mvc_export_head_prot10(backend *b, strea
print_width = get_print_width(mtype, type->eclass,
c->type.digits, c->type.scale, type_has_tz(&c->type), b->batCacheid, c->p);
}
- if (type->eclass == EC_TIMESTAMP || type->eclass == EC_DATE) {
+ if (type->eclass == EC_TIMESTAMP || type->eclass ==
EC_TIMESTAMP_TZ || type->eclass == EC_DATE) {
// timestamps are converted to Unix Timestamps
mtype = TYPE_lng;
typelen = sizeof(lng);
diff --git a/sql/backends/monet5/sql_statement.c
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -2838,7 +2838,7 @@ stmt_convert(backend *be, stmt *v, sql_s
if (EC_VARCHAR(t->type->eclass) && !(f->type->eclass == EC_STRING &&
t->digits == 0))
q = pushInt(mb, q, t->digits);
/* convert a string to a time(stamp) with time zone */
- if (EC_VARCHAR(f->type->eclass) && EC_TEMP_FRAC(t->type->eclass) &&
type_has_tz(t))
+ if (EC_VARCHAR(f->type->eclass) && EC_TEMP_TZ(t->type->eclass))
q = pushInt(mb, q, type_has_tz(t));
if (t->type->eclass == EC_GEOM) {
/* push the type and coordinates of the column */
diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c
--- a/sql/common/sql_types.c
+++ b/sql/common/sql_types.c
@@ -95,23 +95,25 @@ int bits2digits(int bits)
/* 3 casts are allowed (requires dynamic checks) (sofar not used) */
static int convert_matrix[EC_MAX][EC_MAX] = {
-/* EC_ANY */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* NULL
*/
-/* EC_TABLE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-/* EC_BIT */ { 0, 0, 1, 1, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-/* EC_CHAR */ { 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
-/* EC_STRING */ { 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
-/* EC_BLOB */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-/* EC_POS */ { 0, 0, 2, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
-/* EC_NUM */ { 0, 0, 2, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
-/* EC_MONTH*/ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0 },
-/* EC_SEC*/ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0 },
-/* EC_DEC */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
-/* EC_FLT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 3, 1, 1, 0, 0, 0, 0, 0 },
-/* EC_TIME */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
-/* EC_DATE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0 },
-/* EC_TSTAMP */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0 },
-/* EC_GEOM */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0 },
-/* EC_EXTERNAL*/{ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+/* EC_ANY */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1 }, /* NULL */
+/* EC_TABLE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0 },
+/* EC_BIT */ { 0, 0, 1, 1, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0 },
+/* EC_CHAR */ { 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2 },
+/* EC_STRING */ { 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2 },
+/* EC_BLOB */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0 },
+/* EC_POS */ { 0, 0, 2, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0 },
+/* EC_NUM */ { 0, 0, 2, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0 },
+/* EC_MONTH*/ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0,
0 },
+/* EC_SEC*/ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0,
0 },
+/* EC_DEC */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0 },
+/* EC_FLT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0,
0 },
+/* EC_TIME */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0,
0 },
+/* EC_TIME_TZ */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
0 },
+/* EC_DATE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 0,
0 },
+/* EC_TSTAMP */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
1, 2, 0, 0 },
+/* EC_TSTAMP_TZ */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0,
0 },
+/* EC_GEOM */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0 },
+/* EC_EXTERNAL*/ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0 }
};
int sql_type_convert (int from, int to)
@@ -689,7 +691,7 @@ sql_find_func(sql_allocator *sa, sql_sch
n = s->funcs.set->h;
if (prev) {
for (; n && !found; n = n->next)
- if (n->data == prev)
+ if (n->data == prev->func)
found = 1;
}
for (; n; n = n->next) {
@@ -1213,10 +1215,10 @@ sqltypeinit( sql_allocator *sa)
MONINT = *t++ = sql_create_type(sa, "MONTH_INTERVAL", 32, 0, 2,
EC_MONTH, "int");
SECINT = *t++ = sql_create_type(sa, "SEC_INTERVAL", 13, SCALE_FIX, 10,
EC_SEC, "lng");
TME = *t++ = sql_create_type(sa, "TIME", 7, 0, 0, EC_TIME, "daytime");
- TMETZ = *t++ = sql_create_type(sa, "TIMETZ", 7, SCALE_FIX, 0, EC_TIME,
"daytime");
+ TMETZ = *t++ = sql_create_type(sa, "TIMETZ", 7, SCALE_FIX, 0,
EC_TIME_TZ, "daytime");
DTE = *t++ = sql_create_type(sa, "DATE", 0, 0, 0, EC_DATE, "date");
TMESTAMP = *t++ = sql_create_type(sa, "TIMESTAMP", 7, 0, 0,
EC_TIMESTAMP, "timestamp");
- TMESTAMPTZ = *t++ = sql_create_type(sa, "TIMESTAMPTZ", 7, SCALE_FIX, 0,
EC_TIMESTAMP, "timestamp");
+ TMESTAMPTZ = *t++ = sql_create_type(sa, "TIMESTAMPTZ", 7, SCALE_FIX, 0,
EC_TIMESTAMP_TZ, "timestamp");
BLOB = *t++ = sql_create_type(sa, "BLOB", 0, 0, 0, EC_BLOB, "blob");
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -290,24 +290,25 @@ typedef enum sql_class {
EC_DEC,
EC_FLT,
EC_TIME,
+ EC_TIME_TZ,
EC_DATE,
EC_TIMESTAMP,
+ EC_TIMESTAMP_TZ,
EC_GEOM,
EC_EXTERNAL,
EC_MAX /* evaluated to the max value, should be always kept at the
bottom */
} sql_class;
-#define has_tz(e,n) (EC_TEMP(e) && \
- ((e == EC_TIME && strcmp(n, "timetz") == 0) || \
- (e == EC_TIMESTAMP && strcmp(n, "timestamptz") == 0)) )
-#define type_has_tz(t) has_tz((t)->type->eclass, (t)->type->sqlname)
-#define EC_VARCHAR(e) (e==EC_CHAR||e==EC_STRING)
-#define EC_INTERVAL(e) (e==EC_MONTH||e==EC_SEC)
-#define EC_NUMBER(e)
(e==EC_POS||e==EC_NUM||EC_INTERVAL(e)||e==EC_DEC||e==EC_FLT)
-#define EC_COMPUTE(e) (e==EC_NUM||e==EC_FLT)
-#define EC_BOOLEAN(e) (e==EC_BIT||e==EC_NUM||e==EC_FLT)
-#define EC_TEMP(e) (e==EC_TIME||e==EC_DATE||e==EC_TIMESTAMP)
-#define EC_TEMP_FRAC(e) (e==EC_TIME||e==EC_TIMESTAMP)
+#define has_tz(e,n) (EC_TEMP_TZ(e))
+#define type_has_tz(t) has_tz((t)->type->eclass, (t)->type->sqlname)
+#define EC_VARCHAR(e) (e==EC_CHAR||e==EC_STRING)
+#define EC_INTERVAL(e) (e==EC_MONTH||e==EC_SEC)
+#define EC_NUMBER(e)
(e==EC_POS||e==EC_NUM||EC_INTERVAL(e)||e==EC_DEC||e==EC_FLT)
+#define EC_COMPUTE(e) (e==EC_NUM||e==EC_FLT)
+#define EC_BOOLEAN(e) (e==EC_BIT||e==EC_NUM||e==EC_FLT)
+#define EC_TEMP_TZ(e) (e==EC_TIME_TZ||e==EC_TIMESTAMP_TZ)
+#define EC_TEMP(e)
(e==EC_TIME||e==EC_DATE||e==EC_TIMESTAMP||EC_TEMP_TZ(e))
+#define EC_TEMP_FRAC(e)
(e==EC_TIME||e==EC_TIMESTAMP||EC_TEMP_TZ(e))
#define EC_FIXED(e)
(e==EC_BIT||e==EC_CHAR||e==EC_POS||e==EC_NUM||EC_INTERVAL(e)||e==EC_DEC||EC_TEMP(e))
typedef struct sql_type {
diff --git a/sql/server/rel_planner.c b/sql/server/rel_planner.c
--- a/sql/server/rel_planner.c
+++ b/sql/server/rel_planner.c
@@ -275,7 +275,7 @@ exp_getrange_sel( mvc *sql, sql_rel *r,
/* 4 case, dbl and lng, date, timestamp */
else if (t->type->eclass == EC_DATE) {
sel =
(emax->data.val.ival-emin->data.val.ival)/(dbl)(amax->data.val.ival-amin->data.val.ival);
- } else if (t->type->eclass == EC_TIMESTAMP) {
+ } else if (t->type->eclass == EC_TIMESTAMP || t->type->eclass ==
EC_TIMESTAMP_TZ) {
sel =
(emax->data.val.lval-emin->data.val.lval)/(dbl)(amax->data.val.lval-amin->data.val.lval);
} else if (t->type->eclass == EC_FLT) {
sel =
(emax->data.val.dval-emin->data.val.dval)/(amax->data.val.dval-amin->data.val.dval);
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -2774,15 +2774,24 @@ rel_unop_(mvc *sql, sql_rel *rel, sql_ex
/* try to find the function without a type, and convert
* the value to the type needed by this function!
*/
- if (!f && (f = find_func(sql, s, fname, 1, type, NULL)) != NULL &&
check_card(card, f)) {
-
- if (!f->func->vararg) {
- sql_arg *a = f->func->ops->h->data;
-
- e = rel_check_type(sql, &a->type, rel, e, type_equal);
- }
- if (!e)
- f = NULL;
+ if (!f) {
+ while ((f = find_func(sql, s, fname, 1, type, f)) != NULL &&
check_card(card, f)) {
+ sql_exp *oe = e;
+
+ if (!f->func->vararg) {
+ sql_arg *a = f->func->ops->h->data;
+
+ e = rel_check_type(sql, &a->type, rel, e,
type_equal);
+ }
+ if (e)
+ break;
+ e = oe;
+
+ /* reset error */
+ sql->session->status = 0;
+ sql->errstr[0] = '\0';
+ //f = NULL;
+ }
}
if (f && check_card(card, f)) {
if (f->func->fix_scale == INOUT) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list