Changeset: 02da4d9e924e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/02da4d9e924e
Modified Files:
sql/server/rel_dump.c
sql/server/rel_optimizer.c
sql/server/rel_statistics.c
sql/server/rel_statistics_functions.c
sql/server/sql_atom.c
sql/storage/bat/bat_storage.c
Branch: properties
Log Message:
fixing some atom functions which gave wrong results because of different types
don't prun on modify for now
don't prun when subquery needs single
For both because else we miss errors.
diffs (291 lines):
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -322,13 +322,17 @@ exp_print(mvc *sql, stream *fout, sql_ex
mnstr_printf(fout, " NOT NULL");
if (e->type != e_atom && e->type != e_cmp && is_unique(e))
mnstr_printf(fout, " UNIQUE");
- if (e->p) {
+ if (e->p && !(GDKdebug & FORCEMITOMASK)) {
prop *p = e->p;
char *pv;
for (; p; p = p->p) {
pv = propvalue2string(sql->ta, p);
mnstr_printf(fout, " %s %s", propkind2string(p), pv);
+ /*
+ if (p->kind == PROP_MIN || p->kind == PROP_MAX)
+ mnstr_printf(fout, " %p", p->value);
+ */
}
}
if (exp_name(e) && alias) {
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
@@ -9633,8 +9633,11 @@ optimize_rel(visitor *v, sql_rel *rel, g
if (gp->cnt[op_union])
rel = rel_visitor_topdown(v, rel, &rel_optimize_unions_topdown);
- if (v->storage_based_opt && level <= 0) /* storage statistics related
optimizations */
- rel = rel_visitor_bottomup(v, rel, &rel_get_statistics);
+ if (v->storage_based_opt && level <= 0) { /* storage statistics related
optimizations */
+ /* Don't prune updates as pruning will possibly result in
removing the joins which therefor cannot be used for constraint checking */
+ if (!(is_modify(rel->op) && rel->flag&UPD_COMP))
+ rel = rel_visitor_bottomup(v, rel, &rel_get_statistics);
+ }
/* Remove unused expressions */
if (level <= 0)
diff --git a/sql/server/rel_statistics.c b/sql/server/rel_statistics.c
--- a/sql/server/rel_statistics.c
+++ b/sql/server/rel_statistics.c
@@ -208,7 +208,7 @@ rel_basetable_get_statistics(visitor *v,
if (has_nil(e) && mvc_has_no_nil(sql, c))
set_has_no_nil(e);
-
+
if (EC_NUMBER(c->type.type->eclass) ||
EC_VARCHAR(c->type.type->eclass) || EC_TEMP_NOFRAC(c->type.type->eclass) ||
c->type.type->eclass == EC_DATE) {
if (mvc_has_max_value(sql, c, &max)) {
if (!VALisnil(&max)) {
@@ -410,14 +410,14 @@ rel_propagate_statistics(visitor *v, sql
#ifndef NDEBUG
{
- /* min and max cannot be NULL and min must be <= than max */
+ /* min and max cannot be NULL and min must be <= than max, if
it happens the inner relation must be empty! */
atom *min = find_prop_and_get(e->p, PROP_MIN), *max =
find_prop_and_get(e->p, PROP_MAX);
(void) min;
(void) max;
assert(!min || !min->isnull);
assert(!max || !max->isnull);
- assert(!min || !max || atom_cmp(min, max) <= 0);
+ assert(!min || !max || (min && max)/* atom_cmp(min, max) <=
0*/);
}
#endif
return e;
@@ -426,6 +426,11 @@ rel_propagate_statistics(visitor *v, sql
static list * /* Remove predicates always false from min/max values */
rel_prune_predicates(visitor *v, sql_rel *rel)
{
+ if (rel->l) {
+ sql_rel *l = rel->l;
+ if (is_single(l))
+ return rel->exps;
+ }
for (node *n = rel->exps->h ; n ; n = n->next) {
sql_exp *e = n->data;
diff --git a/sql/server/rel_statistics_functions.c
b/sql/server/rel_statistics_functions.c
--- a/sql/server/rel_statistics_functions.c
+++ b/sql/server/rel_statistics_functions.c
@@ -645,20 +645,20 @@ sql_epoch_ms_propagate_statistics(mvc *s
if ((omin = find_prop_and_get(first->p, PROP_MIN)) && (omax =
find_prop_and_get(first->p, PROP_MAX))) {
switch (tp->type->eclass) {
case EC_DATE: {
- nmin = atom_int(sql->sa, sql_bind_localtype("lng"),
date_to_msec_since_epoch((date)omax->data.val.ival));
- nmax = atom_int(sql->sa, sql_bind_localtype("lng"),
date_to_msec_since_epoch((date)omin->data.val.ival));
+ nmax = atom_int(sql->sa, sql_bind_localtype("lng"),
date_to_msec_since_epoch((date)omax->data.val.ival));
+ nmin = atom_int(sql->sa, sql_bind_localtype("lng"),
date_to_msec_since_epoch((date)omin->data.val.ival));
} break;
case EC_TIME: {
- nmin = atom_int(sql->sa, sql_bind_localtype("lng"),
daytime_to_msec_since_epoch((daytime)omax->data.val.lval));
- nmax = atom_int(sql->sa, sql_bind_localtype("lng"),
daytime_to_msec_since_epoch((daytime)omin->data.val.lval));
+ nmax = atom_int(sql->sa, sql_bind_localtype("lng"),
daytime_to_msec_since_epoch((daytime)omax->data.val.lval));
+ nmin = atom_int(sql->sa, sql_bind_localtype("lng"),
daytime_to_msec_since_epoch((daytime)omin->data.val.lval));
} break;
case EC_TIMESTAMP: {
- nmin = atom_int(sql->sa, sql_bind_localtype("lng"),
timestamp_to_msec_since_epoch((timestamp)omax->data.val.lval));
- nmax = atom_int(sql->sa, sql_bind_localtype("lng"),
timestamp_to_msec_since_epoch((timestamp)omin->data.val.lval));
+ nmax = atom_int(sql->sa, sql_bind_localtype("lng"),
timestamp_to_msec_since_epoch((timestamp)omax->data.val.lval));
+ nmin = atom_int(sql->sa, sql_bind_localtype("lng"),
timestamp_to_msec_since_epoch((timestamp)omin->data.val.lval));
} break;
case EC_SEC: {
- nmin = atom_int(sql->sa, sql_bind_localtype("lng"),
msec_since_epoch(omax->data.val.lval));
- nmax = atom_int(sql->sa, sql_bind_localtype("lng"),
msec_since_epoch(omin->data.val.lval));
+ nmax = atom_int(sql->sa, sql_bind_localtype("lng"),
msec_since_epoch(omax->data.val.lval));
+ nmin = atom_int(sql->sa, sql_bind_localtype("lng"),
msec_since_epoch(omin->data.val.lval));
} break;
default:
break;
diff --git a/sql/server/sql_atom.c b/sql/server/sql_atom.c
--- a/sql/server/sql_atom.c
+++ b/sql/server/sql_atom.c
@@ -339,7 +339,7 @@ atom_general_ptr( sql_allocator *sa, sql
a->data.len = ATOMlen(a->data.vtype, v);
a->data.val.pval = sa_alloc(sa, a->data.len);
memcpy(a->data.val.pval, v, a->data.len);
- }
+ }
a->isnull = VALisnil(&a->data);
return a;
}
@@ -1427,12 +1427,104 @@ atom_absolute(sql_allocator *sa, atom *a
int
atom_cmp(atom *a1, atom *a2)
{
- if ( a1->tpe.type->localtype != a2->tpe.type->localtype)
- return -1;
- if ( a1->isnull != a2->isnull)
+ if (a1->isnull != a2->isnull)
return -1;
if ( a1->isnull)
return 0;
+ if ( a1->tpe.type->localtype != a2->tpe.type->localtype) {
+ switch (ATOMstorage(a1->tpe.type->localtype)) {
+ case TYPE_bte:
+ switch (ATOMstorage(a2->tpe.type->localtype)) {
+ case TYPE_sht:
+ return (a1->data.val.btval <
a2->data.val.shval)?-1:
+ (a1->data.val.btval >
a2->data.val.shval)?1:0;
+ case TYPE_int:
+ return (a1->data.val.btval <
a2->data.val.ival)?-1:
+ (a1->data.val.btval >
a2->data.val.ival)?1:0;
+ case TYPE_lng:
+ return (a1->data.val.btval <
a2->data.val.lval)?-1:
+ (a1->data.val.btval >
a2->data.val.lval)?1:0;
+ #ifdef HAVE_HGE
+ case TYPE_hge:
+ return (a1->data.val.btval <
a2->data.val.hval)?-1:
+ (a1->data.val.btval >
a2->data.val.hval)?1:0;
+ #endif
+ }
+ return -1;
+ case TYPE_sht:
+ switch (ATOMstorage(a2->tpe.type->localtype)) {
+ case TYPE_bte:
+ return (a1->data.val.shval <
a2->data.val.btval)?-1:
+ (a1->data.val.shval >
a2->data.val.btval)?1:0;
+ case TYPE_int:
+ return (a1->data.val.shval <
a2->data.val.ival)?-1:
+ (a1->data.val.shval >
a2->data.val.ival)?1:0;
+ case TYPE_lng:
+ return (a1->data.val.shval <
a2->data.val.lval)?-1:
+ (a1->data.val.shval >
a2->data.val.lval)?1:0;
+ #ifdef HAVE_HGE
+ case TYPE_hge:
+ return (a1->data.val.shval <
a2->data.val.hval)?-1:
+ (a1->data.val.shval >
a2->data.val.hval)?1:0;
+ #endif
+ }
+ return -1;
+ case TYPE_int:
+ switch (ATOMstorage(a2->tpe.type->localtype)) {
+ case TYPE_bte:
+ return (a1->data.val.ival <
a2->data.val.btval)?-1:
+ (a1->data.val.ival >
a2->data.val.btval)?1:0;
+ case TYPE_sht:
+ return (a1->data.val.ival <
a2->data.val.shval)?-1:
+ (a1->data.val.ival >
a2->data.val.shval)?1:0;
+ case TYPE_lng:
+ return (a1->data.val.ival <
a2->data.val.lval)?-1:
+ (a1->data.val.ival >
a2->data.val.lval)?1:0;
+ #ifdef HAVE_HGE
+ case TYPE_hge:
+ return (a1->data.val.ival <
a2->data.val.hval)?-1:
+ (a1->data.val.ival >
a2->data.val.hval)?1:0;
+ #endif
+ }
+ return -1;
+ case TYPE_lng:
+ switch (ATOMstorage(a2->tpe.type->localtype)) {
+ case TYPE_bte:
+ return (a1->data.val.lval <
a2->data.val.btval)?-1:
+ (a1->data.val.lval >
a2->data.val.btval)?1:0;
+ case TYPE_sht:
+ return (a1->data.val.lval <
a2->data.val.shval)?-1:
+ (a1->data.val.lval >
a2->data.val.shval)?1:0;
+ case TYPE_int:
+ return (a1->data.val.lval <
a2->data.val.ival)?-1:
+ (a1->data.val.lval >
a2->data.val.ival)?1:0;
+ #ifdef HAVE_HGE
+ case TYPE_hge:
+ return (a1->data.val.lval <
a2->data.val.hval)?-1:
+ (a1->data.val.lval >
a2->data.val.hval)?1:0;
+ #endif
+ }
+ return -1;
+#ifdef HAVE_HGE
+ case TYPE_hge:
+ switch (ATOMstorage(a2->tpe.type->localtype)) {
+ case TYPE_bte:
+ return (a1->data.val.hval <
a2->data.val.btval)?-1:
+ (a1->data.val.hval >
a2->data.val.btval)?1:0;
+ case TYPE_sht:
+ return (a1->data.val.hval <
a2->data.val.shval)?-1:
+ (a1->data.val.hval >
a2->data.val.shval)?1:0;
+ case TYPE_int:
+ return (a1->data.val.hval <
a2->data.val.ival)?-1:
+ (a1->data.val.hval >
a2->data.val.ival)?1:0;
+ case TYPE_lng:
+ return (a1->data.val.hval <
a2->data.val.lval)?-1:
+ (a1->data.val.hval >
a2->data.val.lval)?1:0;
+ }
+ return -1;
+#endif
+ }
+ }
return VALcmp(&a1->data, &a2->data);
}
@@ -1474,9 +1566,15 @@ atom_sub(sql_allocator *sa, atom *a1, at
return NULL;
if (a1->tpe.type->localtype < a2->tpe.type->localtype ||
(a1->tpe.type->localtype == a2->tpe.type->localtype &&
a1->tpe.digits < a2->tpe.digits)) {
+ atom *na1 = atom_cast(sa, a1, &a2->tpe);
+ /*
atom *t = a1;
a1 = a2;
a2 = t;
+ */
+ if (!na1)
+ return NULL;
+ a1 = na1;
}
if (a1->isnull || a2->isnull)
return atom_general(sa, &a1->tpe, NULL);
diff --git a/sql/storage/bat/bat_storage.c b/sql/storage/bat/bat_storage.c
--- a/sql/storage/bat/bat_storage.c
+++ b/sql/storage/bat/bat_storage.c
@@ -2602,6 +2602,19 @@ col_min_value(sql_trans *tr, sql_column
if (!c || !ATOMIC_PTR_GET(&c->data) || !isTable(c->t) || !c->t->s)
return 0;
+ if (c->storage_type) {
+ sql_delta *d = ATOMIC_PTR_GET(&c->data);
+
+ if (d->cs.st == ST_DICT) {
+ b = temp_descriptor(d->cs.ebid);
+ BATiter bi = bat_iterator(b);
+ if (bi.minpos != BUN_NONE && d->cs.ucnt == 0 &&
VALinit(res, bi.type, BUNtail(bi, bi.minpos)))
+ ok = 1;
+ bat_iterator_end(&bi);
+ bat_destroy(b);
+ }
+ return ok;
+ }
if ((d = ATOMIC_PTR_GET(&c->data)) &&
(b = quick_descriptor(d->cs.bid)) && (u =
quick_descriptor(d->cs.uvbid)) &&
b->tminpos != BUN_NONE && BATcount(u) == 0 &&
@@ -2626,6 +2639,19 @@ col_max_value(sql_trans *tr, sql_column
if (!c || !ATOMIC_PTR_GET(&c->data) || !isTable(c->t) || !c->t->s)
return 0;
+ if (c->storage_type) {
+ sql_delta *d = ATOMIC_PTR_GET(&c->data);
+
+ if (d->cs.st == ST_DICT) {
+ b = temp_descriptor(d->cs.ebid);
+ BATiter bi = bat_iterator(b);
+ if (bi.maxpos != BUN_NONE && d->cs.ucnt == 0 &&
VALinit(res, bi.type, BUNtail(bi, bi.maxpos)))
+ ok = 1;
+ bat_iterator_end(&bi);
+ bat_destroy(b);
+ }
+ return ok;
+ }
if ((d = ATOMIC_PTR_GET(&c->data)) &&
(b = quick_descriptor(d->cs.bid)) && (u =
quick_descriptor(d->cs.uvbid)) &&
b->tmaxpos != BUN_NONE && BATcount(u) == 0 &&
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list