@@ -2099,6 +2099,7 @@ String NonReservedWord() :
20992099 | tk=<K_INCLUDING:"INCLUDING">
21002100 | tk=<K_INCREMENT:"INCREMENT">
21012101 | tk=<K_INDEX: "INDEX">
2102+ | tk=<K_INSTALL: "INSTALL">
21022103 | tk=<K_INFORMATION: "INFORMATION">
21032104 | tk=<K_INSERT:"INSERT">
21042105 | tk=<K_INTERLEAVE: "INTERLEAVE">
@@ -2127,6 +2128,7 @@ String NonReservedWord() :
21272128 | tk=<K_LINEAR:"LINEAR">
21282129 | tk=<K_LINES:"LINES">
21292130 | tk=<K_LIST:"LIST">
2131+ | tk=<K_LOAD: "LOAD">
21302132 | tk=<K_LOCAL:"LOCAL">
21312133 | tk=<K_LOCK:"LOCK">
21322134 | tk=<K_LOCKED:"LOCKED">
@@ -2942,6 +2944,10 @@ Statement SingleStatement() :
29422944 |
29432945 LOOKAHEAD({ getToken(1).kind == K_PRAGMA }) stm = PragmaStatement()
29442946 |
2947+ LOOKAHEAD({ getToken(1).kind == K_INSTALL || getToken(1).kind == K_LOAD
2948+ || (getToken(1).kind == K_FORCE && getToken(2).kind == K_INSTALL) })
2949+ stm = ExtensionStatement()
2950+ |
29452951 stm = PurgeStatement()
29462952 |
29472953 stm = SessionStatement()
@@ -4343,6 +4349,38 @@ RenameTableStatement RenameTableStatement(): {
43434349 }
43444350}
43454351
4352+ /**
4353+ * DuckDB's [FORCE] INSTALL extension [FROM repository] and LOAD extension.
4354+ */
4355+ ExtensionStatement ExtensionStatement() #ExtensionStatement:
4356+ {
4357+ ExtensionStatement extensionStatement = new ExtensionStatement();
4358+ ObjectNames name;
4359+ Token token;
4360+ }
4361+ {
4362+ [ <K_FORCE> { extensionStatement.setForce(true); } ]
4363+ (
4364+ <K_INSTALL> { extensionStatement.setOperation(ExtensionStatement.Operation.INSTALL); }
4365+ |
4366+ <K_LOAD> { extensionStatement.setOperation(ExtensionStatement.Operation.LOAD); }
4367+ )
4368+ (
4369+ token=<S_CHAR_LITERAL> { extensionStatement.setExtensionName(token.image); }
4370+ |
4371+ name=RelObjectNames() { extensionStatement.setExtensionName(String.join(".", name.getNames())); }
4372+ )
4373+ [
4374+ LOOKAHEAD(2) <K_FROM>
4375+ (
4376+ token=<S_CHAR_LITERAL> { extensionStatement.setRepository(token.image); }
4377+ |
4378+ name=RelObjectNames() { extensionStatement.setRepository(String.join(".", name.getNames())); }
4379+ )
4380+ ]
4381+ { return extensionStatement; }
4382+ }
4383+
43464384/**
43474385 * DuckDB/SQLite PRAGMA name [(arguments) | = value].
43484386 */
@@ -16428,14 +16466,20 @@ RollbackStatement RollbackStatement():
1642816466{
1642916467 <K_ROLLBACK> { rollbackStatement = new RollbackStatement(); }
1643016468 [ <K_WORK> { rollbackStatement.setUsingWorkKeyword(true); } ]
16431- [ (
16432- <K_TO> [ <K_SAVEPOINT> { rollbackStatement.setUsingSavepointKeyword(true); }]
16433- token=<S_IDENTIFIER> { rollbackStatement.setSavepointName(token.image); }
16434- )
16435- |
16469+ // explicit lookahead: FORCE INSTALL starts a new statement, FORCE 'id' belongs here
16470+ [
16471+ LOOKAHEAD(2)
1643616472 (
16437- <K_FORCE> token=<S_CHAR_LITERAL> { rollbackStatement.setForceDistributedTransactionIdentifier(token.image); }
16438- ) ]
16473+ (
16474+ <K_TO> [ <K_SAVEPOINT> { rollbackStatement.setUsingSavepointKeyword(true); }]
16475+ token=<S_IDENTIFIER> { rollbackStatement.setSavepointName(token.image); }
16476+ )
16477+ |
16478+ (
16479+ <K_FORCE> token=<S_CHAR_LITERAL> { rollbackStatement.setForceDistributedTransactionIdentifier(token.image); }
16480+ )
16481+ )
16482+ ]
1643916483
1644016484 {
1644116485 return rollbackStatement;
0 commit comments