Proposal: SELECT * EXCLUDE (...) command

From: Hunaid Sohail <hunaidpgml(at)gmail(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Proposal: SELECT * EXCLUDE (...) command
Date: 2026-01-08 10:17:25
Message-ID: CAMWA6yb9GGiJbe9iU88yjurVQCsFgZvW7xSxa0aFLC0Wtz4Aqg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

I would like feedback on the proposed feature: SELECT * EXCLUDE.

The idea is to allow excluding a small number of columns from * without
having to list all remaining columns explicitly. This is mainly intended for
wide tables, columns with metadata, long text fields, or other columns that
may not be needed, making SELECT * more practical while omitting
unnecessary data.

Similar functionality exists in other databases such as DuckDB, Snowflake,
and BigQuery. I haven't tried BigQuery and Snowflake seems to only support
unqualified column names as mentioned in its documentation [1]. My
implementation
is more like DuckDB, which supports both qualified or unqualified column
names.

Qualified stars are supported, and excluded column names may be qualified or
unqualified. If an excluded name matches multiple columns from the *
expansion,
all matching columns are excluded. If no column matches, an error is raised.
EXCLUDE is only allowed with *. Using it on non-star expressions results in
error.

I have attached an initial draft patch that includes code changes,
documentation
updates, and a fairly good amount of test cases. The tests are meant to
clearly
describe the intended behavior and scope, including qualified and
unqualified
column names, table aliases, joins, multiple tables, and expected error
cases.
The patch also allows EXCLUDE to be used with SELECT INTO,
INSERT INTO ... SELECT ..., and RETURNING clauses, similar to how DuckDB
supports it, but the details of those cases can be discussed later.

A few examples:

SELECT * EXCLUDE (email, created_at) FROM users;
SELECT * EXCLUDE (does_not_exist) FROM users; -- error

SELECT * EXCLUDE (users.created_at)
FROM users
JOIN orders ON orders.user_id = users.id;

SELECT * EXCLUDE (users.created_at, orders.amount)
FROM users
JOIN orders ON orders.user_id = users.id;

SELECT users.* EXCLUDE (email), orders.* EXCLUDE (user_id)
FROM users
JOIN orders ON orders.user_id = users.id;

Looking forward to the feedback. Thanks!

Regards,
Hunaid Sohail

[1] https://docs.snowflake.com/en/sql-reference/sql/select

Attachment Content-Type Size
v1-0001-Implement-SELECT-EXCLUDE-.-command.patch application/x-patch 38.8 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message John Naylor 2026-01-08 10:27:05 Re: Proposal: SELECT * EXCLUDE (...) command
Previous Message Alastair Turner 2026-01-08 10:14:16 Re: Proposal - Enabling btree_gist by default