Changeset: e1fa36d687f5 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e1fa36d687f5
Modified Files:
        sql/server/rel_partition.c
        sql/server/rel_propagate.c
        sql/server/sql_atom.c
        sql/server/sql_partition.c
        sql/server/sql_semantic.c
Branch: Apr2019
Log Message:

Check for stack overflows while compiling expressions, disallow SQL parameters 
and variables as well.


diffs (259 lines):

diff --git a/sql/server/rel_partition.c b/sql/server/rel_partition.c
--- a/sql/server/rel_partition.c
+++ b/sql/server/rel_partition.c
@@ -41,8 +41,13 @@ rel_getcount(mvc *sql, sql_rel *rel)
 }
 
 static void
-find_basetables( sql_rel *rel, list *tables )
+find_basetables(mvc *sql, sql_rel *rel, list *tables )
 {
+       if (THRhighwater()) {
+               (void) sql_error(sql, 10, SQLSTATE(42000) "query too complex: 
running out of stack space");
+               return;
+       }
+
        if (!rel)
                return;
        switch (rel->op) {
@@ -68,9 +73,9 @@ find_basetables( sql_rel *rel, list *tab
        case op_inter: 
        case op_except: 
                if (rel->l)
-                       find_basetables(rel->l, tables); 
+                       find_basetables(sql, rel->l, tables);
                if (rel->r)
-                       find_basetables(rel->r, tables); 
+                       find_basetables(sql, rel->r, tables);
                break;
        case op_groupby: 
        case op_project:
@@ -78,7 +83,7 @@ find_basetables( sql_rel *rel, list *tab
        case op_topn: 
        case op_sample: 
                if (rel->l)
-                       find_basetables(rel->l, tables); 
+                       find_basetables(sql, rel->l, tables);
                break;
        case op_ddl: 
                break;
@@ -87,7 +92,7 @@ find_basetables( sql_rel *rel, list *tab
        case op_delete:
        case op_truncate:
                if (rel->r)
-                       find_basetables(rel->r, tables); 
+                       find_basetables(sql, rel->r, tables);
                break;
        }
 }
@@ -98,7 +103,7 @@ static sql_rel *
        list *tables = sa_list(sql->sa); 
        /* find basetable relations */
        /* mark one (largest) with REL_PARTITION */
-       find_basetables(rel, tables); 
+       find_basetables(sql, rel, tables);
        if (list_length(tables)) {
                sql_rel *r;
                node *n;
@@ -137,6 +142,8 @@ has_groupby(sql_rel *rel)
 sql_rel *
 rel_partition(mvc *sql, sql_rel *rel) 
 {
+       if (THRhighwater())
+               return sql_error(sql, 10, SQLSTATE(42000) "query too complex: 
running out of stack space");
        (void)sql;
        if (rel->op == op_basetable) {
                rel->flag = REL_PARTITION;
diff --git a/sql/server/rel_propagate.c b/sql/server/rel_propagate.c
--- a/sql/server/rel_propagate.c
+++ b/sql/server/rel_propagate.c
@@ -412,6 +412,9 @@ static sql_rel* rel_change_base_table(mv
 static sql_exp*
 exp_change_column_table(mvc *sql, sql_exp *e, sql_table* oldt, sql_table* newt)
 {
+       if (THRhighwater())
+               return sql_error(sql, 10, SQLSTATE(42000) "query too complex: 
running out of stack space");
+
        if (!e)
                return NULL;
        switch(e->type) {
@@ -485,6 +488,9 @@ exp_change_column_table(mvc *sql, sql_ex
 static sql_rel*
 rel_change_base_table(mvc* sql, sql_rel* rel, sql_table* oldt, sql_table* newt)
 {
+       if (THRhighwater())
+               return sql_error(sql, 10, SQLSTATE(42000) "query too complex: 
running out of stack space");
+
        if (!rel)
                return NULL;
 
diff --git a/sql/server/sql_atom.c b/sql/server/sql_atom.c
--- a/sql/server/sql_atom.c
+++ b/sql/server/sql_atom.c
@@ -375,6 +375,8 @@ atom2sql(atom *a)
        if (a->data.vtype == TYPE_str && EC_INTERVAL(ec))
                ec = EC_STRING; 
        /* todo handle NULL's early */
+       if (a->isnull)
+               return _STRDUP("NULL");
        switch (ec) {
        case EC_BIT:
                assert( a->data.vtype == TYPE_bit);
@@ -383,11 +385,8 @@ atom2sql(atom *a)
                return _STRDUP("false");
        case EC_CHAR:
        case EC_STRING:
-               assert (a->data.vtype == TYPE_str);
-               if (a->data.val.sval)
-                       sprintf(buf, "'%s'", a->data.val.sval);
-               else
-                       sprintf(buf, "NULL");
+               assert(a->data.vtype == TYPE_str && a->data.val.sval);
+               sprintf(buf, "'%s'", a->data.val.sval);
                break;
        case EC_BLOB:
                /* TODO atom to string */
@@ -500,11 +499,8 @@ atom2sql(atom *a)
        case EC_DATE:
        case EC_TIMESTAMP:
                if (a->data.vtype == TYPE_str) {
-                       if (a->data.val.sval)
-                               sprintf(buf, "%s '%s'", a->tpe.type->sqlname,
-                                       a->data.val.sval);
-                       else
-                               sprintf(buf, "NULL");
+                       assert(a->data.val.sval);
+                       sprintf(buf, "%s '%s'", a->tpe.type->sqlname, 
a->data.val.sval);
                }
                break;
        default:
diff --git a/sql/server/sql_partition.c b/sql/server/sql_partition.c
--- a/sql/server/sql_partition.c
+++ b/sql/server/sql_partition.c
@@ -86,6 +86,11 @@ static void exp_find_table_columns(mvc *
 static void
 rel_find_table_columns(mvc* sql, sql_rel* rel, sql_table *t, list *cols)
 {
+       if (THRhighwater()) {
+               (void) sql_error(sql, 10, SQLSTATE(42000) "query too complex: 
running out of stack space");
+               return;
+       }
+
        if (!rel)
                return;
 
@@ -134,6 +139,11 @@ rel_find_table_columns(mvc* sql, sql_rel
 static void
 exp_find_table_columns(mvc *sql, sql_exp *e, sql_table *t, list *cols)
 {
+       if (THRhighwater()) {
+               (void) sql_error(sql, 10, SQLSTATE(42000) "query too complex: 
running out of stack space");
+               return;
+       }
+
        if (!e)
                return;
        switch(e->type) {
@@ -208,11 +218,8 @@ exp_find_table_columns(mvc *sql, sql_exp
 }
 
 static str
-find_expression_type(sql_exp *e, sql_subtype *tpe, char *query)
+find_expression_type(sql_exp *e, sql_subtype *tpe)
 {
-       if (!e)
-               throw(SQL,"sql.partition", SQLSTATE(42000) "It was not possible 
to compile the expression: '%s'", query);
-
        switch(e->type) {
                case e_convert: {
                        assert(list_length(e->r) == 2);
@@ -225,14 +232,16 @@ find_expression_type(sql_exp *e, sql_sub
                        } else if (e->r) {
                                *tpe = e->tpe;
                        } else if (e->f) {
-                               throw(SQL,"sql.partition", SQLSTATE(42000) "The 
expression should return 1 value only");
+                               throw(SQL,"sql.partition", SQLSTATE(42000) 
"List of values not allowed in expressions");
+                       } else {
+                               throw(SQL,"sql.partition", SQLSTATE(42000) 
"Variables/parameters are not allowed in expressions");
                        }
                } break;
                case e_func: {
                        sql_subfunc *f = e->f;
                        sql_func *func = f->func;
-                       if(list_length(func->res) != 1)
-                               throw(SQL,"sql.partition", SQLSTATE(42000) "The 
expression should return 1 value only");
+                       if (list_length(func->res) != 1)
+                               throw(SQL,"sql.partition", SQLSTATE(42000) "An 
expression should return a single value");
                        *tpe = *(sql_subtype *)f->res->h->data;
                }       break;
                case e_cmp: {
@@ -243,9 +252,9 @@ find_expression_type(sql_exp *e, sql_sub
                        *tpe = e->tpe;
                } break;
                case e_psm:
-                       throw(SQL,"sql.partition", SQLSTATE(42000) "PSM calls 
not supported in expressions");
+                       throw(SQL,"sql.partition", SQLSTATE(42000) "PSM calls 
are not allowed in expressions");
                case e_aggr:
-                       throw(SQL,"sql.partition", SQLSTATE(42000) "Aggregation 
functions not supported in expressions");
+                       throw(SQL,"sql.partition", SQLSTATE(42000) "Aggregation 
functions are not allowed in expressions");
        }
        return NULL;
 }
@@ -262,6 +271,9 @@ bootstrap_partition_expression(mvc* sql,
 
        assert(isPartitionedByExpressionTable(mt));
 
+       if (sql->emode == m_prepare)
+               throw(SQL,"sql.partition", SQLSTATE(42000) "Partition 
expressions not compilable with prepared statements");
+
        r = rel_basetable(sql, mt, mt->base.name);
        query = mt->part.pexp->exp;
        if((exp = rel_parse_val(sql, sa_message(sql->sa, "select %s;", query), 
sql->emode, r)) == NULL) {
@@ -278,7 +290,7 @@ bootstrap_partition_expression(mvc* sql,
                mt->part.pexp->cols = sa_list(rsa);
        exp_find_table_columns(sql, exp, mt, mt->part.pexp->cols);
 
-       if((msg = find_expression_type(exp, &(mt->part.pexp->type), query)) != 
NULL)
+       if((msg = find_expression_type(exp, &(mt->part.pexp->type))) != NULL)
                return msg;
 
        sql_ec = mt->part.pexp->type.type->eclass;
@@ -289,7 +301,7 @@ bootstrap_partition_expression(mvc* sql,
                        throw(SQL, "sql.partition", SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
                } else {
                        msg = createException(SQL, "sql.partition",
-                                                                 
SQLSTATE(42000) "Column type %s not yet supported for the expression return 
value", err);
+                                                                 
SQLSTATE(42000) "Column type %s not supported for the expression return value", 
err);
                        GDKfree(err);
                }
        }
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
@@ -360,6 +360,9 @@ char *symbol2string(mvc *sql, symbol *se
                _DELETE(l);
                break;
        }
+       case SQL_PARAMETER:
+               strcpy(buf,"?");
+               break;
        case SQL_NULL:
                strcpy(buf,"NULL");
                break;
@@ -414,7 +417,7 @@ char *symbol2string(mvc *sql, symbol *se
                                *err = e;
                }
                return NULL;
-       }       
+       }
        case SQL_CAST: {
                dlist *dl = se->data.lval;
                char *val;
@@ -436,7 +439,6 @@ char *symbol2string(mvc *sql, symbol *se
        }
        case SQL_AGGR:
        case SQL_SELECT:
-       case SQL_PARAMETER:
        case SQL_CASE:
        case SQL_COALESCE:
        case SQL_NULLIF:
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to