mirror of https://github.com/citusdata/citus.git
Detect vars referencing outer queries in local-dist table
We were checking just range table list to detect local-dist table joins but there can be vars referencing to outer queries which belong to a distributed table. The current logic is we keep track of rtable list when we are descending in the query tree. At any level, we find the range table entries that are references by the vars of the current subquery. Then we use this to determine if we should convert local-distributed tables to a subquery.pull/4470/head
parent
75c533ca02
commit
69f4b0f297
|
@ -355,27 +355,6 @@ AllRangeTableEntriesHaveUniqueIndex(List *rangeTableEntryDetailsList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ShouldConvertLocalTableJoinsToSubqueries returns true if we should
|
|
||||||
* convert local-dist table joins to subqueries.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
ShouldConvertLocalTableJoinsToSubqueries(List *rangeTableList)
|
|
||||||
{
|
|
||||||
if (LocalTableJoinPolicy == LOCAL_JOIN_POLICY_NEVER)
|
|
||||||
{
|
|
||||||
/* user doesn't want Citus to enable local table joins */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ContainsLocalTableDistributedTableJoin(rangeTableList))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HasConstantFilterOnUniqueColumn returns true if the given rangeTableEntry has a constant
|
* HasConstantFilterOnUniqueColumn returns true if the given rangeTableEntry has a constant
|
||||||
* filter on a unique column.
|
* filter on a unique column.
|
||||||
|
|
|
@ -920,7 +920,7 @@ ModifyQuerySupported(Query *queryTree, Query *originalQuery, bool multiShardQuer
|
||||||
ExtractRangeTableEntryWalker((Node *) originalQuery, &rangeTableList);
|
ExtractRangeTableEntryWalker((Node *) originalQuery, &rangeTableList);
|
||||||
}
|
}
|
||||||
bool containsLocalTableDistributedTableJoin =
|
bool containsLocalTableDistributedTableJoin =
|
||||||
ContainsLocalTableDistributedTableJoin(queryTree->rtable);
|
ContainsLocalTableDistributedTableJoin(queryTree->rtable, NULL, NULL);
|
||||||
|
|
||||||
RangeTblEntry *rangeTableEntry = NULL;
|
RangeTblEntry *rangeTableEntry = NULL;
|
||||||
foreach_ptr(rangeTableEntry, rangeTableList)
|
foreach_ptr(rangeTableEntry, rangeTableList)
|
||||||
|
|
|
@ -74,6 +74,7 @@
|
||||||
#include "distributed/relation_restriction_equivalence.h"
|
#include "distributed/relation_restriction_equivalence.h"
|
||||||
#include "distributed/log_utils.h"
|
#include "distributed/log_utils.h"
|
||||||
#include "distributed/shard_pruning.h"
|
#include "distributed/shard_pruning.h"
|
||||||
|
#include "distributed/var_utils.h"
|
||||||
#include "distributed/version_compat.h"
|
#include "distributed/version_compat.h"
|
||||||
#include "lib/stringinfo.h"
|
#include "lib/stringinfo.h"
|
||||||
#include "optimizer/clauses.h"
|
#include "optimizer/clauses.h"
|
||||||
|
@ -111,6 +112,7 @@ struct RecursivePlanningContextInternal
|
||||||
uint64 planId;
|
uint64 planId;
|
||||||
bool allDistributionKeysInQueryAreEqual; /* used for some optimizations */
|
bool allDistributionKeysInQueryAreEqual; /* used for some optimizations */
|
||||||
List *subPlanList;
|
List *subPlanList;
|
||||||
|
List *rtableList; /* list of rtables */
|
||||||
PlannerRestrictionContext *plannerRestrictionContext;
|
PlannerRestrictionContext *plannerRestrictionContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -144,6 +146,9 @@ static DeferredErrorMessage * RecursivelyPlanSubqueriesAndCTEs(Query *query,
|
||||||
static bool ShouldRecursivelyPlanNonColocatedSubqueries(Query *subquery,
|
static bool ShouldRecursivelyPlanNonColocatedSubqueries(Query *subquery,
|
||||||
RecursivePlanningContext *
|
RecursivePlanningContext *
|
||||||
context);
|
context);
|
||||||
|
static bool ShouldConvertLocalTableJoinsToSubqueries(List *rangeTableList,
|
||||||
|
List *tableList, List *rtableList);
|
||||||
|
|
||||||
static bool ContainsSubquery(Query *query);
|
static bool ContainsSubquery(Query *query);
|
||||||
static void RecursivelyPlanNonColocatedSubqueries(Query *subquery,
|
static void RecursivelyPlanNonColocatedSubqueries(Query *subquery,
|
||||||
RecursivePlanningContext *context);
|
RecursivePlanningContext *context);
|
||||||
|
@ -195,6 +200,9 @@ static Query * CreateOuterSubquery(RangeTblEntry *rangeTableEntry,
|
||||||
List *outerSubqueryTargetList);
|
List *outerSubqueryTargetList);
|
||||||
static List * GenerateRequiredColNamesFromTargetList(List *targetList);
|
static List * GenerateRequiredColNamesFromTargetList(List *targetList);
|
||||||
static char * GetRelationNameAndAliasName(RangeTblEntry *rangeTablentry);
|
static char * GetRelationNameAndAliasName(RangeTblEntry *rangeTablentry);
|
||||||
|
static void ContainsLocalTableDistributedTableVars(List *tableList, List *rtableList,
|
||||||
|
bool *containsLocalTable,
|
||||||
|
bool *containsDistributedTable);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GenerateSubplansForSubqueriesAndCTEs is a wrapper around RecursivelyPlanSubqueriesAndCTEs.
|
* GenerateSubplansForSubqueriesAndCTEs is a wrapper around RecursivelyPlanSubqueriesAndCTEs.
|
||||||
|
@ -219,6 +227,7 @@ GenerateSubplansForSubqueriesAndCTEs(uint64 planId, Query *originalQuery,
|
||||||
context.planId = planId;
|
context.planId = planId;
|
||||||
context.subPlanList = NIL;
|
context.subPlanList = NIL;
|
||||||
context.plannerRestrictionContext = plannerRestrictionContext;
|
context.plannerRestrictionContext = plannerRestrictionContext;
|
||||||
|
context.rtableList = NIL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculating the distribution key equality upfront is a trade-off for us.
|
* Calculating the distribution key equality upfront is a trade-off for us.
|
||||||
|
@ -276,6 +285,8 @@ GenerateSubplansForSubqueriesAndCTEs(uint64 planId, Query *originalQuery,
|
||||||
static DeferredErrorMessage *
|
static DeferredErrorMessage *
|
||||||
RecursivelyPlanSubqueriesAndCTEs(Query *query, RecursivePlanningContext *context)
|
RecursivelyPlanSubqueriesAndCTEs(Query *query, RecursivePlanningContext *context)
|
||||||
{
|
{
|
||||||
|
context->rtableList = lcons(query->rtable, context->rtableList);
|
||||||
|
|
||||||
DeferredErrorMessage *error = RecursivelyPlanCTEs(query, context);
|
DeferredErrorMessage *error = RecursivelyPlanCTEs(query, context);
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
{
|
{
|
||||||
|
@ -350,8 +361,9 @@ RecursivelyPlanSubqueriesAndCTEs(Query *query, RecursivePlanningContext *context
|
||||||
RecursivelyPlanNonColocatedSubqueries(query, context);
|
RecursivelyPlanNonColocatedSubqueries(query, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List *tableList = PullAllRangeTablesEntries(query, context->rtableList);
|
||||||
if (ShouldConvertLocalTableJoinsToSubqueries(query->rtable))
|
if (ShouldConvertLocalTableJoinsToSubqueries(query->rtable, tableList,
|
||||||
|
context->rtableList))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Logical planner cannot handle "local_table" [OUTER] JOIN "dist_table", or
|
* Logical planner cannot handle "local_table" [OUTER] JOIN "dist_table", or
|
||||||
|
@ -361,11 +373,64 @@ RecursivelyPlanSubqueriesAndCTEs(Query *query, RecursivePlanningContext *context
|
||||||
RecursivelyPlanLocalTableJoins(query, context);
|
RecursivelyPlanLocalTableJoins(query, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context->rtableList = list_delete_first(context->rtableList);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ShouldConvertLocalTableJoinsToSubqueries returns true if we should
|
||||||
|
* convert local-dist table joins to subqueries.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
ShouldConvertLocalTableJoinsToSubqueries(List *rangeTableList, List *tableList,
|
||||||
|
List *rtableList)
|
||||||
|
{
|
||||||
|
if (LocalTableJoinPolicy == LOCAL_JOIN_POLICY_NEVER)
|
||||||
|
{
|
||||||
|
/* user doesn't want Citus to enable local table joins */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool containsDistributedTable = false;
|
||||||
|
bool containsLocalTable = false;
|
||||||
|
|
||||||
|
if (ContainsLocalTableDistributedTableJoin(rangeTableList, &containsLocalTable,
|
||||||
|
&containsDistributedTable))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we have vars that references local or distributed tables, it means we need to do subquery-conversion */
|
||||||
|
ContainsLocalTableDistributedTableVars(tableList, rtableList, &containsLocalTable,
|
||||||
|
&containsDistributedTable);
|
||||||
|
|
||||||
|
return containsDistributedTable && containsLocalTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ContainsLocalTableDistributedTableVars(List *tableList, List *rtableList,
|
||||||
|
bool *containsLocalTable,
|
||||||
|
bool *containsDistributedTable)
|
||||||
|
{
|
||||||
|
RangeTblEntry *rte = NULL;
|
||||||
|
foreach_ptr(rte, tableList)
|
||||||
|
{
|
||||||
|
if (IsDistributedOrReferenceTableRTE((Node *) rte))
|
||||||
|
{
|
||||||
|
*containsDistributedTable = true;
|
||||||
|
}
|
||||||
|
else if (IsRecursivelyPlannableRelation(rte) &&
|
||||||
|
IsLocalTableRteOrMatView((Node *) rte))
|
||||||
|
{
|
||||||
|
/* we consider citus local tables as local table */
|
||||||
|
*containsLocalTable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetPlannerRestrictionContext returns the planner restriction context
|
* GetPlannerRestrictionContext returns the planner restriction context
|
||||||
* from the given context.
|
* from the given context.
|
||||||
|
@ -1576,7 +1641,8 @@ IsRecursivelyPlannableRelation(RangeTblEntry *rangeTableEntry)
|
||||||
* or reference table.
|
* or reference table.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
ContainsLocalTableDistributedTableJoin(List *rangeTableList)
|
ContainsLocalTableDistributedTableJoin(List *rangeTableList, bool *containsLocalTableOut,
|
||||||
|
bool *containsDistributedTableOut)
|
||||||
{
|
{
|
||||||
bool containsLocalTable = false;
|
bool containsLocalTable = false;
|
||||||
bool containsDistributedTable = false;
|
bool containsDistributedTable = false;
|
||||||
|
@ -1596,7 +1662,14 @@ ContainsLocalTableDistributedTableJoin(List *rangeTableList)
|
||||||
containsLocalTable = true;
|
containsLocalTable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (containsLocalTableOut)
|
||||||
|
{
|
||||||
|
*containsLocalTableOut = containsLocalTable;
|
||||||
|
}
|
||||||
|
if (containsDistributedTableOut)
|
||||||
|
{
|
||||||
|
*containsDistributedTableOut = containsDistributedTable;
|
||||||
|
}
|
||||||
return containsLocalTable && containsDistributedTable;
|
return containsLocalTable && containsDistributedTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* var_utils.c
|
||||||
|
* Utilities regarding vars
|
||||||
|
*
|
||||||
|
* Copyright (c) Citus Data, Inc.
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "distributed/pg_version_constants.h"
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "distributed/var_utils.h"
|
||||||
|
|
||||||
|
#include "parser/parsetree.h"
|
||||||
|
#include "nodes/makefuncs.h"
|
||||||
|
#include "nodes/nodeFuncs.h"
|
||||||
|
#include "nodes/nodes.h"
|
||||||
|
#include "nodes/nodeFuncs.h"
|
||||||
|
#include "nodes/pg_list.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/guc.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "nodes/primnodes.h"
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_12
|
||||||
|
#include "nodes/pathnodes.h"
|
||||||
|
#else
|
||||||
|
#include "nodes/relation.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct PullTableContext
|
||||||
|
{
|
||||||
|
List *rteList;
|
||||||
|
List *rtableList;
|
||||||
|
}PullTableContext;
|
||||||
|
|
||||||
|
|
||||||
|
static bool PullAllRangeTablesEntriesWalker(Node *node,
|
||||||
|
PullTableContext *pullTableContext);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PullAllRangeTablesEntries collects all the range table entries that are referenced
|
||||||
|
* in the given query. The range table entry could be outside of the given query but a var
|
||||||
|
* could exist that points to it.
|
||||||
|
* rtableList should contain list of rtables up to this query from the top query.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
PullAllRangeTablesEntries(Query *query, List *rtableList)
|
||||||
|
{
|
||||||
|
PullTableContext p;
|
||||||
|
p.rtableList = rtableList;
|
||||||
|
p.rteList = NIL;
|
||||||
|
|
||||||
|
query_or_expression_tree_walker((Node *) query,
|
||||||
|
PullAllRangeTablesEntriesWalker,
|
||||||
|
(void *) &p,
|
||||||
|
0);
|
||||||
|
|
||||||
|
return p.rteList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PullAllRangeTablesEntriesWalker descends into the given node and collects
|
||||||
|
* all range table entries that are referenced by a Var.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
PullAllRangeTablesEntriesWalker(Node *node, PullTableContext *pullTableContext)
|
||||||
|
{
|
||||||
|
if (node == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (IsA(node, Var))
|
||||||
|
{
|
||||||
|
Var *var = (Var *) node;
|
||||||
|
|
||||||
|
List *rtableList = pullTableContext->rtableList;
|
||||||
|
int index = var->varlevelsup;
|
||||||
|
if (index >= list_length(rtableList) || index < 0)
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errmsg("unexpected state: %d is not between 0-%d", index,
|
||||||
|
list_length(rtableList))));
|
||||||
|
}
|
||||||
|
List *rtable = (List *) list_nth(rtableList, index);
|
||||||
|
RangeTblEntry *rte = (RangeTblEntry *) list_nth(rtable, var->varno - 1);
|
||||||
|
pullTableContext->rteList = lappend(pullTableContext->rteList, rte);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (IsA(node, PlaceHolderVar))
|
||||||
|
{
|
||||||
|
/* PlaceHolderVar *phv = (PlaceHolderVar *) node; */
|
||||||
|
|
||||||
|
/* we don't want to look into the contained expression */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (IsA(node, Query))
|
||||||
|
{
|
||||||
|
/* Recurse into RTE subquery or not-yet-planned sublink subquery */
|
||||||
|
|
||||||
|
Query *query = (Query *) node;
|
||||||
|
pullTableContext->rtableList = lcons(query->rtable, pullTableContext->rtableList);
|
||||||
|
bool result = query_tree_walker(query, PullAllRangeTablesEntriesWalker,
|
||||||
|
(void *) pullTableContext, 0);
|
||||||
|
pullTableContext->rtableList = list_delete_first(pullTableContext->rtableList);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return expression_tree_walker(node, PullAllRangeTablesEntriesWalker,
|
||||||
|
(void *) pullTableContext);
|
||||||
|
}
|
|
@ -27,7 +27,6 @@ typedef enum
|
||||||
|
|
||||||
extern int LocalTableJoinPolicy;
|
extern int LocalTableJoinPolicy;
|
||||||
|
|
||||||
extern bool ShouldConvertLocalTableJoinsToSubqueries(List *rangeTableList);
|
|
||||||
extern void RecursivelyPlanLocalTableJoins(Query *query,
|
extern void RecursivelyPlanLocalTableJoins(Query *query,
|
||||||
RecursivePlanningContext *context);
|
RecursivePlanningContext *context);
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,9 @@ extern Query * BuildReadIntermediateResultsArrayQuery(List *targetEntryList,
|
||||||
List *resultIdList,
|
List *resultIdList,
|
||||||
bool useBinaryCopyFormat);
|
bool useBinaryCopyFormat);
|
||||||
extern bool GeneratingSubplans(void);
|
extern bool GeneratingSubplans(void);
|
||||||
extern bool ContainsLocalTableDistributedTableJoin(List *rangeTableList);
|
extern bool ContainsLocalTableDistributedTableJoin(List *rangeTableList,
|
||||||
|
bool *containsLocalTableOut,
|
||||||
|
bool *containsDistributedTableOut);
|
||||||
extern void ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry,
|
extern void ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry,
|
||||||
List *requiredAttrNumbers,
|
List *requiredAttrNumbers,
|
||||||
RecursivePlanningContext *context);
|
RecursivePlanningContext *context);
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* var_utils.h
|
||||||
|
* Utilities regarding vars
|
||||||
|
*
|
||||||
|
* Copyright (c) Citus Data, Inc.
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef VAR_UTILS
|
||||||
|
#define VAR_UTILS
|
||||||
|
#include "nodes/pg_list.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
|
||||||
|
List * PullAllRangeTablesEntries(Query *query, List *rtableList);
|
||||||
|
#endif
|
|
@ -0,0 +1,285 @@
|
||||||
|
CREATE SCHEMA local_table_join_vars;
|
||||||
|
SET search_path TO local_table_join_vars;
|
||||||
|
SET client_min_messages to ERROR;
|
||||||
|
SELECT master_add_node('localhost', :master_port, groupId => 0) AS coordinator_nodeid \gset
|
||||||
|
SET client_min_messages TO DEBUG1;
|
||||||
|
CREATE TABLE postgres_table (key int, value text, value_2 jsonb);
|
||||||
|
CREATE TABLE reference_table (key int, value text, value_2 jsonb);
|
||||||
|
SELECT create_reference_table('reference_table');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE distributed_table (key int, value text, value_2 jsonb);
|
||||||
|
SELECT create_distributed_table('distributed_table', 'key');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE distributed_table_pkey (key int primary key, value text, value_2 jsonb);
|
||||||
|
DEBUG: CREATE TABLE / PRIMARY KEY will create implicit index "distributed_table_pkey_pkey" for table "distributed_table_pkey"
|
||||||
|
SELECT create_distributed_table('distributed_table_pkey', 'key');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE distributed_table_windex (key int primary key, value text, value_2 jsonb);
|
||||||
|
DEBUG: CREATE TABLE / PRIMARY KEY will create implicit index "distributed_table_windex_pkey" for table "distributed_table_windex"
|
||||||
|
SELECT create_distributed_table('distributed_table_windex', 'key');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX key_index ON distributed_table_windex (key);
|
||||||
|
CREATE TABLE citus_local(key int, value text);
|
||||||
|
SELECT create_citus_local_table('citus_local');
|
||||||
|
create_citus_local_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE distributed_partitioned_table(key int, value text) PARTITION BY RANGE (key);
|
||||||
|
CREATE TABLE distributed_partitioned_table_1 PARTITION OF distributed_partitioned_table FOR VALUES FROM (0) TO (50);
|
||||||
|
CREATE TABLE distributed_partitioned_table_2 PARTITION OF distributed_partitioned_table FOR VALUES FROM (50) TO (200);
|
||||||
|
SELECT create_distributed_table('distributed_partitioned_table', 'key');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE local_partitioned_table(key int, value text) PARTITION BY RANGE (key);
|
||||||
|
CREATE TABLE local_partitioned_table_1 PARTITION OF local_partitioned_table FOR VALUES FROM (0) TO (50);
|
||||||
|
CREATE TABLE local_partitioned_table_2 PARTITION OF local_partitioned_table FOR VALUES FROM (50) TO (200);
|
||||||
|
CREATE TABLE distributed_table_composite (key int, value text, value_2 jsonb, primary key (key, value));
|
||||||
|
DEBUG: CREATE TABLE / PRIMARY KEY will create implicit index "distributed_table_composite_pkey" for table "distributed_table_composite"
|
||||||
|
SELECT create_distributed_table('distributed_table_composite', 'key');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO postgres_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
INSERT INTO reference_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
||||||
|
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
||||||
|
INSERT INTO distributed_table_windex SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
||||||
|
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
||||||
|
INSERT INTO distributed_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
||||||
|
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
||||||
|
INSERT INTO distributed_table_pkey SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
||||||
|
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
||||||
|
INSERT INTO distributed_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
||||||
|
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
||||||
|
INSERT INTO distributed_table_composite SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
||||||
|
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
||||||
|
INSERT INTO local_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
-- vars referencing outer queries should work in SELECT
|
||||||
|
SELECT (SELECT COUNT(*) FROM postgres_table WHERE postgres_table.key = distributed_table.key) FROM distributed_table ORDER BY 1 LIMIT 1;
|
||||||
|
DEBUG: Wrapping relation "postgres_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.postgres_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (SELECT count(*) AS count FROM (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table WHERE (postgres_table.key OPERATOR(pg_catalog.=) distributed_table.key)) AS count FROM local_table_join_vars.distributed_table ORDER BY (SELECT count(*) AS count FROM (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table WHERE (postgres_table.key OPERATOR(pg_catalog.=) distributed_table.key)) LIMIT 1
|
||||||
|
DEBUG: push down of limit count: 1
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT (SELECT COUNT(*) FROM postgres_table WHERE distributed_table.key = 5) FROM distributed_table ORDER BY 1 LIMIT 1;
|
||||||
|
DEBUG: Wrapping relation "postgres_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS "dummy-1" FROM local_table_join_vars.postgres_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (SELECT count(*) AS count FROM (SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) postgres_table_1) postgres_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) 5)) AS count FROM local_table_join_vars.distributed_table ORDER BY (SELECT count(*) AS count FROM (SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) postgres_table_1) postgres_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) 5)) LIMIT 1
|
||||||
|
DEBUG: push down of limit count: 1
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT (SELECT COUNT(*) FROM distributed_table WHERE postgres_table.key = 5) FROM postgres_table ORDER BY 1 LIMIT 1;
|
||||||
|
DEBUG: Wrapping relation "distributed_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS "dummy-1" FROM local_table_join_vars.distributed_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (SELECT count(*) AS count FROM (SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) distributed_table_1) distributed_table WHERE (postgres_table.key OPERATOR(pg_catalog.=) 5)) AS count FROM local_table_join_vars.postgres_table ORDER BY (SELECT count(*) AS count FROM (SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) distributed_table_1) distributed_table WHERE (postgres_table.key OPERATOR(pg_catalog.=) 5)) LIMIT 1
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT (SELECT COUNT(*) FROM distributed_table WHERE postgres_table.key = distributed_table.key) FROM postgres_table ORDER BY 1 LIMIT 1;
|
||||||
|
DEBUG: Wrapping relation "distributed_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.distributed_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (SELECT count(*) AS count FROM (SELECT distributed_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) distributed_table_1) distributed_table WHERE (postgres_table.key OPERATOR(pg_catalog.=) distributed_table.key)) AS count FROM local_table_join_vars.postgres_table ORDER BY (SELECT count(*) AS count FROM (SELECT distributed_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) distributed_table_1) distributed_table WHERE (postgres_table.key OPERATOR(pg_catalog.=) distributed_table.key)) LIMIT 1
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- vars referencing outer queries should work in SELECT with citus local tables
|
||||||
|
SELECT (SELECT COUNT(*) FROM citus_local WHERE citus_local.key = distributed_table.key) FROM distributed_table ORDER BY 1 LIMIT 1;
|
||||||
|
DEBUG: Wrapping relation "citus_local" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.citus_local WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (SELECT count(*) AS count FROM (SELECT citus_local_1.key, NULL::text AS value FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) citus_local_1) citus_local WHERE (citus_local.key OPERATOR(pg_catalog.=) distributed_table.key)) AS count FROM local_table_join_vars.distributed_table ORDER BY (SELECT count(*) AS count FROM (SELECT citus_local_1.key, NULL::text AS value FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) citus_local_1) citus_local WHERE (citus_local.key OPERATOR(pg_catalog.=) distributed_table.key)) LIMIT 1
|
||||||
|
DEBUG: push down of limit count: 1
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT (SELECT COUNT(*) FROM citus_local WHERE distributed_table.key = 5) FROM distributed_table ORDER BY 1 LIMIT 1;
|
||||||
|
DEBUG: Wrapping relation "citus_local" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS "dummy-1" FROM local_table_join_vars.citus_local WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (SELECT count(*) AS count FROM (SELECT NULL::integer AS key, NULL::text AS value FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) citus_local_1) citus_local WHERE (distributed_table.key OPERATOR(pg_catalog.=) 5)) AS count FROM local_table_join_vars.distributed_table ORDER BY (SELECT count(*) AS count FROM (SELECT NULL::integer AS key, NULL::text AS value FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) citus_local_1) citus_local WHERE (distributed_table.key OPERATOR(pg_catalog.=) 5)) LIMIT 1
|
||||||
|
DEBUG: push down of limit count: 1
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT (SELECT COUNT(*) FROM distributed_table WHERE citus_local.key = 5) FROM citus_local ORDER BY 1 LIMIT 1;
|
||||||
|
DEBUG: Wrapping relation "distributed_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS "dummy-1" FROM local_table_join_vars.distributed_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (SELECT count(*) AS count FROM (SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) distributed_table_1) distributed_table WHERE (citus_local.key OPERATOR(pg_catalog.=) 5)) AS count FROM local_table_join_vars.citus_local ORDER BY (SELECT count(*) AS count FROM (SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) distributed_table_1) distributed_table WHERE (citus_local.key OPERATOR(pg_catalog.=) 5)) LIMIT 1
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT (SELECT COUNT(*) FROM distributed_table WHERE citus_local.key = distributed_table.key) FROM citus_local ORDER BY 1 LIMIT 1;
|
||||||
|
DEBUG: Wrapping relation "distributed_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.distributed_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (SELECT count(*) AS count FROM (SELECT distributed_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) distributed_table_1) distributed_table WHERE (citus_local.key OPERATOR(pg_catalog.=) distributed_table.key)) AS count FROM local_table_join_vars.citus_local ORDER BY (SELECT count(*) AS count FROM (SELECT distributed_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) distributed_table_1) distributed_table WHERE (citus_local.key OPERATOR(pg_catalog.=) distributed_table.key)) LIMIT 1
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
-- vars referencing outer queries should work in WHERE
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM postgres_table WHERE key > distributed_table.key);
|
||||||
|
DEBUG: Wrapping relation "postgres_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.postgres_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_table_join_vars.distributed_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT postgres_table.key FROM (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table WHERE (postgres_table.key OPERATOR(pg_catalog.>) distributed_table.key)))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT COUNT(*) FROM postgres_table WHERE key in (SELECT key FROM distributed_table WHERE key > postgres_table.key);
|
||||||
|
DEBUG: Wrapping relation "distributed_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.distributed_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_table_join_vars.postgres_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM (SELECT distributed_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) distributed_table_1) distributed_table WHERE (distributed_table.key OPERATOR(pg_catalog.>) postgres_table.key)))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT COUNT(*) FROM postgres_table WHERE key in (SELECT key FROM distributed_table WHERE postgres_table.key > 5);
|
||||||
|
DEBUG: Wrapping relation "distributed_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.distributed_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_table_join_vars.postgres_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM (SELECT distributed_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) distributed_table_1) distributed_table WHERE (postgres_table.key OPERATOR(pg_catalog.>) 5)))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
95
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM postgres_table WHERE distributed_table.key > 5);
|
||||||
|
DEBUG: Wrapping relation "postgres_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.postgres_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_table_join_vars.distributed_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT postgres_table.key FROM (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table WHERE (distributed_table.key OPERATOR(pg_catalog.>) 5)))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
95
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- vars referencing outer queries should work in WHERE with citus local tables
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM citus_local WHERE key > distributed_table.key);
|
||||||
|
DEBUG: Wrapping relation "citus_local" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.citus_local WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_table_join_vars.distributed_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT citus_local.key FROM (SELECT citus_local_1.key, NULL::text AS value FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) citus_local_1) citus_local WHERE (citus_local.key OPERATOR(pg_catalog.>) distributed_table.key)))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT COUNT(*) FROM citus_local WHERE key in (SELECT key FROM distributed_table WHERE key > citus_local.key);
|
||||||
|
DEBUG: Wrapping relation "distributed_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.distributed_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_table_join_vars.citus_local WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM (SELECT distributed_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) distributed_table_1) distributed_table WHERE (distributed_table.key OPERATOR(pg_catalog.>) citus_local.key)))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT COUNT(*) FROM citus_local WHERE key in (SELECT key FROM distributed_table WHERE citus_local.key > 5);
|
||||||
|
DEBUG: Wrapping relation "distributed_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.distributed_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_table_join_vars.citus_local WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM (SELECT distributed_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) distributed_table_1) distributed_table WHERE (citus_local.key OPERATOR(pg_catalog.>) 5)))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM citus_local WHERE distributed_table.key > 5);
|
||||||
|
DEBUG: Wrapping relation "citus_local" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.citus_local WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_table_join_vars.distributed_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT citus_local.key FROM (SELECT citus_local_1.key, NULL::text AS value FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) citus_local_1) citus_local WHERE (distributed_table.key OPERATOR(pg_catalog.>) 5)))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- citus-local, local and dist should work
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM citus_local JOIN postgres_table USING(key) WHERE key > distributed_table.key);
|
||||||
|
DEBUG: Wrapping relation "citus_local" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.citus_local WHERE true
|
||||||
|
DEBUG: Wrapping relation "postgres_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_2 for subquery SELECT key FROM local_table_join_vars.postgres_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_table_join_vars.distributed_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT citus_local.key FROM ((SELECT citus_local_1.key, NULL::text AS value FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) citus_local_1) citus_local JOIN (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table USING (key)) WHERE (citus_local.key OPERATOR(pg_catalog.>) distributed_table.key)))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Will work when we fix "correlated subqueries are not supported when the FROM clause contains a CTE or subquery"
|
||||||
|
SELECT COUNT(*) FROM citus_local WHERE key in (SELECT key FROM distributed_table JOIN postgres_table USING(key) WHERE key > citus_local.key);
|
||||||
|
DEBUG: Wrapping relation "postgres_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.postgres_table WHERE true
|
||||||
|
DEBUG: Wrapping relation "citus_local" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_2 for subquery SELECT key FROM local_table_join_vars.citus_local WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT citus_local_1.key, NULL::text AS value FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) citus_local_1) citus_local WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM (local_table_join_vars.distributed_table JOIN (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table USING (key)) WHERE (distributed_table.key OPERATOR(pg_catalog.>) citus_local.key)))
|
||||||
|
ERROR: correlated subqueries are not supported when the FROM clause contains a CTE or subquery
|
||||||
|
-- Will work when we fix "correlated subqueries are not supported when the FROM clause contains a CTE or subquery"
|
||||||
|
SELECT COUNT(*) FROM citus_local WHERE key in (SELECT key FROM distributed_table JOIN postgres_table USING(key) WHERE citus_local.key > 5);
|
||||||
|
DEBUG: Wrapping relation "postgres_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.postgres_table WHERE true
|
||||||
|
DEBUG: Wrapping relation "citus_local" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_2 for subquery SELECT key FROM local_table_join_vars.citus_local WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT citus_local_1.key, NULL::text AS value FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) citus_local_1) citus_local WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT distributed_table.key FROM (local_table_join_vars.distributed_table JOIN (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table USING (key)) WHERE (citus_local.key OPERATOR(pg_catalog.>) 5)))
|
||||||
|
ERROR: correlated subqueries are not supported when the FROM clause contains a CTE or subquery
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM citus_local JOIN postgres_table USING(key) WHERE distributed_table.key > 5);
|
||||||
|
DEBUG: Wrapping relation "citus_local" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.citus_local WHERE true
|
||||||
|
DEBUG: Wrapping relation "postgres_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_2 for subquery SELECT key FROM local_table_join_vars.postgres_table WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_table_join_vars.distributed_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT citus_local.key FROM ((SELECT citus_local_1.key, NULL::text AS value FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) citus_local_1) citus_local JOIN (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table USING (key)) WHERE (distributed_table.key OPERATOR(pg_catalog.>) 5)))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Will work when we fix "correlated subqueries are not supported when the FROM clause contains a CTE or subquery"
|
||||||
|
SELECT (SELECT (SELECT COUNT(*) FROM postgres_table WHERE postgres_table.key = distributed_table.key) FROM postgres_table p2) FROM distributed_table;
|
||||||
|
DEBUG: Wrapping relation "postgres_table" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key FROM local_table_join_vars.postgres_table WHERE true
|
||||||
|
DEBUG: Wrapping relation "postgres_table" "p2" to a subquery
|
||||||
|
DEBUG: generating subplan XXX_2 for subquery SELECT NULL::integer AS "dummy-1" FROM local_table_join_vars.postgres_table p2 WHERE true
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (SELECT (SELECT count(*) AS count FROM (SELECT postgres_table_1.key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) postgres_table_1) postgres_table WHERE (postgres_table.key OPERATOR(pg_catalog.=) distributed_table.key)) AS count FROM (SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) p2_1) p2) AS count FROM local_table_join_vars.distributed_table
|
||||||
|
ERROR: correlated subqueries are not supported when the FROM clause contains a CTE or subquery
|
||||||
|
RESET client_min_messages;
|
||||||
|
\set VERBOSITY terse
|
||||||
|
DROP SCHEMA local_table_join_vars CASCADE;
|
||||||
|
NOTICE: drop cascades to 11 other objects
|
|
@ -231,6 +231,7 @@ test: local_dist_join_modifications
|
||||||
test: local_table_join
|
test: local_table_join
|
||||||
test: local_dist_join_mixed
|
test: local_dist_join_mixed
|
||||||
test: citus_local_dist_joins
|
test: citus_local_dist_joins
|
||||||
|
test: local_table_join_vars
|
||||||
|
|
||||||
# ---------
|
# ---------
|
||||||
# multi_copy creates hash and range-partitioned tables and performs COPY
|
# multi_copy creates hash and range-partitioned tables and performs COPY
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
CREATE SCHEMA local_table_join_vars;
|
||||||
|
SET search_path TO local_table_join_vars;
|
||||||
|
|
||||||
|
SET client_min_messages to ERROR;
|
||||||
|
SELECT master_add_node('localhost', :master_port, groupId => 0) AS coordinator_nodeid \gset
|
||||||
|
|
||||||
|
SET client_min_messages TO DEBUG1;
|
||||||
|
|
||||||
|
CREATE TABLE postgres_table (key int, value text, value_2 jsonb);
|
||||||
|
CREATE TABLE reference_table (key int, value text, value_2 jsonb);
|
||||||
|
SELECT create_reference_table('reference_table');
|
||||||
|
CREATE TABLE distributed_table (key int, value text, value_2 jsonb);
|
||||||
|
SELECT create_distributed_table('distributed_table', 'key');
|
||||||
|
|
||||||
|
CREATE TABLE distributed_table_pkey (key int primary key, value text, value_2 jsonb);
|
||||||
|
SELECT create_distributed_table('distributed_table_pkey', 'key');
|
||||||
|
|
||||||
|
CREATE TABLE distributed_table_windex (key int primary key, value text, value_2 jsonb);
|
||||||
|
SELECT create_distributed_table('distributed_table_windex', 'key');
|
||||||
|
CREATE UNIQUE INDEX key_index ON distributed_table_windex (key);
|
||||||
|
|
||||||
|
CREATE TABLE citus_local(key int, value text);
|
||||||
|
SELECT create_citus_local_table('citus_local');
|
||||||
|
|
||||||
|
CREATE TABLE distributed_partitioned_table(key int, value text) PARTITION BY RANGE (key);
|
||||||
|
CREATE TABLE distributed_partitioned_table_1 PARTITION OF distributed_partitioned_table FOR VALUES FROM (0) TO (50);
|
||||||
|
CREATE TABLE distributed_partitioned_table_2 PARTITION OF distributed_partitioned_table FOR VALUES FROM (50) TO (200);
|
||||||
|
SELECT create_distributed_table('distributed_partitioned_table', 'key');
|
||||||
|
|
||||||
|
CREATE TABLE local_partitioned_table(key int, value text) PARTITION BY RANGE (key);
|
||||||
|
CREATE TABLE local_partitioned_table_1 PARTITION OF local_partitioned_table FOR VALUES FROM (0) TO (50);
|
||||||
|
CREATE TABLE local_partitioned_table_2 PARTITION OF local_partitioned_table FOR VALUES FROM (50) TO (200);
|
||||||
|
|
||||||
|
CREATE TABLE distributed_table_composite (key int, value text, value_2 jsonb, primary key (key, value));
|
||||||
|
SELECT create_distributed_table('distributed_table_composite', 'key');
|
||||||
|
|
||||||
|
INSERT INTO postgres_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
INSERT INTO reference_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
INSERT INTO distributed_table_windex SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
INSERT INTO distributed_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
INSERT INTO distributed_table_pkey SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
INSERT INTO distributed_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
INSERT INTO distributed_table_composite SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
INSERT INTO local_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i;
|
||||||
|
|
||||||
|
-- vars referencing outer queries should work in SELECT
|
||||||
|
SELECT (SELECT COUNT(*) FROM postgres_table WHERE postgres_table.key = distributed_table.key) FROM distributed_table ORDER BY 1 LIMIT 1;
|
||||||
|
SELECT (SELECT COUNT(*) FROM postgres_table WHERE distributed_table.key = 5) FROM distributed_table ORDER BY 1 LIMIT 1;
|
||||||
|
SELECT (SELECT COUNT(*) FROM distributed_table WHERE postgres_table.key = 5) FROM postgres_table ORDER BY 1 LIMIT 1;
|
||||||
|
SELECT (SELECT COUNT(*) FROM distributed_table WHERE postgres_table.key = distributed_table.key) FROM postgres_table ORDER BY 1 LIMIT 1;
|
||||||
|
|
||||||
|
-- vars referencing outer queries should work in SELECT with citus local tables
|
||||||
|
SELECT (SELECT COUNT(*) FROM citus_local WHERE citus_local.key = distributed_table.key) FROM distributed_table ORDER BY 1 LIMIT 1;
|
||||||
|
SELECT (SELECT COUNT(*) FROM citus_local WHERE distributed_table.key = 5) FROM distributed_table ORDER BY 1 LIMIT 1;
|
||||||
|
SELECT (SELECT COUNT(*) FROM distributed_table WHERE citus_local.key = 5) FROM citus_local ORDER BY 1 LIMIT 1;
|
||||||
|
SELECT (SELECT COUNT(*) FROM distributed_table WHERE citus_local.key = distributed_table.key) FROM citus_local ORDER BY 1 LIMIT 1;
|
||||||
|
|
||||||
|
-- vars referencing outer queries should work in WHERE
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM postgres_table WHERE key > distributed_table.key);
|
||||||
|
SELECT COUNT(*) FROM postgres_table WHERE key in (SELECT key FROM distributed_table WHERE key > postgres_table.key);
|
||||||
|
SELECT COUNT(*) FROM postgres_table WHERE key in (SELECT key FROM distributed_table WHERE postgres_table.key > 5);
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM postgres_table WHERE distributed_table.key > 5);
|
||||||
|
|
||||||
|
-- vars referencing outer queries should work in WHERE with citus local tables
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM citus_local WHERE key > distributed_table.key);
|
||||||
|
SELECT COUNT(*) FROM citus_local WHERE key in (SELECT key FROM distributed_table WHERE key > citus_local.key);
|
||||||
|
SELECT COUNT(*) FROM citus_local WHERE key in (SELECT key FROM distributed_table WHERE citus_local.key > 5);
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM citus_local WHERE distributed_table.key > 5);
|
||||||
|
|
||||||
|
-- citus-local, local and dist should work
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM citus_local JOIN postgres_table USING(key) WHERE key > distributed_table.key);
|
||||||
|
-- Will work when we fix "correlated subqueries are not supported when the FROM clause contains a CTE or subquery"
|
||||||
|
SELECT COUNT(*) FROM citus_local WHERE key in (SELECT key FROM distributed_table JOIN postgres_table USING(key) WHERE key > citus_local.key);
|
||||||
|
-- Will work when we fix "correlated subqueries are not supported when the FROM clause contains a CTE or subquery"
|
||||||
|
SELECT COUNT(*) FROM citus_local WHERE key in (SELECT key FROM distributed_table JOIN postgres_table USING(key) WHERE citus_local.key > 5);
|
||||||
|
SELECT COUNT(*) FROM distributed_table WHERE key in (SELECT key FROM citus_local JOIN postgres_table USING(key) WHERE distributed_table.key > 5);
|
||||||
|
|
||||||
|
-- Will work when we fix "correlated subqueries are not supported when the FROM clause contains a CTE or subquery"
|
||||||
|
SELECT (SELECT (SELECT COUNT(*) FROM postgres_table WHERE postgres_table.key = distributed_table.key) FROM postgres_table p2) FROM distributed_table;
|
||||||
|
|
||||||
|
|
||||||
|
RESET client_min_messages;
|
||||||
|
\set VERBOSITY terse
|
||||||
|
DROP SCHEMA local_table_join_vars CASCADE;
|
Loading…
Reference in New Issue