Skip to content

Commit 5dda694

Browse files
author
Dray Lacy
committed
Added LEFT JOIN.
1 parent 3c0215c commit 5dda694

File tree

8 files changed

+538
-493
lines changed

8 files changed

+538
-493
lines changed

lib/sql/parser.racc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ rule
3838
| table_reference CROSS JOIN table_name { result = SQL::Statement::CrossJoin.new(val[0], SQL::Statement::Table.new(val[3])) }
3939

4040
qualified_join
41-
: table_reference INNER JOIN table_reference join_specification { result = SQL::Statement::InnerJoin.new(val[0], val[3], val[4]) }
41+
: table_reference join_type JOIN table_reference join_specification { result = val[1].new(val[0], val[3], val[4]) }
42+
43+
join_type
44+
: INNER { result = SQL::Statement::InnerJoin }
45+
| LEFT { result = SQL::Statement::LeftJoin }
4246

4347
join_specification
4448
: join_condition

lib/sql/parser.racc.rb

Lines changed: 513 additions & 492 deletions
Large diffs are not rendered by default.

lib/sql/parser.rex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ rule
5353
CROSS { [:CROSS, text] }
5454
JOIN { [:JOIN, text] }
5555
ON { [:ON, text] }
56+
LEFT { [:LEFT, text] }
5657
5758
# tokens
5859
<> { [:not_equals_operator, text] }

lib/sql/parser.rex.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ def scan_evaluate( str )
146146
when (text = ss.scan(/ON/))
147147
@rex_tokens.push action { [:ON, text] }
148148

149+
when (text = ss.scan(/LEFT/))
150+
@rex_tokens.push action { [:LEFT, text] }
151+
149152
when (text = ss.scan(/<>/))
150153
@rex_tokens.push action { [:not_equals_operator, text] }
151154

lib/sql/sql_visitor.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ def visit_InnerJoin(o)
153153
"#{visit(o.left)} INNER JOIN #{visit(o.right)} ON #{visit(o.search_condition)}"
154154
end
155155

156+
def visit_LeftJoin(o)
157+
"#{visit(o.left)} LEFT JOIN #{visit(o.right)} ON #{visit(o.search_condition)}"
158+
end
159+
156160
def visit_Table(o)
157161
o.name
158162
end

lib/sql/statement.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ def initialize(left, right, search_condition)
233233
class InnerJoin < QualifiedJoin
234234
end
235235

236+
class LeftJoin < QualifiedJoin
237+
end
238+
236239
class Table < Node
237240
def initialize(name)
238241
@name = name

test/test_parser.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
require 'test/unit'
33

44
class TestParser < Test::Unit::TestCase
5+
def test_left_join
6+
assert_understands 'SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a'
7+
assert_understands 'SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a'
8+
end
9+
510
def test_inner_join
611
assert_understands 'SELECT * FROM t1 INNER JOIN t2 ON t1.a = t2.a'
712
assert_understands 'SELECT * FROM t1 INNER JOIN t2 ON t1.a = t2.a INNER JOIN t3 ON t2.a = t3.a'

test/test_statement.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ def test_from_clause
2828
assert_sql 'FROM users', SQL::Statement::FromClause.new(SQL::Statement::Table.new('users'))
2929
end
3030

31+
def test_left_join
32+
assert_sql 't1 LEFT JOIN t2 ON t1.a = t2.a', SQL::Statement::LeftJoin.new(SQL::Statement::Table.new('t1'), SQL::Statement::Table.new('t2'), SQL::Statement::Equals.new(SQL::Statement::QualifiedColumn.new('t1', 'a'), SQL::Statement::QualifiedColumn.new('t2', 'a')))
33+
end
34+
3135
def test_inner_join
3236
assert_sql 't1 INNER JOIN t2 ON t1.a = t2.a', SQL::Statement::InnerJoin.new(SQL::Statement::Table.new('t1'), SQL::Statement::Table.new('t2'), SQL::Statement::Equals.new(SQL::Statement::QualifiedColumn.new('t1', 'a'), SQL::Statement::QualifiedColumn.new('t2', 'a')))
3337
end

0 commit comments

Comments
 (0)