Update of /cvsroot/monetdb/sql/src/server
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv19756/src/server
Modified Files:
rel_bin.mx rel_exp.mx rel_optimizer.mx rel_prop.mx
sql_parser.mx sql_rel2bin.mx sql_scan.mx sql_statement.mx
sql_updates.mx
Log Message:
the relational version now does use the hash indices on selects
U sql_updates.mx
Index: sql_updates.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_updates.mx,v
retrieving revision 1.137
retrieving revision 1.138
diff -u -d -r1.137 -r1.138
--- sql_updates.mx 25 Apr 2008 07:25:29 -0000 1.137
+++ sql_updates.mx 14 May 2008 20:18:28 -0000 1.138
@@ -380,7 +380,7 @@
{
stmt *is = NULL;
- if (i->type == unique) {
+ if (i->type == hash_idx) {
is = hash_insert(sql, i, inserts);
} else if (i->type == join_idx) {
is = join_idx_insert(sql, i, inserts);
@@ -1030,7 +1030,7 @@
if (is_idx_updated(i, updates) == 0)
continue;
- if (i->type == unique) {
+ if (i->type == hash_idx) {
is = hash_update(sql, i, updates, updcol);
} else if (i->type == join_idx) {
is = join_idx_update(i, updates, updcol);
U sql_rel2bin.mx
Index: sql_rel2bin.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_rel2bin.mx,v
retrieving revision 1.117
retrieving revision 1.118
diff -u -d -r1.117 -r1.118
--- sql_rel2bin.mx 6 Mar 2008 08:36:00 -0000 1.117
+++ sql_rel2bin.mx 14 May 2008 20:18:26 -0000 1.118
@@ -792,7 +792,7 @@
sql_idx *i;
for(in = t->idxs.set->h; in; in = in->next){
i = in->data;
- if (i->type == unique &&
+ if (i->type == hash_idx &&
list_length(l) == list_length(i->columns)) {
node *icn;
U rel_bin.mx
Index: rel_bin.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_bin.mx,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- rel_bin.mx 24 Apr 2008 20:42:27 -0000 1.40
+++ rel_bin.mx 14 May 2008 20:18:23 -0000 1.41
@@ -287,10 +287,6 @@
/* here we handle join indices */
if ((p=find_prop(e->p, PROP_JOINIDX)) != NULL) {
- /* it maybe much easier to rewrite the join expression
- in the optimizer, to allready use the 'columns'
- fk_idx, pk_idx
- */
sql_idx *i = p->value, *ri;
sql_fkey *fk = (sql_fkey*)i->key;
sql_exp *el = e->l;
@@ -303,9 +299,9 @@
if (!l) {
swapped = 1;
l = bin_find_column(right, el->l, i->base.name);
- r = bin_find_column(left, er->l, ri->base.name);
+ r = bin_find_column(left, er->l, "%OID%");
} else {
- r = bin_find_column(right, er->l,
ri->base.name);
+ r = bin_find_column(right, er->l, "%OID%");
}
/* small performance improvement, ie use idx directly */
if (l->type == st_alias &&
@@ -426,18 +422,22 @@
list_append(l, sc);
}
if (t->idxs.set) {
+ /* oid column */
+ if (t->columns.set->h) {
+ sql_column *c = t->columns.set->h->data;
+ stmt *sc = stmt_bat(c, stmt_dup(ts), RDONLY);
+ char *rnme = (rel->name)?rel->name:t->base.name;
+
+ rnme = (rnme)?_strdup(rnme):NULL;
+ sc = stmt_mirror(sc);
+ sc = stmt_alias(sc, rnme, _strdup("%OID%"));
+ list_append(l, sc);
+ }
for (n = t->idxs.set->h; n; n = n->next) {
sql_idx *i = n->data;
- stmt *sc = NULL;
+ stmt *sc = stmt_idxbat(i, RDONLY);
char *rnme = (rel->name)?rel->name:t->base.name;
- if (i->type == join_idx) {
- sc = stmt_idxbat(i, RDONLY);
- } else {
- sql_column *c = t->columns.set->h->data;
- sc = stmt_bat(c, stmt_dup(ts), RDONLY);
- sc = stmt_mirror(sc);
- }
rnme = (rnme)?_strdup(rnme):NULL;
sc = stmt_alias(sc, rnme, _strdup(i->base.name));
list_append(l, sc);
@@ -1135,6 +1135,40 @@
}
static stmt *
+rel2bin_hash_lookup( mvc *sql, sql_rel *rel, stmt *sub, sql_idx *i, node *en )
+{
+ sql_subtype *it = sql_bind_localtype("int");
+ stmt *h = NULL;
+ stmt *bits = stmt_atom_int(1 + 31/(list_length(i->columns)+2));
+ sql_exp *e = en->data;
+ sql_exp *l = e->l;
+ stmt *idx = bin_find_column(sub, l->l, i->base.name);
+
+ for( en = rel->exps->h; en; en = en->next ) {
+ sql_exp *e = en->data;
+ stmt *s;
+
+ assert(e->type == e_cmp && e->flag == cmp_equal);
+ s = exp_bin(sql, e->r, NULL, NULL, NULL, NULL);
+
+ if (h) {
+ sql_subfunc *xor =
sql_bind_func_result3(sql->session->schema, "rotate_xor_hash", it, it,
tail_type(s), it);
+
+ h = stmt_Nop(stmt_list( list_append( list_append(
+ list_append(create_stmt_list(), h),
+ stmt_dup(bits)), s)), xor);
+ } else {
+ sql_subfunc *hf =
sql_bind_func_result(sql->session->schema, "hash", tail_type(s), NULL, it);
+
+ h = stmt_unop(s, hf);
+ }
+ }
+ stmt_destroy(bits);
+ return stmt_uselect(idx, h, cmp_equal);
+}
+
+
+static stmt *
rel2bin_select( mvc *sql, sql_rel *rel )
{
list *l;
@@ -1156,6 +1190,18 @@
} else {
predicate = rel2bin_predicate();
}
+ /* handle possible index lookups */
+ /* expressions are in index order ! */
+ if ( (en = rel->exps->h) != NULL) {
+ sql_exp *e = en->data;
+ prop *p;
+
+ if ((p=find_prop(e->p, PROP_HASHIDX)) != NULL) {
+ sql_idx *i = p->value;
+
+ sel = rel2bin_hash_lookup(sql, rel, sub, i, en);
+ }
+ }
for( en = rel->exps->h; en; en = en->next ) {
stmt *s = exp_bin(sql, en->data, sub, NULL, NULL, sel);
U rel_optimizer.mx
Index: rel_optimizer.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_optimizer.mx,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- rel_optimizer.mx 9 Apr 2008 09:56:23 -0000 1.15
+++ rel_optimizer.mx 14 May 2008 20:18:24 -0000 1.16
@@ -548,6 +548,7 @@
idx = find_fk_index(r, rcols, l, lcols);
swapped = 1;
}
+ /* TODO then maybe 2 hash indices */
#ifdef DEBUG
printf("%s %d %s %d (%d)\n",
@@ -1024,6 +1025,156 @@
return rel;
}
+static int
+index_exp(sql_exp *e, sql_idx *i)
+{
+ if (e->type == e_cmp) {
+ switch(i->type) {
+ case hash_idx:
+ if (e->flag == cmp_equal)
+ return 0;
+ case join_idx:
+ default:
+ return -1;
+ }
+ }
+ return -1;
+}
+
+static sql_column *
+selectexp_col(sql_exp *e, sql_rel *r)
+{
+ sql_table *t = r->l;
+
+ if (e->type == e_cmp) {
+ sql_exp *ec = e->l;
+
+ if (ec->type == e_column) {
+ char *name = ec->name;
+ node *cn;
+
+ if (r->exps) { /* use alias */
+ for (cn = r->exps->h; cn; cn = cn->next) {
+ sql_exp *ce = cn->data;
+ if (strcmp(ce->name, name) == 0) {
+ name = ce->r;
+ break;
+ }
+ }
+ }
+ for (cn = t->columns.set->h; cn; cn = cn->next) {
+ sql_column *c = cn->data;
+ if (strcmp(c->base.name, name) == 0)
+ return c;
+ }
+ }
+ }
+ return NULL;
+}
+
+static sql_idx *
+find_index(sql_rel *r, list **EXPS)
+{
+ sql_rel *b;
+ sql_table *t;
+
+ if ((b = find_basetable(r)) == NULL)
+ return NULL;
+
+ /* any (partial) match of the expressions with the index columns */
+ /* Depending on the index type we may need full matches and only
+ limited number of cmp types (hash only equality etc) */
+ /* Depending on the index type we should (in the rel_bin) generate
+ more code, ie for spatial index add post filter etc, for hash
+ compute hash value and use index */
+ t = b->l;
+ if (t->idxs.set) {
+ node *in;
+
+ /* find the columns involved in the selection over this base
table*/
+ for(in = t->idxs.set->h; in; in = in->next) {
+ list *exps, *cols;
+ sql_idx *i = in->data;
+ fcmp cmp = (fcmp)&sql_column_kc_cmp;
+
+ /* join indices are only interesting for joins */
+ if (i->type == join_idx || list_length(i->columns) <= 1)
+ continue;
+ /* based on the index type, find qualifying exps */
+ exps = list_select(r->exps, i, (fcmp) &index_exp,
(fdup)exp_dup);
+ /* now we obtain the columns, move into
sql_column_kc_cmp! */
+ cols = list_map(exps, b, (fmap) &selectexp_col);
+
+ /* Match the index columns with the expression columns.
+ TODO, Allow partial matches ! */
+ if (list_match(cols, i->columns, cmp) == 0) {
+ /* re-order exps in index order */
+ node *n, *m;
+ list *es = list_create((fdestroy)&exp_destroy);
+
+ for(n = i->columns->h; n; n = n->next) {
+ int i = 0;
+ for(m = cols->h; m; m = m->next, i++) {
+ if (cmp(m->data, n->data) == 0){
+ sql_exp *e =
list_fetch(exps, i);
+ list_append(es,
exp_dup(e) );
+ break;
+ }
+ }
+ }
+ assert(list_length(exps) == list_length(es));
+ /* fix the destroy function */
+ cols->destroy = NULL;
+ list_destroy(cols);
+ list_destroy(exps);
+ *EXPS = es;
+ return i;
+ }
+ cols->destroy = NULL;
+ list_destroy(cols);
+ list_destroy(exps);
+ }
+ }
+ return NULL;
+}
+
+static sql_rel *
+rel_select_use_index(mvc *sql, sql_rel *rel)
+{
+ (void)sql;
+ if (rel->op == op_select) {
+ list *exps = NULL;
+ sql_idx *i = find_index(rel, &exps);
+
+#ifdef DEBUG
+ rel_print(sql, rel, 0);
+#endif
+ if (i) {
+ prop *p;
+ node *n;
+
+ /* add PROP_HASHIDX to all column exps */
+ for( n = exps->h; n; n = n->next) {
+ sql_exp *e = n->data;
+
+ e->p = p = prop_create(PROP_HASHIDX, e->p);
+ p->value = i;
+ }
+ /* add the remaining exps to the new exp list */
+ if (list_length(rel->exps) < list_length(exps)) {
+ for( n = rel->exps->h; n; n = n->next) {
+ sql_exp *e = n->data;
+ if (!list_find(exps, e, (fcmp)&exp_cmp))
+ list_append(exps, exp_dup(e));
+ }
+ }
+ list_destroy(rel->exps);
+ rel->exps = exps;
+ }
+ }
+ return rel;
+}
+
static sql_rel *
rewrite(mvc *sql, sql_rel *rel, rewrite_fptr rewriter)
{
@@ -1088,6 +1239,8 @@
if (gp.cnt[op_select])
rel = rewrite(sql, rel, &rel_push_select_down);
*/
+ if (gp.cnt[op_select])
+ rel = rewrite(sql, rel, &rel_select_use_index);
if (gp.cnt[op_join])
rel = rewrite(sql, rel, &rel_join_order);
U sql_statement.mx
Index: sql_statement.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_statement.mx,v
retrieving revision 1.164
retrieving revision 1.165
diff -u -d -r1.164 -r1.165
--- sql_statement.mx 24 Apr 2008 20:43:32 -0000 1.164
+++ sql_statement.mx 14 May 2008 20:18:27 -0000 1.165
@@ -2282,7 +2282,7 @@
case st_bat:
return &st->op1.cval->type;
case st_idxbat:
- if (st->op1.idxval->type == unique) {
+ if (st->op1.idxval->type == hash_idx) {
return sql_bind_localtype("int");
} else if (st->op1.idxval->type == join_idx) {
return sql_bind_localtype("oid");
U rel_exp.mx
Index: rel_exp.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_exp.mx,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- rel_exp.mx 9 Apr 2008 09:56:23 -0000 1.10
+++ rel_exp.mx 14 May 2008 20:18:23 -0000 1.11
@@ -72,6 +72,7 @@
extern sql_exp *rel_find_exp( sql_rel *rel, sql_exp *e);
+extern int exp_cmp( sql_exp *e1, sql_exp *e2);
extern int exp_is_join(sql_exp *e);
extern int exp_is_eqjoin(sql_exp *e);
extern int exp_is_correlation(sql_exp *e, sql_rel *r );
@@ -410,6 +411,12 @@
return NULL;
}
+int
+exp_cmp( sql_exp *e1, sql_exp *e2)
+{
+ return (e1 == e2)?0:-1;
+}
+
int
exp_is_join(sql_exp *e)
{
U rel_prop.mx
Index: rel_prop.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_prop.mx,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- rel_prop.mx 27 Jan 2008 15:40:08 -0000 1.1
+++ rel_prop.mx 14 May 2008 20:18:24 -0000 1.2
@@ -31,6 +31,8 @@
#define PROP_COUNT 0
#define PROP_JOINIDX 1 /* could use join idx */
+#define PROP_HASHIDX 2 /* could use hash idx */
+#define PROP_SORTIDX 3 /* could use sortedness */
#define prop_list() list_create((fdestroy)&prop_destroy)
U sql_scan.mx
Index: sql_scan.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_scan.mx,v
retrieving revision 1.134
retrieving revision 1.135
diff -u -d -r1.134 -r1.135
--- sql_scan.mx 1 Apr 2008 17:04:59 -0000 1.134
+++ sql_scan.mx 14 May 2008 20:18:27 -0000 1.135
@@ -234,6 +234,7 @@
keywords_insert("INTERSECT", INTERSECT);
keywords_insert("CORRESPONDING", CORRESPONDING);
keywords_insert("UNIQUE", UNIQUE);
+ keywords_insert("CLUSTERED", CLUSTERED);
keywords_insert("USING", USING);
keywords_insert("VALUES", VALUES);
keywords_insert("VIEW", VIEW);
U sql_parser.mx
Index: sql_parser.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_parser.mx,v
retrieving revision 1.281
retrieving revision 1.282
diff -u -d -r1.281 -r1.282
--- sql_parser.mx 9 May 2008 14:00:54 -0000 1.281
+++ sql_parser.mx 14 May 2008 20:18:25 -0000 1.282
@@ -681,7 +681,7 @@
%token<sval> PUBLIC REFERENCES SCHEMA SET AUTO_COMMIT
%token RETURN
-%token ALTER ADD TABLE COLUMN TO UNIQUE VALUES VIEW WHERE WITH
+%token ALTER ADD TABLE COLUMN TO UNIQUE CLUSTERED VALUES VIEW WHERE WITH
%token<sval> sqlDATE TIME TIMESTAMP INTERVAL
%token YEAR MONTH DAY HOUR MINUTE SECOND ZONE
%token LIMIT OFFSET
@@ -1336,8 +1336,9 @@
;
opt_index_type:
- UNIQUE { $$ = unique; }
- | /* empty */ { $$ = unique; }
+ UNIQUE { $$ = hash_idx; }
+ | CLUSTERED { $$ = clustered; }
+ | /* empty */ { $$ = hash_idx; }
;
/* sql-server def
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Monetdb-sql-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-sql-checkins