Changeset: 0e2bc5c9f44e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0e2bc5c9f44e
Modified Files:
sql/backends/monet5/rel_bin.c
sql/rel.txt
sql/server/rel_select.c
sql/test/BugTracker-2010/Tests/LIMIT_OFFSET_big-endian.Bug-2622.stable.out
Branch: linear-hashing
Log Message:
Defensive lines. Don't append a NULL sql_exp to a list, because some optimizers
assume sql_exp is non-NULL. For topN append a NULL atom when the limit is to be
ignored. Also updated rel.txt
diffs (165 lines):
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -2783,11 +2783,12 @@ sql_reorder(backend *be, stmt *order, st
}
static sql_exp*
-topn_limit( sql_rel *rel )
+topn_limit(mvc *sql, sql_rel *rel)
{
if (rel->exps) {
sql_exp *limit = rel->exps->h->data;
-
+ if (exp_is_null(sql, limit)) /* If the limit is NULL, ignore
the value */
+ return NULL;
return limit;
}
return NULL;
@@ -2814,7 +2815,7 @@ rel2bin_project(backend *be, sql_rel *re
stmt *l = NULL;
if (topn) {
- sql_exp *le = topn_limit(topn);
+ sql_exp *le = topn_limit(sql, topn);
sql_exp *oe = topn_offset(topn);
if (!le) { /* Don't push only offset */
@@ -3173,7 +3174,7 @@ rel2bin_topn(backend *be, sql_rel *rel,
if (!sub)
return NULL;
- le = topn_limit(rel);
+ le = topn_limit(sql, rel);
oe = topn_offset(rel);
n = sub->op4.lval->h;
@@ -3233,13 +3234,12 @@ rel2bin_sample(backend *be, sql_rel *rel
const char *cname = column_name(sql->sa, sc);
const char *tname = table_name(sql->sa, sc);
- sample_size = exp_bin(be, rel->exps->h->data, NULL, NULL, NULL,
NULL, NULL, NULL);
- if (!sample_size)
- sample_size = stmt_atom_lng_nil(be);
+ if (!(sample_size = exp_bin(be, rel->exps->h->data, NULL,
NULL, NULL, NULL, NULL, NULL)))
+ return NULL;
if (rel->exps->cnt == 2) {
seed = exp_bin(be, rel->exps->h->next->data, NULL,
NULL, NULL, NULL, NULL, NULL);
- if(!seed)
+ if (!seed)
return NULL;
}
diff --git a/sql/rel.txt b/sql/rel.txt
--- a/sql/rel.txt
+++ b/sql/rel.txt
@@ -62,12 +62,12 @@ GROUPBY (card ATOM (no group by exps),
-> r is list of group by expressions
TOPN (card ATOM, AGGR, or MULTI (same card as lower relation))
- -> exps (list) lng limit, [ lng offset ]
+ -> exps (list) lng limit, [ lng offset ] -> if the limit is a
NULL value, then it's ignored, ie only the offset will be used
-> l is relation
-> flag (bounds for limit can be including (1) or excluding (0)
(ie later just returns the topN, including will return atleast N)
SAMPLE (card ATOM, AGGR, or MULTI (same card as lower relation))
- -> exps first is either an lng for rownumbers or double between
[0,1] for percentage. An optional second contains an int for the seed value
+ -> exps first is either an lng for rownumbers or double between
[0,1] for percentage. An optional second contains an int for the seed value. ->
if the first value is a NULL, then it's ignored, ie only the offset will be used
-> l is relation
-> flag (0) no flags
@@ -125,20 +125,18 @@ e_cmp
cmp_or = 7, or handling
->l/r are both lists
cmp_in = 8, in list handling
->r is a list of values
cmp_notin = 9 not in list handling ->r is
a list of values
- cmp_equal_nil = 10, special equal for equi join case,
with nil = nil, at rel_dump, it prints =*
- /* mark join cases */
- mark_in = 11,
- mark_not_in = 12,
- mark_exists = 13,
- mark_not_exists = 14,
+ mark_in = 10, /* mark joins */
+ mark_notin = 11,
+ mark_exists = 12,
+ mark_notexists = 13,
/* The followin cmp_* are only used within stmt (not
sql_exp) */
- cmp_all = 15, /* special case for
crossproducts */
- cmp_project = 16, /* special case for
projection joins */
- cmp_joined = 17, /* special case already
joined */
- cmp_left = 18, /* special case equi
join, keep left order */
- cmp_left_project = 19 /* last step of outer join */
+ cmp_all = 14, /* special case for
crossproducts */
+ cmp_project = 15, /* special case for
projection joins */
+ cmp_joined = 16, /* special case already
joined */
+ cmp_left = 17, /* special case equi
join, keep left order */
+ cmp_left_project = 18 /* last step of outer join */
)
e_func
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
@@ -5276,14 +5276,14 @@ rel_having_limits_nodes(sql_query *query
sql_subaggr *zero_or_one =
sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(l));
l = exp_aggr1(sql->sa, l, zero_or_one, 0, 0,
CARD_ATOM, has_nil(l));
}
- append(exps, l);
+ list_append(exps, l);
} else
- append(exps, NULL);
+ list_append(exps, exp_atom(sql->sa,
atom_null_value(sql->sa, lng)));
if (sn->offset) {
sql_exp *o = rel_value_exp( query, NULL, sn->offset, 0,
ek);
if (!o || !(o=rel_check_type(sql, lng, NULL, o,
type_equal)))
return NULL;
- append(exps, o);
+ list_append(exps, o);
}
rel = rel_topn(sql->sa, rel, exps);
}
@@ -5297,16 +5297,16 @@ rel_having_limits_nodes(sql_query *query
return NULL;
if (!exp_subtype(s) && rel_set_type_param(sql,
sql_bind_localtype("lng"), NULL, s, 0) < 0)
return NULL;
- append(exps, s);
- } else if (sn->seed)
+ list_append(exps, s);
+ } else {
+ assert(sn->seed);
return sql_error(sql, 02, SQLSTATE(42000) "SEED: cannot
have SEED without SAMPLE");
- else
- append(exps, NULL);
+ }
if (sn->seed) {
sql_exp *e = rel_value_exp(query, NULL, sn->seed, 0,
ek);
if (!e || !(e=rel_check_type(sql,
sql_bind_localtype("int"), NULL, e, type_equal)))
return NULL;
- append(exps, e);
+ list_append(exps, e);
}
rel = rel_sample(sql->sa, rel, exps);
}
diff --git
a/sql/test/BugTracker-2010/Tests/LIMIT_OFFSET_big-endian.Bug-2622.stable.out
b/sql/test/BugTracker-2010/Tests/LIMIT_OFFSET_big-endian.Bug-2622.stable.out
--- a/sql/test/BugTracker-2010/Tests/LIMIT_OFFSET_big-endian.Bug-2622.stable.out
+++ b/sql/test/BugTracker-2010/Tests/LIMIT_OFFSET_big-endian.Bug-2622.stable.out
@@ -44,7 +44,7 @@ top N (
| project (
| | table(sys.oblo) [ "oblo"."a" ] COUNT
| ) [ "oblo"."a" ]
-) [ bigint "2" ]
+) [ bigint "NULL", bigint "2" ]
#PLAN select * from oblo LIMIT 2;
% .plan # table_name
% rel # name
@@ -96,7 +96,7 @@ top N (
| | | table(sys.oblo) [ "oblo"."a" ] COUNT
| | ) [ "oblo"."a" ]
| ) [ "oblo"."a" ] [ "oblo"."a" ASC ]
-) [ bigint "2" ]
+) [ bigint "NULL", bigint "2" ]
#PLAN select * from oblo ORDER BY a LIMIT 2;
% .plan # table_name
% rel # name
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list