From bb8d1011708705e9032803a2886e7c8cffd62cdb Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Tue, 26 Nov 2024 23:38:51 +0900 Subject: [PATCH] Fix JoinMethod handling (#213) --- ast/const.go | 6 +- parser.go | 8 +- .../query/select_singer_with_hash_join.sql | 8 +- .../select_singer_with_hash_join.sql.txt | 183 +++--------------- .../select_singer_with_hash_join.sql.txt | 183 +++--------------- 5 files changed, 70 insertions(+), 318 deletions(-) diff --git a/ast/const.go b/ast/const.go index eff6d893..9ea9a7d9 100644 --- a/ast/const.go +++ b/ast/const.go @@ -14,12 +14,12 @@ const ( JoinTypeJoinHint JoinHintKey = "JOIN_TYPE" ) +// JoinMethod is used for prefix of JOIN, not for hint. type JoinMethod string const ( - HashJoinMethod JoinMethod = "HASH" - ApplyJoinMethod JoinMethod = "APPLY" - LoopJoinMethod JoinMethod = "LOOP" // Undocumented, but the Spanner accept this value at least. + HashJoinMethod JoinMethod = "HASH" + LookupJoinMethod JoinMethod = "LOOKUP" // Undocumented, but the GoogleSQL can parse this value. ) type PositionKeyword string diff --git a/parser.go b/parser.go index c2a2595f..0655fc52 100644 --- a/parser.go +++ b/parser.go @@ -737,13 +737,9 @@ func (p *Parser) parseTableExpr(toplevel bool) ast.TableExpr { p.nextToken() method = ast.HashJoinMethod needJoin = true - case p.Token.IsKeywordLike("APPLY"): + case p.Token.IsKeywordLike("LOOKUP"): p.nextToken() - method = ast.ApplyJoinMethod - needJoin = true - case p.Token.IsKeywordLike("LOOP"): - p.nextToken() - method = ast.LoopJoinMethod + method = ast.LookupJoinMethod needJoin = true } } diff --git a/testdata/input/query/select_singer_with_hash_join.sql b/testdata/input/query/select_singer_with_hash_join.sql index cd77034d..e5d1e7e4 100644 --- a/testdata/input/query/select_singer_with_hash_join.sql +++ b/testdata/input/query/select_singer_with_hash_join.sql @@ -4,10 +4,4 @@ FROM Singers A HASH JOIN Singers B - ON A.SingerID = B.SingerID - APPLY JOIN - Singer C - ON B.SingerID = C.SingerID - LOOP JOIN - Singer D - ON C.SingerID = D.SingerID + ON A.SingerID = B.SingerID \ No newline at end of file diff --git a/testdata/result/query/select_singer_with_hash_join.sql.txt b/testdata/result/query/select_singer_with_hash_join.sql.txt index 6a385ba4..51741f24 100644 --- a/testdata/result/query/select_singer_with_hash_join.sql.txt +++ b/testdata/result/query/select_singer_with_hash_join.sql.txt @@ -6,13 +6,6 @@ FROM HASH JOIN Singers B ON A.SingerID = B.SingerID - APPLY JOIN - Singer C - ON B.SingerID = C.SingerID - LOOP JOIN - Singer D - ON C.SingerID = D.SingerID - --- AST &ast.QueryStatement{ Hint: (*ast.Hint)(nil), @@ -30,168 +23,56 @@ FROM From: 11, Source: &ast.Join{ Op: "INNER JOIN", - Method: "LOOP", + Method: "HASH", Hint: (*ast.Hint)(nil), - Left: &ast.Join{ - Op: "INNER JOIN", - Method: "APPLY", - Hint: (*ast.Hint)(nil), - Left: &ast.Join{ - Op: "INNER JOIN", - Method: "HASH", - Hint: (*ast.Hint)(nil), - Left: &ast.TableName{ - Table: &ast.Ident{ - NamePos: 18, - NameEnd: 25, - Name: "Singers", - }, - Hint: (*ast.Hint)(nil), - As: &ast.AsAlias{ - As: -1, - Alias: &ast.Ident{ - NamePos: 26, - NameEnd: 27, - Name: "A", - }, - }, - Sample: (*ast.TableSample)(nil), - }, - Right: &ast.TableName{ - Table: &ast.Ident{ - NamePos: 42, - NameEnd: 49, - Name: "Singers", - }, - Hint: (*ast.Hint)(nil), - As: &ast.AsAlias{ - As: -1, - Alias: &ast.Ident{ - NamePos: 50, - NameEnd: 51, - Name: "B", - }, - }, - Sample: (*ast.TableSample)(nil), - }, - Cond: &ast.On{ - On: 54, - Expr: &ast.BinaryExpr{ - Op: "=", - Left: &ast.Path{ - Idents: []*ast.Ident{ - &ast.Ident{ - NamePos: 57, - NameEnd: 58, - Name: "A", - }, - &ast.Ident{ - NamePos: 59, - NameEnd: 67, - Name: "SingerID", - }, - }, - }, - Right: &ast.Path{ - Idents: []*ast.Ident{ - &ast.Ident{ - NamePos: 70, - NameEnd: 71, - Name: "B", - }, - &ast.Ident{ - NamePos: 72, - NameEnd: 80, - Name: "SingerID", - }, - }, - }, - }, - }, - }, - Right: &ast.TableName{ - Table: &ast.Ident{ - NamePos: 96, - NameEnd: 102, - Name: "Singer", - }, - Hint: (*ast.Hint)(nil), - As: &ast.AsAlias{ - As: -1, - Alias: &ast.Ident{ - NamePos: 103, - NameEnd: 104, - Name: "C", - }, - }, - Sample: (*ast.TableSample)(nil), + Left: &ast.TableName{ + Table: &ast.Ident{ + NamePos: 18, + NameEnd: 25, + Name: "Singers", }, - Cond: &ast.On{ - On: 107, - Expr: &ast.BinaryExpr{ - Op: "=", - Left: &ast.Path{ - Idents: []*ast.Ident{ - &ast.Ident{ - NamePos: 110, - NameEnd: 111, - Name: "B", - }, - &ast.Ident{ - NamePos: 112, - NameEnd: 120, - Name: "SingerID", - }, - }, - }, - Right: &ast.Path{ - Idents: []*ast.Ident{ - &ast.Ident{ - NamePos: 123, - NameEnd: 124, - Name: "C", - }, - &ast.Ident{ - NamePos: 125, - NameEnd: 133, - Name: "SingerID", - }, - }, - }, + Hint: (*ast.Hint)(nil), + As: &ast.AsAlias{ + As: -1, + Alias: &ast.Ident{ + NamePos: 26, + NameEnd: 27, + Name: "A", }, }, + Sample: (*ast.TableSample)(nil), }, Right: &ast.TableName{ Table: &ast.Ident{ - NamePos: 148, - NameEnd: 154, - Name: "Singer", + NamePos: 42, + NameEnd: 49, + Name: "Singers", }, Hint: (*ast.Hint)(nil), As: &ast.AsAlias{ As: -1, Alias: &ast.Ident{ - NamePos: 155, - NameEnd: 156, - Name: "D", + NamePos: 50, + NameEnd: 51, + Name: "B", }, }, Sample: (*ast.TableSample)(nil), }, Cond: &ast.On{ - On: 159, + On: 54, Expr: &ast.BinaryExpr{ Op: "=", Left: &ast.Path{ Idents: []*ast.Ident{ &ast.Ident{ - NamePos: 162, - NameEnd: 163, - Name: "C", + NamePos: 57, + NameEnd: 58, + Name: "A", }, &ast.Ident{ - NamePos: 164, - NameEnd: 172, + NamePos: 59, + NameEnd: 67, Name: "SingerID", }, }, @@ -199,13 +80,13 @@ FROM Right: &ast.Path{ Idents: []*ast.Ident{ &ast.Ident{ - NamePos: 175, - NameEnd: 176, - Name: "D", + NamePos: 70, + NameEnd: 71, + Name: "B", }, &ast.Ident{ - NamePos: 177, - NameEnd: 185, + NamePos: 72, + NameEnd: 80, Name: "SingerID", }, }, @@ -223,4 +104,4 @@ FROM } --- SQL -SELECT * FROM Singers A INNER JOIN Singers B ON A.SingerID = B.SingerID INNER JOIN Singer C ON B.SingerID = C.SingerID INNER JOIN Singer D ON C.SingerID = D.SingerID +SELECT * FROM Singers A INNER JOIN Singers B ON A.SingerID = B.SingerID diff --git a/testdata/result/statement/select_singer_with_hash_join.sql.txt b/testdata/result/statement/select_singer_with_hash_join.sql.txt index 6a385ba4..51741f24 100644 --- a/testdata/result/statement/select_singer_with_hash_join.sql.txt +++ b/testdata/result/statement/select_singer_with_hash_join.sql.txt @@ -6,13 +6,6 @@ FROM HASH JOIN Singers B ON A.SingerID = B.SingerID - APPLY JOIN - Singer C - ON B.SingerID = C.SingerID - LOOP JOIN - Singer D - ON C.SingerID = D.SingerID - --- AST &ast.QueryStatement{ Hint: (*ast.Hint)(nil), @@ -30,168 +23,56 @@ FROM From: 11, Source: &ast.Join{ Op: "INNER JOIN", - Method: "LOOP", + Method: "HASH", Hint: (*ast.Hint)(nil), - Left: &ast.Join{ - Op: "INNER JOIN", - Method: "APPLY", - Hint: (*ast.Hint)(nil), - Left: &ast.Join{ - Op: "INNER JOIN", - Method: "HASH", - Hint: (*ast.Hint)(nil), - Left: &ast.TableName{ - Table: &ast.Ident{ - NamePos: 18, - NameEnd: 25, - Name: "Singers", - }, - Hint: (*ast.Hint)(nil), - As: &ast.AsAlias{ - As: -1, - Alias: &ast.Ident{ - NamePos: 26, - NameEnd: 27, - Name: "A", - }, - }, - Sample: (*ast.TableSample)(nil), - }, - Right: &ast.TableName{ - Table: &ast.Ident{ - NamePos: 42, - NameEnd: 49, - Name: "Singers", - }, - Hint: (*ast.Hint)(nil), - As: &ast.AsAlias{ - As: -1, - Alias: &ast.Ident{ - NamePos: 50, - NameEnd: 51, - Name: "B", - }, - }, - Sample: (*ast.TableSample)(nil), - }, - Cond: &ast.On{ - On: 54, - Expr: &ast.BinaryExpr{ - Op: "=", - Left: &ast.Path{ - Idents: []*ast.Ident{ - &ast.Ident{ - NamePos: 57, - NameEnd: 58, - Name: "A", - }, - &ast.Ident{ - NamePos: 59, - NameEnd: 67, - Name: "SingerID", - }, - }, - }, - Right: &ast.Path{ - Idents: []*ast.Ident{ - &ast.Ident{ - NamePos: 70, - NameEnd: 71, - Name: "B", - }, - &ast.Ident{ - NamePos: 72, - NameEnd: 80, - Name: "SingerID", - }, - }, - }, - }, - }, - }, - Right: &ast.TableName{ - Table: &ast.Ident{ - NamePos: 96, - NameEnd: 102, - Name: "Singer", - }, - Hint: (*ast.Hint)(nil), - As: &ast.AsAlias{ - As: -1, - Alias: &ast.Ident{ - NamePos: 103, - NameEnd: 104, - Name: "C", - }, - }, - Sample: (*ast.TableSample)(nil), + Left: &ast.TableName{ + Table: &ast.Ident{ + NamePos: 18, + NameEnd: 25, + Name: "Singers", }, - Cond: &ast.On{ - On: 107, - Expr: &ast.BinaryExpr{ - Op: "=", - Left: &ast.Path{ - Idents: []*ast.Ident{ - &ast.Ident{ - NamePos: 110, - NameEnd: 111, - Name: "B", - }, - &ast.Ident{ - NamePos: 112, - NameEnd: 120, - Name: "SingerID", - }, - }, - }, - Right: &ast.Path{ - Idents: []*ast.Ident{ - &ast.Ident{ - NamePos: 123, - NameEnd: 124, - Name: "C", - }, - &ast.Ident{ - NamePos: 125, - NameEnd: 133, - Name: "SingerID", - }, - }, - }, + Hint: (*ast.Hint)(nil), + As: &ast.AsAlias{ + As: -1, + Alias: &ast.Ident{ + NamePos: 26, + NameEnd: 27, + Name: "A", }, }, + Sample: (*ast.TableSample)(nil), }, Right: &ast.TableName{ Table: &ast.Ident{ - NamePos: 148, - NameEnd: 154, - Name: "Singer", + NamePos: 42, + NameEnd: 49, + Name: "Singers", }, Hint: (*ast.Hint)(nil), As: &ast.AsAlias{ As: -1, Alias: &ast.Ident{ - NamePos: 155, - NameEnd: 156, - Name: "D", + NamePos: 50, + NameEnd: 51, + Name: "B", }, }, Sample: (*ast.TableSample)(nil), }, Cond: &ast.On{ - On: 159, + On: 54, Expr: &ast.BinaryExpr{ Op: "=", Left: &ast.Path{ Idents: []*ast.Ident{ &ast.Ident{ - NamePos: 162, - NameEnd: 163, - Name: "C", + NamePos: 57, + NameEnd: 58, + Name: "A", }, &ast.Ident{ - NamePos: 164, - NameEnd: 172, + NamePos: 59, + NameEnd: 67, Name: "SingerID", }, }, @@ -199,13 +80,13 @@ FROM Right: &ast.Path{ Idents: []*ast.Ident{ &ast.Ident{ - NamePos: 175, - NameEnd: 176, - Name: "D", + NamePos: 70, + NameEnd: 71, + Name: "B", }, &ast.Ident{ - NamePos: 177, - NameEnd: 185, + NamePos: 72, + NameEnd: 80, Name: "SingerID", }, }, @@ -223,4 +104,4 @@ FROM } --- SQL -SELECT * FROM Singers A INNER JOIN Singers B ON A.SingerID = B.SingerID INNER JOIN Singer C ON B.SingerID = C.SingerID INNER JOIN Singer D ON C.SingerID = D.SingerID +SELECT * FROM Singers A INNER JOIN Singers B ON A.SingerID = B.SingerID