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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list