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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list