Changeset: cd936df9a584 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=cd936df9a584
Modified Files:
        monetdb5/modules/atoms/mtime.c
        sql/test/miscellaneous/Tests/simple_plans.stable.out
        sql/test/miscellaneous/Tests/simple_plans.stable.out.single
Branch: clean-candidates
Log Message:

Merged with default


diffs (truncated from 7365 to 300 lines):

diff --git a/documentation/source/build.rst b/documentation/source/build.rst
--- a/documentation/source/build.rst
+++ b/documentation/source/build.rst
@@ -31,7 +31,7 @@ Prerequisites
 =============
 
 PATH settings: None
-ROle of clients?? How to install
+Role of clients?? How to install
 
 ## Testing
 
@@ -47,9 +47,9 @@ Configuration options
 
 The way options interact with building of the MonetDB source has
 fundamentally changed from the way this was done using the autotools
-buildsystem. Now almost all options are on by default. And these options
+build system. Now almost all options are on by default. And these options
 mostly control library detection. In the old system, it was possible to
-build a subset of the codebase. For example, you could choose not to
+build a subset of the code base. For example, you could choose not to
 build the sql part. Now the every part of the code is build, as long as
 the dependent libraries are detected. And by default, the system would
 try to detect all dependent libraries. If your system does not have a
