Skip to content

Commit 344c350

Browse files
committed
Implement INSERT
1 parent 05a067e commit 344c350

File tree

3 files changed

+186
-5
lines changed

3 files changed

+186
-5
lines changed

src/sqlParser.jison

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
[\w]+[\u4e00-\u9fa5]+[0-9a-zA-Z_\u4e00-\u9fa5]* return 'IDENTIFIER'
1616
[\u4e00-\u9fa5][0-9a-zA-Z_\u4e00-\u9fa5]* return 'IDENTIFIER'
1717
SELECT return 'SELECT'
18+
INSERT return 'INSERT'
19+
DEFAULT return 'DEFAULT'
1820
ALL return 'ALL'
1921
ANY return 'ANY'
2022
DISTINCT return 'DISTINCT'
@@ -67,6 +69,8 @@ ORDER\s+BY return 'ORDER_
6769
GROUP\s+BY return 'GROUP_BY'
6870
IGNORE return 'IGNORE'
6971
LOW_PRIORITY return 'LOW_PRIORITY'
72+
DELAYED return 'DELAYED'
73+
HIGH_PRIORITY return 'HIGH_PRIORITY'
7074
FORCE return 'FORCE'
7175
INNER return 'INNER'
7276
CROSS return 'CROSS'
@@ -91,6 +95,12 @@ SHARE return 'SHARE'
9195
MODE return 'MODE'
9296
OJ return 'OJ'
9397
LIMIT return 'LIMIT'
98+
INTO return 'INTO'
99+
VALUE return 'VALUE'
100+
VALUES return 'VALUES'
101+
DUPLICATE return 'DUPLICATE'
102+
KEY return 'KEY'
103+
UPDATE return 'UPDATE'
94104

95105
"," return ','
96106
"=" return '='
@@ -168,13 +178,74 @@ main
168178
query
169179
: selectClause
170180
| updateClause
181+
| insertClause
182+
;
183+
184+
insertClause
185+
: INSERT priority_opt ignore_opt
186+
into_opt identifier
187+
partitionOpt
188+
insert_cols
189+
insert_source
190+
on_dup_assigns
191+
{
192+
$$ = {
193+
type: 'Insert',
194+
priority: $2,
195+
ignore: $3,
196+
into: $4,
197+
table: $5,
198+
partitions: $6,
199+
cols: $7,
200+
src: $8,
201+
duplicateAssignments: $9
202+
}
203+
}
204+
;
205+
206+
insert_source
207+
: insert_value value_list_list { $$ = { type: 'Values', keyword: $1, values: $2 } }
208+
| selectClause
209+
;
210+
211+
on_dup_assigns
212+
: { $$ = null}
213+
| ON DUPLICATE KEY UPDATE assignment_list { $$ = $5 }
214+
;
215+
216+
insert_cols
217+
: { $$ = null}
218+
| '(' identifier_list ')' { $$ = $2 }
219+
;
220+
221+
value
222+
: expr | DEFAULT
223+
;
224+
225+
value_list
226+
: value_list ',' value { $1.value.push($3); }
227+
| value { $$ = { type: 'ValueList', value: [ $1 ] } }
228+
;
229+
230+
value_list_list
231+
: value_list_list ',' '(' value_list ')' { $1.value.push($4); }
232+
| '(' value_list ')' { $$ = { type: 'InsertList', value: [ $2 ] } }
233+
;
234+
235+
insert_value
236+
: VALUE | VALUES
237+
;
238+
239+
into_opt
240+
: { $$ = null }
241+
| INTO { $$ = $1 }
171242
;
172243

173244
updateClause
174245
: UPDATE low_priority_opt ignore_opt
175246
table_refrences
176247
SET
177-
assignmentList
248+
assignment_list
178249
where_opt
179250
order_by_opt
180251
limit_opt
@@ -197,6 +268,13 @@ low_priority_opt
197268
| LOW_PRIORITY { $$ = $1 }
198269
;
199270

271+
priority_opt
272+
: { $$ = null }
273+
| LOW_PRIORITY { $$ = $1 }
274+
| HIGH_PRIORITY { $$ = $1 }
275+
| DELAYED { $$ = $1 }
276+
;
277+
200278
ignore_opt
201279
: { $$ = null }
202280
| IGNORE { $$ = $1 }
@@ -206,8 +284,8 @@ assignment
206284
: identifier '=' expr { $$ = { type: 'Assignment', left: $1, right: $3 } }
207285
;
208286

209-
assignmentList
210-
: assignmentList ',' assignment { $1.value.push($3); }
287+
assignment_list
288+
: assignment_list ',' assignment { $1.value.push($3); }
211289
| assignment { $$ = { type: 'AssignmentList', value: [ $1 ] } }
212290
;
213291

