Skip to content

Commit 7052778

Browse files
committed
comment per statement to disable static validation
1 parent 3895ee7 commit 7052778

File tree

8 files changed

+240
-441
lines changed

8 files changed

+240
-441
lines changed

sample/definitions/function/static_error_disabled.pgsql.json

Lines changed: 0 additions & 403 deletions
This file was deleted.

sample/definitions/function/static_error_disabled.pgsql renamed to sample/definitions/trigger/static_error_disabled.pgsql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ begin
1414
end;
1515
$function$;
1616

17-
-- TODO some kind of flag for disabling static analysis only per statement
1817
-- plpgsql-language-server:disable-static
18+
create trigger update_users_2_modtime_disabled -- error silenced
19+
before update on users_2 for each row
20+
execute function update_updated_at_column ();
21+
1922
create trigger update_users_2_modtime -- should raise error
2023
before update on users_2 for each row
2124
execute function update_updated_at_column ();
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
[
2+
{
3+
"RawStmt": {
4+
"stmt": {
5+
"DropStmt": {
6+
"objects": [
7+
{
8+
"List": {
9+
"items": [
10+
{
11+
"String": {
12+
"str": "users_2"
13+
}
14+
}
15+
]
16+
}
17+
}
18+
],
19+
"removeType": "OBJECT_TABLE",
20+
"behavior": "DROP_CASCADE",
21+
"missing_ok": true
22+
}
23+
},
24+
"stmt_len": 36
25+
}
26+
},
27+
{
28+
"RawStmt": {
29+
"stmt": {
30+
"CreateStmt": {
31+
"relation": {
32+
"relname": "users_2",
33+
"inh": true,
34+
"relpersistence": "p"
35+
},
36+
"tableElts": [
37+
{
38+
"ColumnDef": {
39+
"colname": "id",
40+
"typeName": {
41+
"names": [
42+
{
43+
"String": {
44+
"str": "pg_catalog"
45+
}
46+
},
47+
{
48+
"String": {
49+
"str": "int4"
50+
}
51+
}
52+
],
53+
"typemod": -1
54+
},
55+
"is_local": true,
56+
"constraints": [
57+
{
58+
"Constraint": {
59+
"contype": "CONSTR_NOTNULL"
60+
}
61+
},
62+
{
63+
"Constraint": {
64+
"contype": "CONSTR_PRIMARY"
65+
}
66+
}
67+
]
68+
}
69+
}
70+
],
71+
"oncommit": "ONCOMMIT_NOOP"
72+
}
73+
},
74+
"stmt_len": 60
75+
}
76+
},
77+
{
78+
"RawStmt": {
79+
"stmt": {
80+
"CreateFunctionStmt": {
81+
"replace": true,
82+
"funcname": [
83+
{
84+
"String": {
85+
"str": "update_updated_at_column"
86+
}
87+
}
88+
],
89+
"returnType": {
90+
"names": [
91+
{
92+
"String": {
93+
"str": "trigger"
94+
}
95+
}
96+
],
97+
"typemod": -1
98+
},
99+
"options": [
100+
{
101+
"DefElem": {
102+
"defname": "language",
103+
"arg": {
104+
"String": {
105+
"str": "plpgsql"
106+
}
107+
},
108+
"defaction": "DEFELEM_UNSPEC"
109+
}
110+
},
111+
{
112+
"DefElem": {
113+
"defname": "as",
114+
"arg": {
115+
"List": {
116+
"items": [
117+
{
118+
"String": {
119+
"str": "\nbegin\n new.updated_at = NOW();\n return new;\nend;\n"
120+
}
121+
}
122+
]
123+
}
124+
},
125+
"defaction": "DEFELEM_UNSPEC"
126+
}
127+
}
128+
]
129+
}
130+
},
131+
"stmt_len": 171
132+
}
133+
},
134+
{
135+
"RawStmt": {
136+
"stmt": {
137+
"CreateTrigStmt": {
138+
"trigname": "update_users_2_modtime_disabled",
139+
"relation": {
140+
"relname": "users_2",
141+
"inh": true,
142+
"relpersistence": "p"
143+
},
144+
"funcname": [
145+
{
146+
"String": {
147+
"str": "update_updated_at_column"
148+
}
149+
}
150+
],
151+
"row": true,
152+
"timing": 2,
153+
"events": 16
154+
}
155+
},
156+
"stmt_len": 195
157+
}
158+
},
159+
{
160+
"RawStmt": {
161+
"stmt": {
162+
"CreateTrigStmt": {
163+
"trigname": "update_users_2_modtime",
164+
"relation": {
165+
"relname": "users_2",
166+
"inh": true,
167+
"relpersistence": "p"
168+
},
169+
"funcname": [
170+
{
171+
"String": {
172+
"str": "update_updated_at_column"
173+
}
174+
}
175+
],
176+
"row": true,
177+
"timing": 2,
178+
"events": 16
179+
}
180+
},
181+
"stmt_len": 148
182+
}
183+
}
184+
]

