Changeset: b75308bf7ec7 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/b75308bf7ec7 Added Files: sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.py sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.stable.err sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.stable.out Modified Files: sql/server/rel_dump.c sql/server/rel_rel.c sql/test/BugTracker-2021/Tests/All Branch: Oct2020 Log Message:
Added test and fix for bug #7110 Fixed binding order for grouping expressions. First projections within the grouping projection list, then group by columns, then the left relation's projections. At rel_bind_column, allow grouping columns references to be returned. diffs (174 lines): 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 @@ -1834,9 +1834,11 @@ rel_read(mvc *sql, char *r, int *pos, li return NULL; rel = rel_project(sql->sa, nrel, exps); /* order by ? */ - if (r[*pos] == '[') - if (!(rel->r = read_exps(sql, nrel, rel, NULL, r, pos, '[', 0, 1))) + if (r[*pos] == '[') { + /* first projected expressions, then left relation projections */ + if (!(rel->r = read_exps(sql, rel, nrel, NULL, r, pos, '[', 0, 1))) return NULL; + } break; case 'g': *pos += (int) strlen("group by"); @@ -1857,11 +1859,14 @@ rel_read(mvc *sql, char *r, int *pos, li if (!(gexps = read_exps(sql, nrel, NULL, NULL, r, pos, '[', 0, 1))) return NULL; skipWS(r, pos); - if (!(exps = read_exps(sql, nrel, NULL, gexps, r, pos, '[', 1, 1))) + rel = rel_groupby(sql, nrel, gexps); + rel->exps = new_exp_list(sql->sa); /* empty projection list for now */ + set_processed(rel); /* don't search beyond the group by */ + /* first group projected expressions, then group by columns, then left relation projections */ + if (!(exps = read_exps(sql, rel, nrel, NULL, r, pos, '[', 1, 1))) return NULL; - - rel = rel_groupby(sql, nrel, gexps); rel->exps = exps; + rel->nrcols = list_length(exps); break; case 's': case 'a': 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 @@ -317,7 +317,7 @@ rel_bind_column( mvc *sql, sql_rel *rel, if (e) e = exp_alias_or_copy(sql, exp_relname(e), cname, rel, e); if (!e && is_groupby(rel->op) && rel->r) { - sql_exp *e = exps_bind_column(rel->r, cname, NULL, NULL, no_tname); + e = exps_bind_column(rel->r, cname, NULL, NULL, no_tname); if (e) e = exp_alias_or_copy(sql, exp_relname(e), cname, rel, e); } diff --git a/sql/test/BugTracker-2021/Tests/All b/sql/test/BugTracker-2021/Tests/All --- a/sql/test/BugTracker-2021/Tests/All +++ b/sql/test/BugTracker-2021/Tests/All @@ -3,3 +3,4 @@ HAVE_PYMONETDB?remote-table-ranges.Bug-7 KNOWNFAIL?query-too-complex.Bug-7092 ntile-wrong-result.Bug-7104 merge-stmt.wrong-error.Bug-7109 +remote-table-groupby.Bug-7110 diff --git a/sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.py b/sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.py new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.py @@ -0,0 +1,56 @@ +import os, socket, sys, tempfile, pymonetdb + +try: + from MonetDBtesting import process +except ImportError: + import process + + +# Find a free network port +def freeport(): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.bind(('', 0)) + port = sock.getsockname()[1] + sock.close() + return port + + +with tempfile.TemporaryDirectory() as farm_dir: + os.mkdir(os.path.join(farm_dir, 'node1')) + os.mkdir(os.path.join(farm_dir, 'node2')) + + node1_port = freeport() + with process.server(mapiport=node1_port, dbname='node1', + dbfarm=os.path.join(farm_dir, 'node1'), + stdin=process.PIPE, stdout=process.PIPE, + stderr=process.PIPE) as node1_proc: + node1_conn = pymonetdb.connect(database='node1', port=node1_port, autocommit=True) + node1_cur = node1_conn.cursor() + + node1_cur.execute("CREATE TABLE keyword_test (toc_no String null,myname String null)") + node1_cur.execute("insert into keyword_test values('A000000009', 'AAAA'),('A000000010', 'BBBB'),('A000000011', 'CCCC'),('A000000012', 'DDDD'),('A000000013', 'EEEE'),('A000000014', 'AAAA'),('A000000015', 'DDDD'),('A000000016', 'AAAA')") + node1_cur.execute("select * from keyword_test order by myname") + print(node1_cur.fetchall()) + node1_cur.execute("select '*' as category, count(*) as cnt from keyword_test group by category") + print(node1_cur.fetchall()) + + node2_port = freeport() + with process.server(mapiport=node2_port, dbname='node2', + dbfarm=os.path.join(farm_dir, 'node2'), + stdin=process.PIPE, stdout=process.PIPE, + stderr=process.PIPE) as node2_proc: + node2_conn = pymonetdb.connect(database='node2', port=node2_port, autocommit=True) + node2_cur = node2_conn.cursor() + + node2_cur.execute("CREATE REMOTE TABLE keyword_test (toc_no String null,myname String null) on 'mapi:monetdb://localhost:{}/node1/sys/keyword_test'".format(node1_port)) + node2_cur.execute("select * from keyword_test order by myname") + print(node2_cur.fetchall()) + node2_cur.execute("select '*' as category, count(*) as cnt from keyword_test group by category") + print(node2_cur.fetchall()) + + # cleanup: shutdown the monetdb servers and remove tempdir + out, err = node1_proc.communicate() + sys.stderr.write(err) + + out, err = node2_proc.communicate() + sys.stderr.write(err) diff --git a/sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.stable.err b/sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.stable.err new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.stable.err @@ -0,0 +1,32 @@ +stderr of test 'remote-table-groupby.Bug-7110` in directory 'sql/test/BugTracker-2021` itself: + + +# 10:13:57 > +# 10:13:57 > "/usr/bin/python3.9" "remote-table-groupby.Bug-7110.py" "remote-table-groupby.Bug-7110" +# 10:13:57 > + +# builtin opt gdk_dbpath = /home/ferreira/repositories/MonetDB-Oct2020/BUILD/var/monetdb5/dbfarm/demo +# builtin opt mapi_port = 50000 +# builtin opt sql_optimizer = default_pipe +# builtin opt sql_debug = 0 +# builtin opt raw_strings = false +# cmdline opt gdk_nr_threads = 0 +# cmdline opt mapi_listenaddr = all +# cmdline opt mapi_port = 33703 +# cmdline opt mapi_usock = /var/tmp/mtest-86937/.s.monetdb.33703 +# cmdline opt gdk_dbpath = /tmp/tmpf489g9j5/node1/node1 +# builtin opt gdk_dbpath = /home/ferreira/repositories/MonetDB-Oct2020/BUILD/var/monetdb5/dbfarm/demo +# builtin opt mapi_port = 50000 +# builtin opt sql_optimizer = default_pipe +# builtin opt sql_debug = 0 +# builtin opt raw_strings = false +# cmdline opt gdk_nr_threads = 0 +# cmdline opt mapi_listenaddr = all +# cmdline opt mapi_port = 44007 +# cmdline opt mapi_usock = /var/tmp/mtest-86937/.s.monetdb.44007 +# cmdline opt gdk_dbpath = /tmp/tmpf489g9j5/node2/node2 + +# 10:13:59 > +# 10:13:59 > "Done." +# 10:13:59 > + diff --git a/sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.stable.out b/sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.stable.out new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2021/Tests/remote-table-groupby.Bug-7110.stable.out @@ -0,0 +1,16 @@ +stdout of test 'remote-table-groupby.Bug-7110` in directory 'sql/test/BugTracker-2021` itself: + + +# 10:13:57 > +# 10:13:57 > "/usr/bin/python3.9" "remote-table-groupby.Bug-7110.py" "remote-table-groupby.Bug-7110" +# 10:13:57 > + +[('A000000009', 'AAAA'), ('A000000014', 'AAAA'), ('A000000016', 'AAAA'), ('A000000010', 'BBBB'), ('A000000011', 'CCCC'), ('A000000012', 'DDDD'), ('A000000015', 'DDDD'), ('A000000013', 'EEEE')] +[('*', 8)] +[('A000000009', 'AAAA'), ('A000000014', 'AAAA'), ('A000000016', 'AAAA'), ('A000000010', 'BBBB'), ('A000000011', 'CCCC'), ('A000000012', 'DDDD'), ('A000000015', 'DDDD'), ('A000000013', 'EEEE')] +[('*', 8)] + +# 10:13:59 > +# 10:13:59 > "Done." +# 10:13:59 > + _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list