Changeset: 4aab2525d40a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/4aab2525d40a
Modified Files:
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql_upgrades.c
        sql/scripts/52_describe.sql
        sql/server/rel_optimize_others.c
        sql/server/rel_optimizer.c
        sql/server/rel_rel.c
        sql/server/rel_rel.h
        sql/server/rel_select.c
        sql/storage/sql_catalog.c
        sql/storage/store.c
        sql/test/BugTracker-2024/Tests/All
        sql/test/Dependencies/Tests/dependency_DBobjects.test
        sql/test/Dependencies/Tests/dependency_owner_schema_3.test
        sql/test/SQLancer/Tests/sqlancer18.test
        
sql/test/emptydb-previous-upgrade-chain-hge/Tests/upgrade.stable.out.int128
        sql/test/emptydb-previous-upgrade-chain/Tests/upgrade.stable.out
        sql/test/emptydb-previous-upgrade-chain/Tests/upgrade.stable.out.int128
        sql/test/emptydb-previous-upgrade-hge/Tests/upgrade.stable.out.int128
        sql/test/emptydb-previous-upgrade/Tests/upgrade.stable.out
        sql/test/emptydb-previous-upgrade/Tests/upgrade.stable.out.int128
        sql/test/emptydb-upgrade-chain-hge/Tests/upgrade.stable.out.int128
        sql/test/emptydb-upgrade-chain/Tests/upgrade.stable.out
        sql/test/emptydb-upgrade-chain/Tests/upgrade.stable.out.int128
        sql/test/emptydb-upgrade-hge/Tests/upgrade.stable.out.int128
        sql/test/emptydb-upgrade/Tests/upgrade.stable.out
        sql/test/emptydb-upgrade/Tests/upgrade.stable.out.int128
        sql/test/emptydb/Tests/check.stable.out
        sql/test/emptydb/Tests/check.stable.out.32bit
        sql/test/emptydb/Tests/check.stable.out.int128
        sql/test/sql_dump/Tests/dump.test
        
sql/test/testdb-previous-upgrade-chain-hge/Tests/upgrade.stable.out.int128
        sql/test/testdb-previous-upgrade-chain/Tests/upgrade.stable.out
        sql/test/testdb-previous-upgrade-chain/Tests/upgrade.stable.out.int128
        sql/test/testdb-previous-upgrade-hge/Tests/upgrade.stable.out.int128
        sql/test/testdb-previous-upgrade/Tests/upgrade.stable.out
        sql/test/testdb-previous-upgrade/Tests/upgrade.stable.out.int128
        sql/test/testdb-upgrade-chain-hge/Tests/upgrade.stable.out.int128
        sql/test/testdb-upgrade-chain/Tests/upgrade.stable.out
        sql/test/testdb-upgrade-chain/Tests/upgrade.stable.out.int128
        sql/test/testdb-upgrade-hge/Tests/upgrade.stable.out.int128
        sql/test/testdb-upgrade/Tests/upgrade.stable.out
        sql/test/testdb-upgrade/Tests/upgrade.stable.out.int128
Branch: default
Log Message:

Merge with Dec2023 branch.


diffs (truncated from 1220 to 300 lines):

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -826,3 +826,4 @@ dcc8c702e685a4faf21ccf663028d1bc3d1165d1
 d656785f49ee62c19705722aa6b7c171904c64d5 Dec2023_7
 d656785f49ee62c19705722aa6b7c171904c64d5 Dec2023_SP2_release
 9a694c41042503a22d6c92aeab5bc4ca1912b62e Dec2023_9
