@@ -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 );
125126static void deparseIntoClause (DeparseState * state , IntoClause * into_clause );
126127static void deparseRangeVar (DeparseState * state , RangeVar * range_var , DeparseNodeContext context );
127128static 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
27692772static 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
90799082static 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