Changeset: 79ca55f34caf for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=79ca55f34caf
Modified Files:
        clients/mapiclient/dump.c
        clients/mapiclient/mclient.c
        gdk/gdk_string.c
        monetdb5/extras/mal_optimizer_template/Tests/opt_sql_append.stable.err
        monetdb5/extras/mal_optimizer_template/Tests/opt_sql_append.stable.out
        monetdb5/modules/mal/tablet.c
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql_result.c
        sql/backends/monet5/sql_result.h
        sql/backends/monet5/sql_statement.c
        sql/common/sql_string.c
        sql/common/sql_string.h
        sql/include/sql_catalog.h
        sql/jdbc/tests/Tests/BugResultSetMetaData_Bug_6183.stable.out
        sql/server/rel_dump.c
        sql/server/rel_updates.c
        sql/server/sql_atom.c
        sql/server/sql_parser.y
        sql/server/sql_scan.c
        sql/storage/bat/res_table.c
        sql/test/BugTracker-2009/Tests/copy_multiple_files.SF-2902320.stable.err
        
sql/test/BugTracker-2012/Tests/strange_escaping_in_csv.Bug-2133.stable.out
        sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
        
sql/test/BugTracker-2015/Tests/quantile_function_resolution.Bug-3773.stable.out
        sql/test/BugTracker-2017/Tests/crash-in-topn.Bug-6478.sql
        sql/test/BugTracker-2017/Tests/crash-on-limit-rename.Bug-6502.sql
        sql/test/BugTracker-2018/Tests/case_with_orderby_limit.Bug-6512.sql
        sql/test/Tests/identifiers.stable.err
        sql/test/Tests/identifiers.stable.out
        sql/test/emptydb/Tests/check.SQL.py
        sql/test/json/Tests/jsonvalidity.Bug-3753.stable.out
Branch: default
Log Message:

Convert SQL strings to internal format early on, i.e. when parsing.


diffs (truncated from 2212 to 300 lines):

diff --git a/clients/mapiclient/dump.c b/clients/mapiclient/dump.c
--- a/clients/mapiclient/dump.c
+++ b/clients/mapiclient/dump.c
@@ -86,9 +86,36 @@ get_comments_clause(Mapi mid)
 }
 
 static int