+9a694c41042503a22d6c92aeab5bc4ca1912b62e Dec2023_SP3_release
diff --git a/monetdb5/modules/atoms/url.c b/monetdb5/modules/atoms/url.c
--- a/monetdb5/modules/atoms/url.c
+++ b/monetdb5/modules/atoms/url.c
@@ -107,8 +107,10 @@ skip_authority(const char *uri, const ch
                                        port = pass = uri + 1;
                                else
                                        port = uri + 1;
-                       } else if (*uri == '@')
+                       } else if (*uri == '@') {
                                host = uri + 1;
+                               port = NULL;
+                       }
                        uri += *uri == '%' ? 3 : 1;
                }
                if (user == host) {
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
@@ -5208,6 +5208,8 @@ SQLuser_password(Client cntxt, MalBlkPtr
                        return msg;
        }
        *password = monet5_password_hash(m, username);
+       if (!(*password))
+               throw(SQL, "mvc", SQLSTATE(42000) "SELECT: Failed to retrieve 
password hash");
        return MAL_SUCCEED;
 }
 
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
@@ -6596,6 +6596,46 @@ sql_update_dec2023_sp1(Client c, mvc *sq
 }
 
 static str
+sql_update_dec2023_sp4(Client c, mvc *sql, sql_schema *s)
+{
+       char *err;
+       res_table *output;
+       BAT *b;
+
+       (void) sql;
+       (void) s;
+
+       /* SQL optimizer fixes make that some "dependencies" are no longer
+        * dependencies (functions that depend on all columns of a table
+        * when it only actually uses a subset of the columns); while we're
+        * at it, also fix some ancient dependency changes where view did
+        * the same thing (i.e. the second delete will normally not delete
+        * anything) */
+       err = SQLstatementIntern(c, "select * from sys.dependencies where (id, 
depend_id) in (select c.id, f.id from sys.functions f, sys._tables t, 
sys._columns c, sys.dependencies d where c.table_id = t.id and f.id = 
d.depend_id and c.id = d.id and f.schema_id = 2000 and t.schema_id = 2000 and 
(f.name, t.name, c.name) in (values ('describe_columns', '_columns', 
'storage')));\n", "update", true, false, &output);
+       if (err)
+               return err;
+       b = BATdescriptor(output->cols[0].b);
+       if (b) {
+               if (BATcount(b) > 0) {
+                       const char query[] = "delete from sys.dependencies 
where (id, depend_id) in (select c.id, f.id from sys.functions f, sys._tables 
t, sys._columns c, sys.dependencies d where c.table_id = t.id and f.id = 
d.depend_id and c.id = d.id and f.schema_id = 2000 and t.schema_id = 2000 and 
(f.name, t.name, c.name) in (values ('describe_columns', '_columns', 
'storage'), ('describe_function', 'function_languages', 'language_name'), 
('describe_function', 'function_types', 'function_type_name'), 
('describe_function', 'functions', 'func'), ('describe_function', 'functions', 
'mod'), ('describe_function', 'functions', 'semantics'), ('describe_function', 
'functions', 'side_effect'), ('describe_function', 'functions', 'system'), 
('describe_function', 'functions', 'vararg'), ('describe_function', 
'functions', 'varres'), ('describe_function', 'schemas', 'authorization'), 
('describe_function', 'schemas', 'owner'), ('describe_function', 'schemas', 
'system'), ('describe_table', '_tables', 'access'), ('de
 scribe_table', '_tables', 'commit_action'), ('describe_table', '_tables', 
'system')));\n"
+                               "delete from sys.dependencies where (id, 
depend_id) in (select c.id, v.id from sys._tables v, sys._tables t, 
sys._columns c, sys.dependencies d where c.table_id = t.id and v.id = 
d.depend_id and c.id = d.id and v.schema_id = 2000 and t.schema_id = 2000 and 
(v.name, t.name, c.name) in (values ('dependency_columns_on_indexes', 
'_columns', 'name'), ('dependency_columns_on_indexes', '_columns', 'number'), 
('dependency_columns_on_indexes', '_columns', 'storage'), 
('dependency_columns_on_indexes', '_columns', 'table_id'), 
('dependency_columns_on_indexes', '_columns', 'type_digits'), 
('dependency_columns_on_indexes', 'keys', 'id'), 
('dependency_columns_on_indexes', 'triggers', 'name'), 
('dependency_columns_on_indexes', 'triggers', 'orientation'), 
('dependency_columns_on_indexes', 'triggers', 'table_id'), 
('dependency_columns_on_indexes', 'triggers', 'time'), 
('dependency_columns_on_keys', '_columns', 'name'), 
('dependency_columns_on_keys', '_columns', 'table_id'), ('dependency_columns_
 on_keys', '_columns', 'type'), ('dependency_columns_on_keys', '_columns', 
'type_digits'), ('dependency_columns_on_keys', '_columns', 'type_scale'), 
('dependency_columns_on_keys', 'triggers', 'name'), 
('dependency_columns_on_keys', 'triggers', 'orientation'), 
('dependency_columns_on_keys', 'triggers', 'table_id'), 
('dependency_columns_on_keys', 'triggers', 'time'), 
('dependency_columns_on_triggers', 'keys', 'name'), 
('dependency_columns_on_triggers', 'keys', 'rkey'), 
('dependency_columns_on_triggers', 'keys', 'type'), 
('dependency_functions_on_triggers', 'keys', 'action'), 
('dependency_functions_on_triggers', 'keys', 'name'), 
('dependency_functions_on_triggers', 'keys', 'rkey'), 
('dependency_functions_on_triggers', 'keys', 'type'), 
('dependency_keys_on_foreignkeys', '_columns', 'default'), 
('dependency_keys_on_foreignkeys', '_columns', 'name'), 
('dependency_keys_on_foreignkeys', '_columns', 'table_id'), 
('dependency_keys_on_foreignkeys', '_columns', 'type'), 
('dependency_keys_on_fore
 ignkeys', '_columns', 'type_digits'), ('dependency_keys_on_foreignkeys', 
'_columns', 'type_scale'), ('dependency_tables_on_foreignkeys', '_columns', 
'default'), ('dependency_tables_on_foreignkeys', '_columns', 'name'), 
('dependency_tables_on_foreignkeys', '_columns', 'table_id'), 
('dependency_tables_on_foreignkeys', '_columns', 'type'), 
('dependency_tables_on_foreignkeys', '_columns', 'type_digits'), 
('dependency_tables_on_foreignkeys', '_columns', 'type_scale'), 
('dependency_tables_on_indexes', '_columns', 'name'), 
('dependency_tables_on_indexes', '_columns', 'number'), 
('dependency_tables_on_indexes', '_columns', 'storage'), 
('dependency_tables_on_indexes', '_columns', 'table_id'), 
('dependency_tables_on_indexes', '_columns', 'type_digits'), 
('dependency_tables_on_indexes', 'keys', 'id'), 
('dependency_tables_on_triggers', 'keys', 'action'), 
('dependency_tables_on_triggers', 'keys', 'name'), 
('dependency_tables_on_triggers', 'keys', 'rkey'), 
('dependency_tables_on_triggers', 'keys'
 , 'type')));\n"
+                               /* the "chain" upgrade check tests fail with a 
duplicate
+                                * entry in sys.dependencies, but running this 
query
+                                * results in NULL values in sys.dependencies 
in some of
+                                * the upgrade tests, so it is disabled */
+                               /*"create temporary table d as (select distinct 
* from sys.dependencies);\ndelete from sys.dependencies;\ninsert into 
sys.dependencies (select * from d);\n"*/;
+                       assert(BATcount(b) == 1);
+                       printf("Running database upgrade commands:\n%s\n", 
query);
+                       fflush(stdout);
+                       err = SQLstatementIntern(c, query, "update", true, 
false, NULL);
+               }
+               BBPunfix(b->batCacheid);
+       }
+       res_table_destroy(output);
+       return err;
+}
+
+static str
 sql_update_default(Client c, mvc *sql, sql_schema *s)
 {
        char *err;
@@ -7219,6 +7259,11 @@ SQLupgrades(Client c, mvc *m)
                goto handle_error;
        }
 
