Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions __fixtures__/generated/generated.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
"pretty/misc-4.sql": "SELECT p.id, p.title,\n CASE\n WHEN EXISTS (\n SELECT 1 FROM reviews r\n WHERE r.product_id = p.id AND r.rating >= 4\n ) THEN 'Popular'\n ELSE 'Unrated'\n END AS status\nFROM products p\nWHERE p.archived = false",
"pretty/misc-5.sql": "WITH logs AS (\n SELECT id, payload::json->>'event' AS event, (payload::json->>'ts')::timestamp AS ts\n FROM event_log\n WHERE ts > NOW() - INTERVAL '7 days'\n)\nSELECT event, COUNT(*) AS freq\nFROM (\n SELECT DISTINCT event, ts::date AS event_day\n FROM logs\n) d\nGROUP BY event\nORDER BY freq DESC",
"pretty/misc-6.sql": "SELECT \n o.id AS order_id,\n u.name AS user_name,\n p.name AS product_name,\n s.status,\n sh.shipped_at,\n r.refund_amount\nFROM orders o\nJOIN users u \n ON o.user_id = u.id\nJOIN order_items oi \n ON oi.order_id = o.id\nJOIN products p \n ON (\n (p.id = oi.product_id AND p.available = true)\n OR \n (p.sku = oi.product_sku AND (p.discontinued = false OR p.replacement_id IS NOT NULL))\n )\nLEFT JOIN shipping sh \n ON (\n sh.order_id = o.id \n AND (\n (sh.carrier = 'UPS' AND sh.tracking_number IS NOT NULL)\n OR \n (sh.carrier = 'FedEx' AND sh.shipped_at > o.created_at + INTERVAL '1 day')\n )\n )\nLEFT JOIN statuses s \n ON s.id = o.status_id \n AND (\n s.name != 'cancelled'\n OR (s.name = 'cancelled' AND s.updated_at > NOW() - INTERVAL '7 days')\n )\nLEFT JOIN refunds r \n ON r.order_id = o.id \n AND (\n (r.status = 'approved' AND r.processed_at IS NOT NULL)\n OR \n (r.status = 'pending' AND r.requested_at < NOW() - INTERVAL '14 days')\n )\nWHERE o.created_at > NOW() - INTERVAL '90 days'\n AND u.active = true\n AND (\n s.status = 'shipped' \n OR (\n s.status = 'processing' \n AND EXISTS (\n SELECT 1 FROM order_notes n WHERE n.order_id = o.id AND n.note ILIKE '%expedite%'\n )\n )\n )\nORDER BY o.created_at DESC",
"pretty/misc-7.sql": "select (CASE \nWHEN ( n = 2 ) THEN ARRAY[ 'month' ]\nWHEN ( n = 4 ) THEN ARRAY[ 'year' ]\nWHEN ( n = 6 ) THEN ARRAY[ 'year', 'month' ]\nWHEN ( n = 8 ) THEN ARRAY[ 'day' ]\nWHEN ( n = 1024 ) THEN ARRAY[ 'hour' ]\nWHEN ( n = 1032 ) THEN ARRAY[ 'day', 'hour' ]\nWHEN ( n = 2048 ) THEN ARRAY[ 'minute' ]\nWHEN ( n = 3072 ) THEN ARRAY[ 'hour', 'minute' ]\nWHEN ( n = 3080 ) THEN ARRAY[ 'day', 'minute' ]\nWHEN ( n = 4096 ) THEN ARRAY[ 'second' ]\nWHEN ( n = 6144 ) THEN ARRAY[ 'minute', 'second' ]\nWHEN ( n = 7168 ) THEN ARRAY[ 'hour', 'second' ]\nWHEN ( n = 7176 ) THEN ARRAY[ 'day', 'second' ]\nWHEN ( n = 32767 ) THEN ARRAY[]::text[]\nEND)",
"pretty/misc-8.sql": "SELECT (\n CASE \n WHEN n = 2 OR n = 3 THEN ARRAY['month', COALESCE(extra_label, 'unknown')]\n WHEN n IN (4, 5) THEN \n CASE \n WHEN is_leap_year THEN ARRAY['year', 'leap']\n ELSE ARRAY['year']\n END\n WHEN n = 6 THEN ARRAY['year', 'month', 'quarter']\n WHEN n = 8 THEN ARRAY['day', 'week', compute_label(n)]\n WHEN n = 1024 THEN ARRAY['hour', format('%s-hour', extra_label)]\n WHEN n = 1032 AND flag = true THEN ARRAY['day', 'hour', 'flagged']\n WHEN n BETWEEN 2048 AND 2049 THEN ARRAY['minute', 'tick']\n WHEN n = 3072 THEN ARRAY['hour', 'minute', current_setting('timezone')]\n WHEN n = 3080 THEN ARRAY['day', 'minute', to_char(now(), 'HH24:MI')]\n WHEN n IN (4096, 4097, 4098) THEN ARRAY['second', 'millisecond']\n WHEN n = 6144 THEN ARRAY['minute', 'second', CASE WHEN use_micro = true THEN 'microsecond' ELSE 'none' END]\n WHEN n = 7168 OR (n > 7170 AND n < 7180) THEN ARRAY['hour', 'second', 'buffered']\n WHEN n = 7176 THEN ARRAY['day', 'second', extra_info::text]\n WHEN n = 32767 THEN ARRAY[]::text[]\n ELSE ARRAY['undefined', 'unknown', 'fallback']\n END\n)",
"pretty/misc-9.sql": "SELECT \n user_id,\n (CASE \n WHEN EXISTS (SELECT 1 FROM logins WHERE logins.user_id = users.user_id AND success = false) \n THEN 'risky'\n ELSE 'safe'\n END) AS risk_status\nFROM users",
"pretty/misc-10.sql": "SELECT * \nFROM orders\nWHERE \n status = (CASE \n WHEN shipped_at IS NOT NULL THEN 'shipped'\n WHEN canceled_at IS NOT NULL THEN 'canceled'\n ELSE 'processing'\n END)",
"pretty/misc-11.sql": "SELECT *\nFROM users u,\nLATERAL (\n SELECT \n (CASE \n WHEN u.is_admin THEN 'admin_dashboard'\n ELSE 'user_dashboard'\n END) AS dashboard_view\n) AS derived",
"pretty/misc-12.sql": "SELECT \n id,\n (SELECT \n CASE \n WHEN COUNT(*) > 5 THEN 'frequent'\n ELSE 'occasional'\n END\n FROM purchases p WHERE p.user_id = u.id) AS purchase_freq\nFROM users u",
"pretty/misc-13.sql": "SELECT \n id,\n CASE \n WHEN rank() OVER (ORDER BY score DESC) = 1 THEN 'top'\n ELSE 'normal'\n END AS tier\nFROM players",
"pretty/create_table-1.sql": "CREATE TABLE users (\n id SERIAL PRIMARY KEY,\n name TEXT NOT NULL,\n email TEXT UNIQUE\n)",
"pretty/create_table-2.sql": "CREATE TABLE products (\n id SERIAL PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n price DECIMAL(10,2) CHECK (price > 0),\n category_id INTEGER,\n description TEXT,\n created_at TIMESTAMP DEFAULT now(),\n updated_at TIMESTAMP,\n UNIQUE (name, category_id),\n FOREIGN KEY (category_id) REFERENCES categories(id)\n)",
"pretty/create_table-3.sql": "CREATE TABLE orders (\n id SERIAL PRIMARY KEY,\n subtotal DECIMAL(10,2) NOT NULL,\n tax_rate DECIMAL(5,4) DEFAULT 0.0825,\n tax_amount DECIMAL(10,2) GENERATED ALWAYS AS (subtotal * tax_rate) STORED,\n total DECIMAL(10,2) GENERATED ALWAYS AS (subtotal + tax_amount) STORED\n)",
Expand Down
102 changes: 102 additions & 0 deletions __fixtures__/kitchen-sink/pretty/misc.sql
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,105 @@ WHERE o.created_at > NOW() - INTERVAL '90 days'
)
)
ORDER BY o.created_at DESC;

