Changeset: f71100494412 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f71100494412 Modified Files: monetdb5/modules/kernel/algebra.c sql/backends/monet5/sql_statement.c sql/server/rel_unnest.c sql/test/mapi/Tests/utf8test.SQL.py sql/test/subquery/Tests/subquery4.sql sql/test/subquery/Tests/subquery4.stable.out sql/test/subquery/Tests/subquery6.sql sql/test/subquery/Tests/subquery6.stable.err sql/test/subquery/Tests/subquery6.stable.out testing/process.py Branch: Jun2020 Log Message:
merged diffs (truncated from 382 to 300 lines): diff --git a/monetdb5/modules/kernel/algebra.c b/monetdb5/modules/kernel/algebra.c --- a/monetdb5/modules/kernel/algebra.c +++ b/monetdb5/modules/kernel/algebra.c @@ -1138,9 +1138,17 @@ ALGfetch(ptr ret, const bat *bid, const if ((b = BATdescriptor(*bid)) == NULL) { throw(MAL, "algebra.fetch", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); } - if ((*pos < (lng) 0) || (*pos >= (lng) BUNlast(b))) { + if (*pos < (lng) 0) { + BBPunfix(b->batCacheid); + throw(MAL, "algebra.fetch", ILLEGAL_ARGUMENT ": row index to fetch must be non negative\n"); + } + if (BATcount(b) == 0) { BBPunfix(b->batCacheid); - throw(MAL, "algebra.fetch", ILLEGAL_ARGUMENT " Idx out of range\n"); + throw(MAL, "algebra.fetch", ILLEGAL_ARGUMENT ": cannot fetch a single row from an empty input\n"); + } + if (*pos >= (lng) BUNlast(b)) { + BBPunfix(b->batCacheid); + throw(MAL, "algebra.fetch", ILLEGAL_ARGUMENT ": row index to fetch is out of range\n"); } msg = doALGfetch(ret, b, (BUN) *pos); BBPunfix(b->batCacheid); 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 @@ -3912,13 +3912,22 @@ const_column(backend *be, stmt *val) stmt * stmt_fetch(backend *be, stmt *val) { - sql_subtype *ct = tail_type(val); + sql_subtype *ct; MalBlkPtr mb = be->mb; InstrPtr q = NULL; - int tt = ct->type->localtype; + int tt; if (val->nr < 0) return NULL; + /* pick from first column on a table case */ + if (val->type == st_table) { + if (list_length(val->op1->op4.lval) > 1) + return NULL; + val = val->op1->op4.lval->h->data; + } + ct = tail_type(val); + tt = ct->type->localtype; + q = newStmt(mb, algebraRef, fetchRef); if (q == NULL) return NULL; diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c --- a/sql/server/rel_unnest.c +++ b/sql/server/rel_unnest.c @@ -1572,8 +1572,20 @@ static sql_exp * rewrite_exp_rel(mvc *sql, sql_rel *rel, sql_exp *e, int depth, int *changes) { (void)changes; - (void)depth; - if (exp_has_rel(e) && !is_ddl(rel->op)) { + + if (exp_is_rel(e) && is_ddl(rel->op) && rel->flag == ddl_psm) { + sql_rel *inner = exp_rel_get_rel(sql->sa, e); + if (is_single(inner)) { + /* use a dummy projection for the single join */ + sql_rel *nrel = rel_project(sql->sa, NULL, append(sa_list(sql->sa), exp_atom_bool(sql->sa, 1))); + + if (!rewrite_inner(sql, nrel, inner, depth?op_left:op_join)) + return NULL; + /* has to apply recursively */ + if (!(e->l = rel_exp_visitor_bottomup(sql, nrel, &rewrite_exp_rel, changes))) + return NULL; + } + } else if (exp_has_rel(e) && !is_ddl(rel->op)) { sql_exp *ne = rewrite_inner(sql, rel, exp_rel_get_rel(sql->sa, e), depth?op_left:op_join); if (!ne) @@ -1588,10 +1600,7 @@ rewrite_exp_rel(mvc *sql, sql_rel *rel, } else { e = exp_rel_update_exp(sql, e); } - } - if (exp_is_rel(e) && is_ddl(rel->op)) - if (!(e->l = rel_exp_visitor_bottomup(sql, e->l, &rewrite_exp_rel, changes))) - return NULL; + } return e; } @@ -2109,7 +2118,7 @@ static sql_exp * rewrite_anyequal(mvc *sql, sql_rel *rel, sql_exp *e, int depth) { sql_subfunc *sf; - if (e->type != e_func || is_ddl(rel->op)) + if (e->type != e_func) return e; sf = e->f; @@ -2241,6 +2250,8 @@ rewrite_anyequal(mvc *sql, sql_rel *rel, if (exp_name(e)) exp_prop_alias(sql->sa, le, e); set_processed(lsq); + if (depth == 1 && is_ddl(rel->op)) /* anyequal is at a ddl statment, it must be inside a relation */ + return exp_rel(sql, lsq); return le; } else { if (lsq) @@ -2589,7 +2600,7 @@ static sql_exp * rewrite_exists(mvc *sql, sql_rel *rel, sql_exp *e, int depth) { sql_subfunc *sf; - if (e->type != e_func || is_ddl(rel->op)) + if (e->type != e_func) return e; sf = e->f; @@ -2647,6 +2658,8 @@ rewrite_exists(mvc *sql, sql_rel *rel, s if (exp_name(e)) exp_prop_alias(sql->sa, le, e); set_processed(sq); + if (depth == 1 && is_ddl(rel->op)) /* exists is at a ddl statment, it must be inside a relation */ + return exp_rel(sql, sq); } else { /* rewrite into semi/anti join */ (void)rewrite_inner(sql, rel, sq, is_exists(sf)?op_semi:op_anti); return exp_atom_bool(sql->sa, 1); diff --git a/sql/test/mapi/Tests/utf8test.SQL.py b/sql/test/mapi/Tests/utf8test.SQL.py --- a/sql/test/mapi/Tests/utf8test.SQL.py +++ b/sql/test/mapi/Tests/utf8test.SQL.py @@ -5,10 +5,10 @@ try: except ImportError: import process -def client(args, universal_newlines = True): +def client(args, text=True): with process.client('sql', args=args, stdout=process.PIPE, stderr=process.PIPE, - universal_newlines=universal_newlines) as clt: + text=text) as clt: return clt.communicate() def printit(file, string): @@ -37,7 +37,7 @@ out, err = client(['-Eutf-8', '-fsql', ' printit(sys.stdout, out) printit(sys.stderr, err) out, err = client(['-fraw', '-Eiso-8859-1', '-s', 'select * from utf8test'], - universal_newlines = False) + text=False) out = out.decode('iso-8859-1') err = err.decode('iso-8859-1') if sys.version_info[0] == 2: @@ -46,7 +46,7 @@ if sys.version_info[0] == 2: printit(sys.stdout, out) printit(sys.stderr, err) out, err = client(['-fsql', '-Eiso-8859-1', '-s', 'select * from utf8test'], - universal_newlines = False) + text=False) out = out.decode('iso-8859-1') err = err.decode('iso-8859-1') if sys.version_info[0] == 2: @@ -55,7 +55,7 @@ if sys.version_info[0] == 2: printit(sys.stdout, out) printit(sys.stderr, err) out, err = client(['-fraw', '-Eus-ascii', '-s', 'select * from utf8test'], - universal_newlines = False) + text=False) out = out.decode('us-ascii') err = err.decode('us-ascii') if sys.version_info[0] == 2: @@ -64,7 +64,7 @@ if sys.version_info[0] == 2: printit(sys.stdout, out) printit(sys.stderr, err) out, err = client(['-fsql', '-Eus-ascii', '-s', 'select * from utf8test'], - universal_newlines = False) + text=False) out = out.decode('us-ascii') err = err.decode('us-ascii') if sys.version_info[0] == 2: diff --git a/sql/test/subquery/Tests/subquery4.sql b/sql/test/subquery/Tests/subquery4.sql --- a/sql/test/subquery/Tests/subquery4.sql +++ b/sql/test/subquery/Tests/subquery4.sql @@ -328,6 +328,27 @@ CREATE OR REPLACE FUNCTION upsme(input I SELECT upsme(1); SELECT upsme(1); +CREATE FUNCTION debugme(input int) RETURNS BOOLEAN +BEGIN + DECLARE n BOOLEAN; + SET n = exists (select i from integers where i < input); + RETURN n; +END; +SELECT debugme(1), debugme(2); + -- False True +DROP FUNCTION debugme; + +CREATE FUNCTION debugme2(n int) returns int +BEGIN + WHILE (exists (select i from integers where i < n)) do + SET n = n - 1; + END WHILE; + RETURN n; +END; +SELECT debugme2(1), debugme2(2); + -- 1 1 +DROP FUNCTION debugme2; + DROP FUNCTION upsme(INT); DROP FUNCTION evilfunction(INT); DROP FUNCTION evilfunction(INT, INT); diff --git a/sql/test/subquery/Tests/subquery4.stable.out b/sql/test/subquery/Tests/subquery4.stable.out --- a/sql/test/subquery/Tests/subquery4.stable.out +++ b/sql/test/subquery/Tests/subquery4.stable.out @@ -397,6 +397,33 @@ stdout of test 'subquery4` in directory % int # type % 1 # length [ 1 ] +#CREATE FUNCTION debugme(input int) RETURNS BOOLEAN +#BEGIN +# DECLARE n BOOLEAN; +# SET n = exists (select i from integers where i < input); +# RETURN n; +#END; +#SELECT debugme(1), debugme(2); +% .%3, .%4 # table_name +% %3, %4 # name +% boolean, boolean # type +% 5, 5 # length +[ false, true ] +#DROP FUNCTION debugme; +#CREATE FUNCTION debugme2(n int) returns int +#BEGIN +# WHILE (exists (select i from integers where i < n)) do +# SET n = n - 1; +# END WHILE; +# RETURN n; +#END; +#SELECT debugme2(1), debugme2(2); +% .%3, .%4 # table_name +% %3, %4 # name +% int, int # type +% 1, 1 # length +[ 1, 1 ] +#DROP FUNCTION debugme2; #DROP FUNCTION upsme(INT); #DROP FUNCTION evilfunction(INT); #DROP FUNCTION evilfunction(INT, INT); diff --git a/sql/test/subquery/Tests/subquery6.sql b/sql/test/subquery/Tests/subquery6.sql --- a/sql/test/subquery/Tests/subquery6.sql +++ b/sql/test/subquery/Tests/subquery6.sql @@ -133,7 +133,7 @@ SELECT i = ALL(i), i < ANY(i), i = ANY(N SELECT i FROM integers WHERE i = ANY(NULL); --empty -CREATE FUNCTION debugme() RETURNS INT +CREATE FUNCTION debugme2() RETURNS INT BEGIN DECLARE n INT; WHILE (1 > (select 9 from integers)) do @@ -141,10 +141,10 @@ BEGIN END WHILE; RETURN n; END; -SELECT debugme(); --error, more than one row returned by a subquery used as an expression -DROP FUNCTION debugme; +SELECT debugme2(); --error, more than one row returned by a subquery used as an expression +DROP FUNCTION debugme2; -CREATE FUNCTION debugme() RETURNS INT +CREATE FUNCTION debugme3() RETURNS INT BEGIN DECLARE n INT; WHILE (1 > ALL(select 1)) do @@ -152,38 +152,39 @@ BEGIN END WHILE; RETURN n; END; -SELECT debugme(); +SELECT debugme3(); --NULL -DROP FUNCTION debugme; +DROP FUNCTION debugme3; -CREATE FUNCTION debugme(input int) RETURNS BOOLEAN -BEGIN - DECLARE n BOOLEAN; - SET n = exists (select i from integers where i < input); - RETURN n; -END; -SELECT debugme(1), debugme(2); - -- True False -DROP FUNCTION debugme; - -CREATE FUNCTION debugme3() RETURNS BOOLEAN +CREATE FUNCTION debugme4() RETURNS BOOLEAN BEGIN DECLARE n BOOLEAN; SET n = (select true union all select false); RETURN n; END; -SELECT debugme3(); --error, more than one row returned by a subquery used as an expression -DROP FUNCTION debugme3; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list