mirror of https://github.com/citusdata/citus.git
Fix segmentation fault in case of joins with WHERE 1=0
parent
70fd42c41c
commit
3318288d75
|
@ -814,7 +814,12 @@ SelectClauseTableIdList(List *selectClauseList)
|
||||||
Var *selectColumn = NULL;
|
Var *selectColumn = NULL;
|
||||||
int selectColumnTableId = 0;
|
int selectColumnTableId = 0;
|
||||||
|
|
||||||
Assert(list_length(selectColumnList) > 0);
|
if (list_length(selectColumnList) == 0)
|
||||||
|
{
|
||||||
|
/* filter is a constant, e.g. false or 1=0 */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
selectColumn = (Var *) linitial(selectColumnList);
|
selectColumn = (Var *) linitial(selectColumnList);
|
||||||
selectColumnTableId = (int) selectColumn->varno;
|
selectColumnTableId = (int) selectColumn->varno;
|
||||||
|
|
||||||
|
@ -944,8 +949,15 @@ TableIdListSelectClauses(List *tableIdList, List *selectClauseList)
|
||||||
foreach(selectClauseCell, selectClauseList)
|
foreach(selectClauseCell, selectClauseList)
|
||||||
{
|
{
|
||||||
Node *selectClause = (Node *) lfirst(selectClauseCell);
|
Node *selectClause = (Node *) lfirst(selectClauseCell);
|
||||||
List *selectColumnList = pull_var_clause_default(selectClause);
|
|
||||||
|
|
||||||
|
List *selectColumnList = pull_var_clause_default(selectClause);
|
||||||
|
if (list_length(selectColumnList) == 0)
|
||||||
|
{
|
||||||
|
/* filter is a constant, e.g. false or 1=0, always include it */
|
||||||
|
tableSelectClauseList = lappend(tableSelectClauseList, selectClause);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Var *selectColumn = (Var *) linitial(selectColumnList);
|
Var *selectColumn = (Var *) linitial(selectColumnList);
|
||||||
int selectClauseTableId = (int) selectColumn->varno;
|
int selectClauseTableId = (int) selectColumn->varno;
|
||||||
|
|
||||||
|
@ -955,6 +967,7 @@ TableIdListSelectClauses(List *tableIdList, List *selectClauseList)
|
||||||
tableSelectClauseList = lappend(tableSelectClauseList, selectClause);
|
tableSelectClauseList = lappend(tableSelectClauseList, selectClause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return tableSelectClauseList;
|
return tableSelectClauseList;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2515,6 +2515,12 @@ PruneShardList(Oid relationId, Index tableId, List *whereClauseList,
|
||||||
Var *partitionColumn = PartitionColumn(relationId, tableId);
|
Var *partitionColumn = PartitionColumn(relationId, tableId);
|
||||||
char partitionMethod = PartitionMethod(relationId);
|
char partitionMethod = PartitionMethod(relationId);
|
||||||
|
|
||||||
|
if (ContainsFalseClause(whereClauseList))
|
||||||
|
{
|
||||||
|
/* always return empty result if WHERE clause is of the form: false (AND ..) */
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
/* build the filter clause list for the partition method */
|
/* build the filter clause list for the partition method */
|
||||||
if (partitionMethod == DISTRIBUTE_BY_HASH)
|
if (partitionMethod == DISTRIBUTE_BY_HASH)
|
||||||
{
|
{
|
||||||
|
@ -2569,6 +2575,35 @@ PruneShardList(Oid relationId, Index tableId, List *whereClauseList,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ContainsFalseClause returns whether the flattened where clause list
|
||||||
|
* contains false as a clause.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
ContainsFalseClause(List *whereClauseList)
|
||||||
|
{
|
||||||
|
bool containsFalseClause = false;
|
||||||
|
ListCell *clauseCell = NULL;
|
||||||
|
|
||||||
|
foreach(clauseCell, whereClauseList)
|
||||||
|
{
|
||||||
|
Node *clause = (Node *) lfirst(clauseCell);
|
||||||
|
|
||||||
|
if (IsA(clause, Const))
|
||||||
|
{
|
||||||
|
Const *constant = (Const *) clause;
|
||||||
|
if (constant->consttype == BOOLOID && !DatumGetBool(constant->constvalue))
|
||||||
|
{
|
||||||
|
containsFalseClause = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return containsFalseClause;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BuildBaseConstraint builds and returns a base constraint. This constraint
|
* BuildBaseConstraint builds and returns a base constraint. This constraint
|
||||||
* implements an expression in the form of (column <= max && column >= min),
|
* implements an expression in the form of (column <= max && column >= min),
|
||||||
|
|
|
@ -231,6 +231,7 @@ extern StringInfo ShardFetchQueryString(uint64 shardId);
|
||||||
/* Function declarations for shard pruning */
|
/* Function declarations for shard pruning */
|
||||||
extern List * PruneShardList(Oid relationId, Index tableId, List *whereClauseList,
|
extern List * PruneShardList(Oid relationId, Index tableId, List *whereClauseList,
|
||||||
List *shardList);
|
List *shardList);
|
||||||
|
extern bool ContainsFalseClause(List *whereClauseList);
|
||||||
extern OpExpr * MakeOpExpression(Var *variable, int16 strategyNumber);
|
extern OpExpr * MakeOpExpression(Var *variable, int16 strategyNumber);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -224,7 +224,7 @@ SELECT count(*) FROM lineitem
|
||||||
WHERE 0 != 0;
|
WHERE 0 != 0;
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
0
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- distinct expressions can be pushed down
|
-- distinct expressions can be pushed down
|
||||||
|
|
|
@ -75,6 +75,22 @@ DEBUG: join prunable for intervals [13473,14947] and [1,5986]
|
||||||
|
|
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- Make sure that we can handle filters without a column
|
||||||
|
SELECT sum(l_linenumber), avg(l_linenumber) FROM lineitem, orders
|
||||||
|
WHERE l_orderkey = o_orderkey AND false;
|
||||||
|
sum | avg
|
||||||
|
-----+-----
|
||||||
|
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT sum(l_linenumber), avg(l_linenumber)
|
||||||
|
FROM lineitem INNER JOIN orders ON (l_orderkey = o_orderkey)
|
||||||
|
WHERE false;
|
||||||
|
sum | avg
|
||||||
|
-----+-----
|
||||||
|
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- These tests check that we can do join pruning for tables partitioned over
|
-- These tests check that we can do join pruning for tables partitioned over
|
||||||
-- different type of columns including varchar, array types, composite types
|
-- different type of columns including varchar, array types, composite types
|
||||||
-- etc. This is in response to a bug we had where we were not able to resolve
|
-- etc. This is in response to a bug we had where we were not able to resolve
|
||||||
|
@ -110,4 +126,3 @@ DEBUG: join prunable for intervals [BA1000U2AMO4ZGX,BZZXSP27F21T6] and [AA1000U
|
||||||
explain statements for distributed queries are not enabled
|
explain statements for distributed queries are not enabled
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SET client_min_messages TO NOTICE;
|
|
||||||
|
|
|
@ -130,5 +130,42 @@ DEBUG: predicate pruning for shardId 290007
|
||||||
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Reset client logging level to its previous value
|
-- Test cases with false in the WHERE clause
|
||||||
SET client_min_messages TO NOTICE;
|
SELECT
|
||||||
|
o_orderkey
|
||||||
|
FROM
|
||||||
|
orders INNER JOIN customer ON (o_custkey = c_custkey)
|
||||||
|
WHERE
|
||||||
|
false;
|
||||||
|
o_orderkey
|
||||||
|
------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
o_orderkey
|
||||||
|
FROM
|
||||||
|
orders INNER JOIN customer ON (o_custkey = c_custkey)
|
||||||
|
WHERE
|
||||||
|
1=0 AND c_custkey < 0;
|
||||||
|
o_orderkey
|
||||||
|
------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
o_orderkey
|
||||||
|
FROM
|
||||||
|
orders INNER JOIN customer ON (o_custkey = c_custkey AND false);
|
||||||
|
o_orderkey
|
||||||
|
------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
o_orderkey
|
||||||
|
FROM
|
||||||
|
orders, customer
|
||||||
|
WHERE
|
||||||
|
o_custkey = c_custkey AND false;
|
||||||
|
o_orderkey
|
||||||
|
------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,14 @@ SELECT sum(l_linenumber), avg(l_linenumber) FROM lineitem, orders
|
||||||
SELECT sum(l_linenumber), avg(l_linenumber) FROM lineitem, orders
|
SELECT sum(l_linenumber), avg(l_linenumber) FROM lineitem, orders
|
||||||
WHERE l_orderkey = o_orderkey AND l_orderkey > 6000 AND o_orderkey < 6000;
|
WHERE l_orderkey = o_orderkey AND l_orderkey > 6000 AND o_orderkey < 6000;
|
||||||
|
|
||||||
|
-- Make sure that we can handle filters without a column
|
||||||
|
SELECT sum(l_linenumber), avg(l_linenumber) FROM lineitem, orders
|
||||||
|
WHERE l_orderkey = o_orderkey AND false;
|
||||||
|
|
||||||
|
SELECT sum(l_linenumber), avg(l_linenumber)
|
||||||
|
FROM lineitem INNER JOIN orders ON (l_orderkey = o_orderkey)
|
||||||
|
WHERE false;
|
||||||
|
|
||||||
-- These tests check that we can do join pruning for tables partitioned over
|
-- These tests check that we can do join pruning for tables partitioned over
|
||||||
-- different type of columns including varchar, array types, composite types
|
-- different type of columns including varchar, array types, composite types
|
||||||
-- etc. This is in response to a bug we had where we were not able to resolve
|
-- etc. This is in response to a bug we had where we were not able to resolve
|
||||||
|
@ -54,5 +62,3 @@ EXPLAIN SELECT count(*)
|
||||||
EXPLAIN SELECT count(*)
|
EXPLAIN SELECT count(*)
|
||||||
FROM varchar_partitioned_table table1, varchar_partitioned_table table2
|
FROM varchar_partitioned_table table1, varchar_partitioned_table table2
|
||||||
WHERE table1.varchar_column = table2.varchar_column;
|
WHERE table1.varchar_column = table2.varchar_column;
|
||||||
|
|
||||||
SET client_min_messages TO NOTICE;
|
|
||||||
|
|
|
@ -67,6 +67,29 @@ WHERE
|
||||||
l_partkey = c_nationkey AND
|
l_partkey = c_nationkey AND
|
||||||
l_orderkey < 0;
|
l_orderkey < 0;
|
||||||
|
|
||||||
-- Reset client logging level to its previous value
|
-- Test cases with false in the WHERE clause
|
||||||
|
SELECT
|
||||||
|
o_orderkey
|
||||||
|
FROM
|
||||||
|
orders INNER JOIN customer ON (o_custkey = c_custkey)
|
||||||
|
WHERE
|
||||||
|
false;
|
||||||
|
|
||||||
SET client_min_messages TO NOTICE;
|
SELECT
|
||||||
|
o_orderkey
|
||||||
|
FROM
|
||||||
|
orders INNER JOIN customer ON (o_custkey = c_custkey)
|
||||||
|
WHERE
|
||||||
|
1=0 AND c_custkey < 0;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
o_orderkey
|
||||||
|
FROM
|
||||||
|
orders INNER JOIN customer ON (o_custkey = c_custkey AND false);
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
o_orderkey
|
||||||
|
FROM
|
||||||
|
orders, customer
|
||||||
|
WHERE
|
||||||
|
o_custkey = c_custkey AND false;
|
||||||
|
|
Loading…
Reference in New Issue