-- 7. A case

select (CASE
WHEN ( n = 2 ) THEN ARRAY[ 'month' ]
WHEN ( n = 4 ) THEN ARRAY[ 'year' ]
WHEN ( n = 6 ) THEN ARRAY[ 'year', 'month' ]
WHEN ( n = 8 ) THEN ARRAY[ 'day' ]
WHEN ( n = 1024 ) THEN ARRAY[ 'hour' ]
WHEN ( n = 1032 ) THEN ARRAY[ 'day', 'hour' ]
WHEN ( n = 2048 ) THEN ARRAY[ 'minute' ]
WHEN ( n = 3072 ) THEN ARRAY[ 'hour', 'minute' ]
WHEN ( n = 3080 ) THEN ARRAY[ 'day', 'minute' ]
WHEN ( n = 4096 ) THEN ARRAY[ 'second' ]
WHEN ( n = 6144 ) THEN ARRAY[ 'minute', 'second' ]
WHEN ( n = 7168 ) THEN ARRAY[ 'hour', 'second' ]
WHEN ( n = 7176 ) THEN ARRAY[ 'day', 'second' ]
WHEN ( n = 32767 ) THEN ARRAY[]::text[]
END);

-- 8. A case

SELECT (
CASE
WHEN n = 2 OR n = 3 THEN ARRAY['month', COALESCE(extra_label, 'unknown')]
WHEN n IN (4, 5) THEN
CASE
WHEN is_leap_year THEN ARRAY['year', 'leap']
ELSE ARRAY['year']
END
WHEN n = 6 THEN ARRAY['year', 'month', 'quarter']
WHEN n = 8 THEN ARRAY['day', 'week', compute_label(n)]
WHEN n = 1024 THEN ARRAY['hour', format('%s-hour', extra_label)]
WHEN n = 1032 AND flag = true THEN ARRAY['day', 'hour', 'flagged']
WHEN n BETWEEN 2048 AND 2049 THEN ARRAY['minute', 'tick']
WHEN n = 3072 THEN ARRAY['hour', 'minute', current_setting('timezone')]
WHEN n = 3080 THEN ARRAY['day', 'minute', to_char(now(), 'HH24:MI')]
WHEN n IN (4096, 4097, 4098) THEN ARRAY['second', 'millisecond']
WHEN n = 6144 THEN ARRAY['minute', 'second', CASE WHEN use_micro = true THEN 'microsecond' ELSE 'none' END]
WHEN n = 7168 OR (n > 7170 AND n < 7180) THEN ARRAY['hour', 'second', 'buffered']
WHEN n = 7176 THEN ARRAY['day', 'second', extra_info::text]
WHEN n = 32767 THEN ARRAY[]::text[]
ELSE ARRAY['undefined', 'unknown', 'fallback']
END
);


