From: | Zhang Mingli <zmlpostgres(at)gmail(dot)com> |
---|---|
To: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
Subject: | Inconsistency between Compression and Storage for Foreign Tables |
Date: | 2025-02-05 17:42:34 |
Message-ID: | 6cecef0e-ee14-473c-bb0a-6aa61f539a66@Spark |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi,
While developing the CREATE FOREIGN TABLE LIKE functionality in [0], I had to consider the like_options, such as STORAGE, COMPRESSION, and others.
Although foreign tables do not have actual storage in PostgreSQL, we allow the STORAGE option as it may be useful for foreign data wrappers (FDWs) that support this concept.
As stated in the ALTER FOREIGN TBALE documentation[1]:
> This form sets the storage mode for a column. See the similar form of ALTER TABLE for more details. Note that the storage mode has no effect unless the table's foreign-data wrapper chooses to pay attention to it.
However, when aligning COMPRESSION with STORAGE, I find it confusing. IMO, COMPRESSION should behave similarly to STORAGE for foreign tables,
even though they lack real storage. This could be particularly useful for FDWs like postgres_fdw.
I noticed several inconsistencies between COMPRESSION and STORAGE for foreign tables:
1. We actually allow both SET COMPRESSION and STORAGE for foreign table columns, but the CREATE FOREIGN TABLE documentation[2] does not mention this.
gpadmin=# CREATE FOREIGN DATA WRAPPER extstats_dummy_fdw;
CREATE FOREIGN DATA WRAPPER
gpadmin=# CREATE SERVER extstats_dummy_srv FOREIGN DATA WRAPPER extstats_dummy_fdw;
CREATE SERVER
gpadmin=# create foreign table ft1(a int, b text compression lz4) server extstats_dummy_srv;
CREATE FOREIGN TABLE
gpadmin=# \set HIDE_TOAST_COMPRESSION false
gpadmin=# \d+ ft1
Foreign table "public.ft1"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
a | integer | | | | | plain | |
b | text | | | | | extended | |
Server: extstats_dummy_srv
gpadmin=# select attname, attcompression from pg_attribute where attname = 'b' and attrelid = 'ft1'::regclass::oid;
attname | attcompression
---------+----------------
b | l
(1 row)
The COMPRESSION info is not listed even HIDE_TOAST_COMPRESSION is set to false because describe.c will ignore that column if table is a foreign table.
But select from pg_attribute will show that compression info.
And the COMPRESSION info is copied when creating a table like that foreign table including options.
gpadmin=# create table t1(like ft1 including all);
CREATE TABLE
gpadmin=# \d+ t1
Table "public.t1"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
--------+---------+-----------+----------+---------+----------+-------------+--------------+-------------
a | integer | | | | plain | | |
b | text | | | | extended | lz4 | |
Access method: heap
The same goes for STORAGE:
gpadmin=# create foreign table ft2(a int, b text storage external) server extstats_dummy_srv;
CREATE FOREIGN TABLE
gpadmin=# \d+ ft2
Foreign table "public.ft2"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
a | integer | | | | | plain | |
b | text | | | | | external | |
Server: extstats_dummy_srv
gpadmin=# create table t2(like ft2 including all);
CREATE TABLE
gpadmin=# \d+ t2
Table "public.t2"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
--------+---------+-----------+----------+---------+----------+-------------+--------------+-------------
a | integer | | | | plain | | |
b | text | | | | external | | |
Access method: heap
2. We allow ALTER COLUMN SET STORAGE for foreign table columns, but we disallow SET COMPRESSION.
gpadmin=# alter foreign table ft1 alter column b set compression pglz;
ERROR: ALTER action ALTER COLUMN ... SET COMPRESSION cannot be performed on relation "ft1"
DETAIL: This operation is not supported for foreign tables.
gpadmin=# alter foreign table ft1 alter column b set storage external;
ALTER FOREIGN TABLE
gpadmin=# \d+ ft1
Foreign table "public.ft1"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
a | integer | | | | | plain | |
b | text | | | | | external | |
Server: extstats_dummy_srv
If foreign tables can utilize STORAGE operations, why shouldn't they also support COMPRESSION? There should be consistency between the two.
I would like to propose a patch to address these inconsistencies, assuming we can reach an agreement on this matter. The changes would include:
1. Modifying the documentation to reflect that we allow setting COMPRESSION and STORAGE on columns when creating foreign tables.
2. Allowing ALTER COLUMN SET COMPRESSION in ALTER FOREIGN TABLE, similar to how we handle SET STORAGE.
3. Including COMPRESSION information for foreign tables when \d?
Thoughts?
[0] https://www.postgresql.org/message-id/42d3f855-2275-4361-a42a-826172ca2dc4%40Spark
[1] https://www.postgresql.org/docs/current/sql-alterforeigntable.html
[2] https://www.postgresql.org/docs/current/sql-createforeigntable.html
--
Zhang Mingli
HashData
From | Date | Subject | |
---|---|---|---|
Next Message | Álvaro Herrera | 2025-02-05 17:58:54 | Re: Failed assertion with jit enabled |
Previous Message | Daniel Gustafsson | 2025-02-05 17:37:12 | Re: Avoid possible deference NULL pointer (src/backend/optimizer/path/allpaths.c) |