Changeset: ce4661cba640 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ce4661cba640
Modified Files:
sql/server/sql_semantic.c
sql/test/merge-partitions/Tests/mergepart20.sql
sql/test/merge-partitions/Tests/mergepart20.stable.out
Branch: Nov2019
Log Message:
Reverted string escape and removed remaining sprintf calls which could leave
the output string 'buf' truncated
diffs (292 lines):
diff --git a/sql/server/sql_semantic.c b/sql/server/sql_semantic.c
--- a/sql/server/sql_semantic.c
+++ b/sql/server/sql_semantic.c
@@ -307,73 +307,107 @@ dlist2string(mvc *sql, dlist *l, int exp
char *
symbol2string(mvc *sql, symbol *se, int expression, char **err) /**/
{
- int len = 0;
- char buf[BUFSIZ];
-
- buf[0] = 0;
switch (se->token) {
case SQL_NOP: {
- dnode *lst = se->data.lval->h;
- dnode *ops = lst->next->data.lval->h;
- char *op = qname_fname(lst->data.lval);
+ dnode *lst = se->data.lval->h, *ops = lst->next->data.lval->h,
*aux;
+ const char *op = qname_fname(lst->data.lval), *sname =
qname_schema(lst->data.lval);
+ int i = 0, nargs = 0;
+ char** inputs = NULL, *res;
+ size_t inputs_length = 0;
+
+ if (!sname)
+ sname = sql->session->schema->base.name;
+
+ for (aux = ops; aux; aux = aux->next) nargs++;
+ inputs = GDKzalloc(nargs * sizeof(char**));
- len = snprintf( buf+len, BUFSIZ-len, "%s(", op);
- for (; ops; ops = ops->next) {
- char *tmp = symbol2string(sql, ops->data.sym,
expression, err);
- if (tmp == NULL)
+ for (aux = ops; aux; aux = aux->next) {
+ if (!(inputs[i] = symbol2string(sql, aux->data.sym,
expression, err))) {
+ for (int j = 0; j < i; j++)
+ GDKfree(inputs[j]);
+ GDKfree(inputs);
return NULL;
- len = snprintf( buf+len, BUFSIZ-len, "%s%s",
- tmp,
- (ops->next)?",":"");
- _DELETE(tmp);
+ }
+ inputs_length += strlen(inputs[i]);
+ i++;
}
- len = snprintf( buf+len, BUFSIZ-len, ")");
+
+ if ((res = NEW_ARRAY(char, strlen(sname) + strlen(op) +
inputs_length + 6 + (nargs - 1 /* commas */) + 2))) {
+ char *concat = stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res,
"\""), sname), "\".\""), op), "\"(");
+ i = 0;
+ for (aux = ops; aux; aux = aux->next) {
+ concat = stpcpy(concat, inputs[i]);
+ if (aux->next)
+ concat = stpcpy(concat, ",");
+ i++;
+ }
+ concat = stpcpy(concat, ")");
+ }
+
+ for (int j = 0; j < nargs; j++)
+ GDKfree(inputs[j]);
+ GDKfree(inputs);
+ return res;
} break;
case SQL_BINOP: {
dnode *lst = se->data.lval->h;
- char *op = qname_fname(lst->data.lval);
- char *l;
- char *r;
- l = symbol2string(sql, lst->next->data.sym, expression, err);
- if (l == NULL)
- return NULL;
- r = symbol2string(sql, lst->next->next->data.sym, expression,
err);
- if (r == NULL) {
+ const char *op = qname_fname(lst->data.lval), *sname =
qname_schema(lst->data.lval);
+ char *l = NULL, *r = NULL, *res;
+
+ if (!sname)
+ sname = sql->session->schema->base.name;
+ if (!(l = symbol2string(sql, lst->next->data.sym, expression,
err)) || !(r = symbol2string(sql, lst->next->next->data.sym, expression, err)))
{
_DELETE(l);
+ _DELETE(r);
return NULL;
}
- len = snprintf( buf+len, BUFSIZ-len, "%s(%s,%s)", op, l, r);
+
+ if ((res = NEW_ARRAY(char, strlen(sname) + strlen(op) +
strlen(l) + strlen(r) + 9)))
+
stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "\""),
sname), "\".\""), op), "\"("), l), ","), r), ")");
+
_DELETE(l);
_DELETE(r);
+ return res;
} break;
case SQL_OP: {
dnode *lst = se->data.lval->h;
- char *op = qname_fname(lst->data.lval);
- len = snprintf( buf+len, BUFSIZ-len, "%s()", op );
+ const char *op = qname_fname(lst->data.lval), *sname =
qname_schema(lst->data.lval);
+ char *res;
+
+ if (!sname)
+ sname = sql->session->schema->base.name;
+
+ if ((res = NEW_ARRAY(char, strlen(sname) + strlen(op) + 8)))
+ stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "\""), sname),
"\".\""), op), "\"()");
+
+ return res;
} break;
case SQL_UNOP: {
dnode *lst = se->data.lval->h;
- char *op = qname_fname(lst->data.lval);
- char *l = symbol2string(sql, lst->next->data.sym, expression,
err);
- if (l == NULL)
+ const char *op = qname_fname(lst->data.lval), *sname =
qname_schema(lst->data.lval);
+ char *l = symbol2string(sql, lst->next->data.sym, expression,
err), *res;
+
+ if (!sname)
+ sname = sql->session->schema->base.name;
+ if (!l)
return NULL;
- len = snprintf( buf+len, BUFSIZ-len, "%s(%s)", op, l);
+
+ if ((res = NEW_ARRAY(char, strlen(sname) + strlen(op) +
strlen(l) + 8)))
+ stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res,
"\""), sname), "\".\""), op), "\"("), l), ")");
+
_DELETE(l);
- break;
+ return res;
}
case SQL_PARAMETER:
- strcpy(buf,"?");
- break;
+ return _STRDUP("?");
case SQL_NULL:
- strcpy(buf,"NULL");
- break;
+ return _STRDUP("NULL");
case SQL_ATOM:{
AtomNode *an = (AtomNode *) se;
if (an && an->a)
return atom2sql(an->a);
else
- strcpy(buf,"NULL");
- break;
+ return _STRDUP("NULL");
}
case SQL_NEXT: {
const char *seq = qname_table(se->data.lval), *sname =
qname_schema(se->data.lval);
@@ -382,17 +416,8 @@ symbol2string(mvc *sql, symbol *se, int
if (!sname)
sname = sql->session->schema->base.name;
- const char *sname_esc = sql_escape_ident(sname);
- const char *seq_esc = sql_escape_ident(seq);
- if (!seq_esc || !sname_esc) {
- c_delete(sname_esc);
- c_delete(seq_esc);
- return NULL;
- }
- if ((res = NEW_ARRAY(char, strlen("next value for \"") +
strlen(sname_esc) + strlen(seq_esc) + 5)))
- stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "next value for
\""), sname_esc), "\".\""), seq_esc), "\"");
- c_delete(sname_esc);
- c_delete(seq_esc);
+ if ((res = NEW_ARRAY(char, strlen("next value for \"") +
strlen(sname) + strlen(seq) + 5)))
+ stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "next value for
\""), sname), "\".\""), seq), "\"");
return res;
} break;
case SQL_IDENT:
@@ -405,58 +430,41 @@ symbol2string(mvc *sql, symbol *se, int
return atom2sql(a);
} else if (expression && dlist_length(l) == 1 && l->h->type ==
type_string) {
/* when compiling an expression, a column of a table
might be present in the symbol, so we need this case */
- const char *l_escp = sql_escape_ident(l->h->data.sval);
+ const char *op = l->h->data.sval;
char *res;
- if (!l_escp)
- return NULL;
-
- if ((res = NEW_ARRAY(char, strlen(l_escp) + 3)))
- stpcpy(stpcpy(stpcpy(res, "\""), l_escp), "\"");
- c_delete(l_escp);
+ if ((res = NEW_ARRAY(char, strlen(op) + 3)))
+ stpcpy(stpcpy(stpcpy(res, "\""), op), "\"");
return res;
} else if (expression && dlist_length(l) == 2 && l->h->type ==
type_string && l->h->next->type == type_string) {
char *first = l->h->data.sval, *second =
l->h->next->data.sval, *res;
if (!first || !second)
return NULL;
- const char *first_esc = sql_escape_ident(first);
- const char *second_esc = sql_escape_ident(first);
- if (!first_esc || !second_esc) {
- c_delete(first_esc);
- c_delete(second_esc);
- return NULL;
- }
-
- if ((res = NEW_ARRAY(char, strlen(first_esc) +
strlen(second_esc) + 6)))
- stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "\""),
first_esc), "\".\""), second_esc), "\"");
- c_delete(first_esc);
- c_delete(second);
+ if ((res = NEW_ARRAY(char, strlen(first) +
strlen(second) + 6)))
+ stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "\""),
first), "\".\""), second), "\"");
return res;
} else {
char *e = dlist2string(sql, l, expression, err);
if (e)
*err = e;
+ return NULL;
}
- return NULL;
}
case SQL_CAST: {
dlist *dl = se->data.lval;
- char *val;
- char *tpe;
+ char *val = NULL, *tpe = NULL, *res;
- val = symbol2string(sql, dl->h->data.sym, expression, err);
- if (val == NULL)
- return NULL;
- tpe = subtype2string(&dl->h->next->data.typeval);
- if (tpe == NULL) {
+ if (!(val = symbol2string(sql, dl->h->data.sym, expression,
err)) || !(tpe = subtype2string(&dl->h->next->data.typeval))) {
_DELETE(val);
+ _DELETE(tpe);
return NULL;
}
- len = snprintf( buf+len, BUFSIZ-len, "cast ( %s as %s )", val,
tpe);
+ if ((res = NEW_ARRAY(char, strlen(val) + strlen(tpe) + 11)))
+ stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "cast("), val),
" as "), tpe), ")");
_DELETE(val);
_DELETE(tpe);
- break;
+ return res;
}
case SQL_AGGR:
case SQL_SELECT:
@@ -466,5 +474,5 @@ symbol2string(mvc *sql, symbol *se, int
default:
return NULL;
}
- return _STRDUP(buf);
+ return NULL;
}
diff --git a/sql/test/merge-partitions/Tests/mergepart20.sql
b/sql/test/merge-partitions/Tests/mergepart20.sql
--- a/sql/test/merge-partitions/Tests/mergepart20.sql
+++ b/sql/test/merge-partitions/Tests/mergepart20.sql
@@ -52,3 +52,9 @@ DROP TABLE subtable2;
DROP TABLE subtable3;
DROP TABLE testme;
DROP FUNCTION iamdummy;
+
+CREATE FUNCTION iamdummy(a int, b int, c int) RETURNS INT BEGIN RETURN a + b +
c; END;
+CREATE MERGE TABLE testme(d int, e int, f int) PARTITION BY RANGE USING
(iamdummy(d, e, f));
+SELECT column_id, expression FROM table_partitions;
+DROP TABLE testme;
+DROP FUNCTION iamdummy;
diff --git a/sql/test/merge-partitions/Tests/mergepart20.stable.out
b/sql/test/merge-partitions/Tests/mergepart20.stable.out
--- a/sql/test/merge-partitions/Tests/mergepart20.stable.out
+++ b/sql/test/merge-partitions/Tests/mergepart20.stable.out
@@ -71,8 +71,8 @@ stdout of test 'mergepart20` in director
% sys.table_partitions, sys.table_partitions # table_name
% column_id, expression # name
% int, varchar # type
-% 1, 8 # length
-[ NULL, "md5(\"a\")" ]
+% 1, 16 # length
+[ NULL, "\"sys\".\"md5\"(\"a\")" ]
#ALTER TABLE testme ADD TABLE subtable1 AS PARTITION FROM
'00000000000000000000000000000000' TO '7fffffffffffffffffffffffffffffff';
#ALTER TABLE testme ADD TABLE subtable2 AS PARTITION FROM
'80000000000000000000000000000000' TO 'ffffffffffffffffffffffffffffffff';
#INSERT INTO testme VALUES (1, 'first'), (2000, 'second'), (3, 'third'),
(4000, 'fourth');
@@ -150,6 +150,17 @@ stdout of test 'mergepart20` in director
#ALTER TABLE testme DROP TABLE subtable2;
#DROP TABLE subtable1;
#DROP TABLE subtable2;
+#DROP TABLE subtable3;
+#DROP TABLE testme;
+#DROP FUNCTION iamdummy;
+#CREATE FUNCTION iamdummy(a int, b int, c int) RETURNS INT BEGIN RETURN a + b
+ c; END;
+#CREATE MERGE TABLE testme(d int, e int, f int) PARTITION BY RANGE USING
(iamdummy(d, e, f));
+#SELECT column_id, expression FROM table_partitions;
+% sys.table_partitions, sys.table_partitions # table_name
+% column_id, expression # name
+% int, varchar # type
+% 1, 29 # length
+[ NULL, "\"sys\".\"iamdummy\"(\"d\",\"e\",\"f\")" ]
#DROP TABLE testme;
#DROP FUNCTION iamdummy;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list