internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: tobymao/sqlglot

Issue:
Athena Iceberg Tables parsing issue
Hi,
I want to parse a SQL Statement that creates an Iceberg table on Athena:

```sql
create table if not exists tmp.mytable (
    name string
)
location 's3://bucket/tmp/mytable/'
tblproperties (
  'table_type'='iceberg',
  'format'='parquet'
);
```
running 
```python
stmts = sqlglot.parse(sql, read=sqlglot.Dialects.ATHENA)
stmts[0].sql()
```
returns:
```sql
CREATE TABLE IF NOT EXISTS tmp.mytable 
    (name TEXT) 
LOCATION 's3://bucket/tmp/mytable/' 
WITH (
    table_type='iceberg', 
    FORMAT='parquet'
)
```

Unfortunately, the syntax in Athena is different for Iceberg Tables and Hive-style tables.

The parsed statement should look like this:

```sql
CREATE TABLE IF NOT EXISTS tmp.mytable 
    (name STRING) 
LOCATION 's3://bucket/tmp/mytable/' 
TBLPROPERTIES (
    'table_type'='iceberg', 
    'FORMAT'='parquet'
)
```

Instead of WITH -> TBLPROPERTIES
The keys in the this block are wrapped in upper quotes and iceberg has slightly different data types. In this case STRING instead of TEXT

https://docs.aws.amazon.com/athena/latest/ug/querying-iceberg-supported-data-types.html
https://docs.aws.amazon.com/athena/latest/ug/querying-iceberg-creating-tables.html




Discussion:

Resolving patch:
diff --git a/sqlglot/dialects/athena.py b/sqlglot/dialects/athena.py
--- a/sqlglot/dialects/athena.py
+++ b/sqlglot/dialects/athena.py
@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+from sqlglot import exp
 from sqlglot.dialects.trino import Trino
 from sqlglot.tokens import TokenType
 
@@ -10,3 +11,27 @@ class Parser(Trino.Parser):
             **Trino.Parser.STATEMENT_PARSERS,
             TokenType.USING: lambda self: self._parse_as_command(self._prev),
         }
+
+    class Generator(Trino.Generator):
+        PROPERTIES_LOCATION = {
+            **Trino.Generator.PROPERTIES_LOCATION,
+            exp.LocationProperty: exp.Properties.Location.POST_SCHEMA,
+        }
+
+        TYPE_MAPPING = {
+            **Trino.Generator.TYPE_MAPPING,
+            exp.DataType.Type.TEXT: "STRING",
+        }
+
+        TRANSFORMS = {
+            **Trino.Generator.TRANSFORMS,
+            exp.FileFormatProperty: lambda self, e: f"'FORMAT'={self.sql(e, 'this')}",
+        }
+
+        def property_sql(self, expression: exp.Property) -> str:
+            return (
+                f"{self.property_name(expression, string_key=True)}={self.sql(expression, 'value')}"
+            )
+
+        def with_properties(self, properties: exp.Properties) -> str:
+            return self.properties(properties, prefix=self.seg("TBLPROPERTIES"))


