mirror of https://github.com/citusdata/citus.git
Enhance columnar_relation_storageid to handle temp tables in PG18+
parent
b947c8ce6b
commit
65615dafa8
|
|
@ -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()))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 session’s temp → don’t touch
|
||||
ELSE columnar.get_storage_id(c.oid)
|
||||
END
|
||||
FROM pg_catalog.pg_class c
|
||||
WHERE c.oid = $1::oid
|
||||
$$;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 session’s temp → don’t touch
|
||||
ELSE columnar.get_storage_id(c.oid)
|
||||
END
|
||||
FROM pg_catalog.pg_class c
|
||||
WHERE c.oid = $1::oid
|
||||
$$;
|
||||
|
|
|
|||
Loading…
Reference in New Issue