Skip to content

Commit e2e8787

Browse files
author
诺奈
committed
support insert...select
1 parent f6bedaf commit e2e8787

6 files changed

Lines changed: 28 additions & 7 deletions

File tree

pegjs/mariadb.pegjs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,12 +1084,16 @@ set_item
10841084
return { column: c, value: v, table: tbl && tbl[0] };
10851085
}
10861086

1087+
insert_value_clause
1088+
= value_clause
1089+
/ select_stmt_nake
1090+
10871091
replace_insert_stmt
10881092
= ri:replace_insert __
1089-
KW_INTO __
1093+
KW_INTO? __
10901094
t:table_ref_list __ LPAREN __
10911095
c:column_list __ RPAREN __
1092-
v:value_clause {
1096+
v:insert_value_clause {
10931097
if (t) t.forEach(tt => tableList.add(`insert::${tt.db}::${tt.table}`));
10941098
if (c) {
10951099
let table = null

pegjs/mysql.pegjs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,13 +1081,16 @@ set_item
10811081
= tbl:(ident __ DOT)? __ c:column __ '=' __ v:additive_expr {
10821082
return { column: c, value: v, table: tbl && tbl[0] };
10831083
}
1084+
insert_value_clause
1085+
= value_clause
1086+
/ select_stmt_nake
10841087

10851088
replace_insert_stmt
10861089
= ri:replace_insert __
1087-
KW_INTO __
1090+
KW_INTO? __
10881091
t:table_ref_list __ LPAREN __
10891092
c:column_list __ RPAREN __
1090-
v:value_clause {
1093+
v:insert_value_clause {
10911094
if (t) t.forEach(tt => tableList.add(`insert::${tt.db}::${tt.table}`));
10921095
if (c) {
10931096
let table = null

pegjs/postgresql.pegjs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,12 +1082,16 @@ set_item
10821082
return { column: c, value: v, table: tbl && tbl[0] };
10831083
}
10841084

1085+
insert_value_clause
1086+
= value_clause
1087+
/ select_stmt_nake
1088+
10851089
replace_insert_stmt
10861090
= ri:replace_insert __
1087-
KW_INTO __
1091+
KW_INTO? __
10881092
t:table_ref_list __ LPAREN __
10891093
c:column_list __ RPAREN __
1090-
v:value_clause {
1094+
v:insert_value_clause {
10911095
if (t) t.forEach(tt => tableList.add(`insert::${tt.db}::${tt.table}`));
10921096
if (c) {
10931097
let table = null

src/insert.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { tablesToSQL } from './tables'
22
import { exprToSQL } from './expr'
33
import { identifierToSql, commonOptionConnector, hasVal } from './util'
4+
import { selectToSQL } from './select'
45

56
/**
67
* @param {Array} values
78
* @return {string}
89
*/
910
function valuesToSQL(values) {
11+
if (values.type === 'select') return selectToSQL(values)
1012
const clauses = values.map(exprToSQL)
1113
return `(${clauses.join('),(')})`
1214
}
@@ -15,7 +17,7 @@ function insertToSQL(stmt) {
1517
const { table, columns, values, where } = stmt
1618
const clauses = ['INSERT INTO', tablesToSQL(table)]
1719
if (Array.isArray(columns)) clauses.push(`(${columns.map(identifierToSql).join(', ')})`)
18-
clauses.push(commonOptionConnector('VALUES', valuesToSQL, values))
20+
clauses.push(commonOptionConnector(Array.isArray(values) ? 'VALUES' : '', valuesToSQL, values))
1921
clauses.push(commonOptionConnector('WHERE', exprToSQL, where))
2022
return clauses.filter(hasVal).join(' ')
2123
}

src/util.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ let parserOpt = DEFAULT_OPT
2121

2222
function commonOptionConnector(keyword, action, opt) {
2323
if (!opt) return
24+
if (!keyword) return action(opt)
2425
return `${keyword.toUpperCase()} ${action(opt)}`
2526
}
2627

test/insert.spec.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ describe('insert', () => {
3131
expect(backSQL).to.be.equal("INSERT INTO `t1` VALUES ('1223','name'),('1224','name2')")
3232
})
3333

34+
it('should support parse insert from select', () => {
35+
const sql = 'INSERT INTO t1(col_a, col_b) select col_a, col_b from t2'
36+
const ast = parser.astify(sql)
37+
const backSQL = parser.sqlify(ast)
38+
expect(backSQL).to.be.equal("INSERT INTO `t1` (`col_a`, `col_b`) SELECT `col_a`, `col_b` FROM `t2`")
39+
})
40+
3441
it('should parse insert and select', () => {
3542
const sql = 'INSERT INTO t1 values("1223", "name") ; SELECT * FROM t'
3643
const [sqla, sqlb] = sql.split(';')

0 commit comments

Comments
 (0)