+       if ((err = sql_update_dec2023_sp4(c, m, s)) != NULL) {
+               TRC_CRITICAL(SQL_PARSER, "%s\n", err);
+               goto handle_error;
+       }
+
        if ((err = sql_update_default(c, m, s)) != NULL) {
                TRC_CRITICAL(SQL_PARSER, "%s\n", err);
                goto handle_error;
diff --git a/sql/scripts/52_describe.sql b/sql/scripts/52_describe.sql
--- a/sql/scripts/52_describe.sql
+++ b/sql/scripts/52_describe.sql
@@ -179,7 +179,6 @@ CREATE VIEW sys.describe_foreign_keys AS
                AND ((fkk."action" >> 8) & 255)  = ou.id
                ORDER BY fkk.name, fkkc.nr;
 
---TODO: CRASHES when this function gets inlined into describe_tables
 CREATE FUNCTION sys.get_merge_table_partition_expressions(tid INT) RETURNS 
STRING
 BEGIN
        RETURN
diff --git a/sql/server/rel_optimize_others.c b/sql/server/rel_optimize_others.c
--- a/sql/server/rel_optimize_others.c
+++ b/sql/server/rel_optimize_others.c
@@ -1054,6 +1054,7 @@ rel_dce_(mvc *sql, sql_rel *rel)
        return rel;
 }
 
