Repository: tobymao/sqlglot

Issue:
Spark support for map(*) and struct(*)
Theres a few ways to covert columns to json in spark depending on the use case, typically using map or struct. While its common to specify the schema, thats not required and sometimes not desired. 
```python
import sqlglot

sql = """
select
    to_json(map(*)),
    to_json(struct(*))
from data
"""
print(sqlglot.parse_one(sql, dialect='spark').sql(dialect='spark', pretty=True))
```
outputs:
```
SELECT
  TO_JSON(STAR_MAP(*)),
  TO_JSON(STRUCT(* AS col1))
FROM data
```
I'd expect this to not modify the query. The `to_json` part likely isn't relevant.

1.  `star_map` isn't a function in spark
2.  `struct(* as col1)` throws: `AnalysisException: Invalid use of '*' in expression 'alias'`

Discussion:

Solution patch:
diff --git a/sqlglot/dialects/hive.py b/sqlglot/dialects/hive.py
index 587fee3482..048907ac42 100644
--- a/sqlglot/dialects/hive.py
+++ b/sqlglot/dialects/hive.py
@@ -446,6 +446,9 @@ def _parse_parameter(self) -> exp.Parameter:
             return self.expression(exp.Parameter, this=this, expression=expression)
 
         def _to_prop_eq(self, expression: exp.Expression, index: int) -> exp.Expression:
+            if expression.is_star:
+                return expression
+
             if isinstance(expression, exp.Column):
                 key = expression.this
             else:
@@ -577,6 +580,7 @@ class Generator(generator.Generator):
             exp.StrToTime: _str_to_time_sql,
             exp.StrToUnix: _str_to_unix_sql,
             exp.StructExtract: struct_extract_sql,
+            exp.StarMap: rename_func("MAP"),
             exp.Table: transforms.preprocess([transforms.unnest_generate_series]),
             exp.TimeStrToDate: rename_func("TO_DATE"),
             exp.TimeStrToTime: timestrtotime_sql,


Test patch:
diff --git a/tests/dialects/test_hive.py b/tests/dialects/test_hive.py
index 7caf9f9091..343be09a95 100644
--- a/tests/dialects/test_hive.py
+++ b/tests/dialects/test_hive.py
@@ -810,6 +810,21 @@ def test_hive(self):
 
         self.validate_identity("SELECT 1_2")
 
+        self.validate_all(
+            "SELECT MAP(*), STRUCT(*) FROM t",
+            read={
+                "hive": "SELECT MAP(*), STRUCT(*) FROM t",
+                "spark2": "SELECT MAP(*), STRUCT(*) FROM t",
+                "spark": "SELECT MAP(*), STRUCT(*) FROM t",
+                "databricks": "SELECT MAP(*), STRUCT(*) FROM t",
+            },
+            write={
+                "spark2": "SELECT MAP(*), STRUCT(*) FROM t",
+                "spark": "SELECT MAP(*), STRUCT(*) FROM t",
+                "databricks": "SELECT MAP(*), STRUCT(*) FROM t",
+            },
+        )
+
     def test_escapes(self) -> None:
         self.validate_identity("'\n'", "'\\n'")
         self.validate_identity("'\\n'")