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