Changeset: 7c5529734f41 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=7c5529734f41 Modified Files: sql/backends/monet5/rel_bin.c sql/backends/monet5/vaults/bam/mykstring.h sql/server/rel_exp.c sql/server/rel_optimizer.c sql/server/rel_select.c sql/storage/bat/bat_table.c sql/test/BugTracker-2016/Tests/column_alias_in_where_clause.Bug-3947.sql sql/test/BugTracker-2016/Tests/column_alias_in_where_clause.Bug-3947.stable.out sql/test/BugTracker-2016/Tests/column_alias_in_where_clause.Bug-3947.stable.out.int128 sql/test/leaks/Tests/check4.stable.out sql/test/leaks/Tests/check4.stable.out.int128 Branch: default Log Message:
Merge with Jul2017 branch. diffs (truncated from 334 to 300 lines): diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c --- a/sql/backends/monet5/rel_bin.c +++ b/sql/backends/monet5/rel_bin.c @@ -24,6 +24,45 @@ static stmt * exp_bin(backend *be, sql_e static stmt * rel_bin(backend *be, sql_rel *rel); static stmt * subrel_bin(backend *be, sql_rel *rel, list *refs); +static stmt *check_types(backend *be, sql_subtype *ct, stmt *s, check_type tpe); + +static stmt * +sql_unop_(backend *be, sql_schema *s, const char *fname, stmt *rs) +{ + mvc *sql = be->mvc; + sql_subtype *rt = NULL; + sql_subfunc *f = NULL; + + if (!s) + s = sql->session->schema; + rt = tail_type(rs); + f = sql_bind_func(sql->sa, s, fname, rt, NULL, F_FUNC); + /* try to find the function without a type, and convert + * the value to the type needed by this function! + */ + if (!f && (f = sql_find_func(sql->sa, s, fname, 1, F_FUNC, NULL)) != NULL) { + sql_arg *a = f->func->ops->h->data; + + rs = check_types(be, &a->type, rs, type_equal); + if (!rs) + f = NULL; + } + if (f) { + /* + if (f->func->res.scale == INOUT) { + f->res.digits = rt->digits; + f->res.scale = rt->scale; + } + */ + return stmt_unop(be, rs, f); + } else if (rs) { + char *type = tail_type(rs)->type->sqlname; + + return sql_error(sql, 02, SQLSTATE(42000) "SELECT: no such unary operator '%s(%s)'", fname, type); + } + return NULL; +} + static stmt * refs_find_rel(list *refs, sql_rel *rel) { @@ -708,10 +747,16 @@ exp_bin(backend *be, sql_exp *e, stmt *l tail_type(l), tail_type(r), F_FUNC); sql_subfunc *a = sql_bind_func(sql->sa, sql->session->schema, "and", bt, bt, F_FUNC); - assert(lf && rf && a); - s = stmt_binop(be, - stmt_binop(be, l, r, lf), - stmt_binop(be, l, r2, rf), a); + + if (is_atom(re->type) && re->l && atom_null((atom*)re->l) && + is_atom(re2->type) && re2->l && atom_null((atom*)re2->l)) { + s = sql_unop_(be, NULL, "isnull", l); + } else { + assert(lf && rf && a); + s = stmt_binop(be, + stmt_binop(be, l, r, lf), + stmt_binop(be, l, r2, rf), a); + } if (is_anti(e)) { sql_subfunc *a = sql_bind_func(sql->sa, sql->session->schema, "not", bt, NULL, F_FUNC); s = stmt_unop(be, s, a); @@ -743,8 +788,6 @@ exp_bin(backend *be, sql_exp *e, stmt *l return s; } -static stmt *check_types(backend *be, sql_subtype *ct, stmt *s, check_type tpe); - static stmt * stmt_col( backend *be, sql_column *c, stmt *del) { @@ -965,43 +1008,6 @@ check_types(backend *be, sql_subtype *ct } static stmt * -sql_unop_(backend *be, sql_schema *s, const char *fname, stmt *rs) -{ - mvc *sql = be->mvc; - sql_subtype *rt = NULL; - sql_subfunc *f = NULL; - - if (!s) - s = sql->session->schema; - rt = tail_type(rs); - f = sql_bind_func(sql->sa, s, fname, rt, NULL, F_FUNC); - /* try to find the function without a type, and convert - * the value to the type needed by this function! - */ - if (!f && (f = sql_find_func(sql->sa, s, fname, 1, F_FUNC, NULL)) != NULL) { - sql_arg *a = f->func->ops->h->data; - - rs = check_types(be, &a->type, rs, type_equal); - if (!rs) - f = NULL; - } - if (f) { - /* - if (f->func->res.scale == INOUT) { - f->res.digits = rt->digits; - f->res.scale = rt->scale; - } - */ - return stmt_unop(be, rs, f); - } else if (rs) { - char *type = tail_type(rs)->type->sqlname; - - return sql_error(sql, 02, SQLSTATE(42000) "SELECT: no such unary operator '%s(%s)'", fname, type); - } - return NULL; -} - -static stmt * sql_Nop_(backend *be, const char *fname, stmt *a1, stmt *a2, stmt *a3, stmt *a4) { mvc *sql = be->mvc; diff --git a/sql/backends/monet5/vaults/bam/mykstring.h b/sql/backends/monet5/vaults/bam/mykstring.h --- a/sql/backends/monet5/vaults/bam/mykstring.h +++ b/sql/backends/monet5/vaults/bam/mykstring.h @@ -51,8 +51,8 @@ static int ksprintf(kstring_t *s, const s->s = (char*)realloc(s->s, s->m); va_start(ap, fmt); l = vsnprintf(s->s + s->l, s->m - s->l, fmt, ap); + va_end(ap); } - va_end(ap); s->l += l; return l; } diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c --- a/sql/server/rel_exp.c +++ b/sql/server/rel_exp.c @@ -1021,7 +1021,7 @@ exp_is_complex_select( sql_exp *e ) list *l = e->l; if (r && l) - for (n = l->h; n; n = n->next) + for (n = l->h; n && !r; n = n->next) r |= exp_is_complex_select(n->data); return r; } @@ -1330,7 +1330,7 @@ exp_is_atom( sql_exp *e ) list *l = e->l; if (r && l) - for (n = l->h; n; n = n->next) + for (n = l->h; n && r; n = n->next) r &= exp_is_atom(n->data); return r; } diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c --- a/sql/server/rel_optimizer.c +++ b/sql/server/rel_optimizer.c @@ -2232,11 +2232,26 @@ rel_distinct_project2groupby(int *change set_nodistinct(rel); } } - if (rel->op == op_project && rel->l && !rel->r /* no order by */ && + if (rel->op == op_project && rel->l && need_distinct(rel) && exps_card(rel->exps) > CARD_ATOM) { node *n; list *exps = new_exp_list(sql->sa), *gbe = new_exp_list(sql->sa); - + list *obe = rel->r; /* we need to readd the ordering later */ + + if (obe) { + int fnd = 0; + + for(n = obe->h; n && !fnd; n = n->next) { + sql_exp *e = n->data; + + if (e->type != e_column) + fnd = 1; + else if (exps_bind_column2(rel->exps, e->l, e->r) == 0) + fnd = 1; + } + if (fnd) + return rel; + } rel->l = rel_project(sql->sa, rel->l, rel->exps); for (n = rel->exps->h; n; n = n->next) { @@ -2254,6 +2269,11 @@ rel_distinct_project2groupby(int *change rel->exps = exps; rel->r = gbe; set_nodistinct(rel); + if (obe) { + /* add order again */ + rel = rel_project(sql->sa, rel, rel_projections(sql, rel, NULL, 1, 1)); + rel->r = obe; + } *changes = 1; } 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 @@ -4427,6 +4427,8 @@ rel_value_exp2(mvc *sql, sql_rel **rel, set_processed(r); } /* single row */ + if (!rel) + return NULL; if (*rel) { sql_rel *p = *rel; diff --git a/sql/storage/bat/bat_table.c b/sql/storage/bat/bat_table.c --- a/sql/storage/bat/bat_table.c +++ b/sql/storage/bat/bat_table.c @@ -154,17 +154,17 @@ column_find_row(sql_trans *tr, sql_colum va_start(va, value); s = delta_cands(tr, c->t); if (!s) - return oid_nil; + goto return_nil; b = full_column(tr, c); if (!b) { bat_destroy(s); - return oid_nil; + goto return_nil; } r = BATselect(b, s, value, NULL, 1, 0, 0); bat_destroy(s); full_destroy(c, b); if (!r) - return oid_nil; + goto return_nil; s = r; while ((n = va_arg(va, sql_column *)) != NULL) { value = va_arg(va, void *); @@ -173,13 +173,13 @@ column_find_row(sql_trans *tr, sql_colum b = full_column(tr, c); if (!b) { bat_destroy(s); - return oid_nil; + goto return_nil; } r = BATselect(b, s, value, NULL, 1, 0, 0); bat_destroy(s); full_destroy(c, b); if (!r) - return oid_nil; + goto return_nil; s = r; } va_end(va); @@ -189,6 +189,9 @@ column_find_row(sql_trans *tr, sql_colum } bat_destroy(s); return rid; + return_nil: + va_end(va); + return oid_nil; } static void * @@ -324,6 +327,7 @@ rids_select( sql_trans *tr, sql_column * full_destroy(key, b); if (s == NULL) { GDKfree(rs); + va_end(va); return NULL; } } diff --git a/sql/test/BugTracker-2016/Tests/column_alias_in_where_clause.Bug-3947.sql b/sql/test/BugTracker-2016/Tests/column_alias_in_where_clause.Bug-3947.sql --- a/sql/test/BugTracker-2016/Tests/column_alias_in_where_clause.Bug-3947.sql +++ b/sql/test/BugTracker-2016/Tests/column_alias_in_where_clause.Bug-3947.sql @@ -33,6 +33,7 @@ SELECT * FROM (SELECT cast(null as char( SELECT cast(null as char(1)) AS "CAT", a AS "A", c AS "C" FROM t_alias WHERE "CAT" IS NULL or "CAT" = NULL; -- SELECT: identifier 'CAT' unknown SELECT * FROM (SELECT cast(null as char(1)) AS "CAT", a AS "A", c AS "C" FROM t_alias) T1 WHERE "CAT" IS NULL or "CAT" = NULL; +SELECT * FROM (SELECT cast(null as char(1)) AS "CAT", a AS "A", c AS "C" FROM t_alias) T1 WHERE "CAT" IS NULL and "CAT" = NULL; -- column aliases can be used in ORDER BY and GROUP BY clauses SELECT a AS "A", b AS "B", c AS "C" FROM t_alias ORDER BY "C", "A", "B"; diff --git a/sql/test/BugTracker-2016/Tests/column_alias_in_where_clause.Bug-3947.stable.out b/sql/test/BugTracker-2016/Tests/column_alias_in_where_clause.Bug-3947.stable.out --- a/sql/test/BugTracker-2016/Tests/column_alias_in_where_clause.Bug-3947.stable.out +++ b/sql/test/BugTracker-2016/Tests/column_alias_in_where_clause.Bug-3947.stable.out @@ -123,7 +123,9 @@ Ready. % .t1, sys.t1, sys.t1 # table_name % CAT, A, C # name % char, int, varchar # type -% 1, 1, 0 # length +% 1, 2, 4 # length +[ NULL, 1, "tien" ] +[ NULL, 11, "elf" ] #SELECT * FROM (SELECT cast(null as char(1)) AS "CAT", a AS "A", c AS "C" FROM t_alias) T1 WHERE "CAT" IS NULL or "CAT" = NULL; % .t1, sys.t1, sys.t1 # table_name % CAT, A, C # name @@ -131,6 +133,11 @@ Ready. % 1, 2, 4 # length [ NULL, 1, "tien" ] [ NULL, 11, "elf" ] _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list