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

Reply via email to