Skip to content

Commit decef4d

Browse files
committed
Refresh deparser code (UNION handling)
1 parent f3485f6 commit decef4d

File tree

1 file changed

+53
-50
lines changed

1 file changed

+53
-50
lines changed

ext/pg_query/postgres_deparse.c

Lines changed: 53 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ typedef enum DeparseNodeContext {
2727
DEPARSE_NODE_CONTEXT_ALTER_TYPE,
2828
DEPARSE_NODE_CONTEXT_SET_STATEMENT,
2929
DEPARSE_NODE_CONTEXT_FUNC_EXPR,
30+
DEPARSE_NODE_CONTEXT_SELECT_SETOP,
3031
// Identifier vs constant context
3132
DEPARSE_NODE_CONTEXT_IDENTIFIER,
3233
DEPARSE_NODE_CONTEXT_CONSTANT
@@ -121,7 +122,7 @@ typedef struct DeparseState
121122
size_t next_comment_index;
122123
} DeparseState;
123124

124-
static void deparseSelectStmt(DeparseState *state, SelectStmt *stmt);
125+
static void deparseSelectStmt(DeparseState *state, SelectStmt *stmt, DeparseNodeContext context);
125126
static void deparseIntoClause(DeparseState *state, IntoClause *into_clause);
126127
static void deparseRangeVar(DeparseState *state, RangeVar *range_var, DeparseNodeContext context);
127128
static void deparseResTarget(DeparseState *state, ResTarget *res_target, DeparseNodeContext context);
@@ -2576,12 +2577,22 @@ static void deparseUtilityOptionList(DeparseState *state, List *options)
25762577
}
25772578
}
25782579

