czlll/Loc-Bench_V0.1 huggingface dataset:
Repository: tobymao/sqlglot
Issue category: Bug Report

Invalid syntax for Redshift:  AS REAL(8)
I'm building a parse tree that includes selecting from a derived table that has its own SQL, which I then just include natively in the parse tree.

```
SELECT
    b.proud_to_order_by_name::float(8)
```

When SQLGlot then generates the SQL for Redshift, it's doing this:

```
SELECT
    CAST(b.proud_to_order_by_name AS REAL(8)),
```

But Redshift throws an exception:  `com.amazon.redshift.util.RedshiftException: ERROR: syntax error at or near "(" in context "proud_to_order_by_name AS REAL("`

It seems to be happy when I run the SQL manually with just `AS REAL`.

Let me know, thanks.



Functions to edit:
sqlglot/dialects/postgres.py:Postgres

Patch:
diff --git a/sqlglot/dialects/postgres.py b/sqlglot/dialects/postgres.py
index e0f3c1b2bd..57984784bb 100644
--- a/sqlglot/dialects/postgres.py
+++ b/sqlglot/dialects/postgres.py
@@ -687,6 +687,14 @@ def datatype_sql(self, expression: exp.DataType) -> str:
                     values = self.expressions(expression, key="values", flat=True)
                     return f"{self.expressions(expression, flat=True)}[{values}]"
                 return "ARRAY"
+
+            if (
+                expression.is_type(exp.DataType.Type.DOUBLE, exp.DataType.Type.FLOAT)
+                and expression.expressions
+            ):
+                # Postgres doesn't support precision for REAL and DOUBLE PRECISION types
+                return f"FLOAT({self.expressions(expression, flat=True)})"
+
             return super().datatype_sql(expression)
 
         def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:

Test patch: diff --git a/tests/dialects/test_redshift.py b/tests/dialects/test_redshift.py
index 971d81b303..4a70859e42 100644
--- a/tests/dialects/test_redshift.py
+++ b/tests/dialects/test_redshift.py
@@ -320,6 +320,7 @@ def test_redshift(self):
         )
 
     def test_identity(self):
+        self.validate_identity("SELECT CAST(value AS FLOAT(8))")
         self.validate_identity("1 div", "1 AS div")
         self.validate_identity("LISTAGG(DISTINCT foo, ', ')")
         self.validate_identity("CREATE MATERIALIZED VIEW orders AUTO REFRESH YES AS SELECT 1")
Repository: tobymao/sqlglot
Issue category: Bug Report

`sqlglot.optimizer.qualify_columns.qualify_columns` fails on `table.*` inside `UNION ALL`
### Explanation

When using `qualify_columns` on a SQL query that contains a `UNION ALL` and one of the statement uses the `SELECT table.*` notation, `qualify_columns` raises an `sqlglot.errors.OptimizeError: Unknown table: p` error.

### Fully reproducible code snippet

```py
from sqlglot import parse_one
from sqlglot.schema import MappingSchema
from sqlglot.optimizer.qualify_columns import qualify_columns

SQL_DIALECT = "snowflake"

print(qualify_columns(parse_one("""
SELECT p.*
FROM p

UNION ALL

SELECT p2.*
FROM p2
""", dialect="snowflake"), schema=MappingSchema(dialect=SQL_DIALECT)).sql(pretty=True, dialect=SQL_DIALECT))
```

Running this snippet raises an error:
```
Traceback (most recent call last):
  File "test_sqlglot.py", line 7, in <module>
    print(qualify_columns(parse_one("""
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "sqlglot/optimizer/qualify_columns.py", line 81, in qualify_columns
    _expand_stars(
  File "sqlglot/optimizer/qualify_columns.py", line 623, in _expand_stars
    raise OptimizeError(f"Unknown table: {table}")
sqlglot.errors.OptimizeError: Unknown table: p
```

Looks like, inside `_expand_stars`, `scope.sources` is an empty list. In that exact case, `scope` represents the entire query (with both SELECT and the UNION ALL in between), and `scope_type` is ROOT (not UNION).


Again, happy to make a PR.


Functions to edit:
sqlglot/optimizer/qualify_columns.py:qualify_columns

