Changeset: 9e6a391a3840 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9e6a391a3840
Added Files:
sql/server/rel_planner.c
sql/server/rel_planner.h
Modified Files:
sql/server/Makefile.ag
sql/server/rel_optimizer.c
sql/server/rel_optimizer.h
Branch: default
Log Message:
MonetDB goes classic....
Added first version of a query planner, just for the join tree/order.
Will need lots more work.., statistics, cost models etc...
Therefor its disabled by default, it can be enabled using --set sql_debug=256
This work started because we would like a better join index storage (which
is less or not dependend on the tuple ids). Disabling the single column
join indices can therefor be switched on also using --set sql_debug=512.
diffs (truncated from 1021 to 300 lines):
diff --git a/sql/server/Makefile.ag b/sql/server/Makefile.ag
--- a/sql/server/Makefile.ag
+++ b/sql/server/Makefile.ag
@@ -49,6 +49,7 @@ lib_sqlserver = {
rel_prop.c \
rel_exp.c \
rel_optimizer.c \
+ rel_planner.c \
rel_distribute.c \
rel_psm.c \
rel_xml.c \
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
@@ -27,6 +27,7 @@
#include "rel_dump.h"
#include "rel_select.h"
#include "rel_updates.h"
+#include "rel_planner.h"
#include "sql_env.h"
#define new_func_list(sa) sa_list(sa)
@@ -415,14 +416,6 @@ exp_keyvalue(sql_exp *e)
return cnt;
}
-static int
-rel_has_exp(sql_rel *rel, sql_exp *e)
-{
- if (rel_find_exp(rel, e) != NULL)
- return 0;
- return -1;
-}
-
static sql_rel *
find_rel(list *rels, sql_exp *e)
{
@@ -432,22 +425,6 @@ find_rel(list *rels, sql_exp *e)
return NULL;
}
-static sql_rel *
-find_one_rel(list *rels, sql_exp *e)
-{
- node *n;
- sql_rel *fnd = NULL;
-
- for(n = rels->h; n; n = n->next) {
- if (rel_has_exp(n->data, e) == 0) {
- if (fnd)
- return NULL;
- fnd = n->data;
- }
- }
- return fnd;
-}
-
static int
joinexp_cmp(list *rels, sql_exp *h, sql_exp *key)
{
@@ -510,7 +487,7 @@ table_colexp(sql_exp *e, sql_rel *r)
return NULL;
}
-static int
+int
exp_joins_rels(sql_exp *e, list *rels)
{
sql_rel *l = NULL, *r = NULL;
@@ -668,7 +645,7 @@ rel_find_column( sql_allocator *sa, sql_
}
static list *
-find_fk( sql_allocator *sa, list *rels, list *exps)
+find_fk( mvc *sql, list *rels, list *exps)
{
node *djn;
list *sdje, *aje, *dje;
@@ -685,7 +662,7 @@ find_fk( sql_allocator *sa, list *rels,
break;
if (!find_prop(je->p, PROP_JOINIDX)) {
int swapped = 0;
- list *aaje = matching_joins(sa, rels, aje, je);
+ list *aaje = matching_joins(sql->sa, rels, aje, je);
list *eje = list_select(aaje, (void*)1, (fcmp)
&exp_is_eqjoin, (fdup)NULL);
sql_rel *lr = find_rel(rels, le), *olr = lr;
sql_rel *rr = find_rel(rels, re), *orr = rr;
@@ -717,7 +694,7 @@ find_fk( sql_allocator *sa, list *rels,
swapped = 1;
}
- if (idx && (iname = sa_strconcat( sa, "%",
idx->base.name)) != NULL &&
+ if (idx && (iname = sa_strconcat( sql->sa, "%",
idx->base.name)) != NULL &&
((!swapped && name_find_column(olr, NULL,
iname, -2, &bt) == NULL) ||
( swapped && name_find_column(orr, NULL,
iname, -2, &bt) == NULL)))
idx = NULL;
@@ -727,28 +704,39 @@ find_fk( sql_allocator *sa, list *rels,
node *n;
sql_exp *t = NULL, *i = NULL;
- /* Add join between idx and TID */
- if (swapped) {
- sql_exp *s = je->l, *l = je->r;
-
- t = rel_find_column(sa, lr, s->l, TID);
- i = rel_find_column(sa, rr, l->l,
iname);
- assert(t && i);
- je = exp_compare(sa, i, t, cmp_equal);
- } else {
- sql_exp *s = je->r, *l = je->l;
-
- t = rel_find_column(sa, rr, s->l, TID);
- i = rel_find_column(sa, lr, l->l,
iname);
- assert(t && i);
- je = exp_compare(sa, i, t, cmp_equal);
+ if (list_length(lcols) > 1 ||
!mvc_debug_on(sql, 512)) {
+
+ /* Add join between idx and TID */
+ if (swapped) {
+ sql_exp *s = je->l, *l = je->r;
+
+ t = rel_find_column(sql->sa,
lr, s->l, TID);
+ i = rel_find_column(sql->sa,
rr, l->l, iname);
+ assert(t && i);
+ je = exp_compare(sql->sa, i, t,
cmp_equal);
+ } else {
+ sql_exp *s = je->r, *l = je->l;
+
+ t = rel_find_column(sql->sa,
rr, s->l, TID);
+ i = rel_find_column(sql->sa,
lr, l->l, iname);
+ assert(t && i);
+ je = exp_compare(sql->sa, i, t,
cmp_equal);
+ }
+
+ /* Remove all join expressions */
+ for (n = eje->h; n; n = n->next)
+ list_remove_data(exps, n->data);
+ append(exps, je);
+ djn->data = je;
+ } else if (swapped) { /* else keep je for
single column expressions */
+ je = exp_compare(sql->sa, je->r, je->l,
cmp_equal);
+ /* Remove all join expressions */
+ for (n = eje->h; n; n = n->next)
+ list_remove_data(exps, n->data);
+ append(exps, je);
+ djn->data = je;
}
- /* Remove all join expressions */
- for (n = eje->h; n; n = n->next)
- list_remove_data(exps, n->data);
- append(exps, je);
- djn->data = je;
- je->p = p = prop_create(sa, PROP_JOINIDX,
je->p);
+ je->p = p = prop_create(sql->sa, PROP_JOINIDX,
je->p);
p->value = idx;
}
lcols->destroy = NULL;
@@ -757,7 +745,7 @@ find_fk( sql_allocator *sa, list *rels,
}
/* sort expressions on weighted number of reducing operators */
- sdje = order_join_expressions(sa, dje, rels);
+ sdje = order_join_expressions(sql->sa, dje, rels);
return sdje;
}
@@ -771,7 +759,10 @@ order_joins(mvc *sql, list *rels, list *
int fnd = 0;
/* find foreign keys and reorder the expressions on reducing quality */
- sdje = find_fk(sql->sa, rels, exps);
+ sdje = find_fk(sql, rels, exps);
+
+ if (list_length(rels) > 2 && mvc_debug_on(sql, 256))
+ return rel_planner(sql, rels, sdje);
/* open problem, some expressions use more than 2 relations */
/* For example a.x = b.y * c.z; */
@@ -990,7 +981,7 @@ reorder_join(mvc *sql, sql_rel *rel)
list_append(rels, rel->l);
list_append(rels, rel->r);
cnt = list_length(exps);
- rel->exps = find_fk(sql->sa, rels, exps);
+ rel->exps = find_fk(sql, rels, exps);
if (list_length(rel->exps) != cnt)
rel->exps = order_join_expressions(sql->sa, exps, rels);
} else {
@@ -5323,7 +5314,7 @@ rel_semijoin_use_fk(int *changes, mvc *s
append(rels, rel->l);
append(rels, rel->r);
- (void) find_fk( sql->sa, rels, exps);
+ (void) find_fk( sql, rels, exps);
rel->exps = exps;
}
return rel;
diff --git a/sql/server/rel_optimizer.h b/sql/server/rel_optimizer.h
--- a/sql/server/rel_optimizer.h
+++ b/sql/server/rel_optimizer.h
@@ -24,4 +24,7 @@
extern sql_rel * rel_optimizer(mvc *sql, sql_rel *rel);
+extern int exp_joins_rels(sql_exp *e, list *rels);
+
+
#endif /*_REL_OPTIMIZER_H_*/
diff --git a/sql/server/rel_planner.c b/sql/server/rel_planner.c
new file mode 100644
--- /dev/null
+++ b/sql/server/rel_planner.c
@@ -0,0 +1,774 @@
+/*
+ * The contents of this file are subject to the MonetDB Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.monetdb.org/Legal/MonetDBLicense
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is the MonetDB Database System.
+ *
+ * The Initial Developer of the Original Code is CWI.
+ * Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
+ * Copyright August 2008-2013 MonetDB B.V.
+ * All Rights Reserved.
+ */
+
+#include "monetdb_config.h"
+#include "rel_planner.h"
+#include "rel_exp.h"
+#include "rel_prop.h"
+#include "rel_select.h"
+#include "rel_optimizer.h"
+
+typedef struct memoitem {
+ char *name;
+ list *rels;
+ list *exps;
+ list *joins;
+ int done;
+ int level;
+ lng count;
+ dbl sel;
+ lng cost;
+ void *data;
+} memoitem;
+
+#define p_pkey 1
+#define p_fkey 2
+#define p_ukey 3
+
+typedef struct memojoin {
+ memoitem *l, *r;
+ int rules; /* handled rules */
+ int prop; /* pkey, fkey, ukey */
+ lng cost;
+ sql_exp *e;
+} memojoin;
+
+static int
+memoitem_key( memoitem *mi )
+{
+ return hash_key(mi->name);
+}
+
+static memoitem*
+memo_find(list *memo, char *name)
+{
+ int key = hash_key(name);
+ sql_hash_e *he = memo->ht->buckets[key&(memo->ht->size-1)];
+
+ for (; he; he = he->chain) {
+ memoitem *mi = he->value;
+
+ if (mi->name && strcmp(mi->name, name) == 0)
+ return mi;
+ }
+ return NULL;
+}
+
+static char *
+merge_names( sql_allocator *sa, char *lname, char *rname)
+{
+ int llen = strlen(lname);
+ int rlen = strlen(rname);
+ char *n = SA_NEW_ARRAY(sa, char, llen+rlen+2), *p = n;
+ char *c = lname;
+
+ while (*c) {
+ int i = 0;
+ for ( ; c[i] && c[i] != ','; i++)
+ p[i] = c[i];
+ p[i] = 0;
+ if (strcmp(p, rname) > 0) {
+ strncpy(p, rname, rlen);
+ p+=rlen;
_______________________________________________
checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list