From 495ed83a8638092fde9554782510c22520b697db Mon Sep 17 00:00:00 2001 From: Bugen Zhao Date: Wed, 28 Feb 2024 14:15:50 +0800 Subject: [PATCH] refactor(frontend): manually implement reader for `pg_type` to ensure `oid` is the primary key (#15290) Signed-off-by: Bugen Zhao --- e2e_test/batch/catalog/atlasgo.slt.part | 46 +++++++++ .../tests/testdata/input/atlasgo.yaml | 14 +++ .../tests/testdata/output/atlasgo.yaml | 21 ++++ .../tests/testdata/output/dbeaver.yaml | 26 +++-- .../tests/testdata/output/pg_catalog.yaml | 16 +-- .../system_catalog/pg_catalog/pg_type.rs | 97 +++++++++++++------ .../catalog/system_catalog/rw_catalog/mod.rs | 2 +- .../system_catalog/rw_catalog/rw_types.rs | 14 +-- 8 files changed, 173 insertions(+), 63 deletions(-) create mode 100644 src/frontend/planner_test/tests/testdata/input/atlasgo.yaml create mode 100644 src/frontend/planner_test/tests/testdata/output/atlasgo.yaml diff --git a/e2e_test/batch/catalog/atlasgo.slt.part b/e2e_test/batch/catalog/atlasgo.slt.part index 6f9f50f6faefc..a9b1671c2985a 100644 --- a/e2e_test/batch/catalog/atlasgo.slt.part +++ b/e2e_test/batch/catalog/atlasgo.slt.part @@ -78,6 +78,52 @@ ORDER BY n.nspname, e.enumtypid, e.enumsortorder ---- +query T rowsort +SELECT + ( + SELECT + t.typtype + FROM + pg_catalog.pg_type AS t + WHERE + t.oid = t4.typelem + ) AS elemtyp +FROM + pg_catalog.pg_type AS t4; +---- +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b + query TTTTTTTTTTTTTTTTTTTTTT SELECT t1.table_name, diff --git a/src/frontend/planner_test/tests/testdata/input/atlasgo.yaml b/src/frontend/planner_test/tests/testdata/input/atlasgo.yaml new file mode 100644 index 0000000000000..5ed2e25d5e358 --- /dev/null +++ b/src/frontend/planner_test/tests/testdata/input/atlasgo.yaml @@ -0,0 +1,14 @@ +- sql: | + SELECT + ( + SELECT + t.typtype + FROM + pg_catalog.pg_type AS t + WHERE + t.oid = t4.typelem + ) AS elemtyp + FROM + pg_catalog.pg_type AS t4; + expected_outputs: + - batch_plan diff --git a/src/frontend/planner_test/tests/testdata/output/atlasgo.yaml b/src/frontend/planner_test/tests/testdata/output/atlasgo.yaml new file mode 100644 index 0000000000000..b1e33a3890e9e --- /dev/null +++ b/src/frontend/planner_test/tests/testdata/output/atlasgo.yaml @@ -0,0 +1,21 @@ +# This file is automatically generated. See `src/frontend/planner_test/README.md` for more information. +- sql: | + SELECT + ( + SELECT + t.typtype + FROM + pg_catalog.pg_type AS t + WHERE + t.oid = t4.typelem + ) AS elemtyp + FROM + pg_catalog.pg_type AS t4; + batch_plan: |- + BatchExchange { order: [], dist: Single } + └─BatchHashJoin { type: LeftOuter, predicate: pg_type.typelem = pg_type.oid, output: [pg_type.typtype] } + ├─BatchExchange { order: [], dist: HashShard(pg_type.typelem) } + │ └─BatchScan { table: pg_type, columns: [pg_type.typelem], distribution: Single } + └─BatchExchange { order: [], dist: HashShard(pg_type.oid) } + └─BatchProject { exprs: [pg_type.typtype, pg_type.oid] } + └─BatchScan { table: pg_type, columns: [pg_type.oid, pg_type.typtype], distribution: Single } diff --git a/src/frontend/planner_test/tests/testdata/output/dbeaver.yaml b/src/frontend/planner_test/tests/testdata/output/dbeaver.yaml index d0fcf6db1cfd4..da79b22fbba58 100644 --- a/src/frontend/planner_test/tests/testdata/output/dbeaver.yaml +++ b/src/frontend/planner_test/tests/testdata/output/dbeaver.yaml @@ -45,28 +45,28 @@ └─BatchSort { order: [$expr4 ASC] } └─BatchHashAgg { group_key: [null:Varchar, null:Int32, null:Int32, $expr1, rw_columns.name, '':Varchar, $expr4, $expr5, $expr6, $expr7], aggs: [] } └─BatchExchange { order: [], dist: HashShard(null:Varchar, null:Int32, null:Int32, $expr1, rw_columns.name, '':Varchar, $expr4, $expr5, $expr6, $expr7) } - └─BatchProject { exprs: [null:Varchar, null:Int32, null:Int32, $expr1, rw_columns.name, '':Varchar, Case(IsNotNull($expr1), ConcatOp($expr1, Coalesce(null:Int16::Varchar, '':Varchar)), IsNotNull(null:Int32), 'T':Varchar, IsNotNull(rw_types.id), 'y':Varchar, IsNotNull(rw_schemas.id), 'n':Varchar, IsNotNull(null:Int32), 'p':Varchar, IsNotNull(null:Int32), 'l':Varchar, IsNotNull(null:Int32), 'R':Varchar, IsNotNull(pg_constraint.oid), ConcatOp('C':Varchar, pg_constraint.contype), IsNotNull(null:Int32), 'A':Varchar, '':Varchar) as $expr4, Coalesce(rw_tables.name, rw_tables.name, rw_tables.name) as $expr5, Case((IsNotNull(rw_tables.name) AND IsNotNull(rw_columns.name)), ConcatOp(ConcatOp(rw_tables.name, '.':Varchar), rw_columns.name), Coalesce(rw_tables.name, pg_constraint.conname, null:Varchar, null:Varchar, rw_types.name, null:Varchar, null:Varchar, rw_schemas.name)) as $expr6, Coalesce(rw_schemas.name, rw_schemas.name, rw_schemas.name, rw_schemas.name, rw_schemas.name, rw_schemas.name) as $expr7] } - └─BatchHashJoin { type: LeftOuter, predicate: null:Int32 = rw_columns.relation_id AND null:Int16 = $expr3, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, rw_types.id, rw_types.name, rw_schemas.name, pg_constraint.oid, pg_constraint.conname, pg_constraint.contype, rw_tables.name, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.id, rw_schemas.name, null:Int32, rw_columns.name] } + └─BatchProject { exprs: [null:Varchar, null:Int32, null:Int32, $expr1, rw_columns.name, '':Varchar, Case(IsNotNull($expr1), ConcatOp($expr1, Coalesce(null:Int16::Varchar, '':Varchar)), IsNotNull(null:Int32), 'T':Varchar, IsNotNull(pg_type.oid), 'y':Varchar, IsNotNull(rw_schemas.id), 'n':Varchar, IsNotNull(null:Int32), 'p':Varchar, IsNotNull(null:Int32), 'l':Varchar, IsNotNull(null:Int32), 'R':Varchar, IsNotNull(pg_constraint.oid), ConcatOp('C':Varchar, pg_constraint.contype), IsNotNull(null:Int32), 'A':Varchar, '':Varchar) as $expr4, Coalesce(rw_tables.name, rw_tables.name, rw_tables.name) as $expr5, Case((IsNotNull(rw_tables.name) AND IsNotNull(rw_columns.name)), ConcatOp(ConcatOp(rw_tables.name, '.':Varchar), rw_columns.name), Coalesce(rw_tables.name, pg_constraint.conname, null:Varchar, null:Varchar, pg_type.typname, null:Varchar, null:Varchar, rw_schemas.name)) as $expr6, Coalesce(rw_schemas.name, rw_schemas.name, rw_schemas.name, rw_schemas.name, rw_schemas.name, rw_schemas.name) as $expr7] } + └─BatchHashJoin { type: LeftOuter, predicate: null:Int32 = rw_columns.relation_id AND null:Int16 = $expr3, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, pg_type.oid, pg_type.typname, rw_schemas.name, pg_constraint.oid, pg_constraint.conname, pg_constraint.contype, rw_tables.name, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.id, rw_schemas.name, null:Int32, rw_columns.name] } ├─BatchExchange { order: [], dist: HashShard(null:Int32, null:Int16) } │ └─BatchHashJoin { type: LeftOuter, predicate: null:Int32 = null:Int32, output: all } │ ├─BatchHashJoin { type: LeftOuter, predicate: null:Int32 = rw_schemas.id, output: all } │ │ ├─BatchHashJoin { type: LeftOuter, predicate: null:Int32 = null:Int32, output: all } │ │ │ ├─BatchExchange { order: [], dist: HashShard(null:Int32) } - │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: rw_tables.schema_id = rw_schemas.id, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, rw_types.id, rw_types.name, rw_schemas.name, pg_constraint.oid, pg_constraint.conname, pg_constraint.contype, rw_tables.name, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name] } + │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: rw_tables.schema_id = rw_schemas.id, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, pg_type.oid, pg_type.typname, rw_schemas.name, pg_constraint.oid, pg_constraint.conname, pg_constraint.contype, rw_tables.name, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name] } │ │ │ │ ├─BatchExchange { order: [], dist: HashShard(rw_tables.schema_id) } - │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: null:Int32 = rw_tables.id, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, rw_types.id, rw_types.name, rw_schemas.name, pg_constraint.oid, pg_constraint.conname, pg_constraint.contype, rw_tables.name, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_tables.schema_id] } + │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: null:Int32 = rw_tables.id, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, pg_type.oid, pg_type.typname, rw_schemas.name, pg_constraint.oid, pg_constraint.conname, pg_constraint.contype, rw_tables.name, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_tables.schema_id] } │ │ │ │ │ ├─BatchExchange { order: [], dist: HashShard(null:Int32) } │ │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: null:Int32 = null:Int32, output: all } │ │ │ │ │ │ ├─BatchExchange { order: [], dist: HashShard(null:Int32) } - │ │ │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: pg_constraint.connamespace = rw_schemas.id, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, rw_types.id, rw_types.name, rw_schemas.name, pg_constraint.oid, pg_constraint.conname, pg_constraint.contype, rw_tables.name, rw_schemas.name] } + │ │ │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: pg_constraint.connamespace = rw_schemas.id, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, pg_type.oid, pg_type.typname, rw_schemas.name, pg_constraint.oid, pg_constraint.conname, pg_constraint.contype, rw_tables.name, rw_schemas.name] } │ │ │ │ │ │ │ ├─BatchExchange { order: [], dist: HashShard(pg_constraint.connamespace) } - │ │ │ │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: pg_constraint.conrelid = rw_tables.id, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, rw_types.id, rw_types.name, rw_schemas.name, pg_constraint.oid, pg_constraint.conname, pg_constraint.connamespace, pg_constraint.contype, rw_tables.name] } + │ │ │ │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: pg_constraint.conrelid = rw_tables.id, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, pg_type.oid, pg_type.typname, rw_schemas.name, pg_constraint.oid, pg_constraint.conname, pg_constraint.connamespace, pg_constraint.contype, rw_tables.name] } │ │ │ │ │ │ │ │ ├─BatchExchange { order: [], dist: HashShard(pg_constraint.conrelid) } │ │ │ │ │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: null:Int32 = pg_constraint.oid, output: all } │ │ │ │ │ │ │ │ │ ├─BatchExchange { order: [], dist: HashShard(null:Int32) } - │ │ │ │ │ │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: rw_schemas.id = rw_schemas.id, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, rw_types.id, rw_types.name, rw_schemas.name] } - │ │ │ │ │ │ │ │ │ │ ├─BatchExchange { order: [], dist: HashShard(rw_schemas.id) } - │ │ │ │ │ │ │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: null:Int32 = rw_types.id, output: all } + │ │ │ │ │ │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: pg_type.typnamespace = rw_schemas.id, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name, pg_type.oid, pg_type.typname, rw_schemas.name] } + │ │ │ │ │ │ │ │ │ │ ├─BatchExchange { order: [], dist: HashShard(pg_type.typnamespace) } + │ │ │ │ │ │ │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: null:Int32 = pg_type.oid, output: all } │ │ │ │ │ │ │ │ │ │ │ ├─BatchExchange { order: [], dist: HashShard(null:Int32) } │ │ │ │ │ │ │ │ │ │ │ │ └─BatchHashJoin { type: LeftOuter, predicate: rw_tables.schema_id = rw_schemas.id, output: [null:Int32, null:Int32, null:Int16, null:Varchar, rw_tables.name, $expr1, rw_columns.name, rw_schemas.name, null:Int32, null:Varchar, rw_schemas.name, null:Int32, null:Varchar, rw_tables.name, rw_schemas.name] } │ │ │ │ │ │ │ │ │ │ │ │ ├─BatchExchange { order: [], dist: HashShard(rw_tables.schema_id) } @@ -125,12 +125,8 @@ │ │ │ │ │ │ │ │ │ │ │ │ │ └─BatchScan { table: rw_views, columns: [rw_views.id, rw_views.name, rw_views.schema_id], distribution: Single } │ │ │ │ │ │ │ │ │ │ │ │ └─BatchExchange { order: [], dist: HashShard(rw_schemas.id) } │ │ │ │ │ │ │ │ │ │ │ │ └─BatchScan { table: rw_schemas, columns: [rw_schemas.id, rw_schemas.name], distribution: Single } - │ │ │ │ │ │ │ │ │ │ │ └─BatchExchange { order: [], dist: HashShard(rw_types.id) } - │ │ │ │ │ │ │ │ │ │ │ └─BatchNestedLoopJoin { type: Inner, predicate: true, output: all } - │ │ │ │ │ │ │ │ │ │ │ ├─BatchScan { table: rw_types, columns: [rw_types.id, rw_types.name], distribution: Single } - │ │ │ │ │ │ │ │ │ │ │ └─BatchProject { exprs: [rw_schemas.id] } - │ │ │ │ │ │ │ │ │ │ │ └─BatchFilter { predicate: (rw_schemas.name = 'pg_catalog':Varchar) } - │ │ │ │ │ │ │ │ │ │ │ └─BatchScan { table: rw_schemas, columns: [rw_schemas.id, rw_schemas.name], distribution: Single } + │ │ │ │ │ │ │ │ │ │ │ └─BatchExchange { order: [], dist: HashShard(pg_type.oid) } + │ │ │ │ │ │ │ │ │ │ │ └─BatchScan { table: pg_type, columns: [pg_type.oid, pg_type.typname, pg_type.typnamespace], distribution: Single } │ │ │ │ │ │ │ │ │ │ └─BatchExchange { order: [], dist: HashShard(rw_schemas.id) } │ │ │ │ │ │ │ │ │ │ └─BatchScan { table: rw_schemas, columns: [rw_schemas.id, rw_schemas.name], distribution: Single } │ │ │ │ │ │ │ │ │ └─BatchExchange { order: [], dist: HashShard(pg_constraint.oid) } diff --git a/src/frontend/planner_test/tests/testdata/output/pg_catalog.yaml b/src/frontend/planner_test/tests/testdata/output/pg_catalog.yaml index cca1da2ee47ee..f005767652364 100644 --- a/src/frontend/planner_test/tests/testdata/output/pg_catalog.yaml +++ b/src/frontend/planner_test/tests/testdata/output/pg_catalog.yaml @@ -2,19 +2,9 @@ - sql: | select * from pg_catalog.pg_type logical_plan: |- - LogicalProject { exprs: [rw_types.id, rw_types.name, rw_types.typelem, rw_types.typarray, rw_types.input_oid, false:Boolean, 0:Int32, -1:Int32, 0:Int32, 0:Int32, rw_schemas.id, 'b':Varchar, 0:Int32, null:Varchar, null:Varchar, null:Int32] } - └─LogicalShare { id: 3 } - └─LogicalProject { exprs: [rw_types.id, rw_types.name, rw_types.typelem, rw_types.typarray, rw_types.input_oid, false:Boolean, 0:Int32, -1:Int32, 0:Int32, 0:Int32, rw_schemas.id, 'b':Varchar, 0:Int32, null:Varchar, null:Varchar, null:Int32] } - └─LogicalJoin { type: Inner, on: (rw_schemas.name = 'pg_catalog':Varchar), output: all } - ├─LogicalSysScan { table: rw_types, columns: [rw_types.id, rw_types.name, rw_types.input_oid, rw_types.typelem, rw_types.typarray] } - └─LogicalSysScan { table: rw_schemas, columns: [rw_schemas.id, rw_schemas.name, rw_schemas.owner, rw_schemas.acl] } - batch_plan: |- - BatchProject { exprs: [rw_types.id, rw_types.name, rw_types.typelem, rw_types.typarray, rw_types.input_oid, false:Boolean, 0:Int32, -1:Int32, 0:Int32, 0:Int32, rw_schemas.id, 'b':Varchar, 0:Int32, null:Varchar, null:Varchar, null:Int32] } - └─BatchNestedLoopJoin { type: Inner, predicate: true, output: all } - ├─BatchScan { table: rw_types, columns: [rw_types.id, rw_types.name, rw_types.input_oid, rw_types.typelem, rw_types.typarray], distribution: Single } - └─BatchProject { exprs: [rw_schemas.id] } - └─BatchFilter { predicate: (rw_schemas.name = 'pg_catalog':Varchar) } - └─BatchScan { table: rw_schemas, columns: [rw_schemas.id, rw_schemas.name], distribution: Single } + LogicalProject { exprs: [pg_type.oid, pg_type.typname, pg_type.typelem, pg_type.typarray, pg_type.typinput, pg_type.typnotnull, pg_type.typbasetype, pg_type.typtypmod, pg_type.typcollation, pg_type.typlen, pg_type.typnamespace, pg_type.typtype, pg_type.typrelid, pg_type.typdefault, pg_type.typcategory, pg_type.typreceive] } + └─LogicalSysScan { table: pg_type, columns: [pg_type.oid, pg_type.typname, pg_type.typelem, pg_type.typarray, pg_type.typinput, pg_type.typnotnull, pg_type.typbasetype, pg_type.typtypmod, pg_type.typcollation, pg_type.typlen, pg_type.typnamespace, pg_type.typtype, pg_type.typrelid, pg_type.typdefault, pg_type.typcategory, pg_type.typreceive] } + batch_plan: 'BatchScan { table: pg_type, columns: [pg_type.oid, pg_type.typname, pg_type.typelem, pg_type.typarray, pg_type.typinput, pg_type.typnotnull, pg_type.typbasetype, pg_type.typtypmod, pg_type.typcollation, pg_type.typlen, pg_type.typnamespace, pg_type.typtype, pg_type.typrelid, pg_type.typdefault, pg_type.typcategory, pg_type.typreceive], distribution: Single }' - sql: | select * from pg_catalog.pg_namespace logical_plan: |- diff --git a/src/frontend/src/catalog/system_catalog/pg_catalog/pg_type.rs b/src/frontend/src/catalog/system_catalog/pg_catalog/pg_type.rs index 65c71bb8fb0e7..99d67d7d5b300 100644 --- a/src/frontend/src/catalog/system_catalog/pg_catalog/pg_type.rs +++ b/src/frontend/src/catalog/system_catalog/pg_catalog/pg_type.rs @@ -15,33 +15,43 @@ use risingwave_common::types::Fields; use risingwave_frontend_macro::system_catalog; +use crate::catalog::system_catalog::rw_catalog::rw_types::read_rw_types; +use crate::catalog::system_catalog::SysCatalogReaderImpl; +use crate::error::Result; + /// The catalog `pg_type` stores information about data types. /// Ref: [`https://www.postgresql.org/docs/current/catalog-pg-type.html`] -#[system_catalog( - view, - "pg_catalog.pg_type", - "SELECT t.id AS oid, - t.name AS typname, - t.typelem AS typelem, - t.typarray AS typarray, - t.input_oid AS typinput, - false AS typnotnull, - 0 AS typbasetype, - -1 AS typtypmod, - 0 AS typcollation, - 0 AS typlen, - s.id AS typnamespace, - 'b' AS typtype, - 0 AS typrelid, - NULL AS typdefault, - NULL AS typcategory, - NULL::integer AS typreceive - FROM rw_catalog.rw_types t - JOIN rw_catalog.rw_schemas s - ON s.name = 'pg_catalog'" -)] + +// TODO: Make it a view atop of `rw_types` to reduce code duplication of the +// `read` function, while reserving the property that `oid` acts as the +// primary key. See https://github.com/risingwavelabs/risingwave/issues/15243. +// +// #[system_catalog( +// view, +// "pg_catalog.pg_type", +// "SELECT t.id AS oid, +// t.name AS typname, +// t.typelem AS typelem, +// t.typarray AS typarray, +// t.input_oid AS typinput, +// false AS typnotnull, +// 0 AS typbasetype, +// -1 AS typtypmod, +// 0 AS typcollation, +// 0 AS typlen, +// s.id AS typnamespace, +// 'b' AS typtype, +// 0 AS typrelid, +// NULL AS typdefault, +// NULL AS typcategory, +// NULL::integer AS typreceive +// FROM rw_catalog.rw_types t +// JOIN rw_catalog.rw_schemas s +// ON s.name = 'pg_catalog'" +// )] #[derive(Fields)] struct PgType { + #[primary_key] oid: i32, typname: String, typelem: i32, @@ -53,9 +63,42 @@ struct PgType { typcollation: i32, typlen: i32, typnamespace: i32, - typtype: String, + typtype: &'static str, typrelid: i32, - typdefault: String, - typcategory: String, - typreceive: i32, + typdefault: Option, + typcategory: Option, + typreceive: Option, +} + +#[system_catalog(table, "pg_catalog.pg_type")] +fn read_pg_type(reader: &SysCatalogReaderImpl) -> Result> { + let catalog_reader = reader.catalog_reader.read_guard(); + let pg_catalog_id = catalog_reader + .get_schema_by_name(&reader.auth_context.database, "pg_catalog")? + .id() as i32; + + let rw_types = read_rw_types(reader)?; + + let mut rows = Vec::with_capacity(rw_types.len()); + for rw_type in rw_types { + rows.push(PgType { + oid: rw_type.id, + typname: rw_type.name, + typelem: rw_type.typelem, + typarray: rw_type.typarray, + typinput: rw_type.input_oid, + typnotnull: false, + typbasetype: 0, + typtypmod: -1, + typcollation: 0, + typlen: 0, + typnamespace: pg_catalog_id, + typtype: "b", + typrelid: 0, + typdefault: None, + typcategory: None, + typreceive: None, + }); + } + Ok(rows) } diff --git a/src/frontend/src/catalog/system_catalog/rw_catalog/mod.rs b/src/frontend/src/catalog/system_catalog/rw_catalog/mod.rs index 9422fd3ec1c57..b5bb9310230a1 100644 --- a/src/frontend/src/catalog/system_catalog/rw_catalog/mod.rs +++ b/src/frontend/src/catalog/system_catalog/rw_catalog/mod.rs @@ -46,7 +46,7 @@ mod rw_system_tables; mod rw_table_fragments; mod rw_table_stats; mod rw_tables; -mod rw_types; +pub(super) mod rw_types; mod rw_user_secrets; mod rw_users; mod rw_views; diff --git a/src/frontend/src/catalog/system_catalog/rw_catalog/rw_types.rs b/src/frontend/src/catalog/system_catalog/rw_catalog/rw_types.rs index 041af546a9980..150948285732b 100644 --- a/src/frontend/src/catalog/system_catalog/rw_catalog/rw_types.rs +++ b/src/frontend/src/catalog/system_catalog/rw_catalog/rw_types.rs @@ -21,17 +21,17 @@ use crate::error::Result; /// `rw_types` stores all supported types in the database. #[derive(Fields)] -struct RwType { +pub struct RwType { #[primary_key] - id: i32, - name: String, - input_oid: String, - typelem: i32, - typarray: i32, + pub id: i32, + pub name: String, + pub input_oid: String, + pub typelem: i32, + pub typarray: i32, } #[system_catalog(table, "rw_catalog.rw_types")] -fn read_rw_types(_: &SysCatalogReaderImpl) -> Result> { +pub fn read_rw_types(_: &SysCatalogReaderImpl) -> Result> { let mut rows = vec![]; for (id, name, input_oid, typelem, typarray) in RW_TYPE_DATA { rows.push(RwType {