diff --git a/src/frontend/src/catalog/system_catalog/information_schema/columns.rs b/src/frontend/src/catalog/system_catalog/information_schema/columns.rs index 074b772ca0bb8..a9a0d8fc4f1b5 100644 --- a/src/frontend/src/catalog/system_catalog/information_schema/columns.rs +++ b/src/frontend/src/catalog/system_catalog/information_schema/columns.rs @@ -34,13 +34,37 @@ use risingwave_frontend_macro::system_catalog; NULL::integer AS numeric_scale, c.position AS ordinal_position, 'YES' AS is_nullable, - NULL AS collation_name, - 'pg_catalog' AS udt_schema, CASE WHEN c.data_type = 'varchar' THEN 'character varying' ELSE c.data_type END AS data_type, - c.udt_type AS udt_name + CURRENT_DATABASE() AS udt_catalog, + 'pg_catalog' AS udt_schema, + c.udt_type AS udt_name, + NULL AS character_set_catalog, + NULL AS character_set_schema, + NULL AS character_set_name, + NULL AS collation_catalog, + NULL AS collation_schema, + NULL AS collation_name, + NULL AS domain_catalog, + NULL AS domain_schema, + NULL AS domain_name, + NULL AS scope_catalog, + NULL AS scope_schema, + NULL AS scope_name, + 'NO' AS is_identity, + NULL AS identity_generation, + NULL AS identity_start, + NULL AS identity_increment, + NULL AS identity_maximum, + NULL AS identity_minimum, + NULL AS identity_cycle, + CASE + WHEN c.is_generated THEN 'ALWAYS' + ELSE 'NEVER' + END AS is_generated, + c.generation_expression FROM rw_catalog.rw_columns c LEFT JOIN rw_catalog.rw_relations r ON c.relation_id = r.id JOIN rw_catalog.rw_schemas s ON s.id = r.schema_id @@ -58,8 +82,29 @@ struct Column { numeric_scale: i32, ordinal_position: i32, is_nullable: String, - collation_name: String, - udt_schema: String, data_type: String, + udt_catalog: String, + udt_schema: String, udt_name: String, + character_set_catalog: String, + character_set_schema: String, + character_set_name: String, + collation_catalog: String, + collation_schema: String, + collation_name: String, + domain_catalog: String, + domain_schema: String, + domain_name: String, + scope_catalog: String, + scope_schema: String, + scope_name: String, + is_identity: String, + identity_generation: String, + identity_start: String, + identity_increment: String, + identity_maximum: String, + identity_minimum: String, + identity_cycle: String, + is_generated: String, + generation_expression: String, } diff --git a/src/frontend/src/catalog/system_catalog/pg_catalog/mod.rs b/src/frontend/src/catalog/system_catalog/pg_catalog/mod.rs index c1a935803f9f4..ce97aeaac552c 100644 --- a/src/frontend/src/catalog/system_catalog/pg_catalog/mod.rs +++ b/src/frontend/src/catalog/system_catalog/pg_catalog/mod.rs @@ -35,6 +35,7 @@ mod pg_matviews; mod pg_namespace; mod pg_opclass; mod pg_operator; +mod pg_partitioned_table; mod pg_proc; mod pg_roles; mod pg_settings; diff --git a/src/frontend/src/catalog/system_catalog/pg_catalog/pg_index.rs b/src/frontend/src/catalog/system_catalog/pg_catalog/pg_index.rs index 196c36ec7f1af..2dfb15f9e527b 100644 --- a/src/frontend/src/catalog/system_catalog/pg_catalog/pg_index.rs +++ b/src/frontend/src/catalog/system_catalog/pg_catalog/pg_index.rs @@ -28,7 +28,8 @@ use risingwave_frontend_macro::system_catalog; ARRAY[]::smallint[] as indoption, NULL AS indexprs, NULL AS indpred, - FALSE AS indisprimary + FALSE AS indisprimary, + ARRAY[]::int[] AS indclass FROM rw_catalog.rw_indexes" )] #[derive(Fields)] @@ -46,4 +47,6 @@ struct PgIndex { indpred: Option, // TODO: we return false as the default value. indisprimary: bool, + // Empty array. We only have a dummy implementation of `pg_opclass` yet. + indclass: Vec, } diff --git a/src/frontend/src/catalog/system_catalog/pg_catalog/pg_partitioned_table.rs b/src/frontend/src/catalog/system_catalog/pg_catalog/pg_partitioned_table.rs new file mode 100644 index 0000000000000..e11739e2609fd --- /dev/null +++ b/src/frontend/src/catalog/system_catalog/pg_catalog/pg_partitioned_table.rs @@ -0,0 +1,30 @@ +// Copyright 2024 RisingWave Labs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use risingwave_common::types::Fields; +use risingwave_frontend_macro::system_catalog; + +/// The catalog `pg_partitioned_table` stores information about how tables are partitioned. Reference: [`https://www.postgresql.org/docs/current/catalog-pg-partitioned-table.html`] +#[system_catalog(view, "pg_catalog.pg_partitioned_table")] +#[derive(Fields)] +struct PgPartitionedTable { + partrelid: i32, + partstrat: String, + partnatts: i16, + partdefid: i32, + partattrs: Vec, + partclass: Vec, + partcollation: Vec, + partexprs: Option, +} diff --git a/src/frontend/src/catalog/system_catalog/rw_catalog/rw_columns.rs b/src/frontend/src/catalog/system_catalog/rw_catalog/rw_columns.rs index 40760df81a492..8491da7062711 100644 --- a/src/frontend/src/catalog/system_catalog/rw_catalog/rw_columns.rs +++ b/src/frontend/src/catalog/system_catalog/rw_catalog/rw_columns.rs @@ -17,6 +17,7 @@ use risingwave_frontend_macro::system_catalog; use crate::catalog::system_catalog::SysCatalogReaderImpl; use crate::error::Result; +use crate::expr::{ExprDisplay, ExprImpl}; #[derive(Fields)] #[primary_key(relation_id, name)] @@ -27,6 +28,8 @@ struct RwColumn { is_hidden: bool, is_primary_key: bool, is_distribution_key: bool, + is_generated: bool, + generation_expression: Option, data_type: String, type_oid: i32, type_len: i16, @@ -51,6 +54,8 @@ fn read_rw_columns(reader: &SysCatalogReaderImpl) -> Result> { is_hidden: false, is_primary_key: false, is_distribution_key: false, + is_generated: false, + generation_expression: None, data_type: column.data_type().to_string(), type_oid: column.data_type().to_oid(), type_len: column.data_type().type_len(), @@ -71,6 +76,8 @@ fn read_rw_columns(reader: &SysCatalogReaderImpl) -> Result> { is_hidden: column.is_hidden, is_primary_key: sink.downstream_pk.contains(&index), is_distribution_key: sink.distribution_key.contains(&index), + is_generated: false, + generation_expression: None, data_type: column.data_type().to_string(), type_oid: column.data_type().to_oid(), type_len: column.data_type().type_len(), @@ -93,6 +100,8 @@ fn read_rw_columns(reader: &SysCatalogReaderImpl) -> Result> { is_hidden: column.is_hidden, is_primary_key: table.pk.contains(&index), is_distribution_key: false, + is_generated: false, + generation_expression: None, data_type: column.data_type().to_string(), type_oid: column.data_type().to_oid(), type_len: column.data_type().type_len(), @@ -104,6 +113,7 @@ fn read_rw_columns(reader: &SysCatalogReaderImpl) -> Result> { let table_rows = schema .iter_valid_table() .flat_map(|table| { + let schema = table.column_schema(); table .columns .iter() @@ -115,6 +125,15 @@ fn read_rw_columns(reader: &SysCatalogReaderImpl) -> Result> { is_hidden: column.is_hidden, is_primary_key: table.pk().iter().any(|idx| idx.column_index == index), is_distribution_key: table.distribution_key.contains(&index), + is_generated: column.is_generated(), + generation_expression: column.generated_expr().map(|expr_node| { + let expr = ExprImpl::from_expr_proto(expr_node).unwrap(); + let expr_display = ExprDisplay { + expr: &expr, + input_schema: &schema, + }; + expr_display.to_string() + }), data_type: column.data_type().to_string(), type_oid: column.data_type().to_oid(), type_len: column.data_type().type_len(), @@ -138,6 +157,8 @@ fn read_rw_columns(reader: &SysCatalogReaderImpl) -> Result> { is_hidden: column.is_hidden, is_primary_key: source.pk_col_ids.contains(&column.column_id()), is_distribution_key: false, + is_generated: false, + generation_expression: None, data_type: column.data_type().to_string(), type_oid: column.data_type().to_oid(), type_len: column.data_type().type_len(), diff --git a/src/frontend/src/catalog/table_catalog.rs b/src/frontend/src/catalog/table_catalog.rs index fbb77a0ca0bb5..2954cb37384dc 100644 --- a/src/frontend/src/catalog/table_catalog.rs +++ b/src/frontend/src/catalog/table_catalog.rs @@ -17,7 +17,7 @@ use std::collections::{HashMap, HashSet}; use fixedbitset::FixedBitSet; use itertools::Itertools; use risingwave_common::catalog::{ - ColumnCatalog, ConflictBehavior, TableDesc, TableId, TableVersionId, + ColumnCatalog, ConflictBehavior, Field, Schema, TableDesc, TableId, TableVersionId, }; use risingwave_common::util::epoch::Epoch; use risingwave_common::util::sort_util::ColumnOrder; @@ -492,6 +492,15 @@ impl TableCatalog { pub fn has_generated_column(&self) -> bool { self.columns.iter().any(|c| c.is_generated()) } + + pub fn column_schema(&self) -> Schema { + Schema::new( + self.columns + .iter() + .map(|c| Field::from(&c.column_desc)) + .collect(), + ) + } } impl From for TableCatalog {