Repository: AfterShip/clickhouse-sql-parser
Pull request #44 (2024-02-06 02:46:34)

Fix cannot parse JOIN only expression correctly
related context: https://github.com/AfterShip/clickhouse-sql-parser/issues/37#issuecomment-1926623733


Patch:
diff --git a/parser/parser_query.go b/parser/parser_query.go
index 782ebca..e4fcf0a 100644
--- a/parser/parser_query.go
+++ b/parser/parser_query.go
@@ -129,6 +129,11 @@ func (p *Parser) parseJoinOp(_ Pos) (Expr, []string, error) {
 	case p.tryConsumeKeyword(KeywordCross) != nil: // cross join
 		modifiers = append(modifiers, KeywordCross)
 	case p.tryConsumeTokenKind(",") != nil:
+		expr, err := p.parseJoinExpr(p.Pos())
+		if err != nil {
+			return nil, nil, err
+		}
+		return expr, nil, nil
 	case p.matchKeyword(KeywordAny), p.matchKeyword(KeywordAll):
 		modifiers = append(modifiers, p.last().String)
 		_ = p.lexer.consumeToken()
@@ -182,17 +187,17 @@ func (p *Parser) parseJoinOp(_ Pos) (Expr, []string, error) {
 			modifiers = append(modifiers, p.last().String)
 			_ = p.lexer.consumeToken()
 		}
-	default:
-		return nil, nil, nil
 	}
+
 	if p.tryConsumeKeyword(KeywordJoin) != nil {
 		modifiers = append(modifiers, KeywordJoin)
+		expr, err := p.parseJoinExpr(p.Pos())
+		if err != nil {
+			return nil, nil, err
+		}
+		return expr, modifiers, nil
 	}
-	expr, err := p.parseJoinExpr(p.Pos())
-	if err != nil {
-		return nil, nil, err
-	}
-	return expr, modifiers, nil
+	return nil, modifiers, nil
 }
 
 func (p *Parser) parseJoinExpr(pos Pos) (expr Expr, err error) {


Test patch:
diff --git a/parser/testdata/query/format/select_with_join_only.sql b/parser/testdata/query/format/select_with_join_only.sql
new file mode 100644
index 0000000..97d8ddf
--- /dev/null
+++ b/parser/testdata/query/format/select_with_join_only.sql
@@ -0,0 +1,10 @@
+-- Origin SQL:
+SELECT * FROM "t1" JOIN "t2" ON true
+
+
+-- Format SQL:
+
+SELECT 
+  *
+FROM
+  't1' JOIN 't2' ON true;
diff --git a/parser/testdata/query/output/select_with_join_only.sql.golden.json b/parser/testdata/query/output/select_with_join_only.sql.golden.json
new file mode 100644
index 0000000..03b8c9a
--- /dev/null
+++ b/parser/testdata/query/output/select_with_join_only.sql.golden.json
@@ -0,0 +1,83 @@
+[
+  {
+    "SelectPos": 0,
+    "StatementEnd": 17,
+    "With": null,
+    "Top": null,
+    "SelectColumns": {
+      "ListPos": 7,
+      "ListEnd": 7,
+      "HasDistinct": false,
+      "Items": [
+        {
+          "Name": "*",
+          "Unquoted": false,
+          "NamePos": 7,
+          "NameEnd": 7
+        }
+      ]
+    },
+    "From": {
+      "FromPos": 9,
+      "Expr": {
+        "JoinPos": 15,
+        "Left": {
+          "TablePos": 15,
+          "TableEnd": 17,
+          "Alias": null,
+          "Expr": {
+            "LiteralPos": 15,
+            "LiteralEnd": 17,
+            "Literal": "t1"
+          },
+          "HasFinal": false
+        },
+        "Right": {
+          "TablePos": 25,
+          "TableEnd": 27,
+          "Alias": null,
+          "Expr": {
+            "LiteralPos": 25,
+            "LiteralEnd": 27,
+            "Literal": "t2"
+          },
+          "HasFinal": false
+        },
+        "Modifiers": [
+          "JOIN"
+        ],
+        "SampleRatio": null,
+        "Constraints": {
+          "OnPos": 29,
+          "On": {
+            "ListPos": 32,
+            "ListEnd": 36,
+            "HasDistinct": false,
+            "Items": [
+              {
+                "Name": "true",
+                "Unquoted": false,
+                "NamePos": 32,
+                "NameEnd": 36
+              }
+            ]
+          }
+        }
+      }
+    },
+    "ArrayJoin": null,
+    "Window": null,
+    "Prewhere": null,
+    "Where": null,
+    "GroupBy": null,
+    "WithTotal": false,
+    "Having": null,
+    "OrderBy": null,
+    "LimitBy": null,
+    "Limit": null,
+    "Settings": null,
+    "UnionAll": null,
+    "UnionDistinct": null,
+    "Except": null
+  }
+]
\ No newline at end of file
diff --git a/parser/testdata/query/select_with_join_only.sql b/parser/testdata/query/select_with_join_only.sql
new file mode 100644
index 0000000..f5cd19e
--- /dev/null
+++ b/parser/testdata/query/select_with_join_only.sql
@@ -0,0 +1,1 @@
+SELECT * FROM "t1" JOIN "t2" ON true