diff --git a/src/backend/columnar/sql/citus_columnar--13.2-1--14.0-1.sql b/src/backend/columnar/sql/citus_columnar--13.2-1--14.0-1.sql index 016c78f6b..dc8318898 100644 --- a/src/backend/columnar/sql/citus_columnar--13.2-1--14.0-1.sql +++ b/src/backend/columnar/sql/citus_columnar--13.2-1--14.0-1.sql @@ -1,2 +1,44 @@ -- citus_columnar--13.2-1--14.0-1 -- bump version to 14.0-1 + +CREATE OR REPLACE VIEW columnar.storage WITH (security_barrier) AS + SELECT c.oid::regclass AS relation, + columnar.get_storage_id(c.oid) AS storage_id + FROM pg_catalog.pg_class c + JOIN pg_catalog.pg_am am ON c.relam = am.oid + WHERE am.amname = 'columnar' + -- exclude other sessions' temp rels, but keep *my* temp tables + AND (c.relpersistence <> 't' + OR c.relnamespace = pg_catalog.pg_my_temp_schema()) + AND pg_catalog.pg_has_role(c.relowner, 'USAGE'); +COMMENT ON VIEW columnar.storage IS 'Columnar relation ID to storage ID mapping.'; +GRANT SELECT ON columnar.storage TO PUBLIC; + +-- re-emit dependent views with OR REPLACE so they stay bound cleanly +CREATE OR REPLACE VIEW columnar.stripe WITH (security_barrier) AS + SELECT relation, storage.storage_id, stripe_num, file_offset, data_length, + column_count, chunk_row_count, row_count, chunk_group_count, first_row_number + FROM columnar_internal.stripe stripe, columnar.storage storage + WHERE stripe.storage_id = storage.storage_id; +COMMENT ON VIEW columnar.stripe + IS 'Columnar stripe information for tables on which the current user has ownership privileges.'; +GRANT SELECT ON columnar.stripe TO PUBLIC; + +CREATE OR REPLACE VIEW columnar.chunk_group WITH (security_barrier) AS + SELECT relation, storage.storage_id, stripe_num, chunk_group_num, row_count + FROM columnar_internal.chunk_group cg, columnar.storage storage + WHERE cg.storage_id = storage.storage_id; +COMMENT ON VIEW columnar.chunk_group + IS 'Columnar chunk group information for tables on which the current user has ownership privileges.'; +GRANT SELECT ON columnar.chunk_group TO PUBLIC; + +CREATE OR REPLACE VIEW columnar.chunk WITH (security_barrier) AS + SELECT relation, storage.storage_id, stripe_num, attr_num, chunk_group_num, + minimum_value, maximum_value, value_stream_offset, value_stream_length, + exists_stream_offset, exists_stream_length, value_compression_type, + value_compression_level, value_decompressed_length, value_count + FROM columnar_internal.chunk chunk, columnar.storage storage + WHERE chunk.storage_id = storage.storage_id; +COMMENT ON VIEW columnar.chunk + IS 'Columnar chunk information for tables on which the current user has ownership privileges.'; +GRANT SELECT ON columnar.chunk TO PUBLIC; diff --git a/src/test/regress/expected/columnar_create.out b/src/test/regress/expected/columnar_create.out index a134fd063..4b02aa4f6 100644 --- a/src/test/regress/expected/columnar_create.out +++ b/src/test/regress/expected/columnar_create.out @@ -214,8 +214,8 @@ SELECT COUNT(*) FROM columnar_temp WHERE i < 5; 4 (1 row) -SELECT columnar.get_storage_id(oid) AS columnar_temp_storage_id -FROM pg_class WHERE relname='columnar_temp' \gset +SELECT COALESCE(columnar_test_helpers.get_storage_id_if_visible('columnar_temp'::regclass), 0) + AS columnar_temp_storage_id \gset BEGIN; DROP TABLE columnar_temp; -- show that we drop stripes properly diff --git a/src/test/regress/expected/columnar_recursive.out b/src/test/regress/expected/columnar_recursive.out index 7b4b828be..1a54f4f59 100644 --- a/src/test/regress/expected/columnar_recursive.out +++ b/src/test/regress/expected/columnar_recursive.out @@ -11,10 +11,19 @@ $$ 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. -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; +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; relname | count --------------------------------------------------------------------- t1 | 1 diff --git a/src/test/regress/expected/columnar_test_helpers.out b/src/test/regress/expected/columnar_test_helpers.out index f4f179e55..b2b17cc94 100644 --- a/src/test/regress/expected/columnar_test_helpers.out +++ b/src/test/regress/expected/columnar_test_helpers.out @@ -146,3 +146,15 @@ 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 +$$; diff --git a/src/test/regress/sql/columnar_create.sql b/src/test/regress/sql/columnar_create.sql index a0708aeac..93db8a25f 100644 --- a/src/test/regress/sql/columnar_create.sql +++ b/src/test/regress/sql/columnar_create.sql @@ -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 columnar.get_storage_id(oid) AS columnar_temp_storage_id -FROM pg_class WHERE relname='columnar_temp' \gset +SELECT COALESCE(columnar_test_helpers.get_storage_id_if_visible('columnar_temp'::regclass), 0) + AS columnar_temp_storage_id \gset BEGIN; DROP TABLE columnar_temp; diff --git a/src/test/regress/sql/columnar_recursive.sql b/src/test/regress/sql/columnar_recursive.sql index 08d77afdb..c916ce066 100644 --- a/src/test/regress/sql/columnar_recursive.sql +++ b/src/test/regress/sql/columnar_recursive.sql @@ -15,10 +15,20 @@ 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. -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; +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 * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; diff --git a/src/test/regress/sql/columnar_test_helpers.sql b/src/test/regress/sql/columnar_test_helpers.sql index 9cff79bbe..51f5123c7 100644 --- a/src/test/regress/sql/columnar_test_helpers.sql +++ b/src/test/regress/sql/columnar_test_helpers.sql @@ -158,3 +158,16 @@ 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 +$$;