mirror of https://github.com/citusdata/citus.git
basic geo partitioning planning
parent
ec994a3a9c
commit
bac16a3785
|
@ -97,3 +97,6 @@ UPDATE pg_dist_partition t
|
||||||
AND t.logicalrelid = 'belgium_planet_osm_roads_geo'::regclass;
|
AND t.logicalrelid = 'belgium_planet_osm_roads_geo'::regclass;
|
||||||
DROP TABLE foo;
|
DROP TABLE foo;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
ALTER SYSTEM SET citus.use_custom_path TO on;
|
||||||
|
SELECT pg_reload_conf();
|
||||||
|
|
|
@ -451,6 +451,11 @@ IsCitusTableTypeInternal(char partitionMethod, char replicationModel,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GEO_DISTRIBUTED:
|
||||||
|
{
|
||||||
|
return partitionMethod == DISTRIBUTE_BY_GEO;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errmsg("Unknown table type %d", tableType)));
|
ereport(ERROR, (errmsg("Unknown table type %d", tableType)));
|
||||||
|
@ -4308,6 +4313,7 @@ GetPartitionTypeInputInfo(char *partitionKeyString, char partitionMethod,
|
||||||
case DISTRIBUTE_BY_APPEND:
|
case DISTRIBUTE_BY_APPEND:
|
||||||
case DISTRIBUTE_BY_RANGE:
|
case DISTRIBUTE_BY_RANGE:
|
||||||
case DISTRIBUTE_BY_HASH:
|
case DISTRIBUTE_BY_HASH:
|
||||||
|
case DISTRIBUTE_BY_GEO:
|
||||||
{
|
{
|
||||||
Node *partitionNode = stringToNode(partitionKeyString);
|
Node *partitionNode = stringToNode(partitionKeyString);
|
||||||
Var *partitionColumn = (Var *) partitionNode;
|
Var *partitionColumn = (Var *) partitionNode;
|
||||||
|
@ -4350,6 +4356,7 @@ GetIntervalTypeInfo(char partitionMethod, Var *partitionColumn,
|
||||||
|
|
||||||
switch (partitionMethod)
|
switch (partitionMethod)
|
||||||
{
|
{
|
||||||
|
case DISTRIBUTE_BY_GEO:
|
||||||
case DISTRIBUTE_BY_APPEND:
|
case DISTRIBUTE_BY_APPEND:
|
||||||
case DISTRIBUTE_BY_RANGE:
|
case DISTRIBUTE_BY_RANGE:
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,6 +74,9 @@ static uint64 NextPlanId = 1;
|
||||||
/* keep track of planner call stack levels */
|
/* keep track of planner call stack levels */
|
||||||
int PlannerLevel = 0;
|
int PlannerLevel = 0;
|
||||||
bool UseCustomPath = false;
|
bool UseCustomPath = false;
|
||||||
|
bool OnlyGeoPartitioning = false;
|
||||||
|
bool UseGeoPartitioning = true;
|
||||||
|
bool EnableGeoPartitioningGrouping = true;
|
||||||
|
|
||||||
static bool ListContainsDistributedTableRTE(List *rangeTableList);
|
static bool ListContainsDistributedTableRTE(List *rangeTableList);
|
||||||
static bool IsUpdateOrDelete(Query *query);
|
static bool IsUpdateOrDelete(Query *query);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "catalog/pg_aggregate.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_type_d.h"
|
#include "catalog/pg_type_d.h"
|
||||||
#include "distributed/citus_custom_scan.h"
|
#include "distributed/citus_custom_scan.h"
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
#include "nodes/plannodes.h"
|
#include "nodes/plannodes.h"
|
||||||
#include "optimizer/pathnode.h"
|
#include "optimizer/pathnode.h"
|
||||||
#include "optimizer/restrictinfo.h"
|
#include "optimizer/restrictinfo.h"
|
||||||
|
#include "optimizer/tlist.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
@ -46,6 +48,13 @@ typedef struct DistributedUnionPath
|
||||||
Oid sampleRelid;
|
Oid sampleRelid;
|
||||||
} DistributedUnionPath;
|
} DistributedUnionPath;
|
||||||
|
|
||||||
|
typedef struct GeoScanPath
|
||||||
|
{
|
||||||
|
CustomPath custom_path;
|
||||||
|
|
||||||
|
RangeTblEntry *rte;
|
||||||
|
} GeoScanPath;
|
||||||
|
|
||||||
static Plan * CreateDistributedUnionPlan(PlannerInfo *root, RelOptInfo *rel, struct CustomPath *best_path, List *tlist, List *clauses, List *custom_plans);
|
static Plan * CreateDistributedUnionPlan(PlannerInfo *root, RelOptInfo *rel, struct CustomPath *best_path, List *tlist, List *clauses, List *custom_plans);
|
||||||
static List * ReparameterizeDistributedUnion(PlannerInfo *root, List *custom_private, RelOptInfo *child_rel);
|
static List * ReparameterizeDistributedUnion(PlannerInfo *root, List *custom_private, RelOptInfo *child_rel);
|
||||||
static CustomPath * WrapTableAccessWithDistributedUnion(Path *originalPath, uint32 colocationId, Expr *partitionValue, Oid sampleRelid, List *subPaths);
|
static CustomPath * WrapTableAccessWithDistributedUnion(Path *originalPath, uint32 colocationId, Expr *partitionValue, Oid sampleRelid, List *subPaths);
|
||||||
|
@ -63,6 +72,14 @@ static List * ShardIntervalListForRelationPartitionValue(Oid relationId, Expr *p
|
||||||
static void PathBasedPlannerGroupAgg(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *output_rel, void *extra);
|
static void PathBasedPlannerGroupAgg(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *output_rel, void *extra);
|
||||||
static Path * OptimizeGroupAgg(PlannerInfo *root, Path *originalPath);
|
static Path * OptimizeGroupAgg(PlannerInfo *root, Path *originalPath);
|
||||||
static bool CanOptimizeAggPath(PlannerInfo *root, AggPath *apath);
|
static bool CanOptimizeAggPath(PlannerInfo *root, AggPath *apath);
|
||||||
|
static GeoScanPath *makeGeoScanPath(Relation rel, RelOptInfo *parent,
|
||||||
|
PathTarget *pathtarget, double rows);
|
||||||
|
static bool IsGeoScanPath(CustomPath *path);
|
||||||
|
static RangeTblEntry *makeRangeTableEntryForRelation(Relation rel,
|
||||||
|
int lockmode,
|
||||||
|
Alias *alias,
|
||||||
|
bool inh,
|
||||||
|
bool inFromCl);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -81,6 +98,10 @@ static optimizeFn joinOptimizations[] = {
|
||||||
GeoOverlapJoin,
|
GeoOverlapJoin,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const CustomPathMethods geoScanMethods = {
|
||||||
|
.CustomName = "GeoScan",
|
||||||
|
};
|
||||||
|
|
||||||
const CustomPathMethods distributedUnionMethods = {
|
const CustomPathMethods distributedUnionMethods = {
|
||||||
.CustomName = "Distributed Union",
|
.CustomName = "Distributed Union",
|
||||||
.PlanCustomPath = CreateDistributedUnionPlan,
|
.PlanCustomPath = CreateDistributedUnionPlan,
|
||||||
|
@ -332,7 +353,7 @@ PathBasedPlannerRelationHook(PlannerInfo *root,
|
||||||
partitionValue = ExtractPartitionValue(relOptInfo->baserestrictinfo, partitionKey);
|
partitionValue = ExtractPartitionValue(relOptInfo->baserestrictinfo, partitionKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wrap every path with a distirbuted union custom path */
|
/* wrap every path with a distributed union custom path */
|
||||||
ListCell *pathCell = NULL;
|
ListCell *pathCell = NULL;
|
||||||
foreach(pathCell, relOptInfo->pathlist)
|
foreach(pathCell, relOptInfo->pathlist)
|
||||||
{
|
{
|
||||||
|
@ -345,6 +366,216 @@ PathBasedPlannerRelationHook(PlannerInfo *root,
|
||||||
NIL);
|
NIL);
|
||||||
SetListCellPtr(pathCell, wrappedPath);
|
SetListCellPtr(pathCell, wrappedPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* hardcoded hack for adding geo distributed tables as an alternative path */
|
||||||
|
Relation rel = relation_open(rte->relid, AccessShareLock);
|
||||||
|
if (UseGeoPartitioning && strcmp(RelationGetRelationName(rel), "belgium_planet_osm_roads_dist") == 0)
|
||||||
|
{
|
||||||
|
if (OnlyGeoPartitioning)
|
||||||
|
{
|
||||||
|
/* makes the geo path the only path to access the relation */
|
||||||
|
relOptInfo->pathlist = NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Oid geoRelid = RelnameGetRelid("belgium_planet_osm_roads_geo");
|
||||||
|
Relation georel = relation_open(geoRelid, AccessShareLock);
|
||||||
|
|
||||||
|
Path *geoPath = (Path *) makeGeoScanPath(georel,
|
||||||
|
relOptInfo,
|
||||||
|
relOptInfo->reltarget,
|
||||||
|
relOptInfo->rows);
|
||||||
|
geoPath = (Path *)
|
||||||
|
WrapTableAccessWithDistributedUnion(geoPath,
|
||||||
|
TableColocationId(geoRelid),
|
||||||
|
NULL,
|
||||||
|
geoRelid,
|
||||||
|
NIL);
|
||||||
|
|
||||||
|
if (EnableGeoPartitioningGrouping)
|
||||||
|
{
|
||||||
|
/* verymuch just an int4 at the moment */
|
||||||
|
SortGroupClause *sgc = makeNode(SortGroupClause);
|
||||||
|
sgc->tleSortGroupRef = 1; /* should be first field */
|
||||||
|
sgc->eqop = 96;
|
||||||
|
sgc->sortop = 97;
|
||||||
|
sgc->nulls_first = false;
|
||||||
|
sgc->hashable = true; /* ? just assume an in can be hashed */
|
||||||
|
|
||||||
|
List *groupClause = list_make1(sgc);
|
||||||
|
|
||||||
|
/* creating the target list */
|
||||||
|
PathTarget *groupPathTarget = create_empty_pathtarget();
|
||||||
|
add_column_to_pathtarget(groupPathTarget, (Expr *) makeVar(1,1,23,-1, 0,0), 0);
|
||||||
|
|
||||||
|
/* any_value on osm_id */
|
||||||
|
Aggref *aggref = makeNode(Aggref);
|
||||||
|
aggref->aggfnoid = 18333; /* any_value */
|
||||||
|
aggref->aggtype = 20;
|
||||||
|
aggref->aggtranstype = 20;
|
||||||
|
aggref->aggfilter = NULL;
|
||||||
|
aggref->aggstar = false;
|
||||||
|
aggref->aggvariadic = false;
|
||||||
|
aggref->aggkind = AGGKIND_NORMAL;
|
||||||
|
aggref->aggsplit = AGGSPLIT_SIMPLE;
|
||||||
|
aggref->location = 0;
|
||||||
|
|
||||||
|
aggref->args = list_make1(
|
||||||
|
makeTargetEntry(
|
||||||
|
(Expr *) makeVar(1, 2, 20, -1, 0, 0),
|
||||||
|
1, NULL, false)); /* osm_id */
|
||||||
|
struct TargetEntry *argTLE = NULL;
|
||||||
|
foreach_ptr(argTLE, aggref->args)
|
||||||
|
{
|
||||||
|
aggref->aggargtypes = lappend_oid(aggref->aggargtypes,
|
||||||
|
exprType((Node *) argTLE->expr));
|
||||||
|
}
|
||||||
|
add_column_to_pathtarget(groupPathTarget, (Expr *) aggref, 0);
|
||||||
|
|
||||||
|
/* ST_Union(way) */
|
||||||
|
Aggref *aggref2 = makeNode(Aggref);
|
||||||
|
aggref2->aggfnoid = 16861; /* ST_Union */
|
||||||
|
aggref2->aggtype = 16390;
|
||||||
|
aggref2->aggtranstype = 2281;
|
||||||
|
aggref2->aggfilter = NULL;
|
||||||
|
aggref2->aggstar = false;
|
||||||
|
aggref2->aggvariadic = false;
|
||||||
|
aggref2->aggkind = AGGKIND_NORMAL;
|
||||||
|
aggref2->aggsplit = AGGSPLIT_SIMPLE;
|
||||||
|
aggref2->location = 0;
|
||||||
|
|
||||||
|
aggref2->args = list_make1(
|
||||||
|
makeTargetEntry(
|
||||||
|
(Expr *) makeVar(1, 3, 16390, -1, 0, 0),
|
||||||
|
1, NULL, false)); /* way */
|
||||||
|
argTLE = NULL;
|
||||||
|
foreach_ptr(argTLE, aggref2->args)
|
||||||
|
{
|
||||||
|
aggref2->aggargtypes = lappend_oid(aggref2->aggargtypes,
|
||||||
|
exprType((Node *) argTLE->expr));
|
||||||
|
}
|
||||||
|
add_column_to_pathtarget(groupPathTarget, (Expr *) aggref2, 0);
|
||||||
|
|
||||||
|
/* TODO figure out costing for our grouping */
|
||||||
|
AggClauseCosts costs = {
|
||||||
|
.numAggs = 2,
|
||||||
|
.numOrderedAggs = 0,
|
||||||
|
.hasNonPartial = false,
|
||||||
|
.hasNonSerial = false,
|
||||||
|
|
||||||
|
.transCost.startup = 0,
|
||||||
|
.transCost.per_tuple = 0,
|
||||||
|
.finalCost.startup = 0,
|
||||||
|
.finalCost.per_tuple = 0,
|
||||||
|
|
||||||
|
.transitionSpace = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
geoPath = (Path *) create_agg_path(root,
|
||||||
|
relOptInfo,
|
||||||
|
geoPath,
|
||||||
|
groupPathTarget,
|
||||||
|
AGG_HASHED,
|
||||||
|
AGGSPLIT_SIMPLE,
|
||||||
|
groupClause,
|
||||||
|
NIL, &costs,
|
||||||
|
2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
add_path(relOptInfo, geoPath);
|
||||||
|
|
||||||
|
relation_close(georel, AccessShareLock);
|
||||||
|
}
|
||||||
|
relation_close(rel, AccessShareLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GeoScanPath *
|
||||||
|
makeGeoScanPath(Relation rel, RelOptInfo *parent, PathTarget *pathtarget, double rows)
|
||||||
|
{
|
||||||
|
GeoScanPath *geoPath = (GeoScanPath *) newNode(sizeof(GeoScanPath), T_CustomPath);
|
||||||
|
CustomPath *cpath = (CustomPath *) geoPath;
|
||||||
|
Path *path = (Path *) geoPath;
|
||||||
|
|
||||||
|
path->pathtype = T_CustomScan;
|
||||||
|
path->parent = parent;
|
||||||
|
|
||||||
|
PathTarget *targetCopy = create_empty_pathtarget();
|
||||||
|
add_column_to_pathtarget(targetCopy, list_nth(pathtarget->exprs, 0), 1);
|
||||||
|
add_column_to_pathtarget(targetCopy, list_nth(pathtarget->exprs, 1), 0);
|
||||||
|
add_column_to_pathtarget(targetCopy, list_nth(pathtarget->exprs, 2), 0);
|
||||||
|
|
||||||
|
path->pathtarget = targetCopy;
|
||||||
|
path->param_info = NULL;
|
||||||
|
|
||||||
|
path->rows = rows * 1.2; /* add 20% for the duplication */
|
||||||
|
path->startup_cost = 0;
|
||||||
|
path->total_cost = 0;
|
||||||
|
|
||||||
|
cpath->methods = &geoScanMethods;
|
||||||
|
|
||||||
|
geoPath->rte = makeRangeTableEntryForRelation(rel, AccessShareLock, NULL, false, true);
|
||||||
|
|
||||||
|
return geoPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
IsGeoScanPath(CustomPath *path)
|
||||||
|
{
|
||||||
|
return path->methods == &geoScanMethods;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static RangeTblEntry *
|
||||||
|
makeRangeTableEntryForRelation(Relation rel,
|
||||||
|
int lockmode,
|
||||||
|
Alias *alias,
|
||||||
|
bool inh,
|
||||||
|
bool inFromCl)
|
||||||
|
{
|
||||||
|
RangeTblEntry *rte = makeNode(RangeTblEntry);
|
||||||
|
char *refname = alias ? alias->aliasname : RelationGetRelationName(rel);
|
||||||
|
|
||||||
|
Assert(lockmode == AccessShareLock ||
|
||||||
|
lockmode == RowShareLock ||
|
||||||
|
lockmode == RowExclusiveLock);
|
||||||
|
Assert(CheckRelationLockedByMe(rel, lockmode, true));
|
||||||
|
|
||||||
|
rte->rtekind = RTE_RELATION;
|
||||||
|
rte->alias = alias;
|
||||||
|
rte->relid = RelationGetRelid(rel);
|
||||||
|
rte->relkind = rel->rd_rel->relkind;
|
||||||
|
rte->rellockmode = lockmode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build the list of effective column names using user-supplied aliases
|
||||||
|
* and/or actual column names.
|
||||||
|
*/
|
||||||
|
rte->eref = makeAlias(refname, NIL);
|
||||||
|
rte->eref->colnames = list_make3(makeString("k"),
|
||||||
|
makeString("osm_id"),
|
||||||
|
makeString("way"));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set flags and access permissions.
|
||||||
|
*
|
||||||
|
* The initial default on access checks is always check-for-READ-access,
|
||||||
|
* which is the right thing for all except target tables.
|
||||||
|
*/
|
||||||
|
rte->lateral = false;
|
||||||
|
rte->inh = inh;
|
||||||
|
rte->inFromCl = inFromCl;
|
||||||
|
|
||||||
|
rte->requiredPerms = ACL_SELECT;
|
||||||
|
rte->checkAsUser = InvalidOid; /* not set-uid by default, either */
|
||||||
|
rte->selectedCols = NULL;
|
||||||
|
rte->insertedCols = NULL;
|
||||||
|
rte->updatedCols = NULL;
|
||||||
|
rte->extraUpdatedCols = NULL;
|
||||||
|
|
||||||
|
return rte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -823,6 +1054,13 @@ ApplyPathToQuery(PlannerInfo *root, Query *query, Path *path, PathQueryInfo *inf
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case T_BitmapHeapScan:
|
||||||
|
{
|
||||||
|
BitmapHeapPath *bpath = castNode(BitmapHeapPath, path);
|
||||||
|
ApplyPathToQuery(root, query, bpath->bitmapqual, info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case T_IndexScan:
|
case T_IndexScan:
|
||||||
case T_IndexOnlyScan:
|
case T_IndexOnlyScan:
|
||||||
case T_SeqScan:
|
case T_SeqScan:
|
||||||
|
@ -977,9 +1215,37 @@ ApplyPathToQuery(PlannerInfo *root, Query *query, Path *path, PathQueryInfo *inf
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case T_CustomScan:
|
||||||
|
{
|
||||||
|
if (IsGeoScanPath(castNode(CustomPath, path)))
|
||||||
|
{
|
||||||
|
GeoScanPath *geoPath = (GeoScanPath *) path;
|
||||||
|
|
||||||
|
Index scan_relid = path->parent->relid;
|
||||||
|
Index rteIndex = info->varno_mapping[scan_relid];
|
||||||
|
|
||||||
|
if (rteIndex == 0)
|
||||||
|
{
|
||||||
|
RangeTblEntry* rte = geoPath->rte;
|
||||||
|
query->rtable = lappend(query->rtable, rte);
|
||||||
|
rteIndex = list_length(query->rtable);
|
||||||
|
info->varno_mapping[scan_relid] = rteIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add to from list */
|
||||||
|
RangeTblRef *rr = makeNode(RangeTblRef);
|
||||||
|
rr->rtindex = rteIndex;
|
||||||
|
query->jointree->fromlist = lappend(query->jointree->fromlist, rr);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fallthrough to error */
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errmsg("unknow path type in worker query"),
|
ereport(ERROR, (errmsg("unknown path type in worker query"),
|
||||||
errdetail("cannot turn worker path into query due to unknown "
|
errdetail("cannot turn worker path into query due to unknown "
|
||||||
"path type in plan. pathtype: %d", path->pathtype))
|
"path type in plan. pathtype: %d", path->pathtype))
|
||||||
);
|
);
|
||||||
|
|
|
@ -1159,6 +1159,36 @@ RegisterCitusConfigVariables(void)
|
||||||
GUC_STANDARD,
|
GUC_STANDARD,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
DefineCustomBoolVariable(
|
||||||
|
"citus.use_geo_partitioning",
|
||||||
|
gettext_noop("Enable planning with geo partitins"),
|
||||||
|
NULL,
|
||||||
|
&UseGeoPartitioning,
|
||||||
|
true,
|
||||||
|
PGC_USERSET,
|
||||||
|
GUC_STANDARD,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
DefineCustomBoolVariable(
|
||||||
|
"citus.use_only_geo_partitioning",
|
||||||
|
gettext_noop("Force the planner to use only the geo partitioning"),
|
||||||
|
NULL,
|
||||||
|
&OnlyGeoPartitioning,
|
||||||
|
false,
|
||||||
|
PGC_USERSET,
|
||||||
|
GUC_STANDARD,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
DefineCustomBoolVariable(
|
||||||
|
"citus.use_geo_partitioning_grouping",
|
||||||
|
gettext_noop("Enable geo partitioning grouping"),
|
||||||
|
NULL,
|
||||||
|
&EnableGeoPartitioningGrouping,
|
||||||
|
true,
|
||||||
|
PGC_USERSET,
|
||||||
|
GUC_STANDARD,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
DefineCustomBoolVariable(
|
DefineCustomBoolVariable(
|
||||||
"citus.use_custom_path_broadcast_join",
|
"citus.use_custom_path_broadcast_join",
|
||||||
gettext_noop("Allow broadcast joins to be used during path based planning"),
|
gettext_noop("Allow broadcast joins to be used during path based planning"),
|
||||||
|
|
|
@ -1003,6 +1003,16 @@ ColocatedShardIntervalList(ShardInterval *shardInterval)
|
||||||
return colocatedShardList;
|
return colocatedShardList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsCitusTableTypeCacheEntry(cacheEntry, GEO_DISTRIBUTED))
|
||||||
|
{
|
||||||
|
/* TODO actual lookup colocated geo tables, since we experiment with selfjoins this hack works */
|
||||||
|
ShardInterval *copyShardInterval = CopyShardInterval(shardInterval);
|
||||||
|
|
||||||
|
colocatedShardList = lappend(colocatedShardList, copyShardInterval);
|
||||||
|
|
||||||
|
return colocatedShardList;
|
||||||
|
}
|
||||||
|
|
||||||
int shardIntervalIndex = ShardIndex(shardInterval);
|
int shardIntervalIndex = ShardIndex(shardInterval);
|
||||||
List *colocatedTableList = ColocatedTableList(distributedTableId);
|
List *colocatedTableList = ColocatedTableList(distributedTableId);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
/* level of planner calls */
|
/* level of planner calls */
|
||||||
extern int PlannerLevel;
|
extern int PlannerLevel;
|
||||||
extern bool UseCustomPath;
|
extern bool UseCustomPath;
|
||||||
|
extern bool OnlyGeoPartitioning;
|
||||||
|
extern bool UseGeoPartitioning;
|
||||||
|
extern bool EnableGeoPartitioningGrouping;
|
||||||
|
|
||||||
typedef struct RelationRestrictionContext
|
typedef struct RelationRestrictionContext
|
||||||
{
|
{
|
||||||
|
|
|
@ -122,6 +122,7 @@ typedef enum
|
||||||
HASH_DISTRIBUTED,
|
HASH_DISTRIBUTED,
|
||||||
APPEND_DISTRIBUTED,
|
APPEND_DISTRIBUTED,
|
||||||
RANGE_DISTRIBUTED,
|
RANGE_DISTRIBUTED,
|
||||||
|
GEO_DISTRIBUTED,
|
||||||
|
|
||||||
/* hash, range or append distributed table */
|
/* hash, range or append distributed table */
|
||||||
DISTRIBUTED_TABLE,
|
DISTRIBUTED_TABLE,
|
||||||
|
|
|
@ -57,7 +57,7 @@ typedef FormData_pg_dist_partition *Form_pg_dist_partition;
|
||||||
#define DISTRIBUTE_BY_NONE 'n'
|
#define DISTRIBUTE_BY_NONE 'n'
|
||||||
#define REDISTRIBUTE_BY_HASH 'x'
|
#define REDISTRIBUTE_BY_HASH 'x'
|
||||||
#define DISTRIBUTE_BY_INVALID '\0'
|
#define DISTRIBUTE_BY_INVALID '\0'
|
||||||
#define REDISTRIBUTE_BY_GEO 'g'
|
#define DISTRIBUTE_BY_GEO 'g'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Valid values for repmodel are 'c' for coordinator, 's' for streaming
|
* Valid values for repmodel are 'c' for coordinator, 's' for streaming
|
||||||
|
|
Loading…
Reference in New Issue