mirror of https://github.com/citusdata/citus.git
Columnar: separate plan and runtime quals. (#5261)
* Columnar: separate plain and exec quals. Make a clear separation between plain quals, which contain constants or extern params; and exec quals, which contain exec params and can't be evaluated until a rescan. Fixes #5258. * more vanilla tests Co-authored-by: Onur Tirtir <onurcantirtir@gmail.com>pull/5276/head
parent
d48ceee238
commit
6e8b19984e
|
@ -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.
|
* 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);
|
path->param_info = get_baserel_parampathinfo(root, rel, paramRelids);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now, baserestrictinfo contains the clauses referencing only this rel,
|
* Usable clauses for this parameterization exist in baserestrictinfo and
|
||||||
* and ppi_clauses (if present) represents the join clauses that reference
|
* ppi_clauses.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
List *allClauses = copyObject(rel->baserestrictinfo);
|
List *allClauses = copyObject(rel->baserestrictinfo);
|
||||||
if (path->param_info != NULL)
|
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);
|
allClauses = list_concat(allClauses, path->param_info->ppi_clauses);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
allClauses = FilterPushdownClauses(root, rel, allClauses);
|
||||||
* 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);
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
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 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,
|
CostColumnarScan(root, rel, rte->relid, cpath, numberOfColumnsRead,
|
||||||
numberOfClausesPushed);
|
numberOfClausesPushed);
|
||||||
|
@ -1188,8 +1235,9 @@ CostColumnarScan(PlannerInfo *root, RelOptInfo *rel, Oid relationId,
|
||||||
{
|
{
|
||||||
Path *path = &cpath->path;
|
Path *path = &cpath->path;
|
||||||
|
|
||||||
|
List *allClauses = lsecond(cpath->custom_private);
|
||||||
Selectivity clauseSel = clauselist_selectivity(
|
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
|
* We already filtered out clauses where the overall selectivity would be
|
||||||
|
@ -1297,18 +1345,28 @@ ColumnarScanPath_PlanCustomPath(PlannerInfo *root,
|
||||||
if (EnableColumnarQualPushdown)
|
if (EnableColumnarQualPushdown)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* List of pushed-down clauses. The Vars referencing other relations
|
* Lists of pushed-down clauses. The Vars in custom_exprs referencing
|
||||||
* will be changed into exec Params by create_customscan_plan().
|
* other relations will be changed into exec Params by
|
||||||
|
* create_customscan_plan().
|
||||||
*
|
*
|
||||||
* XXX: this just means what will be pushed into the columnar reader
|
* Like CustomPath->custom_private, keep a list of plain clauses
|
||||||
* code; some of these may not be usable. We should fix this by
|
* separate from the list of all clauses by making them sublists of a
|
||||||
* passing down something more like ScanKeys, where we've already
|
* 2-element list.
|
||||||
* verified that the operators match the btree opclass of the chunk
|
*
|
||||||
* predicates.
|
* 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(
|
List *plainClauses = extract_actual_clauses(
|
||||||
extract_actual_clauses(best_path->custom_private,
|
linitial(best_path->custom_private), false /* no pseudoconstants */);
|
||||||
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(
|
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;
|
columnarScanState->css_RuntimeContext = cscanstate->ss.ps.ps_ExprContext;
|
||||||
cscanstate->ss.ps.ps_ExprContext = stdecontext;
|
cscanstate->ss.ps.ps_ExprContext = stdecontext;
|
||||||
|
|
||||||
/* XXX: separate into runtime clauses and normal clauses */
|
|
||||||
ResetExprContext(columnarScanState->css_RuntimeContext);
|
ResetExprContext(columnarScanState->css_RuntimeContext);
|
||||||
|
List *plainClauses = linitial(cscan->custom_exprs);
|
||||||
columnarScanState->qual = (List *) EvalParamsMutator(
|
columnarScanState->qual = (List *) EvalParamsMutator(
|
||||||
(Node *) cscan->custom_exprs, columnarScanState->css_RuntimeContext);
|
(Node *) plainClauses, columnarScanState->css_RuntimeContext);
|
||||||
|
|
||||||
/* scan slot is already initialized */
|
/* scan slot is already initialized */
|
||||||
}
|
}
|
||||||
|
@ -1604,8 +1662,9 @@ ColumnarScan_ReScanCustomScan(CustomScanState *node)
|
||||||
ColumnarScanState *columnarScanState = (ColumnarScanState *) node;
|
ColumnarScanState *columnarScanState = (ColumnarScanState *) node;
|
||||||
|
|
||||||
ResetExprContext(columnarScanState->css_RuntimeContext);
|
ResetExprContext(columnarScanState->css_RuntimeContext);
|
||||||
|
List *allClauses = lsecond(cscan->custom_exprs);
|
||||||
columnarScanState->qual = (List *) EvalParamsMutator(
|
columnarScanState->qual = (List *) EvalParamsMutator(
|
||||||
(Node *) cscan->custom_exprs, columnarScanState->css_RuntimeContext);
|
(Node *) allClauses, columnarScanState->css_RuntimeContext);
|
||||||
|
|
||||||
TableScanDesc scanDesc = node->ss.ss_currentScanDesc;
|
TableScanDesc scanDesc = node->ss.ss_currentScanDesc;
|
||||||
|
|
||||||
|
@ -1635,7 +1694,7 @@ ColumnarScan_ExplainCustomScan(CustomScanState *node, List *ancestors,
|
||||||
projectedColumnsStr, es);
|
projectedColumnsStr, es);
|
||||||
|
|
||||||
CustomScan *cscan = castNode(CustomScan, node->ss.ps.plan);
|
CustomScan *cscan = castNode(CustomScan, node->ss.ps.plan);
|
||||||
List *chunkGroupFilter = cscan->custom_exprs;
|
List *chunkGroupFilter = lsecond(cscan->custom_exprs);
|
||||||
if (chunkGroupFilter != NULL)
|
if (chunkGroupFilter != NULL)
|
||||||
{
|
{
|
||||||
const char *pushdownClausesStr = ColumnarPushdownClausesStr(
|
const char *pushdownClausesStr = ColumnarPushdownClausesStr(
|
||||||
|
|
|
@ -746,3 +746,76 @@ select filtered_row_count('execute foo(3)');
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
drop table columnar_prepared_stmt;
|
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;
|
||||||
|
|
|
@ -746,3 +746,76 @@ select filtered_row_count('execute foo(3)');
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
drop table columnar_prepared_stmt;
|
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;
|
||||||
|
|
|
@ -187,3 +187,52 @@ UNION
|
||||||
|
|
||||||
SET client_min_messages TO WARNING;
|
SET client_min_messages TO WARNING;
|
||||||
DROP SCHEMA columnar_join CASCADE;
|
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;
|
||||||
|
|
|
@ -713,5 +713,58 @@ SELECT * FROM (
|
||||||
SELECT * FROM search_graph ORDER BY seq
|
SELECT * FROM search_graph ORDER BY seq
|
||||||
) as foo;
|
) as foo;
|
||||||
ERROR: recursive CTEs are not supported in distributed queries
|
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;
|
set client_min_messages to error;
|
||||||
drop schema pg14 cascade;
|
drop schema pg14 cascade;
|
||||||
|
|
|
@ -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)');
|
||||||
select filtered_row_count('execute foo(3)');
|
select filtered_row_count('execute foo(3)');
|
||||||
drop table columnar_prepared_stmt;
|
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;
|
||||||
|
|
|
@ -91,3 +91,40 @@ UNION
|
||||||
|
|
||||||
SET client_min_messages TO WARNING;
|
SET client_min_messages TO WARNING;
|
||||||
DROP SCHEMA columnar_join CASCADE;
|
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;
|
||||||
|
|
|
@ -272,7 +272,6 @@ REINDEX TABLE dist_part_table;
|
||||||
-- but we support REINDEXing partitions
|
-- but we support REINDEXing partitions
|
||||||
REINDEX TABLE dist_part_table_1;
|
REINDEX TABLE dist_part_table_1;
|
||||||
|
|
||||||
|
|
||||||
-- test if we error with CTEs with search clauses
|
-- test if we error with CTEs with search clauses
|
||||||
CREATE TABLE graph0(f INT, t INT, label TEXT);
|
CREATE TABLE graph0(f INT, t INT, label TEXT);
|
||||||
SELECT create_distributed_table('graph0', 'f');
|
SELECT create_distributed_table('graph0', 'f');
|
||||||
|
@ -337,5 +336,35 @@ SELECT * FROM (
|
||||||
SELECT * FROM search_graph ORDER BY seq
|
SELECT * FROM search_graph ORDER BY seq
|
||||||
) as foo;
|
) 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;
|
set client_min_messages to error;
|
||||||
drop schema pg14 cascade;
|
drop schema pg14 cascade;
|
||||||
|
|
Loading…
Reference in New Issue