Update of /cvsroot/monetdb/sql/src/server
In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv6651/src/server
Modified Files:
rel_optimizer.mx rel_select.mx
Log Message:
stefan de konink implemented a new optimizer which pushes down counts
under a crossproduct.
U rel_select.mx
Index: rel_select.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_select.mx,v
retrieving revision 1.157
retrieving revision 1.158
diff -u -d -r1.157 -r1.158
--- rel_select.mx 14 Sep 2009 18:20:25 -0000 1.157
+++ rel_select.mx 9 Oct 2009 20:47:36 -0000 1.158
@@ -72,6 +72,9 @@
extern char * rel_name( sql_rel *r );
+extern sql_rel *rel_groupby(sql_rel *l, list *groupbyexps );
+extern sql_exp *rel_groupby_add_aggr(mvc *sql, sql_rel *rel, sql_exp *e);
+
#endif /*_REL_SELECT_H_*/
@c
@@ -88,8 +91,8 @@
#include "rel_dump.h"
#include "rel_prop.h"
-#define ERR_AMBIGUOUS 050000
#define rel_groupby_gbe(r,e) rel_groupby(r, append(new_exp_list(), e))
+#define ERR_AMBIGUOUS 050000
sql_rel *
rel_dup(sql_rel *r)
@@ -674,7 +677,8 @@
return NULL;
}
-static sql_exp *rel_groupby_add_aggr(mvc *sql, sql_rel *rel, sql_exp *e)
+sql_exp *
+rel_groupby_add_aggr(mvc *sql, sql_rel *rel, sql_exp *e)
{
sql_exp *m = NULL, *ne;
char name[16], *nme = NULL;
@@ -818,7 +822,7 @@
return NULL;
}
-static sql_rel *
+sql_rel *
rel_groupby(sql_rel *l, list *groupbyexps )
{
sql_rel *rel = rel_create();
U rel_optimizer.mx
Index: rel_optimizer.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_optimizer.mx,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -d -r1.71 -r1.72
--- rel_optimizer.mx 14 Sep 2009 18:20:25 -0000 1.71
+++ rel_optimizer.mx 9 Oct 2009 20:47:36 -0000 1.72
@@ -26,6 +26,8 @@
#include "rel_semantic.h"
extern sql_rel * rel_optimizer(mvc *sql, sql_rel *rel);
+extern sql_rel * rel_groupby(sql_rel *l, list *groupbyexps );
+extern sql_exp * rel_groupby_add_aggr(mvc *sql, sql_rel *rel, sql_exp *e);
#endif /*_REL_OPTIMIZER_H_*/
@c
@@ -46,6 +48,8 @@
typedef sql_rel *(*rewrite_fptr)(int *changes, mvc *sql, sql_rel *rel);
typedef int (*find_prop_fptr)(mvc *sql, sql_rel *rel);
+static sql_subfunc *find_func( mvc *sql, char *name, list *exps );
+
/* The important task of the relational optimizer is to optimize the
join order.
@@ -1115,6 +1119,92 @@
return 0;
}
+
+/*
+ * Push Count inside crossjoin down, and multiply the results
+ *
+ * project ( project(
+ * group by ( crossproduct (
+ * crossproduct( project (
+ * L, => group by (
+ * R L
+ * ) [ ] [ count NOT NULL ] ) [ ] [ count
NOT NULL ]
+ * ) ),
+ * ) [ NOT NULL ] project (
+ * group by (
+ * R
+ * ) [ ] [ count
NOT NULL ]
+ * )
+ * ) [ sql_mul(.., .. NOT
NULL) ]
+ * )
+ */
+
+
+
+static sql_rel *
+rel_push_count_down(int *changes, mvc *sql, sql_rel *rel)
+{
+ sql_rel *r = rel->l;
+
+ if (is_groupby(rel->op) &&
+ r && !r->exps && r->op == op_join && !(rel_is_ref(r)) &&
+ ((sql_exp *) rel->exps->h->data)->type == e_aggr &&
+ strcmp(((sql_subaggr *) ((sql_exp *)
rel->exps->h->data)->f)->aggr->base.name, "count") == 0) {
+/* TODO check for count(*) */
+ sql_exp *nce, *oce;
+ sql_rel *gbl, *gbr; /* Group By */
+ sql_rel *cp; /* Cross Product */
+ sql_subfunc *mult;
+ list *args;
+ char *rname = NULL, *name = NULL;
+ sql_rel *srel;
+
+ oce = rel->exps->h->data;
+ if (oce->l) /* we only handle COUNT(*) */
+ return rel;
+ rname = oce->rname;
+ name = oce->name;
+
+ args = new_exp_list();
+ srel = r->l;
+ {
+ sql_subaggr *cf = sql_bind_aggr(sql->session->schema,
"count", NULL);
+ sql_exp *cnt, *e = exp_aggr(NULL, cf,
need_distinct(oce), need_no_nil(oce), oce->card, 0);
+
+ exp_label(e, ++sql->label);
+ cnt = exp_column(NULL, exp_name(e), exp_subtype(e),
e->card, has_nil(e), is_intern(e));
+ gbl = rel_groupby(rel_dup(srel), NULL);
+ rel_groupby_add_aggr(sql, gbl, e);
+ append(args, cnt);
+ }
+
+ srel = r->r;
+ {
+ sql_subaggr *cf = sql_bind_aggr(sql->session->schema,
"count", NULL);
+ sql_exp *cnt, *e = exp_aggr(NULL, cf,
need_distinct(oce), need_no_nil(oce), oce->card, 0);
+
+ exp_label(e, ++sql->label);
+ cnt = exp_column(NULL, exp_name(e), exp_subtype(e),
e->card, has_nil(e), is_intern(e));
+ gbr = rel_groupby(rel_dup(srel), NULL);
+ rel_groupby_add_aggr(sql, gbr, e);
+ append(args, cnt);
+ }
+
+ mult = find_func(sql, "sql_mul", args);
+ cp = rel_crossproduct(gbl, gbr, op_join);
+
+ nce = exp_op(args, mult);
+ exp_setname(nce, rname, name );
+
+ rel_destroy(rel);
+ rel = rel_project(cp, append(new_exp_list(), nce));
+
+ (*changes)++;
+ }
+
+ return rel;
+}
+
/*
* Push TopN (only LIMIT, no ORDER BY) down through projections underneath
crossproduct, i.e.,
*
@@ -3135,9 +3225,13 @@
/* TODO push select up. Sounds bad, but isn't. In case of an join-idx
we want the selection on
the 'unique/primary (right hand side)' done before the (fake)-join
and the selections on the foreign
part done after. */
+
- if (gp.cnt[op_join] && gp.cnt[op_groupby])
+
+ if (gp.cnt[op_join] && gp.cnt[op_groupby]) {
+ rel = rewrite(sql, rel, &rel_push_count_down);
rel = rewrite(sql, rel, &rel_push_join_down);
+ }
if (gp.cnt[op_groupby])
rel = rewrite(sql, rel, &rel_avg2sum_count);
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Monetdb-sql-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-sql-checkins