Skip to content

Commit af68835

Browse files
committed
SQL: handle transactions starting from BEGIN
Signed-off-by: Masatake YAMATO <[email protected]>
1 parent aa49e87 commit af68835

File tree

4 files changed

+77
-5
lines changed

4 files changed

+77
-5
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--sort=no
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
neighborhoods input.sql /^CREATE TABLE "neighborhoods" (gid serial,$/;" t
2+
gid input.sql /^CREATE TABLE "neighborhoods" (gid serial,$/;" E table:neighborhoods
3+
objectid input.sql /^"objectid" numeric(10,0),$/;" E table:neighborhoods
4+
pri_neigh_ input.sql /^"pri_neigh_" varchar(3),$/;" E table:neighborhoods
5+
pri_neigh input.sql /^"pri_neigh" varchar(50),$/;" E table:neighborhoods
6+
sec_neigh_ input.sql /^"sec_neigh_" varchar(3),$/;" E table:neighborhoods
7+
sec_neigh input.sql /^"sec_neigh" varchar(50),$/;" E table:neighborhoods
8+
shape_area input.sql /^"shape_area" numeric,$/;" E table:neighborhoods
9+
shape_len input.sql /^"shape_len" numeric);$/;" E table:neighborhoods
10+
neighborhoods_geom_gist input.sql /^CREATE INDEX "neighborhoods_geom_gist" ON "neighborhoods" USING GIST ("geom");$/;" i table:neighborhoods
11+
player input.sql /^CREATE TABLE "player" (uid serial, "name" varchar(50));$/;" t
12+
uid input.sql /^CREATE TABLE "player" (uid serial, "name" varchar(50));$/;" E table:player
13+
name input.sql /^CREATE TABLE "player" (uid serial, "name" varchar(50));$/;" E table:player
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-- Based on https://github.com/tonyta/ScrallWall/blob/master/db/data/neighborhoods.sql
2+
SET CLIENT_ENCODING TO UTF8;
3+
SET STANDARD_CONFORMING_STRINGS TO ON;
4+
BEGIN;
5+
CREATE TABLE "neighborhoods" (gid serial,
6+
"objectid" numeric(10,0),
7+
"pri_neigh_" varchar(3),
8+
"pri_neigh" varchar(50),
9+
"sec_neigh_" varchar(3),
10+
"sec_neigh" varchar(50),
11+
"shape_area" numeric,
12+
"shape_len" numeric);
13+
ALTER TABLE "neighborhoods" ADD PRIMARY KEY (gid);
14+
CREATE INDEX "neighborhoods_geom_gist" ON "neighborhoods" USING GIST ("geom");
15+
COMMIT;
16+
17+
BEGIN TRANSACTION;
18+
CREATE TABLE "player" (uid serial, "name" varchar(50));
19+
COMMIT;

parsers/sql.c

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ enum eKeywordId {
7474
KEYWORD_call,
7575
KEYWORD_case,
7676
KEYWORD_check,
77+
KEYWORD_commit,
7778
KEYWORD_comment,
7879
KEYWORD_constraint,
7980
KEYWORD_create,
@@ -280,6 +281,7 @@ static const keywordTable SqlKeywordTable [] = {
280281
{ "call", KEYWORD_call },
281282
{ "case", KEYWORD_case },
282283
{ "check", KEYWORD_check },
284+
{ "commit", KEYWORD_commit },
283285
{ "comment", KEYWORD_comment },
284286
{ "constraint", KEYWORD_constraint },
285287
{ "create", KEYWORD_create },
@@ -416,6 +418,7 @@ static struct SqlReservedWord SqlReservedWord [SQLKEYWORD_COUNT] = {
416418
[KEYWORD_call] = {1 & 0&1&1&0 & 0&0 & 1},
417419
[KEYWORD_case] = {1 & 1&1&1&1 & 0&1 & 1},
418420
[KEYWORD_check] = {1 & 1&1&1&1 & 1&1 & 1},
421+
[KEYWORD_commit] = {0 & 0&1&1&1 & 0&0 & 0}, /* SQLANYWERE:??? */
419422
[KEYWORD_comment] = {0 & 0&0&0&0 & 1&1 & 1},
420423
[KEYWORD_constraint] = {1 & 1&1&1&1 & 0&1 & 1},
421424
[KEYWORD_create] = {1 & 1&1&1&1 & 1&1 & 1},
@@ -2007,15 +2010,51 @@ static void parseBlockFull (tokenInfo *const token, const bool local, langType l
20072010
}
20082011
if (isKeyword (token, KEYWORD_begin))
20092012
{
2013+
bool is_transaction = false;
2014+
20102015
readToken (token);
2011-
/*
2012-
* Check for ANSI declarations which always follow
2013-
* a BEGIN statement. This routine will not advance
2014-
* the token if none are found.
2016+
2017+
/* BEGIN of Postgresql initiates a transaction.
2018+
*
2019+
* BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ]
2020+
*
2021+
* BEGIN of MySQL does the same.
2022+
*
2023+
* BEGIN [WORK]
2024+
*
2025+
* BEGIN of SQLite does the same.
2026+
*
2027+
* BEGIN [[DEFERRED | IMMEDIATE | EXCLUSIVE] TRANSACTION]
2028+
*
20152029
*/
2016-
parseDeclareANSI (token, local);
2030+
if (isCmdTerm(token))
2031+
{
2032+
is_transaction = true;
2033+
readToken (token);
2034+
}
2035+
else if (isType (token, TOKEN_IDENTIFIER)
2036+
&& (strcasecmp (vStringValue(token->string), "work") == 0
2037+
|| strcasecmp (vStringValue(token->string), "transaction") == 0
2038+
|| (
2039+
strcasecmp (vStringValue(token->string), "deferred") == 0
2040+
|| strcasecmp (vStringValue(token->string), "immediate") == 0
2041+
|| strcasecmp (vStringValue(token->string), "exclusive") == 0
2042+
)
2043+
))
2044+
is_transaction = true;
2045+
else
2046+
{
2047+
/*
2048+
* Check for ANSI declarations which always follow
2049+
* a BEGIN statement. This routine will not advance
2050+
* the token if none are found.
2051+
*/
2052+
parseDeclareANSI (token, local);
2053+
}
2054+
20172055
token->begin_end_nest_lvl++;
20182056
while (! isKeyword (token, KEYWORD_end) &&
2057+
! (is_transaction && isKeyword(token, KEYWORD_commit)) &&
20192058
! isType (token, TOKEN_EOF))
20202059
{
20212060
parseStatements (token, false);

0 commit comments

Comments
 (0)