Skip to content

Commit 93512d5

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

File tree

5 files changed

+90
-2
lines changed

5 files changed

+90
-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: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# frozen_string_literal: true
2+
3+
module Plume
4+
# - `schema_name` → `_Nilable(String)`
5+
# - `table_name` → `String`
6+
# - `select_statement` → `_Nilable(SelectStatement)`
7+
# - `columns` → `_Array(ColumnDefinition)`
8+
# - `strict` → `_Nilable(_Boolean)`
9+
# - `temporary` → `_Nilable(_Boolean)`
10+
# - `if_not_exists` → `_Nilable(_Boolean)`
11+
# - `without_row_id` → `_Nilable(_Boolean)`
12+
# - `constraints` → `_Array(TableConstraint)`
13+
#
14+
# **[SQLite Docs](https://www.sqlite.org/lang_createtable.html)**
15+
#
16+
# ```sql
17+
# create table tb0 (c0 primary key desc on conflict abort autoincrement)
18+
# ```
19+
class CommitStatement < Node
20+
token :commit_kw
21+
token :transaction_kw
22+
23+
def self.concrete(*, commit_kw:, transaction_kw:, **) = super
24+
end
25+
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)