Changeset: bf888184fc89 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=bf888184fc89
Modified Files:
sql/server/rel_dump.c
sql/test/BugTracker-2009/Tests/copy_multiple_files.SF-2902320.stable.out
sql/test/BugTracker-2009/Tests/copy_multiple_files.SF-2902320.stable.out.Windows
sql/test/BugTracker-2011/Tests/crash_on_alias.Bug-2798.stable.out
sql/test/BugTracker-2018/Tests/count_from_commented_function_signatures.Bug-6542.stable.out
sql/test/BugTracker-2018/Tests/local_replica_table_not_detected.Bug-6620.stable.out
sql/test/BugTracker-2020/Tests/table-udf-on-remote.Bug-6971.py
sql/test/BugTracker-2020/Tests/table-udf-on-remote.Bug-6971.stable.out
sql/test/BugTracker-2020/Tests/values-like-join.Bug-6954.sql
sql/test/BugTracker-2020/Tests/values-like-join.Bug-6954.stable.out
sql/test/BugTracker/Tests/jdbc_no_debug.SF-1739356.stable.out
sql/test/miscellaneous/Tests/groupby_error.stable.out
sql/test/miscellaneous/Tests/groupby_prepare.stable.out
sql/test/miscellaneous/Tests/simple_plans.stable.out
sql/test/out2in/Tests/out2in.stable.out
Branch: default
Log Message:
Merged with Oct2020
diffs (truncated from 3606 to 300 lines):
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -75,6 +75,25 @@ cmp_print(mvc *sql, stream *fout, int cm
mnstr_printf(fout, " %s ", r);
}
+static const char *
+dump_escape_ident(sql_allocator *sa, const char *s)
+{
+ char *res = NULL;
+ if (s) {
+ size_t l = strlen(s);
+ char *r = SA_NEW_ARRAY(sa, char, (l * 2) + 1);
+
+ res = r;
+ while (*s) {
+ if (*s == '"')
+ *r++ = '\\';
+ *r++ = *s++;
+ }
+ *r = '\0';
+ }
+ return res;
+}
+
static void exps_print(mvc *sql, stream *fout, list *exps, int depth, list
*refs, int alias, int brackets);
static void
@@ -90,8 +109,8 @@ exp_print(mvc *sql, stream *fout, sql_ex
const char *rname = exp_relname(e);
int level = GET_PSM_LEVEL(e->flag);
if (rname)
- mnstr_printf(fout, "\"%s\".", rname);
- mnstr_printf(fout, "\"%s\" = ", exp_name(e));
+ mnstr_printf(fout, "\"%s\".",
dump_escape_ident(sql->ta, rname));
+ mnstr_printf(fout, "\"%s\" = ",
dump_escape_ident(sql->ta, exp_name(e)));
exp_print(sql, fout, e->l, depth, refs, 0, 0);
mnstr_printf(fout, " FRAME %d ", level);
alias = 0;
@@ -102,8 +121,8 @@ exp_print(mvc *sql, stream *fout, sql_ex
int level = GET_PSM_LEVEL(e->flag);
mnstr_printf(fout, "declare ");
if (rname)
- mnstr_printf(fout, "\"%s\".", rname);
- mnstr_printf(fout, "\"%s\" %s FRAME %d ", exp_name(e),
type_str ? type_str : "", level);
+ mnstr_printf(fout, "\"%s\".",
dump_escape_ident(sql->ta, rname));
+ mnstr_printf(fout, "\"%s\" %s FRAME %d ",
dump_escape_ident(sql->ta, exp_name(e)), type_str ? type_str : "", level);
alias = 0;
} else if (e->flag & PSM_RETURN) {
int level = GET_PSM_LEVEL(e->flag);
@@ -142,10 +161,10 @@ exp_print(mvc *sql, stream *fout, sql_ex
atom *a = e->l;
if (atom_type(a)->type->localtype == TYPE_ptr) {
sql_table *t = a->data.val.pval;
- mnstr_printf(fout, "%s(%s)",
+ mnstr_printf(fout, "%s(\"%s\")",
isMergeTable(t)?"merge table":
isReplicaTable(t)?"replica
table":"table",
- t->base.name);
+ dump_escape_ident(sql->ta,
t->base.name));
} else {
char *t = sql_subtype_string(sql->ta,
atom_type(a));
if (a->isnull)
@@ -163,8 +182,8 @@ exp_print(mvc *sql, stream *fout, sql_ex
if (e->r) { /* named parameters and declared variables
*/
sql_var_name *vname = (sql_var_name*) e->r;
if (vname->sname)
- mnstr_printf(fout, "\"%s\".",
vname->sname);
- mnstr_printf(fout, "\"%s\"", vname->name);
+ mnstr_printf(fout, "\"%s\".",
dump_escape_ident(sql->ta, vname->sname));
+ mnstr_printf(fout, "\"%s\"",
dump_escape_ident(sql->ta, vname->name));
} else if (e->f) { /* values list */
list *l = e->f;
exps_print(sql, fout, l, depth, refs, 0, 0);
@@ -175,9 +194,9 @@ exp_print(mvc *sql, stream *fout, sql_ex
} break;
case e_func: {
sql_subfunc *f = e->f;
- mnstr_printf(fout, "%s.%s",
- f->func->s?f->func->s->base.name:"sys",
- f->func->base.name);
+ mnstr_printf(fout, "\"%s\".\"%s\"",
+ f->func->s?dump_escape_ident(sql->ta,
f->func->s->base.name):"sys",
+ dump_escape_ident(sql->ta, f->func->base.name));
exps_print(sql, fout, e->l, depth, refs, alias, 1);
if (e->r) { /* list of optional lists */
list *l = e->r;
@@ -189,9 +208,9 @@ exp_print(mvc *sql, stream *fout, sql_ex
} break;
case e_aggr: {
sql_subfunc *a = e->f;
- mnstr_printf(fout, "%s.%s",
- a->func->s?a->func->s->base.name:"sys",
- a->func->base.name);
+ mnstr_printf(fout, "\"%s\".\"%s\"",
+ a->func->s?dump_escape_ident(sql->ta,
a->func->s->base.name):"sys",
+ dump_escape_ident(sql->ta, a->func->base.name));
if (need_distinct(e))
mnstr_printf(fout, " unique ");
if (need_no_nil(e))
@@ -207,8 +226,8 @@ exp_print(mvc *sql, stream *fout, sql_ex
if (is_freevar(e))
mnstr_printf(fout, "!!!FREE!!! ");
if (e->l)
- mnstr_printf(fout, "\"%s\".", (char*)e->l);
- mnstr_printf(fout, "\"%s\"", (char*)e->r);
+ mnstr_printf(fout, "\"%s\".",
dump_escape_ident(sql->ta, (char*)e->l));
+ mnstr_printf(fout, "\"%s\"", dump_escape_ident(sql->ta,
(char*)e->r));
if (exp_relname(e) && exp_name(e) && e->l && e->r &&
strcmp(exp_relname(e), e->l) == 0 &&
strcmp(exp_name(e), e->r) == 0)
@@ -235,7 +254,7 @@ exp_print(mvc *sql, stream *fout, sql_ex
exps_print(sql, fout, e->l, depth, refs, alias, 1);
if (is_anti(e))
mnstr_printf(fout, " !");
- mnstr_printf(fout, " FILTER %s ", f->func->base.name);
+ mnstr_printf(fout, " FILTER \"%s\" ",
dump_escape_ident(sql->ta, f->func->base.name));
exps_print(sql, fout, e->r, depth, refs, alias, 1);
} else if (e->f) {
exp_print(sql, fout, e->r, depth+1, refs, 0, 0);
@@ -287,8 +306,8 @@ exp_print(mvc *sql, stream *fout, sql_ex
if (exp_name(e) && alias) {
mnstr_printf(fout, " as ");
if (exp_relname(e))
- mnstr_printf(fout, "\"%s\".", exp_relname(e));
- mnstr_printf(fout, "\"%s\"", exp_name(e));
+ mnstr_printf(fout, "\"%s\".",
dump_escape_ident(sql->ta, exp_relname(e)));
+ mnstr_printf(fout, "\"%s\"", dump_escape_ident(sql->ta,
exp_name(e)));
}
if (comma)
mnstr_printf(fout, ", ");
@@ -392,7 +411,8 @@ rel_print_(mvc *sql, stream *fout, sql_
sql_column *c = rel->r;
if (!t && c) {
- mnstr_printf(fout, "dict(%s.%s)", c->t->base.name,
c->base.name);
+ mnstr_printf(fout, "dict(\"%s\".\"%s\")",
+ dump_escape_ident(sql->ta,
c->t->base.name), dump_escape_ident(sql->ta, c->base.name));
} else {
const char *sname = t->s ? t->s->base.name : NULL; /*
All tables, but declared ones on the stack have schema */
const char *tname = t->base.name;
@@ -404,15 +424,15 @@ rel_print_(mvc *sql, stream *fout, sql_
tname = mapiuri_table( uri, sql->sa, tname);
}
if (sname)
- mnstr_printf(fout, "%s(%s.%s)",
+ mnstr_printf(fout, "%s(\"%s\".\"%s\")",
isRemote(t)&&decorate?"REMOTE":
isReplicaTable(t)?"REPLICA":"table",
- sname, tname);
+ dump_escape_ident(sql->ta, sname),
dump_escape_ident(sql->ta, tname));
else
- mnstr_printf(fout, "%s(%s)",
+ mnstr_printf(fout, "%s(\"%s\")",
isRemote(t)&&decorate?"REMOTE":
isReplicaTable(t)?"REPLICA":"table",
- tname);
+ dump_escape_ident(sql->ta, tname));
}
if (rel->exps)
exps_print(sql, fout, rel->exps, depth, refs, 1, 0);
@@ -687,15 +707,33 @@ skipIdent( char *r, int *pos)
{
if (r[*pos] == '"') {
(*pos)++;
- while(r[*pos] && r[*pos] != '"')
- (*pos)++;
- (*pos)++;
+ while(r[*pos] && r[*pos] != '"') {
+ if (r[*pos] == '\\' && r[*pos + 1] == '"') /* We send
escaped '"' character, so consider this pair as just one */
+ (*pos)+=2;
+ else
+ (*pos)++;
+ }
} else {
while(r[*pos] && (isalnum((unsigned char) r[*pos]) || r[*pos]
== '_' || r[*pos] == '%'))
(*pos)++;
}
}
+static void /* We send escaped '"' character, so remove the escape after
parsing */
+convertIdent(char *r)
+{
+ int i = 0, j = 0;
+ while(r[i] && r[i] != '"') {
+ if (r[i] == '\\' && r[i + 1] == '"') {
+ r[j++] = '"';
+ i+=2;
+ } else {
+ r[j++] = r[i++];
+ }
+ }
+ r[i] = '\0';
+}
+
static void
skipIdentOrSymbol( char *r, int *pos)
{
@@ -734,8 +772,12 @@ readString( char *r, int *pos)
if (r[*pos] == '"'){
(*pos)++;
st = r+*pos;
- while (r[*pos] != '"')
- (*pos)++;
+ while (r[*pos] != '"') {
+ if (r[*pos] == '\\' && r[*pos + 1] == '"')
+ (*pos)+=2;
+ else
+ (*pos)++;
+ }
r[*pos] = 0;
(*pos)++;
}
@@ -749,30 +791,31 @@ read_prop( mvc *sql, sql_exp *exp, char
{
/* PROPs */
if (strncmp(r+*pos, "JOINIDX", strlen("JOINIDX")) == 0) {
- int old;
- char *sname,*iname;
+ char *sname, *tname, *iname;
sql_schema *s = NULL;
prop *p;
(*pos)+= (int) strlen("JOINIDX");
skipWS(r, pos);
/* schema.table.index */
- sname = r+*pos;
+ sname = r+*pos + 1;
skipIdent(r,pos);
+ convertIdent(sname);
+ (*pos)++;
if (r[*pos] != '.')
return sql_error(sql, -1, SQLSTATE(42000) "JOINIDX:
missing '.'\n");
- r[*pos] = 0;
+ tname = r+*pos + 1;
+ skipIdent(r,pos);
+ convertIdent(tname);
(*pos)++;
- skipIdent(r,pos);
if (r[*pos] != '.')
return sql_error(sql, -1, SQLSTATE(42000) "JOINIDX:
missing '.'\n");
- r[*pos] = 0;
- (*pos)++;
- iname = r+*pos;
+ iname = r+*pos + 1;
skipIdent(r,pos);
- old = r[*pos];
- r[*pos] = 0;
+ convertIdent(iname);
+ (*pos)++;
+ (void) tname;
s = mvc_bind_schema(sql, sname);
if (sname && !s)
return sql_error(sql, -1, SQLSTATE(42000) "Schema %s
missing\n", sname);
@@ -781,7 +824,6 @@ read_prop( mvc *sql, sql_exp *exp, char
if (!(p->value = mvc_bind_idx(sql, s, iname)))
return sql_error(sql, -1, SQLSTATE(42000)
"Index %s missing\n", iname);
}
- r[*pos] = old;
skipWS(r,pos);
}
return exp;
@@ -843,17 +885,24 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
quote = (r[*pos] == '"');
b += quote;
skipIdent(r, pos);
- e = r+*pos-quote;
+ e = r+*pos;
+ (*pos) += quote;
skipWS(r, pos);
switch(r[*pos]) {
case '.':
*e = 0;
(*pos)++;
tname = b;
+ convertIdent(tname);
cname = r + *pos + quote;
skipIdentOrSymbol(r, pos);
- e = r+*pos - quote;
- old = *e;
+ e = r+*pos;
+ if (quote) {
+ old = ' ';
+ convertIdent(cname);
+ } else {
+ old = *e;
+ }
*e = 0;
tname = sa_strdup(sql->sa, tname);
@@ -898,11 +947,10 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
}
skipWS(r, pos);
if (filter) {
- fname = r+*pos;
+ fname = r+*pos + 1;
skipIdent(r,pos);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list