sample/definitions/function/static_error_trigger_column_does_not_exist.pgsql.json renamed to sample/definitions/trigger/static_error_trigger_column_does_not_exist.pgsql.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@
347347
"events": 16
348348
}
349349
},
350-
"stmt_len": 190
350+
"stmt_len": 148
351351
}
352352
},
353353
{

server/src/postgres/queries/queryFileStaticAnalysis.ts

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from "@/postgres/parameters"
99
import { FunctionInfo, TriggerInfo } from "@/postgres/parsers/parseFunctions"
1010
import { Settings } from "@/settings"
11+
import { DISABLE_STATIC_VALIDATION_RE } from "@/utilities/regex"
1112
import {
1213
getLineRangeFromBuffer,
1314
getRangeFromBuffer, getTextAllRange,
@@ -162,40 +163,44 @@ export async function queryFileStaticAnalysis(
162163
location: number | undefined,
163164
stmtLen?: number,
164165
) {
165-
rows.forEach(
166-
(row) => {
167-
const range = (() => {
168-
if (location === undefined) {
169-
return getTextAllRange(document)
170-
}
171-
if (stmtLen) {
172-
return getRangeFromBuffer(
173-
fileText,
174-
location + 1,
175-
location + 1 + stmtLen,
176-
)
166+
rows.forEach((row) => {
167+
const range = (() => {
168+
if (location === undefined) {
169+
return getTextAllRange(document)
170+
}
171+
if (stmtLen) {
172+
const stmt = fileText.slice(location + 1, location + 1 + stmtLen)
173+
if (DISABLE_STATIC_VALIDATION_RE
174+
.test(stmt)) {
175+
return
177176
}
178177

179-
const lineRange = getLineRangeFromBuffer(
178+
return getRangeFromBuffer(
180179
fileText,
181-
location,
182-
row.lineno ? row.lineno - 1 : 0,
180+
location + 1,
181+
location + 1 + stmtLen,
183182
)
183+
}
184+
const lineRange = getLineRangeFromBuffer(
185+
fileText,
186+
location,
187+
row.lineno ? row.lineno - 1 : 0,
188+
)
189+
190+
if (!lineRange) {
191+
return getTextAllRange(document)
192+
}
193+
194+
return lineRange
195+
})()
196+
197+
if (!range) {
198+
return
199+
}
184200

185-
if (!lineRange) {
186-
return getTextAllRange(document)
187-
}
188-
189-
return lineRange
190-
})()
191-
192-
errors.push({
193-
level: row.level, range, message: row.message,
194-
})
195-
196-
}
197-
,
198-
)
199-
201+
errors.push({
202+
level: row.level, range, message: row.message,
203+
})
204+
})
200205
}
201206
}

server/src/services/validation.test.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ describe("Validate Tests", () => {
7474

7575
it("TRIGGER on inexistent field", async () => {
7676
const diagnostics = await validateSampleFile(
77-
"definitions/function/static_error_trigger_column_does_not_exist.pgsql",
77+
"definitions/trigger/static_error_trigger_column_does_not_exist.pgsql",
7878
)
7979

8080
expect(diagnostics).toStrictEqual([
@@ -90,13 +90,21 @@ describe("Validate Tests", () => {
9090
])
9191
})
9292

93-
// TODO
94-
it.skip("static analysis disabled on invalid statement", async () => {
93+
it("static analysis disabled on invalid statement", async () => {
9594
const diagnostics = await validateSampleFile(
96-
"definitions/function/static_error_disabled.pgsql",
95+
"definitions/trigger/static_error_disabled.pgsql",
9796
)
9897

99-
expect(diagnostics).toStrictEqual([])
98+
if (!diagnostics) {
99+
throw new Error("")
100+
}
101+
if (diagnostics?.length === 0) {
102+
throw new Error("")
103+
}
104+
105+
expect(diagnostics).toHaveLength(1)
106+
expect(diagnostics[0].message)
107+
.toContain("record \"new\" has no field \"updated_at\"")
100108
})
101109

102110
it("FUNCTION column does not exists", async () => {

server/src/utilities/regex.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* eslint-disable max-len */
2+
13
export function escapeRegex(string: string): string {
24
return string.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&")
35
}
@@ -8,5 +10,5 @@ export const BEGIN_RE = /^([\s]*begin[\s]*;)/igm
810
export const COMMIT_RE = /^([\s]*commit[\s]*;)/igm
911
export const ROLLBACK_RE = /^([\s]*rollback[\s]*;)/igm
1012

11-
// eslint-disable-next-line max-len
1213
export const DISABLE_STATEMENT_VALIDATION_RE = /^ *-- +plpgsql-language-server:disable *$/m
14+
export const DISABLE_STATIC_VALIDATION_RE = /^ *-- +plpgsql-language-server:disable-static *$/m

0 commit comments

Comments
 (0)