Skip to content

Commit 4f6f152

Browse files
committed
casts
1 parent 662d870 commit 4f6f152

File tree

5 files changed

+132
-4
lines changed

5 files changed

+132
-4
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`should format foreign key constraint with pretty option enabled 1`] = `
4+
"SELECT
5+
CAST('123' AS int);"
6+
`;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`should format pg_catalog.char with pretty option enabled 1`] = `
4+
"CREATE TABLE dashboard_jobs.jobs (
5+
id bigserial PRIMARY KEY,
6+
queue_name text DEFAULT CAST(public.gen_random_uuid() AS text),
7+
task_identifier text NOT NULL,
8+
payload pg_catalog.json DEFAULT CAST('{}' AS pg_catalog.json) NOT NULL,
9+
priority int DEFAULT 0 NOT NULL,
10+
run_at timestamptz DEFAULT now() NOT NULL,
11+
attempts int DEFAULT 0 NOT NULL,
12+
max_attempts int DEFAULT 25 NOT NULL,
13+
key text,
14+
last_error text,
15+
locked_at timestamptz,
16+
locked_by text,
17+
CHECK (length(key) < 513),
18+
CHECK (length(task_identifier) < 127),
19+
CHECK (max_attempts > 0),
20+
CHECK (length(queue_name) < 127),
21+
CHECK (length(locked_by) > 3),
22+
UNIQUE (key)
23+
);"
24+
`;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { expectParseDeparse } from '../../test-utils';
2+
3+
it('should format foreign key constraint with pretty option enabled', async () => {
4+
const sql = `SELECT CAST('123' AS INTEGER);`;
5+
const result = await expectParseDeparse(sql, { pretty: true });
6+
expect(result).toMatchSnapshot();
7+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { expectParseDeparse } from '../../test-utils';
2+
3+
it('should format pg_catalog.char with pretty option enabled', async () => {
4+
const sql = `
5+
CREATE TABLE dashboard_jobs.jobs (
6+
id bigserial PRIMARY KEY,
7+
queue_name text DEFAULT CAST(public.gen_random_uuid() AS text),
8+
task_identifier text NOT NULL,
9+
payload pg_catalog.json DEFAULT CAST('{}' AS pg_catalog.json) NOT NULL,
10+
priority int DEFAULT 0 NOT NULL,
11+
run_at timestamptz DEFAULT now() NOT NULL,
12+
attempts int DEFAULT 0 NOT NULL,
13+
max_attempts int DEFAULT 25 NOT NULL,
14+
key text,
15+
last_error text,
16+
locked_at timestamptz,
17+
locked_by text,
18+
CHECK (length(key) < 513),
19+
CHECK (length(task_identifier) < 127),
20+
CHECK (max_attempts > 0),
21+
CHECK (length(queue_name) < 127),
22+
CHECK (length(locked_by) > 3),
23+
UNIQUE (key)
24+
);
25+
`;
26+
const result = await expectParseDeparse(sql, { pretty: true });
27+
expect(result).toMatchSnapshot();
28+
});

packages/deparser/src/deparser.ts

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,73 @@ import { QuoteUtils } from './utils/quote-utils';
55
import { ListUtils } from './utils/list-utils';
66
import * as t from '@pgsql/types';
77

8+
/**
9+
* List of real PostgreSQL built-in types as they appear in pg_catalog.pg_type.typname.
10+
* These are stored in lowercase in PostgreSQL system catalogs.
11+
* Use these for lookups, validations, or introspection logic.
12+
*/
13+
14+
const pgCatalogTypes = [
15+
// Integers
16+
'int2', // smallint
17+
'int4', // integer
18+
'int8', // bigint
19+
20+
// Floating-point & numeric
21+
'float4', // real
22+
'float8', // double precision
23+
'numeric', // arbitrary precision (aka "decimal")
24+
25+
// Text & string
26+
'varchar', // variable-length string
27+
'char', // internal one-byte type (used in special cases)
28+
'bpchar', // blank-padded char(n)
29+
'text', // unlimited string
30+
'bool', // boolean
31+
32+
// Dates & times
33+
'date', // calendar date
34+
'time', // time without time zone
35+
'timetz', // time with time zone
36+
'timestamp', // timestamp without time zone
37+
'timestamptz', // timestamp with time zone
38+
'interval', // duration
39+
40+
// Binary & structured
41+
'bytea', // binary data
42+
'uuid', // universally unique identifier
43+
44+
// JSON & XML
45+
'json', // textual JSON
46+
'jsonb', // binary JSON
47+
'xml', // XML format
48+
49+
// Money & bitstrings
50+
'money', // currency value
51+
'bit', // fixed-length bit string
52+
'varbit', // variable-length bit string
53+
54+
// Network types
55+
'inet', // IPv4 or IPv6 address
56+
'cidr', // network address
57+
'macaddr', // MAC address (6 bytes)
58+
'macaddr8' // MAC address (8 bytes)
59+
];
60+
61+
62+
/**
63+
* Parser-level type aliases accepted by PostgreSQL SQL syntax,
64+
* but not present in pg_catalog.pg_type. These are resolved to
65+
* real types during parsing and never appear in introspection.
66+
*/
67+
const pgCatalogTypeAliases: [string, string[]][] = [
68+
['numeric', ['decimal', 'dec']],
69+
['int4', ['int', 'integer']],
70+
['float8', ['float']],
71+
['bpchar', ['character']],
72+
['varchar', ['character varying']]
73+
];
74+
875
export interface DeparserOptions {
976
newline?: string;
1077
tab?: string;
@@ -1609,10 +1676,6 @@ export class Deparser implements DeparserVisitor {
16091676
}
16101677

16111678
if (catalog === 'pg_catalog') {
1612-
const builtinTypes = ['int2', 'int4', 'int8', 'float4', 'float8', 'numeric', 'decimal',
1613-
'varchar', 'char', 'bpchar', 'text', 'bool', 'date', 'time', 'timestamp',
1614-
'timestamptz', 'interval', 'bytea', 'uuid', 'json', 'jsonb'];
1615-
16161679
let typeName = `${catalog}.${type}`;
16171680

16181681
if (type === 'bpchar' && args) {

0 commit comments

Comments
 (0)