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 -- [email protected]
To unsubscribe send an email to [email protected]