Changeset: 3a8b7121fb92 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/3a8b7121fb92
Modified Files:
        sql/server/rel_exp.c
        sql/test/prepare/Tests/sqlancer_prepare.sql
        sql/test/prepare/Tests/sqlancer_prepare.stable.out
        sql/test/prepare/Tests/sqlancer_prepare.stable.out.int128
Branch: default
Log Message:

Merged with Jan2022


diffs (226 lines):

diff --git a/gdk/ChangeLog.Jan2022 b/gdk/ChangeLog.Jan2022
--- a/gdk/ChangeLog.Jan2022
+++ b/gdk/ChangeLog.Jan2022
@@ -5,7 +5,7 @@
 - Fixed a bug in the append code for msk (bit mask) bats.
 - Conversions from floating point types to integral types that involve
   multiplication now use the "long double" as intermediate type, thereby
-  using as few significant bits as is feasible.
+  loosing as few significant bits as is feasible.
 - Found and fixed another source for the now infamous BBPcheckbats error
   that sometimes occurs at startup of the server.
 
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -3035,15 +3035,11 @@ set_exp_type(mvc *sql, sql_subtype *type
                (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: 
running out of stack space");
                return -1;
        }
-       if (e->tpe.type)
-               return 0;
-
        if (e->type == e_column) {
                const char *nrname = (const char*) e->l, *nename = (const 
char*) e->r;
                /* find all the column references and set the type */
-               if (rel_find_parameter(sql, type, rel, nrname, nename) < 0)
-                       return -1;
                e->tpe = *type;
+               return rel_find_parameter(sql, type, rel, nrname, nename);
        } else if (e->type == e_atom && e->f) {
                list *atoms = e->f;
                if (!list_empty(atoms))
@@ -3051,10 +3047,10 @@ set_exp_type(mvc *sql, sql_subtype *type
                                if (set_exp_type(sql, type, rel, n->data) < 0) 
/* set recursively */
                                        return -1;
                e->tpe = *type;
+               return 1; /* on a list of atoms, everything should be found */
        } else if (e->type == e_atom && !e->l && !e->r && !e->f) {
-               if (set_type_param(sql, type, e->flag) != 0)
-                       return -1;
                e->tpe = *type;
+               return set_type_param(sql, type, e->flag) == 0 ? 1 : 0;
        } else if (exp_is_rel(e)) { /* for relation expressions, restart cycle 
*/
                rel = (sql_rel*) e->l;
                /* limiting to these cases */
@@ -3062,9 +3058,8 @@ set_exp_type(mvc *sql, sql_subtype *type
                        return 0;
                sql_exp *re = rel->exps->h->data;
 
-               if (set_exp_type(sql, type, rel, re) < 0) /* set recursively */
-                       return -1;
                e->tpe = *type;
+               return set_exp_type(sql, type, rel, re); /* set recursively */
        }
        return 0;
 }
@@ -3072,10 +3067,7 @@ set_exp_type(mvc *sql, sql_subtype *type
 int
 rel_set_type_param(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *exp, 
int upcast)
 {
-       sql_exp *e = exp;
-       int is_rel = exp_is_rel(exp);
-
-       if (!type || !exp || (exp->type != e_atom && exp->type != e_column && 
!is_rel))
+       if (!type || !exp || (exp->type != e_atom && exp->type != e_column && 
!exp_is_rel(exp)))
                return -1;
 
        /* use largest numeric types */
@@ -3088,7 +3080,7 @@ rel_set_type_param(mvc *sql, sql_subtype
        else if (upcast && type->type->eclass == EC_FLT)
                type = sql_bind_localtype("dbl");
 
-       return set_exp_type(sql, type, rel, e);
+       return set_exp_type(sql, type, rel, exp);
 }
 
 /* try to do an in-place conversion
@@ -3240,9 +3232,12 @@ exp_values_set_supertype(mvc *sql, sql_e
        return values;
 }
 
+/* return -1 on error, 0 not found, 1 found */
 static int
 rel_find_parameter(mvc *sql, sql_subtype *type, sql_rel *rel, const char 
*relname, const char *expname)
 {
+       int res = 0;
+
        if (mvc_highwater(sql)) {
                (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: 
running out of stack space");
                return -1;
@@ -3260,7 +3255,7 @@ rel_find_parameter(mvc *sql, sql_subtype
                        e = exps_bind_column(rel->exps, nename, NULL, NULL, 1);
                }
                if (!e)
-                       return 0;
+                       return 0; /* not found */
                /* set order by column types */
                if (is_simple_project(rel->op) && !list_empty(rel->r)) {
                        sql_exp *ordere = NULL;
@@ -3276,8 +3271,9 @@ rel_find_parameter(mvc *sql, sql_subtype
                        nrname = (const char*) e->l;
                        nename = (const char*) e->r;
                        e->tpe = *type;
-               } else if ((e->type == e_atom || exp_is_rel(e)) && 
set_exp_type(sql, type, rel, e) < 0) {
-                       return -1; /* don't search further */
+                       res = 1; /* found */
+               } else if ((e->type == e_atom || exp_is_rel(e)) && (res = 
set_exp_type(sql, type, rel, e)) <= 0) {
+                       return res; /* don't search further */
                }
                /* group by columns can have aliases! */
                if (is_groupby(rel->op) && !list_empty(rel->r)) {
@@ -3286,16 +3282,18 @@ rel_find_parameter(mvc *sql, sql_subtype
                        } else if (nename) {
                                e = exps_bind_column(rel->r, nename, NULL, 
NULL, 1);
                        }
-                       if (e && e->type == e_column) {
+                       if (!e)
+                               return res; /* don't search further */
+                       if (e->type == e_column) {
                                nrname = (const char*) e->l;
                                nename = (const char*) e->r;
                                e->tpe = *type;
-                       } else if (e && (e->type == e_atom || exp_is_rel(e)) && 
set_exp_type(sql, type, rel, e) < 0) {
-                               return -1; /* don't search further */
+                       } else if ((e->type == e_atom || exp_is_rel(e)) && (res 
= set_exp_type(sql, type, rel, e)) <= 0) {
+                               return res; /* don't search further */
                        }
                }
-               if (!e || e->type != e_column)
-                       return 0; /* don't search further */
+               if (e->type != e_column)
+                       return res; /* don't search further */
        }
 
        switch (rel->op) {
@@ -3303,9 +3301,15 @@ rel_find_parameter(mvc *sql, sql_subtype
                case op_left:
                case op_right:
                case op_full:
-                       if ((rel->l && rel_find_parameter(sql, type, rel->l, 
nrname, nename) < 0) ||
-                               (rel->r && rel_find_parameter(sql, type, 
rel->r, nrname, nename)))
-                               return -1;
+                       if (rel->l)
+                               res = rel_find_parameter(sql, type, rel->l, 
nrname, nename);
+                       if (rel->r && res <= 0) { /* try other relation if not 
found */
+                               if (res < 0) { /* reset error */
+                                       sql->session->status = 0;
+                                       sql->errstr[0] = '\0';
+                               }
+                               res = rel_find_parameter(sql, type, rel->r, 
nrname, nename);
+                       }
                        break;
                case op_semi:
                case op_anti:
@@ -3314,8 +3318,8 @@ rel_find_parameter(mvc *sql, sql_subtype
                case op_select:
                case op_topn:
                case op_sample:
-                       if ((rel->l && rel_find_parameter(sql, type, rel->l, 
nrname, nename) < 0))
-                               return -1;
+                       if (rel->l)
+                               res = rel_find_parameter(sql, type, rel->l, 
nrname, nename);
                        break;
                case op_union: /* TODO for set relations this needs further 
improvement */
                case op_inter:
@@ -3324,9 +3328,9 @@ rel_find_parameter(mvc *sql, sql_subtype
                        return -1;
                }
                default: /* For table returning functions, the type must be set 
when the relation is created */
-                       break;
+                       return 0;
        }
-       return 0;
+       return res;
 }
 
 sql_exp *
diff --git a/sql/test/prepare/Tests/sqlancer_prepare.sql 
b/sql/test/prepare/Tests/sqlancer_prepare.sql
--- a/sql/test/prepare/Tests/sqlancer_prepare.sql
+++ b/sql/test/prepare/Tests/sqlancer_prepare.sql
@@ -79,3 +79,7 @@ CREATE TABLE t0 (c0 INT);
 -- In order to compute the OR, an identity function call is needed, but the 
projection only contains parameters
 PREPARE WITH x(x) AS (SELECT ?) SELECT 1 FROM x WHERE COALESCE(FALSE, TRUE) OR 
(SELECT TRUE FROM t0); --error
 ROLLBACK;
+
+PREPARE WITH y(a,b) AS (SELECT 1, ?) SELECT "json"."filter"(JSON '"a"', y.b) 
FROM y CROSS JOIN ((SELECT 1, 4) EXCEPT (SELECT 1,2)) x(x,y);
+
+PREPARE WITH y(a,b) AS (SELECT 1, ?) SELECT "json"."filter"(JSON '"a"', y.b) 
FROM ((SELECT 1, 4) EXCEPT (SELECT 1,2)) x(x,y) CROSS JOIN y;
diff --git a/sql/test/prepare/Tests/sqlancer_prepare.stable.out 
b/sql/test/prepare/Tests/sqlancer_prepare.stable.out
--- a/sql/test/prepare/Tests/sqlancer_prepare.stable.out
+++ b/sql/test/prepare/Tests/sqlancer_prepare.stable.out
@@ -149,3 +149,15 @@
 % int # type
 % 1 # length
 [ 1    ]
+% .prepare,    .prepare,       .prepare,       .prepare,       .prepare,       
.prepare # table_name
+% type,        digits, scale,  schema, table,  column # name
+% varchar,     int,    int,    varchar,        varchar,        varchar # type
+% 4,   1,      1,      0,      3,      3 # length
+[ "json",      0,      0,      "",     "%15",  "%15"   ]
+[ "clob",      0,      0,      NULL,   NULL,   NULL    ]
+% .prepare,    .prepare,       .prepare,       .prepare,       .prepare,       
.prepare # table_name
+% type,        digits, scale,  schema, table,  column # name
+% varchar,     int,    int,    varchar,        varchar,        varchar # type
+% 4,   1,      1,      0,      3,      3 # length
+[ "json",      0,      0,      "",     "%15",  "%15"   ]
+[ "clob",      0,      0,      NULL,   NULL,   NULL    ]
diff --git a/sql/test/prepare/Tests/sqlancer_prepare.stable.out.int128 
b/sql/test/prepare/Tests/sqlancer_prepare.stable.out.int128
--- a/sql/test/prepare/Tests/sqlancer_prepare.stable.out.int128
+++ b/sql/test/prepare/Tests/sqlancer_prepare.stable.out.int128
@@ -149,3 +149,15 @@
 % int # type
 % 1 # length
 [ 1    ]
+% .prepare,    .prepare,       .prepare,       .prepare,       .prepare,       
.prepare # table_name
+% type,        digits, scale,  schema, table,  column # name
+% varchar,     int,    int,    varchar,        varchar,        varchar # type
+% 4,   1,      1,      0,      3,      3 # length
+[ "json",      0,      0,      "",     "%15",  "%15"   ]
+[ "clob",      0,      0,      NULL,   NULL,   NULL    ]
+% .prepare,    .prepare,       .prepare,       .prepare,       .prepare,       
.prepare # table_name
+% type,        digits, scale,  schema, table,  column # name
+% varchar,     int,    int,    varchar,        varchar,        varchar # type
+% 4,   1,      1,      0,      3,      3 # length
+[ "json",      0,      0,      "",     "%15",  "%15"   ]
+[ "clob",      0,      0,      NULL,   NULL,   NULL    ]
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to