diff --git a/monetdb5/mal/mal_linker.c b/monetdb5/mal/mal_linker.c
--- a/monetdb5/mal/mal_linker.c
+++ b/monetdb5/mal/mal_linker.c
@@ -485,7 +485,7 @@ MSP_locate_sqlscript(const char *filenam
 int
 malLibraryEnabled(str name)
 {
-       if (strcmp(name, "pyapi3") == 0) {
+       if (strcmp(name, "pyapi3") == 0 || strcmp(name, "pyapi3map") == 0) {
                const char *val = GDKgetenv("embedded_py");
                return val && (strcmp(val, "3") == 0 ||
                                           strcasecmp(val, "true") == 0 ||
@@ -510,7 +510,7 @@ malLibraryEnabled(str name)
 char *
 malLibraryHowToEnable(str name)
 {
-       if (strcmp(name, "pyapi3") == 0) {
+       if (strcmp(name, "pyapi3") == 0 || strcmp(name, "pyapi3map") == 0) {
                HOW_TO_ENABLE_ERROR("Python 3", "embedded_py=3")
        } else if (strcmp(name, "rapi") == 0) {
                HOW_TO_ENABLE_ERROR("R", "embedded_r=true")
diff --git a/monetdb5/modules/atoms/mtime.c b/monetdb5/modules/atoms/mtime.c
--- a/monetdb5/modules/atoms/mtime.c
+++ b/monetdb5/modules/atoms/mtime.c
@@ -465,9 +465,9 @@ date_diff_imp(const date d1, const date 
        return is_int_nil(diff) ? lng_nil : (lng) diff * (lng) (24*60*60*1000);
 }
 func2(MTIMEdate_diff, "diff", date, date, lng, date_diff_imp, func2_noexcept, \
-         DEC_VAR_R, DEC_VAR_R, DEC_VAR_R, DEC_INT, INIT_VAR, INIT_VAR, 
INIT_VAR, GET_NEXT_VAR, GET_NEXT_VAR, APPEND_VAR, FINISH_INT_SINGLE, 
CLEAR_NOTHING)
+         DEC_VAR, DEC_VAR, DEC_VAR_R, DEC_INT, INIT_VAR, INIT_VAR, INIT_VAR, 
GET_NEXT_VAR, GET_NEXT_VAR, APPEND_VAR, FINISH_INT_SINGLE, CLEAR_NOTHING)
 func2(MTIMEdaytime_diff_msec, "diff", daytime, daytime, lng, daytime_diff, 
func2_noexcept, \
-         DEC_VAR_R, DEC_VAR_R, DEC_VAR_R, DEC_INT, INIT_VAR, INIT_VAR, 
INIT_VAR, GET_NEXT_VAR, GET_NEXT_VAR, APPEND_VAR, FINISH_INT_SINGLE, 
CLEAR_NOTHING)
+         DEC_VAR, DEC_VAR, DEC_VAR_R, DEC_INT, INIT_VAR, INIT_VAR, INIT_VAR, 
GET_NEXT_VAR, GET_NEXT_VAR, APPEND_VAR, FINISH_INT_SINGLE, CLEAR_NOTHING)
 
 static inline str
 date_sub_msec_interval(date *ret, date d, lng ms)
@@ -644,7 +644,7 @@ TSDIFF(timestamp t1, timestamp t2)
        return diff;
 }
 func2(MTIMEtimestamp_diff_msec, "diff", timestamp, timestamp, lng, TSDIFF, 
func2_noexcept, \
-         DEC_VAR_R, DEC_VAR_R, DEC_VAR_R, DEC_INT, INIT_VAR, INIT_VAR, 
INIT_VAR, GET_NEXT_VAR, GET_NEXT_VAR, APPEND_VAR, FINISH_INT_SINGLE, 
CLEAR_NOTHING)
+         DEC_VAR, DEC_VAR, DEC_VAR_R, DEC_INT, INIT_VAR, INIT_VAR, INIT_VAR, 
GET_NEXT_VAR, GET_NEXT_VAR, APPEND_VAR, FINISH_INT_SINGLE, CLEAR_NOTHING)
 
 static inline int
 timestamp_century(const timestamp t)
diff --git a/monetdb5/modules/kernel/bat5.c b/monetdb5/modules/kernel/bat5.c
--- a/monetdb5/modules/kernel/bat5.c
+++ b/monetdb5/modules/kernel/bat5.c
@@ -867,8 +867,7 @@ BKCshrinkBAT(bat *ret, const bat *bid, c
        bn->tseqbase = oid_nil;
        bn->tkey = b->tkey;
        bn->tnonil = b->tnonil;
-       bn->tnil = b->tnil;
-
+       bn->tnil = false;               /* can't be sure if values deleted */
 
        BBPunfix(b->batCacheid);
        BBPunfix(bs->batCacheid);
diff --git a/monetdb5/modules/mal/batcalc.c b/monetdb5/modules/mal/batcalc.c
--- a/monetdb5/modules/mal/batcalc.c
+++ b/monetdb5/modules/mal/batcalc.c
@@ -1051,8 +1051,7 @@ CMDconvertbat(MalStkPtr stk, InstrPtr pc
                }
                if (s && ATOMtype(s->ttype) != TYPE_oid) {
                        BBPunfix(b->batCacheid);
-                       if (s)
-                               BBPunfix(s->batCacheid);
+                       BBPunfix(s->batCacheid);
                        throw(MAL, "batcalc.convert", SQLSTATE(42000) 
ILLEGAL_ARGUMENT);
                }
        }
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -1564,32 +1564,126 @@ rel_read(mvc *sql, char *r, int *pos, li
                        skipIdent(r, pos);
                        e = r+*pos;
                        skipWS(r, pos);
-                       if (r[*pos] != ')')
-                               sql_error(sql, -1, SQLSTATE(42000) "Table: 
missing ')'\n");
-                       *e = 0;
-                       (*pos)++;
-                       skipWS(r, pos);
-                       if (!(s = mvc_bind_schema(sql, sname)))
-                               return sql_error(sql, -1, SQLSTATE(3F000) "No 
such schema '%s'\n", sname);
-                       if (!(t = mvc_bind_table(sql, s, tname)))
-                               return sql_error(sql, -1, SQLSTATE(42S02) 
"Table missing '%s.%s'\n", sname, tname);
-                       if (isMergeTable(t))
-                               return sql_error(sql, -1, SQLSTATE(42000) 
"Merge tables not supported under remote connections\n");
-                       if (isRemote(t))
-                               return sql_error(sql, -1, SQLSTATE(42000) 
"Remote tables not supported under remote connections\n");
-                       if (isReplicaTable(t))
-                               return sql_error(sql, -1, SQLSTATE(42000) 
"Replica tables not supported under remote connections\n");
-                       rel = rel_basetable(sql, t, tname);
-                       if (!table_privs(sql, t, PRIV_SELECT) && !(rel = 
rel_reduce_on_column_privileges(sql, rel, t)))
-                               return sql_error(sql, -1, SQLSTATE(42000) 
"Access denied for %s to table '%s.%s'\n", 
sqlvar_get_string(find_global_var(sql, mvc_bind_schema(sql, "sys"), 
"current_user")), s->base.name, tname);
+                       if (r[*pos] == '(') { /* table returning function */
+                               node *m;
+                               sql_exp *tudf, *next;
+                               list *inputs, *outputs;
+                               sql_subfunc *sf;
+                               int x = *pos, y; /* save current position, 
after parsing the input relation we have to parse the input parameters */
+                               bool inside_identifier = false;
+
+                               while (r[*pos] && (inside_identifier || r[*pos] 
!= '\n')) { /* the input parameters must be parsed after the input relation, 
skip them for now  */
+                                       (*pos)++;
+                                       if (r[*pos] == '"')
+                                               inside_identifier = 
!inside_identifier;
+                               }
+                               if (r[*pos] != '\n')
+                                       return sql_error(sql, -1, 
SQLSTATE(42000) "Table returning function: missing ']' for output 
parameters\n");
+
+                               skipWS(r, pos); /* now parse the input relation 
*/
+                               if (!(lrel = rel_read(sql, r, pos, refs)))
+                                       return NULL;
+                               y = *pos; /* later we have to return here to 
parse the output identifiers */
+                               *pos = x;
+                               if (!(inputs = read_exps(sql, lrel, NULL, NULL, 
r, pos, '(', 0)))
+                                       return NULL;
+
+                               if (!(s = mvc_bind_schema(sql, sname)))
+                                       return sql_error(sql, -1, 
SQLSTATE(3F000) "No such schema '%s'\n", sname);
+                               *e = 0; /* closing table udf name string */
+                               if (!(tudf = find_table_function(sql, s, tname, 
list_empty(inputs) ? NULL : inputs, list_empty(inputs) ? NULL : 
exp_types(sql->sa, inputs))))
+                                       return sql_error(sql, 02, 
SQLSTATE(42S02) "No such table returning function '%s.%s'\n", sname, tname);
+                               sf = tudf->f;
+                               if (tudf->type != e_func || sf->func->type != 
F_UNION)
+                                       return sql_error(sql, 02, 
SQLSTATE(42000) "'%s' does not return a table\n", exp_func_name(tudf));
+
+                               *pos = y; /* now at the end of the input 
relation */
+                               skipWS(r, pos);
+                               if (r[*pos] != ')')
+                                       return sql_error(sql, -1, 
SQLSTATE(42000) "Table returning function: missing ')' at the end of the input 
relation\n");
+                               (*pos)++;
+                               skipWS(r, pos);
+
+                               /* Parse identifiers manually, we cannot use 
read_exps because the labels may not match */
+                               if (r[*pos] != '[')
+                                       return sql_error(sql, -1, 
SQLSTATE(42000) "Table returning function: missing '[' for output 
parameters\n");
+                               (*pos)++;
+                               skipWS(r, pos);
+                               m = sf->func->res->h;
+                               outputs = new_exp_list(sql->sa);
+                               while (r[*pos] && r[*pos] != ']' && m) {
+                                       sql_arg *a = m->data;
+                                       char *nrname, *ncname;
 
-                       if (!r[*pos])
-                               return rel;
+                                       if (r[*pos] != '"')
+                                               return sql_error(sql, -1, 
SQLSTATE(42000) "Table returning function: missing identifier for output 
parameters\n");
+                                       (*pos)++;
+                                       nrname = r+*pos;
+                                       skipIdent(r, pos);
+                                       if (r[*pos] != '"')
+                                               return sql_error(sql, -1, 
SQLSTATE(42000) "Table returning function: missing identifier for output 
parameters\n");
+                                       e = r+*pos;
+                                       *e = 0;
+                                       (*pos)++;
+                                       if (r[*pos] != '.')
+                                               return sql_error(sql, -1, 
SQLSTATE(42000) "Table returning function: missing '.' for output 
parameters\n");
+                                       (*pos)++; /* skip '.' */
+                                       if (r[*pos] != '"')
+                                               return sql_error(sql, -1, 
SQLSTATE(42000) "Table returning function: missing identifier for output 
parameters\n");
+                                       (*pos)++;
+                                       ncname = r+*pos;
+                                       skipIdent(r, pos);
+                                       if (r[*pos] != '"')
+                                               return sql_error(sql, -1, 
SQLSTATE(42000) "Table returning function: missing identifier for output 
parameters\n");
+                                       e = r+*pos;
+                                       *e = 0;
+                                       (*pos)++;
+                                       if (r[*pos] == ',')
+                                               (*pos)++;
 
-                       /* scan aliases */
-                       if (!(exps = read_exps(sql, rel, NULL, NULL, r, pos, 
'[', 0)))
-                               return NULL;
-                       rel->exps = exps;
+                                       next = exp_column(sql->sa, nrname, 
ncname, &a->type, CARD_MULTI, 1, 0);
+                                       set_basecol(next);
+                                       append(outputs, next);
+                                       m = m->next;
+                                       skipWS(r, pos);
+                               }
+                               if (r[*pos] != ']')
+                                       return sql_error(sql, -1, 
SQLSTATE(42000) "Table returning function: missing ']' for output 
parameters\n");
+                               (*pos)++;
+                               skipWS(r, pos);
+                               if (list_length(outputs) != 
list_length(sf->func->res))
+                                       return sql_error(sql, -1, 
SQLSTATE(42000) "Table returning function: the number of output parameters 
don't match the table ones relation outputs: %d != function outputs: %d\n",
+                                                                        
list_length(outputs), list_length(sf->func->res));
+                               rel = rel_table_func(sql->sa, lrel, tudf, 
outputs, TABLE_FROM_RELATION);
+                       } else {
+                               if (r[*pos] != ')')
+                                       sql_error(sql, -1, SQLSTATE(42000) 
"Table: missing ')'\n");
+                               *e = 0;
+                               (*pos)++;
+                               skipWS(r, pos);
+                               if (!(s = mvc_bind_schema(sql, sname)))
+                                       return sql_error(sql, -1, 
SQLSTATE(3F000) "No such schema '%s'\n", sname);
+                               if (!(t = mvc_bind_table(sql, s, tname)))
+                                       return sql_error(sql, -1, 
SQLSTATE(42S02) "Table missing '%s.%s'\n", sname, tname);
+                               if (isMergeTable(t))
+                                       return sql_error(sql, -1, 
SQLSTATE(42000) "Merge tables not supported under remote connections\n");
+                               if (isRemote(t))
+                                       return sql_error(sql, -1, 
SQLSTATE(42000) "Remote tables not supported under remote connections\n");
+                               if (isReplicaTable(t))
+                                       return sql_error(sql, -1, 
SQLSTATE(42000) "Replica tables not supported under remote connections\n");
+                               rel = rel_basetable(sql, t, tname);
+                               if (!table_privs(sql, t, PRIV_SELECT) && !(rel 
= rel_reduce_on_column_privileges(sql, rel, t)))
+                                       return sql_error(sql, -1, 
SQLSTATE(42000) "Access denied for %s to table '%s.%s'\n",
+                                                                        
sqlvar_get_string(find_global_var(sql, mvc_bind_schema(sql, "sys"), 
"current_user")), s->base.name, tname);
+
+                               if (!r[*pos])
+                                       return rel;
+
+                               /* scan aliases */
+                               if (!(exps = read_exps(sql, rel, NULL, NULL, r, 
pos, '[', 0)))
+                                       return NULL;
+                               rel->exps = exps;
+                       }
                        if (strncmp(r+*pos, "COUNT",  strlen("COUNT")) == 0) {
                                (*pos)+= (int) strlen("COUNT");
                                skipWS( r, pos);
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
@@ -1091,15 +1091,20 @@ exp_cmp( sql_exp *e1, sql_exp *e2)
        return (e1 == e2)?0:-1;
 }
 
+#define alias_cmp(e1, e2) \
+       do { \
+               if (e1->alias.rname && e2->alias.rname && 
strcmp(e1->alias.rname, e2->alias.rname) == 0) \
+                       return strcmp(e1->alias.name, e2->alias.name); \
+               if (!e1->alias.rname && !e2->alias.rname && e1->alias.label == 
e2->alias.label && e1->alias.name && e2->alias.name) \
+                       return strcmp(e1->alias.name, e2->alias.name); \
+       } while (0);
+
 int
 exp_equal( sql_exp *e1, sql_exp *e2)
 {
        if (e1 == e2)
                return 0;
-       if (e1->alias.rname && e2->alias.rname && strcmp(e1->alias.rname, 
e2->alias.rname) == 0)
-               return strcmp(e1->alias.name, e2->alias.name);
-       if (!e1->alias.rname && !e2->alias.rname && e1->alias.label == 
e2->alias.label && e1->alias.name && e2->alias.name)
-               return strcmp(e1->alias.name, e2->alias.name);
+       alias_cmp(e1, e2);
        return -1;
 }
 
@@ -1288,6 +1293,10 @@ exp_match_exp( sql_exp *e1, sql_exp *e2)
 {
        if (exp_match(e1, e2))
                return 1;
+       if (is_ascending(e1) != is_ascending(e2) || nulls_last(e1) != 
nulls_last(e2) || zero_if_empty(e1) != zero_if_empty(e2) ||
+               need_no_nil(e1) != need_no_nil(e2) || is_anti(e1) != 
is_anti(e2) || is_semantics(e1) != is_semantics(e2) ||
+               need_distinct(e1) != need_distinct(e2))
+               return 0;
        if (e1->type == e2->type) {
                switch(e1->type) {
                case e_cmp:
@@ -1300,7 +1309,7 @@ exp_match_exp( sql_exp *e1, sql_exp *e2)
                            exp_match_list(e1->l, e2->l) &&
                            exp_match_list(e1->r, e2->r))
                                return 1;
-                       else if (e1->flag == e2->flag && is_anti(e1) == 
is_anti(e2) &&
+                       else if (e1->flag == e2->flag &&
                                (e1->flag == cmp_in || e1->flag == cmp_notin) &&
                            exp_match_exp(e1->l, e2->l) &&
                            exp_match_list(e1->r, e2->r))
@@ -1357,6 +1366,27 @@ exps_any_match(list *l, sql_exp *e)
 }
 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to