-quoted_print(stream *f, const char *s, bool singleq)
+dquoted_print(stream *f, const char *s, const char *suff)
 {
-       if (mnstr_write(f, singleq ? "'" : "\"", 1, 1) < 0)
+       size_t n;
+       if (mnstr_write(f, "\"", 1, 1) < 0)
+               return -1;
+       while (*s) {
+               if ((n = strcspn(s, "\"")) > 0) {
+                       if (mnstr_write(f, s, 1, n) < 0)
+                               return -1;
+                       s += n;
+               }
+               if (*s) {
+                       assert(*s == '"');
+                       if (mnstr_write(f, "\"\"", 1, 2) < 0)
+                               return -1;
+                       s++;
+               }
+       }
+       if (mnstr_write(f, "\"", 1, 1) < 0)
+               return -1;
+       if (suff != NULL && mnstr_printf(f, "%s", suff) < 0)
+               return -1;
+       return 0;
+}
+
+static int
+squoted_print(stream *f, const char *s, char quote)
+{
+       assert(quote == '\'' || quote == '"');
+       if (mnstr_printf(f, "%c", quote) < 0)
                return -1;
        while (*s) {
                switch (*s) {
@@ -96,12 +123,10 @@ quoted_print(stream *f, const char *s, b
                        if (mnstr_write(f, "\\\\", 1, 2) < 0)
                                return -1;
                        break;
+               case '\'':
                case '"':
-                       if (mnstr_write(f, "\"\"", 1, singleq ? 1 : 2) < 0)
-                               return -1;
-                       break;
-               case '\'':
-                       if (mnstr_write(f, "''", 1, singleq ? 2 : 1) < 0)
+                       if (mnstr_write(f, s, 1, 1) < 0 ||
+                           (*s == quote && mnstr_write(f, s, 1, 1) < 0))
                                return -1;
                        break;
                case '\n':
@@ -124,29 +149,78 @@ quoted_print(stream *f, const char *s, b
                }
                s++;
        }
-       if (mnstr_write(f, singleq ? "'" : "\"", 1, 1) < 0)
+       if (mnstr_printf(f, "%c", quote) < 0)
                return -1;
        return 0;
 }
 
+static char *
+descape(const char *s)
+{
+       const char *p;
+       size_t n = 1;
+
+       for (p = s; *p; p++) {
+               n += *p == '"';
+       }
+       n += p - s;
+       char *d = malloc(n);
+       if (d == NULL)
+               return NULL;
+       for (p = s, n = 0; *p; p++) {
+               d[n++] = *p;
+               if (*p == '"')
+                       d[n++] = '"';
+       }
+       d[n] = 0;
+       return d;
+}
+
+static char *
+sescape(const char *s)
+{
+       const char *p;
+       size_t n = 1;
+
+       for (p = s; *p; p++) {
+               n += *p == '\'' || *p == '\\';
+       }
+       n += p - s;
+       char *d = malloc(n);
+       if (d == NULL)
+               return NULL;
+       for (p = s, n = 0; *p; p++) {
+               d[n++] = *p;
+               if (*p == '\'')
+                       d[n++] = '\'';
+               else if (*p == '\\')
+                       d[n++] = '\\';
+       }
+       d[n] = 0;
+       return d;
+}
+
 static int
 comment_on(stream *toConsole, const char *object,
           const char *ident1, const char *ident2, const char *ident3,
           const char *remark)
 {
        if (remark) {
-               if (mnstr_printf(toConsole, "COMMENT ON %s \"%s\"", object, 
ident1) < 0)
+               if (mnstr_printf(toConsole, "COMMENT ON %s ", object) < 0 ||
+                   dquoted_print(toConsole, ident1, NULL) < 0)
                        return -1;
                if (ident2) {
-                       if (mnstr_printf(toConsole, ".\"%s\"", ident2) < 0)
+                       if (mnstr_printf(toConsole, ".") < 0 ||
+                           dquoted_print(toConsole, ident2, NULL) < 0)
                                return -1;
                        if (ident3) {
-                               if (mnstr_printf(toConsole, ".\"%s\"", ident3) 
< 0)
+                               if (mnstr_printf(toConsole, ".") < 0 ||
+                                   dquoted_print(toConsole, ident3, NULL) < 0)
                                        return -1;
                        }
                }
                if (mnstr_write(toConsole, " IS ", 1, 4) < 0 ||
-                   quoted_print(toConsole, remark, true) < 0 ||
+                   squoted_print(toConsole, remark, '\'') < 0 ||
                    mnstr_write(toConsole, ";\n", 1, 2) < 0)
                        return -1;
        }
@@ -335,7 +409,9 @@ dump_foreign_keys(Mapi mid, const char *
        size_t maxquerylen = 0;
 
        if (tname != NULL) {
-               maxquerylen = 1024 + strlen(tname) + strlen(schema);
+               char *s = sescape(schema);
+               char *t = sescape(tname);
+               maxquerylen = 1024 + strlen(t) + strlen(s);
                query = malloc(maxquerylen);
                if (query == NULL)
                        goto bailout;
@@ -367,7 +443,9 @@ dump_foreign_keys(Mapi mid, const char *
                           "AND fkt.schema_id = fs.id "
                           "AND fs.name = '%s' "
                           "AND fkt.name = '%s' "
-                        "ORDER BY fkk.name, fkkc.nr", schema, tname);
+                        "ORDER BY fkk.name, fkkc.nr", s, t);
+               free(s);
+               free(t);
        } else if (tid != NULL) {
                maxquerylen = 1024 + strlen(tid);
                query = malloc(maxquerylen);
@@ -487,26 +565,29 @@ dump_foreign_keys(Mapi mid, const char *
                        fkeys[nkeys - 1] = mapi_fetch_field(hdl, 3);
                }
                if (tname == NULL && tid == NULL) {
-                       mnstr_printf(toConsole,
-                                    "ALTER TABLE \"%s\".\"%s\" ADD ",
-                                    c_fsname, c_ftname);
+                       mnstr_printf(toConsole, "ALTER TABLE ");
+                       dquoted_print(toConsole, c_fsname, ".");
+                       dquoted_print(toConsole, c_ftname, " ADD ");
                } else {
                        mnstr_printf(toConsole, ",\n\t");
                }
                if (c_fkname) {
-                       mnstr_printf(toConsole, "CONSTRAINT \"%s\" ",
-                               c_fkname);
+                       mnstr_printf(toConsole, "CONSTRAINT ");
+                       dquoted_print(toConsole, c_fkname, " ");
                }
                mnstr_printf(toConsole, "FOREIGN KEY (");
                for (i = 0; i < nkeys; i++) {
-                       mnstr_printf(toConsole, "%s\"%s\"",
-                                    i > 0 ? ", " : "", fkeys[i]);
+                       if (i > 0)
+                               mnstr_printf(toConsole, ", ");
+                       dquoted_print(toConsole, fkeys[i], NULL);
                }
-               mnstr_printf(toConsole, ") REFERENCES \"%s\".\"%s\" (",
-                            c_psname, c_ptname);
+               mnstr_printf(toConsole, ") REFERENCES ");
+               dquoted_print(toConsole, c_psname, ".");
+               dquoted_print(toConsole, c_ptname, " (");
                for (i = 0; i < nkeys; i++) {
-                       mnstr_printf(toConsole, "%s\"%s\"",
-                                    i > 0 ? ", " : "", pkeys[i]);
+                       if (i > 0)
+                               mnstr_printf(toConsole, ", ");
+                       dquoted_print(toConsole, pkeys[i], NULL);
                }
                mnstr_printf(toConsole, ")");
                free((void *) fkeys);
@@ -728,16 +809,18 @@ dump_column_definition(Mapi mid, stream 
 {
        MapiHdl hdl = NULL;
        char *query = NULL;
+       char *s, *t;
        size_t maxquerylen = 1024;
        int cnt;
-       int slen;
        int cap;
 #define CAP(X) ((cap = (int) (X)) < 0 ? 0 : cap)
 
+       t = tname ? sescape(tname) : NULL;
+       s = schema ? sescape(schema) : NULL;
        if (tid == NULL) {
                if (tname == NULL || schema == NULL)
                        return 1;
-               maxquerylen += strlen(tname) + strlen(schema);
+               maxquerylen += 2 * strlen(tname) + 2 * strlen(schema);
        }
        else
                maxquerylen += strlen(tid);
@@ -771,14 +854,13 @@ dump_column_definition(Mapi mid, stream 
                              "sys._tables t, "
                              "sys.schemas s "
                         "WHERE c.table_id = t.id "
-                          "AND '%s' = t.name "
+                          "AND t.name = '%s' "
                           "AND t.schema_id = s.id "
                           "AND s.name = '%s' "
-                        "ORDER BY c.number", tname, schema);
+                        "ORDER BY c.number", t, s);
        if ((hdl = mapi_query(mid, query)) == NULL || mapi_error(mid))
                goto bailout;
 
-       slen = mapi_get_len(hdl, 0);
        cnt = 0;
        while ((mapi_fetch_row(hdl)) != 0) {
                const char *c_name = mapi_fetch_field(hdl, 0);
@@ -794,8 +876,8 @@ dump_column_definition(Mapi mid, stream 
                if (cnt)
                        mnstr_printf(toConsole, ",\n");
 
-               mnstr_printf(toConsole, "\t\"%s\"%*s ",
-                            c_name, CAP(slen - strlen(c_name)), "");
+               mnstr_printf(toConsole, "\t");
+               dquoted_print(toConsole, c_name, " ");
                space = dump_type(mid, toConsole, c_type, c_type_digits, 
c_type_scale, hashge);
                if (strcmp(c_null, "false") == 0) {
                        mnstr_printf(toConsole, "%*s NOT NULL",
@@ -846,7 +928,7 @@ dump_column_definition(Mapi mid, stream 
                           "AND t.schema_id = s.id "
                           "AND s.name = '%s' "
                           "AND t.name = '%s' "
-                        "ORDER BY kc.id, kc.nr", schema, tname);
+                        "ORDER BY kc.id, kc.nr", s, t);
        if ((hdl = mapi_query(mid, query)) == NULL || mapi_error(mid))
                goto bailout;
        cnt = 0;
@@ -859,13 +941,13 @@ dump_column_definition(Mapi mid, stream 
                if (cnt == 0) {
                        mnstr_printf(toConsole, ",\n\t");
                        if (k_name) {
-                               mnstr_printf(toConsole, "CONSTRAINT \"%s\" ",
-                                       k_name);
+                               mnstr_printf(toConsole, "CONSTRAINT ");
+                               dquoted_print(toConsole, k_name, " ");
                        }
                        mnstr_printf(toConsole, "PRIMARY KEY (");
                } else
                        mnstr_printf(toConsole, ", ");
-               mnstr_printf(toConsole, "\"%s\"", c_column);
+               dquoted_print(toConsole, c_column, NULL);
                cnt++;
                if (mnstr_errnr(toConsole))
                        goto bailout;
@@ -905,7 +987,7 @@ dump_column_definition(Mapi mid, stream 
                           "AND t.schema_id = s.id "
                           "AND s.name = '%s' "
                           "AND t.name = '%s' "
-                        "ORDER BY kc.id, kc.nr", schema, tname);
+                        "ORDER BY kc.id, kc.nr", s, t);
        if ((hdl = mapi_query(mid, query)) == NULL || mapi_error(mid))
                goto bailout;
        cnt = 0;
@@ -921,14 +1003,14 @@ dump_column_definition(Mapi mid, stream 
                                mnstr_write(toConsole, ")", 1, 1);
                        mnstr_printf(toConsole, ",\n\t");
                        if (k_name) {
-                               mnstr_printf(toConsole, "CONSTRAINT \"%s\" ",
-                                       k_name);
+                               mnstr_printf(toConsole, "CONSTRAINT ");
+                               dquoted_print(toConsole, k_name, " ");
                        }
                        mnstr_printf(toConsole, "UNIQUE (");
                        cnt = 1;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to