dbt-labs / dbt-labs/dbt

[BUG] [DuckDB] STRPTIME→DATE cast through a CTE with a window function fails with dbt1308 Conversion Error

Open
#15,112 0 comments 0 reactions 0 assignees View on GitHub
adapter:duckdb area:static-analysis engine:v2 status:triage type:bug
Dominant language
Rust
Stars
13.8k
Forks
2.6k
Avg merge
21h 31m
Merged PRs (30d)
56

Description

**Describe the bug**

dbt-fusion fails to build a model on the DuckDB adapter with `dbt1308 Conversion Error: invalid date field format` when a `CAST(STRPTIME(varchar, fmt) AS DATE)` flows through a CTE containing a window function. The same compiled SQL succeeds against raw DuckDB 1.5.3 via the Python driver. dbt Core (`dbt-duckdb` 1.10.0) builds both models without error.

Related to dbt-labs/dbt-core#14526, which exhibited a different error (`INTERNAL Error: Failed to bind column reference ... inequal types (DATE != VARCHAR)`) on the same trigger pattern with driver `dbt0.0.21`. That error no longer reproduces on driver `dbt0.0.23`; this one does.

**What version of dbt Fusion is this bug in?**

`dbt-fusion 2.0.0-preview.178` with `duckdb_extended-0.21.0.dev+dbt0.0.23`. Also reproduces with the auto-installed `0.0.22` driver.

**To Reproduce**

Full reproduction project: https://github.com/dbt-labs/scratch/tree/main/repros/fusion-2226

`models/stg_events.sql`:

```sql
{{ config(materialized='table') }}

SELECT '3/22/2006 16:04:41' AS dt_str, 1 AS id
UNION ALL
SELECT '4/01/2006 10:00:00' AS dt_str, 2 AS id
```

`models/fact_events.sql`:

```sql
{{ config(materialized='table') }}

WITH source AS (
SELECT
id,
CAST(STRPTIME(dt_str, '%m/%d/%Y %H:%M:%S') AS DATE) AS dt
FROM {{ ref('stg_events') }}
),

ranked AS (
SELECT
*,
ROW_NUMBER() OVER (ORDER BY id) AS rn
FROM source
)

SELECT id, dt FROM ranked WHERE rn = 1
```

`profiles.yml`:

```yaml
duckdb:
target: dev
outputs:
dev:
type: duckdb
path: 'db.db'
schema: main
```

Then:

```shell
rm -rf target/ db.db
dbt run
```

**Expected behavior**

Both models build. dbt Core (`dbt-duckdb` 1.10.0, DuckDB 1.5.3) handles this fine:

```
1 of 2 OK created sql table model main.stg_events
2 of 2 OK created sql table model main.fact_events
Done. PASS=2 WARN=0 ERROR=0 SKIP=0 NO-OP=0 TOTAL=2
```

**Actual behavior**

```
dbt-fusion 2.0.0-preview.178
Succeeded [ 0.02s] model main.stg_events (table)
Failed [ 1.02s] model main.fact_events (table)

[error] [DbDriverFailed (dbt1308)]: Database Error in model fact_events (target/run/.../fact_events.sql)
Conversion Error: invalid date field format: "3/22/2006 16:04:41", expected format is (YYYY-MM-DD)
```

**What I tried**

Both the `STRPTIME` cast and the window function are required to reproduce:

- Removing the `ROW_NUMBER()` (so `ranked` is just `SELECT * FROM source`): passes
- Selecting directly from `source` (skipping the `ranked` CTE): passes
- Renaming the casted column so there's no name collision with upstream: still fails

The exact compiled SQL fusion sends to the driver runs cleanly against `duckdb` 1.5.3 (Python):

```python
import duckdb
c = duckdb.connect(":memory:")
c.execute("CREATE TABLE stg_events AS SELECT '3/22/2006 16:04:41' AS dt_str, 1 AS id")
c.execute("""
CREATE TABLE fact_events AS
WITH source AS (
SELECT id, CAST(STRPTIME(dt_str, '%m/%d/%Y %H:%M:%S') AS DATE) AS dt FROM stg_events
),
ranked AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS rn FROM source
)
SELECT id, dt FROM ranked WHERE rn = 1
""")
print(c.execute("SELECT * FROM fact_events").fetchall())
# [(1, datetime.date(2006, 3, 22))]
```

**Operating System and CPU Type**

- macOS / ARM (Apple Silicon)
- Also reproduces on `ubuntu-latest` (x86_64): https://github.com/dbt-labs/ade-bench/actions/runs/26313456631/job/77467368095

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.