mirror of https://github.com/citusdata/citus.git
Do not prune shards if the distribution key is NULL
The root of the problem is that, standard_planner() converts the following qual ``` {OPEXPR :opno 98 :opfuncid 67 :opresulttype 16 :opretset false :opcollid 0 :inputcollid 100 :args ( {VAR :varno 1 :varattno 1 :vartype 25 :vartypmod -1 :varcollid 100 :varlevelsup 0 :varnoold 1 :varoattno 1 :location 45 } {CONST :consttype 25 :consttypmod -1 :constcollid 100 :constlen -1 :constbyval false :constisnull true :location 51 :constvalue <> } ) :location 49 } ``` To ``` ( {CONST :consttype 16 :consttypmod -1 :constcollid 0 :constlen 1 :constbyval true :constisnull true :location -1 :constvalue <> } ) ``` So, Citus doesn't deal with NULL values in real-time or non-fast path router queries. And, in the FastPathRouter planner, we check constisnull in DistKeyInSimpleOpExpression(). However, in deferred pruning case, we do not check for isnull for const. Thus, the fix consists of two parts: - Let PruneShards() not crash when NULL parameter is passed - For deferred shard pruning in fast-path queries, explicitly check that we have CONST which is not NULLpull/3498/head
parent
cd8210d516
commit
975c4c2264
|
@ -545,8 +545,8 @@ HandleDeferredShardPruningForFastPathQueries(DistributedPlan *distributedPlan)
|
|||
bool isMultiShardQuery = false;
|
||||
List *shardIntervalList =
|
||||
TargetShardIntervalForFastPathQuery(workerJob->jobQuery,
|
||||
&workerJob->partitionKeyValue,
|
||||
&isMultiShardQuery, NULL);
|
||||
&isMultiShardQuery, NULL,
|
||||
&workerJob->partitionKeyValue);
|
||||
|
||||
/*
|
||||
* A fast-path router query can only yield multiple shards when the parameter
|
||||
|
|
|
@ -2091,8 +2091,9 @@ PlanRouterQuery(Query *originalQuery,
|
|||
plannerRestrictionContext->fastPathRestrictionContext->distributionKeyValue;
|
||||
|
||||
List *shardIntervalList =
|
||||
TargetShardIntervalForFastPathQuery(originalQuery, partitionValueConst,
|
||||
&isMultiShardQuery, distributionKeyValue);
|
||||
TargetShardIntervalForFastPathQuery(originalQuery, &isMultiShardQuery,
|
||||
distributionKeyValue,
|
||||
partitionValueConst);
|
||||
|
||||
/*
|
||||
* This could only happen when there is a parameter on the distribution key.
|
||||
|
@ -2375,25 +2376,32 @@ GetAnchorShardId(List *prunedShardIntervalListList)
|
|||
* one list of a a one shard interval (see FastPathRouterQuery()
|
||||
* for the detail).
|
||||
*
|
||||
* Also set the outgoing partition column value if requested via
|
||||
* partitionValueConst
|
||||
* If the caller requested the distributionKey value that this function
|
||||
* yields, set outputPartitionValueConst.
|
||||
*/
|
||||
List *
|
||||
TargetShardIntervalForFastPathQuery(Query *query, Const **partitionValueConst,
|
||||
bool *isMultiShardQuery, Const *distributionKeyValue)
|
||||
TargetShardIntervalForFastPathQuery(Query *query, bool *isMultiShardQuery,
|
||||
Const *inputDistributionKeyValue,
|
||||
Const **outputPartitionValueConst)
|
||||
{
|
||||
Oid relationId = ExtractFirstDistributedTableId(query);
|
||||
|
||||
if (distributionKeyValue)
|
||||
if (PartitionMethod(relationId) == DISTRIBUTE_BY_NONE)
|
||||
{
|
||||
/* we don't need to do shard pruning for reference tables */
|
||||
return list_make1(LoadShardIntervalList(relationId));
|
||||
}
|
||||
|
||||
if (inputDistributionKeyValue && !inputDistributionKeyValue->constisnull)
|
||||
{
|
||||
DistTableCacheEntry *cache = DistributedTableCacheEntry(relationId);
|
||||
ShardInterval *shardInterval =
|
||||
FindShardInterval(distributionKeyValue->constvalue, cache);
|
||||
FindShardInterval(inputDistributionKeyValue->constvalue, cache);
|
||||
|
||||
if (partitionValueConst != NULL)
|
||||
if (outputPartitionValueConst != NULL)
|
||||
{
|
||||
/* set the outgoing partition column value if requested */
|
||||
*partitionValueConst = distributionKeyValue;
|
||||
*outputPartitionValueConst = inputDistributionKeyValue;
|
||||
}
|
||||
List *shardIntervalList = list_make1(shardInterval);
|
||||
|
||||
|
@ -2402,10 +2410,24 @@ TargetShardIntervalForFastPathQuery(Query *query, Const **partitionValueConst,
|
|||
|
||||
Node *quals = query->jointree->quals;
|
||||
int relationIndex = 1;
|
||||
Const *queryPartitionValueConst = NULL;
|
||||
|
||||
/*
|
||||
* We couldn't do the shard pruning based on inputDistributionKeyValue as it might
|
||||
* be passed as NULL. Still, we can search the quals for distribution key.
|
||||
*/
|
||||
Const *distributionKeyValueInQuals = NULL;
|
||||
List *prunedShardIntervalList =
|
||||
PruneShards(relationId, relationIndex, make_ands_implicit((Expr *) quals),
|
||||
&queryPartitionValueConst);
|
||||
&distributionKeyValueInQuals);
|
||||
|
||||
if (!distributionKeyValueInQuals || distributionKeyValueInQuals->constisnull)
|
||||
{
|
||||
/*
|
||||
* If the distribution key equals to NULL, we prefer to treat it as a zero shard
|
||||
* query as it cannot return any rows.
|
||||
*/
|
||||
return NIL;
|
||||
}
|
||||
|
||||
/* we're only expecting single shard from a single table */
|
||||
Node *distKey PG_USED_FOR_ASSERTS_ONLY = NULL;
|
||||
|
@ -2416,10 +2438,10 @@ TargetShardIntervalForFastPathQuery(Query *query, Const **partitionValueConst,
|
|||
*isMultiShardQuery = true;
|
||||
}
|
||||
else if (list_length(prunedShardIntervalList) == 1 &&
|
||||
partitionValueConst != NULL)
|
||||
outputPartitionValueConst != NULL)
|
||||
{
|
||||
/* set the outgoing partition column value if requested */
|
||||
*partitionValueConst = queryPartitionValueConst;
|
||||
*outputPartitionValueConst = distributionKeyValueInQuals;
|
||||
}
|
||||
|
||||
return list_make1(prunedShardIntervalList);
|
||||
|
|
|
@ -749,13 +749,21 @@ AddPartitionKeyRestrictionToInstance(ClauseWalkerContext *context, OpExpr *opCla
|
|||
constantClause);
|
||||
if (constantClause == NULL)
|
||||
{
|
||||
/* couldn't coerce value, so we note this as a restriction we don't grok */
|
||||
/* couldn't coerce value, so we save it in otherRestrictions */
|
||||
prune->otherRestrictions = lappend(prune->otherRestrictions, opClause);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (constantClause->constisnull)
|
||||
{
|
||||
/* we cannot do pruning for NULL values, so we save it in otherRestrictions */
|
||||
prune->otherRestrictions = lappend(prune->otherRestrictions, opClause);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* at this point, we'd better be able to pass binary Datums to comparison functions */
|
||||
Assert(IsBinaryCoercible(constantClause->consttype, partitionColumn->vartype));
|
||||
|
||||
|
|
|
@ -77,9 +77,9 @@ extern List * WorkersContainingAllShards(List *prunedShardIntervalsList);
|
|||
|
||||
extern uint64 GetAnchorShardId(List *relationShardList);
|
||||
extern List * TargetShardIntervalForFastPathQuery(Query *query,
|
||||
Const **partitionValueConst,
|
||||
bool *isMultiShardQuery,
|
||||
Const *distributionKeyValue);
|
||||
Const *inputDistributionKeyValue,
|
||||
Const **outGoingPartitionValueConst);
|
||||
extern void GenerateSingleShardRouterTaskList(Job *job,
|
||||
List *relationShardList,
|
||||
List *placementList, uint64 shardId);
|
||||
|
|
|
@ -1636,6 +1636,68 @@ DEBUG: Plan is router executable
|
|||
41 | 1 | aznavour | 11814
|
||||
(5 rows)
|
||||
|
||||
EXECUTE author_articles(NULL);
|
||||
id | author_id | title | word_count
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
EXECUTE author_articles(NULL);
|
||||
id | author_id | title | word_count
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
EXECUTE author_articles(NULL);
|
||||
id | author_id | title | word_count
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
EXECUTE author_articles(NULL);
|
||||
id | author_id | title | word_count
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
EXECUTE author_articles(NULL);
|
||||
id | author_id | title | word_count
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
EXECUTE author_articles(NULL);
|
||||
id | author_id | title | word_count
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
EXECUTE author_articles(NULL);
|
||||
id | author_id | title | word_count
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
PREPARE author_articles_update(int) AS
|
||||
UPDATE articles_hash SET title = 'test' WHERE author_id = $1;
|
||||
EXECUTE author_articles_update(NULL);
|
||||
DEBUG: Deferred pruning for a fast-path router query
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
EXECUTE author_articles_update(NULL);
|
||||
DEBUG: Deferred pruning for a fast-path router query
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
EXECUTE author_articles_update(NULL);
|
||||
DEBUG: Deferred pruning for a fast-path router query
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
EXECUTE author_articles_update(NULL);
|
||||
DEBUG: Deferred pruning for a fast-path router query
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
EXECUTE author_articles_update(NULL);
|
||||
DEBUG: Deferred pruning for a fast-path router query
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
EXECUTE author_articles_update(NULL);
|
||||
DEBUG: Deferred pruning for a fast-path router query
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
EXECUTE author_articles_update(NULL);
|
||||
-- queries inside plpgsql functions could be router plannable
|
||||
CREATE OR REPLACE FUNCTION author_articles_max_id() RETURNS int AS $$
|
||||
DECLARE
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -201,7 +201,7 @@ test: multi_transaction_recovery
|
|||
# multi_router_planner creates hash partitioned tables.
|
||||
# ---------
|
||||
test: multi_copy fast_path_router_modify
|
||||
test: multi_router_planner multi_router_planner_fast_path
|
||||
test: multi_router_planner multi_router_planner_fast_path null_parameters
|
||||
|
||||
# ----------
|
||||
# multi_large_shardid loads more lineitem data using high shard identifiers
|
||||
|
|
|
@ -666,6 +666,25 @@ EXECUTE author_articles(1);
|
|||
EXECUTE author_articles(1);
|
||||
EXECUTE author_articles(1);
|
||||
|
||||
EXECUTE author_articles(NULL);
|
||||
EXECUTE author_articles(NULL);
|
||||
EXECUTE author_articles(NULL);
|
||||
EXECUTE author_articles(NULL);
|
||||
EXECUTE author_articles(NULL);
|
||||
EXECUTE author_articles(NULL);
|
||||
EXECUTE author_articles(NULL);
|
||||
|
||||
PREPARE author_articles_update(int) AS
|
||||
UPDATE articles_hash SET title = 'test' WHERE author_id = $1;
|
||||
|
||||
EXECUTE author_articles_update(NULL);
|
||||
EXECUTE author_articles_update(NULL);
|
||||
EXECUTE author_articles_update(NULL);
|
||||
EXECUTE author_articles_update(NULL);
|
||||
EXECUTE author_articles_update(NULL);
|
||||
EXECUTE author_articles_update(NULL);
|
||||
EXECUTE author_articles_update(NULL);
|
||||
|
||||
-- queries inside plpgsql functions could be router plannable
|
||||
CREATE OR REPLACE FUNCTION author_articles_max_id() RETURNS int AS $$
|
||||
DECLARE
|
||||
|
|
|
@ -0,0 +1,315 @@
|
|||
-- this file contain tests with pruning of NULL
|
||||
-- values with prepared statements
|
||||
CREATE SCHEMA null_parameters;
|
||||
SET search_path TO null_parameters;
|
||||
|
||||
SET citus.next_shard_id TO 1680000;
|
||||
CREATE TABLE text_dist_column (key text, value text);
|
||||
SELECT create_distributed_table('text_dist_column', 'key');
|
||||
|
||||
SET client_min_messages TO DEBUG;
|
||||
|
||||
|
||||
PREPARE null_select_on_text AS SELECT count(*) FROM text_dist_column WHERE key = NULL;
|
||||
EXECUTE null_select_on_text;
|
||||
EXECUTE null_select_on_text;
|
||||
EXECUTE null_select_on_text;
|
||||
EXECUTE null_select_on_text;
|
||||
EXECUTE null_select_on_text;
|
||||
EXECUTE null_select_on_text;
|
||||
|
||||
PREPARE null_select_on_text_param(text) AS SELECT count(*) FROM text_dist_column WHERE key = $1;
|
||||
EXECUTE null_select_on_text_param(NULL);
|
||||
EXECUTE null_select_on_text_param(NULL);
|
||||
EXECUTE null_select_on_text_param(5::text);
|
||||
EXECUTE null_select_on_text_param(NULL);
|
||||
EXECUTE null_select_on_text_param(NULL);
|
||||
EXECUTE null_select_on_text_param(NULL);
|
||||
EXECUTE null_select_on_text_param(NULL);
|
||||
EXECUTE null_select_on_text_param(NULL);
|
||||
EXECUTE null_select_on_text_param(NULL::varchar);
|
||||
EXECUTE null_select_on_text_param('test'::varchar);
|
||||
EXECUTE null_select_on_text_param(5::text);
|
||||
|
||||
PREPARE null_select_on_text_param_and_false(text) AS SELECT count(*) FROM text_dist_column WHERE key = $1 AND false;
|
||||
EXECUTE null_select_on_text_param_and_false(NULL);
|
||||
EXECUTE null_select_on_text_param_and_false(NULL);
|
||||
EXECUTE null_select_on_text_param_and_false(NULL);
|
||||
EXECUTE null_select_on_text_param_and_false(NULL);
|
||||
EXECUTE null_select_on_text_param_and_false(NULL);
|
||||
EXECUTE null_select_on_text_param_and_false(NULL);
|
||||
EXECUTE null_select_on_text_param_and_false(NULL);
|
||||
|
||||
PREPARE null_select_on_text_param_and_in(text) AS SELECT count(*) FROM text_dist_column WHERE key IN ($1);
|
||||
EXECUTE null_select_on_text_param_and_in(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in(NULL);
|
||||
|
||||
PREPARE null_select_on_text_param_and_in_2(text) AS SELECT count(*) FROM text_dist_column WHERE key IN ($1, 'test');
|
||||
EXECUTE null_select_on_text_param_and_in_2(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_2(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_2(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_2(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_2(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_2(NULL);
|
||||
|
||||
PREPARE null_select_on_text_param_and_in_3(text, text) AS SELECT count(*) FROM text_dist_column WHERE key IN ($1, $2);
|
||||
EXECUTE null_select_on_text_param_and_in_3(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_3(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_3(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_3(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_3(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_3(NULL, NULL);
|
||||
|
||||
|
||||
PREPARE null_select_on_text_param_and_in_4(text) AS SELECT count(*) FROM text_dist_column WHERE key IN ($1) AND false;
|
||||
EXECUTE null_select_on_text_param_and_in_4(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_4(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_4(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_4(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_4(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_4(NULL);
|
||||
|
||||
-- not a fast-path, still good to run
|
||||
PREPARE null_select_on_text_param_and_in_5(text, text) AS SELECT count(*) FROM text_dist_column WHERE key = $1 OR key = $2;
|
||||
EXECUTE null_select_on_text_param_and_in_5(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_5(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_5(1, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_5(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_5(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_5(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_5(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_5(NULL, NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_5(1, NULL);
|
||||
|
||||
-- not a fast-path, still good to have
|
||||
PREPARE null_select_on_text_param_and_in_6(text) AS SELECT count(*) FROM text_dist_column WHERE key NOT IN (SELECT value FROM text_dist_column WHERE key = $1);
|
||||
EXECUTE null_select_on_text_param_and_in_6(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_6(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_6(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_6(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_6(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_6(NULL);
|
||||
EXECUTE null_select_on_text_param_and_in_6(NULL);
|
||||
|
||||
-- different expression types which may not be fast-path queries
|
||||
PREPARE null_select_on_text_param_7(text) AS SELECT count(*) FROM text_dist_column WHERE (key = $1) is true;
|
||||
EXECUTE null_select_on_text_param_7(NULL);
|
||||
EXECUTE null_select_on_text_param_7(NULL);
|
||||
EXECUTE null_select_on_text_param_7(NULL);
|
||||
EXECUTE null_select_on_text_param_7(NULL);
|
||||
EXECUTE null_select_on_text_param_7(NULL);
|
||||
EXECUTE null_select_on_text_param_7(NULL);
|
||||
EXECUTE null_select_on_text_param_7(NULL);
|
||||
|
||||
-- different expression types which may not be fast-path queries
|
||||
PREPARE null_select_on_text_param_8(text) AS SELECT count(*) FROM text_dist_column WHERE key = ANY(ARRAY[$1]);
|
||||
EXECUTE null_select_on_text_param_8(NULL);
|
||||
EXECUTE null_select_on_text_param_8(NULL);
|
||||
EXECUTE null_select_on_text_param_8(NULL);
|
||||
EXECUTE null_select_on_text_param_8(NULL);
|
||||
EXECUTE null_select_on_text_param_8(NULL);
|
||||
EXECUTE null_select_on_text_param_8(NULL);
|
||||
EXECUTE null_select_on_text_param_8(NULL);
|
||||
|
||||
|
||||
PREPARE null_select_on_text_param_9(text) AS SELECT count(*) FROM text_dist_column WHERE key = ANY(ARRAY[$1, 'test']);
|
||||
EXECUTE null_select_on_text_param_9(NULL);
|
||||
EXECUTE null_select_on_text_param_9(NULL);
|
||||
EXECUTE null_select_on_text_param_9(NULL);
|
||||
EXECUTE null_select_on_text_param_9(NULL);
|
||||
EXECUTE null_select_on_text_param_9(NULL);
|
||||
EXECUTE null_select_on_text_param_9(NULL);
|
||||
EXECUTE null_select_on_text_param_9(NULL);
|
||||
|
||||
-- different expression types which may not be fast-path queries
|
||||
PREPARE null_select_on_text_param_10(text) AS SELECT count(*) FROM text_dist_column WHERE key = ALL(ARRAY[$1]);
|
||||
EXECUTE null_select_on_text_param_10(NULL);
|
||||
EXECUTE null_select_on_text_param_10(NULL);
|
||||
EXECUTE null_select_on_text_param_10(NULL);
|
||||
EXECUTE null_select_on_text_param_10(NULL);
|
||||
EXECUTE null_select_on_text_param_10(NULL);
|
||||
EXECUTE null_select_on_text_param_10(NULL);
|
||||
EXECUTE null_select_on_text_param_10(NULL);
|
||||
|
||||
-- different expression types which may not be fast-path queries
|
||||
PREPARE null_select_on_text_param_11(text) AS SELECT count(*) FROM text_dist_column WHERE (CASE WHEN key > $1 THEN key::int / 100 > 1 ELSE false END);
|
||||
EXECUTE null_select_on_text_param_11(NULL);
|
||||
EXECUTE null_select_on_text_param_11(NULL);
|
||||
EXECUTE null_select_on_text_param_11(NULL);
|
||||
EXECUTE null_select_on_text_param_11(NULL);
|
||||
EXECUTE null_select_on_text_param_11(NULL);
|
||||
EXECUTE null_select_on_text_param_11(NULL);
|
||||
EXECUTE null_select_on_text_param_11(NULL);
|
||||
EXECUTE null_select_on_text_param_11(NULL);
|
||||
|
||||
-- different expression types which may not be fast-path queries
|
||||
PREPARE null_select_on_text_param_12(text) AS SELECT count(*) FROM text_dist_column WHERE COALESCE(($1::int/50000)::bool, false);
|
||||
|
||||
EXECUTE null_select_on_text_param_12(NULL);
|
||||
EXECUTE null_select_on_text_param_12(NULL);
|
||||
EXECUTE null_select_on_text_param_12(NULL);
|
||||
EXECUTE null_select_on_text_param_12(NULL);
|
||||
EXECUTE null_select_on_text_param_12(NULL);
|
||||
EXECUTE null_select_on_text_param_12(NULL);
|
||||
EXECUTE null_select_on_text_param_12(NULL);
|
||||
|
||||
-- different expression types which may not be fast-path queries
|
||||
PREPARE null_select_on_text_param_13(text) AS SELECT count(*) FROM text_dist_column WHERE NULLIF(($1::int/50000)::bool, false);
|
||||
|
||||
EXECUTE null_select_on_text_param_13(NULL);
|
||||
EXECUTE null_select_on_text_param_13(NULL);
|
||||
EXECUTE null_select_on_text_param_13(NULL);
|
||||
EXECUTE null_select_on_text_param_13(NULL);
|
||||
EXECUTE null_select_on_text_param_13(NULL);
|
||||
EXECUTE null_select_on_text_param_13(NULL);
|
||||
EXECUTE null_select_on_text_param_13(NULL);
|
||||
|
||||
PREPARE null_select_on_text_param_14(text) AS SELECT count(*) FROM text_dist_column WHERE key = $1 AND 0!=0;
|
||||
EXECUTE null_select_on_text_param_14(NULL);
|
||||
EXECUTE null_select_on_text_param_14(NULL);
|
||||
EXECUTE null_select_on_text_param_14(NULL);
|
||||
EXECUTE null_select_on_text_param_14(NULL);
|
||||
EXECUTE null_select_on_text_param_14(NULL);
|
||||
EXECUTE null_select_on_text_param_14(NULL);
|
||||
EXECUTE null_select_on_text_param_14(NULL);
|
||||
EXECUTE null_select_on_text_param_14(NULL);
|
||||
|
||||
PREPARE null_select_on_text_param_15(text) AS SELECT count(*) FROM text_dist_column WHERE row(key, 100) > row($1, 0);
|
||||
EXECUTE null_select_on_text_param_15(NULL);
|
||||
EXECUTE null_select_on_text_param_15(NULL);
|
||||
EXECUTE null_select_on_text_param_15(NULL);
|
||||
EXECUTE null_select_on_text_param_15(NULL);
|
||||
EXECUTE null_select_on_text_param_15(NULL);
|
||||
EXECUTE null_select_on_text_param_15(NULL);
|
||||
EXECUTE null_select_on_text_param_15(NULL);
|
||||
EXECUTE null_select_on_text_param_15(NULL);
|
||||
|
||||
|
||||
PREPARE null_select_on_text_param_16(text) AS SELECT count(*) FROM text_dist_column WHERE key IS DISTINCT FROM $1;
|
||||
EXECUTE null_select_on_text_param_16(NULL);
|
||||
EXECUTE null_select_on_text_param_16(NULL);
|
||||
EXECUTE null_select_on_text_param_16(NULL);
|
||||
EXECUTE null_select_on_text_param_16(NULL);
|
||||
EXECUTE null_select_on_text_param_16(NULL);
|
||||
EXECUTE null_select_on_text_param_16(NULL);
|
||||
EXECUTE null_select_on_text_param_16(NULL);
|
||||
EXECUTE null_select_on_text_param_16(NULL);
|
||||
|
||||
|
||||
|
||||
PREPARE null_select_on_text_param_17(text) AS SELECT count(*) FROM text_dist_column WHERE key = $1 AND 0!=1;
|
||||
EXECUTE null_select_on_text_param_17(NULL);
|
||||
EXECUTE null_select_on_text_param_17(NULL);
|
||||
EXECUTE null_select_on_text_param_17(NULL);
|
||||
EXECUTE null_select_on_text_param_17(NULL);
|
||||
EXECUTE null_select_on_text_param_17(NULL);
|
||||
EXECUTE null_select_on_text_param_17(NULL);
|
||||
EXECUTE null_select_on_text_param_17(NULL);
|
||||
EXECUTE null_select_on_text_param_17(NULL);
|
||||
|
||||
PREPARE null_select_on_text_param_18(text) AS SELECT count(*) FROM text_dist_column WHERE key = upper($1);
|
||||
EXECUTE null_select_on_text_param_18(NULL);
|
||||
EXECUTE null_select_on_text_param_18(NULL);
|
||||
EXECUTE null_select_on_text_param_18(NULL);
|
||||
EXECUTE null_select_on_text_param_18(NULL);
|
||||
EXECUTE null_select_on_text_param_18(NULL);
|
||||
EXECUTE null_select_on_text_param_18(NULL);
|
||||
EXECUTE null_select_on_text_param_18(NULL);
|
||||
|
||||
PREPARE null_select_on_text_param_19(text) AS SELECT count(*) FROM text_dist_column WHERE key = $1::varchar(4);
|
||||
EXECUTE null_select_on_text_param_19(NULL);
|
||||
EXECUTE null_select_on_text_param_19(NULL);
|
||||
EXECUTE null_select_on_text_param_19(NULL);
|
||||
EXECUTE null_select_on_text_param_19(NULL);
|
||||
EXECUTE null_select_on_text_param_19(NULL);
|
||||
EXECUTE null_select_on_text_param_19(NULL);
|
||||
EXECUTE null_select_on_text_param_19(NULL);
|
||||
|
||||
|
||||
PREPARE null_update_on_text AS UPDATE text_dist_column SET value = '' WHERE key = NULL;
|
||||
EXECUTE null_update_on_text(NULL);
|
||||
EXECUTE null_update_on_text(NULL);
|
||||
EXECUTE null_update_on_text(NULL);
|
||||
EXECUTE null_update_on_text(NULL);
|
||||
EXECUTE null_update_on_text(NULL);
|
||||
EXECUTE null_update_on_text(NULL);
|
||||
|
||||
|
||||
PREPARE null_update_on_text_param(text) AS UPDATE text_dist_column SET value = '' WHERE key = $1;
|
||||
EXECUTE null_update_on_text_param(NULL);
|
||||
EXECUTE null_update_on_text_param(NULL);
|
||||
EXECUTE null_update_on_text_param(NULL);
|
||||
EXECUTE null_update_on_text_param(NULL);
|
||||
EXECUTE null_update_on_text_param(NULL);
|
||||
EXECUTE null_update_on_text_param(NULL);
|
||||
EXECUTE null_update_on_text_param(NULL);
|
||||
|
||||
|
||||
PREPARE null_update_on_text_param_and_false(text) AS UPDATE text_dist_column SET value = '' WHERE key = $1 AND false;
|
||||
EXECUTE null_update_on_text_param_and_false(NULL);
|
||||
EXECUTE null_update_on_text_param_and_false(NULL);
|
||||
EXECUTE null_update_on_text_param_and_false(NULL);
|
||||
EXECUTE null_update_on_text_param_and_false(NULL);
|
||||
EXECUTE null_update_on_text_param_and_false(NULL);
|
||||
EXECUTE null_update_on_text_param_and_false(NULL);
|
||||
EXECUTE null_update_on_text_param_and_false(NULL);
|
||||
|
||||
|
||||
|
||||
PREPARE null_update_on_text_param_and_in(text) AS UPDATE text_dist_column SET value = '' WHERE key IN ($1);
|
||||
EXECUTE null_update_on_text_param_and_in(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in(NULL);
|
||||
|
||||
|
||||
|
||||
PREPARE null_update_on_text_param_and_in_2(text) AS UPDATE text_dist_column SET value = '' WHERE key IN ($1, 'test');
|
||||
EXECUTE null_update_on_text_param_and_in_2(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_2(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_2(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_2(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_2(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_2(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_2(NULL);
|
||||
|
||||
|
||||
PREPARE null_update_on_text_param_and_in_3(text, text) AS UPDATE text_dist_column SET value = '' WHERE key IN ($1, $2);
|
||||
EXECUTE null_update_on_text_param_and_in_3(NULL, NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_3(NULL, NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_3(NULL, NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_3(NULL, NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_3(NULL, NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_3(NULL, NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_3(NULL, 'test');
|
||||
|
||||
PREPARE null_update_on_text_param_and_in_4(text) AS UPDATE text_dist_column SET value = '' WHERE key IN ($1) and false;
|
||||
EXECUTE null_update_on_text_param_and_in_4(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_4(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_4(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_4(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_4(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_4(NULL);
|
||||
EXECUTE null_update_on_text_param_and_in_4(NULL);
|
||||
|
||||
-- sanity check with JSBONB column
|
||||
CREATE TABLE jsonb_dist_column (key jsonb, value text);
|
||||
SELECT create_distributed_table('jsonb_dist_column', 'key');
|
||||
PREPARE null_select_on_json_param(jsonb) AS SELECT count(*) FROM jsonb_dist_column WHERE key = $1;
|
||||
EXECUTE null_select_on_json_param(NULL);
|
||||
EXECUTE null_select_on_json_param(NULL);
|
||||
EXECUTE null_select_on_json_param(NULL);
|
||||
EXECUTE null_select_on_json_param(NULL);
|
||||
EXECUTE null_select_on_json_param(NULL);
|
||||
EXECUTE null_select_on_json_param(NULL);
|
||||
EXECUTE null_select_on_json_param(NULL);
|
||||
|
||||
SET client_min_messages TO ERROR;
|
||||
DROP SCHEMA null_parameters CASCADE;
|
Loading…
Reference in New Issue