pgsql-deparser 17.12.2 → 17.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/deparser.d.ts +0 -2
- package/deparser.js +179 -223
- package/esm/deparser.js +179 -223
- package/esm/kwlist.js +531 -0
- package/esm/utils/quote-utils.js +77 -46
- package/kwlist.d.ts +16 -0
- package/kwlist.js +535 -0
- package/package.json +4 -3
- package/utils/quote-utils.d.ts +23 -2
- package/utils/quote-utils.js +77 -46
package/utils/quote-utils.js
CHANGED
|
@@ -1,53 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.QuoteUtils = void 0;
|
|
4
|
-
const
|
|
5
|
-
'all', 'analyse', 'analyze', 'and', 'any', 'array', 'as', 'asc', 'asymmetric',
|
|
6
|
-
'authorization', 'binary', 'both', 'case', 'cast', 'check', 'collate', 'collation',
|
|
7
|
-
'column', 'concurrently', 'constraint', 'create', 'cross', 'current_catalog',
|
|
8
|
-
'current_date', 'current_role', 'current_schema', 'current_time', 'current_timestamp',
|
|
9
|
-
'current_user', 'default', 'deferrable', 'desc', 'distinct', 'do', 'else', 'end',
|
|
10
|
-
'except', 'false', 'fetch', 'for', 'foreign', 'freeze', 'from', 'full', 'grant',
|
|
11
|
-
'group', 'having', 'ilike', 'in', 'initially', 'inner', 'intersect', 'into', 'is',
|
|
12
|
-
'isnull', 'join', 'lateral', 'leading', 'left', 'like', 'limit', 'localtime',
|
|
13
|
-
'localtimestamp', 'natural', 'not', 'notnull', 'null', 'offset', 'on', 'only',
|
|
14
|
-
'or', 'order', 'outer', 'overlaps', 'placing', 'primary', 'references', 'returning',
|
|
15
|
-
'right', 'select', 'session_user', 'similar', 'some', 'symmetric', 'table', 'tablesample',
|
|
16
|
-
'then', 'to', 'trailing', 'true', 'union', 'unique', 'user', 'using', 'variadic',
|
|
17
|
-
'verbose', 'when', 'where', 'window', 'with'
|
|
18
|
-
]);
|
|
4
|
+
const kwlist_1 = require("../kwlist");
|
|
19
5
|
class QuoteUtils {
|
|
20
|
-
static needsQuotes(value) {
|
|
21
|
-
if (!value || typeof value !== 'string') {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
const lowerValue = value.toLowerCase();
|
|
25
|
-
if (RESERVED_WORDS.has(lowerValue)) {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
if (!/^[a-z_][a-z0-9_$]*$/i.test(value)) {
|
|
29
|
-
return true;
|
|
30
|
-
}
|
|
31
|
-
if (value !== value.toLowerCase()) {
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
static quote(value) {
|
|
37
|
-
if (value == null) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
if (Array.isArray(value)) {
|
|
41
|
-
return value.map(v => this.quote(v));
|
|
42
|
-
}
|
|
43
|
-
if (typeof value !== 'string') {
|
|
44
|
-
return value;
|
|
45
|
-
}
|
|
46
|
-
if (this.needsQuotes(value)) {
|
|
47
|
-
return `"${value}"`;
|
|
48
|
-
}
|
|
49
|
-
return value;
|
|
50
|
-
}
|
|
51
6
|
static escape(literal) {
|
|
52
7
|
return `'${literal.replace(/'/g, "''")}'`;
|
|
53
8
|
}
|
|
@@ -81,5 +36,81 @@ class QuoteUtils {
|
|
|
81
36
|
// unless it's a raw \x... bytea-style literal.
|
|
82
37
|
return !/^\\x[0-9a-fA-F]+$/i.test(value) && value.includes('\\');
|
|
83
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Quote an identifier only if needed
|
|
41
|
+
*
|
|
42
|
+
* This is a TypeScript port of PostgreSQL's quote_identifier() function from ruleutils.c
|
|
43
|
+
* https://github.com/postgres/postgres/blob/fab5cd3dd1323f9e66efeb676c4bb212ff340204/src/backend/utils/adt/ruleutils.c#L13055-L13137
|
|
44
|
+
*
|
|
45
|
+
* Can avoid quoting if ident starts with a lowercase letter or underscore
|
|
46
|
+
* and contains only lowercase letters, digits, and underscores, *and* is
|
|
47
|
+
* not any SQL keyword. Otherwise, supply quotes.
|
|
48
|
+
*
|
|
49
|
+
* When quotes are needed, embedded double quotes are properly escaped as "".
|
|
50
|
+
*/
|
|
51
|
+
static quoteIdentifier(ident) {
|
|
52
|
+
if (!ident)
|
|
53
|
+
return ident;
|
|
54
|
+
let nquotes = 0;
|
|
55
|
+
let safe = true;
|
|
56
|
+
// Check first character: must be lowercase letter or underscore
|
|
57
|
+
const firstChar = ident[0];
|
|
58
|
+
if (!((firstChar >= 'a' && firstChar <= 'z') || firstChar === '_')) {
|
|
59
|
+
safe = false;
|
|
60
|
+
}
|
|
61
|
+
// Check all characters
|
|
62
|
+
for (let i = 0; i < ident.length; i++) {
|
|
63
|
+
const ch = ident[i];
|
|
64
|
+
if ((ch >= 'a' && ch <= 'z') ||
|
|
65
|
+
(ch >= '0' && ch <= '9') ||
|
|
66
|
+
(ch === '_')) {
|
|
67
|
+
// okay
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
safe = false;
|
|
71
|
+
if (ch === '"') {
|
|
72
|
+
nquotes++;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (safe) {
|
|
77
|
+
// Check for keyword. We quote keywords except for unreserved ones.
|
|
78
|
+
// (In some cases we could avoid quoting a col_name or type_func_name
|
|
79
|
+
// keyword, but it seems much harder than it's worth to tell that.)
|
|
80
|
+
const kwKind = (0, kwlist_1.keywordKindOf)(ident);
|
|
81
|
+
if (kwKind !== 'NO_KEYWORD' && kwKind !== 'UNRESERVED_KEYWORD') {
|
|
82
|
+
safe = false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (safe) {
|
|
86
|
+
return ident; // no change needed
|
|
87
|
+
}
|
|
88
|
+
// Build quoted identifier with escaped embedded quotes
|
|
89
|
+
let result = '"';
|
|
90
|
+
for (let i = 0; i < ident.length; i++) {
|
|
91
|
+
const ch = ident[i];
|
|
92
|
+
if (ch === '"') {
|
|
93
|
+
result += '"'; // escape " as ""
|
|
94
|
+
}
|
|
95
|
+
result += ch;
|
|
96
|
+
}
|
|
97
|
+
result += '"';
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Quote a possibly-qualified identifier
|
|
102
|
+
*
|
|
103
|
+
* This is a TypeScript port of PostgreSQL's quote_qualified_identifier() function from ruleutils.c
|
|
104
|
+
* https://github.com/postgres/postgres/blob/fab5cd3dd1323f9e66efeb676c4bb212ff340204/src/backend/utils/adt/ruleutils.c#L13139-L13156
|
|
105
|
+
*
|
|
106
|
+
* Return a name of the form qualifier.ident, or just ident if qualifier
|
|
107
|
+
* is null/undefined, quoting each component if necessary.
|
|
108
|
+
*/
|
|
109
|
+
static quoteQualifiedIdentifier(qualifier, ident) {
|
|
110
|
+
if (qualifier) {
|
|
111
|
+
return `${QuoteUtils.quoteIdentifier(qualifier)}.${QuoteUtils.quoteIdentifier(ident)}`;
|
|
112
|
+
}
|
|
113
|
+
return QuoteUtils.quoteIdentifier(ident);
|
|
114
|
+
}
|
|
84
115
|
}
|
|
85
116
|
exports.QuoteUtils = QuoteUtils;
|