Changeset: 50f30821d640 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=50f30821d640 Modified Files: sql/backends/monet5/sql_statement.c sql/server/sql_atom.c sql/server/sql_atom.h sql/test/BugDay_2005-10-06_2.9.3/Tests/UNION_JOIN_vs_plain_set_UNION-2.SF-920585.stable.out sql/test/pg_regress/Tests/strings.stable.out sql/test/pg_regress/Tests/strings_cast.stable.out Branch: Jun2020 Log Message:
Fix for crashing query. At stmt_convert, if the type to be converted to is equivalent in MAL (eg. char and clob), propagate the statement type, because it may still be checked later on diffs (194 lines): 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 @@ -2834,6 +2834,58 @@ stmt_exception(backend *be, stmt *cond, return NULL; } +/* The type setting is not propagated to statements such as st_bat and st_append, + because they are not considered projections */ +static void +tail_set_type(stmt *st, sql_subtype *t) +{ + for (;;) { + switch (st->type) { + case st_const: + st = st->op2; + continue; + case st_alias: + case st_gen_group: + case st_order: + st = st->op1; + continue; + case st_list: + st = st->op4.lval->h->data; + continue; + case st_join: + case st_join2: + case st_joinN: + if (st->flag == cmp_project) { + st = st->op2; + continue; + } + return; + case st_aggr: + case st_Nop: { + list *res = st->op4.funcval->res; + + if (res && list_length(res) == 1) + res->h->data = t; + return; + } + case st_atom: + atom_set_type(st->op4.aval, t); + return; + case st_convert: + case st_temp: + case st_single: + st->op4.typeval = *t; + return; + case st_var: + if (st->op4.typeval.type) + st->op4.typeval = *t; + return; + default: + return; + } + } +} + stmt * stmt_convert(backend *be, stmt *v, sql_subtype *f, sql_subtype *t, stmt *cond) { @@ -2852,6 +2904,9 @@ stmt_convert(backend *be, stmt *v, sql_s f->type->eclass != EC_DEC && (t->digits == 0 || f->digits == t->digits) && type_has_tz(t) == type_has_tz(f)) { + /* set output type. Despite the MAL code already being generated, + the output type may still be checked */ + tail_set_type(v, t); return v; } @@ -3344,7 +3399,6 @@ tail_type(stmt *st) case st_const: st = st->op2; continue; - case st_semijoin: case st_uselect: case st_uselect2: @@ -3361,17 +3415,15 @@ tail_type(stmt *st) case st_order: st = st->op1; continue; - case st_list: st = st->op4.lval->h->data; continue; - case st_bat: return &st->op4.cval->type; case st_idxbat: if (hash_index(st->op4.idxval->type)) { return sql_bind_localtype("lng"); - } else if (st->op4.idxval->type == join_idx) { + } else if (oid_index(st->op4.idxval->type)) { return sql_bind_localtype("oid"); } /* fall through */ @@ -3391,20 +3443,13 @@ tail_type(stmt *st) return sql_bind_localtype("oid"); case st_table_clear: return sql_bind_localtype("lng"); - - case st_aggr: { - list *res = st->op4.funcval->res; - - if (res && list_length(res) == 1) - return res->h->data; - - return NULL; - } + case st_aggr: case st_Nop: { list *res = st->op4.funcval->res; if (res && list_length(res) == 1) return res->h->data; + return NULL; } case st_atom: diff --git a/sql/server/sql_atom.c b/sql/server/sql_atom.c --- a/sql/server/sql_atom.c +++ b/sql/server/sql_atom.c @@ -595,6 +595,12 @@ atom_type(atom *a) return &a->tpe; } +void +atom_set_type(atom *a, sql_subtype *t) +{ + a->tpe = *t; +} + atom * atom_dup(sql_allocator *sa, atom *a) { diff --git a/sql/server/sql_atom.h b/sql/server/sql_atom.h --- a/sql/server/sql_atom.h +++ b/sql/server/sql_atom.h @@ -51,6 +51,7 @@ extern int atom_cast(sql_allocator *sa, extern char *atom2string(sql_allocator *sa, atom *a); extern char *atom2sql(atom *a); extern sql_subtype *atom_type(atom *a); +extern void atom_set_type(atom *a, sql_subtype *t); #ifdef HAVE_HGE extern hge atom_get_int(atom *a); diff --git a/sql/test/BugDay_2005-10-06_2.9.3/Tests/UNION_JOIN_vs_plain_set_UNION-2.SF-920585.stable.out b/sql/test/BugDay_2005-10-06_2.9.3/Tests/UNION_JOIN_vs_plain_set_UNION-2.SF-920585.stable.out --- a/sql/test/BugDay_2005-10-06_2.9.3/Tests/UNION_JOIN_vs_plain_set_UNION-2.SF-920585.stable.out +++ b/sql/test/BugDay_2005-10-06_2.9.3/Tests/UNION_JOIN_vs_plain_set_UNION-2.SF-920585.stable.out @@ -100,7 +100,7 @@ stdout of test 'UNION_JOIN_vs_plain_set_ [ "users", "SELECT u.\"t\" AS \"name\", ui.\"fullname\", ui.\"default_schema\" FROM \"sys\".\"db_users\" AS u, \"sys\".\"db_user_info\" AS ui WHERE u.\"h\" = ui.\"id\" AND u.\"h\" NOT IN (SELECT s.\"h\" FROM \"sys\".\"db_scens\" AS s WHERE s.\"t\" NOT LIKE 'sql');", false, true, 0, 0 ] % .tables, .tables, .tables, .tables, .tables, .tables, .tables, .tables, .tables, .tables # table_name % table_cat, table_schem, table_name, table_type, remarks, type_cat, type_schem, type_name, self_referencing_col_name, ref_generation # name -% char, varchar, varchar, char, char, char, char, char, char, char # type +% char, varchar, varchar, char, varchar, char, char, char, char, char # type % 4, 3, 8, 12, 222, 4, 4, 4, 2, 6 # length [ "null", "sys", "columns", "SYSTEM TABLE", "", "null", "null", "null", "id", "SYSTEM" ] [ "null", "sys", "db_scens", "SYSTEM TABLE", "", "null", "null", "null", "id", "SYSTEM" ] diff --git a/sql/test/pg_regress/Tests/strings.stable.out b/sql/test/pg_regress/Tests/strings.stable.out --- a/sql/test/pg_regress/Tests/strings.stable.out +++ b/sql/test/pg_regress/Tests/strings.stable.out @@ -98,7 +98,7 @@ stdout of test 'strings` in directory 's #SELECT CAST('namefield' AS text) AS "text(name)"; % . # table_name % text(name) # name -% char # type +% clob # type % 9 # length [ "namefield" ] #CREATE TABLE TEXT_TBL (f1 text); @@ -158,7 +158,7 @@ stdout of test 'strings` in directory 's #SELECT CAST('namefield' AS string) AS "varchar(name)"; % . # table_name % varchar(name) # name -% char # type +% clob # type % 9 # length [ "namefield" ] #DROP TABLE CHAR_TBL; diff --git a/sql/test/pg_regress/Tests/strings_cast.stable.out b/sql/test/pg_regress/Tests/strings_cast.stable.out --- a/sql/test/pg_regress/Tests/strings_cast.stable.out +++ b/sql/test/pg_regress/Tests/strings_cast.stable.out @@ -89,7 +89,7 @@ stdout of test 'strings_cast` in directo #SELECT CAST('namefield' AS text) AS "text(name)"; % . # table_name % text(name) # name -% char # type +% clob # type % 9 # length [ "namefield" ] #SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list