Skip to content

Commit e583c77

Browse files
authored
fix: handle AExpr and NullTest nodes in SQL parsing (#354)
This fix addresses an issue where AExpr and NullTest nodes were not being correctly handled in SQL parsing. This ensures that expressions like and are properly interpreted and typed.
1 parent 2b0dcbe commit e583c77

File tree

4 files changed

+110
-0
lines changed

4 files changed

+110
-0
lines changed

.changeset/olive-coins-travel.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@ts-safeql/eslint-plugin": patch
3+
"@ts-safeql/generate": patch
4+
---
5+
6+
fixed an issue when dealing with AExpr and NullTest nodes

packages/eslint-plugin/src/rules/check-sql.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,27 @@ RuleTester.describe("check-sql", () => {
12771277
}),
12781278
code: "sql<{ phone_number: PhoneNumber }>`select phone_number from caregiver_phone`",
12791279
},
1280+
{
1281+
name: "select case when then jsonb with not like with type reference",
1282+
filename,
1283+
options: withConnection(connections.withTag, {
1284+
targets: [{ tag: "sql", transform: "{type}[]" }],
1285+
}),
1286+
code: `
1287+
type Meta = { is_test: boolean; };
1288+
type Caregiver = { meta: Meta | null };
1289+
1290+
await sql<Caregiver[]>\`
1291+
SELECT
1292+
CASE WHEN caregiver.id IS NOT NULL
1293+
THEN jsonb_build_object('is_test', caregiver.middle_name NOT LIKE '%test%')
1294+
ELSE NULL
1295+
END AS meta
1296+
FROM
1297+
caregiver
1298+
\`;
1299+
`,
1300+
},
12801301
],
12811302
invalid: [
12821303
{

packages/generate/src/ast-describe.ts

+40
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,49 @@ function getDescribedNode(params: {
202202
return getDescribedCaseExpr({ alias: alias, node: node.CaseExpr, context });
203203
}
204204

205+
if (node.NullTest !== undefined) {
206+
return getDescribedNullTest({ alias: alias, node: node.NullTest, context });
207+
}
208+
209+
if (node.A_Expr !== undefined) {
210+
return getDescribedAExpr({ alias: alias, node: node.A_Expr, context });
211+
}
212+
205213
return [];
206214
}
207215

216+
function getDescribedAExpr({
217+
alias,
218+
context,
219+
}: GetDescribedParamsOf<LibPgQueryAST.AExpr>): ASTDescribedColumn[] {
220+
return [
221+
{
222+
name: alias ?? "?column?",
223+
type: resolveType({
224+
context: context,
225+
nullable: false,
226+
type: context.toTypeScriptType({ name: "boolean" }),
227+
}),
228+
},
229+
];
230+
}
231+
232+
function getDescribedNullTest({
233+
alias,
234+
context,
235+
}: GetDescribedParamsOf<LibPgQueryAST.NullTest>): ASTDescribedColumn[] {
236+
return [
237+
{
238+
name: alias ?? "?column?",
239+
type: resolveType({
240+
context: context,
241+
nullable: false,
242+
type: context.toTypeScriptType({ name: "boolean" }),
243+
}),
244+
},
245+
];
246+
}
247+
208248
function getDescribedCaseExpr({
209249
alias,
210250
node,

packages/generate/src/generate.test.ts

+43
Original file line numberDiff line numberDiff line change
@@ -1500,3 +1500,46 @@ test("select case when expr with returned string literals", async () => {
15001500
expected: [["case", { kind: "type", value: "boolean" }]],
15011501
});
15021502
});
1503+
1504+
test("select case when expr is not null else is not null", async () => {
1505+
await testQuery({
1506+
query: `
1507+
SELECT
1508+
CASE WHEN TRUE
1509+
THEN caregiver.id IS NOT NULL
1510+
ELSE caregiver.id IS NOT NULL
1511+
END
1512+
FROM caregiver`,
1513+
expected: [["case", { kind: "type", value: "boolean" }]],
1514+
});
1515+
});
1516+
1517+
test("select case when with jsonb_build_object", async () => {
1518+
await testQuery({
1519+
query: `
1520+
SELECT
1521+
CASE
1522+
WHEN caregiver.id IS NOT NULL THEN (
1523+
jsonb_build_object(
1524+
'is_test',
1525+
caregiver.first_name NOT LIKE '%test%'
1526+
)
1527+
)
1528+
ELSE NULL
1529+
END AS col
1530+
FROM
1531+
caregiver`,
1532+
expected: [
1533+
[
1534+
"col",
1535+
{
1536+
kind: "union",
1537+
value: [
1538+
{ kind: "object", value: [["is_test", { kind: "type", value: "boolean" }]] },
1539+
{ kind: "type", value: "null" },
1540+
],
1541+
},
1542+
],
1543+
],
1544+
});
1545+
});

0 commit comments

Comments
 (0)