Changeset: 1a557e468767 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1a557e468767 Modified Files: sql/include/sql_relation.h sql/server/rel_optimizer.c Branch: graph0 Log Message:
Join reordering diffs (truncated from 663 to 300 lines): diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h --- a/sql/include/sql_relation.h +++ b/sql/include/sql_relation.h @@ -231,6 +231,10 @@ typedef enum operator_type { (op == op_sample) #define is_graph(op) \ (op == op_graph_join || op == op_graph_select) +#define is_extended_select(op) \ + (is_select(op) || op == op_graph_select) +#define is_extended_join(op) \ + (is_join(op) || op == op_graph_join) /* NO NIL semantics of aggr operations */ #define need_no_nil(e) \ 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 @@ -34,6 +34,8 @@ typedef int (*find_prop_fptr)(mvc *sql, static sql_rel * rewrite_topdown(mvc *sql, sql_rel *rel, rewrite_fptr rewriter, int *has_changes); static sql_rel * rewrite(mvc *sql, sql_rel *rel, rewrite_fptr rewriter, int *has_changes) ; +static sql_rel * rel_graph_pda(int *changes, mvc *sql, sql_rel *rel); +static sql_rel * rel_push_select_down(int *changes, mvc *sql, sql_rel *rel); static sql_rel * rel_remove_empty_select(int *changes, mvc *sql, sql_rel *rel); static sql_subfunc *find_func( mvc *sql, char *name, list *exps ); @@ -321,19 +323,25 @@ static sql_rel * rel_join_order(mvc *sql // graph related stuff typedef struct { - sql_exp* join; + sql_exp* exp; sql_rel* graph; } graph_association; static int graph_association_cmp(graph_association* a, sql_exp* e){ - return (e == a->join) ? 0 : -1; + return (e == a->exp) ? 0 : -1; } static void get_relations(mvc *sql, sql_rel *rel, list *rels) { - if (!rel_is_ref(rel) && (rel->op == op_join || rel->op == op_graph_join) && rel->exps == NULL) { + bool domain_op; + + if(!rel) return; // stop the recursion + + domain_op = rel->op == op_join || rel->op == op_graph_join || rel->op == op_select || rel->op == op_graph_select; + + if (domain_op && !rel_is_ref(rel) && rel->exps == NULL) { sql_rel *l = rel->l; sql_rel *r = rel->r; @@ -608,6 +616,7 @@ find_basetable( sql_rel *r) return r; case op_project: case op_select: + case op_graph_select: return find_basetable(r->l); default: return NULL; @@ -646,10 +655,18 @@ order_join_expressions(mvc *sql, list *d sql_rel *l = find_rel(rels, e->l); sql_rel *r = find_rel(rels, e->r); - if (l && (is_select(l->op) || l->op == op_graph_select) && l->exps) - keys[i] += list_length(l->exps)*10 + exps_count(l->exps)*debug; - if (r && (is_select(r->op) || r->op == op_graph_select) && r->exps) - keys[i] += list_length(r->exps)*10 + exps_count(r->exps)*debug; + if(l != NULL){ + while (is_extended_select(l->op)){ + keys[i] += list_length(l->exps)*10 + exps_count(l->exps)*debug; + l = l->l; + } + } + if(r != NULL){ + while (is_extended_select(r->op)) { + keys[i] += list_length(r->exps)*10 + exps_count(r->exps)*debug; + r = r->l; + } + } } pos[i] = i; } @@ -721,7 +738,7 @@ distinct_join_exps(list *aje, list *lrel return res; } -static list * +static list* find_fk( mvc *sql, list *rels, list *exps) { node *djn; @@ -740,6 +757,9 @@ find_fk( mvc *sql, list *rels, list *exp sql_idx *idx = NULL; sql_exp *je = djn->data, *le = je->l, *re = je->r; + if (je->type == e_graph) + continue; + if (je->type != e_cmp || is_complex_exp(je->flag)) break; if (!find_prop(je->p, PROP_JOINIDX)) { @@ -832,20 +852,7 @@ find_fk( mvc *sql, list *rels, list *exp static sql_rel * -reset_graph_join(mvc *sql, list* graphs, sql_rel *l, sql_rel *r, sql_exp *e){ - node* n = NULL; - sql_rel* graph = NULL; - - n = list_find(graphs, e, (fcmp) graph_association_cmp); - assert(n != NULL); - graph = rel_graph_move2rel(sql, ((graph_association*) n->data)->graph, l, r, e); - list_remove_node(graphs, n); - - return graph; -} - -static sql_rel * -order_joins(mvc *sql, list *rels, list *exps, list *graphs) +order_joins(mvc *sql, list *rels, list *exps) { sql_rel *top = NULL, *l = NULL, *r = NULL; sql_exp *cje; @@ -873,79 +880,56 @@ order_joins(mvc *sql, list *rels, list * /* find the involved relations */ - /* complex expressions may touch multiple base tables + /* complex expressions may touch multiple base tables * Should be pushed up to extra selection. * */ if (cje->type != e_cmp || !is_complex_exp(cje->flag) || !find_prop(cje->p, PROP_HASHCOL) /*|| (cje->type == e_cmp && cje->f == NULL)*/) { - sql_exp *le, *re; - if(cje->type == e_graph){ - assert(list_length(cje->l) == 1 && list_length(cje->r) == 1); - le = ((list*) cje->l)->h->data; - re = ((list*) cje->r)->h->data; - } else { - le = cje->l; - re = cje->r; - } - - l = find_one_rel(rels, le); - r = find_one_rel(rels, re); + l = find_one_rel(rels, cje->l); + r = find_one_rel(rels, cje->r); } if (l && r && l != r) { list_remove_data(sdje, cje); list_remove_data(exps, cje); - list_remove_data(rels, l); - list_remove_data(rels, r); - list_append(n_rels, l); - list_append(n_rels, r); - - /* Create a relation between l and r. Since the calling - functions rewrote the join tree, into a list of expressions - and a list of (simple) relations, there are no outer joins - involved, we can simply do a crossproduct here. - */ - if(cje->type != e_graph){ - top = rel_crossproduct(sql->sa, l, r, op_join); - rel_join_add_exp(sql->sa, top, cje); - } else { // bring back to life the graph join - top = reset_graph_join(sql, graphs, l, r, cje); - } - - /* all other join expressions on these 2 relations */ - while((djn = list_find(exps, n_rels, (fcmp)&exp_joins_rels)) != NULL) { - sql_exp *e = djn->data; - assert(e->type != e_graph && "Mixing regular and graph joins"); - - rel_join_add_exp(sql->sa, top, e); - list_remove_data(exps, e); - } - /* Remove other joins on the current 'n_rels' set in the distinct list too */ - while((djn = list_find(sdje, n_rels, (fcmp)&exp_joins_rels)) != NULL) - list_remove_data(sdje, djn->data); - fnd = 1; - } - } - + } + } + if (l && r && l != r) { + list_remove_data(rels, l); + list_remove_data(rels, r); + list_append(n_rels, l); + list_append(n_rels, r); + + /* Create a relation between l and r. Since the calling + functions rewrote the join tree, into a list of expressions + and a list of (simple) relations, there are no outer joins + involved, we can simply do a crossproduct here. + */ + top = rel_crossproduct(sql->sa, l, r, op_join); + rel_join_add_exp(sql->sa, top, cje); + + /* all other join expressions on these 2 relations */ + while((djn = list_find(exps, n_rels, (fcmp)&exp_joins_rels)) != NULL) { + sql_exp *e = djn->data; + + rel_join_add_exp(sql->sa, top, e); + list_remove_data(exps, e); + } + /* Remove other joins on the current 'n_rels' set in the distinct list too */ + while((djn = list_find(sdje, n_rels, (fcmp)&exp_joins_rels)) != NULL) + list_remove_data(sdje, djn->data); + fnd = 1; + } /* build join tree using the ordered list */ while(list_length(exps) && fnd) { fnd = 0; /* find the first expression which could be added */ for(djn = sdje->h; djn && !fnd && rels->h; djn = (!fnd)?djn->next:NULL) { node *ln, *rn, *en; - sql_exp *le, *re; - + cje = djn->data; - if(cje->type == e_graph){ - assert(list_length(cje->l) == 1 && list_length(cje->r) == 1); - le = ((list*) cje->l)->h->data; - re = ((list*) cje->r)->h->data; - } else { - le = cje->l; - re = cje->r; - } - ln = list_find(n_rels, le, (fcmp)&rel_has_exp); - rn = list_find(n_rels, re, (fcmp)&rel_has_exp); + ln = list_find(n_rels, cje->l, (fcmp)&rel_has_exp); + rn = list_find(n_rels, cje->r, (fcmp)&rel_has_exp); if (ln || rn) { /* remove the expression from the lists */ @@ -962,32 +946,27 @@ order_joins(mvc *sql, list *rels, list * } else if (ln || rn) { if (ln) { l = ln->data; - r = find_rel(rels, re); + r = find_rel(rels, cje->r); } else { l = rn->data; - r = find_rel(rels, le); + r = find_rel(rels, cje->l); } list_remove_data(rels, r); append(n_rels, r); /* create a join using the current expression */ - if(cje->type != e_graph){ - top = rel_crossproduct(sql->sa, top, r, op_join); - rel_join_add_exp(sql->sa, top, cje); - } else { - top = reset_graph_join(sql, graphs, l, r, cje); - } + top = rel_crossproduct(sql->sa, top, r, op_join); + rel_join_add_exp(sql->sa, top, cje); /* all join expressions on these tables */ while((en = list_find(exps, n_rels, (fcmp)&exp_joins_rels)) != NULL) { sql_exp *e = en->data; - assert(e->type != e_graph && "Mixing regular and graph joins"); rel_join_add_exp(sql->sa, top, e); list_remove_data(exps, e); } - /* Remove other joins on the current 'n_rels' + /* Remove other joins on the current 'n_rels' set in the distinct list too */ - while((en = list_find(sdje, n_rels, (fcmp)&exp_joins_rels)) != NULL) + while((en = list_find(sdje, n_rels, (fcmp)&exp_joins_rels)) != NULL) list_remove_data(sdje, en->data); fnd = 1; } @@ -998,7 +977,7 @@ order_joins(mvc *sql, list *rels, list * for(n=rels->h; n; n = n->next) { if (top) top = rel_crossproduct(sql->sa, top, n->data, op_join); - else + else top = n->data; } } @@ -1011,13 +990,13 @@ order_joins(mvc *sql, list *rels, list * /* find the involved relations */ - /* complex expressions may touch multiple base tables + /* complex expressions may touch multiple base tables * Should be push up to extra selection. */ /* l = find_one_rel(rels, e->l); r = find_one_rel(rels, e->r); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list