Skip to content

Commit

Permalink
Implement INSERT
Browse files Browse the repository at this point in the history
  • Loading branch information
gpittarelli committed Apr 10, 2018
1 parent c4b1c55 commit 84f4402
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 6 deletions.
89 changes: 85 additions & 4 deletions src/sqlParser.jison
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
[\w]+[\u4e00-\u9fa5]+[0-9a-zA-Z_\u4e00-\u9fa5]* return 'IDENTIFIER'
[\u4e00-\u9fa5][0-9a-zA-Z_\u4e00-\u9fa5]* return 'IDENTIFIER'
SELECT return 'SELECT'
INSERT return 'INSERT'
DEFAULT return 'DEFAULT'
ALL return 'ALL'
ANY return 'ANY'
DISTINCT return 'DISTINCT'
Expand Down Expand Up @@ -67,6 +69,8 @@ ORDER\s+BY return 'ORDER_
GROUP\s+BY return 'GROUP_BY'
IGNORE return 'IGNORE'
LOW_PRIORITY return 'LOW_PRIORITY'
DELAYED return 'DELAYED'
HIGH_PRIORITY return 'HIGH_PRIORITY'
FORCE return 'FORCE'
INNER return 'INNER'
CROSS return 'CROSS'
Expand All @@ -91,6 +95,12 @@ SHARE return 'SHARE'
MODE return 'MODE'
OJ return 'OJ'
LIMIT return 'LIMIT'
INTO return 'INTO'
VALUE return 'VALUE'
VALUES return 'VALUES'
DUPLICATE return 'DUPLICATE'
KEY return 'KEY'
UPDATE return 'UPDATE'

"," return ','
"=" return '='
Expand Down Expand Up @@ -168,13 +178,74 @@ main
query
: selectClause
| updateClause
| insertClause
;

insertClause
: INSERT priority_opt ignore_opt
into_opt simple_table_factor
partitionOpt
insert_cols
insert_source
on_dup_assigns
{
$$ = {
type: 'Insert',
priority: $2,
ignore: $3,
into: $4,
table: $5,
partitions: $6,
cols: $7,
src: $8,
duplicateAssignments: $9
}
}
;

insert_source
: insert_value value_list_list { $$ = { type: 'Values', keyword: $1, values: $2 } }
| selectClause
;

on_dup_assigns
: { $$ = null}
| ON DUPLICATE KEY UPDATE assignment_list { $$ = $5 }
;

insert_cols
: { $$ = null}
| '(' identifier_list ')' { $$ = $2 }
;

value
: expr | DEFAULT
;

value_list
: value_list ',' value { $1.value.push($3); }
| value { $$ = { type: 'ValueList', value: [ $1 ] } }
;

value_list_list
: value_list_list ',' '(' value_list ')' { $1.value.push($4); }
| '(' value_list ')' { $$ = { type: 'InsertList', value: [ $2 ] } }
;

insert_value
: VALUE | VALUES
;

into_opt
: { $$ = null }
| INTO { $$ = $1 }
;

updateClause
: UPDATE low_priority_opt ignore_opt
table_refrences
SET
assignmentList
assignment_list
where_opt
order_by_opt
limit_opt
Expand All @@ -197,6 +268,13 @@ low_priority_opt
| LOW_PRIORITY { $$ = $1 }
;

priority_opt
: { $$ = null }
| LOW_PRIORITY { $$ = $1 }
| HIGH_PRIORITY { $$ = $1 }
| DELAYED { $$ = $1 }
;

ignore_opt
: { $$ = null }
| IGNORE { $$ = $1 }
Expand All @@ -206,8 +284,8 @@ assignment
: identifier '=' expr { $$ = { type: 'Assignment', left: $1, right: $3 } }
;

assignmentList
: assignmentList ',' assignment { $1.value.push($3); }
assignment_list
: assignment_list ',' assignment { $1.value.push($3); }
| assignment { $$ = { type: 'AssignmentList', value: [ $1 ] } }
;