Test patch:
diff --git a/tests/dialects/test_athena.py b/tests/dialects/test_athena.py
--- a/tests/dialects/test_athena.py
+++ b/tests/dialects/test_athena.py
@@ -14,3 +14,7 @@ def test_athena(self):
             some_function(1)""",
             check_command_warning=True,
         )
+
+        self.validate_identity(
+            "CREATE TABLE IF NOT EXISTS t (name STRING) LOCATION 's3://bucket/tmp/mytable/' TBLPROPERTIES ('table_type'='iceberg', 'FORMAT'='parquet')"
+        )
Repository: tobymao/sqlglot

Issue:
running simplify multiple times fails
**Fully reproducible code snippet**
Please include a fully reproducible code snippet or the input sql, dialect, and expected output.

```
>>> from sqlglot.optimizer.scope import exp
>>> from sqlglot.optimizer.simplify import simplify                                                                                 
>>> from sqlglot import parse_one
>>> ast=parse_one("SELECT a,c,b from table1 where 1 = 1;")
>>> w = ast.find(exp.Where)
>>> w2 = simplify(w)
>>> w2 = simplify(w)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lib/python3.9/site-packages/sqlglot/optimizer/simplify.py", line 109, in simplify
    expression = while_changing(expression, _simplify)
  File "lib/python3.9/site-packages/sqlglot/helper.py", line 211, in while_changing
    expression = func(expression)
  File "lib/python3.9/site-packages/sqlglot/optimizer/simplify.py", line 106, in _simplify
    expression.replace(node)
  File "lib/python3.9/site-packages/sqlglot/expressions.py", line 624, in replace
    value = parent.args[key]
KeyError: 'where'
>>> 
```

in my code i run simplify multiple times as I reduce some elements of a query. in this case, elements in the where clause.

as you see in the sample code, first time works fine but then the where clause was removed and the code fails. 
This used to work before, so I guess some check that they key exists has been removed.



Discussion:

Resolving patch:
diff --git a/sqlglot/expressions.py b/sqlglot/expressions.py
--- a/sqlglot/expressions.py
+++ b/sqlglot/expressions.py
@@ -621,7 +621,7 @@ def replace(self, expression):
             return expression
 
         key = self.arg_key
-        value = parent.args[key]
+        value = parent.args.get(key)
 
         if isinstance(value, list):
             index = self.index
@@ -639,7 +639,7 @@ def replace(self, expression):
                 else:
                     value[index] = expression
                     parent._set_parent(key, expression, index=index)
-        else:
+        elif value is not None:
             if expression is None:
                 parent.args.pop(key)
             else:


Test patch:
diff --git a/tests/test_optimizer.py b/tests/test_optimizer.py
--- a/tests/test_optimizer.py
+++ b/tests/test_optimizer.py
@@ -342,6 +342,9 @@ def test_pushdown_projection(self):
     def test_simplify(self):
         self.check_file("simplify", simplify, set_dialect=True)
 
+        expression = parse_one("SELECT a, c, b FROM table1 WHERE 1 = 1")
+        self.assertEqual(simplify(simplify(expression.find(exp.Where))).sql(), "WHERE TRUE")
+
         expression = parse_one("TRUE AND TRUE AND TRUE")
         self.assertEqual(exp.true(), optimizer.simplify.simplify(expression))
         self.assertEqual(exp.true(), optimizer.simplify.simplify(expression.this))
Repository: tobymao/sqlglot

Issue:
Clickhouse SELECT ... FORMAT raises ParseError
**Fully reproducible code snippet**

```
import unittest

from sqlglot import parse_one
from sqlglot.dialects import ClickHouse


class TestClickhouseParseOneSelectFormat(unittest.TestCase):
    def test_parse_one_format_tab_separated(self):
        query = 'SELECT 1 FORMAT TabSeparated'
        ast = parse_one(sql=query, dialect=ClickHouse)
        self.assertIsNotNone(ast)

    def test_parse_one_format_native(self):
        query = 'SELECT 1 FORMAT Native'
        ast = parse_one(sql=query, dialect=ClickHouse)
        self.assertIsNotNone(ast)


if __name__ == '__main__':
    unittest.main()

```
**Native ParseError**

```
           sqlglot.errors.ParseError: Invalid expression / Unexpected token. Line 1, Col: 22.
             SELECT 1 FORMAT Native
```

**TabSeparated ParseError**

```
           sqlglot.errors.ParseError: Invalid expression / Unexpected token. Line 1, Col: 28.
             SELECT 1 FORMAT TabSeparated
```



**Official Documentation**
FORMAT clause official documentation: https://clickhouse.com/docs/en/sql-reference/statements/select/format 

Thanks in advance


Discussion:

Resolving patch:
diff --git a/sqlglot/dialects/clickhouse.py b/sqlglot/dialects/clickhouse.py
--- a/sqlglot/dialects/clickhouse.py
+++ b/sqlglot/dialects/clickhouse.py
@@ -306,6 +306,10 @@ class Parser(parser.Parser):
             TokenType.SETTINGS,
         }
 
+        ALIAS_TOKENS = parser.Parser.ALIAS_TOKENS - {
+            TokenType.FORMAT,
+        }
+
         LOG_DEFAULTS_TO_LN = True
 
         QUERY_MODIFIER_PARSERS = {
diff --git a/sqlglot/parser.py b/sqlglot/parser.py
--- a/sqlglot/parser.py
+++ b/sqlglot/parser.py
@@ -405,6 +405,8 @@ class Parser(metaclass=_Parser):
         TokenType.WINDOW,
     }
 
+    ALIAS_TOKENS = ID_VAR_TOKENS
+
     COMMENT_TABLE_ALIAS_TOKENS = TABLE_ALIAS_TOKENS - {TokenType.IS}
 
     UPDATE_ALIAS_TOKENS = TABLE_ALIAS_TOKENS - {TokenType.SET}
@@ -5385,7 +5387,7 @@ def _parse_alias(
             self._match_r_paren(aliases)
             return aliases
 
-        alias = self._parse_id_var(any_token) or (
+        alias = self._parse_id_var(any_token, tokens=self.ALIAS_TOKENS) or (
             self.STRING_ALIASES and self._parse_string_as_identifier()
         )
 


Test patch:
diff --git a/tests/dialects/test_clickhouse.py b/tests/dialects/test_clickhouse.py
--- a/tests/dialects/test_clickhouse.py
+++ b/tests/dialects/test_clickhouse.py
@@ -401,6 +401,11 @@ def test_clickhouse(self):
             """INSERT INTO FUNCTION hdfs('hdfs://hdfs1:9000/test', 'TSV', 'name String, column2 UInt32, column3 UInt32') VALUES ('test', 1, 2)""",
         )
 
+        self.validate_identity("SELECT 1 FORMAT TabSeparated")
+        self.validate_identity("SELECT * FROM t FORMAT TabSeparated")
+        self.validate_identity("SELECT FORMAT")
+        self.validate_identity("1 AS FORMAT").assert_is(exp.Alias)
+
     def test_cte(self):
         self.validate_identity("WITH 'x' AS foo SELECT foo")
         self.validate_identity("WITH ['c'] AS field_names SELECT field_names")
Repository: tobymao/sqlglot

Issue:
ex.convert(b"\x00\x00\x00\x00\x00\x00\x07\xd3") throws, but should be HexString
The behavior of binary literal's is a bit weird currently:

```python
import sqlglot.expressions as ex
import sqlglot as sg

print(
    repr(sg.parse_one("select 0x00000000000007d3", dialect="tsql"))
)  # binary literal in SQL Server
print(
    sg.parse_one("select 0x00000000000007d3", dialect="tsql").sql("duckdb")
)  # SELECT 2003 --> it's an int in duckdb, a bit unfortunate

import duckdb

duckdb.execute(
    "select '0x00000000000007d3'::blob"
).fetchall()  # correctly gives [(b'0x00000000000007d3',)]

ex.convert(
    b"\x00\x00\x00\x00\x00\x00\x07\xd3"
)  # should be ex.HexString(this="0x00000000000007d3"), I guess
# currently throws

```

Maybe a dedicated BinaryLiteral Type would be good? Not sure how to solve this :)



Discussion:
How would you go from `b"\x00\x00\x00\x00\x00\x00\x07\xd3"` to `"0x00000000000007d3"`?
I guess using something like `"0x" + b"\x00\x00\x00\x00\x00\x00\x07\xd3".hex()`?

Resolving patch:
diff --git a/sqlglot/expressions.py b/sqlglot/expressions.py
--- a/sqlglot/expressions.py
+++ b/sqlglot/expressions.py
@@ -6958,6 +6958,8 @@ def convert(value: t.Any, copy: bool = False) -> Expression:
         return null()
     if isinstance(value, numbers.Number):
         return Literal.number(value)
+    if isinstance(value, bytes):
+        return HexString(this=value.hex())
     if isinstance(value, datetime.datetime):
         datetime_literal = Literal.string(
             (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()


Test patch:
diff --git a/tests/test_expressions.py b/tests/test_expressions.py
--- a/tests/test_expressions.py
+++ b/tests/test_expressions.py
@@ -802,6 +802,7 @@ def test_convert(self):
             ),
             (datetime.date(2022, 10, 1), "DATE_STR_TO_DATE('2022-10-01')"),
             (math.nan, "NULL"),
+            (b"\x00\x00\x00\x00\x00\x00\x07\xd3", "2003"),
         ]:
             with self.subTest(value):
                 self.assertEqual(exp.convert(value).sql(), expected)
Repository: tobymao/sqlglot

Issue:
Incorrect optimized SQL.
```
import sqlglot
from sqlglot.optimizer import optimize
optimize(sqlglot.parse_one("select a from (select 1 a, 2 c union all by name select 3 c, 4 a)", dialect="duckdb")).sql(dialect="duckdb")
```
```
WITH "_q_0" AS (SELECT 1 AS "a" UNION ALL BY NAME SELECT 3 AS "c") SELECT "_q_0"."a" AS "a" FROM "_q_0" AS "_q_0"
```
The result of optimized SQL query is different from original SQL query.
```
select a from (select 1 a, 2 c union all by name select 3 c, 4 a);
┌───────┐
│   a   │
│ int32 │
├───────┤
│     1 │
│     4 │
└───────┘
-- optimized
WITH "_q_0" AS (SELECT 1 AS "a" UNION ALL BY NAME SELECT 3 AS "c") SELECT "_q_0"."a" AS "a" FROM "_q_0" AS "_q_0";
┌───────┐
│   a   │
│ int32 │
├───────┤
│     1 │
│       │
└───────┘
```


Discussion:

Resolving patch:
diff --git a/sqlglot/optimizer/pushdown_projections.py b/sqlglot/optimizer/pushdown_projections.py
--- a/sqlglot/optimizer/pushdown_projections.py
+++ b/sqlglot/optimizer/pushdown_projections.py
@@ -54,11 +54,15 @@ def pushdown_projections(expression, schema=None, remove_unused_selections=True)
             if any(select.is_star for select in right.expression.selects):
                 referenced_columns[right] = parent_selections
             elif not any(select.is_star for select in left.expression.selects):
-                referenced_columns[right] = [
-                    right.expression.selects[i].alias_or_name
-                    for i, select in enumerate(left.expression.selects)
-                    if SELECT_ALL in parent_selections or select.alias_or_name in parent_selections
-                ]
+                if scope.expression.args.get("by_name"):
+                    referenced_columns[right] = referenced_columns[left]
+                else:
+                    referenced_columns[right] = [
+                        right.expression.selects[i].alias_or_name
+                        for i, select in enumerate(left.expression.selects)
+                        if SELECT_ALL in parent_selections
+                        or select.alias_or_name in parent_selections
+                    ]
 
         if isinstance(scope.expression, exp.Select):
             if remove_unused_selections:


Test patch:
diff --git a/tests/fixtures/optimizer/pushdown_projections.sql b/tests/fixtures/optimizer/pushdown_projections.sql
--- a/tests/fixtures/optimizer/pushdown_projections.sql
+++ b/tests/fixtures/optimizer/pushdown_projections.sql
@@ -106,3 +106,6 @@ WITH cte1 AS (SELECT tb.cola AS cola FROM tb AS tb UNION ALL SELECT tb2.colc AS
 
 SELECT * FROM ((SELECT c FROM t1) JOIN t2);
 SELECT * FROM ((SELECT t1.c AS c FROM t1 AS t1) AS _q_0, t2 AS t2);
+
+SELECT a, d FROM (SELECT 1 a, 2 c, 3 d, 4 e UNION ALL BY NAME SELECT 5 b, 6 c, 7 d, 8 a, 9 e)
+SELECT a, d FROM (SELECT 1 a, 3 d, UNION ALL BY NAME SELECT 7 d, 8 a)
Repository: tobymao/sqlglot

Issue:
bigquery options timestamp
```sql
CREATE VIEW `dataset.events`
OPTIONS(
  expiration_timestamp=TIMESTAMP "2020-01-02T04:05:06.007Z",
  description=""
)
AS
SELECT
    *
FROM
    dataset.events_raw;
```

Parsing fails on the `TIMESTAMP` cast within OPTIONS. 

This is pretty similar to their example in the docs - https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list. Other types (e.g interval) are also valid within OPTIONS.



Discussion:

Resolving patch:
diff --git a/sqlglot/parser.py b/sqlglot/parser.py
--- a/sqlglot/parser.py
+++ b/sqlglot/parser.py
@@ -1728,7 +1728,7 @@ def _parse_property(self) -> t.Optional[exp.Expression]:
         return self.expression(
             exp.Property,
             this=key.to_dot() if isinstance(key, exp.Column) else key,
-            value=self._parse_column() or self._parse_var(any_token=True),
+            value=self._parse_bitwise() or self._parse_var(any_token=True),
         )
 
     def _parse_stored(self) -> exp.FileFormatProperty:


Test patch:
diff --git a/tests/dialects/test_bigquery.py b/tests/dialects/test_bigquery.py
--- a/tests/dialects/test_bigquery.py
+++ b/tests/dialects/test_bigquery.py
@@ -184,6 +184,10 @@ def test_bigquery(self):
         self.validate_identity(
             "CREATE OR REPLACE VIEW test (tenant_id OPTIONS (description='Test description on table creation')) AS SELECT 1 AS tenant_id, 1 AS customer_id",
         )
+        self.validate_identity(
+            "CREATE VIEW `d.v` OPTIONS (expiration_timestamp=TIMESTAMP '2020-01-02T04:05:06.007Z') AS SELECT 1 AS c",
+            "CREATE VIEW `d.v` OPTIONS (expiration_timestamp=CAST('2020-01-02T04:05:06.007Z' AS TIMESTAMP)) AS SELECT 1 AS c",
+        )
         self.validate_identity(
             "SELECT ARRAY(SELECT AS STRUCT 1 a, 2 b)",
             "SELECT ARRAY(SELECT AS STRUCT 1 AS a, 2 AS b)",
Repository: tobymao/sqlglot

Issue:
duckdb: non-literal date is no longer cast as date when converted from snowflake 
The following conversion fails when executed by duckdb, because `DATE` is not a valid duckdb expression:
```
❯ python -c 'import sqlglot; print(repr(sqlglot.parse_one("SELECT date(a.start_date) from SOURCE_TABLE AS a", read="snowflake").sql(dialect="duckdb")));'
'SELECT DATE(a.start_date) FROM SOURCE_TABLE AS a'
```

sqlglot 21.2 didn't have this problem, and would cast a non-literal as date, eg: 
```
❯ python -c 'import sqlglot; print(repr(sqlglot.parse_one("SELECT date(a.start_date) from SOURCE_TABLE AS a", read="snowflake").sql(dialect="duckdb")));'
'SELECT CAST(a.start_date AS DATE) FROM SOURCE_TABLE AS a'
```


Discussion:

Resolving patch:
diff --git a/sqlglot/dialects/snowflake.py b/sqlglot/dialects/snowflake.py
--- a/sqlglot/dialects/snowflake.py
+++ b/sqlglot/dialects/snowflake.py
@@ -33,10 +33,9 @@ def _build_datetime(
 ) -> t.Callable[[t.List], exp.Func]:
     def _builder(args: t.List) -> exp.Func:
         value = seq_get(args, 0)
+        int_value = value is not None and is_int(value.name)
 
         if isinstance(value, exp.Literal):
-            int_value = is_int(value.this)
-
             # Converts calls like `TO_TIME('01:02:03')` into casts
             if len(args) == 1 and value.is_string and not int_value:
                 return exp.cast(value, kind)
@@ -49,7 +48,7 @@ def _builder(args: t.List) -> exp.Func:
                 if not is_float(value.this):
                     return build_formatted_time(exp.StrToTime, "snowflake")(args)
 
-        if len(args) == 2 and kind == exp.DataType.Type.DATE:
+        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


Test patch:
diff --git a/tests/dialects/test_snowflake.py b/tests/dialects/test_snowflake.py
--- a/tests/dialects/test_snowflake.py
+++ b/tests/dialects/test_snowflake.py
@@ -1038,10 +1038,16 @@ 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_identity("TO_DATE(x)").assert_is(exp.TsOrDsToDate)
+        self.validate_identity("TRY_TO_DATE(x)").assert_is(exp.TsOrDsToDate)
 
+        self.validate_all(
+            "DATE(x)",
+            write={
+                "duckdb": "CAST(x AS DATE)",
+                "snowflake": "TO_DATE(x)",
+            },
+        )
         self.validate_all(
             "TO_DATE(x, 'MM-DD-YYYY')",
             write={
Repository: tobymao/sqlglot

Issue:
"optimize" is not exported from module "sqlglot.optimizer"
```
"optimize" is not exported from module "sqlglot.optimizer"
  Import from "sqlglot.optimizer.optimizer" instead
```

for:
```python
from sqlglot.optimizer import optimize
```


![CleanShot 2024-04-26 at 15 01 41@2x](https://github.com/tobymao/sqlglot/assets/125105/e32ea679-f980-4acd-ba81-35b5e37112f1)

I think it needs to be added to `__init__.py`


Discussion:
i see no issue, 

`from sqlglot.optimizer import optimize` 

runs perfectly fine, and there are no errors with mypy, this is probably an error with pylance?
mypy in strict mode will error too:
```
❯ .venv/bin/mypy --strict fakesnow/test.py
fakesnow/test.py:1: error: Module "sqlglot.optimizer" does not explicitly export attribute "optimize"  [attr-defined]
```

#1203 is a similar issue addressed in the same way.

As background context, pyright (and therefore pylance) considers these symbols private based on [these rules](https://github.com/microsoft/pyright/blob/main/docs/typed-libraries.md#library-interface) derived from:

- [PEP 008](https://www.python.org/dev/peps/pep-0008/#id50) states modules should explicitly declare the names in their public API using the `__all__` attribute .
- [PEP 484](https://www.python.org/dev/peps/pep-0484/#stub-files) also mentions that imported modules are not considered exported unless they use the `import ... as ...` syntax or equivalent.

Resolving patch:
diff --git a/sqlglot/optimizer/__init__.py b/sqlglot/optimizer/__init__.py
--- a/sqlglot/optimizer/__init__.py
+++ b/sqlglot/optimizer/__init__.py
@@ -1,11 +1,11 @@
 # ruff: noqa: F401
 
-from sqlglot.optimizer.optimizer import RULES, optimize
+from sqlglot.optimizer.optimizer import RULES as RULES, optimize as optimize
 from sqlglot.optimizer.scope import (
-    Scope,
-    build_scope,
-    find_all_in_scope,
-    find_in_scope,
-    traverse_scope,
-    walk_in_scope,
+    Scope as Scope,
+    build_scope as build_scope,
+    find_all_in_scope as find_all_in_scope,
+    find_in_scope as find_in_scope,
+    traverse_scope as traverse_scope,
+    walk_in_scope as walk_in_scope,
 )


Test patch:
Repository: tobymao/sqlglot

Issue:
Syntactically incorrect result produced when using DuckDB `date_sub` as an input 
Hei,

when trying to format already existing duckdb sql-ddl code that contains a `date_sub` function, sqlglot will create a sql-ddl string that contains the `interval` keyword which produces a syntax error when executing it in duckdb. To the best of my knowledge, this keyword is not available in duckdb.

Documentation duckdb time functions: https://duckdb.org/docs/sql/functions/time

### Code that causes an error

```python3
import duckdb
import sqlglot

sql_in= """
CREATE TABLE "testtable" (
  "Number"	NUMERIC(5,2) NOT NULL,
  "Name" STRUCT(title VARCHAR, firstname VARCHAR, lastname VARCHAR) NOT NULL,
  "date_to_check"	DATE NOT NULL CHECK(date_sub('year', "date_to_check", '2020-01-01') < 20),
  PRIMARY KEY("Number")
);
"""
output = sqlglot.transpile(sql_in, read="duckdb", write="duckdb", pretty=True, normalize_functions="upper")

duckdb.sql(output[0])
```

### content of the sqlglot output

```sql
"CREATE TABLE "testtable" (
  "Number" DECIMAL(5, 2) NOT NULL,
  "Name" STRUCT(title TEXT, firstname TEXT, lastname TEXT) NOT NULL,
  "date_to_check" DATE NOT NULL CHECK ('year' - INTERVAL ("date_to_check") 2020-01-01 < 20),
  PRIMARY KEY ("Number")
)"
```

### Error Message

```error
Traceback (most recent call last):
  File "/opt/pycharm-2023.3/plugins/python/helpers/pydev/pydevconsole.py", line 364, in runcode
    coro = func()
           ^^^^^^
  File "<input>", line 1, in <module>
duckdb.duckdb.ParserException: Parser Error: syntax error at or near "2020"
```





Discussion:

Resolving patch:
diff --git a/sqlglot/dialects/duckdb.py b/sqlglot/dialects/duckdb.py
--- a/sqlglot/dialects/duckdb.py
+++ b/sqlglot/dialects/duckdb.py
@@ -280,6 +280,8 @@ class Parser(parser.Parser):
             "RANGE": _build_generate_series(end_exclusive=True),
         }
 
+        FUNCTIONS.pop("DATE_SUB")
+
         FUNCTION_PARSERS = parser.Parser.FUNCTION_PARSERS.copy()
         FUNCTION_PARSERS.pop("DECODE")
 


Test patch:
diff --git a/tests/dialects/test_duckdb.py b/tests/dialects/test_duckdb.py
--- a/tests/dialects/test_duckdb.py
+++ b/tests/dialects/test_duckdb.py
@@ -324,6 +324,8 @@ def test_duckdb(self):
         self.validate_identity(
             "SELECT * FROM (PIVOT Cities ON Year USING SUM(Population) GROUP BY Country) AS pivot_alias"
         )
+        self.validate_identity("DATE_SUB('YEAR', col, '2020-01-01')").assert_is(exp.Anonymous)
+        self.validate_identity("DATESUB('YEAR', col, '2020-01-01')").assert_is(exp.Anonymous)
 
         self.validate_all("0b1010", write={"": "0 AS b1010"})
         self.validate_all("0x1010", write={"": "0 AS x1010"})