Changeset: 01a52e34518a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=01a52e34518a
Modified Files:
        sql/common/sql_types.c
        sql/server/rel_rel.c
        sql/server/rel_select.c
        sql/test/miscellaneous/Tests/simple_plans.stable.out
Branch: default
Log Message:

Merged with Jun2020


diffs (truncated from 340 to 300 lines):

diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c
--- a/sql/common/sql_types.c
+++ b/sql/common/sql_types.c
@@ -575,8 +575,8 @@ sql_dup_subfunc(sql_allocator *sa, sql_f
                                sql_arg *rarg = tn->data;
                                sql_subtype *res, *r = &rarg->type;
        
-                               /* same scale as the input */
-                               if (member && member->scale > scale)
+                               /* same scale as the input if result has a 
scale */
+                               if (member && (r->type->eclass == EC_ANY || 
r->type->scale != SCALE_NONE) && member->scale > scale)
                                        scale = member->scale;
                                digits = r->digits;
                                if (!member) {
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -1296,7 +1296,6 @@ rel_push_select(mvc *sql, sql_rel *rel, 
        return rel;
 }
 
-
 /* ls and rs are the left and right expression of the join, e is the
    join expression.
  */
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
@@ -1699,6 +1699,46 @@ rel_filter_exp_(mvc *sql, sql_rel *rel, 
 }
 
 static sql_rel *
+rel_compare_push_exp(mvc *sql, sql_rel *rel, sql_exp *e, sql_exp *ls, sql_exp 
*L, sql_exp *rs, sql_exp *R, sql_exp *rs2)
+{
+       if (rs->card <= CARD_ATOM && (exp_is_atom(rs) || exp_has_freevar(sql, 
rs) || exp_has_freevar(sql, ls)) &&
+          (!rs2 || (rs2->card <= CARD_ATOM && (exp_is_atom(rs2) || 
exp_has_freevar(sql, rs2))))) {
+               if ((ls->card == rs->card && !rs2) || rel->processed)  /* bin 
compare op */
+                       return rel_select(sql->sa, rel, e);
+
+               if (/*is_semi(rel->op) ||*/ is_outerjoin(rel->op)) {
+                       if ((is_left(rel->op) || is_full(rel->op)) && 
rel_find_exp(rel->l, ls)) {
+                               rel_join_add_exp(sql->sa, rel, e);
+                               return rel;
+                       } else if ((is_right(rel->op) || is_full(rel->op)) && 
rel_find_exp(rel->r, ls)) {
+                               rel_join_add_exp(sql->sa, rel, e);
+                               return rel;
+                       }
+                       if (is_left(rel->op) && rel_find_exp(rel->r, ls)) {
+                               rel->r = rel_push_select(sql, rel->r, L, e);
+                               return rel;
+                       } else if (is_right(rel->op) && rel_find_exp(rel->l, 
ls)) {
+                               rel->l = rel_push_select(sql, rel->l, L, e);
+                               return rel;
+                       }
+               }
+               /* push select into the given relation */
+               return rel_push_select(sql, rel, L, e);
+       } else { /* join */
+               sql_rel *r;
+               if (/*is_semi(rel->op) ||*/ (is_outerjoin(rel->op) && 
!is_processed((rel)))) {
+                       rel_join_add_exp(sql->sa, rel, e);
+                       return rel;
+               }
+               /* push join into the given relation */
+               if ((r = rel_push_join(sql, rel, L, R, rs2, e)) != NULL)
+                       return r;
+               rel_join_add_exp(sql->sa, rel, e);
+               return rel;
+       }
+}
+
+static sql_rel *
 rel_compare_exp_(sql_query *query, sql_rel *rel, sql_exp *ls, sql_exp *rs, 
sql_exp *rs2, int type, int anti, int quantifier)
 {
        mvc *sql = query->sql;
@@ -1759,45 +1799,7 @@ rel_compare_exp_(sql_query *query, sql_r
                else
                        return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) 
"SELECT: cannot use non GROUP BY column in query results without an aggregate 
function");
        }
-       if (rs->card <= CARD_ATOM && (exp_is_atom(rs) || exp_has_freevar(sql, 
rs) || exp_has_freevar(sql, ls)) &&
-          (!rs2 || (rs2->card <= CARD_ATOM && (exp_is_atom(rs2) || 
exp_has_freevar(sql, rs2))))) {
-               if ((ls->card == rs->card && !rs2) || rel->processed)  /* bin 
compare op */
-                       return rel_select(sql->sa, rel, e);
-
-               if (/*is_semi(rel->op) ||*/ is_outerjoin(rel->op)) {
-                       if ((is_left(rel->op) || is_full(rel->op)) && 
rel_find_exp(rel->l, ls)) {
-                               rel_join_add_exp(sql->sa, rel, e);
-                               return rel;
-                       } else if ((is_right(rel->op) || is_full(rel->op)) && 
rel_find_exp(rel->r, ls)) {
-                               rel_join_add_exp(sql->sa, rel, e);
-                               return rel;
-                       }
-                       if (is_semi(rel->op)) {
-                               rel_join_add_exp(sql->sa, rel, e);
-                               return rel;
-                       }
-                       if (is_left(rel->op) && rel_find_exp(rel->r, ls)) {
-                               rel->r = rel_push_select(sql, rel->r, L, e);
-                               return rel;
-                       } else if (is_right(rel->op) && rel_find_exp(rel->l, 
ls)) {
-                               rel->l = rel_push_select(sql, rel->l, L, e);
-                               return rel;
-                       }
-               }
-               /* push select into the given relation */
-               return rel_push_select(sql, rel, L, e);
-       } else { /* join */
-               sql_rel *r;
-               if (/*is_semi(rel->op) ||*/ (is_outerjoin(rel->op) && 
!is_processed((rel)))) {
-                       rel_join_add_exp(sql->sa, rel, e);
-                       return rel;
-               }
-               /* push join into the given relation */
-               if ((r = rel_push_join(sql, rel, L, R, rs2, e)) != NULL)
-                       return r;
-               rel_join_add_exp(sql->sa, rel, e);
-               return rel;
-       }
+       return rel_compare_push_exp(sql, rel, e, ls, L, rs, R, rs2);
 }
 
 static sql_rel *
@@ -2140,10 +2142,28 @@ rel_in_value_exp(sql_query *query, sql_r
                        if (rel_binop_check_types(sql, rel ? *rel : NULL, le, 
values, 0) < 0)
                                return NULL;
                        supertype(&super, exp_subtype(values), exp_subtype(le));
-                       if ((le = rel_check_type(sql, &super, NULL, le, 
type_equal)) == NULL)
+
+                       /* on selection/join cases we can generate cmp 
expressions instead of anyequal for trivial cases */
+                       if (is_sql_where(f) && !is_sql_farg(f) && 
exps_are_atoms(vals)) { 
+                               if (list_length(vals) == 1) { /* use cmp_equal 
instead of anyequal for 1 constant */
+                                       sql_exp *first = vals->h->data;
+                                       if (rel_convert_types(sql, rel ? *rel : 
NULL, rel ? *rel : NULL, &le, &first, 1, type_equal_no_any) < 0)
+                                               return NULL;
+                                       e = exp_compare(sql->sa, le, first, 
(sc->token == SQL_IN) ? cmp_equal : cmp_notequal);
+                               } else { /* use cmp_in instead of anyequal for 
n constants */
+                                       for (node *n = vals->h ; n ; n = 
n->next)
+                                               if ((n->data = 
rel_check_type(sql, &super, rel ? *rel : NULL, n->data, type_equal)) == NULL)
+                                                       return NULL;
+                                       if ((le = rel_check_type(sql, &super, 
rel ? *rel : NULL, le, type_equal)) == NULL)
+                                               return NULL;
+                                       e = exp_in(sql->sa, le, vals, 
(sc->token == SQL_IN) ? cmp_in : cmp_notin);
+                               }
+                       }
+                       if (!e && (le = rel_check_type(sql, &super, rel ? *rel 
: NULL, le, type_equal)) == NULL)
                                return NULL;
                }
-               e = exp_in_func(sql, le, values, (sc->token == SQL_IN), 
is_tuple);
+               if (!e)
+                       e = exp_in_func(sql, le, values, (sc->token == SQL_IN), 
is_tuple);
        }
        if (e && le)
                e->card = le->card;
