Changeset: e274dae813b9 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/e274dae813b9
Branch: literal_features
Log Message:

merge with default


diffs (truncated from 696 to 300 lines):

diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -16,7 +16,6 @@ jobs:
     strategy:
       fail-fast: false  # don't stop other jobs
       matrix:
-        branch: [ master ]
         os: [ ubuntu-latest, macos-latest, windows-latest ]
         c_compiler: [ gcc, clang, cl ]
         include:
@@ -42,13 +41,11 @@ jobs:
           - os: ubuntu-latest
             c_compiler: cl
     runs-on: ${{ matrix.os }}
-    env:
-      CTEST: ${{ runner.os == 'Windows' && 'RUN_TESTS' || 'test' }}
     steps:
       - name: Checkout
         uses: actions/checkout@v3
         with:
-          ref: ${{ matrix.branch }}
+          ref: ${{ github.ref }}
 
       - name: install pymonetdb cryptography
         run: pip3 install pymonetdb cryptography
@@ -106,13 +103,22 @@ jobs:
       - name: ctest 
         run: |
           cd build 
-          cmake --build . --target ${{ CTEST }}
+          cmake --build . --target ${{ runner.os == 'Windows' && 'RUN_TESTS' 
|| 'test' }}
+        if: runner.os != 'Windows'
 
       - name: mtest 
         run: |
           PATH=$HOME/MDB/bin:$PATH $HOME/MDB/bin/Mtest.py -r --debug=0 --ci 
--no-html --TSTTRGBASE=.
         if: runner.os != 'Windows'
 
+      - name: ctest 
+        shell: pwsh
+        run: |
+          $env:PATH = 
'C:\MDB\lib;C:\MDB\lib\monetdb5;C:\MDB\bin;C:\vcpkg\installed\x64-windows\bin;C:\vcpkg\installed\x64-windows\debug\bin;'
 + $env:PATH
+          cd build 
+          cmake --build . --target ${{ runner.os == 'Windows' && 'RUN_TESTS' 
|| 'test' }}
+        if: runner.os == 'Windows'
+
       - name: mtest 
         shell: pwsh
         run: |
@@ -125,5 +131,5 @@ jobs:
       - name: Publish mtest results
         uses: actions/upload-artifact@v3
         with:
-          name: mtest-${{ matrix.branch }}-${{ matrix.os }}-${{ 
matrix.c_compiler }}
+          name: mtest-${{ github.sha }}-${{ matrix.os }}-${{ matrix.c_compiler 
}}
           path: mtests.tar
diff --git a/sql/backends/monet5/sql_gencode.c 
b/sql/backends/monet5/sql_gencode.c
--- a/sql/backends/monet5/sql_gencode.c
+++ b/sql/backends/monet5/sql_gencode.c
@@ -354,7 +354,8 @@ static int
        Client c = MCgetClient(m->clientid);
        MalBlkPtr curBlk = 0;
        InstrPtr curInstr = 0, p, o;
-       sqlid table_id = prp->id;
+       tid_uri *tu = ((list*)prp->value.pval)->h->data;
+       sqlid table_id = tu->id;
        node *n;
        int i, q, v, res = -1, added_to_cache = 0, *lret, *rret;
        size_t len = 1024, nr, pwlen = 0;
@@ -389,6 +390,7 @@ static int
 
        sql_table *rt = sql_trans_find_table(m->session->tr, table_id);
        const char *uri = mapiuri_uri(rt->query, m->sa);
