Skip to content

Commit 330a9c4

Browse files
Merge pull request taozhi8833998#362 from taozhi8833998/feature-pg-mysql
Feature pg mysql
2 parents 4cd3a37 + 7c9241b commit 330a9c4

File tree

7 files changed

+40
-18
lines changed

7 files changed

+40
-18
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "node-sql-parser",
3-
"version": "2.2.1",
3+
"version": "2.2.2",
44
"description": "simple node sql parser",
55
"main": "index.js",
66
"types": "index.d.ts",

pegjs/mysql.pegjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
'THEN': true,
7777
'TRUE': true,
7878
'TRUNCATE': true,
79-
'TYPE': true, // reserved (MySQL)
79+
// 'TYPE': true, // reserved (MySQL)
8080

8181
'UNION': true,
8282
'UPDATE': true,

pegjs/postgresql.pegjs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,15 @@ join_op
11551155
/ (KW_INNER __)? KW_JOIN { return 'INNER JOIN'; }
11561156

11571157
table_name
1158-
= dt:ident __ DOT __ STAR {
1158+
= dt:ident schema:(__ DOT __ ident) tail:(__ DOT __ ident) {
1159+
const obj = { db: null, table: dt };
1160+
if (tail !== null) {
1161+
obj.db = `${dt}.${schema[3]}`;
1162+
obj.table = tail[3];
1163+
}
1164+
return obj;
1165+
}
1166+
/ dt:ident __ DOT __ STAR {
11591167
tableList.add(`select::${dt}::(.*)`);
11601168
return {
11611169
db: dt,
@@ -1695,7 +1703,7 @@ ident_name
16951703

16961704
ident_start = [A-Za-z_]
16971705

1698-
ident_part = [A-Za-z0-9_]
1706+
ident_part = [A-Za-z0-9_\-]
16991707

17001708
// to support column name like `cf1:name` in hbase
17011709
column_part = [A-Za-z0-9_]
@@ -1761,7 +1769,7 @@ extract_filed
17611769
return f
17621770
}
17631771
extract_func
1764-
= kw:KW_EXTRACT __ LPAREN __ f:extract_filed __ KW_FROM __ t:(KW_TIMESTAMP / KW_INTERVAL / KW_TIME)? __ s:literal_string __ RPAREN {
1772+
= kw:KW_EXTRACT __ LPAREN __ f:extract_filed __ KW_FROM __ t:(KW_TIMESTAMP / KW_INTERVAL / KW_TIME)? __ s:expr __ RPAREN {
17651773
return {
17661774
type: kw.toLowerCase(),
17671775
args: {

src/expr.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { literalToSQL, toUpper, connector, extractFunToSQL } from './util'
1+
import { literalToSQL, toUpper, connector } from './util'
22
import { alterExprToSQL } from './alter'
33
import { aggrToSQL } from './aggregation'
44
import { assignToSQL } from './assign'
55
import { binaryToSQL } from './binary'
66
import { caseToSQL } from './case'
77
import { columnRefToSQL } from './column'
8-
import { castToSQL, funcToSQL } from './func'
8+
import { castToSQL, extractFunToSQL, funcToSQL } from './func'
99
import { intervalToSQL } from './interval'
1010
import { selectToSQL } from './select'
1111
import { arrayStructExprToSQL } from './array-struct'

src/func.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { exprToSQL } from './expr'
2-
import { hasVal } from './util'
2+
import { hasVal, toUpper } from './util'
33
import { overToSQL } from './over'
44

55
function castToSQL(expr) {
@@ -21,6 +21,13 @@ function castToSQL(expr) {
2121
return `${prefix}${symbolChar}${dataType}${str}${suffix}`
2222
}
2323

24+
function extractFunToSQL(stmt) {
25+
const { args, type } = stmt
26+
const { field, cast_type: castType, source } = args
27+
const result = [`${toUpper(type)}(${toUpper(field)}`, 'FROM', toUpper(castType), exprToSQL(source)]
28+
return `${result.filter(hasVal).join(' ')})`
29+
}
30+
2431
function funcToSQL(expr) {
2532
const { args, name } = expr
2633
if (!args) return name
@@ -32,5 +39,6 @@ function funcToSQL(expr) {
3239

3340
export {
3441
castToSQL,
42+
extractFunToSQL,
3543
funcToSQL,
3644
}

src/util.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,6 @@ function commonKeywordArgsToSQL(kwArgs) {
264264
return [toUpper(kwArgs.keyword), toUpper(kwArgs.args)]
265265
}
266266

267-
function extractFunToSQL(stmt) {
268-
const { args, type } = stmt
269-
const { field, cast_type: castType, source } = args
270-
const result = [`${toUpper(type)}(${toUpper(field)}`, 'FROM', toUpper(castType), literalToSQL(source)]
271-
return `${result.filter(hasVal).join(' ')})`
272-
}
273-
274267
function autoIncreatementToSQL(autoIncreatement) {
275268
if (!autoIncreatement || typeof autoIncreatement === 'string') return toUpper(autoIncreatement)
276269
const { keyword, seed, increment, parentheses } = autoIncreatement
@@ -290,5 +283,5 @@ export {
290283
connector, commonTypeValue,commentToSQL, createBinaryExpr,
291284
createValueExpr, DEFAULT_OPT, escape, literalToSQL,
292285
identifierToSql, onPartitionsToSQL, replaceParams, returningToSQL,
293-
hasVal, setParserOpt, toUpper, topToSQL, triggerEventToSQL,extractFunToSQL,
286+
hasVal, setParserOpt, toUpper, topToSQL, triggerEventToSQL,
294287
}

test/select.spec.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,12 @@ describe('select', () => {
211211
expect(parser.sqlify(ast, opt)).to.eql("SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5')");
212212
expect(parser.sqlify(parser.astify("SELECT EXTRACT(MILLISECONDS FROM TIMESTAMP '2016-12-31 13:30:15')", opt), opt)).to.eql("SELECT EXTRACT(MILLISECONDS FROM TIMESTAMP '2016-12-31 13:30:15')");
213213
expect(parser.sqlify(parser.astify("SELECT EXTRACT(MILLISECONDS FROM '2016-12-31 13:30:15')", opt), opt)).to.eql("SELECT EXTRACT(MILLISECONDS FROM '2016-12-31 13:30:15')");
214+
expect(parser.sqlify(parser.astify(`WITH tss AS
215+
(SELECT CURRENT_TIMESTAMP AS ts)
216+
SELECT
217+
EXTRACT(EPOCH FROM ts)
218+
FROM
219+
tss`, opt), opt)).to.eql('WITH tss AS (SELECT CURRENT_TIMESTAMP AS "ts") SELECT EXTRACT(EPOCH FROM "ts") FROM "tss"');
214220
});
215221

216222
it('should parse function expression', () => {
@@ -332,6 +338,13 @@ describe('select', () => {
332338
expect(backSQL).to.equal('SELECT `user0__`.`user_id` AS `userId` FROM `user` AS `user0__`')
333339
})
334340

341+
it('should support select from db.xxx.table', () => {
342+
const sql = 'select id from db-name.public.table-name'
343+
const opt = { database: 'postgresql' }
344+
const ast = parser.astify(sql, opt)
345+
const backSQL = parser.sqlify(ast,opt )
346+
expect(backSQL).to.equal('SELECT "id" FROM "db-name.public"."table-name"')
347+
})
335348

336349
it('should parse subselect', () => {
337350
const ast = parser.astify('SELECT * FROM (SELECT id FROM t1) someAlias');
@@ -1012,9 +1025,9 @@ describe('select', () => {
10121025
expect(fun).to.throw(`authority = 'select::null::b' is required in table whiteList to execute SQL = '${sql}'`)
10131026
})
10141027
it('should fail for as column reserved word check', () => {
1015-
const sql = 'SELECT id as type FROM b'
1028+
const sql = 'SELECT id as delete FROM b'
10161029
const fun = parser.astify.bind(parser, sql)
1017-
expect(fun).to.throw('Error: "type" is a reserved word, can not as alias clause')
1030+
expect(fun).to.throw('Error: "delete" is a reserved word, can not as alias clause')
10181031
})
10191032
it('should fail for as table reserved word check', () => {
10201033
const sql = 'SELECT id as bc FROM b as table'

0 commit comments

Comments
 (0)