Changeset: 42e9cee252f9 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/42e9cee252f9
Modified Files:
        sql/server/rel_distribute.c
        sql/server/rel_prop.c
        sql/server/rel_prop.h
Branch: new_rmt_opt
Log Message:

New implementation for remote optimizer WIP


diffs (219 lines):

diff --git a/sql/server/rel_distribute.c b/sql/server/rel_distribute.c
--- a/sql/server/rel_distribute.c
+++ b/sql/server/rel_distribute.c
@@ -206,6 +206,163 @@ bind_rewrite_replica(visitor *v, global_
        return gp->needs_mergetable_rewrite || gp->needs_remote_replica_rewrite 
? rel_rewrite_replica : NULL;
 }
 
+static sql_rel *
+rel_rewrite_remote_2_(visitor *v, sql_rel *rel)
+{
+       prop *p, *pl, *pr;
+
+       if (!eliminate_remote_or_replica_refs(v, &rel))
+               return rel;
+
+       sql_rel *l = rel->l, *r = rel->r; /* look on left and right relations 
after possibly doing rel_copy */
+
+       switch (rel->op) {
+       case op_basetable: {
+               sql_table *t = rel->l;
+
+               /* when a basetable wraps a sql_table (->l) which is remote we 
want to store its remote
+                * uri to the REMOTE property. As the property is pulled up the 
tree it can be used in
+                * the case of binary rel operators (see later switch cases) in 
order to
+                * 1. resolve properly (same uri) replica tables in the other 
subtree (that's why we
+                *    call the rewrite_replica)
+                * 2. pull REMOTE over the binary op if the other subtree has a 
matching uri remote table
+                */
+               if (t && isRemote(t) && (p = find_prop(rel->p, PROP_REMOTE)) == 
NULL) {
+                       if (t->query) {
+                               tid_uri *tu = SA_NEW(v->sql->sa, tid_uri);
+                               tu->id = t->base.id;
+                               tu->uri = mapiuri_uri(t->query, v->sql->sa);
+                               list *uris = sa_list(v->sql->sa);
+                               append(uris, tu);
+                               p = rel->p = prop_create(v->sql->sa, 
PROP_REMOTE, rel->p);
+                               p->value.pval = (void *)uris;
+                       }
+               }
+               if (t && isReplicaTable(t) && !list_empty(t->members)) {
+                       /* the replicas probably have at least one remote so
+                        * 1. find all the remotes
+                        * 2. store them in the PROP_REMOTE pval
+                        */
+                       p = rel->p = prop_create(v->sql->sa, PROP_REMOTE, 
rel->p);
+                       list *uris = sa_list(v->sql->sa);
+                       for (node *n = t->members->h; n; n = n->next) {
+                               sql_part *part = n->data;
+                               sql_table *ptable = 
find_sql_table_id(v->sql->session->tr, t->s, part->member);
+                               if (isRemote(ptable)) {
+                                       assert(ptable->query);
+                                       tid_uri *tu = SA_NEW(v->sql->sa, 
tid_uri);
+                                       tu->id = ptable->base.id;
+                                       tu->uri = mapiuri_uri(ptable->query, 
v->sql->sa);
+                                       append(uris, tu);
+                               }
+                       }
+                       p->value.pval = (void*)uris;
+               }
+       } break;
+       case op_table:
+               if (IS_TABLE_PROD_FUNC(rel->flag) || rel->flag == 
TABLE_FROM_RELATION) {
+                       if (l && (p = find_prop(l->p, PROP_REMOTE)) != NULL) {
+                               l->p = prop_remove(l->p, p);
+                               if (!find_prop(rel->p, PROP_REMOTE)) {
+                                       p->p = rel->p;
+                                       rel->p = p;
+                               }
+                       }
+               } break;
+       case op_join:
+       case op_left:
+       case op_right:
+       case op_full:
+
+       case op_semi:
+       case op_anti:
+
+       case op_union:
+       case op_inter:
+       case op_except:
+
+       case op_insert:
+       case op_update:
+       case op_delete:
+       case op_merge:
+
+               if (rel->flag&MERGE_LEFT) /* search for any remote tables but 
don't propagate over to this relation */
+                       return rel;
+
+               /* if both subtrees have REMOTE property with the common uri 
then pull it up */
+               if (l && (pl = find_prop(l->p, PROP_REMOTE)) != NULL &&
+                       r && (pr = find_prop(r->p, PROP_REMOTE)) != NULL) {
+
+                       /* find the common uris */
+                       list* uris = sa_list(v->sql->sa);
+                       // TODO this double loop must go (maybe use the hashmap 
of the list)
+                       for (node* n = ((list*)pl->value.pval)->h; n; n = 
n->next) {
+                               for (node* m = ((list*)pr->value.pval)->h; m; m 
= m->next) {
+                                       tid_uri* ltu = n->data;
+                                       tid_uri* rtu = m->data;
+                                       if (strcmp(ltu->uri, rtu->uri) == 0) {
+                                               append(uris, n->data);
+                                       }
+                               }
+                       }
+
+                       /* if there are common uris pull the REMOTE prop with 
the common uris up */
+                       if (!list_empty(uris)) {
+                               l->p = prop_remove(l->p, pl);
+                               r->p = prop_remove(r->p, pr);
+                               if (!find_prop(rel->p, PROP_REMOTE)) {
+                                       /* set the new (matching) uris */
+                                       pl->value.pval = uris;
+                                       /* push the pl REMOTE property to the 
list of properties */
+                                       pl->p = rel->p;
+                                       rel->p = pl;
+                               } else {
+                                       // TODO what if we are here? can that 
even happen?
+                               }
+                       }
+               }
+               break;
+       case op_project:
+       case op_select:
+       case op_groupby:
+       case op_topn:
+       case op_sample:
+       case op_truncate:
+               /* if the subtree has the REMOTE property just pull it up */
+               if (l && (p = find_prop(l->p, PROP_REMOTE)) != NULL) {
+                       l->p = prop_remove(l->p, p);
+                       if (!find_prop(rel->p, PROP_REMOTE)) {
+                               p->p = rel->p;
+                               rel->p = p;
+                       }
+               }
+               break;
+       case op_ddl:
+               // TODO properly handle the op_ddl
+               /*if (rel->flag == ddl_output || rel->flag == ddl_create_seq || 
rel->flag == ddl_alter_seq [>|| rel->flag == ddl_alter_table || rel->flag == 
ddl_create_table || rel->flag == ddl_create_view<]) {*/
+                       /*if (l && (p = find_prop(l->p, PROP_REMOTE)) != NULL) 
{*/
+                               /*l->p = prop_remove(l->p, p);*/
+                               /*if (!find_prop(rel->p, PROP_REMOTE)) {*/
+                                       /*p->p = rel->p;*/
+                                       /*rel->p = p;*/
+                               /*}*/
+                       /*}*/
+               /*} else if (rel->flag == ddl_list || rel->flag == 
ddl_exception) {*/
+                       /*if (l && (pl = find_prop(l->p, PROP_REMOTE)) != NULL 
&&*/
+                               /*r && (pr = find_prop(r->p, PROP_REMOTE)) != 
NULL &&*/
+                               /*strcmp(pl->value.pval, pr->value.pval) == 0) 
{*/
+                               /*l->p = prop_remove(l->p, pl);*/
+                               /*r->p = prop_remove(r->p, pr);*/
+                               /*if (!find_prop(rel->p, PROP_REMOTE)) {*/
+                                       /*pl->p = rel->p;*/
+                                       /*rel->p = pl;*/
+                               /*}*/
+                       /*}*/
+               /*}*/
+               break;
+       }
+       return rel;
+}
 
 static sql_rel *
 rel_rewrite_remote_(visitor *v, sql_rel *rel)
