Changeset: 73e6feaccc18 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=73e6feaccc18
Removed Files:
        
sql/test/BugTracker-2020/Tests/values-like-join.Bug-6954.stable.out.single
Modified Files:
        sql/server/rel_dump.c
        sql/server/rel_prop.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-2009/Tests/use_order_column_first.SF-2686008.stable.out
        
sql/test/BugTracker-2010/Tests/LIMIT_OFFSET_big-endian.Bug-2622.stable.out
        
sql/test/BugTracker-2010/Tests/ORDER_BY_over_UNION_EXCEPT_INTERSECT.Bug-2606.stable.out
        sql/test/BugTracker-2011/Tests/crash_on_alias.Bug-2798.stable.out
        sql/test/BugTracker-2011/Tests/crash_on_alias.Bug-2798.stable.out.int128
        sql/test/BugTracker-2013/Tests/rangejoin_optimizer.Bug-3411.stable.out
        sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
        
sql/test/BugTracker-2015/Tests/crash_in_reduce_groupby.Bug-3818.stable.out
        sql/test/BugTracker-2015/Tests/large_join.Bug-3809.stable.out
        
sql/test/BugTracker-2015/Tests/quantile_function_resolution.Bug-3773.stable.out
        sql/test/BugTracker-2015/Tests/schema_view.Bug-3708.stable.out
        
sql/test/BugTracker-2016/Tests/memory-consumption-query-PLAN-25joins.Bug-3972.stable.out
        sql/test/BugTracker-2016/Tests/merge_project.Bug-3955.stable.out
        sql/test/BugTracker-2017/Tests/caching_stats_bug.6374.stable.out
        
sql/test/BugTracker-2017/Tests/sqlitelogictest-aggregation-having-avg.Bug-6428.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/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-0join-query.stable.out
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-0join-view.stable.out
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-1join-query.stable.out
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-1join-view.stable.out
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-2join-query.stable.out
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-2join-view.stable.out
        sql/test/Tests/keys.stable.out
        sql/test/Tests/order_by_complex_exp.stable.out
        sql/test/Tests/truncate-statements-extra.stable.out
        sql/test/astro/Tests/update.stable.out
        sql/test/merge-partitions/Tests/mergepart31.stable.out
        sql/test/mergetables/Tests/mergequery.stable.out
        sql/test/mergetables/Tests/part-elim.stable.out
        sql/test/miscellaneous/Tests/groupby_error.stable.out
        sql/test/miscellaneous/Tests/groupby_expressions.stable.out
        sql/test/miscellaneous/Tests/simple_plans.stable.out
        sql/test/out2in/Tests/out2in.stable.out.int128
Branch: Oct2020
Log Message:

Show identifiers between double quotes in the SQL plan and escape them properly 
on remote plan parsing. I will do the merge into default. I know the plans 
changed


diffs (truncated from 4089 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,11 +161,11 @@ 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\")",
                                        isStream(t)?"stream":
                                        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)
@@ -164,8 +183,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);
@@ -176,9 +195,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;
@@ -190,9 +209,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))
@@ -208,8 +227,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)
@@ -236,7 +255,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);
@@ -288,8 +307,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, ", ");
@@ -393,7 +412,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;
@@ -405,17 +425,17 @@ 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\")",
                                        isStream(t)?"stream":
                                        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\")",
                                        isStream(t)?"stream":
                                        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);
@@ -690,15 +710,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)
 {
@@ -756,30 +794,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);
@@ -788,7 +827,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;
@@ -850,17 +888,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);
@@ -905,11 +950,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);
-                               e = r+*pos;
-                               *e = 0;
+                               convertIdent(fname);
                                (*pos)++;
                                skipWS(r,pos);
                        }
@@ -960,6 +1004,7 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                                        return sql_error(sql, -1, 
SQLSTATE(42000) "Type: missing ')'\n");
                                (*pos)++;
                        }
+                       convertIdent(tname);
                        if (!(tpe = sql_bind_subtype(sql->sa, tname, d, s)))
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to