mirror of https://github.com/citusdata/citus.git
Refactor ErrorIfQueryNotSupported to defer errors
parent
71ce42b936
commit
e12ea914b9
|
@ -113,7 +113,6 @@ static bool IsDistributedTableRTE(Node *node);
|
||||||
static FieldSelect * CompositeFieldRecursive(Expr *expression, Query *query);
|
static FieldSelect * CompositeFieldRecursive(Expr *expression, Query *query);
|
||||||
static bool FullCompositeFieldList(List *compositeFieldList);
|
static bool FullCompositeFieldList(List *compositeFieldList);
|
||||||
static MultiNode * MultiNodeTree(Query *queryTree);
|
static MultiNode * MultiNodeTree(Query *queryTree);
|
||||||
static void ErrorIfQueryNotSupported(Query *queryTree);
|
|
||||||
static DeferredErrorMessage * DeferredErrorIfUnsupportedRecurringTuplesJoin(
|
static DeferredErrorMessage * DeferredErrorIfUnsupportedRecurringTuplesJoin(
|
||||||
PlannerRestrictionContext *plannerRestrictionContext);
|
PlannerRestrictionContext *plannerRestrictionContext);
|
||||||
static bool ShouldRecurseForRecurringTuplesJoinChecks(RelOptInfo *relOptInfo);
|
static bool ShouldRecurseForRecurringTuplesJoinChecks(RelOptInfo *relOptInfo);
|
||||||
|
@ -396,12 +395,17 @@ SubqueryMultiNodeTree(Query *originalQuery, Query *queryTree,
|
||||||
{
|
{
|
||||||
MultiNode *multiQueryNode = NULL;
|
MultiNode *multiQueryNode = NULL;
|
||||||
DeferredErrorMessage *subqueryPushdownError = NULL;
|
DeferredErrorMessage *subqueryPushdownError = NULL;
|
||||||
|
DeferredErrorMessage *unsupportedQueryError = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a generic error check that applies to both subquery pushdown
|
* This is a generic error check that applies to both subquery pushdown
|
||||||
* and single table repartition subquery.
|
* and single table repartition subquery.
|
||||||
*/
|
*/
|
||||||
ErrorIfQueryNotSupported(originalQuery);
|
unsupportedQueryError = DeferErrorIfQueryNotSupported(originalQuery);
|
||||||
|
if (unsupportedQueryError != NULL)
|
||||||
|
{
|
||||||
|
RaiseDeferredError(unsupportedQueryError, ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In principle, we're first trying subquery pushdown planner. If it fails
|
* In principle, we're first trying subquery pushdown planner. If it fails
|
||||||
|
@ -916,7 +920,7 @@ DeferErrorIfFromClauseRecurs(Query *queryTree)
|
||||||
* the join condition must be partition columns.
|
* the join condition must be partition columns.
|
||||||
* c. If there is a distinct clause, it must be on the partition column.
|
* c. If there is a distinct clause, it must be on the partition column.
|
||||||
*
|
*
|
||||||
* This function is very similar to ErrorIfQueryNotSupported() in logical
|
* This function is very similar to DeferErrorIfQueryNotSupported() in logical
|
||||||
* planner, but we don't reuse it, because differently for subqueries we support
|
* planner, but we don't reuse it, because differently for subqueries we support
|
||||||
* a subset of distinct, union and left joins.
|
* a subset of distinct, union and left joins.
|
||||||
*
|
*
|
||||||
|
@ -1760,9 +1764,14 @@ MultiNodeTree(Query *queryTree)
|
||||||
MultiProject *projectNode = NULL;
|
MultiProject *projectNode = NULL;
|
||||||
MultiExtendedOp *extendedOpNode = NULL;
|
MultiExtendedOp *extendedOpNode = NULL;
|
||||||
MultiNode *currentTopNode = NULL;
|
MultiNode *currentTopNode = NULL;
|
||||||
|
DeferredErrorMessage *unsupportedQueryError = NULL;
|
||||||
|
|
||||||
/* verify we can perform distributed planning on this query */
|
/* verify we can perform distributed planning on this query */
|
||||||
ErrorIfQueryNotSupported(queryTree);
|
unsupportedQueryError = DeferErrorIfQueryNotSupported(queryTree);
|
||||||
|
if (unsupportedQueryError != NULL)
|
||||||
|
{
|
||||||
|
RaiseDeferredError(unsupportedQueryError, ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
/* extract where clause qualifiers and verify we can plan for them */
|
/* extract where clause qualifiers and verify we can plan for them */
|
||||||
whereClauseList = WhereClauseList(queryTree->jointree);
|
whereClauseList = WhereClauseList(queryTree->jointree);
|
||||||
|
@ -2220,8 +2229,8 @@ IsReadIntermediateResultFunction(Node *node)
|
||||||
* the given query. The checks in this function will be removed as we support
|
* the given query. The checks in this function will be removed as we support
|
||||||
* more functionality in our distributed planning.
|
* more functionality in our distributed planning.
|
||||||
*/
|
*/
|
||||||
static void
|
DeferredErrorMessage *
|
||||||
ErrorIfQueryNotSupported(Query *queryTree)
|
DeferErrorIfQueryNotSupported(Query *queryTree)
|
||||||
{
|
{
|
||||||
char *errorMessage = NULL;
|
char *errorMessage = NULL;
|
||||||
bool hasTablesample = false;
|
bool hasTablesample = false;
|
||||||
|
@ -2329,10 +2338,12 @@ ErrorIfQueryNotSupported(Query *queryTree)
|
||||||
if (!preconditionsSatisfied)
|
if (!preconditionsSatisfied)
|
||||||
{
|
{
|
||||||
bool showHint = ErrorHintRequired(errorHint, queryTree);
|
bool showHint = ErrorHintRequired(errorHint, queryTree);
|
||||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
return DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED,
|
||||||
errmsg("%s", errorMessage),
|
errorMessage, NULL,
|
||||||
showHint ? errhint("%s", errorHint) : 0));
|
showHint ? errorHint : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3847,9 +3858,14 @@ SubqueryPushdownMultiNodeTree(Query *queryTree)
|
||||||
Query *pushedDownQuery = NULL;
|
Query *pushedDownQuery = NULL;
|
||||||
List *subqueryTargetEntryList = NIL;
|
List *subqueryTargetEntryList = NIL;
|
||||||
List *havingClauseColumnList = NIL;
|
List *havingClauseColumnList = NIL;
|
||||||
|
DeferredErrorMessage *unsupportedQueryError = NULL;
|
||||||
|
|
||||||
/* verify we can perform distributed planning on this query */
|
/* verify we can perform distributed planning on this query */
|
||||||
ErrorIfQueryNotSupported(queryTree);
|
unsupportedQueryError = DeferErrorIfQueryNotSupported(queryTree);
|
||||||
|
if (unsupportedQueryError != NULL)
|
||||||
|
{
|
||||||
|
RaiseDeferredError(unsupportedQueryError, ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We would be creating a new Query and pushing down top level query's
|
* We would be creating a new Query and pushing down top level query's
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#define MULTI_LOGICAL_PLANNER_H
|
#define MULTI_LOGICAL_PLANNER_H
|
||||||
|
|
||||||
#include "distributed/citus_nodes.h"
|
#include "distributed/citus_nodes.h"
|
||||||
|
#include "distributed/errormessage.h"
|
||||||
#include "distributed/multi_join_order.h"
|
#include "distributed/multi_join_order.h"
|
||||||
#include "distributed/relation_restriction_equivalence.h"
|
#include "distributed/relation_restriction_equivalence.h"
|
||||||
#include "nodes/nodes.h"
|
#include "nodes/nodes.h"
|
||||||
|
@ -205,6 +206,7 @@ extern List * FindNodesOfType(MultiNode *node, int type);
|
||||||
extern List * JoinClauseList(List *whereClauseList);
|
extern List * JoinClauseList(List *whereClauseList);
|
||||||
extern bool IsJoinClause(Node *clause);
|
extern bool IsJoinClause(Node *clause);
|
||||||
extern List * SubqueryEntryList(Query *queryTree);
|
extern List * SubqueryEntryList(Query *queryTree);
|
||||||
|
extern DeferredErrorMessage * DeferErrorIfQueryNotSupported(Query *queryTree);
|
||||||
extern bool ExtractRangeTableIndexWalker(Node *node, List **rangeTableIndexList);
|
extern bool ExtractRangeTableIndexWalker(Node *node, List **rangeTableIndexList);
|
||||||
extern List * WhereClauseList(FromExpr *fromExpr);
|
extern List * WhereClauseList(FromExpr *fromExpr);
|
||||||
extern List * QualifierList(FromExpr *fromExpr);
|
extern List * QualifierList(FromExpr *fromExpr);
|
||||||
|
|
Loading…
Reference in New Issue