diff --git a/__fixtures__/generated/generated.json b/__fixtures__/generated/generated.json index 982b01a3..d026e733 100644 --- a/__fixtures__/generated/generated.json +++ b/__fixtures__/generated/generated.json @@ -79,6 +79,7 @@ "pretty/misc-14.sql": "CREATE TRIGGER decrease_job_queue_count_on_delete \n AFTER DELETE ON dashboard_jobs.jobs \n FOR EACH ROW\n WHEN ( OLD.queue_name IS NOT NULL ) \n EXECUTE PROCEDURE dashboard_jobs.tg_decrease_job_queue_count ()", "pretty/misc-15.sql": "ALTER DEFAULT PRIVILEGES IN SCHEMA dashboard_jobs \n GRANT EXECUTE ON FUNCTIONS TO administrator", "pretty/misc-16.sql": "GRANT EXECUTE ON FUNCTION dashboard_private.uuid_generate_seeded_uuid TO PUBLIC", + "pretty/misc-17.sql": "SELECT CAST(t.date AT TIME ZONE $$America/New_York$$ AS text)::date FROM tbl t", "pretty/cte-1.sql": "WITH regional_sales AS (SELECT region, SUM(sales_amount) as total_sales FROM sales GROUP BY region) SELECT * FROM regional_sales", "pretty/cte-2.sql": "WITH regional_sales AS (SELECT region, SUM(sales_amount) as total_sales FROM sales GROUP BY region), top_regions AS (SELECT region FROM regional_sales WHERE total_sales > 1000000) SELECT * FROM top_regions", "pretty/cte-3.sql": "WITH RECURSIVE employee_hierarchy AS (SELECT id, name, manager_id, 1 as level FROM employees WHERE manager_id IS NULL UNION ALL SELECT e.id, e.name, e.manager_id, eh.level + 1 FROM employees e JOIN employee_hierarchy eh ON e.manager_id = eh.id) SELECT * FROM employee_hierarchy", @@ -21285,6 +21286,7 @@ "misc/issues-14.sql": "SELECT (1 IS NOT NULL) IS DISTINCT FROM (2 IS NOT NULL)", "misc/issues-15.sql": "select \"A\" from \"table_name\"", "misc/issues-16.sql": "select \"AA\" from \"table_name\"", + "misc/issues-17.sql": "SELECT CAST(t.date AT TIME ZONE $$America/New_York$$ AS text)::date FROM tbl t", "misc/inflection-1.sql": "CREATE SCHEMA inflection", "misc/inflection-2.sql": "GRANT USAGE ON SCHEMA inflection TO PUBLIC", "misc/inflection-3.sql": "ALTER DEFAULT PRIVILEGES IN SCHEMA inflection \n GRANT EXECUTE ON FUNCTIONS TO PUBLIC", diff --git a/__fixtures__/kitchen-sink/misc/issues.sql b/__fixtures__/kitchen-sink/misc/issues.sql index 02e39944..d3806f4c 100644 --- a/__fixtures__/kitchen-sink/misc/issues.sql +++ b/__fixtures__/kitchen-sink/misc/issues.sql @@ -71,4 +71,7 @@ SELECT (1 IS NOT NULL) IS DISTINCT FROM (2 IS NOT NULL); -- https://github.com/launchql/pgsql-parser/issues/101 select "A" from "table_name"; -select "AA" from "table_name"; \ No newline at end of file +select "AA" from "table_name"; + +-- https://github.com/launchql/pgsql-parser/issues/217 +SELECT CAST(t.date AT TIME ZONE $$America/New_York$$ AS text)::date FROM tbl t; \ No newline at end of file diff --git a/__fixtures__/kitchen-sink/pretty/misc.sql b/__fixtures__/kitchen-sink/pretty/misc.sql index 41259005..86b2fbe9 100644 --- a/__fixtures__/kitchen-sink/pretty/misc.sql +++ b/__fixtures__/kitchen-sink/pretty/misc.sql @@ -229,3 +229,7 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA dashboard_jobs -- 16. grant execute on function GRANT EXECUTE ON FUNCTION dashboard_private.uuid_generate_seeded_uuid TO PUBLIC; + + +-- https://github.com/launchql/pgsql-parser/issues/217 +SELECT CAST(t.date AT TIME ZONE $$America/New_York$$ AS text)::date FROM tbl t; \ No newline at end of file diff --git a/packages/deparser/__tests__/kitchen-sink/misc-issues.test.ts b/packages/deparser/__tests__/kitchen-sink/misc-issues.test.ts index 76c7afd4..758a6d03 100644 --- a/packages/deparser/__tests__/kitchen-sink/misc-issues.test.ts +++ b/packages/deparser/__tests__/kitchen-sink/misc-issues.test.ts @@ -19,6 +19,7 @@ it('misc-issues', async () => { "misc/issues-13.sql", "misc/issues-14.sql", "misc/issues-15.sql", - "misc/issues-16.sql" + "misc/issues-16.sql", + "misc/issues-17.sql" ]); }); diff --git a/packages/deparser/__tests__/kitchen-sink/pretty-misc.test.ts b/packages/deparser/__tests__/kitchen-sink/pretty-misc.test.ts index 5a57f1e6..4ea3778e 100644 --- a/packages/deparser/__tests__/kitchen-sink/pretty-misc.test.ts +++ b/packages/deparser/__tests__/kitchen-sink/pretty-misc.test.ts @@ -19,6 +19,7 @@ it('pretty-misc', async () => { "pretty/misc-13.sql", "pretty/misc-14.sql", "pretty/misc-15.sql", - "pretty/misc-16.sql" + "pretty/misc-16.sql", + "pretty/misc-17.sql" ]); }); diff --git a/packages/deparser/__tests__/misc/__snapshots__/pg-catalog.test.ts.snap b/packages/deparser/__tests__/misc/__snapshots__/pg-catalog.test.ts.snap index 0916aeb6..462d9f90 100644 --- a/packages/deparser/__tests__/misc/__snapshots__/pg-catalog.test.ts.snap +++ b/packages/deparser/__tests__/misc/__snapshots__/pg-catalog.test.ts.snap @@ -3,7 +3,7 @@ exports[`should format pg_catalog.char with pretty option enabled 1`] = ` "CREATE TABLE dashboard_jobs.jobs ( id bigserial PRIMARY KEY, - queue_name text DEFAULT public.gen_random_uuid()::text, + queue_name text DEFAULT (public.gen_random_uuid())::text, task_identifier text NOT NULL, payload pg_catalog.json DEFAULT '{}'::json NOT NULL, priority int DEFAULT 0 NOT NULL, diff --git a/packages/deparser/__tests__/pretty/__snapshots__/misc-pretty.test.ts.snap b/packages/deparser/__tests__/pretty/__snapshots__/misc-pretty.test.ts.snap index 71ed4c55..136e03e3 100644 --- a/packages/deparser/__tests__/pretty/__snapshots__/misc-pretty.test.ts.snap +++ b/packages/deparser/__tests__/pretty/__snapshots__/misc-pretty.test.ts.snap @@ -32,6 +32,8 @@ exports[`non-pretty: pretty/misc-15.sql 1`] = `"ALTER DEFAULT PRIVILEGES IN SCHE exports[`non-pretty: pretty/misc-16.sql 1`] = `"GRANT EXECUTE ON FUNCTION dashboard_private.uuid_generate_seeded_uuid TO PUBLIC"`; +exports[`non-pretty: pretty/misc-17.sql 1`] = `"SELECT CAST((t.date AT TIME ZONE 'America/New_York')::text AS date) FROM tbl AS t"`; + exports[`pretty: pretty/misc-1.sql 1`] = ` "WITH recent_orders AS (SELECT @@ -295,3 +297,8 @@ exports[`pretty: pretty/misc-15.sql 1`] = ` `; exports[`pretty: pretty/misc-16.sql 1`] = `"GRANT EXECUTE ON FUNCTION dashboard_private.uuid_generate_seeded_uuid TO PUBLIC"`; + +exports[`pretty: pretty/misc-17.sql 1`] = ` +"SELECT CAST((t.date AT TIME ZONE 'America/New_York')::text AS date) +FROM tbl AS t" +`; diff --git a/packages/deparser/__tests__/pretty/misc-pretty.test.ts b/packages/deparser/__tests__/pretty/misc-pretty.test.ts index 92c96f57..33d717cd 100644 --- a/packages/deparser/__tests__/pretty/misc-pretty.test.ts +++ b/packages/deparser/__tests__/pretty/misc-pretty.test.ts @@ -16,7 +16,8 @@ const testCases = [ 'pretty/misc-13.sql', 'pretty/misc-14.sql', 'pretty/misc-15.sql', - 'pretty/misc-16.sql' + 'pretty/misc-16.sql', + 'pretty/misc-17.sql', ]; const prettyTest = new PrettyTest(testCases); diff --git a/packages/deparser/src/deparser.ts b/packages/deparser/src/deparser.ts index 16d3e884..26fde3a9 100644 --- a/packages/deparser/src/deparser.ts +++ b/packages/deparser/src/deparser.ts @@ -2255,9 +2255,14 @@ export class Deparser implements DeparserVisitor { if (isSimpleArgument || isFunctionCall) { // For simple arguments, avoid :: syntax if they have complex structure - if (isSimpleArgument && (arg.includes('(') || arg.startsWith('-'))) { - } else { + const shouldUseCastSyntax = isSimpleArgument && (arg.includes('(') || arg.startsWith('-')); + + if (!shouldUseCastSyntax) { const cleanTypeName = typeName.replace('pg_catalog.', ''); + // Wrap FuncCall arguments in parentheses to prevent operator precedence issues + if (isFunctionCall) { + return `${context.parens(arg)}::${cleanTypeName}`; + } return `${arg}::${cleanTypeName}`; } }