Repository: AfterShip/clickhouse-sql-parser
Pull request #125 (2025-03-02 23:01:17)

Parse select item alias even without `AS` keyword
ClickHouse allows to not use `AS` keyword when naming selected columns:

```
SELECT col1 AS one, col2 two
FROM tbl
```

Fix it.

coveralls: ## Pull Request Test Coverage Report for [Build 13620153978](https://coveralls.io/builds/72502741)


### Details

* **14** of **14**   **(100.0%)**  changed or added relevant lines in **2** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage increased (+**0.06%**) to **60.841%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/72502741/badge)](https://coveralls.io/builds/72502741) |
| :-- | --: |
| Change from base [Build 13580367952](https://coveralls.io/builds/72473804): |  0.06% |
| Covered Lines: | 6541 |
| Relevant Lines: | 10751 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/parser/parser_column.go b/parser/parser_column.go
index d13d658..f20a0dc 100644
--- a/parser/parser_column.go
+++ b/parser/parser_column.go
@@ -735,7 +735,10 @@ func (p *Parser) parseSelectItem() (*SelectItem, error) {
 		if err != nil {
 			return nil, err
 		}
+	} else {
+		alias = p.tryParseIdent()
 	}
+
 	return &SelectItem{
 		Expr:      expr,
 		Modifiers: modifiers,
diff --git a/parser/parser_common.go b/parser/parser_common.go
index 72bf588..07b8d4f 100644
--- a/parser/parser_common.go
+++ b/parser/parser_common.go
@@ -78,6 +78,20 @@ func (p *Parser) tryConsumeKeyword(keyword string) *Token {
 	return nil
 }
 
+func (p *Parser) tryParseIdent() *Ident {
+	if p.lastTokenKind() != TokenKindIdent {
+		return nil
+	}
+	lastToken := p.last()
+	_ = p.lexer.consumeToken()
+	return &Ident{
+		NamePos:   lastToken.Pos,
+		NameEnd:   lastToken.End,
+		Name:      lastToken.String,
+		QuoteType: lastToken.QuoteType,
+	}
+}
+
 func (p *Parser) parseIdent() (*Ident, error) {
 	lastToken, err := p.consumeTokenKind(TokenKindIdent)
 	if err != nil {


Test patch:
diff --git a/parser/testdata/query/format/select_simple_field_alias.sql b/parser/testdata/query/format/select_simple_field_alias.sql
new file mode 100644
index 0000000..5b012c2
--- /dev/null
+++ b/parser/testdata/query/format/select_simple_field_alias.sql
@@ -0,0 +1,5 @@
+-- Origin SQL:
+SELECT field0, field1 as x, field2 y from events;
+
+-- Format SQL:
+SELECT field0, field1 AS x, field2 AS y FROM events;
diff --git a/parser/testdata/query/output/select_simple_field_alias.sql.golden.json b/parser/testdata/query/output/select_simple_field_alias.sql.golden.json
new file mode 100644
index 0000000..4d8f856
--- /dev/null
+++ b/parser/testdata/query/output/select_simple_field_alias.sql.golden.json
@@ -0,0 +1,88 @@
+[
+  {
+    "SelectPos": 0,
+    "StatementEnd": 48,
+    "With": null,
+    "Top": null,
+    "SelectItems": [
+      {
+        "Expr": {
+          "Name": "field0",
+          "QuoteType": 1,
+          "NamePos": 7,
+          "NameEnd": 13
+        },
+        "Modifiers": [],
+        "Alias": null
+      },
+      {
+        "Expr": {
+          "Name": "field1",
+          "QuoteType": 1,
+          "NamePos": 15,
+          "NameEnd": 21
+        },
+        "Modifiers": [],
+        "Alias": {
+          "Name": "x",
+          "QuoteType": 1,
+          "NamePos": 25,
+          "NameEnd": 26
+        }
+      },
+      {
+        "Expr": {
+          "Name": "field2",
+          "QuoteType": 1,
+          "NamePos": 28,
+          "NameEnd": 34
+        },
+        "Modifiers": [],
+        "Alias": {
+          "Name": "y",
+          "QuoteType": 1,
+          "NamePos": 35,
+          "NameEnd": 36
+        }
+      }
+    ],
+    "From": {
+      "FromPos": 37,
+      "Expr": {
+        "Table": {
+          "TablePos": 42,
+          "TableEnd": 48,
+          "Alias": null,
+          "Expr": {
+            "Database": null,
+            "Table": {
+              "Name": "events",
+              "QuoteType": 1,
+              "NamePos": 42,
+              "NameEnd": 48
+            }
+          },
+          "HasFinal": false
+        },
+        "StatementEnd": 48,
+        "SampleRatio": null,
+        "HasFinal": false
+      }
+    },
+    "ArrayJoin": null,
+    "Window": null,
+    "Prewhere": null,
+    "Where": null,
+    "GroupBy": null,
+    "WithTotal": false,
+    "Having": null,
+    "OrderBy": null,
+    "LimitBy": null,
+    "Limit": null,
+    "Settings": null,
+    "Format": null,
+    "UnionAll": null,
+    "UnionDistinct": null,
+    "Except": null
+  }
+]
\ No newline at end of file
diff --git a/parser/testdata/query/select_simple_field_alias.sql b/parser/testdata/query/select_simple_field_alias.sql
new file mode 100644
index 0000000..786a821
--- /dev/null
+++ b/parser/testdata/query/select_simple_field_alias.sql
@@ -0,0 +1,1 @@
+SELECT field0, field1 as x, field2 y from events;
\ No newline at end of file