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

Reply via email to