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

Reply via email to