@@ -2151,6 +2171,29 @@ rel_in_value_exp(sql_query *query, sql_r
 }
 
 static sql_rel *
+push_select_exp(mvc *sql, sql_rel *rel, sql_exp *e, sql_exp *ls) /* 'e' is an 
expression where the right is a constant(s)! */
+{
+       if (is_outerjoin(rel->op)) {
+               if ((is_left(rel->op) || is_full(rel->op)) && 
rel_find_exp(rel->l, ls)) {
+                       rel_join_add_exp(sql->sa, rel, e);
+                       return rel;
+               } else if ((is_right(rel->op) || is_full(rel->op)) && 
rel_find_exp(rel->r, ls)) {
+                       rel_join_add_exp(sql->sa, rel, e);
+                       return rel;
+               }
+               if (is_left(rel->op) && rel_find_exp(rel->r, ls)) {
+                       rel->r = rel_push_select(sql, rel->r, ls, e);
+                       return rel;
+               } else if (is_right(rel->op) && rel_find_exp(rel->l, ls)) {
+                       rel->l = rel_push_select(sql, rel->l, ls, e);
+                       return rel;
+               }
+       }
+       /* push select into the given relation */
+       return rel_push_select(sql, rel, ls, e);
+}
+
+static sql_rel *
 rel_in_exp(sql_query *query, sql_rel *rel, symbol *sc, int f) 
 {
        mvc *sql = query->sql;
@@ -2159,8 +2202,10 @@ rel_in_exp(sql_query *query, sql_rel *re
        assert(!is_sql_sel(f));
        if (!e || !rel)
                return NULL;
-       rel = rel_select_add_exp(sql->sa, rel, e);
-       return rel;
+
+       if (e->type == e_cmp) /* it's a exp_in or cmp_equal of constants, push 
down early on if possible */
+               return push_select_exp(sql, rel, e, e->l);
+       return rel_select_add_exp(sql->sa, rel, e);;
 }
 
 sql_exp *
@@ -2707,8 +2752,8 @@ rel_logical_exp(sql_query *query, sql_re
                        }
                        if (!e1)
                                return NULL;
-                       e2 = exp_atom_bool(sql->sa, 1);
-                       rel = rel_select(sql->sa, rel, exp_compare(sql->sa,  
e1, e2, cmp_equal));
+                       e2 = exp_compare(sql->sa, e1, exp_atom_bool(sql->sa, 
1), cmp_equal);
+                       return rel_compare_push_exp(sql, rel, e2, le, le, re1, 
re1, re2);
                } else if (sc->token == SQL_NOT_BETWEEN) {
                        rel = rel_compare_exp_(query, rel, le, re1, re2, 
3|CMP_BETWEEN|flag, 1, 0);
                } else {
@@ -2720,22 +2765,18 @@ rel_logical_exp(sql_query *query, sql_re
        case SQL_IS_NOT_NULL:
        /* is (NOT) NULL */
        {
-               sql_exp *re, *le = rel_value_exp(query, &rel, sc->data.sym, f, 
ek);
+               sql_exp *le = rel_value_exp(query, &rel, sc->data.sym, f, ek), 
*ls = le;
 
                if (!le)
                        return NULL;
                if (!(le = rel_unop_(sql, rel, le, NULL, "isnull", card_value)))
                        return NULL;
                set_has_no_nil(le);
-               if (sc->token == SQL_IS_NULL)
-                       re = exp_atom_bool(sql->sa, 1);
-               else
-                       re = exp_atom_bool(sql->sa, 0);
-               le = exp_compare(sql->sa, le, re, cmp_equal);
-               return rel_select(sql->sa, rel, le);
+               le = exp_compare(sql->sa, le, exp_atom_bool(sql->sa, (sc->token 
== SQL_IS_NULL) ? 1 : 0), cmp_equal);
+               return push_select_exp(sql, rel, le, ls);
        }
        case SQL_NOT: {
-               sql_exp *le;
+               sql_exp *le, *ls;
                switch (sc->data.sym->token) {
                case SQL_IN:
                        sc->data.sym->token = SQL_NOT_IN;
@@ -2746,25 +2787,25 @@ rel_logical_exp(sql_query *query, sql_re
                default:
                        break;
                } 
-               le = rel_value_exp(query, &rel, sc->data.sym, f|sql_farg, ek);
+               ls = le = rel_value_exp(query, &rel, sc->data.sym, f|sql_farg, 
ek);
 
                if (!le)
                        return NULL;
                if (!(le = rel_unop_(sql, rel, le, NULL, "not", card_value)))
                        return NULL;
                le = exp_compare(sql->sa, le, exp_atom_bool(sql->sa, 1), 
cmp_equal);
-               return rel_select(sql->sa, rel, le);
+               return push_select_exp(sql, rel, le, ls);
        }
        case SQL_ATOM: {
                /* TRUE or FALSE */
                AtomNode *an = (AtomNode *) sc;
                sql_exp *e = exp_atom(sql->sa, atom_dup(sql->sa, an->a));
-               return rel_select(sql->sa, rel, e);
+               return push_select_exp(sql, rel, e, e);
        }
        case SQL_IDENT:
        case SQL_COLUMN: {
                sql_rel *or = rel;
-               sql_exp *e = rel_column_ref(query, &rel, sc, f);
+               sql_exp *e = rel_column_ref(query, &rel, sc, f), *ls = e;
 
                if (e) {
                        sql_subtype bt;
@@ -2774,7 +2815,7 @@ rel_logical_exp(sql_query *query, sql_re
                }
                if (!e || or != rel)
                        return NULL;
-               return rel_select(sql->sa, rel, e);
+               return push_select_exp(sql, rel, e, ls);
        }
        case SQL_UNION:
        case SQL_EXCEPT:
@@ -2793,16 +2834,15 @@ rel_logical_exp(sql_query *query, sql_re
                        return sq;
                sq = rel_zero_or_one(sql, sq, ek);
                if (is_sql_where(f)) {
-                       sql_exp *le = exp_rel(sql, sq), *re;
+                       sql_exp *le = exp_rel(sql, sq), *ls = le;
                        sql_subtype bt;
 
                        sql_find_subtype(&bt, "boolean", 0, 0);
                        le = rel_check_type(sql, &bt, rel, le, type_equal);
                        if (!le)
                                return NULL;
-                       re = exp_atom_bool(sql->sa, 1);
-                       le = exp_compare(sql->sa, le, re, cmp_equal);
-                       return rel_select(sql->sa, rel, le);
+                       le = exp_compare(sql->sa, le, exp_atom_bool(sql->sa, 
1), cmp_equal);
+                       return push_select_exp(sql, rel, le, ls);
                } else {
                        sq = rel_crossproduct(sql->sa, rel, sq, (f==sql_sel || 
sq->single)?op_left:op_join);
                }
@@ -2811,7 +2851,7 @@ rel_logical_exp(sql_query *query, sql_re
        case SQL_DEFAULT:
                return sql_error(sql, 02, SQLSTATE(42000) "DEFAULT keyword not 
allowed outside insert and update statements");
        default: {
-               sql_exp *le = rel_value_exp(query, &rel, sc, f, ek);
+               sql_exp *le = rel_value_exp(query, &rel, sc, f, ek), *ls = le;
                sql_subtype bt;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to