Repository: tobymao/sqlglot

Issue:
Postgres interval not formatted correctly
Postgres interval [1] value is not formatted (or parsed?) correctly.

```py
query = """
SELECT GENERATE_SERIES('2023-01-01', '2024-01-01', INTERVAL '1 week') AS week
"""
parsed = sqlglot.parse_one(query, read="postgres")
print(parsed.sql(dialect="postgres"))
```

Output:
```sql
SELECT GENERATE_SERIES('2023-01-01', '2024-01-01', INTERVAL '1' week) AS week
```
Fails with `ERROR:  syntax error at or near "week"`

Expected output:
```sql
SELECT GENERATE_SERIES('2023-01-01', '2024-01-01', INTERVAL '1 week') AS week
```


[1] https://www.postgresql.org/docs/current/functions-datetime.html


Discussion:
Thanks for the report, I'll have a fix soon.

Resolving patch:
diff --git a/sqlglot/dialects/postgres.py b/sqlglot/dialects/postgres.py
--- a/sqlglot/dialects/postgres.py
+++ b/sqlglot/dialects/postgres.py
@@ -304,7 +304,7 @@ def _parse_date_part(self) -> exp.Expression:
             return self.expression(exp.Extract, this=part, expression=value)
 
     class Generator(generator.Generator):
-        INTERVAL_ALLOWS_PLURAL_FORM = False
+        SINGLE_STRING_INTERVAL = True
         LOCKING_READS_SUPPORTED = True
         JOIN_HINTS = False
         TABLE_HINTS = False
diff --git a/sqlglot/dialects/redshift.py b/sqlglot/dialects/redshift.py
--- a/sqlglot/dialects/redshift.py
+++ b/sqlglot/dialects/redshift.py
@@ -74,7 +74,6 @@ class Tokenizer(Postgres.Tokenizer):
 
     class Generator(Postgres.Generator):
         LOCKING_READS_SUPPORTED = False
-        SINGLE_STRING_INTERVAL = True
         RENAME_TABLE_WITH_DB = False
 
         TYPE_MAPPING = {
diff --git a/sqlglot/generator.py b/sqlglot/generator.py
--- a/sqlglot/generator.py
+++ b/sqlglot/generator.py
@@ -1852,7 +1852,7 @@ def interval_sql(self, expression: exp.Interval) -> str:
 
         if self.SINGLE_STRING_INTERVAL:
             this = expression.this.name if expression.this else ""
-            return f"INTERVAL '{this}{unit}'"
+            return f"INTERVAL '{this}{unit}'" if this else f"INTERVAL{unit}"
 
         this = self.sql(expression, "this")
         if this:


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
@@ -322,7 +322,7 @@ def test_bigquery(self):
         self.validate_all(
             "DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)",
             write={
-                "postgres": "CURRENT_DATE - INTERVAL '1' DAY",
+                "postgres": "CURRENT_DATE - INTERVAL '1 DAY'",
                 "bigquery": "DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY)",
             },
         )
@@ -332,7 +332,7 @@ def test_bigquery(self):
                 "bigquery": "DATE_ADD(CURRENT_DATE, INTERVAL 1 DAY)",
                 "duckdb": "CURRENT_DATE + INTERVAL 1 DAY",
                 "mysql": "DATE_ADD(CURRENT_DATE, INTERVAL 1 DAY)",
-                "postgres": "CURRENT_DATE + INTERVAL '1' DAY",
+                "postgres": "CURRENT_DATE + INTERVAL '1 DAY'",
                 "presto": "DATE_ADD('DAY', 1, CURRENT_DATE)",
                 "hive": "DATE_ADD(CURRENT_DATE, 1)",
                 "spark": "DATE_ADD(CURRENT_DATE, 1)",
diff --git a/tests/dialects/test_dialect.py b/tests/dialects/test_dialect.py
--- a/tests/dialects/test_dialect.py
+++ b/tests/dialects/test_dialect.py
@@ -574,7 +574,7 @@ def test_time(self):
                 "duckdb": "x + INTERVAL 1 DAY",
                 "hive": "DATE_ADD(x, 1)",
                 "mysql": "DATE_ADD(x, INTERVAL 1 DAY)",
-                "postgres": "x + INTERVAL '1' DAY",
+                "postgres": "x + INTERVAL '1 DAY'",
                 "presto": "DATE_ADD('DAY', 1, x)",
                 "snowflake": "DATEADD(DAY, 1, x)",
                 "spark": "DATE_ADD(x, 1)",
diff --git a/tests/dialects/test_postgres.py b/tests/dialects/test_postgres.py
--- a/tests/dialects/test_postgres.py
+++ b/tests/dialects/test_postgres.py
@@ -193,7 +193,7 @@ def test_postgres(self):
         self.validate_all(
             "GENERATE_SERIES(a, b, '  2   days  ')",
             write={
-                "postgres": "GENERATE_SERIES(a, b, INTERVAL '2' day)",
+                "postgres": "GENERATE_SERIES(a, b, INTERVAL '2 days')",
                 "presto": "SEQUENCE(a, b, INTERVAL '2' day)",
                 "trino": "SEQUENCE(a, b, INTERVAL '2' day)",
             },
@@ -201,7 +201,7 @@ def test_postgres(self):
         self.validate_all(
             "GENERATE_SERIES('2019-01-01'::TIMESTAMP, NOW(), '1day')",
             write={
-                "postgres": "GENERATE_SERIES(CAST('2019-01-01' AS TIMESTAMP), CURRENT_TIMESTAMP, INTERVAL '1' day)",
+                "postgres": "GENERATE_SERIES(CAST('2019-01-01' AS TIMESTAMP), CURRENT_TIMESTAMP, INTERVAL '1 day')",
                 "presto": "SEQUENCE(TRY_CAST('2019-01-01' AS TIMESTAMP), CAST(CURRENT_TIMESTAMP AS TIMESTAMP), INTERVAL '1' day)",
                 "trino": "SEQUENCE(TRY_CAST('2019-01-01' AS TIMESTAMP), CAST(CURRENT_TIMESTAMP AS TIMESTAMP), INTERVAL '1' day)",
             },
diff --git a/tests/dialects/test_redshift.py b/tests/dialects/test_redshift.py
--- a/tests/dialects/test_redshift.py
+++ b/tests/dialects/test_redshift.py
@@ -42,7 +42,7 @@ def test_redshift(self):
                 "snowflake": "SELECT EXTRACT(month FROM CAST('20220502' AS DATE))",
             },
         )
-        self.validate_all("SELECT INTERVAL '5 day'", read={"": "SELECT INTERVAL '5' days"})
+        self.validate_all("SELECT INTERVAL '5 days'", read={"": "SELECT INTERVAL '5' days"})
         self.validate_all("CONVERT(INTEGER, x)", write={"redshift": "CAST(x AS INTEGER)"})
         self.validate_all(
             "DATEADD('day', ndays, caldate)", write={"redshift": "DATEADD(day, ndays, caldate)"}