+
 /* Remove unused expressions */
 static sql_rel *
 rel_dce(visitor *v, global_props *gp, sql_rel *rel)
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -607,8 +607,8 @@ run_optimizer_set(visitor *v, sql_optimi
 
 /* 'profile' means to benchmark each individual optimizer run */
 /* 'instantiate' means to rewrite logical tables: (merge, remote, replica 
tables) */
-sql_rel *
-rel_optimizer(mvc *sql, sql_rel *rel, int profile, int instantiate, int 
value_based_opt, int storage_based_opt)
+static sql_rel *
+rel_optimizer_one(mvc *sql, sql_rel *rel, int profile, int instantiate, int 
value_based_opt, int storage_based_opt)
 {
        global_props gp = (global_props) {.cnt = {0}, .instantiate = 
(uint8_t)instantiate, .opt_cycle = 0,
                                                                          
.has_special_modify = rel && is_modify(rel->op) && rel->flag&UPD_COMP};
@@ -635,3 +635,32 @@ rel_optimizer(mvc *sql, sql_rel *rel, in
        rel = run_optimizer_set(&v, sql->runs, rel, &gp, post_sql_optimizers);
        return rel;
 }
+
+static sql_exp *
+exp_optimize_one(visitor *v, sql_rel *rel, sql_exp *e, int depth )
+{
+       (void)rel;
+       (void)depth;
+       if (e->type == e_psm && e->flag == PSM_REL && e->l) {
+               e->l = rel_optimizer_one(v->sql, e->l, 0, v->changes, 
v->value_based_opt, v->storage_based_opt);
+       }
+       return e;
+}
+
+sql_rel *
+rel_optimizer(mvc *sql, sql_rel *rel, int profile, int instantiate, int 
value_based_opt, int storage_based_opt)
+{
+       if (rel && rel->op == op_ddl && rel->flag == ddl_psm) {
+               if (!list_empty(rel->exps)) {
+                       bool changed = 0;
+                       visitor v = { .sql = sql, .value_based_opt = 
value_based_opt, .storage_based_opt = storage_based_opt, .changes = instantiate 
};
+                       for(node *n = rel->exps->h; n; n = n->next) {
+                               sql_exp *e = n->data;
+                               exp_visitor(&v, rel, e, 1, exp_optimize_one, 
true, true, true, &changed);
+                       }
+               }
+               return rel;
+       } else {
+               return rel_optimizer_one(sql, rel, profile, instantiate, 
value_based_opt, storage_based_opt);
+       }
+}
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
@@ -2048,17 +2048,17 @@ rel_dependencies(mvc *sql, sql_rel *r)
        return l;
 }
 
-static list *exps_exp_visitor(visitor *v, sql_rel *rel, list *exps, int depth, 
exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown);
+static list *exps_exp_visitor(visitor *v, sql_rel *rel, list *exps, int depth, 
exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown, bool 
visit_relations_once);
 
 static inline list *
-exps_exps_exp_visitor(visitor *v, sql_rel *rel, list *lists, int depth, 
exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown)
+exps_exps_exp_visitor(visitor *v, sql_rel *rel, list *lists, int depth, 
exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown, bool 
visit_relations_once)
 {
        node *n;
 
        if (list_empty(lists))
                return lists;
        for (n = lists->h; n; n = n->next) {
-               if (n->data && (n->data = exps_exp_visitor(v, rel, n->data, 
depth, exp_rewriter, topdown, relations_topdown)) == NULL)
+               if (n->data && (n->data = exps_exp_visitor(v, rel, n->data, 
depth, exp_rewriter, topdown, relations_topdown, visit_relations_once)) == NULL)
                        return NULL;
        }
        return lists;
@@ -2066,8 +2066,8 @@ exps_exps_exp_visitor(visitor *v, sql_re
 
 static sql_rel *rel_exp_visitor(visitor *v, sql_rel *rel, exp_rewrite_fptr 
exp_rewriter, bool topdown, bool relations_topdown);
 
-static sql_exp *
-exp_visitor(visitor *v, sql_rel *rel, sql_exp *e, int depth, exp_rewrite_fptr 
exp_rewriter, bool topdown, bool relations_topdown, bool *changed)
+sql_exp *
+exp_visitor(visitor *v, sql_rel *rel, sql_exp *e, int depth, exp_rewrite_fptr 
exp_rewriter, bool topdown, bool relations_topdown, bool visit_relations_once, 
bool *changed)
 {
        if (mvc_highwater(v->sql))
                return sql_error(v->sql, 10, SQLSTATE(42000) "Query too 
complex: running out of stack space");
@@ -2084,59 +2084,59 @@ exp_visitor(visitor *v, sql_rel *rel, sq
        case e_column:
                break;
        case e_convert:
-               if  ((e->l = exp_visitor(v, rel, e->l, depth+1, exp_rewriter, 
topdown, relations_topdown, changed)) == NULL)
+               if  ((e->l = exp_visitor(v, rel, e->l, depth+1, exp_rewriter, 
topdown, relations_topdown, visit_relations_once, changed)) == NULL)
                        return NULL;
                break;
        case e_aggr:
        case e_func:
                if (e->r) /* rewrite rank -r is list of lists */
-                       if ((e->r = exps_exps_exp_visitor(v, rel, e->r, 
depth+1, exp_rewriter, topdown, relations_topdown)) == NULL)
+                       if ((e->r = exps_exps_exp_visitor(v, rel, e->r, 
depth+1, exp_rewriter, topdown, relations_topdown, visit_relations_once)) == 
NULL)
                                return NULL;
                if (e->l)
-                       if ((e->l = exps_exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown)) == NULL)
+                       if ((e->l = exps_exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once)) == NULL)
                                return NULL;
                break;
        case e_cmp:
                if (e->flag == cmp_or || e->flag == cmp_filter) {
-                       if ((e->l = exps_exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown)) == NULL)
+                       if ((e->l = exps_exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once)) == NULL)
                                return NULL;
-                       if ((e->r = exps_exp_visitor(v, rel, e->r, depth+1, 
exp_rewriter, topdown, relations_topdown)) == NULL)
+                       if ((e->r = exps_exp_visitor(v, rel, e->r, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once)) == NULL)
                                return NULL;
                } else if (e->flag == cmp_in || e->flag == cmp_notin) {
-                       if ((e->l = exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown, changed)) == NULL)
+                       if ((e->l = exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once, changed)) == 
NULL)
                                return NULL;
-                       if ((e->r = exps_exp_visitor(v, rel, e->r, depth+1, 
exp_rewriter, topdown, relations_topdown)) == NULL)
+                       if ((e->r = exps_exp_visitor(v, rel, e->r, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once)) == NULL)
                                return NULL;
                } else {
-                       if ((e->l = exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown, changed)) == NULL)
+                       if ((e->l = exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once, changed)) == 
NULL)
                                return NULL;
