@@ -219,9 +219,11 @@ export class Deparser implements DeparserVisitor {
219219
220220 if ( ! node . op || node . op === 'SETOP_NONE' ) {
221221 if ( node . valuesLists == null ) {
222- output . push ( 'SELECT' ) ;
222+ if ( ! this . formatter . isPretty ( ) || ! node . targetList ) {
223+ output . push ( 'SELECT' ) ;
224+ }
223225 }
224- } else {
226+ } else {
225227 const leftStmt = this . SelectStmt ( node . larg as t . SelectStmt , context ) ;
226228 const rightStmt = this . SelectStmt ( node . rarg as t . SelectStmt , context ) ;
227229
@@ -272,26 +274,40 @@ export class Deparser implements DeparserVisitor {
272274 }
273275 }
274276
277+ // Handle DISTINCT clause - in pretty mode, we'll include it in the SELECT clause
278+ let distinctPart = '' ;
275279 if ( node . distinctClause ) {
276280 const distinctClause = ListUtils . unwrapList ( node . distinctClause ) ;
277281 if ( distinctClause . length > 0 && Object . keys ( distinctClause [ 0 ] ) . length > 0 ) {
278- output . push ( 'DISTINCT ON' ) ;
279282 const clause = distinctClause
280283 . map ( e => this . visit ( e as Node , { ...context , select : true } ) )
281284 . join ( ', ' ) ;
282- output . push ( this . formatter . parens ( clause ) ) ;
285+ distinctPart = ' DISTINCT ON ' + this . formatter . parens ( clause ) ;
283286 } else {
284- output . push ( 'DISTINCT' ) ;
287+ distinctPart = ' DISTINCT' ;
288+ }
289+
290+ if ( ! this . formatter . isPretty ( ) ) {
291+ if ( distinctClause . length > 0 && Object . keys ( distinctClause [ 0 ] ) . length > 0 ) {
292+ output . push ( 'DISTINCT ON' ) ;
293+ const clause = distinctClause
294+ . map ( e => this . visit ( e as Node , { ...context , select : true } ) )
295+ . join ( ', ' ) ;
296+ output . push ( this . formatter . parens ( clause ) ) ;
297+ } else {
298+ output . push ( 'DISTINCT' ) ;
299+ }
285300 }
286301 }
287302
288303 if ( node . targetList ) {
289304 const targetList = ListUtils . unwrapList ( node . targetList ) ;
290- if ( this . formatter . isPretty ( ) && targetList . length > 1 ) {
291- const targets = targetList
292- . map ( e => this . formatter . indent ( this . visit ( e as Node , { ...context , select : true } ) ) )
293- . join ( ',' + this . formatter . newline ( ) ) ;
294- output . push ( this . formatter . newline ( ) + targets ) ;
305+ if ( this . formatter . isPretty ( ) ) {
306+ const targetStrings = targetList
307+ . map ( e => this . formatter . indent ( this . visit ( e as Node , { ...context , select : true } ) ) ) ;
308+ const formattedTargets = targetStrings . join ( ',' + this . formatter . newline ( ) ) ;
309+ output . push ( 'SELECT' + distinctPart ) ;
310+ output . push ( formattedTargets ) ;
295311 } else {
296312 const targets = targetList
297313 . map ( e => this . visit ( e as Node , { ...context , select : true } ) )
@@ -306,14 +322,15 @@ export class Deparser implements DeparserVisitor {
306322 }
307323
308324 if ( node . fromClause ) {
309- output . push ( 'FROM' ) ;
310325 const fromList = ListUtils . unwrapList ( node . fromClause ) ;
311- if ( this . formatter . isPretty ( ) && fromList . length > 1 ) {
326+ if ( this . formatter . isPretty ( ) ) {
327+ output . push ( 'FROM' ) ;
312328 const fromItems = fromList
313- . map ( e => this . formatter . indent ( this . deparse ( e as Node , { ...context , from : true } ) ) )
314- . join ( ',' + this . formatter . newline ( ) ) ;
315- output . push ( this . formatter . newline ( ) + fromItems ) ;
329+ . map ( e => this . deparse ( e as Node , { ...context , from : true } ) )
330+ . join ( ', ' ) ;
331+ output . push ( fromItems ) ;
316332 } else {
333+ output . push ( 'FROM' ) ;
317334 const fromItems = fromList
318335 . map ( e => this . deparse ( e as Node , { ...context , from : true } ) )
319336 . join ( ', ' ) ;
@@ -322,10 +339,11 @@ export class Deparser implements DeparserVisitor {
322339 }
323340
324341 if ( node . whereClause ) {
325- output . push ( 'WHERE' ) ;
326342 if ( this . formatter . isPretty ( ) ) {
343+ output . push ( 'WHERE' ) ;
327344 output . push ( this . formatter . indent ( this . visit ( node . whereClause as Node , context ) ) ) ;
328345 } else {
346+ output . push ( 'WHERE' ) ;
329347 output . push ( this . visit ( node . whereClause as Node , context ) ) ;
330348 }
331349 }
@@ -340,14 +358,15 @@ export class Deparser implements DeparserVisitor {
340358 }
341359
342360 if ( node . groupClause ) {
343- output . push ( 'GROUP BY' ) ;
344361 const groupList = ListUtils . unwrapList ( node . groupClause ) ;
345- if ( this . formatter . isPretty ( ) && groupList . length > 1 ) {
362+ if ( this . formatter . isPretty ( ) ) {
346363 const groupItems = groupList
347364 . map ( e => this . formatter . indent ( this . visit ( e as Node , { ...context , group : true } ) ) )
348365 . join ( ',' + this . formatter . newline ( ) ) ;
349- output . push ( this . formatter . newline ( ) + groupItems ) ;
366+ output . push ( 'GROUP BY' ) ;
367+ output . push ( groupItems ) ;
350368 } else {
369+ output . push ( 'GROUP BY' ) ;
351370 const groupItems = groupList
352371 . map ( e => this . visit ( e as Node , { ...context , group : true } ) )
353372 . join ( ', ' ) ;
@@ -356,10 +375,11 @@ export class Deparser implements DeparserVisitor {
356375 }
357376
358377 if ( node . havingClause ) {
359- output . push ( 'HAVING' ) ;
360378 if ( this . formatter . isPretty ( ) ) {
379+ output . push ( 'HAVING' ) ;
361380 output . push ( this . formatter . indent ( this . visit ( node . havingClause as Node , context ) ) ) ;
362381 } else {
382+ output . push ( 'HAVING' ) ;
363383 output . push ( this . visit ( node . havingClause as Node , context ) ) ;
364384 }
365385 }
@@ -374,14 +394,15 @@ export class Deparser implements DeparserVisitor {
374394 }
375395
376396 if ( node . sortClause ) {
377- output . push ( 'ORDER BY' ) ;
378397 const sortList = ListUtils . unwrapList ( node . sortClause ) ;
379- if ( this . formatter . isPretty ( ) && sortList . length > 1 ) {
398+ if ( this . formatter . isPretty ( ) ) {
380399 const sortItems = sortList
381400 . map ( e => this . formatter . indent ( this . visit ( e as Node , { ...context , sort : true } ) ) )
382401 . join ( ',' + this . formatter . newline ( ) ) ;
383- output . push ( this . formatter . newline ( ) + sortItems ) ;
402+ output . push ( 'ORDER BY' ) ;
403+ output . push ( sortItems ) ;
384404 } else {
405+ output . push ( 'ORDER BY' ) ;
385406 const sortItems = sortList
386407 . map ( e => this . visit ( e as Node , { ...context , sort : true } ) )
387408 . join ( ', ' ) ;
@@ -390,13 +411,23 @@ export class Deparser implements DeparserVisitor {
390411 }
391412
392413 if ( node . limitCount ) {
393- output . push ( 'LIMIT' ) ;
394- output . push ( this . visit ( node . limitCount as Node , context ) ) ;
414+ if ( this . formatter . isPretty ( ) ) {
415+ output . push ( 'LIMIT' ) ;
416+ output . push ( this . visit ( node . limitCount as Node , context ) ) ;
417+ } else {
418+ output . push ( 'LIMIT' ) ;
419+ output . push ( this . visit ( node . limitCount as Node , context ) ) ;
420+ }
395421 }
396422
397423 if ( node . limitOffset ) {
398- output . push ( 'OFFSET' ) ;
399- output . push ( this . visit ( node . limitOffset as Node , context ) ) ;
424+ if ( this . formatter . isPretty ( ) ) {
425+ output . push ( 'OFFSET' ) ;
426+ output . push ( this . visit ( node . limitOffset as Node , context ) ) ;
427+ } else {
428+ output . push ( 'OFFSET' ) ;
429+ output . push ( this . visit ( node . limitOffset as Node , context ) ) ;
430+ }
400431 }
401432
402433 if ( node . lockingClause ) {
@@ -408,7 +439,8 @@ export class Deparser implements DeparserVisitor {
408439 }
409440
410441 if ( this . formatter . isPretty ( ) ) {
411- return output . join ( this . formatter . newline ( ) ) ;
442+ const filteredOutput = output . filter ( item => item . trim ( ) !== '' ) ;
443+ return filteredOutput . join ( this . formatter . newline ( ) ) ;
412444 }
413445 return output . join ( ' ' ) ;
414446 }
0 commit comments