Repository: tobymao/sqlglot

Issue:
Order By All keyword is not correctly parsed 
Hello,

In duckdb the ALL keyword indicates that the output should be sorted by every column in order from left to right. The direction of this sort may be modified using either ORDER BY ALL ASC or ORDER BY ALL DESC and/or NULLS FIRST or NULLS LAST.

Using `sqlglot 25.5.1`, I was not able to parse correctly the "all" keyword.                                

**Fully reproducible code snippet**
```python 
import sqlglot

sql = """SELECT *
FROM test
ORDER BY ALL DESC;"""

parsed_sql = sqlglot.parse_one(
    sql=sql,
    read=sqlglot.Dialects.DUCKDB,
).sql(sqlglot.Dialects.DUCKDB)

print(parsed_sql)
```
```
>>> SELECT * FROM test ORDER BY "ALL" DESC
```

The output query is not correct and running it will produce an error.
The correct output should be:
```
>>> SELECT * FROM test ORDER BY ALL DESC
```

**Official Documentation**
https://duckdb.org/docs/sql/query_syntax/orderby.html


Discussion:
tobymao: could we make this instead a group by property? this should make it easier to transpile, 
VaggelisD: @tobymao  Sure, I'll do some research on `GROUP BY ALL` and follow up with a new PR

Patch:
diff --git a/sqlglot/dialects/dialect.py b/sqlglot/dialects/dialect.py
index da212869..3ba72ea7 100644
--- a/sqlglot/dialects/dialect.py
+++ b/sqlglot/dialects/dialect.py
@@ -356,6 +356,11 @@ class Dialect(metaclass=_Dialect):
     EXPAND_ALIAS_REFS_EARLY_ONLY_IN_GROUP_BY = False
     """Whether alias reference expansion before qualification should only happen for the GROUP BY clause."""
 
+    SUPPORTS_ORDER_BY_ALL = False
+    """
+    Whether ORDER BY ALL is supported (expands to all the selected columns) as in DuckDB, Spark3/Databricks
+    """
+
     # --- Autofilled ---
 
     tokenizer_class = Tokenizer
diff --git a/sqlglot/dialects/duckdb.py b/sqlglot/dialects/duckdb.py
index c8313054..0f3c9ee3 100644
--- a/sqlglot/dialects/duckdb.py
+++ b/sqlglot/dialects/duckdb.py
@@ -172,6 +172,7 @@ class DuckDB(Dialect):
     SAFE_DIVISION = True
     INDEX_OFFSET = 1
     CONCAT_COALESCE = True
+    SUPPORTS_ORDER_BY_ALL = True
 
     # https://duckdb.org/docs/sql/introduction.html#creating-a-new-table
     NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
diff --git a/sqlglot/dialects/spark.py b/sqlglot/dialects/spark.py
index 2f2ec878..623aaba7 100644
--- a/sqlglot/dialects/spark.py
+++ b/sqlglot/dialects/spark.py
@@ -90,6 +90,8 @@ def _dateadd_sql(self: Spark.Generator, expression: exp.TsOrDsAdd | exp.Timestam
 
 
 class Spark(Spark2):
+    SUPPORTS_ORDER_BY_ALL = True
+
     class Tokenizer(Spark2.Tokenizer):
         STRING_ESCAPES_ALLOWED_IN_RAW_STRINGS = False
 
diff --git a/sqlglot/generator.py b/sqlglot/generator.py
index 482e5f34..c2ad9ade 100644
--- a/sqlglot/generator.py
+++ b/sqlglot/generator.py
@@ -512,6 +512,7 @@ class Generator(metaclass=_Generator):
 
     # Expressions whose comments are separated from them for better formatting
     WITH_SEPARATED_COMMENTS: t.Tuple[t.Type[exp.Expression], ...] = (
+        exp.Command,
         exp.Create,
         exp.Delete,
         exp.Drop,
diff --git a/sqlglot/parser.py b/sqlglot/parser.py
index 2718a135..f9ec3fd4 100644
--- a/sqlglot/parser.py
+++ b/sqlglot/parser.py
@@ -1478,7 +1478,10 @@ class Parser(metaclass=_Parser):
     def _parse_command(self) -> exp.Command:
         self._warn_unsupported()
         return self.expression(
-            exp.Command, this=self._prev.text.upper(), expression=self._parse_string()
+            exp.Command,
+            comments=self._prev_comments,
+            this=self._prev.text.upper(),
+            expression=self._parse_string(),
         )
 
     def _try_parse(self, parse_method: t.Callable[[], T], retreat: bool = False) -> t.Optional[T]:
@@ -3842,6 +3845,9 @@ class Parser(metaclass=_Parser):
         if not this:
             return None
 
+        if this.name.upper() == "ALL" and self.dialect.SUPPORTS_ORDER_BY_ALL:
+            this = exp.var("ALL")
+
         asc = self._match(TokenType.ASC)
         desc = self._match(TokenType.DESC) or (asc and False)
 


Test patch:
diff --git a/tests/dialects/test_bigquery.py b/tests/dialects/test_bigquery.py
index 803ac11a..75be8480 100644
--- a/tests/dialects/test_bigquery.py
+++ b/tests/dialects/test_bigquery.py
@@ -1427,6 +1427,12 @@ WHERE
             transpile("DATE_ADD(x, day)", read="bigquery")
 
     def test_warnings(self):
+        with self.assertLogs(parser_logger) as cm:
+            self.validate_identity(
+                "/* some comment */ DECLARE foo DATE DEFAULT DATE_SUB(current_date, INTERVAL 2 day)"
+            )
+            self.assertIn("contains unsupported syntax", cm.output[0])
+
         with self.assertLogs(helper_logger) as cm:
             self.validate_identity(
                 "WITH cte(c) AS (SELECT * FROM t) SELECT * FROM cte",
diff --git a/tests/dialects/test_dialect.py b/tests/dialects/test_dialect.py
index 44839e9e..a6ac69a7 100644
--- a/tests/dialects/test_dialect.py
+++ b/tests/dialects/test_dialect.py
@@ -1164,6 +1164,13 @@ class TestDialect(Validator):
             },
         )
 
+        order_by_all_sql = "SELECT * FROM t ORDER BY ALL"
+        self.validate_identity(order_by_all_sql).find(exp.Ordered).this.assert_is(exp.Column)
+
+        for dialect in ("duckdb", "spark", "databricks"):
+            with self.subTest(f"Testing ORDER BY ALL in {dialect}"):
+                parse_one(order_by_all_sql, read=dialect).find(exp.Ordered).this.assert_is(exp.Var)
+
     def test_json(self):
         self.validate_all(
             """JSON_EXTRACT(x, '$["a b"]')""",