-                       if ((e->r = exp_visitor(v, rel, e->r, depth+1, 
exp_rewriter, topdown, relations_topdown, changed)) == NULL)
+                       if ((e->r = exp_visitor(v, rel, e->r, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once, changed)) == 
NULL)
                                return NULL;
-                       if (e->f && (e->f = exp_visitor(v, rel, e->f, depth+1, 
exp_rewriter, topdown, relations_topdown, changed)) == NULL)
+                       if (e->f && (e->f = exp_visitor(v, rel, e->f, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once, changed)) == 
NULL)
                                return NULL;
                }
                break;
        case e_psm:
                if (e->flag & PSM_SET || e->flag & PSM_RETURN || e->flag & 
PSM_EXCEPTION) {
-                       if ((e->l = exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown, changed)) == NULL)
+                       if ((e->l = exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once, changed)) == 
NULL)
                                return NULL;
                } else if (e->flag & PSM_VAR) {
                        return e;
                } else if (e->flag & PSM_WHILE || e->flag & PSM_IF) {
-                       if ((e->l = exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown, changed)) == NULL)
+                       if ((e->l = exp_visitor(v, rel, e->l, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once, changed)) == 
NULL)
                                return NULL;
-                       if ((e->r = exps_exp_visitor(v, rel, e->r, depth+1, 
exp_rewriter, topdown, relations_topdown)) == NULL)
+                       if ((e->r = exps_exp_visitor(v, rel, e->r, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once)) == NULL)
                                return NULL;
