Changeset: 6a1476d5cb19 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6a1476d5cb19
Added Files:
        sql/test/merge-partitions/Tests/mergepart31.sql
        sql/test/merge-partitions/Tests/mergepart31.stable.err
        sql/test/merge-partitions/Tests/mergepart31.stable.out
Modified Files:
        sql/include/sql_catalog.h
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
        sql/server/rel_propagate.c
        sql/server/sql_atom.c
        sql/server/sql_atom.h
        sql/storage/store.c
        
sql/test/BugTracker-2016/Tests/memory-consumption-query-PLAN-25joins.Bug-3972.stable.out
        sql/test/merge-partitions/Tests/All
        sql/test/mergetables/Tests/forex1.stable.out
Branch: Jun2020
Log Message:

Several improvements for predicates on partitioned tables.

At least one partition would be selected for every selection, even if it didn't 
overlap with any predicates from the selection. Now this is no longer the case. 
If no child tables overlap, an empty relation is generated.
If a column from the parent table is used at more than one predicate, test if 
it overlaps. Before it was tested for just one predicate.
Prune range and list partitioned tables for =,>,<,>=,>= and cmp_in predicates 
if possible, based on the values they cover logically. Also prune IS NULL 
predicates for these tables.
Added support for EC_TIME and EC_TIMESTAMP classes at conversion from strings 
at atom_cast.
Simplify atom creation from pointers. Eliminated create_table_part_atom_exp 
function in favor of atom_general_ptr. The former didn't cover time and 
timestamps with timezone.


diffs (truncated from 1433 to 300 lines):

diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -309,6 +309,7 @@ typedef enum sql_class {
 #define EC_TEMP_TZ(e)          (e==EC_TIME_TZ||e==EC_TIMESTAMP_TZ)
 #define EC_TEMP(e)                     
(e==EC_TIME||e==EC_DATE||e==EC_TIMESTAMP||EC_TEMP_TZ(e))
 #define EC_TEMP_FRAC(e)                
(e==EC_TIME||e==EC_TIMESTAMP||EC_TEMP_TZ(e))
+#define EC_TEMP_NOFRAC(e)      (e==EC_TIME||e==EC_TIMESTAMP)
 #define EC_BACKEND_FIXED(e)    (EC_NUMBER(e)||e==EC_BIT||EC_TEMP(e))
 
 typedef struct sql_type {
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
@@ -18,8 +18,6 @@
 #ifdef HAVE_HGE
 #include "mal.h"               /* for have_hge */
 #endif
-#include "gdk_time.h"
-#include "blob.h"
 
 comp_type
 compare_str2type(const char *compare_op)
@@ -2526,97 +2524,6 @@ exp_sum_scales(sql_subfunc *f, sql_exp *
        }
 }
 
-sql_exp *
-create_table_part_atom_exp(mvc *sql, sql_subtype tpe, ptr value)
-{
-       str buf = NULL;
-       size_t len = 0;
-       sql_exp *res = NULL;
-
-       switch (tpe.type->eclass) {
-               case EC_BIT: {
-                       bit bval = *((bit*) value);
-                       return exp_atom_bool(sql->sa, bval ? 1 : 0);
-               }
-               case EC_POS:
-               case EC_NUM:
-               case EC_DEC:
-               case EC_SEC:
-               case EC_MONTH:
-                       switch (tpe.type->localtype) {
-#ifdef HAVE_HGE
-                               case TYPE_hge: {
-                                       hge hval = *((hge*) value);
-                                       return exp_atom_hge(sql->sa, hval);
-                               }
-#endif
-                               case TYPE_lng: {
-                                       lng lval = *((lng*) value);
-                                       return exp_atom_lng(sql->sa, lval);
-                               }
-                               case TYPE_int: {
-                                       int ival = *((int*) value);
-                                       return exp_atom_int(sql->sa, ival);
-                               }
-                               case TYPE_sht: {
-                                       sht sval = *((sht*) value);
-                                       return exp_atom_sht(sql->sa, sval);
-                               }
-                               case TYPE_bte: {
-                                       bte bbval = *((bte *) value);
-                                       return exp_atom_bte(sql->sa, bbval);
-                               }
-                               default:
-                                       return NULL;
-                       }
-               case EC_FLT:
-                       switch (tpe.type->localtype) {
-                               case TYPE_flt: {
-                                       flt fval = *((flt*) value);
-                                       return exp_atom_flt(sql->sa, fval);
-                               }
-                               case TYPE_dbl: {
-                                       dbl dval = *((dbl*) value);
-                                       return exp_atom_dbl(sql->sa, dval);
-                               }
-                               default:
-                                       return NULL;
-                       }
-               case EC_DATE: {
-                       if(date_tostr(&buf, &len, (const date *)value, false) < 
0)
-                               return NULL;
-                       res = exp_atom(sql->sa, atom_general(sql->sa, &tpe, 
buf));
-                       break;
-               }
-               case EC_TIME: {
-                       if(daytime_tostr(&buf, &len, (const daytime *)value, 
false) < 0)
-                               return NULL;
-                       res = exp_atom(sql->sa, atom_general(sql->sa, &tpe, 
buf));
-                       break;
-               }
-               case EC_TIMESTAMP: {
-                       if(timestamp_tostr(&buf, &len, (const timestamp 
*)value, false) < 0)
-                               return NULL;
-                       res = exp_atom(sql->sa, atom_general(sql->sa, &tpe, 
buf));
-                       break;
-               }
-               case EC_BLOB: {
-                       if(BLOBtostr(&buf, &len, (const blob *)value, false) < 
0)
-                               return NULL;
-                       res = exp_atom(sql->sa, atom_general(sql->sa, &tpe, 
buf));
-                       break;
-               }
-               case EC_CHAR:
-               case EC_STRING:
-                       return exp_atom_clob(sql->sa, sa_strdup(sql->sa, 
value));
-               default:
-                       assert(0);
-       }
-       if(buf)
-               GDKfree(buf);
-       return res;
-}
-
 int
 exp_aggr_is_count(sql_exp *e)
 {
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -185,8 +185,6 @@ extern atom *exp_flatten(mvc *sql, sql_e
 
 extern void exp_sum_scales(sql_subfunc *f, sql_exp *l, sql_exp *r);
 
-extern sql_exp *create_table_part_atom_exp(mvc *sql, sql_subtype tpe, ptr 
value);
-
 extern int exp_aggr_is_count(sql_exp *e);
 
 extern void exps_reset_freevar(list *exps);
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -8962,52 +8962,15 @@ rel_add_dicts(visitor *v, sql_rel *rel)
 }
 
 static int
-find_col_exp( list *exps, sql_exp *e)
-{
-       node *n;
-       int nr = 0;
-
-       for (n=exps->h; n; n=n->next, nr++){
-               if (n->data == e)
-                       return nr;
-       }
-       return -1;
-}
-
-static int
-exp_range_overlap(mvc *sql, sql_exp *e, char *min, char *max, atom *emin, atom 
*emax)
-{
-       sql_subtype *t = exp_subtype(e);
-       int localtype = t->type->localtype;
-
-       if (!min || !max || !emin || !emax || strNil(min) || strNil(max) || 
emin->isnull || emax->isnull || !ATOMlinear(localtype))
+exp_range_overlap(atom *min, atom *max, atom *emin, atom *emax, bool 
min_exclusive, bool max_exclusive)
+{
+       if (!min || !max || !emin || !emax || min->isnull || max->isnull || 
emin->isnull || emax->isnull)
                return 0;
 
-       switch (ATOMstorage(localtype)) {
-       case TYPE_bte:
-       case TYPE_sht:
-       case TYPE_int:
-       case TYPE_lng:
-#ifdef HAVE_HGE
-       case TYPE_hge:
-#endif
-       case TYPE_flt:
-       case TYPE_dbl:
-       case TYPE_str: {
-               atom *cmin, *cmax;
-
-#ifdef HAVE_HGE
-               if (localtype == TYPE_hge && !have_hge)
-                       return 0;
-#endif
-               cmin = atom_general(sql->sa, t, min);
-               cmax = atom_general(sql->sa, t, max);
-               if (VALcmp(&(emax->data), &(cmin->data)) < 0 || 
VALcmp(&(emin->data), &(cmax->data)) > 0)
-                       return 0;
-       } break;
-       default:
+       if ((!min_exclusive && VALcmp(&(emax->data), &(min->data)) < 0) || 
(min_exclusive && VALcmp(&(emax->data), &(min->data)) <= 0))
                return 0;
-       }
+       if ((!max_exclusive && VALcmp(&(emin->data), &(max->data)) > 0) || 
(max_exclusive && VALcmp(&(emin->data), &(max->data)) >= 0))
+               return 0;
        return 1;
 }
 
@@ -9043,13 +9006,22 @@ rel_rename_part(mvc *sql, sql_rel *p, ch
        return p;
 }
 
+typedef struct {
+       atom *lval;
+       atom *hval;
+       bte anti:1,
+               semantics:1;
+       int flag;
+       list *values;
+} range_limit;
+
 /* rewrite merge tables into union of base tables and call optimizer again */
 static sql_rel *
 rel_merge_table_rewrite(visitor *v, sql_rel *rel)
 {
        sql_rel *sel = NULL;
 
-       if(is_modify(rel->op)) {
+       if (is_modify(rel->op)) {
                sql_query *query = query_create(v->sql);
                return rel_propagate(query, rel, &v->changes);
        } else {
@@ -9064,63 +9036,58 @@ rel_merge_table_rewrite(visitor *v, sql_
                                /* instantiate merge table */
                                sql_rel *nrel = NULL;
                                char *tname = t->base.name;
-                               list *cols = NULL, *low = NULL, *high = NULL;
+                               list *cols = NULL, *ranges = NULL;
 
                                if (list_empty(t->members.set))
                                        return rel;
                                if (sel) {
-                                       node *n;
-
-                                       /* no need to reduce the tables list */
-                                       if (list_length(t->members.set) <= 1)
-                                               return sel;
-
                                        cols = sa_list(v->sql->sa);
-                                       low = sa_list(v->sql->sa);
-                                       high = sa_list(v->sql->sa);
-                                       for(n = sel->exps->h; n; n = n->next) {
-                                               sql_exp *e = n->data;
-                                               atom *lval = NULL, *hval = NULL;
-
-                                               if (e->type == e_cmp && 
(e->flag == cmp_equal || e->f )) {
-                                                       sql_exp *l = e->r;
-                                                       sql_exp *h = e->f;
-                                                       sql_exp *c = e->l;
-
-                                                       c = rel_find_exp(rel, 
c);
-                                                       lval = 
exp_flatten(v->sql, l);
-                                                       if (!h)
-                                                               hval = lval;
-                                                       else if (h)
-                                                               hval = 
exp_flatten(v->sql, h);
-                                                       if (c && lval && hval) {
-                                                               append(cols, c);
-                                                               append(low, 
lval);
-                                                               append(high, 
hval);
+                                       ranges = sa_list(v->sql->sa);
+                                       for (node *n = sel->exps->h; n; n = 
n->next) {
+                                               sql_exp *e = n->data, *c = e->l;
+                                               int flag = e->flag & 
~CMP_BETWEEN;
+
+                                               if (e->type != e_cmp || 
(!is_theta_exp(flag) && flag != cmp_in) || !(c = rel_find_exp(rel, c)))
+                                                       continue;
+
+                                               if (flag == cmp_gt || flag == 
cmp_gte || flag == cmp_lte || flag == cmp_lt || flag == cmp_equal) {
+                                                       sql_exp *l = e->r, *h = 
e->f;
+                                                       atom *lval = 
exp_flatten(v->sql, l);
+                                                       atom *hval = h ? 
exp_flatten(v->sql, h) : lval;
+
+                                                       if (lval && hval) {
+                                                               range_limit 
*next = SA_ZNEW(v->sql->sa, range_limit);
+                                                               next->lval = 
lval;
+                                                               next->hval = 
hval;
+                                                               next->flag = 
flag;
+                                                               next->anti = 
is_anti(e);
+                                                               next->semantics 
= is_semantics(e);
+
+                                                               
list_append(cols, c);
+                                                               
list_append(ranges, next);
                                                        }
                                                }
-                                               /* handle in lists */
-                                               if (e->type == e_cmp && e->flag 
== cmp_in) {
-                                                       list *vals = e->r;
-                                                       sql_exp *c = e->l;
-                                                       node *n;
-                                                       list *vlist = 
sa_list(v->sql->sa);
-
-                                                       c = rel_find_exp(rel, 
c);
-                                                       if (c) {
-                                                               for ( n = 
vals->h; n; n = n->next) {
-                                                                       sql_exp 
*l = n->data;
-                                                                       atom 
*lval = exp_flatten(v->sql, l);
-
-                                                                       if 
(!lval)
-                                                                               
break;
-                                                                       
append(vlist, lval);
-                                                               }
-                                                               if (!n) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to