2579-
static void deparseSelectStmt(DeparseState *state, SelectStmt *stmt)
2580+
static void deparseSelectStmt(DeparseState *state, SelectStmt *stmt, DeparseNodeContext context)
25802581
{
25812582
const ListCell *lc = NULL;
25822583
const ListCell *lc2 = NULL;
2584+
bool need_parens = context == DEPARSE_NODE_CONTEXT_SELECT_SETOP && (
2585+
list_length(stmt->sortClause) > 0 ||
2586+
stmt->limitOffset != NULL ||
2587+
stmt->limitCount != NULL ||
2588+
list_length(stmt->lockingClause) > 0 ||
2589+
stmt->withClause != NULL ||
2590+
stmt->op != SETOP_NONE);
25832591

2584-
deparseStatePushStatement(state);
2592+
if (need_parens)
2593+
deparseAppendStringInfoChar(state, '(');
2594+
if (need_parens || context != DEPARSE_NODE_CONTEXT_SELECT_SETOP)
2595+
deparseStatePushStatement(state);
25852596

25862597
if (stmt->withClause)
25872598
{
@@ -2676,46 +2687,35 @@ static void deparseSelectStmt(DeparseState *state, SelectStmt *stmt)
26762687
case SETOP_INTERSECT:
26772688
case SETOP_EXCEPT:
26782689
{
2679-
bool need_larg_parens =
2680-
list_length(stmt->larg->sortClause) > 0 ||
2681-
stmt->larg->limitOffset != NULL ||
2682-
stmt->larg->limitCount != NULL ||
2683-
list_length(stmt->larg->lockingClause) > 0 ||
2684-
stmt->larg->withClause != NULL ||
2685-
stmt->larg->op != SETOP_NONE;
2686-
bool need_rarg_parens =
2687-
list_length(stmt->rarg->sortClause) > 0 ||
2688-
stmt->rarg->limitOffset != NULL ||
2689-
stmt->rarg->limitCount != NULL ||
2690-
list_length(stmt->rarg->lockingClause) > 0 ||
2691-
stmt->rarg->withClause != NULL ||
2692-
stmt->rarg->op != SETOP_NONE;
2693-
if (need_larg_parens)
2694-
deparseAppendStringInfoChar(state, '(');
2695-
deparseSelectStmt(state, stmt->larg);
2696-
if (need_larg_parens)
2697-
deparseAppendStringInfoChar(state, ')');
2690+
// If WITH clause preceded, make sure to not place any opening parens on the same line
2691+
if (stmt->withClause)
2692+
deparseAppendBreakpoint(state);
2693+
2694+
deparseSelectStmt(state, stmt->larg, DEPARSE_NODE_CONTEXT_SELECT_SETOP);
26982695
switch (stmt->op)
26992696
{
27002697
case SETOP_UNION:
2701-
deparseAppendStringInfoString(state, " UNION ");
2698+
if (stmt->all)
2699+
deparseAppendMajorKeyword(state, "UNION ALL", true);
2700+
else
2701+
deparseAppendMajorKeyword(state, "UNION", true);
27022702
break;
27032703
case SETOP_INTERSECT:
2704-
deparseAppendStringInfoString(state, " INTERSECT ");
2704+
if (stmt->all)
2705+
deparseAppendMajorKeyword(state, "INTERSECT ALL", true);
2706+
else
2707+
deparseAppendMajorKeyword(state, "INTERSECT", true);
27052708
break;
27062709
case SETOP_EXCEPT:
2707-
deparseAppendStringInfoString(state, " EXCEPT ");
2710+
if (stmt->all)
2711+
deparseAppendMajorKeyword(state, "EXCEPT ALL", true);
2712+
else
2713+
deparseAppendMajorKeyword(state, "EXCEPT", true);
27082714
break;
27092715
default:
27102716
Assert(false);
27112717
}
2712-
if (stmt->all)
2713-
deparseAppendStringInfoString(state, "ALL ");
2714-
if (need_rarg_parens)
2715-
deparseAppendStringInfoChar(state, '(');
2716-
deparseSelectStmt(state, stmt->rarg);
2717-
if (need_rarg_parens)
2718-
deparseAppendStringInfoChar(state, ')');
2718+
deparseSelectStmt(state, stmt->rarg, DEPARSE_NODE_CONTEXT_SELECT_SETOP);
27192719
deparseAppendStringInfoChar(state, ' ');
27202720
}
27212721
break;
@@ -2763,7 +2763,10 @@ static void deparseSelectStmt(DeparseState *state, SelectStmt *stmt)
27632763

27642764
removeTrailingSpace(state);
27652765

2766-
deparseStatePopStatement(state);
2766+
if (need_parens || context != DEPARSE_NODE_CONTEXT_SELECT_SETOP)
2767+
deparseStatePopStatement(state);
2768+
if (need_parens)
2769+
deparseAppendStringInfoChar(state, ')');
27672770
}
27682771

27692772
static void deparseIntoClause(DeparseState *state, IntoClause *into_clause)
@@ -3355,15 +3358,15 @@ static void deparseSubLink(DeparseState *state, SubLink* sub_link)
33553358
switch (sub_link->subLinkType) {
33563359
case EXISTS_SUBLINK:
33573360
deparseAppendStringInfoString(state, "EXISTS (");
3358-
deparseSelectStmt(state, castNode(SelectStmt, sub_link->subselect));
3361+
deparseSelectStmt(state, castNode(SelectStmt, sub_link->subselect), DEPARSE_NODE_CONTEXT_NONE);
33593362
deparseAppendStringInfoChar(state, ')');
33603363
return;
33613364
case ALL_SUBLINK:
33623365
deparseExpr(state, sub_link->testexpr, DEPARSE_NODE_CONTEXT_A_EXPR);
33633366
deparseAppendStringInfoChar(state, ' ');
33643367
deparseSubqueryOp(state, sub_link->operName);
33653368
deparseAppendStringInfoString(state, " ALL (");
3366-
deparseSelectStmt(state, castNode(SelectStmt, sub_link->subselect));
3369+
deparseSelectStmt(state, castNode(SelectStmt, sub_link->subselect), DEPARSE_NODE_CONTEXT_NONE);
33673370
deparseAppendStringInfoChar(state, ')');
33683371
return;
33693372
case ANY_SUBLINK:
@@ -3379,7 +3382,7 @@ static void deparseSubLink(DeparseState *state, SubLink* sub_link)
33793382
deparseAppendStringInfoString(state, " IN ");
33803383
}
33813384
deparseAppendStringInfoChar(state, '(');
3382-
deparseSelectStmt(state, castNode(SelectStmt, sub_link->subselect));
3385+
deparseSelectStmt(state, castNode(SelectStmt, sub_link->subselect), DEPARSE_NODE_CONTEXT_NONE);
33833386
deparseAppendStringInfoChar(state, ')');
33843387
return;
33853388
case ROWCOMPARE_SUBLINK:
@@ -3388,7 +3391,7 @@ static void deparseSubLink(DeparseState *state, SubLink* sub_link)
33883391
return;
33893392
case EXPR_SUBLINK:
33903393
deparseAppendStringInfoString(state, "(");
3391-
deparseSelectStmt(state, castNode(SelectStmt, sub_link->subselect));
3394+
deparseSelectStmt(state, castNode(SelectStmt, sub_link->subselect), DEPARSE_NODE_CONTEXT_NONE);
33923395
deparseAppendStringInfoChar(state, ')');
33933396
return;
33943397
case MULTIEXPR_SUBLINK:
@@ -3397,7 +3400,7 @@ static void deparseSubLink(DeparseState *state, SubLink* sub_link)
33973400
return;
33983401
case ARRAY_SUBLINK:
33993402
deparseAppendStringInfoString(state, "ARRAY(");
3400-
deparseSelectStmt(state, castNode(SelectStmt, sub_link->subselect));
3403+
deparseSelectStmt(state, castNode(SelectStmt, sub_link->subselect), DEPARSE_NODE_CONTEXT_NONE);
34013404
deparseAppendStringInfoChar(state, ')');
34023405
return;
34033406
case CTE_SUBLINK: /* for SubPlans only */
@@ -3972,7 +3975,7 @@ static void deparseRangeSubselect(DeparseState *state, RangeSubselect *range_sub
39723975
deparseAppendStringInfoString(state, "LATERAL ");
39733976

39743977
deparseAppendStringInfoChar(state, '(');
3975-
deparseSelectStmt(state, castNode(SelectStmt, range_subselect->subquery));
3978+
deparseSelectStmt(state, castNode(SelectStmt, range_subselect->subquery), DEPARSE_NODE_CONTEXT_NONE);
39763979
deparseAppendStringInfoChar(state, ')');
39773980

39783981
if (range_subselect->alias != NULL)
@@ -4638,7 +4641,7 @@ static void deparseInsertStmt(DeparseState *state, InsertStmt *insert_stmt)
46384641

46394642
if (insert_stmt->selectStmt != NULL)
46404643
{
4641-
deparseSelectStmt(state, castNode(SelectStmt, insert_stmt->selectStmt));
4644+
deparseSelectStmt(state, castNode(SelectStmt, insert_stmt->selectStmt), DEPARSE_NODE_CONTEXT_NONE);
46424645
deparseAppendStringInfoChar(state, ' ');
46434646
}
46444647
else
@@ -4747,7 +4750,7 @@ static void deparseUpdateStmt(DeparseState *state, UpdateStmt *update_stmt)
47474750

47484751
if (list_length(update_stmt->targetList) > 0)
47494752
{
4750-
deparseAppendStringInfoString(state, "SET ");
4753+
deparseAppendMajorKeyword(state, "SET", true);
47514754
deparseSetClauseList(state, update_stmt->targetList);
47524755
deparseAppendStringInfoChar(state, ' ');
47534756
}
@@ -4757,7 +4760,7 @@ static void deparseUpdateStmt(DeparseState *state, UpdateStmt *update_stmt)
47574760

47584761
if (list_length(update_stmt->returningList) > 0)
47594762
{
4760-
deparseAppendStringInfoString(state, "RETURNING ");
4763+
deparseAppendMajorKeyword(state, "RETURNING", true);
47614764
deparseTargetList(state, update_stmt->returningList);
47624765
}
47634766

@@ -6269,7 +6272,7 @@ static void deparseCreateTableAsStmt(DeparseState *state, CreateTableAsStmt *cre
62696272
if (IsA(create_table_as_stmt->query, ExecuteStmt))
62706273
deparseExecuteStmt(state, castNode(ExecuteStmt, create_table_as_stmt->query));
62716274
else
6272-
deparseSelectStmt(state, castNode(SelectStmt, create_table_as_stmt->query));
6275+
deparseSelectStmt(state, castNode(SelectStmt, create_table_as_stmt->query), DEPARSE_NODE_CONTEXT_NONE);
62736276
deparseAppendStringInfoChar(state, ' ');
62746277

62756278
if (create_table_as_stmt->into->skipData)
@@ -6303,7 +6306,7 @@ static void deparseViewStmt(DeparseState *state, ViewStmt *view_stmt)
63036306
deparseOptWith(state, view_stmt->options);
63046307

63056308
deparseAppendStringInfoString(state, "AS ");
6306-
deparseSelectStmt(state, castNode(SelectStmt, view_stmt->query));
6309+
deparseSelectStmt(state, castNode(SelectStmt, view_stmt->query), DEPARSE_NODE_CONTEXT_NONE);
63076310
deparseAppendStringInfoChar(state, ' ');
63086311

63096312
switch (view_stmt->withCheckOption)
@@ -9073,7 +9076,7 @@ static void deparseDeclareCursorStmt(DeparseState *state, DeclareCursorStmt *dec
90739076

90749077
deparseAppendStringInfoString(state, "FOR ");
90759078

9076-
deparseSelectStmt(state, castNode(SelectStmt, declare_cursor_stmt->query));
9079+
deparseSelectStmt(state, castNode(SelectStmt, declare_cursor_stmt->query), DEPARSE_NODE_CONTEXT_NONE);
90779080
}
90789081

90799082
static void deparseFetchStmt(DeparseState *state, FetchStmt *fetch_stmt)
@@ -11025,7 +11028,7 @@ static void deparseJsonArrayQueryConstructor(DeparseState *state, JsonArrayQuery
1102511028
{
1102611029
deparseAppendStringInfoString(state, "JSON_ARRAY(");
1102711030

11028-
deparseSelectStmt(state, castNode(SelectStmt, json_array_query_constructor->query));
11031+
deparseSelectStmt(state, castNode(SelectStmt, json_array_query_constructor->query), DEPARSE_NODE_CONTEXT_NONE);
1102911032
deparseJsonFormat(state, json_array_query_constructor->format);
1103011033
deparseJsonOutput(state, json_array_query_constructor->output);
1103111034

@@ -11412,7 +11415,7 @@ static void deparsePreparableStmt(DeparseState *state, Node *node)
1141211415
switch (nodeTag(node))
1141311416
{
1141411417
case T_SelectStmt:
11415-
deparseSelectStmt(state, castNode(SelectStmt, node));
11418+
deparseSelectStmt(state, castNode(SelectStmt, node), DEPARSE_NODE_CONTEXT_NONE);
1141611419
break;
1141711420
case T_InsertStmt:
1141811421
deparseInsertStmt(state, castNode(InsertStmt, node));
@@ -11437,7 +11440,7 @@ static void deparseRuleActionStmt(DeparseState *state, Node *node)
1143711440
switch (nodeTag(node))
1143811441
{
1143911442
case T_SelectStmt:
11440-
deparseSelectStmt(state, castNode(SelectStmt, node));
11443+
deparseSelectStmt(state, castNode(SelectStmt, node), DEPARSE_NODE_CONTEXT_NONE);
1144111444
break;
1144211445
case T_InsertStmt:
1144311446
deparseInsertStmt(state, castNode(InsertStmt, node));
@@ -11462,7 +11465,7 @@ static void deparseExplainableStmt(DeparseState *state, Node *node)
1146211465
switch (nodeTag(node))
1146311466
{
1146411467
case T_SelectStmt:
11465-
deparseSelectStmt(state, castNode(SelectStmt, node));
11468+
deparseSelectStmt(state, castNode(SelectStmt, node), DEPARSE_NODE_CONTEXT_NONE);
1146611469
break;
1146711470
case T_InsertStmt:
1146811471
deparseInsertStmt(state, castNode(InsertStmt, node));
@@ -11859,7 +11862,7 @@ static void deparseStmt(DeparseState *state, Node *node)
1185911862
deparseSecLabelStmt(state, castNode(SecLabelStmt, node));
1186011863
break;
1186111864
case T_SelectStmt:
11862-
deparseSelectStmt(state, castNode(SelectStmt, node));
11865+
deparseSelectStmt(state, castNode(SelectStmt, node), DEPARSE_NODE_CONTEXT_NONE);
1186311866
break;
1186411867
case T_TransactionStmt:
1186511868
deparseTransactionStmt(state, castNode(TransactionStmt, node));

0 commit comments

Comments
 (0)