-                       if (e->flag == PSM_IF && e->f && (e->f = 
exps_exp_visitor(v, rel, e->f, depth+1, exp_rewriter, topdown, 
relations_topdown)) == NULL)
+                       if (e->flag == PSM_IF && e->f && (e->f = 
exps_exp_visitor(v, rel, e->f, depth+1, exp_rewriter, topdown, 
relations_topdown, visit_relations_once)) == NULL)
                                return NULL;
                } else if (e->flag & PSM_REL) {
-                       if ((e->l = rel_exp_visitor(v, e->l, exp_rewriter, 
topdown, relations_topdown)) == NULL)
+                       if (!visit_relations_once && (e->l = rel_exp_visitor(v, 
e->l, exp_rewriter, topdown, relations_topdown)) == NULL)
                                return NULL;
                }
                break;
        case e_atom:
                if (e->f)
-                       if ((e->f = exps_exp_visitor(v, rel, e->f, depth+1, 
exp_rewriter, topdown, relations_topdown)) == NULL)
+                       if ((e->f = exps_exp_visitor(v, rel, e->f, depth+1, 
exp_rewriter, topdown, relations_topdown, visit_relations_once)) == NULL)
                                return NULL;
                break;
        }
@@ -2150,13 +2150,13 @@ exp_visitor(visitor *v, sql_rel *rel, sq
 }
 
 static list *
-exps_exp_visitor(visitor *v, sql_rel *rel, list *exps, int depth, 
exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown)
+exps_exp_visitor(visitor *v, sql_rel *rel, list *exps, int depth, 
exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown, bool 
visit_relations_once)
 {
        bool changed = false;
        if (list_empty(exps))
                return exps;
        for (node *n = exps->h; n; n = n->next)
-               if (n->data && (n->data = exp_visitor(v, rel, n->data, depth, 
exp_rewriter, topdown, relations_topdown, &changed)) == NULL)
+               if (n->data && (n->data = exp_visitor(v, rel, n->data, depth, 
exp_rewriter, topdown, relations_topdown, visit_relations_once, &changed)) == 
NULL)
                        return NULL;
        if (changed && depth == 0) /* only level 0 exps use hash, so remove 
only on those */
                list_hash_clear(exps);
@@ -2173,9 +2173,9 @@ rel_exp_visitor(visitor *v, sql_rel *rel
                return rel;
 
        if (relations_topdown) {
-               if (rel->exps && (rel->exps = exps_exp_visitor(v, rel, 
rel->exps, 0, exp_rewriter, topdown, relations_topdown)) == NULL)
+               if (rel->exps && (rel->exps = exps_exp_visitor(v, rel, 
rel->exps, 0, exp_rewriter, topdown, relations_topdown, false)) == NULL)
                        return NULL;
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to