Changeset: 49e4a3c72706 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=49e4a3c72706
Modified Files:
sql/server/rel_partition.c
sql/server/rel_propagate.c
sql/server/rel_select.c
sql/server/sql_atom.c
sql/server/sql_partition.c
sql/server/sql_semantic.c
sql/test/BugTracker-2009/Tests/count_bug.SF-2604583.stable.out
Branch: default
Log Message:
merged with default
diffs (truncated from 385 to 300 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
@@ -42,8 +42,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
@@ -418,6 +418,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) {
@@ -491,44 +494,53 @@ 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(!rel)
+ if (THRhighwater())
+ return sql_error(sql, 10, SQLSTATE(42000) "query too complex:
running out of stack space");
+
+ if (!rel)
return NULL;
if(rel->exps)
for(node *n = rel->exps->h ; n ; n = n->next)
n->data = exp_change_column_table(sql, (sql_exp*)
n->data, oldt, newt);
- switch(rel->op) {
- case op_basetable:
- if(rel->l == oldt)
- rel->l = newt;
- if(rel->r)
- rel->r = rel_change_base_table(sql, rel->r,
oldt, newt);
+ switch (rel->op) {
+ case op_ddl:
break;
case op_table:
- case op_topn:
- case op_sample:
- case op_project:
- case op_groupby:
- case op_select:
- case op_insert:
- case op_ddl:
- case op_update:
- case op_delete:
- case op_truncate:
- case op_union:
- case op_inter:
- case op_except:
+ case op_basetable:
+ if (rel->l == oldt)
+ rel->l = newt;
+ break;
case op_join:
case op_left:
case op_right:
case op_full:
case op_semi:
case op_anti:
- if(rel->l)
+ case op_union:
+ case op_inter:
+ case op_except:
+ if (rel->l)
rel->l = rel_change_base_table(sql, rel->l,
oldt, newt);
- if(rel->r)
+ if (rel->r)
rel->r = rel_change_base_table(sql, rel->r,
oldt, newt);
+ break;
+ case op_groupby:
+ case op_project:
+ case op_select:
+ case op_topn:
+ case op_sample:
+ if (rel->l)
+ rel->l = rel_change_base_table(sql, rel->l,
oldt, newt);
+ break;
+ case op_insert:
+ case op_update:
+ case op_delete:
+ case op_truncate:
+ if (rel->r)
+ rel->r = rel_change_base_table(sql, rel->r,
oldt, newt);
+ break;
}
return rel;
}
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -3786,8 +3786,7 @@ rel_intermediates_add_exp(mvc *sql, sql_
while(pp->l && pp->l != p)
pp = pp->l;
- if (pp && pp->l == p) {
- assert(pp->op == op_project);
+ if (pp && pp->l == p && pp->op == op_project) {
in = exp_column(sql->sa, exp_relname(in), exp_name(in),
exp_subtype(in), exp_card(in), has_nil(in), is_intern(in));
in = rel_project_add_exp(sql, pp, in);
}
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
@@ -87,21 +87,63 @@ static void exp_find_table_columns(mvc *
static void
rel_find_table_columns(mvc* sql, sql_rel* rel, sql_table *t, list *cols)
{
- if(!rel)
+ if (THRhighwater()) {
+ (void) sql_error(sql, 10, SQLSTATE(42000) "query too complex:
running out of stack space");
+ return;
+ }
+
+ if (!rel)
return;
- if(rel->exps)
- for(node *n = rel->exps->h ; n ; n = n->next)
+ if (rel->exps)
+ for (node *n = rel->exps->h ; n ; n = n->next)
exp_find_table_columns(sql, (sql_exp*) n->data, t,
cols);
- if(rel->l)
- rel_find_table_columns(sql, rel->l, t, cols);
- if(rel->r)
- rel_find_table_columns(sql, rel->r, t, cols);
+
+ switch (rel->op) {
+ case op_table:
+ case op_basetable:
+ case op_ddl:
+ break;
+ case op_join:
+ case op_left:
+ case op_right:
+ case op_full:
+ case op_semi:
+ case op_anti:
+ case op_union:
+ case op_inter:
+ case op_except:
+ if (rel->l)
+ rel_find_table_columns(sql, rel->l, t, cols);
+ if (rel->r)
+ rel_find_table_columns(sql, rel->r, t, cols);
+ break;
+ case op_groupby:
+ case op_project:
+ case op_select:
+ case op_topn:
+ case op_sample:
+ if (rel->l)
+ rel_find_table_columns(sql, rel->l, t, cols);
+ break;
+ case op_insert:
+ case op_update:
+ case op_delete:
+ case op_truncate:
+ if (rel->r)
+ rel_find_table_columns(sql, rel->r, t, cols);
+ break;
+ }
}
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) {
@@ -176,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);
@@ -193,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");
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list