Changeset: 069b61f984e4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=069b61f984e4
Modified Files:
sql/backends/monet5/rel_bin.c
sql/backends/monet5/sql_gencode.c
sql/backends/monet5/sql_statement.c
sql/backends/monet5/sql_statement.h
sql/server/rel_exp.c
sql/server/rel_select.c
sql/server/sql_semantic.c
sql/test/BugDay_2005-12-19_2.9.3/Tests/bogus_prepare.SF-1377079.stable.err
sql/test/BugDay_2005-12-19_2.9.3/Tests/prepare-where.SF-1238867.1238959.1238965.1240124.stable.err
sql/test/BugTracker-2017/Tests/wrong_aggregation_count.Bug-6257.stable.out
sql/test/BugTracker-2019/Tests/alter_table_set_schema.Bug-6701.stable.out
sql/test/miscellaneous/Tests/groupby_error.sql
sql/test/miscellaneous/Tests/groupby_error.stable.err
sql/test/miscellaneous/Tests/groupby_error.stable.out
Branch: default
Log Message:
Merged with linear-hashing
diffs (truncated from 1023 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
@@ -2226,6 +2226,7 @@ rel2bin_semijoin(backend *be, sql_rel *r
list *l;
node *en = NULL, *n;
stmt *left = NULL, *right = NULL, *join = NULL, *jl, *jr, *c;
+ int semi_used = 0;
if (rel->op == op_anti && !list_empty(rel->exps) &&
list_length(rel->exps) == 1 && ((sql_exp*)rel->exps->h->data)->flag ==
mark_notin)
return rel2bin_antijoin(be, rel, refs);
@@ -2243,7 +2244,37 @@ rel2bin_semijoin(backend *be, sql_rel *r
* first cheap join(s) (equality or idx)
* second selects/filters
*/
- if (rel->exps) {
+ if (rel->op != op_anti && rel->exps && list_length(rel->exps) == 1) {
+ sql_exp *e = rel->exps->h->data;
+
+ if (e->type == e_cmp && (e->flag == cmp_equal || e->flag ==
mark_in) && !e->anti && !e->f) {
+ stmt *r, *l = exp_bin(be, e->l, left, NULL, NULL, NULL,
NULL, NULL);
+ int swap = 0;
+
+ if (!l) {
+ swap = 1;
+ l = exp_bin(be, e->l, right, NULL, NULL, NULL,
NULL, NULL);
+ }
+ r = exp_bin(be, e->r, left, right, NULL, NULL, NULL,
NULL);
+
+ if (swap) {
+ stmt *t = l;
+ l = r;
+ r = t;
+ }
+
+ if (!l || !r)
+ return NULL;
+ join = stmt_semijoin(be, l, r);
+ if (join)
+ join = stmt_result(be, join, 0);
+ if (!join)
+ return NULL;
+ semi_used = 1;
+ }
+ }
+
+ if (!semi_used && rel->exps) {
int idx = 0;
list *jexps = sa_list(sql->sa);
list *lje = sa_list(sql->sa);
@@ -2317,13 +2348,14 @@ rel2bin_semijoin(backend *be, sql_rel *r
stmt *r = bin_first_column(be, right);
join = stmt_join(be, l, r, 0, cmp_all);
}
- } else {
+ } else if (!semi_used) {
stmt *l = bin_first_column(be, left);
stmt *r = bin_first_column(be, right);
join = stmt_join(be, l, r, 0, cmp_all);
}
- jl = stmt_result(be, join, 0);
- if (en) {
+ if (!semi_used)
+ jl = stmt_result(be, join, 0);
+ if (!semi_used && en) {
stmt *sub, *sel = NULL;
list *nl;
@@ -2373,13 +2405,15 @@ rel2bin_semijoin(backend *be, sql_rel *r
/* construct relation */
l = sa_list(sql->sa);
- /* We did a full join, thats too much.
- Reduce this using difference and intersect */
- c = stmt_mirror(be, left->op4.lval->h->data);
- if (rel->op == op_anti) {
- join = stmt_tdiff(be, c, jl);
- } else {
- join = stmt_tinter(be, c, jl);
+ if (!semi_used) {
+ /* We did a full join, thats too much.
+ Reduce this using difference and intersect */
+ c = stmt_mirror(be, left->op4.lval->h->data);
+ if (rel->op == op_anti) {
+ join = stmt_tdiff(be, c, jl);
+ } else {
+ join = stmt_tinter(be, c, jl);
+ }
}
/* project all the left columns */
diff --git a/sql/backends/monet5/sql_gencode.c
b/sql/backends/monet5/sql_gencode.c
--- a/sql/backends/monet5/sql_gencode.c
+++ b/sql/backends/monet5/sql_gencode.c
@@ -792,7 +792,7 @@ backend_dumpproc(backend *be, Client c,
sql_type *tpe = a->type.type;
int type, varid = 0;
- if (!tpe) {
+ if (!tpe || tpe->eclass == EC_ANY) {
sql_error(m, 003, SQLSTATE(42000) "Could not
determine type for argument number %d\n", argc+1);
goto cleanup;
}
diff --git a/sql/backends/monet5/sql_statement.c
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -1976,6 +1976,40 @@ stmt_join(backend *be, stmt *op1, stmt *
return NULL;
}
+stmt *
+stmt_semijoin(backend *be, stmt *op1, stmt *op2)
+{
+ MalBlkPtr mb = be->mb;
+ InstrPtr q = NULL;
+
+ if (op1->nr < 0 || op2->nr < 0)
+ return NULL;
+
+ q = newStmt(mb, algebraRef, semijoinRef);
+ q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
+ q = pushArgument(mb, q, op1->nr);
+ q = pushArgument(mb, q, op2->nr);
+ q = pushNil(mb, q, TYPE_bat);
+ q = pushNil(mb, q, TYPE_bat);
+ q = pushBit(mb, q, FALSE);
+ q = pushNil(mb, q, TYPE_lng);
+ if (q == NULL)
+ return NULL;
+ if (q) {
+ stmt *s = stmt_create(be->mvc->sa, st_semijoin);
+
+ s->op1 = op1;
+ s->op2 = op2;
+ s->flag = cmp_equal;
+ s->key = 0;
+ s->nrcols = 2;
+ s->nr = getDestVar(q);
+ s->q = q;
+ return s;
+ }
+ return NULL;
+}
+
static InstrPtr
stmt_project_join(backend *be, stmt *op1, stmt *op2, stmt *ins)
{
@@ -3227,6 +3261,7 @@ tail_type(stmt *st)
st = st->op2;
continue;
+ case st_semijoin:
case st_uselect:
case st_uselect2:
case st_limit:
@@ -3315,6 +3350,7 @@ stmt_has_null(stmt *s)
switch (s->type) {
case st_aggr:
case st_Nop:
+ case st_semijoin:
case st_uselect:
case st_uselect2:
case st_atom:
@@ -3383,6 +3419,7 @@ const char *
case st_result:
case st_append:
case st_gen_group:
+ case st_semijoin:
case st_uselect:
case st_uselect2:
case st_limit:
@@ -3440,6 +3477,7 @@ schema_name(sql_allocator *sa, stmt *st)
{
switch (st->type) {
case st_const:
+ case st_semijoin:
case st_join:
case st_join2:
case st_joinN:
diff --git a/sql/backends/monet5/sql_statement.h
b/sql/backends/monet5/sql_statement.h
--- a/sql/backends/monet5/sql_statement.h
+++ b/sql/backends/monet5/sql_statement.h
@@ -65,6 +65,7 @@ typedef enum stmt_type {
st_join,
st_join2,
st_joinN,
+ st_semijoin,
st_export,
st_append,
@@ -184,6 +185,7 @@ extern stmt *stmt_join(backend *be, stmt
extern stmt *stmt_join2(backend *be, stmt *l, stmt *ra, stmt *rb, int cmp, int
anti, int swapped);
/* generic join operator, with a left and right statement list */
extern stmt *stmt_genjoin(backend *be, stmt *l, stmt *r, sql_subfunc *op, int
anti, int swapped);
+extern stmt *stmt_semijoin(backend *be, stmt *op1, stmt *op2);
extern stmt *stmt_project(backend *be, stmt *op1, stmt *op2);
extern stmt *stmt_project_delta(backend *be, stmt *col, stmt *upd, stmt *ins);
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
@@ -782,7 +782,8 @@ exp_rel(mvc *sql, sql_rel *rel)
assert(rel);
if (is_project(rel->op)) {
sql_exp *last = rel->exps->t->data;
- e->tpe = *exp_subtype(last);
+ sql_subtype *t = exp_subtype(last);
+ e->tpe = t ? *t : (sql_subtype) {0};
}
return e;
}
@@ -1702,7 +1703,7 @@ exp_is_atom( sql_exp *e )
int
exp_is_rel( sql_exp *e )
{
- return (e->type == e_psm && e->flag == PSM_REL && e->l);
+ return (e && e->type == e_psm && e->flag == PSM_REL && e->l);
}
int
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
@@ -1251,7 +1251,10 @@ exp_fix_scale(mvc *sql, sql_subtype *ct,
static int
rel_set_type_param(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp
*rel_exp, int upcast)
{
- if (!type || !rel_exp || (rel_exp->type != e_atom && rel_exp->type !=
e_column))
+ sql_rel *r = rel;
+ int is_rel = exp_is_rel(rel_exp);
+
+ if (!type || !rel_exp || (rel_exp->type != e_atom && rel_exp->type !=
e_column && !is_rel))
return -1;
/* use largest numeric types */
@@ -1264,15 +1267,37 @@ rel_set_type_param(mvc *sql, sql_subtype
if (upcast && type->type->eclass == EC_FLT)
type = sql_bind_localtype("dbl");
- if ((rel_exp->type == e_atom || rel_exp->type == e_column) &&
(rel_exp->l || rel_exp->r || rel_exp->f)) {
+ if (is_rel)
+ r = (sql_rel*) rel_exp->l;
+
+ if ((rel_exp->type == e_atom && (rel_exp->l || rel_exp->r ||
rel_exp->f)) || rel_exp->type == e_column || is_rel) {
/* it's not a parameter set possible parameters below */
const char *relname = exp_relname(rel_exp), *expname =
exp_name(rel_exp);
- return rel_set_type_recurse(sql, type, rel, &relname, &expname);
- } else if (set_type_param(sql, type, rel_exp->flag) == 0) {
- rel_exp->tpe = *type;
- return 0;
- }
- return -1;
+ if (rel_set_type_recurse(sql, type, r, &relname, &expname) < 0)
+ return -1;
+ } else if (set_type_param(sql, type, rel_exp->flag) != 0)
+ return -1;
+
+ rel_exp->tpe = *type;
+ return 0;
+}
+
+static int
+rel_binop_check_types(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *rs, int
upcast)
+{
+ sql_subtype *t1 = exp_subtype(ls), *t2 = exp_subtype(rs);
+
+ if (!t1 || !t2) {
+ if (t2 && !t1 && rel_set_type_param(sql, t2, rel, ls, upcast) <
0)
+ return -1;
+ if (t1 && !t2 && rel_set_type_param(sql, t1, rel, rs, upcast) <
0)
+ return -1;
+ }
+ if (!exp_subtype(ls) && !exp_subtype(rs)) {
+ (void) sql_error(sql, 01, SQLSTATE(42000) "Cannot have a
parameter (?) on both sides of an expression");
+ return -1;
+ }
+ return 0;
}
/* try to do an in-place conversion
@@ -1613,6 +1638,8 @@ rel_compare_exp_(sql_query *query, sql_r
if (anti)
set_anti(e);
} else {
+ if (rel_binop_check_types(sql, rel, ls, rs, 0) < 0)
+ return NULL;
e = exp_compare_func(sql, ls, rs, rs2,
compare_func((comp_type)type, quantifier?0:anti), quantifier);
if (anti && quantifier)
e = rel_unop_(sql, NULL, e, NULL, "not",
card_value);
@@ -1631,8 +1658,6 @@ rel_compare_exp_(sql_query *query, sql_r
type = (int)swap_compare((comp_type)type);
}
- if (!exp_subtype(ls) && !exp_subtype(rs))
- return sql_error(sql, 01, SQLSTATE(42000) "Cannot have
a parameter (?) on both sides of an expression");
if (rel_convert_types(sql, rel, rel, &ls, &rs, 1,
type_equal_no_any) < 0)
return NULL;
e = exp_compare(sql->sa, ls, rs, type);
@@ -1802,8 +1827,6 @@ rel_compare(sql_query *query, sql_rel *r
if (!rs2)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list