Changeset: a6023133240b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a6023133240b
Modified Files:
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql_upgrades.c
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
        sql/server/rel_propagate.c
        sql/server/rel_psm.c
        sql/server/rel_schema.c
        sql/server/rel_select.c
        sql/server/rel_select.h
        sql/server/rel_sequence.c
        sql/server/rel_unnest.c
        sql/server/rel_updates.c
        sql/server/rel_xml.c
        sql/server/sql_atom.c
        sql/server/sql_atom.h
        sql/test/SQLancer/Tests/All
        sql/test/SQLancer/Tests/sqlancer02.stable.out
Branch: default
Log Message:

Merged with Jun2020


diffs (truncated from 1405 to 300 lines):

diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -326,7 +326,7 @@ create_table_or_view(mvc *sql, char* sna
                        }
                        r = rel_parse(sql, s, sa_message(sql->sa, "select %s;", 
c->def), m_deps);
                        if (!r || !is_project(r->op) || !r->exps || 
list_length(r->exps) != 1 ||
-                               rel_check_type(sql, &c->type, r, 
r->exps->h->data, type_equal) == NULL) {
+                               exp_check_type(sql, &c->type, r, 
r->exps->h->data, type_equal) == NULL) {
                                if (r)
                                        rel_destroy(r);
                                sa_destroy(sql->sa);
diff --git a/sql/backends/monet5/sql_upgrades.c 
b/sql/backends/monet5/sql_upgrades.c
--- a/sql/backends/monet5/sql_upgrades.c
+++ b/sql/backends/monet5/sql_upgrades.c
@@ -2548,40 +2548,6 @@ sql_update_jun2020(Client c, mvc *sql, c
                        " external name \"sql\".\"corr\";\n"
                        "GRANT EXECUTE ON WINDOW corr(INTERVAL MONTH, INTERVAL 
MONTH) TO PUBLIC;\n");
 
-#ifdef HAVE_HGE
-       if (have_hge) {
-               /* 39_analytics_hge.sql */
-               pos += snprintf(buf + pos, bufsize - pos,
-                       "create window stddev_samp(val HUGEINT) returns 
DOUBLE\n"
-                       " external name \"sql\".\"stdev\";\n"
-                       "GRANT EXECUTE ON WINDOW stddev_samp(HUGEINT) TO 
PUBLIC;\n"
-                       "create window stddev_pop(val HUGEINT) returns DOUBLE\n"
-                       " external name \"sql\".\"stdevp\";\n"
-                       "GRANT EXECUTE ON WINDOW stddev_pop(HUGEINT) TO 
PUBLIC;\n"
-                       "create window var_samp(val HUGEINT) returns DOUBLE\n"
-                       " external name \"sql\".\"variance\";\n"
-                       "GRANT EXECUTE ON WINDOW var_samp(HUGEINT) TO PUBLIC;\n"
-                       "create window var_pop(val HUGEINT) returns DOUBLE\n"
-                       " external name \"sql\".\"variancep\";\n"
-                       "GRANT EXECUTE ON WINDOW var_pop(HUGEINT) TO PUBLIC;\n"
-                       "create aggregate covar_samp(e1 HUGEINT, e2 HUGEINT) 
returns DOUBLE\n"
-                       " external name \"aggr\".\"covariance\";\n"
-                       "GRANT EXECUTE ON AGGREGATE covar_samp(HUGEINT, 
HUGEINT) TO PUBLIC;\n"
-                       "create window covar_samp(e1 HUGEINT, e2 HUGEINT) 
returns DOUBLE\n"
-                       " external name \"sql\".\"covariance\";\n"
-                       "GRANT EXECUTE ON WINDOW covar_samp(HUGEINT, HUGEINT) 
TO PUBLIC;\n"
-                       "create aggregate covar_pop(e1 HUGEINT, e2 HUGEINT) 
returns DOUBLE\n"
-                       " external name \"aggr\".\"covariancep\";\n"
-                       "GRANT EXECUTE ON AGGREGATE covar_pop(HUGEINT, HUGEINT) 
TO PUBLIC;\n"
-                       "create window covar_pop(e1 HUGEINT, e2 HUGEINT) 
returns DOUBLE\n"
-                       " external name \"sql\".\"covariancep\";\n"
-                       "GRANT EXECUTE ON WINDOW covar_pop(HUGEINT, HUGEINT) TO 
PUBLIC;\n"
-                       "create window corr(e1 HUGEINT, e2 HUGEINT) returns 
DOUBLE\n"
-                       " external name \"sql\".\"corr\";\n"
-                       "GRANT EXECUTE ON WINDOW corr(HUGEINT, HUGEINT) TO 
PUBLIC;\n");
-       }
-#endif
-
        pos += snprintf(buf + pos, bufsize - pos,
                "create window sys.group_concat(str STRING) returns STRING\n"
                " external name \"sql\".\"str_group_concat\";\n"
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
@@ -498,6 +498,13 @@ exp_null(sql_allocator *sa, sql_subtype 
        return exp_atom(sa, a);
 }
 
+sql_exp *
+exp_zero(sql_allocator *sa, sql_subtype *tpe)
+{
+       atom *a = atom_zero_value(sa, tpe);
+       return exp_atom(sa, a);
+}
+
 atom *
 exp_value(mvc *sql, sql_exp *e, atom **args, int maxarg)
 {
@@ -2759,6 +2766,205 @@ exps_reset_freevar(list *exps)
        }
 }
 
+int
+rel_set_type_param(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp 
*rel_exp, int upcast)
+{
+       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 */
+       if (upcast && type->type->eclass == EC_NUM)
+#ifdef HAVE_HGE
+               type = sql_bind_localtype(have_hge ? "hge" : "lng");
+#else
+               type = sql_bind_localtype("lng");
+#endif
+       if (upcast && type->type->eclass == EC_FLT)
+               type = sql_bind_localtype("dbl");
+
+       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);
+               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;
+}
+
+/* try to do an in-place conversion
+ *
+ * in-place conversion is only possible if the exp is a variable.
+ * This is only done to be able to map more cached queries onto the same
+ * interface.
+ */
+
+static void
+convert_atom(atom *a, sql_subtype *rt)
+{
+       if (atom_null(a)) {
+               if (a->data.vtype != rt->type->localtype) {
+                       const void *p;
+
+                       a->data.vtype = rt->type->localtype;
+                       p = ATOMnilptr(a->data.vtype);
+                       VALset(&a->data, a->data.vtype, (ptr) p);
+               }
+       }
+       a->tpe = *rt;
+}
+
+static sql_exp *
+exp_convert_inplace(mvc *sql, sql_subtype *t, sql_exp *exp)
+{
+       atom *a;
+
+       /* exclude named variables and variable lists */
+       if (exp->type != e_atom || exp->r /* named */ || exp->f /* list */ || 
!exp->l /* not direct atom */)
+               return NULL;
+
+       a = exp->l;
+       if (t->scale && t->type->eclass != EC_FLT)
+               return NULL;
+
+       if (a && atom_cast(sql->sa, a, t)) {
+               convert_atom(a, t);
+               exp->tpe = *t;
+               return exp;
+       }
+       return NULL;
+}
+
+sql_exp *
+exp_numeric_supertype(mvc *sql, sql_exp *e )
+{
+       sql_subtype *tp = exp_subtype(e);
+
+       if (tp->type->eclass == EC_DEC) {
+               sql_subtype *dtp = sql_bind_localtype("dbl");
+
+               return exp_check_type(sql, dtp, NULL, e, type_cast);
+       }
+       if (tp->type->eclass == EC_NUM) {
+#ifdef HAVE_HGE
+               sql_subtype *ltp = sql_bind_localtype(have_hge ? "hge" : "lng");
+#else
+               sql_subtype *ltp = sql_bind_localtype("lng");
+#endif
+
+               return exp_check_type(sql, ltp, NULL, e, type_cast);
+       }
+       return e;
+}
+
+sql_exp *
+exp_check_type(mvc *sql, sql_subtype *t, sql_rel *rel, sql_exp *exp, 
check_type tpe)
+{
+       int c, err = 0;
+       sql_exp* nexp = NULL;
+       sql_subtype *fromtype = exp_subtype(exp);
+
+       if ((!fromtype || !fromtype->type) && rel_set_type_param(sql, t, rel, 
exp, 0) == 0)
+               return exp;
+
+       /* first try cheap internal (in-place) conversions ! */
+       if ((nexp = exp_convert_inplace(sql, t, exp)) != NULL)
+               return nexp;
+
+       if (fromtype && subtype_cmp(t, fromtype) != 0) {
+               if (EC_INTERVAL(fromtype->type->eclass) && (t->type->eclass == 
EC_NUM || t->type->eclass == EC_POS) && t->digits < fromtype->digits) {
+                       err = 1; /* conversion from interval to num depends on 
the number of digits */
+               } else {
+                       c = sql_type_convert(fromtype->type->eclass, 
t->type->eclass);
+                       if (!c || (c == 2 && tpe == type_set) || (c == 3 && tpe 
!= type_cast)) {
+                               err = 1;
+                       } else {
+                               exp = exp_convert(sql->sa, exp, fromtype, t);
+                       }
+               }
+       }
+       if (err) {
+               sql_exp *res = sql_error( sql, 03, SQLSTATE(42000) "types 
%s(%u,%u) and %s(%u,%u) are not equal%s%s%s",
+                       fromtype->type->sqlname,
+                       fromtype->digits,
+                       fromtype->scale,
+                       t->type->sqlname,
+                       t->digits,
+                       t->scale,
+                       (exp->type == e_column ? " for column '" : ""),
+                       (exp->type == e_column ? exp_name(exp) : ""),
+                       (exp->type == e_column ? "'" : "")
+               );
+               return res;
+       }
+       return exp;
+}
+
+sql_exp *
+exp_values_set_supertype(mvc *sql, sql_exp *values, sql_subtype *opt_super)
+{
+       assert(is_values(values));
+       list *vals = exp_get_values(values), *nexps;
+       sql_subtype *tpe = opt_super?opt_super:exp_subtype(vals->h->data);
+
+       if (!opt_super && tpe)
+               values->tpe = *tpe;
+
+       for (node *m = vals->h; m; m = m->next) {
+               sql_exp *e = m->data;
+               sql_subtype super, *ttpe;
+
+               /* if the expression is a parameter set its type */
+               if (tpe && e->type == e_atom && !e->l && !e->r && !e->f && 
!e->tpe.type) {
+                       if (set_type_param(sql, tpe, e->flag) == 0)
+                               e->tpe = *tpe;
+                       else
+                               return NULL;
+               }
+               ttpe = exp_subtype(e);
+               if (tpe && ttpe) {
+                       supertype(&super, ttpe, tpe);
+                       values->tpe = super;
+                       tpe = &values->tpe;
+               } else {
+                       tpe = ttpe;
+               }
+       }
+
+       if (tpe) {
+               /* if the expression is a parameter set its type */
+               for (node *m = vals->h; m; m = m->next) {
+                       sql_exp *e = m->data;
+                       if (e->type == e_atom && !e->l && !e->r && !e->f && 
!e->tpe.type) {
+                               if (set_type_param(sql, tpe, e->flag) == 0)
+                                       e->tpe = *tpe;
+                               else
+                                       return NULL;
+                       }
+               }
+               values->tpe = *tpe;
+               nexps = sa_list(sql->sa);
+               for (node *m = vals->h; m; m = m->next) {
+                       sql_exp *e = m->data;
+                       e = exp_check_type(sql, &values->tpe, NULL, e, 
type_equal);
+                       if (!e)
+                               return NULL;
+                       exp_label(sql->sa, e, ++sql->label);
+                       append(nexps, e);
+               }
+               values->f = nexps;
+       }
+       return values;
+}
+
 static int
 exp_set_list_recurse(mvc *sql, sql_subtype *type, sql_exp *e, const char 
**relname, const char** expname)
 {
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -12,6 +12,7 @@
 #include "sql_relation.h"
 #include "sql_mvc.h"
 #include "sql_atom.h"
+#include "sql_semantic.h"
 
 #define new_exp_list(sa) sa_list(sa)
 #define exp2list(sa,e)   append(sa_list(sa),e)
@@ -74,6 +75,7 @@ extern sql_exp * exp_atom_clob(sql_alloc
 extern sql_exp * exp_atom_ptr(sql_allocator *sa, void *s);
 extern sql_exp * exp_atom_ref(sql_allocator *sa, int i, sql_subtype *tpe);
 extern sql_exp * exp_null(sql_allocator *sa, sql_subtype *tpe);
+extern sql_exp * exp_zero(sql_allocator *sa, sql_subtype *tpe); /* Apply it to 
numeric types only obviously */
 extern sql_exp * exp_param_or_declared(sql_allocator *sa, const char *sname, 
const char *name, sql_subtype *tpe, int frame);
 extern atom * exp_value(mvc *sql, sql_exp *e, atom **args, int maxarg);
 extern sql_exp * exp_values(sql_allocator *sa, list *exps);
@@ -189,5 +191,10 @@ extern int exp_aggr_is_count(sql_exp *e)
 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to