@@ -371,8 +371,20 @@ export class Deparser implements DeparserVisitor {
371371 const targetList = ListUtils . unwrapList ( node . targetList ) ;
372372 if ( this . formatter . isPretty ( ) ) {
373373 if ( targetList . length === 1 ) {
374- const target = this . visit ( targetList [ 0 ] as Node , { ...context , select : true } ) ;
375- output . push ( 'SELECT' + distinctPart + ' ' + target ) ;
374+ const targetNode = targetList [ 0 ] as Node ;
375+ const target = this . visit ( targetNode , { ...context , select : true } ) ;
376+
377+ // Check if single target is complex - if so, use multiline format
378+ if ( this . isComplexSelectTarget ( targetNode ) ) {
379+ output . push ( 'SELECT' + distinctPart ) ;
380+ if ( this . containsMultilineStringLiteral ( target ) ) {
381+ output . push ( target ) ;
382+ } else {
383+ output . push ( this . formatter . indent ( target ) ) ;
384+ }
385+ } else {
386+ output . push ( 'SELECT' + distinctPart + ' ' + target ) ;
387+ }
376388 } else {
377389 const targetStrings = targetList
378390 . map ( e => {
@@ -824,6 +836,67 @@ export class Deparser implements DeparserVisitor {
824836 ) ;
825837 }
826838
839+ private isComplexSelectTarget ( node : any ) : boolean {
840+ if ( ! node ) return false ;
841+
842+ // Always complex: CASE expressions
843+ if ( node . CaseExpr ) return true ;
844+
845+ // Always complex: Subqueries and subselects
846+ if ( node . SubLink ) return true ;
847+
848+ // Always complex: Boolean tests and expressions
849+ if ( node . NullTest || node . BooleanTest || node . BoolExpr ) return true ;
850+
851+ // COALESCE and similar functions - complex if multiple arguments
852+ if ( node . CoalesceExpr ) {
853+ const args = node . CoalesceExpr . args ;
854+ if ( args && Array . isArray ( args ) && args . length > 1 ) return true ;
855+ }
856+
857+ // Function calls - complex if multiple args or has clauses
858+ if ( node . FuncCall ) {
859+ const funcCall = node . FuncCall ;
860+ const args = funcCall . args ? ( Array . isArray ( funcCall . args ) ? funcCall . args : [ funcCall . args ] ) : [ ] ;
861+
862+ // Complex if has window clause, filter, order by, etc.
863+ if ( funcCall . over || funcCall . agg_filter || funcCall . agg_order || funcCall . agg_distinct ) {
864+ return true ;
865+ }
866+
867+ // Complex if multiple arguments
868+ if ( args . length > 1 ) return true ;
869+
870+ if ( args . length === 1 ) {
871+ return this . isComplexSelectTarget ( args [ 0 ] ) ;
872+ }
873+ }
874+
875+ if ( node . A_Expr ) {
876+ const expr = node . A_Expr ;
877+ // Check if operands are complex
878+ if ( expr . lexpr && this . isComplexSelectTarget ( expr . lexpr ) ) return true ;
879+ if ( expr . rexpr && this . isComplexSelectTarget ( expr . rexpr ) ) return true ;
880+ return false ;
881+ }
882+
883+ if ( node . TypeCast ) {
884+ return this . isComplexSelectTarget ( node . TypeCast . arg ) ;
885+ }
886+
887+ if ( node . A_ArrayExpr ) return true ;
888+
889+ if ( node . A_Indirection ) {
890+ return this . isComplexSelectTarget ( node . A_Indirection . arg ) ;
891+ }
892+
893+ if ( node . A_Const || node . ColumnRef || node . ParamRef || node . A_Star ) {
894+ return false ;
895+ }
896+
897+ return false ;
898+ }
899+
827900 visitBetweenRange ( rexpr : any , context : DeparserContext ) : string {
828901 if ( rexpr && 'List' in rexpr && rexpr . List ?. items ) {
829902 const items = rexpr . List . items . map ( ( item : any ) => this . visit ( item , context ) ) ;
0 commit comments