@@ -353,7 +510,10 @@ static sql_rel *
 rel_rewrite_remote(visitor *v, global_props *gp, sql_rel *rel)
 {
        (void) gp;
-       return rel_visitor_bottomup(v, rel, &rel_rewrite_remote_);
+       // TODO next call is no-op remove together with the rel_rewrite_remote_ 
impl
+       rel_visitor_bottomup(v, NULL, &rel_rewrite_remote_);
+       rel = rel_visitor_bottomup(v, rel, &rel_rewrite_remote_2_);
+       return rel;
 }
 
 run_optimizer
diff --git a/sql/server/rel_prop.c b/sql/server/rel_prop.c
--- a/sql/server/rel_prop.c
+++ b/sql/server/rel_prop.c
@@ -138,10 +138,16 @@ propvalue2string(sql_allocator *sa, prop
                }
        } break;
        case PROP_REMOTE: {
-               char *uri = p->value.pval;
-
-               if (uri)
-                       return sa_strdup(sa, uri);
+               list *tids_uris = p->value.pval;
+               if (!list_empty(tids_uris)) {
+                       size_t offset = 0;
+                       for (node *n = ((list*)p->value.pval)->h; n; n = 
n->next) {
+                               tid_uri *tu = n->data;
+                               if (tu->uri)
+                                       offset += snprintf(buf + offset, 
BUFSIZ, "[%d]%s\" ", tu->id, sql_escape_ident(sa, tu->uri));
+                       }
+                       return sa_strdup(sa, buf);
+               }
        } break;
        case PROP_MIN:
        case PROP_MAX: {
diff --git a/sql/server/rel_prop.h b/sql/server/rel_prop.h
--- a/sql/server/rel_prop.h
+++ b/sql/server/rel_prop.h
@@ -35,6 +35,12 @@ typedef struct prop {
        struct prop *p; /* some relations may have many properties, which are 
kept in a chain list */
 } prop;
 
+/* for REMOTE prop we need to keep a list with tids and uris for the remote 
tables */
+typedef struct tid_uri {
+       sqlid id;
+       const char* uri;
+} tid_uri;
+
 extern prop * prop_create( sql_allocator *sa, rel_prop kind, prop *pre );
 extern prop * prop_copy( sql_allocator *sa, prop *p);
 extern prop * prop_remove( prop *plist, prop *p);
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to