Expand Down Expand Up @@ -603,8 +681,11 @@ index_hint
| IGNORE index_or_key for_opt '(' identifier_list ')' { $$ = { type: 'IgnoreIndexHint', value: $5, forOpt: $3, indexOrKey: $2 } }
| FORCE index_or_key for_opt '(' identifier_list ')' { $$ = { type: 'ForceIndexHint', value: $5, forOpt: $3, indexOrKey: $2 } }
;
table_factor
simple_table_factor
: identifier partitionOpt aliasOpt index_hint_list_opt { $$ = { type: 'TableFactor', value: $1, partition: $2, alias: $3.alias, hasAs: $3.hasAs, indexHintOpt: $4 } }
;
table_factor
: simple_table_factor
| '(' selectClause ')' aliasOpt { $$ = { type: 'SubQuery', value: $2, alias: $4.alias, hasAs: $4.hasAs } }
| '(' table_refrences ')' { $$ = $2; $$.hasParentheses = true }
;
64 changes: 62 additions & 2 deletions src/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ Sql.prototype.travelMain = function(ast) {
this.travelSelect(ast.value);
} else if (ast.value.type === 'Update') {
this.travelUpdate(ast.value);
} else if (ast.value.type === 'Insert') {
this.travelInsert(ast.value);
} else {
throw new Error('Unknown query value type');
}
Expand Down Expand Up @@ -129,6 +131,64 @@ Sql.prototype.travelSelect = function(ast) {
this.appendKeyword(ast.updateLockMode);
}
}
Sql.prototype.travelInsert = function(ast) {
this.appendKeyword('insert', true);

if (ast.lowPriority) {
this.appendKeyword('low_priority');
}
if (ast.ignore) {
this.appendKeyword('ignore');
}
if (ast.into) {
this.appendKeyword('into');
}
this.travelTableRefrence(ast.table);
if (ast.partitions) {
this.travelPartitions(ast.partitions);
}
if (ast.cols) {
this.travel('(');
this.travelIdentifierList(ast.cols);
this.travel(')');
}
this.travel(ast.value);
if (ast.src.type === 'Select') {
this.travelSelect(ast.src);
} else if (ast.src.type === 'Values') {
this.travel(ast.src.keyword);
this.travelInsertRows(ast.src.values);
}
if (ast.duplicateAssignments) {
this.appendKeyword('ON');
this.appendKeyword('DUPLICATE');
this.appendKeyword('KEY');
this.appendKeyword('UPDATE');
this.travelAssignments(ast.duplicateAssignments);
}
}
Sql.prototype.travelInsertRows = function(ast) {
for (var i = 0; i < ast.value.length; i++) {
var x = ast.value[i];
this.travel('(');
this.travelValueList(x.value);
this.travel(')');

if (i !== ast.value.length - 1) {
this.append(',', true);
}
}
}
Sql.prototype.travelValueList = function(ast) {
for (var i = 0; i < ast.length; i++) {
var x = ast[i];
this.travel(x);

if (i !== ast.length - 1) {
this.append(',', true);
}
}
}
Sql.prototype.travelUpdate = function(ast) {
this.appendKeyword('update', true);
if (ast.lowPriority) {
Expand All @@ -154,9 +214,9 @@ Sql.prototype.travelUpdate = function(ast) {
Sql.prototype.travelAssignments = function(ast) {
for (var i = 0; i < ast.value.length; i++) {
var x = ast.value[i];
this.travelIdentifier(x.left);
this.travel(x.left);
this.travel('=');
this.travelIdentifier(x.right);
this.travel(x.right);

if (i !== ast.value.length - 1) {
this.append(',', true);
Expand Down
43 changes: 43 additions & 0 deletions test/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ AND (rd.rd_numberofrooms <= (select sum(rn.reservation_numberofrooms) as count_r
testParser('select a from b limit 2;');
});

it ('subquery.', function () {
testParser('select a from (select 1 as x) b limit 2;');
});

it('update0', function () {
testParser('update A SET b=2 WHERE c=3;');
});
Expand All @@ -148,4 +152,43 @@ AND (rd.rd_numberofrooms <= (select sum(rn.reservation_numberofrooms) as count_r
it('update2', function () {
testParser('update LOW_PRIORITY ignore A, B, C SET b=2, `C`.c=d WHERE e=4 ORDER BY d DESC limit 1;');
});

it('insert0', function () {
testParser('INSERT INTO A VALUES (a, `b`), (c, 3)');
});

it('insert1', function () {
testParser('INSERT DELAYED IGNORE INTO A VALUE (a, DEFAULT, 3+2)');
});

it('insert2', function () {
testParser('INSERT DELAYED IGNORE INTO A VALUE (a, `b`)');
});

it('insert3', function () {
testParser('INSERT DELAYED IGNORE INTO A (`a`, b, c) VALUE (1, 2+3)');
});

it('insert4', function () {
testParser('INSERT DELAYED IGNORE INTO `s0`.`A` PARTITION (p0, p1) (`a`, b, c) VALUE (1, 2+3)');
});

it('insert5', function () {
testParser(`
INSERT DELAYED IGNORE INTO \`s0\`.\`A\`
PARTITION (p0, p1) (\`a\`, b, c)
VALUE (1, 2+3), (5, '6')
ON DUPLICATE KEY UPDATE q=q+1, c=b
`);
});

it('insert6', function () {
testParser(`
INSERT HIGH_PRIORITY \`massdrop\`.\`A\`
PARTITION (p0, p1) (\`a\`, b, c)
SELECT 1+1 as b, d
FROM B
ON DUPLICATE KEY UPDATE q=q+1, c=b
`);
});
});

0 comments on commit 84f4402

Please sign in to comment.