+       assert(strcmp(tu->uri, uri) == 0);
        if (!rt) {
                sql_error(m, 10, SQLSTATE(HY013) MAL_MALLOC_FAIL);
                goto cleanup;
@@ -928,8 +930,12 @@ static int
        Symbol symbackup = c->curprg;
        exception_buffer ebsave = m->sa->eb;
 
-       if (prp->id == 0) {
-               sql_error(m, 003, SQLSTATE(42000) "Missing property on the 
input relation");
+       if (list_empty(prp->value.pval)) {
+               sql_error(m, 003, SQLSTATE(42000) "Missing REMOTE property on 
the input relation");
+               goto bailout;
+       }
+       if (list_length(prp->value.pval) != 1) {
+               sql_error(m, 003, SQLSTATE(42000) "REMOTE property on the input 
relation is NOT unique");
                goto bailout;
        }
        if (strlen(mod) >= IDLENGTH) {
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
@@ -15,6 +15,12 @@
 #include "rel_remote.h"
 #include "sql_privileges.h"
 
+typedef struct rmt_prop_state {
+       int depth;
+       prop* rmt;
+       sql_rel* orig;
+} rps;
+
 static int
 has_remote_or_replica( sql_rel *rel )
 {
@@ -66,7 +72,7 @@ has_remote_or_replica( sql_rel *rel )
 }
 
 static sql_rel *
-rewrite_replica(mvc *sql, list *exps, sql_table *t, sql_table *p, int 
remote_prop)
+do_replica_rewrite(mvc *sql, list *exps, sql_table *t, sql_table *p, int 
remote_prop)
 {
        node *n, *m;
        sql_rel *r = rel_basetable(sql, p, t->base.name);
@@ -96,11 +102,15 @@ rewrite_replica(mvc *sql, list *exps, sq
 
        /* set_remote() */
        if (remote_prop && p && isRemote(p)) {
-               sqlid id = p->base.id;
-               char *local_name = sa_strconcat(sql->sa, sa_strconcat(sql->sa, 
p->s->base.name, "."), p->base.name);
-               prop *p = r->p = prop_create(sql->sa, PROP_REMOTE, r->p);
-               p->id = id;
-               p->value.pval = local_name;
+               list *uris = sa_list(sql->sa);
+               tid_uri *tu = SA_NEW(sql->sa, tid_uri);
+               tu->id = p->base.id;
+               tu->uri = sa_strconcat(sql->sa, sa_strconcat(sql->sa, 
p->s->base.name, "."), p->base.name);
+               append(uris, tu);
+
+               prop *rmt_prop = r->p = prop_create(sql->sa, PROP_REMOTE, r->p);
+               rmt_prop->id = p->base.id;
+               rmt_prop->value.pval = uris;
        }
        return r;
 }
@@ -109,24 +119,33 @@ static sql_rel *
 replica_rewrite(visitor *v, sql_table *t, list *exps)
 {
        sql_rel *res = NULL;
-       const char *uri = (const char *) v->data;
+       prop *rp = ((rps*)v->data)->rmt;
+       sqlid tid = rp->id;
+       list *uris = rp->value.pval;
 
        if (mvc_highwater(v->sql))
                return sql_error(v->sql, 10, SQLSTATE(42000) "Query too 
complex: running out of stack space");
 
-       if (uri) {
-               /* replace by the replica which matches the uri */
-               for (node *n = t->members->h; n; n = n->next) {
+       /* if there was a REMOTE property in any higher node and there is not
+        * a local tid then use the available uris to rewrite */
+       if (uris && !tid) {
+               for (node *n = t->members->h; n && !res; n = n->next) {
                        sql_part *p = n->data;
                        sql_table *pt = find_sql_table_id(v->sql->session->tr, 
t->s, p->member);
 
-                       if (isRemote(pt) && strcmp(uri, pt->query) == 0) {
-                               res = rewrite_replica(v->sql, exps, t, pt, 0);
-                               break;
+                       if (!isRemote(pt))
+                               continue;
+
+                       for (node *m = uris->h; m && !res; m = m->next) {
+                               if (strcmp(((tid_uri*)m->data)->uri, pt->query) 
== 0) {
+                                       res = do_replica_rewrite(v->sql, exps, 
t, pt, 0);
+                               }
                        }
                }
        }
-       if (!res) { /* no match, find one without remote or use first */
+
+       /* no match, find one without remote or use first */
+       if (!res) {
                sql_table *pt = NULL;
                int remote = 1;
 
@@ -138,6 +157,10 @@ replica_rewrite(visitor *v, sql_table *t
                        if (!isRemote(next) && ((!isReplicaTable(next) && 
!isMergeTable(next)) || !list_empty(next->members))) {
                                pt = next;
                                remote = 0;
+                               /* if we resolved the replica to a local table 
we have to
+                                * go and remove the remote property from the 
subtree */
+                               sql_rel *r = ((rps*)v->data)->orig;
+                               r->p = prop_remove(r->p, rp);
                                break;
                        }
                }
@@ -149,29 +172,64 @@ replica_rewrite(visitor *v, sql_table *t
                if ((isMergeTable(pt) || isReplicaTable(pt)) && 
list_empty(pt->members))
                        return sql_error(v->sql, 02, SQLSTATE(42000) "%s 
'%s'.'%s' should have at least one table associated",
                                                        
TABLE_TYPE_DESCRIPTION(pt->type, pt->properties), pt->s->base.name, 
pt->base.name);
-               res = isReplicaTable(pt) ? replica_rewrite(v, pt, exps) : 
rewrite_replica(v->sql, exps, t, pt, remote);
+               res = isReplicaTable(pt) ? replica_rewrite(v, pt, exps) : 
do_replica_rewrite(v->sql, exps, t, pt, remote);
        }
        return res;
 }
 
+static bool
+eliminate_remote_or_replica_refs(visitor *v, sql_rel **rel)
+{
+       if (rel_is_ref(*rel) && !((*rel)->flag&MERGE_LEFT)) {
+               if (has_remote_or_replica(*rel)) {
+                       sql_rel *nrel = rel_copy(v->sql, *rel, 1);
+                       rel_destroy(*rel);
+                       *rel = nrel;
+                       return true;
+               } else {
+                       // TODO why do we want to bail out if we have a non 
rmt/rpl ref?
+                       return false;
+               }
+       }
+       return true;
+}
+
 static sql_rel *
 rel_rewrite_replica_(visitor *v, sql_rel *rel)
 {
-       /* for merge statement join, ignore the multiple references */
-       if (rel_is_ref(rel) && !(rel->flag&MERGE_LEFT)) {
-               if (has_remote_or_replica(rel)) {
-                       sql_rel *nrel = rel_copy(v->sql, rel, 1);
+       if (!eliminate_remote_or_replica_refs(v, &rel))
+               return rel;
 
-                       rel_destroy(rel);
-                       rel = nrel;
-               } else {
-                       return rel;
+       /* no-leaf nodes: store the REMOTE property uris in the state of the 
visitor
+        * leaf nodes: check if they are basetable replicas and proceed with 
the rewrite */
+       prop *p;
+       if (!is_basetable(rel->op)) {
+               /* if we are higher in the tree clear the previous REMOTE prop 
in the visitor state */
+               if (v->data && v->depth <= ((rps*)v->data)->depth) {
+                       v->data = NULL;
                }
-       }
-       if (is_basetable(rel->op)) {
+               /* if there is a REMOTE prop set it to the visitor state */
+               if ((p = find_prop(rel->p, PROP_REMOTE)) != NULL) {
+                       rps *rp = SA_NEW(v->sql->sa, rps);
+                       rp->depth = v->depth;
+                       rp->rmt = p;
+                       rp->orig = rel;
+                       v->data = rp;
+               }
+       } else {
                sql_table *t = rel->l;
 
                if (t && isReplicaTable(t)) {
+                       /* we might have reached a replica table through a 
branch that has
+                        * no REMOTE property. In this case we have to set the 
v->data */
+                       if (!v->data && (p = find_prop(rel->p, PROP_REMOTE)) != 
NULL) {
+                               rps *rp = SA_NEW(v->sql->sa, rps);
+                               rp->depth = v->depth;
+                               rp->rmt = p;
+                               rp->orig = rel;
+                               v->data = rp;
+                       }
+
                        if (list_empty(t->members)) /* in DDL statement cases 
skip if replica is empty */
                                return rel;
 
@@ -187,7 +245,7 @@ static sql_rel *
 rel_rewrite_replica(visitor *v, global_props *gp, sql_rel *rel)
 {
        (void) gp;
-       return rel_visitor_bottomup(v, rel, &rel_rewrite_replica_);
+       return rel_visitor_topdown(v, rel, &rel_rewrite_replica_);
 }
 
 run_optimizer
@@ -197,23 +255,31 @@ bind_rewrite_replica(visitor *v, global_
        return gp->needs_mergetable_rewrite || gp->needs_remote_replica_rewrite 
? rel_rewrite_replica : NULL;
 }
 
+static list*
+rel_merge_remote_prop(visitor *v, prop *pl, prop *pr)
+{
+       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);
+                       }
+               }
+       }
+       return uris;
+}
 
 static sql_rel *
 rel_rewrite_remote_(visitor *v, sql_rel *rel)
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to