diff --git a/src/backend/columnar/columnar_customscan.c b/src/backend/columnar/columnar_customscan.c index 3efcf4588..101f0223f 100644 --- a/src/backend/columnar/columnar_customscan.c +++ b/src/backend/columnar/columnar_customscan.c @@ -1100,6 +1100,29 @@ ParameterizationAsString(PlannerInfo *root, Relids paramRelids, StringInfo buf) } +/* + * ContainsExecParams tests whether the node contains any exec params. The + * signature accepts an extra argument for use with expression_tree_walker. + */ +static bool +ContainsExecParams(Node *node, void *notUsed) +{ + if (node == NULL) + { + return false; + } + else if (IsA(node, Param)) + { + Param *param = castNode(Param, node); + if (param->paramkind == PARAM_EXEC) + { + return true; + } + } + return expression_tree_walker(node, ContainsExecParams, NULL); +} + + /* * Create and add a path with the given parameterization paramRelids. * @@ -1133,11 +1156,8 @@ AddColumnarScanPath(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte, path->param_info = get_baserel_parampathinfo(root, rel, paramRelids); /* - * Now, baserestrictinfo contains the clauses referencing only this rel, - * and ppi_clauses (if present) represents the join clauses that reference - * this rel and rels contained in paramRelids (after accounting for - * ECs). Combine the two lists of clauses, extracting the actual clause - * from the rinfo, and filtering out pseudoconstants and SAOPs. + * Usable clauses for this parameterization exist in baserestrictinfo and + * ppi_clauses. */ List *allClauses = copyObject(rel->baserestrictinfo); if (path->param_info != NULL) @@ -1145,20 +1165,47 @@ AddColumnarScanPath(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte, allClauses = list_concat(allClauses, path->param_info->ppi_clauses); } - /* - * This is the set of clauses that can be pushed down for this - * parameterization (with the given paramRelids), and will be used to - * construct the CustomScan plan. - */ - List *pushdownClauses = FilterPushdownClauses(root, rel, allClauses); + allClauses = FilterPushdownClauses(root, rel, allClauses); + /* + * Plain clauses may contain extern params, but not exec params, and can + * be evaluated at init time or rescan time. Track them in another list + * that is a subset of allClauses. + * + * Note: although typically baserestrictinfo contains plain clauses, + * that's not always true. It can also contain a qual referencing a Var at + * a higher query level, which can be turned into an exec param, and + * therefore it won't be a plain clause. + */ + List *plainClauses = NIL; + ListCell *lc; + foreach(lc, allClauses) + { + RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc); + if (bms_is_subset(rinfo->required_relids, rel->relids) && + !ContainsExecParams((Node *) rinfo->clause, NULL)) + { + plainClauses = lappend(plainClauses, rinfo); + } + } + + /* + * We can't make our own CustomPath structure, so we need to put + * everything in the custom_private list. To keep the two lists separate, + * we make them sublists in a 2-element list. + */ if (EnableColumnarQualPushdown) { - cpath->custom_private = pushdownClauses; + cpath->custom_private = list_make2(copyObject(plainClauses), + copyObject(allClauses)); + } + else + { + cpath->custom_private = list_make2(NIL, NIL); } int numberOfColumnsRead = bms_num_members(rte->selectedCols); - int numberOfClausesPushed = list_length(cpath->custom_private); + int numberOfClausesPushed = list_length(allClauses); CostColumnarScan(root, rel, rte->relid, cpath, numberOfColumnsRead, numberOfClausesPushed); @@ -1188,8 +1235,9 @@ CostColumnarScan(PlannerInfo *root, RelOptInfo *rel, Oid relationId, { Path *path = &cpath->path; + List *allClauses = lsecond(cpath->custom_private); Selectivity clauseSel = clauselist_selectivity( - root, cpath->custom_private, rel->relid, JOIN_INNER, NULL); + root, allClauses, rel->relid, JOIN_INNER, NULL); /* * We already filtered out clauses where the overall selectivity would be @@ -1297,18 +1345,28 @@ ColumnarScanPath_PlanCustomPath(PlannerInfo *root, if (EnableColumnarQualPushdown) { /* - * List of pushed-down clauses. The Vars referencing other relations - * will be changed into exec Params by create_customscan_plan(). + * Lists of pushed-down clauses. The Vars in custom_exprs referencing + * other relations will be changed into exec Params by + * create_customscan_plan(). * - * XXX: this just means what will be pushed into the columnar reader - * code; some of these may not be usable. We should fix this by - * passing down something more like ScanKeys, where we've already - * verified that the operators match the btree opclass of the chunk - * predicates. + * Like CustomPath->custom_private, keep a list of plain clauses + * separate from the list of all clauses by making them sublists of a + * 2-element list. + * + * XXX: custom_exprs are the quals that will be pushed into the + * columnar reader code; some of these may not be usable. We should + * fix this by processing the quals more completely and using + * ScanKeys. */ - cscan->custom_exprs = copyObject( - extract_actual_clauses(best_path->custom_private, - false /* no pseudoconstants */)); + List *plainClauses = extract_actual_clauses( + linitial(best_path->custom_private), false /* no pseudoconstants */); + List *allClauses = extract_actual_clauses( + lsecond(best_path->custom_private), false /* no pseudoconstants */); + cscan->custom_exprs = copyObject(list_make2(plainClauses, allClauses)); + } + else + { + cscan->custom_exprs = list_make2(NIL, NIL); } cscan->scan.plan.qual = extract_actual_clauses( @@ -1447,10 +1505,10 @@ ColumnarScan_BeginCustomScan(CustomScanState *cscanstate, EState *estate, int ef columnarScanState->css_RuntimeContext = cscanstate->ss.ps.ps_ExprContext; cscanstate->ss.ps.ps_ExprContext = stdecontext; - /* XXX: separate into runtime clauses and normal clauses */ ResetExprContext(columnarScanState->css_RuntimeContext); + List *plainClauses = linitial(cscan->custom_exprs); columnarScanState->qual = (List *) EvalParamsMutator( - (Node *) cscan->custom_exprs, columnarScanState->css_RuntimeContext); + (Node *) plainClauses, columnarScanState->css_RuntimeContext); /* scan slot is already initialized */ } @@ -1604,8 +1662,9 @@ ColumnarScan_ReScanCustomScan(CustomScanState *node) ColumnarScanState *columnarScanState = (ColumnarScanState *) node; ResetExprContext(columnarScanState->css_RuntimeContext); + List *allClauses = lsecond(cscan->custom_exprs); columnarScanState->qual = (List *) EvalParamsMutator( - (Node *) cscan->custom_exprs, columnarScanState->css_RuntimeContext); + (Node *) allClauses, columnarScanState->css_RuntimeContext); TableScanDesc scanDesc = node->ss.ss_currentScanDesc; @@ -1635,7 +1694,7 @@ ColumnarScan_ExplainCustomScan(CustomScanState *node, List *ancestors, projectedColumnsStr, es); CustomScan *cscan = castNode(CustomScan, node->ss.ps.plan); - List *chunkGroupFilter = cscan->custom_exprs; + List *chunkGroupFilter = lsecond(cscan->custom_exprs); if (chunkGroupFilter != NULL) { const char *pushdownClausesStr = ColumnarPushdownClausesStr( diff --git a/src/test/regress/expected/columnar_chunk_filtering.out b/src/test/regress/expected/columnar_chunk_filtering.out index 3f110a64b..90c201ae9 100644 --- a/src/test/regress/expected/columnar_chunk_filtering.out +++ b/src/test/regress/expected/columnar_chunk_filtering.out @@ -746,3 +746,76 @@ select filtered_row_count('execute foo(3)'); (1 row) drop table columnar_prepared_stmt; +-- +-- https://github.com/citusdata/citus/issues/5258 +-- +set default_table_access_method to columnar; +CREATE TABLE atest1 ( a int, b text ); +CREATE TABLE atest2 (col1 varchar(10), col2 boolean); +INSERT INTO atest1 VALUES (1, 'one'); +SELECT * FROM atest1; -- ok + a | b +--------------------------------------------------------------------- + 1 | one +(1 row) + +SELECT * FROM atest2; -- ok + col1 | col2 +--------------------------------------------------------------------- +(0 rows) + +INSERT INTO atest1 VALUES (2, 'two'); -- ok +INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok +SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) ); + col1 | col2 +--------------------------------------------------------------------- +(0 rows) + +CREATE TABLE t1 (name TEXT, n INTEGER); +CREATE TABLE t2 (name TEXT, n INTEGER); +CREATE TABLE t3 (name TEXT, n INTEGER); +INSERT INTO t1 VALUES ( 'bb', 11 ); +INSERT INTO t2 VALUES ( 'bb', 12 ); +INSERT INTO t2 VALUES ( 'cc', 22 ); +INSERT INTO t2 VALUES ( 'ee', 42 ); +INSERT INTO t3 VALUES ( 'bb', 13 ); +INSERT INTO t3 VALUES ( 'cc', 23 ); +INSERT INTO t3 VALUES ( 'dd', 33 ); +SELECT * FROM +(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 +NATURAL INNER JOIN +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL INNER JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 +--------------------------------------------------------------------- + bb | 11 | 1 | 12 | 2 | 13 | 3 +(1 row) + +CREATE TABLE numrange_test (nr NUMRANGE); +INSERT INTO numrange_test VALUES('[,)'); +INSERT INTO numrange_test VALUES('[3,]'); +INSERT INTO numrange_test VALUES('[, 5)'); +INSERT INTO numrange_test VALUES(numrange(1.1, 2.2)); +INSERT INTO numrange_test VALUES('empty'); +INSERT INTO numrange_test VALUES(numrange(1.7, 1.7, '[]')); +create table numrange_test2(nr numrange); +INSERT INTO numrange_test2 VALUES('[, 5)'); +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2,'()')); +INSERT INTO numrange_test2 VALUES('empty'); +set enable_nestloop=t; +set enable_hashjoin=f; +set enable_mergejoin=f; +select * from numrange_test natural join numrange_test2 order by nr; + nr +--------------------------------------------------------------------- + empty + (,5) + [1.1,2.2) + [1.1,2.2) +(4 rows) + +DROP TABLE atest1, atest2, t1, t2, t3, numrange_test, numrange_test2; +set default_table_access_method to default; diff --git a/src/test/regress/expected/columnar_chunk_filtering_0.out b/src/test/regress/expected/columnar_chunk_filtering_0.out index 18e32a0cc..fe507bc6c 100644 --- a/src/test/regress/expected/columnar_chunk_filtering_0.out +++ b/src/test/regress/expected/columnar_chunk_filtering_0.out @@ -746,3 +746,76 @@ select filtered_row_count('execute foo(3)'); (1 row) drop table columnar_prepared_stmt; +-- +-- https://github.com/citusdata/citus/issues/5258 +-- +set default_table_access_method to columnar; +CREATE TABLE atest1 ( a int, b text ); +CREATE TABLE atest2 (col1 varchar(10), col2 boolean); +INSERT INTO atest1 VALUES (1, 'one'); +SELECT * FROM atest1; -- ok + a | b +--------------------------------------------------------------------- + 1 | one +(1 row) + +SELECT * FROM atest2; -- ok + col1 | col2 +--------------------------------------------------------------------- +(0 rows) + +INSERT INTO atest1 VALUES (2, 'two'); -- ok +INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok +SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) ); + col1 | col2 +--------------------------------------------------------------------- +(0 rows) + +CREATE TABLE t1 (name TEXT, n INTEGER); +CREATE TABLE t2 (name TEXT, n INTEGER); +CREATE TABLE t3 (name TEXT, n INTEGER); +INSERT INTO t1 VALUES ( 'bb', 11 ); +INSERT INTO t2 VALUES ( 'bb', 12 ); +INSERT INTO t2 VALUES ( 'cc', 22 ); +INSERT INTO t2 VALUES ( 'ee', 42 ); +INSERT INTO t3 VALUES ( 'bb', 13 ); +INSERT INTO t3 VALUES ( 'cc', 23 ); +INSERT INTO t3 VALUES ( 'dd', 33 ); +SELECT * FROM +(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 +NATURAL INNER JOIN +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL INNER JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 +--------------------------------------------------------------------- + bb | 11 | 1 | 12 | 2 | 13 | 3 +(1 row) + +CREATE TABLE numrange_test (nr NUMRANGE); +INSERT INTO numrange_test VALUES('[,)'); +INSERT INTO numrange_test VALUES('[3,]'); +INSERT INTO numrange_test VALUES('[, 5)'); +INSERT INTO numrange_test VALUES(numrange(1.1, 2.2)); +INSERT INTO numrange_test VALUES('empty'); +INSERT INTO numrange_test VALUES(numrange(1.7, 1.7, '[]')); +create table numrange_test2(nr numrange); +INSERT INTO numrange_test2 VALUES('[, 5)'); +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2,'()')); +INSERT INTO numrange_test2 VALUES('empty'); +set enable_nestloop=t; +set enable_hashjoin=f; +set enable_mergejoin=f; +select * from numrange_test natural join numrange_test2 order by nr; + nr +--------------------------------------------------------------------- + empty + (,5) + [1.1,2.2) + [1.1,2.2) +(4 rows) + +DROP TABLE atest1, atest2, t1, t2, t3, numrange_test, numrange_test2; +set default_table_access_method to default; diff --git a/src/test/regress/expected/columnar_query.out b/src/test/regress/expected/columnar_query.out index 0934e332e..03593f3d5 100644 --- a/src/test/regress/expected/columnar_query.out +++ b/src/test/regress/expected/columnar_query.out @@ -187,3 +187,52 @@ UNION SET client_min_messages TO WARNING; DROP SCHEMA columnar_join CASCADE; +-- +-- https://github.com/citusdata/citus/issues/5258 +-- +set default_table_access_method to columnar; +CREATE TABLE atest1 ( a int, b text ); +CREATE TABLE atest2 (col1 varchar(10), col2 boolean); +INSERT INTO atest1 VALUES (1, 'one'); +SELECT * FROM atest1; -- ok + a | b +--------------------------------------------------------------------- + 1 | one +(1 row) + +SELECT * FROM atest2; -- ok + col1 | col2 +--------------------------------------------------------------------- +(0 rows) + +INSERT INTO atest1 VALUES (2, 'two'); -- ok +INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok +SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) ); + col1 | col2 +--------------------------------------------------------------------- +(0 rows) + +DROP TABLE atest1; +DROP TABLE atest2; +set default_table_access_method to default; +create temp table t1 (f1 numeric(14,0), f2 varchar(30)) USING columnar; +select * from + (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs + from t1 up) ss +group by f1,f2,fs; + f1 | f2 | fs +--------------------------------------------------------------------- +(0 rows) + +drop table t1; +CREATE TABLE tbl1(c0 int4range) USING COLUMNAR; +CREATE TABLE tbl2(c0 int4range); +INSERT INTO tbl1(c0) VALUES('[0,1]'::int4range); +INSERT INTO tbl1(c0) VALUES('[0,1]'::int4range); +SELECT tbl1.c0 FROM tbl1 JOIN tbl2 ON tbl1.c0=tbl2.c0 WHERE tbl2.c0<=tbl2.c0 ISNULL; + c0 +--------------------------------------------------------------------- +(0 rows) + +DROP TABLE tbl1; +DROP TABLE tbl2; diff --git a/src/test/regress/expected/pg14.out b/src/test/regress/expected/pg14.out index 911e78bdf..9a6c40b3a 100644 --- a/src/test/regress/expected/pg14.out +++ b/src/test/regress/expected/pg14.out @@ -713,5 +713,58 @@ SELECT * FROM ( SELECT * FROM search_graph ORDER BY seq ) as foo; ERROR: recursive CTEs are not supported in distributed queries +-- +-- https://github.com/citusdata/citus/issues/5258 +-- +CREATE TABLE nummultirange_test (nmr NUMMULTIRANGE) USING columnar; +INSERT INTO nummultirange_test VALUES('{}'); +INSERT INTO nummultirange_test VALUES('{[,)}'); +INSERT INTO nummultirange_test VALUES('{[3,]}'); +INSERT INTO nummultirange_test VALUES('{[, 5)}'); +INSERT INTO nummultirange_test VALUES(nummultirange()); +INSERT INTO nummultirange_test VALUES(nummultirange(variadic '{}'::numrange[])); +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.1, 2.2))); +INSERT INTO nummultirange_test VALUES('{empty}'); +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.7, 1.9))); +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.9, 2.1))); +create table nummultirange_test2(nmr nummultirange) USING columnar; +INSERT INTO nummultirange_test2 VALUES('{[, 5)}'); +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))); +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))); +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2,'()'))); +INSERT INTO nummultirange_test2 VALUES('{}'); +select * from nummultirange_test2 where nmr = '{}'; + nmr +--------------------------------------------------------------------- + {} +(1 row) + +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.2)); + nmr +--------------------------------------------------------------------- + {[1.1,2.2)} + {[1.1,2.2)} +(2 rows) + +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.3)); + nmr +--------------------------------------------------------------------- +(0 rows) + +set enable_nestloop=t; +set enable_hashjoin=f; +set enable_mergejoin=f; +select * from nummultirange_test natural join nummultirange_test2 order by nmr; + nmr +--------------------------------------------------------------------- + {} + {} + {} + {} + {(,5)} + {[1.1,2.2)} + {[1.1,2.2)} +(7 rows) + set client_min_messages to error; drop schema pg14 cascade; diff --git a/src/test/regress/sql/columnar_chunk_filtering.sql b/src/test/regress/sql/columnar_chunk_filtering.sql index 3c3ed03b9..aea13839d 100644 --- a/src/test/regress/sql/columnar_chunk_filtering.sql +++ b/src/test/regress/sql/columnar_chunk_filtering.sql @@ -316,3 +316,61 @@ select filtered_row_count('execute foo(3)'); select filtered_row_count('execute foo(3)'); select filtered_row_count('execute foo(3)'); drop table columnar_prepared_stmt; + +-- +-- https://github.com/citusdata/citus/issues/5258 +-- +set default_table_access_method to columnar; +CREATE TABLE atest1 ( a int, b text ); +CREATE TABLE atest2 (col1 varchar(10), col2 boolean); + +INSERT INTO atest1 VALUES (1, 'one'); +SELECT * FROM atest1; -- ok +SELECT * FROM atest2; -- ok +INSERT INTO atest1 VALUES (2, 'two'); -- ok +INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok + +SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) ); + +CREATE TABLE t1 (name TEXT, n INTEGER); +CREATE TABLE t2 (name TEXT, n INTEGER); +CREATE TABLE t3 (name TEXT, n INTEGER); + +INSERT INTO t1 VALUES ( 'bb', 11 ); +INSERT INTO t2 VALUES ( 'bb', 12 ); +INSERT INTO t2 VALUES ( 'cc', 22 ); +INSERT INTO t2 VALUES ( 'ee', 42 ); +INSERT INTO t3 VALUES ( 'bb', 13 ); +INSERT INTO t3 VALUES ( 'cc', 23 ); +INSERT INTO t3 VALUES ( 'dd', 33 ); + +SELECT * FROM +(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 +NATURAL INNER JOIN +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL INNER JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + +CREATE TABLE numrange_test (nr NUMRANGE); +INSERT INTO numrange_test VALUES('[,)'); +INSERT INTO numrange_test VALUES('[3,]'); +INSERT INTO numrange_test VALUES('[, 5)'); +INSERT INTO numrange_test VALUES(numrange(1.1, 2.2)); +INSERT INTO numrange_test VALUES('empty'); +INSERT INTO numrange_test VALUES(numrange(1.7, 1.7, '[]')); + +create table numrange_test2(nr numrange); +INSERT INTO numrange_test2 VALUES('[, 5)'); +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2,'()')); +INSERT INTO numrange_test2 VALUES('empty'); + +set enable_nestloop=t; +set enable_hashjoin=f; +set enable_mergejoin=f; +select * from numrange_test natural join numrange_test2 order by nr; + +DROP TABLE atest1, atest2, t1, t2, t3, numrange_test, numrange_test2; + +set default_table_access_method to default; diff --git a/src/test/regress/sql/columnar_query.sql b/src/test/regress/sql/columnar_query.sql index a56860956..9a99367e0 100644 --- a/src/test/regress/sql/columnar_query.sql +++ b/src/test/regress/sql/columnar_query.sql @@ -91,3 +91,40 @@ UNION SET client_min_messages TO WARNING; DROP SCHEMA columnar_join CASCADE; + +-- +-- https://github.com/citusdata/citus/issues/5258 +-- + +set default_table_access_method to columnar; +CREATE TABLE atest1 ( a int, b text ); +CREATE TABLE atest2 (col1 varchar(10), col2 boolean); + +INSERT INTO atest1 VALUES (1, 'one'); +SELECT * FROM atest1; -- ok +SELECT * FROM atest2; -- ok +INSERT INTO atest1 VALUES (2, 'two'); -- ok +INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok + +SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) ); + +DROP TABLE atest1; +DROP TABLE atest2; +set default_table_access_method to default; + +create temp table t1 (f1 numeric(14,0), f2 varchar(30)) USING columnar; +select * from + (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs + from t1 up) ss +group by f1,f2,fs; +drop table t1; + +CREATE TABLE tbl1(c0 int4range) USING COLUMNAR; +CREATE TABLE tbl2(c0 int4range); + +INSERT INTO tbl1(c0) VALUES('[0,1]'::int4range); +INSERT INTO tbl1(c0) VALUES('[0,1]'::int4range); + +SELECT tbl1.c0 FROM tbl1 JOIN tbl2 ON tbl1.c0=tbl2.c0 WHERE tbl2.c0<=tbl2.c0 ISNULL; +DROP TABLE tbl1; +DROP TABLE tbl2; diff --git a/src/test/regress/sql/pg14.sql b/src/test/regress/sql/pg14.sql index e7f9a3ca8..cbb1d755a 100644 --- a/src/test/regress/sql/pg14.sql +++ b/src/test/regress/sql/pg14.sql @@ -272,7 +272,6 @@ REINDEX TABLE dist_part_table; -- but we support REINDEXing partitions REINDEX TABLE dist_part_table_1; - -- test if we error with CTEs with search clauses CREATE TABLE graph0(f INT, t INT, label TEXT); SELECT create_distributed_table('graph0', 'f'); @@ -337,5 +336,35 @@ SELECT * FROM ( SELECT * FROM search_graph ORDER BY seq ) as foo; +-- +-- https://github.com/citusdata/citus/issues/5258 +-- +CREATE TABLE nummultirange_test (nmr NUMMULTIRANGE) USING columnar; +INSERT INTO nummultirange_test VALUES('{}'); +INSERT INTO nummultirange_test VALUES('{[,)}'); +INSERT INTO nummultirange_test VALUES('{[3,]}'); +INSERT INTO nummultirange_test VALUES('{[, 5)}'); +INSERT INTO nummultirange_test VALUES(nummultirange()); +INSERT INTO nummultirange_test VALUES(nummultirange(variadic '{}'::numrange[])); +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.1, 2.2))); +INSERT INTO nummultirange_test VALUES('{empty}'); +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.7, 1.9))); +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.9, 2.1))); + +create table nummultirange_test2(nmr nummultirange) USING columnar; +INSERT INTO nummultirange_test2 VALUES('{[, 5)}'); +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))); +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))); +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2,'()'))); +INSERT INTO nummultirange_test2 VALUES('{}'); +select * from nummultirange_test2 where nmr = '{}'; +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.2)); +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.3)); + +set enable_nestloop=t; +set enable_hashjoin=f; +set enable_mergejoin=f; +select * from nummultirange_test natural join nummultirange_test2 order by nmr; + set client_min_messages to error; drop schema pg14 cascade;