diff --git a/src/languages/postgresql/postgresql.formatter.ts b/src/languages/postgresql/postgresql.formatter.ts index d3d8a51fd2..14ba55171b 100644 --- a/src/languages/postgresql/postgresql.formatter.ts +++ b/src/languages/postgresql/postgresql.formatter.ts @@ -8,6 +8,7 @@ const reservedSelect = expandPhrases(['SELECT [ALL | DISTINCT]']); const reservedClauses = expandPhrases([ // queries 'WITH [RECURSIVE]', + 'INTO [TEMPORARY | TEMP | UNLOGGED] [TABLE]', 'FROM', 'WHERE', 'GROUP BY [ALL | DISTINCT]', diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index e8e99adfea..455522ed99 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -25,6 +25,44 @@ describe('PostgreSqlFormatter', () => { const language = 'postgresql'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); + // Issue #864 + it.each([ + 'INTO', + 'INTO TABLE', + 'INTO TEMP', + 'INTO TEMP TABLE', + 'INTO TEMPORARY', + 'INTO TEMPORARY TABLE', + 'INTO UNLOGGED', + 'INTO UNLOGGED TABLE', + ])('formats SELECT %s on a separate line', into => { + const result = format(`SELECT id, name ${into} new_users FROM users WHERE active;`); + expect(result).toBe(dedent` + SELECT + id, + name + ${into} + new_users + FROM + users + WHERE + active; + `); + expect(format(result)).toBe(result); + }); + + it('formats the case of SELECT INTO modifiers', () => { + expect(format('select id into temporary table new_users from users;', { keywordCase: 'upper' })) + .toBe(dedent` + SELECT + id + INTO TEMPORARY TABLE + new_users + FROM + users; + `); + }); + behavesLikePostgresqlFormatter(format); supportsCreateView(format, { orReplace: true, materialized: true, ifNotExists: true }); supportsCreateTable(format, { ifNotExists: true });