Skip expensive checks when fast-path query

The definition of fast-path query is very strict. So, we don't need
to do some extra checks.
pull/3332/head
Onder Kalaci 2019-12-19 15:16:58 +01:00 committed by Jelte Fennema
parent 7f3ab7892d
commit 13a9b55695
2 changed files with 61 additions and 21 deletions

View File

@ -79,7 +79,8 @@ static DistributedPlan * CreateDistributedPlan(uint64 planId, Query *originalQue
bool hasUnresolvedParams, bool hasUnresolvedParams,
PlannerRestrictionContext * PlannerRestrictionContext *
plannerRestrictionContext); plannerRestrictionContext);
static void FinalizeDistributedPlan(DistributedPlan *plan, Query *originalQuery); static void FinalizeDistributedPlan(DistributedPlan *plan, Query *originalQuery,
bool fastPathRouterQuery);
static void RecordSubPlansUsedInPlan(DistributedPlan *plan, Query *originalQuery); static void RecordSubPlansUsedInPlan(DistributedPlan *plan, Query *originalQuery);
static DeferredErrorMessage * DeferErrorIfPartitionTableNotSingleReplicated(Oid static DeferredErrorMessage * DeferErrorIfPartitionTableNotSingleReplicated(Oid
relationId); relationId);
@ -168,7 +169,7 @@ distributed_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
* don't have a way of doing both things and therefore error out, but do * don't have a way of doing both things and therefore error out, but do
* have a handy tip for users. * have a handy tip for users.
*/ */
if (InsertSelectIntoLocalTable(parse)) if (!fastPathRouterQuery && InsertSelectIntoLocalTable(parse))
{ {
ereport(ERROR, (errmsg("cannot INSERT rows from a distributed query into a " ereport(ERROR, (errmsg("cannot INSERT rows from a distributed query into a "
"local table"), "local table"),
@ -183,13 +184,27 @@ distributed_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
* set, which doesn't break our goals, but, prevents us keeping an extra copy * set, which doesn't break our goals, but, prevents us keeping an extra copy
* of the query tree. Note that we copy the query tree once we're sure it's a * of the query tree. Note that we copy the query tree once we're sure it's a
* distributed query. * distributed query.
*
* Since fast-path queries do not through standard planner, we skip unnecessary
* parts in that case.
*/ */
rteIdCounter = AssignRTEIdentities(rangeTableList, rteIdCounter); if (!fastPathRouterQuery)
originalQuery = copyObject(parse); {
rteIdCounter = AssignRTEIdentities(rangeTableList, rteIdCounter);
originalQuery = copyObject(parse);
setPartitionedTablesInherited = false; setPartitionedTablesInherited = false;
AdjustPartitioningForDistributedPlanning(rangeTableList, AdjustPartitioningForDistributedPlanning(rangeTableList,
setPartitionedTablesInherited); setPartitionedTablesInherited);
}
else
{
/*
* We still need to copy the parse tree because the FastPathPlanner
* modifies it.
*/
originalQuery = copyObject(parse);
}
} }
/* /*
@ -249,9 +264,12 @@ distributed_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
result = CreateDistributedPlannedStmt(planId, result, originalQuery, parse, result = CreateDistributedPlannedStmt(planId, result, originalQuery, parse,
boundParams, plannerRestrictionContext); boundParams, plannerRestrictionContext);
setPartitionedTablesInherited = true; if (!fastPathRouterQuery)
AdjustPartitioningForDistributedPlanning(rangeTableList, {
setPartitionedTablesInherited); setPartitionedTablesInherited = true;
AdjustPartitioningForDistributedPlanning(rangeTableList,
setPartitionedTablesInherited);
}
} }
else else
{ {
@ -667,7 +685,8 @@ CreateDistributedPlan(uint64 planId, Query *originalQuery, Query *query, ParamLi
{ {
DistributedPlan *distributedPlan = NULL; DistributedPlan *distributedPlan = NULL;
bool hasCtes = originalQuery->cteList != NIL; bool hasCtes = originalQuery->cteList != NIL;
bool fastPathRouterQuery =
plannerRestrictionContext->fastPathRestrictionContext->fastPathRouterQuery;
if (IsModifyCommand(originalQuery)) if (IsModifyCommand(originalQuery))
{ {
@ -703,7 +722,7 @@ CreateDistributedPlan(uint64 planId, Query *originalQuery, Query *query, ParamLi
if (distributedPlan->planningError == NULL) if (distributedPlan->planningError == NULL)
{ {
FinalizeDistributedPlan(distributedPlan, originalQuery); FinalizeDistributedPlan(distributedPlan, originalQuery, fastPathRouterQuery);
return distributedPlan; return distributedPlan;
} }
@ -725,7 +744,7 @@ CreateDistributedPlan(uint64 planId, Query *originalQuery, Query *query, ParamLi
plannerRestrictionContext); plannerRestrictionContext);
if (distributedPlan->planningError == NULL) if (distributedPlan->planningError == NULL)
{ {
FinalizeDistributedPlan(distributedPlan, originalQuery); FinalizeDistributedPlan(distributedPlan, originalQuery, fastPathRouterQuery);
return distributedPlan; return distributedPlan;
} }
@ -819,7 +838,7 @@ CreateDistributedPlan(uint64 planId, Query *originalQuery, Query *query, ParamLi
plannerRestrictionContext); plannerRestrictionContext);
distributedPlan->subPlanList = subPlanList; distributedPlan->subPlanList = subPlanList;
FinalizeDistributedPlan(distributedPlan, originalQuery); FinalizeDistributedPlan(distributedPlan, originalQuery, fastPathRouterQuery);
return distributedPlan; return distributedPlan;
} }
@ -831,7 +850,7 @@ CreateDistributedPlan(uint64 planId, Query *originalQuery, Query *query, ParamLi
*/ */
if (IsModifyCommand(originalQuery)) if (IsModifyCommand(originalQuery))
{ {
FinalizeDistributedPlan(distributedPlan, originalQuery); FinalizeDistributedPlan(distributedPlan, originalQuery, fastPathRouterQuery);
return distributedPlan; return distributedPlan;
} }
@ -864,7 +883,7 @@ CreateDistributedPlan(uint64 planId, Query *originalQuery, Query *query, ParamLi
/* distributed plan currently should always succeed or error out */ /* distributed plan currently should always succeed or error out */
Assert(distributedPlan && distributedPlan->planningError == NULL); Assert(distributedPlan && distributedPlan->planningError == NULL);
FinalizeDistributedPlan(distributedPlan, originalQuery); FinalizeDistributedPlan(distributedPlan, originalQuery, fastPathRouterQuery);
return distributedPlan; return distributedPlan;
} }
@ -875,9 +894,17 @@ CreateDistributedPlan(uint64 planId, Query *originalQuery, Query *query, ParamLi
* currently only implements some optimizations for intermediate result(s) pruning. * currently only implements some optimizations for intermediate result(s) pruning.
*/ */
static void static void
FinalizeDistributedPlan(DistributedPlan *plan, Query *originalQuery) FinalizeDistributedPlan(DistributedPlan *plan, Query *originalQuery,
bool fastPathRouterQuery)
{ {
RecordSubPlansUsedInPlan(plan, originalQuery); /*
* Fast path queries, we cannot have any subplans by their definition,
* so skip expensive traversals.
*/
if (!fastPathRouterQuery)
{
RecordSubPlansUsedInPlan(plan, originalQuery);
}
} }

View File

@ -552,6 +552,8 @@ ModifyQuerySupported(Query *queryTree, Query *originalQuery, bool multiShardQuer
ListCell *rangeTableCell = NULL; ListCell *rangeTableCell = NULL;
uint32 queryTableCount = 0; uint32 queryTableCount = 0;
CmdType commandType = queryTree->commandType; CmdType commandType = queryTree->commandType;
bool fastPathRouterQuery =
plannerRestrictionContext->fastPathRestrictionContext->fastPathRouterQuery;
Oid distributedTableId = ModifyQueryResultRelationId(queryTree); Oid distributedTableId = ModifyQueryResultRelationId(queryTree);
if (!IsDistributedTable(distributedTableId)) if (!IsDistributedTable(distributedTableId))
@ -575,8 +577,12 @@ ModifyQuerySupported(Query *queryTree, Query *originalQuery, bool multiShardQuer
* rows based on the ctid column. This is a bad idea because ctid of * rows based on the ctid column. This is a bad idea because ctid of
* the rows could be changed before the modification part of * the rows could be changed before the modification part of
* the query is executed. * the query is executed.
*
* We can exclude fast path queries since they cannot have intermediate
* results by definition.
*/ */
if (ContainsReadIntermediateResultFunction((Node *) originalQuery)) if (!fastPathRouterQuery &&
ContainsReadIntermediateResultFunction((Node *) originalQuery))
{ {
bool hasTidColumn = FindNodeCheck((Node *) originalQuery->jointree, IsTidColumn); bool hasTidColumn = FindNodeCheck((Node *) originalQuery->jointree, IsTidColumn);
if (hasTidColumn) if (hasTidColumn)
@ -649,8 +655,15 @@ ModifyQuerySupported(Query *queryTree, Query *originalQuery, bool multiShardQuer
} }
} }
/* extract range table entries */ /*
ExtractRangeTableEntryWalker((Node *) originalQuery, &rangeTableList); * Extract range table entries for queries that are not fast path. We can skip fast
* path queries because their definition is a single RTE entry, which is a relation,
* so the following check doesn't apply for fast-path queries.
*/
if (!fastPathRouterQuery)
{
ExtractRangeTableEntryWalker((Node *) originalQuery, &rangeTableList);
}
foreach(rangeTableCell, rangeTableList) foreach(rangeTableCell, rangeTableList)
{ {