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

Reply via email to