Changeset: 90eeac6503b8 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=90eeac6503b8 Modified Files: sql/server/rel_exp.c sql/server/rel_select.c sql/test/miscellaneous/Tests/groupby_error.sql sql/test/miscellaneous/Tests/groupby_error.stable.err sql/test/miscellaneous/Tests/groupby_error.stable.out Branch: linear-hashing Log Message:
Handle IN subqueries with prepared statements and cleanup diffs (141 lines): 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 @@ -782,7 +782,8 @@ exp_rel(mvc *sql, sql_rel *rel) assert(rel); if (is_project(rel->op)) { sql_exp *last = rel->exps->t->data; - e->tpe = *exp_subtype(last); + sql_subtype *t = exp_subtype(last); + e->tpe = t ? *t : (sql_subtype) {0}; } return e; } 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 @@ -1251,7 +1251,9 @@ exp_fix_scale(mvc *sql, sql_subtype *ct, static int rel_set_type_param(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *rel_exp, int upcast) { - if (!type || !rel_exp || (rel_exp->type != e_atom && rel_exp->type != e_column)) + sql_rel *r = rel; + + if (!type || !rel_exp || (rel_exp->type != e_atom && rel_exp->type != e_column && rel_exp->type == e_psm && rel_exp->flag != PSM_REL)) return -1; /* use largest numeric types */ @@ -1264,19 +1266,19 @@ rel_set_type_param(mvc *sql, sql_subtype if (upcast && type->type->eclass == EC_FLT) type = sql_bind_localtype("dbl"); - if ((rel_exp->type == e_atom || rel_exp->type == e_column) && (rel_exp->l || rel_exp->r || rel_exp->f)) { + if (rel_exp->type == e_psm) + r = (sql_rel*) rel_exp->l; + + if ((rel_exp->type == e_atom && (rel_exp->l || rel_exp->r || rel_exp->f)) || rel_exp->type == e_column || rel_exp->type == e_psm) { /* it's not a parameter set possible parameters below */ const char *relname = exp_relname(rel_exp), *expname = exp_name(rel_exp); - if (rel_set_type_recurse(sql, type, rel, &relname, &expname) < 0) + if (rel_set_type_recurse(sql, type, r, &relname, &expname) < 0) return -1; - } - if (exp_subtype(rel_exp)) - return 0; - if (set_type_param(sql, type, rel_exp->flag) == 0) { - rel_exp->tpe = *type; - return 0; - } - return -1; + } else if (set_type_param(sql, type, rel_exp->flag) != 0) + return -1; + + rel_exp->tpe = *type; + return 0; } /* try to do an in-place conversion @@ -5314,7 +5316,7 @@ rel_select_exp(sql_query *query, sql_rel list *te = NULL; sql_exp *ce = rel_column_exp(query, &inner, n->data.sym, sql_sel | group_totals); - if (ce && exp_subtype(ce)) { + if (ce && (exp_subtype(ce) || (ce->type == e_atom && !ce->l && !ce->f))) { pexps = append(pexps, ce); rel = inner; continue; diff --git a/sql/test/miscellaneous/Tests/groupby_error.sql b/sql/test/miscellaneous/Tests/groupby_error.sql --- a/sql/test/miscellaneous/Tests/groupby_error.sql +++ b/sql/test/miscellaneous/Tests/groupby_error.sql @@ -15,9 +15,11 @@ SELECT ALL * FROM tab0 AS cor0 WHERE col prepare select col0 from tab0 where (?) in (select col0 from tab0); prepare select col0 from tab0 where (?,?) in (select col0,col1 from tab0); - +prepare select col0 from tab0 where (col1,col1) in (select col0,? from tab0); +prepare select col0 from tab0 where (col1,col1) in (select ?,? from tab0); +prepare select col0 from tab0 where (col0) in (?); +prepare select col0 from tab0 where (col0) in (?,?); -prepare select col0 from tab0 where (col0) in (?); - +prepare select col0 from tab0 where (?) in (?); --error ROLLBACK; diff --git a/sql/test/miscellaneous/Tests/groupby_error.stable.err b/sql/test/miscellaneous/Tests/groupby_error.stable.err --- a/sql/test/miscellaneous/Tests/groupby_error.stable.err +++ b/sql/test/miscellaneous/Tests/groupby_error.stable.err @@ -31,6 +31,10 @@ MAPI = (monetdb) /var/tmp/mtest-13678/. QUERY = SELECT parent."sys_id" FROM "kagami_dump"."test_task" parent INNER JOIN "kagami_dump"."test_task" child ON child."parent" = parent."sys_id" GROUP BY parent."sys_id" HAVING count(child."sys_id") >= 1 ORDER BY parent."number"; --error, parent."number" requires an aggregate function ERROR = !SELECT: no such column 'parent.number' CODE = 42S22 +MAPI = (monetdb) /var/tmp/mtest-19682/.s.monetdb.38130 +QUERY = prepare select col0 from tab0 where (?) in (?); --error +ERROR = !Cannot have a parameter (?) on both sides of an expression +CODE = 42000 # 10:56:47 > # 10:56:47 > "Done." diff --git a/sql/test/miscellaneous/Tests/groupby_error.stable.out b/sql/test/miscellaneous/Tests/groupby_error.stable.out --- a/sql/test/miscellaneous/Tests/groupby_error.stable.out +++ b/sql/test/miscellaneous/Tests/groupby_error.stable.out @@ -103,6 +103,23 @@ stdout of test 'groupby_error` in direct [ "int", 32, 0, "", "tab0", "col0" ] [ "int", 32, 0, NULL, NULL, NULL ] [ "int", 32, 0, NULL, NULL, NULL ] +#prepare select col0 from tab0 where (col1,col1) in (select col0,? from tab0); +#prepare select col0 from tab0 where (col1,col1) in (select col0,? from tab0); +% .prepare, .prepare, .prepare, .prepare, .prepare, .prepare # table_name +% type, digits, scale, schema, table, column # name +% varchar, int, int, str, str, str # type +% 3, 3, 1, 0, 4, 4 # length +[ "int", 32, 0, "", "tab0", "col0" ] +[ "int", 32, 0, NULL, NULL, NULL ] +#prepare select col0 from tab0 where (col1,col1) in (select ?,? from tab0); +#prepare select col0 from tab0 where (col1,col1) in (select ?,? from tab0); +% .prepare, .prepare, .prepare, .prepare, .prepare, .prepare # table_name +% type, digits, scale, schema, table, column # name +% varchar, int, int, str, str, str # type +% 3, 3, 1, 0, 4, 4 # length +[ "int", 32, 0, "", "tab0", "col0" ] +[ "int", 32, 0, NULL, NULL, NULL ] +[ "int", 32, 0, NULL, NULL, NULL ] #prepare select col0 from tab0 where (col0) in (?); #prepare select col0 from tab0 where (col0) in (?); % .prepare, .prepare, .prepare, .prepare, .prepare, .prepare # table_name @@ -111,6 +128,15 @@ stdout of test 'groupby_error` in direct % 3, 3, 1, 0, 4, 4 # length [ "int", 32, 0, "", "tab0", "col0" ] [ "int", 32, 0, NULL, NULL, NULL ] +#prepare select col0 from tab0 where (col0) in (?,?); +#prepare select col0 from tab0 where (col0) in (?,?); +% .prepare, .prepare, .prepare, .prepare, .prepare, .prepare # table_name +% type, digits, scale, schema, table, column # name +% varchar, int, int, str, str, str # type +% 3, 3, 1, 0, 4, 4 # length +[ "int", 32, 0, "", "tab0", "col0" ] +[ "int", 32, 0, NULL, NULL, NULL ] +[ "int", 32, 0, NULL, NULL, NULL ] #ROLLBACK; # 10:56:47 > _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list