On 06-07-2026 14:00, Adriano dos Santos Fernandes wrote:
> Isn't the problem of CTAs with (WITH ...) just a more general problem?
No (see below)
> We do not accept that:
>
> SQL> (with q as (select 1 n from rdb$database) select * from q);
> Statement failed, SQLSTATE = 42000
> Dynamic SQL Error
> -SQL error code = -104
> -Token unknown - line 1, column 2
> -with
>
> While PostgreSQL accepts:
>
> postgres=# (with q as (select 1 n) select * from q);
> n
> ---
> 1
> (1 row)
Our syntax matches the SQL standard requirements in that regard, as it
explicitly disallows using WITH in a parenthesized top-level statement,
but that's different in the case of the CREATE TABLE ... AS syntax as
that is a query expression in a subquery.
A top-level select is a cursor specification:
```
<cursor specification> ::=
<query expression> [ <updatability clause> ]
<query expression> ::=
[ <with clause> ] <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first
clause> ]
<query expression body> ::=
<query term>
| <query expression body> UNION [ ALL | DISTINCT ]
[ <corresponding spec> ] <query term>
| <query expression body> EXCEPT [ ALL | DISTINCT ]
[ <corresponding spec> ] <query term>
<query term> ::=
<query primary>
| <query term> INTERSECT [ ALL | DISTINCT ]
[ <corresponding spec> ] <query primary>
<query primary> ::=
<simple table>
| <left paren> <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first
clause> ]
<right paren>
<simple table> ::=
<query specification>
| <table value constructor>
| <explicit table>
```
In other words, top-level WITH can't occur parenthesized: it would have
to be outside the parentheses.
For CREATE TABLE AS, the syntax derivation is:
```
<table definition> ::=
CREATE [ <table scope> ] TABLE <table name> <table contents source>
[ WITH <system versioning clause> ]
[ ON COMMIT <table commit action> ROWS ]
<table contents source> ::=
<table element list>
| <typed table clause>
| <as subquery clause>
<as subquery clause> ::=
[ <left paren> <column name list> <right paren> ] AS <table subquery>
<with or without data>
<table subquery> ::=
<subquery>
<subquery> ::=
<left paren> <query expression> <right paren>
```
In other words, the derivation is through a subquery, in which case a
WITH clause *must* be parenthesized, as by definition the query
expression is in parentheses.
Mark
--
Mark Rotteveel