Patch:
diff --git a/sqlglot/optimizer/qualify_columns.py b/sqlglot/optimizer/qualify_columns.py
index 4880a615c6..ca5684407c 100644
--- a/sqlglot/optimizer/qualify_columns.py
+++ b/sqlglot/optimizer/qualify_columns.py
@@ -75,7 +75,7 @@ def qualify_columns(
         if not schema.empty and expand_alias_refs:
             _expand_alias_refs(scope, resolver)
 
-        if not isinstance(scope.expression, exp.UDTF):
+        if isinstance(scope.expression, exp.Select):
             if expand_stars:
                 _expand_stars(
                     scope,

Test patch: diff --git a/tests/fixtures/optimizer/qualify_columns.sql b/tests/fixtures/optimizer/qualify_columns.sql
index 2640145bed..735c71a5e7 100644
--- a/tests/fixtures/optimizer/qualify_columns.sql
+++ b/tests/fixtures/optimizer/qualify_columns.sql
@@ -190,6 +190,10 @@ SELECT x._col_0 AS _col_0, x._col_1 AS _col_1 FROM (VALUES (1, 2)) AS x(_col_0,
 SELECT SOME_UDF(data).* FROM t;
 SELECT SOME_UDF(t.data).* FROM t AS t;
 
+# execute: false
+SELECT p.* FROM p UNION ALL SELECT p2.* FROM p2;
+SELECT p.* FROM p AS p UNION ALL SELECT p2.* FROM p2 AS p2;
+
 # execute: false
 # allow_partial_qualification: true
 # validate_qualify_columns: false
Repository: tobymao/sqlglot
Issue category: Bug Report

Parsing DuckDB escape string literals throws error
Trying to parse escape string literals like `E'\n'` fails with `sqlglot.errors.ParseError: Invalid expression / Unexpected token`. Can be worked around by using character codes and string concatenation.

**Fully reproducible code snippet**
```python
import sqlglot

sql = r"SELECT E'\n'"
ast = sqlglot.parse_one(sql, dialect="duckdb")
print(repr(ast))
```

**Official Documentation**
- Docs for escape string literals: https://duckdb.org/docs/sql/data_types/literal_types.html#escape-string-literals
- General info about how to handle special characters: https://duckdb.org/docs/sql/data_types/text#strings-with-special-characters



Functions to edit:
sqlglot/dialects/duckdb.py:Tokenizer

Patch:
diff --git a/sqlglot/dialects/duckdb.py b/sqlglot/dialects/duckdb.py
index 946410f5bf..33a9366029 100644
--- a/sqlglot/dialects/duckdb.py
+++ b/sqlglot/dialects/duckdb.py
@@ -297,6 +297,7 @@ def to_json_path(self, path: t.Optional[exp.Expression]) -> t.Optional[exp.Expre
         return super().to_json_path(path)
 
     class Tokenizer(tokens.Tokenizer):
+        BYTE_STRINGS = [("e'", "'"), ("E'", "'")]
         HEREDOC_STRINGS = ["$"]
 
         HEREDOC_TAG_IS_IDENTIFIER = True

Test patch: diff --git a/tests/dialects/test_duckdb.py b/tests/dialects/test_duckdb.py
index a9d6330228..09f0134dbc 100644
--- a/tests/dialects/test_duckdb.py
+++ b/tests/dialects/test_duckdb.py
@@ -899,6 +899,16 @@ def test_duckdb(self):
             "NOT a ILIKE b",
         )
 
+        self.validate_all(
+            "SELECT e'Hello\nworld'",
+            read={
+                "duckdb": "SELECT E'Hello\nworld'",
+            },
+            write={
+                "duckdb": "SELECT e'Hello\nworld'",
+            },
+        )
+
     def test_array_index(self):
         with self.assertLogs(helper_logger) as cm:
             self.validate_all(
Repository: tobymao/sqlglot
Issue category: Bug Report

Trino CURRENT_USER does not allow parenthesis
```python
from sqlglot import parse_one
from sqlglot.dialects import Trino

sql_in = parse_one("SELECT CURRENT_USER", dialect=Trino)
print(sql_in.sql(dialect=Trino))
```
```bash
SELECT CURRENT_USER()
```

https://prestodb.io/docs/current/functions/session.html
https://trino.io/docs/current/functions/session.html

I believe that the Postgres dialect already implements the desired workaround for this function
https://github.com/tobymao/sqlglot/blob/v25.32.1/sqlglot/dialects/postgres.py#L527


Functions to edit:
sqlglot/dialects/presto.py:Presto

Patch:
diff --git a/sqlglot/dialects/presto.py b/sqlglot/dialects/presto.py
index 056d974c27..a87a5fce00 100644
--- a/sqlglot/dialects/presto.py
+++ b/sqlglot/dialects/presto.py
@@ -376,6 +376,7 @@ class Generator(generator.Generator):
             exp.Cast: transforms.preprocess([transforms.epoch_cast_to_ts]),
             exp.CurrentTime: lambda *_: "CURRENT_TIME",
             exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
+            exp.CurrentUser: lambda *_: "CURRENT_USER",
             exp.DateAdd: _date_delta_sql("DATE_ADD"),
             exp.DateDiff: lambda self, e: self.func(
                 "DATE_DIFF", unit_to_str(e), e.expression, e.this

Test patch: diff --git a/tests/dialects/test_presto.py b/tests/dialects/test_presto.py
index c0870895e3..f39a0d5ef5 100644
--- a/tests/dialects/test_presto.py
+++ b/tests/dialects/test_presto.py
@@ -1071,6 +1071,18 @@ def test_presto(self):
                 "databricks": "REGEXP_EXTRACT('abc', '(a)(b)(c)', 0)",
             },
         )
+        self.validate_all(
+            "CURRENT_USER",
+            read={
+                "presto": "CURRENT_USER",
+                "trino": "CURRENT_USER",
+                "snowflake": "CURRENT_USER()",  # Although the ANSI standard is CURRENT_USER
+            },
+            write={
+                "trino": "CURRENT_USER",
+                "snowflake": "CURRENT_USER()",
+            },
+        )
 
     def test_encode_decode(self):
         self.validate_identity("FROM_UTF8(x, y)")
Repository: tobymao/sqlglot
Issue category: Bug Report

Incorrect handling of TSQL DATEPART
Read & write dialect: tsql
Issue: TSQL DATEPART is incorrectly interpreted by sqlglot when calculating week number.

`SELECT DATEPART(WEEK, '2024-11-21')`

Example TSQL to return week # of year, for 2024-11-21 this would be 47.

This is incorrectly interpreted as:

`SELECT DATEPART(DW, CAST('2024-11-21' AS DATETIME2))`

Which incorrectly refers to 'DW' as the DATEPART, returning weekday # in week 1-7, instead of week # in year 1-52.

[https://learn.microsoft.com/en-us/sql/t-sql/functions/datepart-transact-sql?view=sql-server-ver16](https://learn.microsoft.com/en-us/sql/t-sql/functions/datepart-transact-sql?view=sql-server-ver16).

Using sqlglot 25.31.4 and sqlmesh 0.133.0



Functions to edit:
sqlglot/dialects/tsql.py:TSQL

Patch:
diff --git a/sqlglot/dialects/tsql.py b/sqlglot/dialects/tsql.py
index 5bd4dde977..5bb257ef23 100644
--- a/sqlglot/dialects/tsql.py
+++ b/sqlglot/dialects/tsql.py
@@ -178,7 +178,7 @@ def _build_hashbytes(args: t.List) -> exp.Expression:
     return exp.func("HASHBYTES", *args)
 
 
-DATEPART_ONLY_FORMATS = {"DW", "HOUR", "QUARTER"}
+DATEPART_ONLY_FORMATS = {"DW", "WK", "HOUR", "QUARTER"}
 
 
 def _format_sql(self: TSQL.Generator, expression: exp.NumberToStr | exp.TimeToStr) -> str:
@@ -398,8 +398,8 @@ class TSQL(Dialect):
         "s": "%-S",
         "millisecond": "%f",
         "ms": "%f",
-        "weekday": "%W",
-        "dw": "%W",
+        "weekday": "%w",
+        "dw": "%w",
         "month": "%m",
         "mm": "%M",
         "m": "%-M",

Test patch: diff --git a/tests/dialects/test_tsql.py b/tests/dialects/test_tsql.py
index e4bd9a7abf..094e5f2336 100644
--- a/tests/dialects/test_tsql.py
+++ b/tests/dialects/test_tsql.py
@@ -1308,6 +1308,12 @@ def test_datepart(self):
             },
         )
 
+        for fmt in ("WEEK", "WW", "WK"):
+            self.validate_identity(
+                f"SELECT DATEPART({fmt}, '2024-11-21')",
+                "SELECT DATEPART(WK, CAST('2024-11-21' AS DATETIME2))",
+            )
+
     def test_convert(self):
         self.validate_all(
             "CONVERT(NVARCHAR(200), x)",
Repository: tobymao/sqlglot
Issue category: Bug Report

DuckDB Min Arg's not supported
```python
import sqlglot

print(sqlglot.parse_one("select min_by(item, a, 2) from test", dialect="duckdb").sql("duckdb"))
```
gives:
```
Argument 'count' is not supported for expression 'ArgMin' when targeting DuckDB.
SELECT ARG_MIN(item, a) FROM test
```

Duckdb does support this however: https://duckdb.org/docs/sql/functions/aggregates.html#min_byarg-val-n



Functions to edit:
sqlglot/dialects/duckdb.py:DuckDB

Patch:
diff --git a/sqlglot/dialects/duckdb.py b/sqlglot/dialects/duckdb.py
index 9dd7a365dd..9c757d677c 100644
--- a/sqlglot/dialects/duckdb.py
+++ b/sqlglot/dialects/duckdb.py
@@ -9,7 +9,6 @@
     JSON_EXTRACT_TYPE,
     NormalizationStrategy,
     approx_count_distinct_sql,
-    arg_max_or_min_no_count,
     arrow_json_extract_sql,
     binary_from_function,
     bool_xor_sql,
@@ -516,8 +515,6 @@ class Generator(generator.Generator):
             exp.ApproxDistinct: approx_count_distinct_sql,
             exp.Array: inline_array_unless_query,
             exp.ArrayFilter: rename_func("LIST_FILTER"),
-            exp.ArgMax: arg_max_or_min_no_count("ARG_MAX"),
-            exp.ArgMin: arg_max_or_min_no_count("ARG_MIN"),
             exp.ArraySort: _array_sort_sql,
             exp.ArraySum: rename_func("LIST_SUM"),
             exp.BitwiseXor: rename_func("XOR"),

Test patch: diff --git a/tests/dialects/test_presto.py b/tests/dialects/test_presto.py
index 31a078c17c..74da50d6e0 100644
--- a/tests/dialects/test_presto.py
+++ b/tests/dialects/test_presto.py
@@ -722,7 +722,7 @@ def test_presto(self):
             "SELECT MIN_BY(a.id, a.timestamp, 3) FROM a",
             write={
                 "clickhouse": "SELECT argMin(a.id, a.timestamp) FROM a",
-                "duckdb": "SELECT ARG_MIN(a.id, a.timestamp) FROM a",
+                "duckdb": "SELECT ARG_MIN(a.id, a.timestamp, 3) FROM a",
                 "presto": "SELECT MIN_BY(a.id, a.timestamp, 3) FROM a",
                 "snowflake": "SELECT MIN_BY(a.id, a.timestamp, 3) FROM a",
                 "spark": "SELECT MIN_BY(a.id, a.timestamp) FROM a",
Repository: tobymao/sqlglot
Issue category: Bug Report

Simple query, wrong tables list
Very simple query, wrong tables list! it considers `activity_id` as a table!

```python
sql='ALTER TABLE ride DROP COLUMN activity_id'
list(sqlglot.parse_one(sql, read='mysql').find_all(sqlglot.exp.Table))
# list(sqlglot.parse_one(sql, read='mysql').find_all(sqlglot.exp.Table))
#  0 = {Table} Table(\n  this=Identifier(this=ride, quoted=False))
#  1 = {Table} Table(\n  this=Identifier(this=activity_id, quoted=False))
```




Functions to edit:
sqlglot/parser.py:Parser._parse_drop

Patch:
diff --git a/sqlglot/parser.py b/sqlglot/parser.py
index a2f118fb5c..5fa7d1ef13 100644
--- a/sqlglot/parser.py
+++ b/sqlglot/parser.py
@@ -1738,9 +1738,13 @@ def _parse_drop(self, exists: bool = False) -> exp.Drop | exp.Command:
 
         concurrently = self._match_text_seq("CONCURRENTLY")
         if_exists = exists or self._parse_exists()
-        table = self._parse_table_parts(
-            schema=True, is_db_reference=self._prev.token_type == TokenType.SCHEMA
-        )
+
+        if kind == "COLUMN":
+            this = self._parse_column()
+        else:
+            this = self._parse_table_parts(
+                schema=True, is_db_reference=self._prev.token_type == TokenType.SCHEMA
+            )
 
         cluster = self._parse_on_property() if self._match(TokenType.ON) else None
 
@@ -1752,7 +1756,7 @@ def _parse_drop(self, exists: bool = False) -> exp.Drop | exp.Command:
         return self.expression(
             exp.Drop,
             exists=if_exists,
-            this=table,
+            this=this,
             expressions=expressions,
             kind=self.dialect.CREATABLE_KIND_MAPPING.get(kind) or kind,
             temporary=temporary,

Test patch: diff --git a/tests/test_parser.py b/tests/test_parser.py
index ba1240c4f7..b60d719341 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -879,3 +879,8 @@ def test_odbc_date_literals(self):
             expr = parse_one(sql)
             self.assertIsInstance(expr, exp.Insert)
             self.assertIsInstance(expr.expression.expressions[0].expressions[0], cls)
+
+    def test_drop_column(self):
+        ast = parse_one("ALTER TABLE tbl DROP COLUMN col")
+        self.assertEqual(len(list(ast.find_all(exp.Table))), 1)
+        self.assertEqual(len(list(ast.find_all(exp.Column))), 1)
Repository: tobymao/sqlglot
Issue category: Bug Report

`median` constructed using `sg.func` is incorrectly capitalized when compiled to ClickHouse
```
In [2]: import sqlglot as sg

In [3]: sg.__version__
Out[3]: '25.29.0'

In [4]: sg.func("median", sg.to_identifier("x")).sql("clickhouse")
Out[4]: 'MEDIAN(x)'
```


Functions to edit:
sqlglot/dialects/clickhouse.py:ClickHouse

Patch:
diff --git a/sqlglot/dialects/clickhouse.py b/sqlglot/dialects/clickhouse.py
index 25cc399d86..ee540565f4 100644
--- a/sqlglot/dialects/clickhouse.py
+++ b/sqlglot/dialects/clickhouse.py
@@ -949,6 +949,7 @@ class Generator(generator.Generator):
             exp.JSONPathKey: json_path_key_only_name,
             exp.JSONPathRoot: lambda *_: "",
             exp.Map: lambda self, e: _lower_func(var_map_sql(self, e)),
+            exp.Median: rename_func("median"),
             exp.Nullif: rename_func("nullIf"),
             exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}",
             exp.Pivot: no_pivot_sql,

Test patch: diff --git a/tests/dialects/test_dialect.py b/tests/dialects/test_dialect.py
index 85402e2cd3..6f6606eed5 100644
--- a/tests/dialects/test_dialect.py
+++ b/tests/dialects/test_dialect.py
@@ -3007,7 +3007,7 @@ def test_median(self):
                     "databricks": f"MEDIAN(x){suffix}",
                     "redshift": f"MEDIAN(x){suffix}",
                     "oracle": f"MEDIAN(x){suffix}",
-                    "clickhouse": f"MEDIAN(x){suffix}",
+                    "clickhouse": f"median(x){suffix}",
                     "postgres": f"PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY x){suffix}",
                 },
             )
Repository: tobymao/sqlglot
Issue category: Bug Report

Bugs in parsing `DATE_TRUNC` function with the timezone parameter in BigQuery
When using `DATE_TRUNC(timestamp_value, timestamp_granularity[, time_zone])` in BigQuery, the `time_zone` argument failed to parse correctly.

For example:
```sql
-- input
SELECT DATE_TRUNC(TIMESTAMP '2024-01-01 12:00:00', MONTH, 'UTC+8')

-- output
SELECT DATE_TRUNC(CAST('2024-01-01 12:00:00' AS TIMESTAMP), MONTH)
```
The timezone `UTC+8` is missing.

The Python script is as follows::
```python
sql = "SELECT DATE_TRUNC(TIMESTAMP '2024-01-01 12:00:00', MONTH, 'UTC+8')"
ast = parse_one(sql, dialect="bigquery")
print(ast.sql(dialect="bigquery"))
# output: SELECT DATE_TRUNC(CAST('2024-01-01 12:00:00' AS TIMESTAMP), MONTH)
```



Functions to edit:
sqlglot/dialects/bigquery.py:BigQuery
Functions added: sqlglot/dialects/bigquery.py:BigQuery

Patch:
diff --git a/sqlglot/dialects/bigquery.py b/sqlglot/dialects/bigquery.py
index 3a71708820..6198aa97a1 100644
--- a/sqlglot/dialects/bigquery.py
+++ b/sqlglot/dialects/bigquery.py
@@ -427,6 +427,7 @@ class Parser(parser.Parser):
             "DATE_TRUNC": lambda args: exp.DateTrunc(
                 unit=exp.Literal.string(str(seq_get(args, 1))),
                 this=seq_get(args, 0),
+                zone=seq_get(args, 2),
             ),
             "DATETIME": _build_datetime,
             "DATETIME_ADD": build_date_delta_with_interval(exp.DatetimeAdd),
@@ -732,7 +733,9 @@ class Generator(generator.Generator):
             exp.DateSub: date_add_interval_sql("DATE", "SUB"),
             exp.DatetimeAdd: date_add_interval_sql("DATETIME", "ADD"),
             exp.DatetimeSub: date_add_interval_sql("DATETIME", "SUB"),
-            exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")),
+            exp.DateTrunc: lambda self, e: self.func(
+                "DATE_TRUNC", e.this, e.text("unit"), e.args.get("zone")
+            ),
             exp.FromTimeZone: lambda self, e: self.func(
                 "DATETIME", self.func("TIMESTAMP", e.this, e.args.get("zone")), "'UTC'"
             ),

Test patch: diff --git a/tests/dialects/test_bigquery.py b/tests/dialects/test_bigquery.py
index 0e91f924b5..8a7fb4cffa 100644
--- a/tests/dialects/test_bigquery.py
+++ b/tests/dialects/test_bigquery.py
@@ -165,6 +165,7 @@ def test_bigquery(self):
         self.validate_identity("SELECT * FROM foo.bar.25ab c", "SELECT * FROM foo.bar.`25ab` AS c")
         self.validate_identity("x <> ''")
         self.validate_identity("DATE_TRUNC(col, WEEK(MONDAY))")
+        self.validate_identity("DATE_TRUNC(col, MONTH, 'UTC+8')")
         self.validate_identity("SELECT b'abc'")
         self.validate_identity("SELECT AS STRUCT 1 AS a, 2 AS b")
         self.validate_identity("SELECT DISTINCT AS STRUCT 1 AS a, 2 AS b")
Repository: tobymao/sqlglot
Issue category: Feature Request

Add support for Bigquery's Levenstein (EDIT_DISTANCE) function
**Is your feature request related [to a problem? Please describe.**
Bigquery's implementation of the Levenshtein function (EDIT_DISTANCE)](https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#edit_distance) is not transpiled.

**Describe the solution you'd like**
Add it to Bigquery's dialect transpiler

**Describe alternatives you've considered**
None that are workable.

**Additional context**
N/A.



Functions to edit:
sqlglot/dialects/bigquery.py:BigQuery

Patch:
diff --git a/sqlglot/dialects/bigquery.py b/sqlglot/dialects/bigquery.py
index 8e248daa2d..3e08efe9ab 100644
--- a/sqlglot/dialects/bigquery.py
+++ b/sqlglot/dialects/bigquery.py
@@ -733,6 +733,7 @@ class Generator(generator.Generator):
             exp.ILike: no_ilike_sql,
             exp.IntDiv: rename_func("DIV"),
             exp.JSONFormat: rename_func("TO_JSON_STRING"),
+            exp.Levenshtein: rename_func("EDIT_DISTANCE"),
             exp.Max: max_or_greatest,
             exp.MD5: lambda self, e: self.func("TO_HEX", self.func("MD5", e.this)),
             exp.MD5Digest: rename_func("MD5"),

Test patch: diff --git a/tests/dialects/test_dialect.py b/tests/dialects/test_dialect.py
index 96ce600b54..84a4ff3711 100644
--- a/tests/dialects/test_dialect.py
+++ b/tests/dialects/test_dialect.py
@@ -1762,6 +1762,7 @@ def test_operators(self):
         self.validate_all(
             "LEVENSHTEIN(col1, col2)",
             write={
+                "bigquery": "EDIT_DISTANCE(col1, col2)",
                 "duckdb": "LEVENSHTEIN(col1, col2)",
                 "drill": "LEVENSHTEIN_DISTANCE(col1, col2)",
                 "presto": "LEVENSHTEIN_DISTANCE(col1, col2)",
@@ -1772,6 +1773,7 @@ def test_operators(self):
         self.validate_all(
             "LEVENSHTEIN(coalesce(col1, col2), coalesce(col2, col1))",
             write={
+                "bigquery": "EDIT_DISTANCE(COALESCE(col1, col2), COALESCE(col2, col1))",
                 "duckdb": "LEVENSHTEIN(COALESCE(col1, col2), COALESCE(col2, col1))",
                 "drill": "LEVENSHTEIN_DISTANCE(COALESCE(col1, col2), COALESCE(col2, col1))",
                 "presto": "LEVENSHTEIN_DISTANCE(COALESCE(col1, col2), COALESCE(col2, col1))",
Repository: tobymao/sqlglot
Issue category: Feature Request

Transpile from DuckDB to BigQuery for UUID results in a BigQuery column type of UUID but no such type exists in BQ
As the name suggests DuckDB defines a number of column types one of which is UUID. But such a type doesn't exist in BigQuery. The below snippet shows that.

```
>>> sqlg.transpile("create table foo(a long, id uuid)", read="duckdb", write="
... bigquery")[0]
'CREATE TABLE foo (a INT64, id UUID)'
```

There exists a BQ function to generate UUIDs: `GENERATE_UUID` and it returns a string.

SQLGlot should probably parse this and return it as a `STRING` when going from duckdb to BQ.

More types reference: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types



Functions to edit:
sqlglot/dialects/bigquery.py:BigQuery
Functions added: sqlglot/dialects/bigquery.py:BigQuery

Patch:
diff --git a/sqlglot/dialects/bigquery.py b/sqlglot/dialects/bigquery.py
index 4c6747d161..6c76635c8a 100644
--- a/sqlglot/dialects/bigquery.py
+++ b/sqlglot/dialects/bigquery.py
@@ -753,8 +753,9 @@ class Generator(generator.Generator):
             exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
             exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
             exp.DataType.Type.TINYINT: "INT64",
-            exp.DataType.Type.VARBINARY: "BYTES",
             exp.DataType.Type.ROWVERSION: "BYTES",
+            exp.DataType.Type.UUID: "STRING",
+            exp.DataType.Type.VARBINARY: "BYTES",
             exp.DataType.Type.VARCHAR: "STRING",
             exp.DataType.Type.VARIANT: "ANY TYPE",
         }

Test patch: diff --git a/tests/dialects/test_duckdb.py b/tests/dialects/test_duckdb.py
index 18a030c6bd..98d1604bde 100644
--- a/tests/dialects/test_duckdb.py
+++ b/tests/dialects/test_duckdb.py
@@ -18,6 +18,13 @@ def test_duckdb(self):
             "WITH _data AS (SELECT [STRUCT(1 AS a, 2 AS b), STRUCT(2 AS a, 3 AS b)] AS col) SELECT col.b FROM _data, UNNEST(_data.col) AS col WHERE col.a = 1",
         )
 
+        self.validate_all(
+            "CAST(x AS UUID)",
+            write={
+                "bigquery": "CAST(x AS STRING)",
+                "duckdb": "CAST(x AS UUID)",
+            },
+        )
         self.validate_all(
             """SELECT CASE WHEN JSON_VALID('{"x: 1}') THEN '{"x: 1}' ELSE NULL END""",
             read={
Repository: tobymao/sqlglot
Issue category: Feature Request

Redshift - add support for oracle style join markers ` (+)`
**Fully reproducible code snippet**
```python
from sqlglot import parse_one
sample_sql_stmt = "select a.foo, b.bar, a.baz from a, b where a.baz = b.baz (+)"
parse_one(sample_sql_stmt, read="redshift").sql(dialect="redshift")
```
expected:
`SELECT a.foo, b.bar, a.baz FROM a, b WHERE a.baz = b.baz (+)`

actual:
`SELECT a.foo, b.bar, a.baz FROM a, b WHERE a.baz = b.BAZ()`

**Official Documentation**
[Oracle-Style outer joins in the WHERE clause](https://docs.aws.amazon.com/redshift/latest/dg/r_WHERE_oracle_outer.html)
>For Oracle compatibility, Amazon Redshift supports the Oracle outer-join operator (+) in WHERE clause join conditions



Functions to edit:
sqlglot/dialects/redshift.py:Redshift

Patch:
diff --git a/sqlglot/dialects/redshift.py b/sqlglot/dialects/redshift.py
index df6985df42..0dd372e7d3 100644
--- a/sqlglot/dialects/redshift.py
+++ b/sqlglot/dialects/redshift.py
@@ -115,6 +115,12 @@ def _parse_approximate_count(self) -> t.Optional[exp.ApproxDistinct]:
             self._retreat(index)
             return None
 
+        def _parse_column(self) -> t.Optional[exp.Expression]:
+            column = super()._parse_column()
+            if column:
+                column.set("join_mark", self._match(TokenType.JOIN_MARKER))
+            return column
+
     class Tokenizer(Postgres.Tokenizer):
         BIT_STRINGS = []
         HEX_STRINGS = []
@@ -128,6 +134,7 @@ class Tokenizer(Postgres.Tokenizer):
             "UNLOAD": TokenType.COMMAND,
             "VARBYTE": TokenType.VARBINARY,
             "MINUS": TokenType.EXCEPT,
+            "(+)": TokenType.JOIN_MARKER,
         }
         KEYWORDS.pop("VALUES")
 
@@ -148,6 +155,7 @@ class Generator(Postgres.Generator):
         HEX_FUNC = "TO_HEX"
         # Redshift doesn't have `WITH` as part of their with_properties so we remove it
         WITH_PROPERTIES_PREFIX = " "
+        COLUMN_JOIN_MARKS_SUPPORTED = True
 
         TYPE_MAPPING = {
             **Postgres.Generator.TYPE_MAPPING,

Test patch: diff --git a/tests/dialects/test_redshift.py b/tests/dialects/test_redshift.py
index 844fe461d4..fa4270b917 100644
--- a/tests/dialects/test_redshift.py
+++ b/tests/dialects/test_redshift.py
@@ -585,3 +585,9 @@ def test_column_unnesting(self):
         self.assertEqual(
             ast.sql("redshift"), "SELECT * FROM x AS a, a.b AS c, c.d.e AS f, f.g.h.i.j.k AS l"
         )
+
+    def test_join_markers(self):
+        self.validate_identity(
+            "select a.foo, b.bar, a.baz from a, b where a.baz = b.baz (+)",
+            "SELECT a.foo, b.bar, a.baz FROM a, b WHERE a.baz = b.baz (+)",
+        )
Repository: tobymao/sqlglot
Issue category: Feature Request

Allow comma-separated values for `CREATE SEQUENCE` properties (Snowflake)
Allow comma-separated values for `CREATE SEQUENCE` properties in Snowflake queries.

This query can be parsed successfully (results is an instance of `exp.Create`):
```
    query = "CREATE SEQUENCE seq1 WITH START=1 INCREMENT=1 ORDER"
    result = parse_one(query, dialect="snowflake")
    print(type(result))

    --> <class 'sqlglot.expressions.Create'>
```

... whereas the following query cannot be fully parsed and is returned as a generic `exp.Command` as fallback:
```
    query = "CREATE SEQUENCE seq1 WITH START=1, INCREMENT=1 ORDER"
    result = parse_one(query, dialect="snowflake")
    print(type(result))

    --> <class 'sqlglot.expressions.Command'>
```

(note - the only subtle difference is the comma `,` between the `START` and `INCREMENT` properties)

Note that the second query syntax may not be covered in the Snowflake docs, but it is indeed a valid syntax that can be executed against Snowflake (and some Snowflake client apps/SDKs are generating queries that are using this syntax, unfortunately).


Functions to edit:
sqlglot/parser.py:Parser._parse_sequence_properties

Patch:
diff --git a/sqlglot/parser.py b/sqlglot/parser.py
index 229af18aec..8f5050ee31 100644
--- a/sqlglot/parser.py
+++ b/sqlglot/parser.py
@@ -1678,6 +1678,7 @@ def _parse_sequence_properties(self) -> t.Optional[exp.SequenceProperties]:
         index = self._index
 
         while self._curr:
+            self._match(TokenType.COMMA)
             if self._match_text_seq("INCREMENT"):
                 self._match_text_seq("BY")
                 self._match_text_seq("=")

Test patch: diff --git a/tests/dialects/test_snowflake.py b/tests/dialects/test_snowflake.py
index d03412cace..c9150ff3ee 100644
--- a/tests/dialects/test_snowflake.py
+++ b/tests/dialects/test_snowflake.py
@@ -1223,6 +1223,14 @@ def test_ddl(self):
             "CREATE OR REPLACE FUNCTION my_udtf(foo BOOLEAN) RETURNS TABLE(col1 ARRAY(INT)) AS $$ WITH t AS (SELECT CAST([1, 2, 3] AS ARRAY(INT)) AS c) SELECT c FROM t $$",
             "CREATE OR REPLACE FUNCTION my_udtf(foo BOOLEAN) RETURNS TABLE (col1 ARRAY(INT)) AS ' WITH t AS (SELECT CAST([1, 2, 3] AS ARRAY(INT)) AS c) SELECT c FROM t '",
         )
+        self.validate_identity(
+            "CREATE SEQUENCE seq1 WITH START=1, INCREMENT=1 ORDER",
+            "CREATE SEQUENCE seq1 START=1 INCREMENT BY 1 ORDER",
+        )
+        self.validate_identity(
+            "CREATE SEQUENCE seq1 WITH START=1 INCREMENT=1 ORDER",
+            "CREATE SEQUENCE seq1 START=1 INCREMENT=1 ORDER",
+        )
 
         self.validate_all(
             "CREATE TABLE orders_clone CLONE orders",
Repository: tobymao/sqlglot
Issue category: Feature Request

feat(snowflake): Adding support for DATE, TO_DATE, TRY_TO_DATE functions
Fixes #3152 

Add support for the mentioned functions by:

- Converting all of them to `exp.TsOrDsToDate` expressions if the format is present _or_ to date casts otherwise
- Adding a new argument `safe` in `exp.TsOrDsToDate` to preserve the roundtrip of `TRY_TO_DATE`, which has a different error handling behavior compared to `TO_DATE / DATE` 

For the transpilation issue #3152, no change was needed in DuckDB as it already transpiles the aforementioned expression to `strptime` (note that it produces a `TIMESTAMP`, thus the cast to `DATE`):

```
>>> import sqlglot
>>> sqlglot.transpile("SELECT try_to_date('01-01-1999', 'MM-DD-YYYY')", read="snowflake", write="duckdb")
SELECT CAST(STRPTIME('01-01-1999', '%m-%d-%Y') AS DATE)
```

Docs
-----------

1. [Snowflake TRY_TO_DATE](https://docs.snowflake.com/en/sql-reference/functions/try_to_date)
2. [Snowflake DATE / TO_DATE](https://docs.snowflake.com/en/sql-reference/functions/to_date)
3. [DuckDB strptime](https://duckdb.org/docs/sql/functions/dateformat.html#strptime-examples)


Functions to edit:
sqlglot/dialects/snowflake.py:_build_datetime

Patch:
diff --git a/sqlglot/dialects/snowflake.py b/sqlglot/dialects/snowflake.py
index 6022132354..0ffe4cf0a3 100644
--- a/sqlglot/dialects/snowflake.py
+++ b/sqlglot/dialects/snowflake.py
@@ -48,10 +48,12 @@ def _builder(args: t.List) -> exp.Func:
                     return exp.UnixToTime(this=value, scale=seq_get(args, 1))
                 if not is_float(value.this):
                     return build_formatted_time(exp.StrToTime, "snowflake")(args)
-            if kind == exp.DataType.Type.DATE and not int_value:
-                formatted_exp = build_formatted_time(exp.TsOrDsToDate, "snowflake")(args)
-                formatted_exp.set("safe", safe)
-                return formatted_exp
+
+        if len(args) == 2 and kind == exp.DataType.Type.DATE:
+            formatted_exp = build_formatted_time(exp.TsOrDsToDate, "snowflake")(args)
+            formatted_exp.set("safe", safe)
+            return formatted_exp
+
         return exp.Anonymous(this=name, expressions=args)
 
     return _builder

Test patch: diff --git a/tests/dialects/test_snowflake.py b/tests/dialects/test_snowflake.py
index 19a1eb58a9..00e6169ac0 100644
--- a/tests/dialects/test_snowflake.py
+++ b/tests/dialects/test_snowflake.py
@@ -985,6 +985,17 @@ def test_timestamps(self):
             "SELECT CAST('2019-02-28' AS DATE) + INTERVAL '1 day, 1 year'",
         )
 
+        self.validate_identity("DATE(x)").assert_is(exp.Anonymous)
+        self.validate_identity("TO_DATE(x)").assert_is(exp.Anonymous)
+        self.validate_identity("TRY_TO_DATE(x)").assert_is(exp.Anonymous)
+
+        self.validate_all(
+            "TO_DATE(x, 'MM-DD-YYYY')",
+            write={
+                "snowflake": "TO_DATE(x, 'mm-DD-yyyy')",
+                "duckdb": "CAST(STRPTIME(x, '%m-%d-%Y') AS DATE)",
+            },
+        )
         self.validate_all(
             "DATE('01-01-2000', 'MM-DD-YYYY')",
             write={
Repository: modin-project/modin
Issue category: Feature Request

Update exception message for `aggregate` function



Functions to edit:
modin/pandas/base.py:BasePandasDataset._validate_function

Patch:
diff --git a/modin/pandas/base.py b/modin/pandas/base.py
index 98d2e1d1520..18607ab4b6a 100644
--- a/modin/pandas/base.py
+++ b/modin/pandas/base.py
@@ -414,7 +414,7 @@ def error_raiser(msg, exception=Exception):
             if isinstance(fn, str):
                 if not (hasattr(self, fn) or hasattr(np, fn)):
                     on_invalid(
-                        f"{fn} is not valid function for {type(self)} object.",
+                        f"'{fn}' is not a valid function for '{type(self).__name__}' object",
                         AttributeError,
                     )
             elif not callable(fn):

Test patch: diff --git a/modin/pandas/test/test_series.py b/modin/pandas/test/test_series.py
index ce4e0df8a10..338044fe4f9 100644
--- a/modin/pandas/test/test_series.py
+++ b/modin/pandas/test/test_series.py
@@ -734,7 +734,12 @@ def test_aggregate_error_checking(data):
         lambda series: series.aggregate("cumprod"),
     )
     eval_general(
-        modin_series, pandas_series, lambda series: series.aggregate("NOT_EXISTS")
+        modin_series,
+        pandas_series,
+        lambda series: series.aggregate("NOT_EXISTS"),
+        raising_exceptions=AttributeError(
+            "'NOT_EXISTS' is not a valid function for 'Series' object"
+        ),
     )
Repository: modin-project/modin
Issue category: Feature Request

Update exception message for `insert` function



Functions to edit:
modin/pandas/dataframe.py:DataFrame.insert

Patch:
diff --git a/modin/pandas/dataframe.py b/modin/pandas/dataframe.py
index 0f0856652bc..35e9d58d54f 100644
--- a/modin/pandas/dataframe.py
+++ b/modin/pandas/dataframe.py
@@ -1048,10 +1048,17 @@ def insert(
             or isinstance(value, (array, np.ndarray))
             and len(value.shape) > 1
         ):
-            if value.shape[1] != 1:
+            if isinstance(value, (array, np.ndarray)) and value.shape[1] != 1:
                 raise ValueError(
                     f"Expected a 1D array, got an array with shape {value.shape}"
                 )
+            elif (
+                isinstance(value, (DataFrame, pandas.DataFrame)) and value.shape[1] != 1
+            ):
+                raise ValueError(
+                    "Expected a one-dimensional object, got a DataFrame with "
+                    + f"{len(value.columns)} columns instead."
+                )
             value = value.squeeze(axis=1)
         if not self._query_compiler.lazy_execution and len(self.index) == 0:
             if not hasattr(value, "index"):

Test patch: diff --git a/modin/pandas/test/dataframe/test_map_metadata.py b/modin/pandas/test/dataframe/test_map_metadata.py
index 40e1a7aded6..c63a00bb38e 100644
--- a/modin/pandas/test/dataframe/test_map_metadata.py
+++ b/modin/pandas/test/dataframe/test_map_metadata.py
@@ -1344,7 +1344,15 @@ def test_insert(data):
     )
 
     # Bad inserts
-    eval_insert(modin_df, pandas_df, col="Bad Column", value=lambda df: df)
+    eval_insert(
+        modin_df,
+        pandas_df,
+        col="Bad Column",
+        value=lambda df: df,
+        raising_exceptions=ValueError(
+            f"Expected a one-dimensional object, got a DataFrame with {len(pandas_df.columns)} columns instead."
+        ),
+    )
     eval_insert(
         modin_df,
         pandas_df,
diff --git a/modin/pandas/test/utils.py b/modin/pandas/test/utils.py
index 258e4af6b7d..2a2ad8662aa 100644
--- a/modin/pandas/test/utils.py
+++ b/modin/pandas/test/utils.py
@@ -904,7 +904,7 @@ def execute_callable(fn, inplace=False, md_kwargs={}, pd_kwargs={}):
                     assert not isinstance(
                         md_e, tuple(raising_exceptions)
                     ), f"not acceptable exception type: {md_e}"
-                elif raising_exceptions and type(raising_exceptions) is type:
+                elif raising_exceptions and type(raising_exceptions) is not type:
                     assert (
                         type(md_e) is type(raising_exceptions)
                         and md_e.args == raising_exceptions.args
Repository: modin-project/modin
Issue category: Feature Request

Update exception message for `iloc/loc` functions



Functions to edit:
modin/pandas/indexing.py:_LocationIndexerBase._validate_key_length

Patch:
diff --git a/modin/pandas/indexing.py b/modin/pandas/indexing.py
index 08bfb995efe..4ae8d0833e4 100644
--- a/modin/pandas/indexing.py
+++ b/modin/pandas/indexing.py
@@ -290,9 +290,7 @@ def _validate_key_length(self, key: tuple) -> tuple:  # noqa: GL08
                 if Ellipsis in key:
                     raise IndexingError(_one_ellipsis_message)
                 return self._validate_key_length(key)
-            raise IndexingError(
-                f"Too many indexers: you're trying to pass {len(key)} indexers to the {type(self.df)} having only {self.df.ndim} dimensions."
-            )
+            raise IndexingError("Too many indexers")
         return key
 
     def __getitem__(self, key):  # pragma: no cover

Test patch: diff --git a/modin/pandas/test/dataframe/test_indexing.py b/modin/pandas/test/dataframe/test_indexing.py
index 49a6e7edb25..d8ed79d9e99 100644
--- a/modin/pandas/test/dataframe/test_indexing.py
+++ b/modin/pandas/test/dataframe/test_indexing.py
@@ -870,10 +870,20 @@ def test_iloc_empty():
     df_equals(pandas_df, modin_df)
 
 
-def test_iloc_loc_key_length():
+def test_iloc_loc_key_length_except():
     modin_ser, pandas_ser = pd.Series(0), pandas.Series(0)
-    eval_general(modin_ser, pandas_ser, lambda ser: ser.iloc[0, 0])
-    eval_general(modin_ser, pandas_ser, lambda ser: ser.loc[0, 0])
+    eval_general(
+        modin_ser,
+        pandas_ser,
+        lambda ser: ser.iloc[0, 0],
+        raising_exceptions=pandas.errors.IndexingError("Too many indexers"),
+    )
+    eval_general(
+        modin_ser,
+        pandas_ser,
+        lambda ser: ser.loc[0, 0],
+        raising_exceptions=pandas.errors.IndexingError("Too many indexers"),
+    )
 
 
 def test_loc_series():
diff --git a/modin/pandas/test/utils.py b/modin/pandas/test/utils.py
index 258e4af6b7d..2a2ad8662aa 100644
--- a/modin/pandas/test/utils.py
+++ b/modin/pandas/test/utils.py
@@ -904,7 +904,7 @@ def execute_callable(fn, inplace=False, md_kwargs={}, pd_kwargs={}):
                     assert not isinstance(
                         md_e, tuple(raising_exceptions)
                     ), f"not acceptable exception type: {md_e}"
-                elif raising_exceptions and type(raising_exceptions) is type:
+                elif raising_exceptions and type(raising_exceptions) is not type:
                     assert (
                         type(md_e) is type(raising_exceptions)
                         and md_e.args == raising_exceptions.args
Repository: modin-project/modin
Issue category: Feature Request

Update Exception message for `astype` function in the case of duplicated values



Functions to edit:
modin/pandas/base.py:BasePandasDataset.astype

Patch:
diff --git a/modin/pandas/base.py b/modin/pandas/base.py
index 6779c47dc9b..98d2e1d1520 100644
--- a/modin/pandas/base.py
+++ b/modin/pandas/base.py
@@ -1005,11 +1005,7 @@ def astype(self, dtype, copy=None, errors="raise"):  # noqa: PR01, RT01, D200
         # convert it to a dict before passing it to the query compiler.
         if isinstance(dtype, (pd.Series, pandas.Series)):
             if not dtype.index.is_unique:
-                raise ValueError(
-                    "The new Series of types must have a unique index, i.e. "
-                    + "it must be one-to-one mapping from column names to "
-                    + " their new dtypes."
-                )
+                raise ValueError("cannot reindex on an axis with duplicate labels")
             dtype = {column: dtype for column, dtype in dtype.items()}
         # If we got a series or dict originally, dtype is a dict now. Its keys
         # must be column names.

Test patch: diff --git a/modin/pandas/test/dataframe/test_map_metadata.py b/modin/pandas/test/dataframe/test_map_metadata.py
index a47ab0cd850..40e1a7aded6 100644
--- a/modin/pandas/test/dataframe/test_map_metadata.py
+++ b/modin/pandas/test/dataframe/test_map_metadata.py
@@ -439,6 +439,9 @@ def test_astype():
             if isinstance(df, pd.DataFrame)
             else pandas.Series([str, str], index=["col1", "col1"])
         ),
+        raising_exceptions=ValueError(
+            "cannot reindex on an axis with duplicate labels"
+        ),
     )
 
 
diff --git a/modin/pandas/test/utils.py b/modin/pandas/test/utils.py
index b350b9aa934..258e4af6b7d 100644
--- a/modin/pandas/test/utils.py
+++ b/modin/pandas/test/utils.py
@@ -900,10 +900,18 @@ def execute_callable(fn, inplace=False, md_kwargs={}, pd_kwargs={}):
                 ), "Got Modin Exception type {}, but pandas Exception type {} was expected".format(
                     type(md_e), type(pd_e)
                 )
-                if raising_exceptions:
+                if raising_exceptions and isinstance(raising_exceptions, (list, tuple)):
                     assert not isinstance(
                         md_e, tuple(raising_exceptions)
                     ), f"not acceptable exception type: {md_e}"
+                elif raising_exceptions and type(raising_exceptions) is type:
+                    assert (
+                        type(md_e) is type(raising_exceptions)
+                        and md_e.args == raising_exceptions.args
+                    ), f"not acceptable Modin's exception: [{repr(md_e)}]"
+                    assert (
+                        pd_e.args == raising_exceptions.args
+                    ), f"not acceptable Pandas' exception: [{repr(pd_e)}]"
             else:
                 raise NoModinException(
                     f"Modin doesn't throw an exception, while pandas does: [{repr(pd_e)}]"
Repository: modin-project/modin
Issue category: Feature Request

Remove unidist specific workaround in `.from_pandas()`
Since unidist 0.6.0 (modin-project/unidist#409) it now always copy the input data, so the workaround can be removed
https://github.com/modin-project/modin/blob/01c529cf06cfaf412b5725f41c81a5f914b44b95/modin/core/dataframe/pandas/partitioning/partition_manager.py#L872-L880


Functions to edit:
modin/core/dataframe/pandas/partitioning/partition_manager.py:PandasDataframePartitionManager.split_pandas_df_into_partitions

Patch:
diff --git a/modin/core/dataframe/pandas/partitioning/partition_manager.py b/modin/core/dataframe/pandas/partitioning/partition_manager.py
index f7b3899550c..2ccbd1de47f 100644
--- a/modin/core/dataframe/pandas/partitioning/partition_manager.py
+++ b/modin/core/dataframe/pandas/partitioning/partition_manager.py
@@ -869,14 +869,7 @@ def split_pandas_df_into_partitions(
         put_func = cls._partition_class.put
         # even a full-axis slice can cost something (https://github.com/pandas-dev/pandas/issues/55202)
         # so we try not to do it if unnecessary.
-        # FIXME: it appears that this optimization doesn't work for Unidist correctly as it
-        # doesn't explicitly copy the data when putting it into storage (as the rest engines do)
-        # causing it to eventially share memory with a pandas object that was provided by user.
-        # Everything works fine if we do this column slicing as pandas then would set some flags
-        # to perform in COW mode apparently (and so it wouldn't crash our tests).
-        # @YarShev promised that this will be eventially fixed on Unidist's side, but for now there's
-        # this hacky condition
-        if col_chunksize >= len(df.columns) and Engine.get() != "Unidist":
+        if col_chunksize >= len(df.columns):
             col_parts = [df]
         else:
             col_parts = [

Test patch: diff --git a/modin/pandas/test/test_general.py b/modin/pandas/test/test_general.py
index 7a445657d2d..72f33d55d80 100644
--- a/modin/pandas/test/test_general.py
+++ b/modin/pandas/test/test_general.py
@@ -971,3 +971,15 @@ def make_frame(lib):
 def test_get(key):
     modin_df, pandas_df = create_test_dfs({"col0": [0, 1]})
     eval_general(modin_df, pandas_df, lambda df: df.get(key))
+
+
+def test_df_immutability():
+    """
+    Verify that modifications of the source data doesn't propagate to Modin's DataFrame objects.
+    """
+    src_data = pandas.DataFrame({"a": [1]})
+
+    md_df = pd.DataFrame(src_data)
+    src_data.iloc[0, 0] = 100
+
+    assert md_df._to_pandas().iloc[0, 0] == 1
Repository: sympy/sympy
Issue category: Bug Report

rewrite(abs) should call rewrite(Abs)
```py
>>> sign(x).rewrite(abs)
sign(x)
>>> sign(x).rewrite(Abs)
Piecewise((0, Eq(x, 0)), (x/Abs(x), True))
```

This is because `rewrite(x)` just dispatches to the method called `_eval_rewrite_as_x`, and the method here is called `_eval_rewrite_as_Abs` since `Abs` is the name of the class. But most people use `abs`, the built-in function which dispatches to `Abs`. So it should be special-cased in rewrite to call `Abs`. 


Functions to edit:
sympy/core/basic.py:Basic.rewrite

Patch:
diff --git a/sympy/core/basic.py b/sympy/core/basic.py
index 62ccd3ed5508..f9f04c728245 100644
--- a/sympy/core/basic.py
+++ b/sympy/core/basic.py
@@ -2075,6 +2075,11 @@ def rewrite(self, *args, deep=True, **hints):
         pattern = args[:-1]
         rule = args[-1]
 
+        # Special case: map `abs` to `Abs`
+        if rule is abs:
+            from sympy.functions.elementary.complexes import Abs
+            rule = Abs
+
         # support old design by _eval_rewrite_as_[...] method
         if isinstance(rule, str):
             method = "_eval_rewrite_as_%s" % rule

Test patch: diff --git a/sympy/core/tests/test_basic.py b/sympy/core/tests/test_basic.py
index 44faf93162f0..d452af7e2a8e 100644
--- a/sympy/core/tests/test_basic.py
+++ b/sympy/core/tests/test_basic.py
@@ -17,6 +17,9 @@
 from sympy.integrals.integrals import Integral
 from sympy.functions.elementary.exponential import exp
 from sympy.testing.pytest import raises, warns_deprecated_sympy
+from sympy.functions.elementary.complexes import Abs, sign
+from sympy.functions.elementary.piecewise import Piecewise
+from sympy.core.relational import Eq
 
 b1 = Basic()
 b2 = Basic(b1)
@@ -331,3 +334,10 @@ class A(Symbol, Generic[T]):
 
     class B(A[T]):
         pass
+
+
+def test_rewrite_abs():
+    # https://github.com/sympy/sympy/issues/27323
+    x = Symbol('x')
+    assert sign(x).rewrite(abs) == sign(x).rewrite(Abs)
+    assert sign(x).rewrite(abs) == Piecewise((0, Eq(x, 0)), (x / Abs(x), True))