Skip to content

CTE inside subquery not working #3156

Open

Description

@ross96D

Version

1.25.0

What happened?

It seems that the parser cannot identify the relation created from the cte when the cte is inside a subquery

Relevant log output

query.sql:1:1: relation "cte_authors" does not exist

Database schema

CREATE TABLE authors (
  id   BIGSERIAL PRIMARY KEY,
  name text      NOT NULL,
  bio  text
);

SQL queries

-- name: test :many
SELECT * FROM (
  WITH cte_authors AS (
    SELECT * FROM authors
  )
  SELECT * FROM authors JOIN cte_authors ON autors.id = cte_autors.et_id
) AS sub WHERE true;

Configuration

{
  "version": "2",
  "sql": [{
    "schema": "schema.sql",
    "queries": "query.sql",
    "engine": "postgresql",
    "gen": {
      "go": {
        "out": "db"
      }
    }
  }]
}

Playground URL

https://play.sqlc.dev/p/ee35e71a5d2a5322c92655a2cfe5269302155113824459cc9c7f1fb74afd771f

What operating system are you using?

Linux

What database engines are you using?

PostgreSQL

What type of code are you generating?

Go

Activity

  1. added
    bugSomething isn't working
    triageNew issues that hasn't been reviewed
    on Jan 24, 2024
  2. matteobassan commented on Jul 9, 2024

    @matteobassan

    Same problem here.
    Using CTE is quite unusable with this package, given the other issues related (#3128)

  3. removed
    triageNew issues that hasn't been reviewed
    on Aug 5, 2024
  4. Bockit commented on Nov 14, 2026

    @Bockit

    This has a silent form as well, and I think it is the more serious one.

    With database: managed: true, or analyzer.database: true and a URI, the relation "x" does not exist error from sqlc's own analysis is discarded and the database's description of the statement is used in its place. Every column then takes its table's NOT NULL, so a column from the nullable side of an outer join is generated as never null.

    CREATE TABLE authors (id BIGSERIAL PRIMARY KEY, name text NOT NULL);
    CREATE TABLE books (id BIGSERIAL PRIMARY KEY, author_id bigint NOT NULL, title text NOT NULL);
    
    -- name: ListAuthors :many
    SELECT a.name, b.title
    FROM authors a
    LEFT JOIN books b ON b.author_id = a.id
    JOIN (WITH x AS (SELECT id FROM authors) SELECT id FROM x) t ON t.id = a.id;

    On 1.31.1 and on main (3ad8b20), generating Go with sql_package: pgx/v5:

    • With no database: relation "x" does not exist, as reported here.
    • With a database: it generates, and Title is string. Move the WITH to the top of the statement and it is pgtype.Text, which is right.
    • With a * in the statement as well: star expansion failed for query, as in Star expansion failed for query #2915.

    #2644 and #2004 were closed as fixed by the database-backed analyzer, which is the path that gives the wrong type.

    The cause is that the query catalog only registers the statement's own WITH. I have a fix on a fork that gives each nested statement a scope of its own, with end-to-end cases: Bockit@f7cedce. With it the query in #3206 generates too. I can open a pull request if a fix to this path is wanted.

    The analysis was done with AI help and checked by me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions