mirror of https://github.com/citusdata/citus.git
Make count return 0 if all shards are pruned away
Before this change, count on a distributed returned NULL if all shards were pruned away, because on the master we replace with count(..) call with a sum(..) call to sum the counts from the shards. However, sum returns NULL when there are no rows, whereas count is expected to return 0.pull/815/head
parent
9c19ad8b78
commit
c4bc0742a7
|
@ -1499,6 +1499,10 @@ MasterAggregateExpression(Aggref *originalAggregate,
|
||||||
*/
|
*/
|
||||||
Var *column = NULL;
|
Var *column = NULL;
|
||||||
TargetEntry *columnTargetEntry = NULL;
|
TargetEntry *columnTargetEntry = NULL;
|
||||||
|
CoerceViaIO *coerceExpr = NULL;
|
||||||
|
Const *zeroConst = NULL;
|
||||||
|
List *coalesceArgs = NULL;
|
||||||
|
CoalesceExpr *coalesceExpr = NULL;
|
||||||
|
|
||||||
/* worker aggregate and original aggregate have the same return type */
|
/* worker aggregate and original aggregate have the same return type */
|
||||||
Oid workerReturnType = exprType((Node *) originalAggregate);
|
Oid workerReturnType = exprType((Node *) originalAggregate);
|
||||||
|
@ -1523,7 +1527,25 @@ MasterAggregateExpression(Aggref *originalAggregate,
|
||||||
columnTargetEntry = makeTargetEntry((Expr *) column, argumentId, NULL, false);
|
columnTargetEntry = makeTargetEntry((Expr *) column, argumentId, NULL, false);
|
||||||
newMasterAggregate->args = list_make1(columnTargetEntry);
|
newMasterAggregate->args = list_make1(columnTargetEntry);
|
||||||
|
|
||||||
newMasterExpression = (Expr *) newMasterAggregate;
|
/* cast numeric sum result to bigint (count's return type) */
|
||||||
|
coerceExpr = makeNode(CoerceViaIO);
|
||||||
|
coerceExpr->arg = (Expr *) newMasterAggregate;
|
||||||
|
coerceExpr->resulttype = INT8OID;
|
||||||
|
coerceExpr->resultcollid = InvalidOid;
|
||||||
|
coerceExpr->coerceformat = COERCE_IMPLICIT_CAST;
|
||||||
|
coerceExpr->location = -1;
|
||||||
|
|
||||||
|
/* convert NULL to 0 in case of no rows */
|
||||||
|
zeroConst = MakeIntegerConstInt64(0);
|
||||||
|
coalesceArgs = list_make2(coerceExpr, zeroConst);
|
||||||
|
|
||||||
|
coalesceExpr = makeNode(CoalesceExpr);
|
||||||
|
coalesceExpr->coalescetype = INT8OID;
|
||||||
|
coalesceExpr->coalescecollid = InvalidOid;
|
||||||
|
coalesceExpr->args = coalesceArgs;
|
||||||
|
coalesceExpr->location = -1;
|
||||||
|
|
||||||
|
newMasterExpression = (Expr *) coalesceExpr;
|
||||||
}
|
}
|
||||||
else if (aggregateType == AGGREGATE_ARRAY_AGG)
|
else if (aggregateType == AGGREGATE_ARRAY_AGG)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -43,7 +43,7 @@ Distributed Query into pg_merge_job_570000
|
||||||
-> Seq Scan on lineitem_290000 lineitem
|
-> Seq Scan on lineitem_290000 lineitem
|
||||||
Master Query
|
Master Query
|
||||||
-> Sort
|
-> Sort
|
||||||
Sort Key: (sum(((sum(intermediate_column_570000_1))::bigint)))::bigint, intermediate_column_570000_0
|
Sort Key: COALESCE((sum((COALESCE((sum(intermediate_column_570000_1))::bigint, '0'::bigint))))::bigint, '0'::bigint), intermediate_column_570000_0
|
||||||
-> HashAggregate
|
-> HashAggregate
|
||||||
Group Key: intermediate_column_570000_0
|
Group Key: intermediate_column_570000_0
|
||||||
-> Seq Scan on pg_merge_job_570000
|
-> Seq Scan on pg_merge_job_570000
|
||||||
|
@ -87,7 +87,7 @@ EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||||
{
|
{
|
||||||
"Plan": {
|
"Plan": {
|
||||||
"Node Type": "Sort",
|
"Node Type": "Sort",
|
||||||
"Sort Key": ["(sum(((sum(intermediate_column_570001_1))::bigint)))::bigint", "intermediate_column_570001_0"],
|
"Sort Key": ["COALESCE((sum((COALESCE((sum(intermediate_column_570001_1))::bigint, '0'::bigint))))::bigint, '0'::bigint)", "intermediate_column_570001_0"],
|
||||||
"Plans": [
|
"Plans": [
|
||||||
{
|
{
|
||||||
"Node Type": "Aggregate",
|
"Node Type": "Aggregate",
|
||||||
|
@ -156,7 +156,7 @@ EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||||
<Plan>
|
<Plan>
|
||||||
<Node-Type>Sort</Node-Type>
|
<Node-Type>Sort</Node-Type>
|
||||||
<Sort-Key>
|
<Sort-Key>
|
||||||
<Item>(sum(((sum(intermediate_column_570003_1))::bigint)))::bigint</Item>
|
<Item>COALESCE((sum((COALESCE((sum(intermediate_column_570003_1))::bigint, '0'::bigint))))::bigint, '0'::bigint)</Item>
|
||||||
<Item>intermediate_column_570003_0</Item>
|
<Item>intermediate_column_570003_0</Item>
|
||||||
</Sort-Key>
|
</Sort-Key>
|
||||||
<Plans>
|
<Plans>
|
||||||
|
@ -213,7 +213,7 @@ EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||||
- Plan:
|
- Plan:
|
||||||
Node Type: "Sort"
|
Node Type: "Sort"
|
||||||
Sort Key:
|
Sort Key:
|
||||||
- "(sum(((sum(intermediate_column_570005_1))::bigint)))::bigint"
|
- "COALESCE((sum((COALESCE((sum(intermediate_column_570005_1))::bigint, '0'::bigint))))::bigint, '0'::bigint)"
|
||||||
- "intermediate_column_570005_0"
|
- "intermediate_column_570005_0"
|
||||||
Plans:
|
Plans:
|
||||||
- Node Type: "Aggregate"
|
- Node Type: "Aggregate"
|
||||||
|
@ -241,7 +241,7 @@ Distributed Query into pg_merge_job_570006
|
||||||
-> Seq Scan on lineitem_290000 lineitem
|
-> Seq Scan on lineitem_290000 lineitem
|
||||||
Master Query
|
Master Query
|
||||||
-> Sort
|
-> Sort
|
||||||
Sort Key: (sum(((sum(intermediate_column_570006_1))::bigint)))::bigint, intermediate_column_570006_0
|
Sort Key: COALESCE((sum((COALESCE((sum(intermediate_column_570006_1))::bigint, '0'::bigint))))::bigint, '0'::bigint), intermediate_column_570006_0
|
||||||
-> HashAggregate
|
-> HashAggregate
|
||||||
Group Key: intermediate_column_570006_0
|
Group Key: intermediate_column_570006_0
|
||||||
-> Seq Scan on pg_merge_job_570006
|
-> Seq Scan on pg_merge_job_570006
|
||||||
|
|
|
@ -46,7 +46,7 @@ DEBUG: predicate pruning for shardId 290008
|
||||||
DEBUG: predicate pruning for shardId 290009
|
DEBUG: predicate pruning for shardId 290009
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
|
0
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Single range-repartition join with a selection clause on the base table to
|
-- Single range-repartition join with a selection clause on the base table to
|
||||||
|
@ -63,7 +63,7 @@ DEBUG: predicate pruning for shardId 280001
|
||||||
DEBUG: predicate pruning for shardId 280000
|
DEBUG: predicate pruning for shardId 280000
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
|
0
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Dual hash-repartition join test case. Note that this query doesn't produce
|
-- Dual hash-repartition join test case. Note that this query doesn't produce
|
||||||
|
@ -127,7 +127,7 @@ DEBUG: predicate pruning for shardId 290006
|
||||||
DEBUG: predicate pruning for shardId 290007
|
DEBUG: predicate pruning for shardId 290007
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
|
0
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Test cases with false in the WHERE clause
|
-- Test cases with false in the WHERE clause
|
||||||
|
|
|
@ -1668,7 +1668,7 @@ SELECT count(*), count(*) FILTER (WHERE id < 3)
|
||||||
WHERE author_id = 1 or author_id = 2;
|
WHERE author_id = 1 or author_id = 2;
|
||||||
count | count
|
count | count
|
||||||
-------+-------
|
-------+-------
|
||||||
10 |
|
10 | 0
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- prepare queries can be router plannable
|
-- prepare queries can be router plannable
|
||||||
|
|
|
@ -59,7 +59,7 @@ TRUNCATE TABLE test_truncate_append;
|
||||||
SELECT count(*) FROM test_truncate_append;
|
SELECT count(*) FROM test_truncate_append;
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
|
0
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- verify no shard exists anymore
|
-- verify no shard exists anymore
|
||||||
|
|
|
@ -66,7 +66,7 @@ SELECT master_apply_delete_command('DELETE FROM customer_delete_protocol');
|
||||||
SELECT count(*) FROM customer_delete_protocol;
|
SELECT count(*) FROM customer_delete_protocol;
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
|
0
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Verify that empty shards are deleted if no condition is provided
|
-- Verify that empty shards are deleted if no condition is provided
|
||||||
|
|
Loading…
Reference in New Issue