Enhance columnar_relation_storageid to handle temp tables in PG18+

m3hm3t/pg18_columnar_access_temp_after_review
Mehmet Yilmaz 2025-10-24 11:42:10 +00:00
parent b947c8ce6b
commit 65615dafa8
7 changed files with 32 additions and 56 deletions

View File

@ -2024,6 +2024,26 @@ Datum
columnar_relation_storageid(PG_FUNCTION_ARGS)
{
Oid relationId = PG_GETARG_OID(0);
#if PG_VERSION_NUM >= PG_VERSION_18
/*
* PG18+: avoid relation_open() on other sessions' temp tables.
* Return NULL so callers/views just skip them (function is STRICT).
*/
HeapTuple classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(relationId));
if (!HeapTupleIsValid(classtup))
PG_RETURN_NULL();
Form_pg_class cls = (Form_pg_class) GETSTRUCT(classtup);
if (cls->relpersistence == RELPERSISTENCE_TEMP &&
isOtherTempNamespace(cls->relnamespace))
{
ReleaseSysCache(classtup);
PG_RETURN_NULL();
}
ReleaseSysCache(classtup);
#endif
Relation relation = relation_open(relationId, AccessShareLock);
if (!object_ownercheck(RelationRelationId, relationId, GetUserId()))

View File

@ -214,8 +214,8 @@ SELECT COUNT(*) FROM columnar_temp WHERE i < 5;
4
(1 row)
SELECT COALESCE(columnar_test_helpers.get_storage_id_if_visible('columnar_temp'::regclass), 0)
AS columnar_temp_storage_id \gset
SELECT columnar.get_storage_id(oid) AS columnar_temp_storage_id
FROM pg_class WHERE relname='columnar_temp' \gset
BEGIN;
DROP TABLE columnar_temp;
-- show that we drop stripes properly

View File

@ -11,19 +11,10 @@ $$ LANGUAGE SQL;
INSERT INTO t2 SELECT i, f(i) FROM generate_series(1, 5) i;
-- there are no subtransactions, so above statement should batch
-- INSERTs inside the UDF and create on stripe per table.
WITH rels(rel) AS (
VALUES ('t1'::regclass), ('t2'::regclass)
),
sids AS (
SELECT rel, columnar.get_storage_id(rel) AS sid
FROM rels
)
SELECT c.relname, COUNT(*) AS count
FROM columnar_internal.stripe st
JOIN sids s ON st.storage_id = s.sid
JOIN pg_catalog.pg_class c ON c.oid = s.rel
GROUP BY c.relname
ORDER BY c.relname;
SELECT relname, count(*) FROM columnar.stripe a, pg_class b
WHERE columnar.get_storage_id(b.oid)=a.storage_id AND relname IN ('t1', 't2')
GROUP BY relname
ORDER BY relname;
relname | count
---------------------------------------------------------------------
t1 | 1

View File

@ -146,15 +146,3 @@ BEGIN
RETURN NEXT;
END LOOP;
END; $$ language plpgsql;
CREATE OR REPLACE FUNCTION get_storage_id_if_visible(rel regclass)
RETURNS bigint
LANGUAGE sql STABLE AS $$
SELECT CASE
WHEN c.relpersistence = 't'
AND c.relnamespace <> pg_catalog.pg_my_temp_schema()
THEN NULL -- other sessions temp → dont touch
ELSE columnar.get_storage_id(c.oid)
END
FROM pg_catalog.pg_class c
WHERE c.oid = $1::oid
$$;

View File

@ -174,8 +174,8 @@ INSERT INTO columnar_temp SELECT i FROM generate_series(1,5) i;
-- test basic select
SELECT COUNT(*) FROM columnar_temp WHERE i < 5;
SELECT COALESCE(columnar_test_helpers.get_storage_id_if_visible('columnar_temp'::regclass), 0)
AS columnar_temp_storage_id \gset
SELECT columnar.get_storage_id(oid) AS columnar_temp_storage_id
FROM pg_class WHERE relname='columnar_temp' \gset
BEGIN;
DROP TABLE columnar_temp;

View File

@ -15,20 +15,10 @@ INSERT INTO t2 SELECT i, f(i) FROM generate_series(1, 5) i;
-- there are no subtransactions, so above statement should batch
-- INSERTs inside the UDF and create on stripe per table.
WITH rels(rel) AS (
VALUES ('t1'::regclass), ('t2'::regclass)
),
sids AS (
SELECT rel, columnar.get_storage_id(rel) AS sid
FROM rels
)
SELECT c.relname, COUNT(*) AS count
FROM columnar_internal.stripe st
JOIN sids s ON st.storage_id = s.sid
JOIN pg_catalog.pg_class c ON c.oid = s.rel
GROUP BY c.relname
ORDER BY c.relname;
SELECT relname, count(*) FROM columnar.stripe a, pg_class b
WHERE columnar.get_storage_id(b.oid)=a.storage_id AND relname IN ('t1', 't2')
GROUP BY relname
ORDER BY relname;
SELECT * FROM t1 ORDER BY a;
SELECT * FROM t2 ORDER BY a;

View File

@ -158,16 +158,3 @@ BEGIN
RETURN NEXT;
END LOOP;
END; $$ language plpgsql;
CREATE OR REPLACE FUNCTION get_storage_id_if_visible(rel regclass)
RETURNS bigint
LANGUAGE sql STABLE AS $$
SELECT CASE
WHEN c.relpersistence = 't'
AND c.relnamespace <> pg_catalog.pg_my_temp_schema()
THEN NULL -- other sessions temp → dont touch
ELSE columnar.get_storage_id(c.oid)
END
FROM pg_catalog.pg_class c
WHERE c.oid = $1::oid
$$;