@@ -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