Changeset: 5c85f16abd60 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5c85f16abd60
Modified Files:
monetdb5/modules/atoms/uuid.c
sql/server/rel_exp.c
sql/server/rel_psm.c
sql/server/rel_select.c
sql/test/miscellaneous/Tests/simple_selects.sql
sql/test/miscellaneous/Tests/simple_selects.stable.out
Branch: default
Log Message:
Merge with Oct2020 branch.
diffs (truncated from 319 to 300 lines):
diff --git a/monetdb5/modules/atoms/uuid.c b/monetdb5/modules/atoms/uuid.c
--- a/monetdb5/modules/atoms/uuid.c
+++ b/monetdb5/modules/atoms/uuid.c
@@ -284,8 +284,9 @@ UUIDgenerateUuidInt_bulk(bat *ret, const
bn->tnonil = true;
bn->tnil = false;
BATsetcount(bn, n);
- bn->tsorted = n < 2;
- bn->tkey = n < 2;
+ bn->tsorted = n <= 1;
+ bn->trevsorted = n <= 1;
+ bn->tkey = n <= 1;
bailout:
if (msg && bn)
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
@@ -228,6 +228,26 @@ exp_or(sql_allocator *sa, list *l, list
return e;
}
+static int /* if the quantifier has to be upcasted, ignore the upper
conversion for the cardinalilty */
+quantifier_has_rel(sql_exp *e)
+{
+ if (!e)
+ return 0;
+ switch(e->type){
+ case e_convert:
+ return quantifier_has_rel(e->l);
+ case e_psm:
+ return exp_is_rel(e);
+ case e_atom:
+ case e_column:
+ case e_func:
+ case e_aggr:
+ case e_cmp:
+ return 0;
+ }
+ return 0;
+}
+
sql_exp *
exp_in(sql_allocator *sa, sql_exp *l, list *r, int cmptype)
{
@@ -241,7 +261,7 @@ exp_in(sql_allocator *sa, sql_exp *l, li
for (node *n = r->h; n ; n = n->next) {
sql_exp *next = n->data;
- if (!exp_is_rel(next) && exps_card < next->card)
+ if (!quantifier_has_rel(next) && exps_card < next->card)
exps_card = next->card;
}
e->card = MAX(l->card, exps_card);
@@ -276,10 +296,10 @@ exp_in_func(mvc *sql, sql_exp *le, sql_e
for (node *n = ((list*)vals->f)->h ; n ; n = n->next) {
sql_exp *next = n->data;
- if (!exp_is_rel(next) && exps_card < next->card)
+ if (!quantifier_has_rel(next) && exps_card <
next->card)
exps_card = next->card;
}
- } else if (!exp_is_rel(vals))
+ } else if (!quantifier_has_rel(vals))
exps_card = vals->card;
e->card = MAX(le->card, exps_card);
@@ -300,7 +320,7 @@ exp_compare_func(mvc *sql, sql_exp *le,
if (e) {
e->flag = quantifier;
/* At ANY and ALL operators, the cardinality on the right side
is ignored if it is a sub-relation */
- e->card = quantifier && exp_is_rel(re) ? le->card :
MAX(le->card, re->card);
+ e->card = quantifier && quantifier_has_rel(re) ? le->card :
MAX(le->card, re->card);
if (!has_nil(le) && !has_nil(re))
set_has_no_nil(e);
}
diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c
--- a/sql/server/rel_psm.c
+++ b/sql/server/rel_psm.c
@@ -622,6 +622,29 @@ rel_select_with_into(sql_query *query, s
return rel_psm_block(query->sql->sa, reslist);
}
+static int while_exps_find_one_return(list *l);
+
+static int
+while_exp_find_one_return(sql_exp *e)
+{
+ if (e->flag & PSM_RETURN)
+ return 1;
+ if (e->flag & PSM_WHILE)
+ return while_exps_find_one_return(e->r);
+ if (e->flag & PSM_IF)
+ return while_exps_find_one_return(e->r) || (e->f &&
while_exps_find_one_return(e->f));
+ return 0;
+}
+
+static int
+while_exps_find_one_return(list *l)
+{
+ int res = 0;
+ for (node *n = l->h ; n && !res; n = n->next)
+ res |= while_exp_find_one_return(n->data);
+ return res;
+}
+
static int has_return( list *l );
static int
@@ -630,8 +653,10 @@ exp_has_return(sql_exp *e)
if (e->type == e_psm) {
if (e->flag & PSM_RETURN)
return 1;
- if (e->flag & PSM_IF)
- return has_return(e->r) && (!e->f || has_return(e->f));
+ if (e->flag & PSM_IF) /* for if, both sides must exist and both
must have a return */
+ return has_return(e->r) && e->f && has_return(e->f);
+ if (e->flag & PSM_WHILE) /* for while, at least one of the
statements must have a return */
+ return while_exps_find_one_return(e->r);
}
return 0;
}
@@ -640,10 +665,9 @@ static int
has_return( list *l )
{
node *n = l->t;
- sql_exp *e = n->data;
/* last statment of sequential block */
- if (exp_has_return(e))
+ if (n && exp_has_return(n->data))
return 1;
return 0;
}
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
@@ -1550,7 +1550,7 @@ static sql_rel *
rel_compare_exp_(sql_query *query, sql_rel *rel, sql_exp *ls, sql_exp *rs,
sql_exp *rs2, int type, int anti, int quantifier, int f)
{
mvc *sql = query->sql;
- sql_exp *L = ls, *R = rs, *e = NULL;
+ sql_exp *e = NULL;
if (quantifier || exp_is_rel(ls) || exp_is_rel(rs)) {
if (rs2) {
@@ -1558,7 +1558,7 @@ rel_compare_exp_(sql_query *query, sql_r
if (anti)
set_anti(e);
} else {
- if (rel_binop_check_types(sql, rel, ls, rs, 0) < 0)
+ if (rel_convert_types(sql, rel, rel, &ls, &rs, 1,
type_equal_no_any) < 0)
return NULL;
e = exp_compare_func(sql, ls, rs,
compare_func((comp_type)type, quantifier?0:anti), quantifier);
if (anti && quantifier)
@@ -1569,22 +1569,18 @@ rel_compare_exp_(sql_query *query, sql_r
} else if (!rs2) {
if (ls->card < rs->card) {
sql_exp *swap = ls;
-
ls = rs;
rs = swap;
-
- swap = L;
- L = R;
- R = swap;
-
type = (int)swap_compare((comp_type)type);
}
if (rel_convert_types(sql, rel, rel, &ls, &rs, 1,
type_equal_no_any) < 0)
return NULL;
e = exp_compare(sql->sa, ls, rs, type);
} else {
- if ((rs = exp_check_type(sql, exp_subtype(ls), rel, rs,
type_equal)) == NULL ||
- (rs2 && (rs2 = exp_check_type(sql, exp_subtype(ls), rel,
rs2, type_equal)) == NULL))
+ assert(rs2);
+ if (rel_convert_types(sql, rel, rel, &ls, &rs, 1,
type_equal_no_any) < 0)
+ return NULL;
+ if (!(rs2 = exp_check_type(sql, exp_subtype(ls), rel, rs2,
type_equal)))
return NULL;
e = exp_compare2(sql->sa, ls, rs, rs2, type);
}
@@ -1607,7 +1603,7 @@ rel_compare_exp_(sql_query *query, sql_r
else
return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000)
"SELECT: cannot use non GROUP BY column in query results without an aggregate
function");
}
- return rel_select_push_exp_down(sql, rel, e, ls, L, rs, R, rs2, f);
+ return rel_select_push_exp_down(sql, rel, e, ls, ls, rs, rs, rs2, f);
}
static sql_rel *
@@ -1624,7 +1620,7 @@ rel_compare_exp(sql_query *query, sql_re
/* TODO to handle filters here */
sql_exp *e;
- if (rel_convert_types(sql, rel, rel, &ls, &rs, 1, type_equal) <
0)
+ if (rel_convert_types(sql, rel, rel, &ls, &rs, 1,
type_equal_no_any) < 0)
return NULL;
e = rel_binop_(sql, rel, ls, rs, NULL, compare_op, card_value);
@@ -2219,7 +2215,7 @@ rel_logical_value_exp(sql_query *query,
cmp_type = swap_compare(cmp_type);
}
- if (rel_binop_check_types(sql, rel ? *rel : NULL, ls, rs, 0) <
0)
+ if (rel_convert_types(sql, rel ? *rel : NULL, rel ? *rel :
NULL, &ls, &rs, 1, type_equal_no_any) < 0)
return NULL;
if (exp_is_null(ls) && exp_is_null(rs))
return exp_atom(sql->sa, atom_general(sql->sa,
sql_bind_localtype("bit"), NULL));
@@ -5070,6 +5066,12 @@ exp_has_rank(sql_exp *e)
/* fall through */
case e_aggr:
return exps_has_rank(e->l);
+ case e_cmp:
+ if (e->flag == cmp_or || e->flag == cmp_filter)
+ return exps_has_rank(e->l) || exps_has_rank(e->r);
+ if (e->flag == cmp_in || e->flag == cmp_notin)
+ return exp_has_rank(e->l) || exps_has_rank(e->r);
+ return exp_has_rank(e->l) || exp_has_rank(e->r) || (e->f &&
exp_has_rank(e->f));
default:
return 0;
}
diff --git a/sql/test/Dependencies/dependency_functions.sql
b/sql/test/Dependencies/dependency_functions.sql
--- a/sql/test/Dependencies/dependency_functions.sql
+++ b/sql/test/Dependencies/dependency_functions.sql
@@ -22,6 +22,8 @@ BEGIN
IF f1() < 0
THEN RETURN 2;
+ ELSE
+ RETURN 3;
END IF;
END;
@@ -31,6 +33,8 @@ RETURNS int
BEGIN
IF f1() < 0
THEN RETURN 1;
+ ELSE
+ RETURN 2;
END IF;
END;
diff --git a/sql/test/miscellaneous/Tests/simple_selects.sql
b/sql/test/miscellaneous/Tests/simple_selects.sql
--- a/sql/test/miscellaneous/Tests/simple_selects.sql
+++ b/sql/test/miscellaneous/Tests/simple_selects.sql
@@ -231,6 +231,21 @@ select 1, null intersect select 1, null;
-- 1 NULL
start transaction;
+create or replace function ups() returns int begin if null > 1 then return 1;
else return 2; end if; end;
+select ups();
+ -- 2
+create or replace function ups() returns int begin while 1 = 1 do if null is
null then return 1; else return 2; end if; end while; end;
+select ups();
+ -- 1
+create or replace function ups() returns int begin declare a int; set a = 2;
while a < 2 do if null is null then return 3; else set a = 2; end if; end
while; end;
+select ups();
+ -- 3
+create or replace function ups() returns int begin if 1 > 1 then return 1; end
if; end; --error, return missing
+rollback;
+
+create or replace function ups() returns int begin declare a int; while 1 = 1
do set a = 2; end while; end; --error, return missing
+
+start transaction;
create function "😀"() returns int return 1;
select "😀"();
-- 1
diff --git a/sql/test/miscellaneous/Tests/simple_selects.stable.err
b/sql/test/miscellaneous/Tests/simple_selects.stable.err
--- a/sql/test/miscellaneous/Tests/simple_selects.stable.err
+++ b/sql/test/miscellaneous/Tests/simple_selects.stable.err
@@ -274,6 +274,14 @@ MAPI = (monetdb) /var/tmp/mtest-921778/
QUERY = select x as z, y as z from (select 1, 2) as x(x,y) order by z;
ERROR = !SELECT: identifier 'z' ambiguous
CODE = 42000
+MAPI = (monetdb) /var/tmp/mtest-331513/.s.monetdb.32675
+QUERY = create or replace function ups() returns int begin if 1 > 1 then
return 1; end if; end; --error, return missing
+ERROR = !CREATE FUNCTION: missing return statement
+CODE = 42000
+MAPI = (monetdb) /var/tmp/mtest-408341/.s.monetdb.34589
+QUERY = create or replace function ups() returns int begin declare a int;
while 1 = 1 do set a = 2; end while; end; --error, return missing
+ERROR = !CREATE FUNCTION: missing return statement
+CODE = 42000
# 17:31:38 >
# 17:31:38 > "Done."
diff --git a/sql/test/miscellaneous/Tests/simple_selects.stable.out
b/sql/test/miscellaneous/Tests/simple_selects.stable.out
--- a/sql/test/miscellaneous/Tests/simple_selects.stable.out
+++ b/sql/test/miscellaneous/Tests/simple_selects.stable.out
@@ -442,6 +442,29 @@ project (
% 1, 0 # length
[ 1, NULL ]
#start transaction;
+#create or replace function ups() returns int begin if null > 1 then return 1;
else return 2; end if; end;
+#select ups();
+% .%2 # table_name
+% %2 # name
+% int # type
+% 1 # length
+[ 2 ]
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list