Changeset: cc438cd295bf for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=cc438cd295bf Modified Files: sql/server/rel_optimizer.c Branch: Jun2020 Log Message:
Missed case, don't apply topN merging if the under relation has more than one reference. Added merging of offsets if expressions are atoms diffs (97 lines): 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 @@ -2079,28 +2079,47 @@ rel_push_topn_and_sample_down(mvc *sql, operator_type relation_type = is_topn(rel->op) ? op_topn : op_sample; sql_rel *(*func) (sql_allocator *, sql_rel *, list *) = is_topn(rel->op) ? rel_topn : rel_sample; - /* nested topN relations without offset */ - if (r && is_topn(rel->op) && is_topn(r->op) && list_length(rel->exps) == 1 && list_length(r->exps) == 1) { + /* nested topN relations */ + if (r && is_topn(rel->op) && is_topn(r->op) && !rel_is_ref(r)) { sql_exp *topN1 = rel->exps->h->data, *topN2 = r->exps->h->data; - - if (topN1->l && topN2->l) { - atom *a1 = (atom *)topN1->l, *a2 = (atom *)topN2->l; - - if (a1->tpe.type->localtype == a2->tpe.type->localtype && !a1->isnull && !a2->isnull) { - if (atom_cmp(a1, a2) < 0) { - rel->l = r->l; - r->l = NULL; - rel_destroy(r); - (*changes)++; - return rel; - } else { - rel->l = NULL; - rel_destroy(rel); - rel = r; - (*changes)++; - return rel; + sql_exp *offset1 = list_length(rel->exps) > 1 ? rel->exps->h->next->data : NULL; + sql_exp *offset2 = list_length(r->exps) > 1 ? r->exps->h->next->data : NULL; + + if (topN1->l && topN2->l && (!offset1 || offset1->l) && (!offset2 || offset2->l)) { /* no parameters */ + bool changed = false; + + if ((!offset1 || (offset1->type == e_atom && offset1->l)) && (!offset2 || (offset2->type == e_atom && offset2->l))) { /* only atoms */ + if (!offset1 && offset2) { + list_append(rel->exps, exp_copy(sql, offset2)); + changed = true; + } else if (offset1 && offset2) { /* sum offsets */ + atom *b1 = (atom *)offset1->l, *b2 = (atom *)offset2->l, *c = atom_add(b1, b2); + + if (!c) /* error, don't apply optimization, WARNING because of this the offset optimization must come before the limit one */ + return rel; + if (atom_cmp(c, b2) < 0) /* overflow */ + c = atom_int(sql->sa, sql_bind_localtype("lng"), GDK_lng_max); + offset1->l = c; + changed = true; } } + + if (topN1->type == e_atom && topN1->l && topN2->type == e_atom && topN2->l) { /* only atoms */ + atom *a1 = (atom *)topN1->l, *a2 = (atom *)topN2->l; + + if (!a2->isnull && (a1->isnull || atom_cmp(a1, a2) >= 0)) { /* topN1 is not set or is larger than topN2 */ + rel->exps->h->data = exp_copy(sql, topN2); + changed = true; + } + } + + if (changed) { + rel->l = r->l; + r->l = NULL; + rel_destroy(r); + (*changes)++; + return rel; + } } } @@ -5505,6 +5524,8 @@ find_candidate_join2semi(sql_rel *rel, b (c=find_candidate_join2semi(rel->r, swap)) != NULL) return c; } + if (is_topn(rel->op) || is_sample(rel->op)) + return find_candidate_join2semi(rel->l, swap); return NULL; } @@ -5521,6 +5542,8 @@ subrel_uses_exp_outside_subrel(sql_rel * subrel_uses_exp_outside_subrel(rel->r, e, c)) return 1; } + if (is_topn(rel->op) || is_sample(rel->op)) + return subrel_uses_exp_outside_subrel(rel->l, e, c); return 0; } @@ -5536,6 +5559,8 @@ rel_uses_exp_outside_subrel(sql_rel *rel if (rel->l) return subrel_uses_exp_outside_subrel(rel->l, e, c); } + if (is_topn(rel->op) || is_sample(rel->op)) + return subrel_uses_exp_outside_subrel(rel->l, e, c); return 1; } _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list