Skip to content

Commit c2a476b

Browse files
committed
Add support for COMMIT statement
This commit allows us to parse the the `COMMIT` / `END` statements.
1 parent c3b899b commit c2a476b

File tree

5 files changed

+80
-2
lines changed

5 files changed

+80
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ SQLite works with a grammar of _167_ token types, _136_ of which are keywords. T
203203
- [ ] `analyze_stmt`
204204
- [ ] `attach_stmt`
205205
- [ ] `begin_stmt`
206-
- [ ] `commit_stmt`
206+
- [x] `commit_stmt`
207207
- [x] `create_table_stmt`
208208
- [ ] `create_index_stmt`
209209
- [ ] `create_trigger_stmt`

lib/plume.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ module Plume
2626
autoload :ColumnDefinition, "plume/ast/column_definition"
2727
autoload :ColumnName, "plume/ast/column_name"
2828
autoload :ColumnType, "plume/ast/column_type"
29+
autoload :CommitStatement, "plume/ast/commit_statement"
2930
autoload :ConflictClause, "plume/ast/conflict_clause"
3031
autoload :CreateTableStatement, "plume/ast/create_table_statement"
3132
autoload :CrossJoinOperator, "plume/ast/cross_join_operator"

lib/plume/ast/commit_statement.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
3+
module Plume
4+
# **[SQLite Docs](https://www.sqlite.org/lang_transaction.html)**
5+
#
6+
# ```sql
7+
# commmit
8+
# ```
9+
class CommitStatement < Node
10+
token :commit_kw
11+
token :transaction_kw
12+
13+
def self.concrete(*, commit_kw:, transaction_kw:, **) = super
14+
end
15+
end

lib/plume/parser.rb

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,31 @@ def select_stmt
596596
# end
597597
end
598598

599+
def commit_stmt
600+
#
601+
# Relevant `parse.y` grammar rules:
602+
# cmd ::= COMMIT|END(X) trans_opt. {sqlite3EndTransaction(pParse,@X);}
603+
#
604+
# Syntax diagram:
605+
# ◯─▶┬─▶{ COMMIT }┬─▶─┬──▶{ TRANSACTION }─┬─▶◯
606+
# ├▶{ End }──▶─┤ ├─────────▶─────────┤
607+
608+
# Simplified grammar:
609+
# COMMIT [TRANSACTION] | END [TRANSACTION]
610+
#
611+
# Relevant SQLite documentation:
612+
# - https://www.sqlite.org/lang_transaction.html
613+
#
614+
commit_kw = require_one_of :COMMIT, :END
615+
transaction_kw = maybe :TRANSACTION
616+
617+
CommitStatement.concrete(
618+
full_source: @lexer.sql,
619+
commit_kw: Token::Keyword(commit_kw),
620+
transaction_kw: Token::Keyword(transaction_kw),
621+
)
622+
end
623+
599624
# ---------- Clauses ----------
600625

601626
def expression(min_precedence = 0)
@@ -2818,4 +2843,4 @@ def error!(token, value, expected)
28182843
throw :ERROR, ErrorMessage.new(msg)
28192844
end
28202845
end
2821-
end
2846+
end

test/commit.test.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
3+
test "commit" do
4+
node = parse_stmt(<<~SQL)
5+
COMMIT;
6+
SQL
7+
8+
assert_equal node.commit_kw_val, "COMMIT"
9+
assert_equal node.transaction_kw_val, nil
10+
end
11+
12+
test "commit transaction" do
13+
node = parse_stmt(<<~SQL)
14+
COMMIT TRANSACTION;
15+
SQL
16+
17+
assert_equal node.commit_kw_val, "COMMIT"
18+
assert_equal node.transaction_kw_val, "TRANSACTION"
19+
end
20+
21+
test "end" do
22+
node = parse_stmt(<<~SQL)
23+
end;
24+
SQL
25+
26+
assert_equal node.commit_kw_val, "end"
27+
assert_equal node.transaction_kw_val, nil
28+
end
29+
30+
test "end transaction" do
31+
node = parse_stmt(<<~SQL)
32+
end transaction;
33+
SQL
34+
35+
assert_equal node.commit_kw_val, "end"
36+
assert_equal node.transaction_kw_val, "transaction"
37+
end

0 commit comments

Comments
 (0)