-- 9. A case with select

SELECT
user_id,
(CASE
WHEN EXISTS (SELECT 1 FROM logins WHERE logins.user_id = users.user_id AND success = false)
THEN 'risky'
ELSE 'safe'
END) AS risk_status
FROM users;

-- 10. A case in where clause

SELECT *
FROM orders
WHERE
status = (CASE
WHEN shipped_at IS NOT NULL THEN 'shipped'
WHEN canceled_at IS NOT NULL THEN 'canceled'
ELSE 'processing'
END);

-- 11. A case in lateral join

SELECT *
FROM users u,
LATERAL (
SELECT
(CASE
WHEN u.is_admin THEN 'admin_dashboard'
ELSE 'user_dashboard'
END) AS dashboard_view
) AS derived;

-- 12. A CASE used inside a scalar subquery in SELECT

SELECT
id,
(SELECT
CASE
WHEN COUNT(*) > 5 THEN 'frequent'
ELSE 'occasional'
END
FROM purchases p WHERE p.user_id = u.id) AS purchase_freq
FROM users u;

-- 13. A case in window function

SELECT
id,
CASE
WHEN rank() OVER (ORDER BY score DESC) = 1 THEN 'top'
ELSE 'normal'
END AS tier
FROM players;
9 changes: 8 additions & 1 deletion packages/deparser/__tests__/kitchen-sink/pretty-misc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ it('pretty-misc', async () => {
"pretty/misc-3.sql",
"pretty/misc-4.sql",
"pretty/misc-5.sql",
"pretty/misc-6.sql"
"pretty/misc-6.sql",
"pretty/misc-7.sql",
"pretty/misc-8.sql",
"pretty/misc-9.sql",
"pretty/misc-10.sql",
"pretty/misc-11.sql",
"pretty/misc-12.sql",
"pretty/misc-13.sql"
]);
});
Loading