src/stringify.js

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ Sql.prototype.travelMain = function(ast) {
5959
this.travelSelect(ast.value);
6060
} else if (ast.value.type === 'Update') {
6161
this.travelUpdate(ast.value);
62+
} else if (ast.value.type === 'Insert') {
63+
this.travelInsert(ast.value);
6264
} else {
6365
throw new Error('Unknown query value type');
6466
}
@@ -129,6 +131,64 @@ Sql.prototype.travelSelect = function(ast) {
129131
this.appendKeyword(ast.updateLockMode);
130132
}
131133
}
134+
Sql.prototype.travelInsert = function(ast) {
135+
this.appendKeyword('insert', true);
136+
137+
if (ast.lowPriority) {
138+
this.appendKeyword('low_priority');
139+
}
140+
if (ast.ignore) {
141+
this.appendKeyword('ignore');
142+
}
143+
if (ast.into) {
144+
this.appendKeyword('into');
145+
}
146+
this.travelTableRefrence(ast.table);
147+
if (ast.partitions) {
148+
this.travelPartitions(ast.partitions);
149+
}
150+
if (ast.cols) {
151+
this.travel('(');
152+
this.travelIdentifierList(ast.cols);
153+
this.travel(')');
154+
}
155+
this.travel(ast.value);
156+
if (ast.src.type === 'Select') {
157+
this.travelSelect(ast.src);
158+
} else if (ast.src.type === 'Values') {
159+
this.travel(ast.src.keyword);
160+
this.travelInsertRows(ast.src.values);
161+
}
162+
if (ast.duplicateAssignments) {
163+
this.appendKeyword('ON');
164+
this.appendKeyword('DUPLICATE');
165+
this.appendKeyword('KEY');
166+
this.appendKeyword('UPDATE');
167+
this.travelAssignments(ast.duplicateAssignments);
168+
}
169+
}
170+
Sql.prototype.travelInsertRows = function(ast) {
171+
for (var i = 0; i < ast.value.length; i++) {
172+
var x = ast.value[i];
173+
this.travel('(');
174+
this.travelValueList(x.value);
175+
this.travel(')');
176+
177+
if (i !== ast.value.length - 1) {
178+
this.append(',', true);
179+
}
180+
}
181+
}
182+
Sql.prototype.travelValueList = function(ast) {
183+
for (var i = 0; i < ast.length; i++) {
184+
var x = ast[i];
185+
this.travel(x);
186+
187+
if (i !== ast.length - 1) {
188+
this.append(',', true);
189+
}
190+
}
191+
}
132192
Sql.prototype.travelUpdate = function(ast) {
133193
this.appendKeyword('update', true);
134194
if (ast.lowPriority) {
@@ -154,9 +214,9 @@ Sql.prototype.travelUpdate = function(ast) {
154214
Sql.prototype.travelAssignments = function(ast) {
155215
for (var i = 0; i < ast.value.length; i++) {
156216
var x = ast.value[i];
157-
this.travelIdentifier(x.left);
217+
this.travel(x.left);
158218
this.travel('=');
159-
this.travelIdentifier(x.right);
219+
this.travel(x.right);
160220

161221
if (i !== ast.value.length - 1) {
162222
this.append(',', true);

test/main.test.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ AND (rd.rd_numberofrooms <= (select sum(rn.reservation_numberofrooms) as count_r
137137
testParser('select a from b limit 2;');
138138
});
139139

140+
it ('subquery.', function () {
141+
testParser('select a from (select 1 as x) b limit 2;');
142+
});
143+
140144
it('update0', function () {
141145
testParser('update A SET b=2 WHERE c=3;');
142146
});
@@ -148,4 +152,43 @@ AND (rd.rd_numberofrooms <= (select sum(rn.reservation_numberofrooms) as count_r
148152
it('update2', function () {
149153
testParser('update LOW_PRIORITY ignore A, B, C SET b=2, `C`.c=d WHERE e=4 ORDER BY d DESC limit 1;');
150154
});
155+
156+
it('insert0', function () {
157+
testParser('INSERT INTO A VALUES (a, `b`), (c, 3)');
158+
});
159+
160+
it('insert1', function () {
161+
testParser('INSERT DELAYED IGNORE INTO A VALUE (a, DEFAULT, 3+2)');
162+
});
163+
164+
it('insert2', function () {
165+
testParser('INSERT DELAYED IGNORE INTO A VALUE (a, `b`)');
166+
});
167+
168+
it('insert3', function () {
169+
testParser('INSERT DELAYED IGNORE INTO A (`a`, b, c) VALUE (1, 2+3)');
170+
});
171+
172+
it('insert4', function () {
173+
testParser('INSERT DELAYED IGNORE INTO `s0`.`A` PARTITION (p0, p1) (`a`, b, c) VALUE (1, 2+3)');
174+
});
175+
176+
it('insert5', function () {
177+
testParser(`
178+
INSERT DELAYED IGNORE INTO \`s0\`.\`A\`
179+
PARTITION (p0, p1) (\`a\`, b, c)
180+
VALUE (1, 2+3), (5, '6')
181+
ON DUPLICATE KEY UPDATE q=q+1, c=b
182+
`);
183+
});
184+
185+
it('insert6', function () {
186+
testParser(`
187+
INSERT HIGH_PRIORITY \`massdrop\`.\`A\`
188+
PARTITION (p0, p1) (\`a\`, b, c)
189+
SELECT 1+1 as b, d
190+
FROM B
191+
ON DUPLICATE KEY UPDATE q=q+1, c=b
192+
`);
193+
});
151194
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy