From 11cf9c827e26b320d241080395766010791cc254 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Wed, 3 Jul 2024 09:31:13 +0800 Subject: [PATCH] feat: dbeaver mysql compatibility, use statement and information_schema.tables (#4218) * feat: add more placeholder field in information_schema.tables * feat: make schema modifiable for use statement * chore: add todo items * fix: resolve lint issues after data type changes * chore: update sqlness results * refactor: patch for select database is no longer needed * test: align tests and data types * Apply suggestions from code review Co-authored-by: dennis zhuang * fix: use canonicalize_identifier for database name * feat: add all columns for information_schema.tables * test: remove vairables from sqlness results * feat: add to_string impl for table options --------- Co-authored-by: dennis zhuang --- src/catalog/src/information_schema/tables.rs | 147 +++++++++++++-- src/catalog/src/table_source.rs | 2 +- src/common/function/src/system/database.rs | 2 +- src/frontend/src/instance.rs | 3 +- src/frontend/src/instance/prom_store.rs | 2 +- src/frontend/src/script.rs | 4 +- src/operator/src/delete.rs | 2 +- src/operator/src/expr_factory.rs | 10 +- src/operator/src/insert.rs | 18 +- .../src/req_convert/delete/row_to_region.rs | 4 +- .../src/req_convert/insert/stmt_to_region.rs | 2 +- src/operator/src/statement.rs | 21 ++- src/pipeline/src/manager/pipeline_operator.rs | 6 +- src/query/src/datafusion.rs | 2 +- src/query/src/sql.rs | 6 +- src/servers/src/grpc/greptime_handler.rs | 2 +- src/servers/src/http/handler.rs | 2 +- src/servers/src/http/prometheus.rs | 6 +- src/servers/src/mysql/federated.rs | 10 +- src/servers/src/mysql/handler.rs | 2 +- src/servers/tests/http/influxdb_test.rs | 5 +- src/servers/tests/http/prom_store_test.rs | 2 +- src/session/src/context.rs | 38 +++- src/session/src/lib.rs | 6 +- src/sql/src/parser.rs | 15 ++ src/sql/src/statements/statement.rs | 3 + src/table/src/requests.rs | 45 +++++ tests-integration/src/tests/instance_test.rs | 176 +++++++++++------- .../common/system/information_schema.result | 89 +++++---- .../common/system/information_schema.sql | 1 + .../standalone/common/view/create.result | 83 +++++---- tests/cases/standalone/common/view/create.sql | 1 + 32 files changed, 497 insertions(+), 220 deletions(-) diff --git a/src/catalog/src/information_schema/tables.rs b/src/catalog/src/information_schema/tables.rs index 1056a164fc7f..ef8eee267289 100644 --- a/src/catalog/src/information_schema/tables.rs +++ b/src/catalog/src/information_schema/tables.rs @@ -26,11 +26,13 @@ use datafusion::physical_plan::SendableRecordBatchStream as DfSendableRecordBatc use datatypes::prelude::{ConcreteDataType, ScalarVectorBuilder, VectorRef}; use datatypes::schema::{ColumnSchema, Schema, SchemaRef}; use datatypes::value::Value; -use datatypes::vectors::{StringVectorBuilder, UInt32VectorBuilder}; +use datatypes::vectors::{ + DateTimeVectorBuilder, StringVectorBuilder, UInt32VectorBuilder, UInt64VectorBuilder, +}; use futures::TryStreamExt; use snafu::{OptionExt, ResultExt}; use store_api::storage::{ScanRequest, TableId}; -use table::metadata::TableType; +use table::metadata::{TableInfo, TableType}; use super::TABLES; use crate::error::{ @@ -43,6 +45,24 @@ pub const TABLE_CATALOG: &str = "table_catalog"; pub const TABLE_SCHEMA: &str = "table_schema"; pub const TABLE_NAME: &str = "table_name"; pub const TABLE_TYPE: &str = "table_type"; +pub const VERSION: &str = "version"; +pub const ROW_FORMAT: &str = "row_format"; +pub const TABLE_ROWS: &str = "table_rows"; +pub const DATA_LENGTH: &str = "data_length"; +pub const INDEX_LENGTH: &str = "index_length"; +pub const MAX_DATA_LENGTH: &str = "max_data_length"; +pub const AVG_ROW_LENGTH: &str = "avg_row_length"; +pub const DATA_FREE: &str = "data_free"; +pub const AUTO_INCREMENT: &str = "auto_increment"; +pub const CREATE_TIME: &str = "create_time"; +pub const UPDATE_TIME: &str = "update_time"; +pub const CHECK_TIME: &str = "check_time"; +pub const TABLE_COLLATION: &str = "table_collation"; +pub const CHECKSUM: &str = "checksum"; +pub const CREATE_OPTIONS: &str = "create_options"; +pub const TABLE_COMMENT: &str = "table_comment"; +pub const MAX_INDEX_LENGTH: &str = "max_index_length"; +pub const TEMPORARY: &str = "temporary"; const TABLE_ID: &str = "table_id"; const ENGINE: &str = "engine"; const INIT_CAPACITY: usize = 42; @@ -69,7 +89,25 @@ impl InformationSchemaTables { ColumnSchema::new(TABLE_NAME, ConcreteDataType::string_datatype(), false), ColumnSchema::new(TABLE_TYPE, ConcreteDataType::string_datatype(), false), ColumnSchema::new(TABLE_ID, ConcreteDataType::uint32_datatype(), true), + ColumnSchema::new(DATA_LENGTH, ConcreteDataType::uint64_datatype(), true), + ColumnSchema::new(MAX_DATA_LENGTH, ConcreteDataType::uint64_datatype(), true), + ColumnSchema::new(INDEX_LENGTH, ConcreteDataType::uint64_datatype(), true), + ColumnSchema::new(MAX_INDEX_LENGTH, ConcreteDataType::uint64_datatype(), true), + ColumnSchema::new(AVG_ROW_LENGTH, ConcreteDataType::uint64_datatype(), true), ColumnSchema::new(ENGINE, ConcreteDataType::string_datatype(), true), + ColumnSchema::new(VERSION, ConcreteDataType::uint64_datatype(), true), + ColumnSchema::new(ROW_FORMAT, ConcreteDataType::string_datatype(), true), + ColumnSchema::new(TABLE_ROWS, ConcreteDataType::uint64_datatype(), true), + ColumnSchema::new(DATA_FREE, ConcreteDataType::uint64_datatype(), true), + ColumnSchema::new(AUTO_INCREMENT, ConcreteDataType::uint64_datatype(), true), + ColumnSchema::new(CREATE_TIME, ConcreteDataType::datetime_datatype(), true), + ColumnSchema::new(UPDATE_TIME, ConcreteDataType::datetime_datatype(), true), + ColumnSchema::new(CHECK_TIME, ConcreteDataType::datetime_datatype(), true), + ColumnSchema::new(TABLE_COLLATION, ConcreteDataType::string_datatype(), true), + ColumnSchema::new(CHECKSUM, ConcreteDataType::uint64_datatype(), true), + ColumnSchema::new(CREATE_OPTIONS, ConcreteDataType::string_datatype(), true), + ColumnSchema::new(TABLE_COMMENT, ConcreteDataType::string_datatype(), true), + ColumnSchema::new(TEMPORARY, ConcreteDataType::string_datatype(), true), ])) } @@ -131,7 +169,25 @@ struct InformationSchemaTablesBuilder { table_names: StringVectorBuilder, table_types: StringVectorBuilder, table_ids: UInt32VectorBuilder, + version: UInt64VectorBuilder, + row_format: StringVectorBuilder, + table_rows: UInt64VectorBuilder, + data_length: UInt64VectorBuilder, + max_data_length: UInt64VectorBuilder, + index_length: UInt64VectorBuilder, + avg_row_length: UInt64VectorBuilder, + max_index_length: UInt64VectorBuilder, + data_free: UInt64VectorBuilder, + auto_increment: UInt64VectorBuilder, + create_time: DateTimeVectorBuilder, + update_time: DateTimeVectorBuilder, + check_time: DateTimeVectorBuilder, + table_collation: StringVectorBuilder, + checksum: UInt64VectorBuilder, + create_options: StringVectorBuilder, + table_comment: StringVectorBuilder, engines: StringVectorBuilder, + temporary: StringVectorBuilder, } impl InformationSchemaTablesBuilder { @@ -149,7 +205,25 @@ impl InformationSchemaTablesBuilder { table_names: StringVectorBuilder::with_capacity(INIT_CAPACITY), table_types: StringVectorBuilder::with_capacity(INIT_CAPACITY), table_ids: UInt32VectorBuilder::with_capacity(INIT_CAPACITY), + data_length: UInt64VectorBuilder::with_capacity(INIT_CAPACITY), + max_data_length: UInt64VectorBuilder::with_capacity(INIT_CAPACITY), + index_length: UInt64VectorBuilder::with_capacity(INIT_CAPACITY), + avg_row_length: UInt64VectorBuilder::with_capacity(INIT_CAPACITY), engines: StringVectorBuilder::with_capacity(INIT_CAPACITY), + version: UInt64VectorBuilder::with_capacity(INIT_CAPACITY), + row_format: StringVectorBuilder::with_capacity(INIT_CAPACITY), + table_rows: UInt64VectorBuilder::with_capacity(INIT_CAPACITY), + max_index_length: UInt64VectorBuilder::with_capacity(INIT_CAPACITY), + data_free: UInt64VectorBuilder::with_capacity(INIT_CAPACITY), + auto_increment: UInt64VectorBuilder::with_capacity(INIT_CAPACITY), + create_time: DateTimeVectorBuilder::with_capacity(INIT_CAPACITY), + update_time: DateTimeVectorBuilder::with_capacity(INIT_CAPACITY), + check_time: DateTimeVectorBuilder::with_capacity(INIT_CAPACITY), + table_collation: StringVectorBuilder::with_capacity(INIT_CAPACITY), + checksum: UInt64VectorBuilder::with_capacity(INIT_CAPACITY), + create_options: StringVectorBuilder::with_capacity(INIT_CAPACITY), + table_comment: StringVectorBuilder::with_capacity(INIT_CAPACITY), + temporary: StringVectorBuilder::with_capacity(INIT_CAPACITY), } } @@ -171,10 +245,8 @@ impl InformationSchemaTablesBuilder { &predicates, &catalog_name, &schema_name, - &table_info.name, + table_info, table.table_type(), - Some(table_info.ident.table_id), - Some(&table_info.meta.engine), ); } } @@ -188,12 +260,14 @@ impl InformationSchemaTablesBuilder { predicates: &Predicates, catalog_name: &str, schema_name: &str, - table_name: &str, + table_info: Arc, table_type: TableType, - table_id: Option, - engine: Option<&str>, ) { - let table_type = match table_type { + let table_name = table_info.name.as_ref(); + let table_id = table_info.table_id(); + let engine = table_info.meta.engine.as_ref(); + + let table_type_text = match table_type { TableType::Base => "BASE TABLE", TableType::View => "VIEW", TableType::Temporary => "LOCAL TEMPORARY", @@ -203,7 +277,7 @@ impl InformationSchemaTablesBuilder { (TABLE_CATALOG, &Value::from(catalog_name)), (TABLE_SCHEMA, &Value::from(schema_name)), (TABLE_NAME, &Value::from(table_name)), - (TABLE_TYPE, &Value::from(table_type)), + (TABLE_TYPE, &Value::from(table_type_text)), ]; if !predicates.eval(&row) { @@ -213,9 +287,38 @@ impl InformationSchemaTablesBuilder { self.catalog_names.push(Some(catalog_name)); self.schema_names.push(Some(schema_name)); self.table_names.push(Some(table_name)); - self.table_types.push(Some(table_type)); - self.table_ids.push(table_id); - self.engines.push(engine); + self.table_types.push(Some(table_type_text)); + self.table_ids.push(Some(table_id)); + // TODO(sunng87): use real data for these fields + self.data_length.push(Some(0)); + self.max_data_length.push(Some(0)); + self.index_length.push(Some(0)); + self.avg_row_length.push(Some(0)); + self.max_index_length.push(Some(0)); + self.checksum.push(Some(0)); + self.table_rows.push(Some(0)); + self.data_free.push(Some(0)); + self.auto_increment.push(Some(0)); + self.row_format.push(Some("Fixed")); + self.table_collation.push(None); + self.update_time.push(None); + self.check_time.push(None); + + // use mariadb default table version number here + self.version.push(Some(11)); + self.table_comment.push(table_info.desc.as_deref()); + self.create_options + .push(Some(table_info.meta.options.to_string().as_ref())); + self.create_time + .push(Some(table_info.meta.created_on.timestamp_millis().into())); + + self.temporary + .push(if matches!(table_type, TableType::Temporary) { + Some("Y") + } else { + Some("N") + }); + self.engines.push(Some(engine)); } fn finish(&mut self) -> Result { @@ -225,7 +328,25 @@ impl InformationSchemaTablesBuilder { Arc::new(self.table_names.finish()), Arc::new(self.table_types.finish()), Arc::new(self.table_ids.finish()), + Arc::new(self.data_length.finish()), + Arc::new(self.max_data_length.finish()), + Arc::new(self.index_length.finish()), + Arc::new(self.max_index_length.finish()), + Arc::new(self.avg_row_length.finish()), Arc::new(self.engines.finish()), + Arc::new(self.version.finish()), + Arc::new(self.row_format.finish()), + Arc::new(self.table_rows.finish()), + Arc::new(self.data_free.finish()), + Arc::new(self.auto_increment.finish()), + Arc::new(self.create_time.finish()), + Arc::new(self.update_time.finish()), + Arc::new(self.check_time.finish()), + Arc::new(self.table_collation.finish()), + Arc::new(self.checksum.finish()), + Arc::new(self.create_options.finish()), + Arc::new(self.table_comment.finish()), + Arc::new(self.temporary.finish()), ]; RecordBatch::new(self.schema.clone(), columns).context(CreateRecordBatchSnafu) } diff --git a/src/catalog/src/table_source.rs b/src/catalog/src/table_source.rs index 7399dca550da..c09c6d45cb13 100644 --- a/src/catalog/src/table_source.rs +++ b/src/catalog/src/table_source.rs @@ -57,7 +57,7 @@ impl DfTableSourceProvider { disallow_cross_catalog_query, resolved_tables: HashMap::new(), default_catalog: query_ctx.current_catalog().to_owned(), - default_schema: query_ctx.current_schema().to_owned(), + default_schema: query_ctx.current_schema(), plan_decoder, } } diff --git a/src/common/function/src/system/database.rs b/src/common/function/src/system/database.rs index 11dbb2da143b..56630270d4d6 100644 --- a/src/common/function/src/system/database.rs +++ b/src/common/function/src/system/database.rs @@ -44,7 +44,7 @@ impl Function for DatabaseFunction { fn eval(&self, func_ctx: FunctionContext, _columns: &[VectorRef]) -> Result { let db = func_ctx.query_ctx.current_schema(); - Ok(Arc::new(StringVector::from_slice(&[db])) as _) + Ok(Arc::new(StringVector::from_slice(&[&db])) as _) } } diff --git a/src/frontend/src/instance.rs b/src/frontend/src/instance.rs index 9a909a54c3f1..91e52815fe3f 100644 --- a/src/frontend/src/instance.rs +++ b/src/frontend/src/instance.rs @@ -509,7 +509,8 @@ pub fn check_permission( Statement::CreateDatabase(_) | Statement::ShowDatabases(_) | Statement::DropDatabase(_) - | Statement::DropFlow(_) => {} + | Statement::DropFlow(_) + | Statement::Use(_) => {} Statement::ShowCreateTable(stmt) => { validate_param(&stmt.table_name, query_ctx)?; } diff --git a/src/frontend/src/instance/prom_store.rs b/src/frontend/src/instance/prom_store.rs index 97ddd238a500..6bfd53c41423 100644 --- a/src/frontend/src/instance/prom_store.rs +++ b/src/frontend/src/instance/prom_store.rs @@ -146,7 +146,7 @@ impl Instance { let table_name = prom_store::table_name(query)?; let output = self - .handle_remote_query(&ctx, catalog_name, schema_name, &table_name, query) + .handle_remote_query(&ctx, catalog_name, &schema_name, &table_name, query) .await .map_err(BoxedError::new) .context(error::ExecuteQuerySnafu)?; diff --git a/src/frontend/src/script.rs b/src/frontend/src/script.rs index 5cda392d112f..a3126cb2d772 100644 --- a/src/frontend/src/script.rs +++ b/src/frontend/src/script.rs @@ -230,7 +230,7 @@ mod python { .script_manager .insert_and_compile( query_ctx.current_catalog(), - query_ctx.current_schema(), + &query_ctx.current_schema(), name, script, ) @@ -266,7 +266,7 @@ mod python { self.script_manager .execute( query_ctx.current_catalog(), - query_ctx.current_schema(), + &query_ctx.current_schema(), name, params, ) diff --git a/src/operator/src/delete.rs b/src/operator/src/delete.rs index ecd3ec23c573..20c7b5381fa9 100644 --- a/src/operator/src/delete.rs +++ b/src/operator/src/delete.rs @@ -179,7 +179,7 @@ impl Deleter { for req in &mut requests.deletes { let catalog = ctx.current_catalog(); let schema = ctx.current_schema(); - let table = self.get_table(catalog, schema, &req.table_name).await?; + let table = self.get_table(catalog, &schema, &req.table_name).await?; let key_column_names = self.key_column_names(&table)?; let rows = req.rows.as_mut().unwrap(); diff --git a/src/operator/src/expr_factory.rs b/src/operator/src/expr_factory.rs index 9f3d2b1c4077..e4605a8a34c8 100644 --- a/src/operator/src/expr_factory.rs +++ b/src/operator/src/expr_factory.rs @@ -551,8 +551,9 @@ pub fn to_create_flow_task_expr( .to_string(); let schema = sink_table_ref .schema() - .unwrap_or(query_ctx.current_schema()) - .to_string(); + .map(|s| s.to_owned()) + .unwrap_or(query_ctx.current_schema()); + let sink_table_name = TableName { catalog_name: catalog, schema_name: schema, @@ -571,8 +572,9 @@ pub fn to_create_flow_task_expr( .to_string(); let schema = reference .schema() - .unwrap_or(query_ctx.current_schema()) - .to_string(); + .map(|s| s.to_string()) + .unwrap_or(query_ctx.current_schema()); + let table_name = TableName { catalog_name: catalog, schema_name: schema, diff --git a/src/operator/src/insert.rs b/src/operator/src/insert.rs index 4bae21f987b9..20cf67df3598 100644 --- a/src/operator/src/insert.rs +++ b/src/operator/src/insert.rs @@ -443,7 +443,7 @@ impl Inserter { for req in &requests.inserts { let catalog = ctx.current_catalog(); let schema = ctx.current_schema(); - let table = self.get_table(catalog, schema, &req.table_name).await?; + let table = self.get_table(catalog, &schema, &req.table_name).await?; match table { Some(table) => { let table_info = table.table_info(); @@ -525,14 +525,14 @@ impl Inserter { // check if exist if self - .get_table(catalog_name, schema_name, &physical_table) + .get_table(catalog_name, &schema_name, &physical_table) .await? .is_some() { return Ok(()); } - let table_reference = TableReference::full(catalog_name, schema_name, &physical_table); + let table_reference = TableReference::full(catalog_name, &schema_name, &physical_table); info!("Physical metric table `{table_reference}` does not exist, try creating table"); // schema with timestamp and field column @@ -621,8 +621,8 @@ impl Inserter { ctx: &QueryContextRef, statement_executor: &StatementExecutor, ) -> Result { - let table_ref = - TableReference::full(ctx.current_catalog(), ctx.current_schema(), &req.table_name); + let schema = ctx.current_schema(); + let table_ref = TableReference::full(ctx.current_catalog(), &schema, &req.table_name); let request_schema = req.rows.as_ref().unwrap().schema.as_slice(); let create_table_expr = &mut build_create_table_expr(&table_ref, request_schema)?; @@ -652,8 +652,8 @@ impl Inserter { ctx: &QueryContextRef, statement_executor: &StatementExecutor, ) -> Result { - let table_ref = - TableReference::full(ctx.current_catalog(), ctx.current_schema(), &req.table_name); + let schema = ctx.current_schema(); + let table_ref = TableReference::full(ctx.current_catalog(), &schema, &req.table_name); // SAFETY: `req.rows` is guaranteed to be `Some` by `handle_log_inserts`. let request_schema = req.rows.as_ref().unwrap().schema.as_slice(); let create_table_expr = &mut build_create_table_expr(&table_ref, request_schema)?; @@ -692,7 +692,7 @@ impl Inserter { let create_table_exprs = create_tables .iter() .map(|req| { - let table_ref = TableReference::full(catalog_name, schema_name, &req.table_name); + let table_ref = TableReference::full(catalog_name, &schema_name, &req.table_name); let request_schema = req.rows.as_ref().unwrap().schema.as_slice(); let mut create_table_expr = build_create_table_expr(&table_ref, request_schema)?; @@ -707,7 +707,7 @@ impl Inserter { .collect::>>()?; let res = statement_executor - .create_logical_tables(catalog_name, schema_name, &create_table_exprs, ctx.clone()) + .create_logical_tables(catalog_name, &schema_name, &create_table_exprs, ctx.clone()) .await; match res { diff --git a/src/operator/src/req_convert/delete/row_to_region.rs b/src/operator/src/req_convert/delete/row_to_region.rs index e69442115206..1b1316c904a5 100644 --- a/src/operator/src/req_convert/delete/row_to_region.rs +++ b/src/operator/src/req_convert/delete/row_to_region.rs @@ -64,13 +64,13 @@ impl<'a> RowToRegion<'a> { let catalog_name = self.ctx.current_catalog(); let schema_name = self.ctx.current_schema(); self.catalog_manager - .table(catalog_name, schema_name, table_name) + .table(catalog_name, &schema_name, table_name) .await .context(CatalogSnafu)? .with_context(|| TableNotFoundSnafu { table_name: common_catalog::format_full_table_name( catalog_name, - schema_name, + &schema_name, table_name, ), }) diff --git a/src/operator/src/req_convert/insert/stmt_to_region.rs b/src/operator/src/req_convert/insert/stmt_to_region.rs index 5f40564b2994..4cd9c0856695 100644 --- a/src/operator/src/req_convert/insert/stmt_to_region.rs +++ b/src/operator/src/req_convert/insert/stmt_to_region.rs @@ -144,7 +144,7 @@ impl<'a> StatementToRegion<'a> { match &obj_name.0[..] { [table] => Ok(( self.ctx.current_catalog().to_owned(), - self.ctx.current_schema().to_owned(), + self.ctx.current_schema(), table.value.clone(), )), [schema, table] => Ok(( diff --git a/src/operator/src/statement.rs b/src/operator/src/statement.rs index 6c1c33a0c809..318b556551a4 100644 --- a/src/operator/src/statement.rs +++ b/src/operator/src/statement.rs @@ -25,6 +25,7 @@ mod tql; use std::sync::Arc; use catalog::CatalogManagerRef; +use client::RecordBatches; use common_error::ext::BoxedError; use common_meta::cache::TableRouteCacheRef; use common_meta::cache_invalidator::CacheInvalidatorRef; @@ -42,7 +43,7 @@ use query::plan::LogicalPlan; use query::QueryEngineRef; use session::context::QueryContextRef; use session::table_name::table_idents_to_full_name; -use snafu::{OptionExt, ResultExt}; +use snafu::{ensure, OptionExt, ResultExt}; use sql::statements::copy::{CopyDatabase, CopyDatabaseArgument, CopyTable, CopyTableArgument}; use sql::statements::statement::Statement; use sql::statements::OptionMap; @@ -56,7 +57,7 @@ use table::TableRef; use self::set::{set_bytea_output, set_datestyle, set_timezone, validate_client_encoding}; use crate::error::{ self, CatalogSnafu, ExecLogicalPlanSnafu, ExternalSnafu, InvalidSqlSnafu, NotSupportedSnafu, - PlanStatementSnafu, Result, TableNotFoundSnafu, + PlanStatementSnafu, Result, SchemaNotFoundSnafu, TableNotFoundSnafu, }; use crate::insert::InserterRef; use crate::statement::copy_database::{COPY_DATABASE_TIME_END_KEY, COPY_DATABASE_TIME_START_KEY}; @@ -307,9 +308,25 @@ impl StatementExecutor { } Statement::ShowIndex(show_index) => self.show_index(show_index, query_ctx).await, Statement::ShowStatus(_) => self.show_status(query_ctx).await, + Statement::Use(db) => self.use_database(db, query_ctx).await, } } + pub async fn use_database(&self, db: String, query_ctx: QueryContextRef) -> Result { + let catalog = query_ctx.current_catalog(); + ensure!( + self.catalog_manager + .schema_exists(catalog, db.as_ref()) + .await + .context(CatalogSnafu)?, + SchemaNotFoundSnafu { schema_info: &db } + ); + + query_ctx.set_current_schema(&db); + + Ok(Output::new_with_record_batches(RecordBatches::empty())) + } + pub async fn plan( &self, stmt: QueryStatement, diff --git a/src/pipeline/src/manager/pipeline_operator.rs b/src/pipeline/src/manager/pipeline_operator.rs index 364bc1374519..5ae81a97a264 100644 --- a/src/pipeline/src/manager/pipeline_operator.rs +++ b/src/pipeline/src/manager/pipeline_operator.rs @@ -154,9 +154,10 @@ impl PipelineOperator { content_type: &str, pipeline: &str, ) -> Result { + let schema = ctx.current_schema(); self.get_pipeline_table_from_cache(ctx.current_catalog()) .context(PipelineTableNotFoundSnafu)? - .insert_and_compile(ctx.current_schema(), name, content_type, pipeline) + .insert_and_compile(&schema, name, content_type, pipeline) .await } } @@ -185,11 +186,12 @@ impl PipelineOperator { name: &str, version: PipelineVersion, ) -> Result>> { + let schema = query_ctx.current_schema(); self.create_pipeline_table_if_not_exists(query_ctx.clone()) .await?; self.get_pipeline_table_from_cache(query_ctx.current_catalog()) .context(PipelineTableNotFoundSnafu)? - .get_pipeline(query_ctx.current_schema(), name, version) + .get_pipeline(&schema, name, version) .await } diff --git a/src/query/src/datafusion.rs b/src/query/src/datafusion.rs index f1fa814104d3..30fff004d671 100644 --- a/src/query/src/datafusion.rs +++ b/src/query/src/datafusion.rs @@ -115,7 +115,7 @@ impl DatafusionQueryEngine { .start_timer(); let default_catalog = &query_ctx.current_catalog().to_owned(); - let default_schema = &query_ctx.current_schema().to_owned(); + let default_schema = &query_ctx.current_schema(); let table_name = dml.table_name.resolve(default_catalog, default_schema); let table = self.find_table(&table_name).await?; diff --git a/src/query/src/sql.rs b/src/query/src/sql.rs index 9b9963797672..a62889bfe7ec 100644 --- a/src/query/src/sql.rs +++ b/src/query/src/sql.rs @@ -311,7 +311,7 @@ pub async fn show_columns( let schema_name = if let Some(database) = stmt.database { database } else { - query_ctx.current_schema().to_owned() + query_ctx.current_schema() }; let projects = if stmt.full { @@ -372,7 +372,7 @@ pub async fn show_index( let schema_name = if let Some(database) = stmt.database { database } else { - query_ctx.current_schema().to_owned() + query_ctx.current_schema() }; let select = vec![ @@ -454,7 +454,7 @@ pub async fn show_tables( let schema_name = if let Some(database) = stmt.database { database } else { - query_ctx.current_schema().to_owned() + query_ctx.current_schema() }; // (dennis): MySQL rename `table_name` to `Tables_in_{schema}`, but we use `Tables` instead. diff --git a/src/servers/src/grpc/greptime_handler.rs b/src/servers/src/grpc/greptime_handler.rs index b4e9f26f5b86..108d53cacddd 100644 --- a/src/servers/src/grpc/greptime_handler.rs +++ b/src/servers/src/grpc/greptime_handler.rs @@ -148,7 +148,7 @@ pub(crate) async fn auth( Identity::UserId(&username, None), Password::PlainText(password.into()), query_ctx.current_catalog(), - query_ctx.current_schema(), + &query_ctx.current_schema(), ) .await .context(AuthSnafu), diff --git a/src/servers/src/http/handler.rs b/src/servers/src/http/handler.rs index 79f60639d272..cfdd7d5d8922 100644 --- a/src/servers/src/http/handler.rs +++ b/src/servers/src/http/handler.rs @@ -332,7 +332,7 @@ async fn validate_schema( query_ctx: QueryContextRef, ) -> Option<(StatusCode, String)> { match sql_handler - .is_valid_schema(query_ctx.current_catalog(), query_ctx.current_schema()) + .is_valid_schema(query_ctx.current_catalog(), &query_ctx.current_schema()) .await { Ok(true) => None, diff --git a/src/servers/src/http/prometheus.rs b/src/servers/src/http/prometheus.rs index cb1588704700..8f24dc11f721 100644 --- a/src/servers/src/http/prometheus.rs +++ b/src/servers/src/http/prometheus.rs @@ -428,7 +428,7 @@ async fn retrieve_series_from_query_result( let table = manager .table( query_ctx.current_catalog(), - query_ctx.current_schema(), + &query_ctx.current_schema(), table_name, ) .await @@ -779,7 +779,7 @@ async fn retrieve_field_names( if matches.is_empty() { // query all tables if no matcher is provided - while let Some(table) = manager.tables(catalog, schema).next().await { + while let Some(table) = manager.tables(catalog, &schema).next().await { let table = table.context(CatalogSnafu)?; for column in table.field_columns() { field_columns.insert(column.name); @@ -790,7 +790,7 @@ async fn retrieve_field_names( for table_name in matches { let table = manager - .table(catalog, schema, &table_name) + .table(catalog, &schema, &table_name) .await .context(CatalogSnafu)? .with_context(|| TableNotFoundSnafu { diff --git a/src/servers/src/mysql/federated.rs b/src/servers/src/mysql/federated.rs index 635e2819c7b3..88fdc20f03bd 100644 --- a/src/servers/src/mysql/federated.rs +++ b/src/servers/src/mysql/federated.rs @@ -38,9 +38,6 @@ static SHOW_LOWER_CASE_PATTERN: Lazy = static SHOW_VARIABLES_LIKE_PATTERN: Lazy = Lazy::new(|| Regex::new("(?i)^(SHOW VARIABLES( LIKE (.*))?)").unwrap()); -static SELECT_DATABASE_PATTERN: Lazy = - Lazy::new(|| Regex::new(r"(?i)^(SELECT DATABASE\(\s*\))").unwrap()); - // SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP()); static SELECT_TIME_DIFF_FUNC_PATTERN: Lazy = Lazy::new(|| Regex::new("(?i)^(SELECT TIMEDIFF\\(NOW\\(\\), UTC_TIMESTAMP\\(\\)\\))").unwrap()); @@ -249,15 +246,12 @@ fn check_show_variables(query: &str) -> Option { } // Check for SET or others query, this is the final check of the federated query. -fn check_others(query: &str, query_ctx: QueryContextRef) -> Option { +fn check_others(query: &str, _query_ctx: QueryContextRef) -> Option { if OTHER_NOT_SUPPORTED_STMT.is_match(query.as_bytes()) { return Some(Output::new_with_record_batches(RecordBatches::empty())); } - let recordbatches = if SELECT_DATABASE_PATTERN.is_match(query) { - let schema = query_ctx.current_schema(); - Some(select_function("database()", schema)) - } else if SELECT_TIME_DIFF_FUNC_PATTERN.is_match(query) { + let recordbatches = if SELECT_TIME_DIFF_FUNC_PATTERN.is_match(query) { Some(select_function( "TIMEDIFF(NOW(), UTC_TIMESTAMP())", "00:00:00", diff --git a/src/servers/src/mysql/handler.rs b/src/servers/src/mysql/handler.rs index 0e90ed0ddc1c..6afdc546eec9 100644 --- a/src/servers/src/mysql/handler.rs +++ b/src/servers/src/mysql/handler.rs @@ -525,7 +525,7 @@ impl AsyncMysqlShim for MysqlInstanceShi let catalog = if let Some(catalog) = &catalog_from_db { catalog.to_string() } else { - self.session.get_catalog() + self.session.catalog() }; if !self diff --git a/src/servers/tests/http/influxdb_test.rs b/src/servers/tests/http/influxdb_test.rs index 0282264f85b8..3e6e743b5c09 100644 --- a/src/servers/tests/http/influxdb_test.rs +++ b/src/servers/tests/http/influxdb_test.rs @@ -57,10 +57,7 @@ impl InfluxdbLineProtocolHandler for DummyInstance { async fn exec(&self, request: InfluxdbRequest, ctx: QueryContextRef) -> Result { let requests: RowInsertRequests = request.try_into()?; for expr in requests.inserts { - let _ = self - .tx - .send((ctx.current_schema().to_owned(), expr.table_name)) - .await; + let _ = self.tx.send((ctx.current_schema(), expr.table_name)).await; } Ok(Output::new_with_affected_rows(0)) diff --git a/src/servers/tests/http/prom_store_test.rs b/src/servers/tests/http/prom_store_test.rs index fc0490fb5183..fd2d01304e4c 100644 --- a/src/servers/tests/http/prom_store_test.rs +++ b/src/servers/tests/http/prom_store_test.rs @@ -70,7 +70,7 @@ impl PromStoreProtocolHandler for DummyInstance { async fn read(&self, request: ReadRequest, ctx: QueryContextRef) -> Result { let _ = self .tx - .send((ctx.current_schema().to_owned(), request.encode_to_vec())) + .send((ctx.current_schema(), request.encode_to_vec())) .await; let response = ReadResponse { diff --git a/src/session/src/context.rs b/src/session/src/context.rs index 592b56b2fb3a..99efbdfc7a92 100644 --- a/src/session/src/context.rs +++ b/src/session/src/context.rs @@ -38,7 +38,8 @@ pub type ConnInfoRef = Arc; #[builder(build_fn(skip))] pub struct QueryContext { current_catalog: String, - current_schema: String, + #[builder(setter(custom))] + current_schema: ArcSwap, current_user: ArcSwap>, #[builder(setter(custom))] timezone: ArcSwap, @@ -55,6 +56,11 @@ impl QueryContextBuilder { self.timezone = Some(ArcSwap::new(tz)); self } + + pub fn current_schema(mut self, schema: String) -> Self { + self.current_schema = Some(ArcSwap::new(Arc::new(schema))); + self + } } impl Display for QueryContext { @@ -72,7 +78,7 @@ impl Clone for QueryContext { fn clone(&self) -> Self { Self { current_catalog: self.current_catalog.clone(), - current_schema: self.current_schema.clone(), + current_schema: ArcSwap::new(self.current_schema.load().clone()), current_user: self.current_user.load().clone().into(), timezone: self.timezone.load().clone().into(), sql_dialect: self.sql_dialect.clone(), @@ -119,7 +125,7 @@ impl From for api::v1::QueryContext { ) -> Self { api::v1::QueryContext { current_catalog, - current_schema, + current_schema: current_schema.load().to_string(), timezone: timezone.to_string(), extensions, } @@ -152,12 +158,16 @@ impl QueryContext { }); QueryContextBuilder::default() .current_catalog(catalog) - .current_schema(schema) + .current_schema(schema.to_string()) .build() } - pub fn current_schema(&self) -> &str { - &self.current_schema + pub fn current_schema(&self) -> String { + self.current_schema.load().as_ref().clone() + } + + pub fn set_current_schema(&self, new_schema: &str) { + let _ = self.current_schema.swap(Arc::new(new_schema.to_string())); } pub fn current_catalog(&self) -> &str { @@ -171,7 +181,7 @@ impl QueryContext { pub fn get_db_string(&self) -> String { let catalog = self.current_catalog(); let schema = self.current_schema(); - build_db_string(catalog, schema) + build_db_string(catalog, &schema) } pub fn timezone(&self) -> Arc { @@ -202,13 +212,21 @@ impl QueryContext { self.extensions.clone() } - /// SQL like `set variable` may change timezone or other info in `QueryContext`. + /// SQL like `set variable`, `use ` may change timezone or other + /// info in `QueryContext`. /// We need persist these change in `Session`. pub fn update_session(&self, session: &SessionRef) { + // update timezone for session let tz = self.timezone(); if *session.timezone() != *tz { session.set_timezone(tz.as_ref().clone()) } + + // update current schema for session + let schema = self.current_schema(); + if *session.schema() != *schema { + session.set_schema(schema) + } } /// Default to double quote and fallback to back quote @@ -235,7 +253,7 @@ impl QueryContextBuilder { .unwrap_or_else(|| DEFAULT_CATALOG_NAME.to_string()), current_schema: self .current_schema - .unwrap_or_else(|| DEFAULT_SCHEMA_NAME.to_string()), + .unwrap_or_else(|| ArcSwap::new(Arc::new(DEFAULT_SCHEMA_NAME.to_string()))), current_user: self .current_user .unwrap_or_else(|| ArcSwap::new(Arc::new(None))), @@ -260,7 +278,7 @@ impl QueryContextBuilder { pub fn from_existing(context: &QueryContext) -> QueryContextBuilder { QueryContextBuilder { current_catalog: Some(context.current_catalog.clone()), - current_schema: Some(context.current_schema.clone()), + current_schema: Some(context.current_schema.load().clone().into()), current_user: Some(context.current_user.load().clone().into()), timezone: Some(context.timezone.load().clone().into()), sql_dialect: Some(context.sql_dialect.clone()), diff --git a/src/session/src/lib.rs b/src/session/src/lib.rs index 627d01b6050e..27270f804a28 100644 --- a/src/session/src/lib.rs +++ b/src/session/src/lib.rs @@ -109,10 +109,14 @@ impl Session { } #[inline] - pub fn get_catalog(&self) -> String { + pub fn catalog(&self) -> String { self.catalog.load().as_ref().clone() } + pub fn schema(&self) -> String { + self.schema.load().as_ref().clone() + } + #[inline] pub fn set_schema(&self, schema: String) { self.schema.store(Arc::new(schema)); diff --git a/src/sql/src/parser.rs b/src/sql/src/parser.rs index 41f771de87cd..01aa0ef39336 100644 --- a/src/sql/src/parser.rs +++ b/src/sql/src/parser.rs @@ -166,6 +166,21 @@ impl<'a> ParserContext<'a> { self.parse_tql() } + Keyword::USE => { + let _ = self.parser.next_token(); + + let database_name = self.parser.parse_identifier(false).context( + error::UnexpectedSnafu { + sql: self.sql, + expected: "a database name", + actual: self.peek_token_as_string(), + }, + )?; + Ok(Statement::Use( + Self::canonicalize_identifier(database_name).value, + )) + } + // todo(hl) support more statements. _ => self.unsupported(self.peek_token_as_string()), } diff --git a/src/sql/src/statements/statement.rs b/src/sql/src/statements/statement.rs index 579f2a372ad2..5275262f7e7f 100644 --- a/src/sql/src/statements/statement.rs +++ b/src/sql/src/statements/statement.rs @@ -98,6 +98,8 @@ pub enum Statement { SetVariables(SetVariables), // SHOW VARIABLES ShowVariables(ShowVariables), + // USE + Use(String), } impl Display for Statement { @@ -136,6 +138,7 @@ impl Display for Statement { write!(f, "SHOW COLLATION {kind}") } Statement::CreateView(s) => s.fmt(f), + Statement::Use(s) => s.fmt(f), } } } diff --git a/src/table/src/requests.rs b/src/table/src/requests.rs index 519ee2adb62b..a00b25eacb13 100644 --- a/src/table/src/requests.rs +++ b/src/table/src/requests.rs @@ -15,6 +15,7 @@ //! Table and TableEngine requests use std::collections::HashMap; +use std::fmt; use std::str::FromStr; use std::time::Duration; @@ -128,6 +129,25 @@ impl TableOptions { } } +impl fmt::Display for TableOptions { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut key_vals = vec![]; + if let Some(size) = self.write_buffer_size { + key_vals.push(format!("{}={}", WRITE_BUFFER_SIZE_KEY, size)); + } + + if let Some(ttl) = self.ttl { + key_vals.push(format!("{}={}", TTL_KEY, humantime::Duration::from(ttl))); + } + + for (k, v) in &self.extra_options { + key_vals.push(format!("{}={}", k, v)); + } + + write!(f, "{}", key_vals.join(" ")) + } +} + impl From<&TableOptions> for HashMap { fn from(opts: &TableOptions) -> Self { let mut res = HashMap::with_capacity(2 + opts.extra_options.len()); @@ -345,4 +365,29 @@ mod tests { let serialized = TableOptions::try_from_iter(&serialized_map).unwrap(); assert_eq!(options, serialized); } + + #[test] + fn test_table_options_to_string() { + let options = TableOptions { + write_buffer_size: Some(ReadableSize::mb(128)), + ttl: Some(Duration::from_secs(1000)), + extra_options: HashMap::new(), + }; + + assert_eq!( + "write_buffer_size=128.0MiB ttl=16m 40s", + options.to_string() + ); + + let options = TableOptions { + write_buffer_size: Some(ReadableSize::mb(128)), + ttl: Some(Duration::from_secs(1000)), + extra_options: HashMap::from([("a".to_string(), "A".to_string())]), + }; + + assert_eq!( + "write_buffer_size=128.0MiB ttl=16m 40s a=A", + options.to_string() + ); + } } diff --git a/tests-integration/src/tests/instance_test.rs b/tests-integration/src/tests/instance_test.rs index 44d2dc5fb37f..b40ed6113b06 100644 --- a/tests-integration/src/tests/instance_test.rs +++ b/tests-integration/src/tests/instance_test.rs @@ -1897,81 +1897,117 @@ async fn test_information_schema_dot_columns(instance: Arc) { let output = execute_sql(&instance, sql).await.data; let expected = "\ -+---------------+--------------------+------------+--------------------------+--------------+---------------+ -| table_catalog | table_schema | table_name | column_name | data_type | semantic_type | -+---------------+--------------------+------------+--------------------------+--------------+---------------+ -| greptime | information_schema | columns | character_maximum_length | bigint | FIELD | -| greptime | information_schema | columns | character_octet_length | bigint | FIELD | -| greptime | information_schema | columns | character_set_name | string | FIELD | -| greptime | information_schema | columns | collation_name | string | FIELD | -| greptime | information_schema | columns | column_comment | string | FIELD | -| greptime | information_schema | columns | column_default | string | FIELD | -| greptime | information_schema | columns | column_key | string | FIELD | -| greptime | information_schema | columns | column_name | string | FIELD | -| greptime | information_schema | columns | column_type | string | FIELD | -| greptime | information_schema | columns | data_type | string | FIELD | -| greptime | information_schema | columns | datetime_precision | bigint | FIELD | -| greptime | information_schema | columns | extra | string | FIELD | -| greptime | information_schema | columns | generation_expression | string | FIELD | -| greptime | information_schema | columns | greptime_data_type | string | FIELD | -| greptime | information_schema | columns | is_nullable | string | FIELD | -| greptime | information_schema | columns | numeric_precision | bigint | FIELD | -| greptime | information_schema | columns | numeric_scale | bigint | FIELD | -| greptime | information_schema | columns | ordinal_position | bigint | FIELD | -| greptime | information_schema | columns | privileges | string | FIELD | -| greptime | information_schema | columns | semantic_type | string | FIELD | -| greptime | information_schema | columns | srs_id | bigint | FIELD | -| greptime | information_schema | columns | table_catalog | string | FIELD | -| greptime | information_schema | columns | table_name | string | FIELD | -| greptime | information_schema | columns | table_schema | string | FIELD | -| greptime | public | numbers | number | int unsigned | TAG | -| greptime | information_schema | tables | engine | string | FIELD | -| greptime | information_schema | tables | table_catalog | string | FIELD | -| greptime | information_schema | tables | table_id | int unsigned | FIELD | -| greptime | information_schema | tables | table_name | string | FIELD | -| greptime | information_schema | tables | table_schema | string | FIELD | -| greptime | information_schema | tables | table_type | string | FIELD | -+---------------+--------------------+------------+--------------------------+--------------+---------------+"; ++---------------+--------------------+------------+--------------------------+-----------------+---------------+ +| table_catalog | table_schema | table_name | column_name | data_type | semantic_type | ++---------------+--------------------+------------+--------------------------+-----------------+---------------+ +| greptime | information_schema | columns | character_maximum_length | bigint | FIELD | +| greptime | information_schema | columns | character_octet_length | bigint | FIELD | +| greptime | information_schema | columns | character_set_name | string | FIELD | +| greptime | information_schema | columns | collation_name | string | FIELD | +| greptime | information_schema | columns | column_comment | string | FIELD | +| greptime | information_schema | columns | column_default | string | FIELD | +| greptime | information_schema | columns | column_key | string | FIELD | +| greptime | information_schema | columns | column_name | string | FIELD | +| greptime | information_schema | columns | column_type | string | FIELD | +| greptime | information_schema | columns | data_type | string | FIELD | +| greptime | information_schema | columns | datetime_precision | bigint | FIELD | +| greptime | information_schema | columns | extra | string | FIELD | +| greptime | information_schema | columns | generation_expression | string | FIELD | +| greptime | information_schema | columns | greptime_data_type | string | FIELD | +| greptime | information_schema | columns | is_nullable | string | FIELD | +| greptime | information_schema | columns | numeric_precision | bigint | FIELD | +| greptime | information_schema | columns | numeric_scale | bigint | FIELD | +| greptime | information_schema | columns | ordinal_position | bigint | FIELD | +| greptime | information_schema | columns | privileges | string | FIELD | +| greptime | information_schema | columns | semantic_type | string | FIELD | +| greptime | information_schema | columns | srs_id | bigint | FIELD | +| greptime | information_schema | columns | table_catalog | string | FIELD | +| greptime | information_schema | columns | table_name | string | FIELD | +| greptime | information_schema | columns | table_schema | string | FIELD | +| greptime | public | numbers | number | int unsigned | TAG | +| greptime | information_schema | tables | auto_increment | bigint unsigned | FIELD | +| greptime | information_schema | tables | avg_row_length | bigint unsigned | FIELD | +| greptime | information_schema | tables | check_time | datetime | FIELD | +| greptime | information_schema | tables | checksum | bigint unsigned | FIELD | +| greptime | information_schema | tables | create_options | string | FIELD | +| greptime | information_schema | tables | create_time | datetime | FIELD | +| greptime | information_schema | tables | data_free | bigint unsigned | FIELD | +| greptime | information_schema | tables | data_length | bigint unsigned | FIELD | +| greptime | information_schema | tables | engine | string | FIELD | +| greptime | information_schema | tables | index_length | bigint unsigned | FIELD | +| greptime | information_schema | tables | max_data_length | bigint unsigned | FIELD | +| greptime | information_schema | tables | max_index_length | bigint unsigned | FIELD | +| greptime | information_schema | tables | row_format | string | FIELD | +| greptime | information_schema | tables | table_catalog | string | FIELD | +| greptime | information_schema | tables | table_collation | string | FIELD | +| greptime | information_schema | tables | table_comment | string | FIELD | +| greptime | information_schema | tables | table_id | int unsigned | FIELD | +| greptime | information_schema | tables | table_name | string | FIELD | +| greptime | information_schema | tables | table_rows | bigint unsigned | FIELD | +| greptime | information_schema | tables | table_schema | string | FIELD | +| greptime | information_schema | tables | table_type | string | FIELD | +| greptime | information_schema | tables | temporary | string | FIELD | +| greptime | information_schema | tables | update_time | datetime | FIELD | +| greptime | information_schema | tables | version | bigint unsigned | FIELD | ++---------------+--------------------+------------+--------------------------+-----------------+---------------+"; check_output_stream(output, expected).await; let output = execute_sql_with(&instance, sql, query_ctx).await.data; let expected = "\ -+-----------------+--------------------+---------------+--------------------------+--------------+---------------+ -| table_catalog | table_schema | table_name | column_name | data_type | semantic_type | -+-----------------+--------------------+---------------+--------------------------+--------------+---------------+ -| another_catalog | another_schema | another_table | i | timestamp(3) | TIMESTAMP | -| another_catalog | information_schema | columns | character_maximum_length | bigint | FIELD | -| another_catalog | information_schema | columns | character_octet_length | bigint | FIELD | -| another_catalog | information_schema | columns | character_set_name | string | FIELD | -| another_catalog | information_schema | columns | collation_name | string | FIELD | -| another_catalog | information_schema | columns | column_comment | string | FIELD | -| another_catalog | information_schema | columns | column_default | string | FIELD | -| another_catalog | information_schema | columns | column_key | string | FIELD | -| another_catalog | information_schema | columns | column_name | string | FIELD | -| another_catalog | information_schema | columns | column_type | string | FIELD | -| another_catalog | information_schema | columns | data_type | string | FIELD | -| another_catalog | information_schema | columns | datetime_precision | bigint | FIELD | -| another_catalog | information_schema | columns | extra | string | FIELD | -| another_catalog | information_schema | columns | generation_expression | string | FIELD | -| another_catalog | information_schema | columns | greptime_data_type | string | FIELD | -| another_catalog | information_schema | columns | is_nullable | string | FIELD | -| another_catalog | information_schema | columns | numeric_precision | bigint | FIELD | -| another_catalog | information_schema | columns | numeric_scale | bigint | FIELD | -| another_catalog | information_schema | columns | ordinal_position | bigint | FIELD | -| another_catalog | information_schema | columns | privileges | string | FIELD | -| another_catalog | information_schema | columns | semantic_type | string | FIELD | -| another_catalog | information_schema | columns | srs_id | bigint | FIELD | -| another_catalog | information_schema | columns | table_catalog | string | FIELD | -| another_catalog | information_schema | columns | table_name | string | FIELD | -| another_catalog | information_schema | columns | table_schema | string | FIELD | -| another_catalog | information_schema | tables | engine | string | FIELD | -| another_catalog | information_schema | tables | table_catalog | string | FIELD | -| another_catalog | information_schema | tables | table_id | int unsigned | FIELD | -| another_catalog | information_schema | tables | table_name | string | FIELD | -| another_catalog | information_schema | tables | table_schema | string | FIELD | -| another_catalog | information_schema | tables | table_type | string | FIELD | -+-----------------+--------------------+---------------+--------------------------+--------------+---------------+"; ++-----------------+--------------------+---------------+--------------------------+-----------------+---------------+ +| table_catalog | table_schema | table_name | column_name | data_type | semantic_type | ++-----------------+--------------------+---------------+--------------------------+-----------------+---------------+ +| another_catalog | another_schema | another_table | i | timestamp(3) | TIMESTAMP | +| another_catalog | information_schema | columns | character_maximum_length | bigint | FIELD | +| another_catalog | information_schema | columns | character_octet_length | bigint | FIELD | +| another_catalog | information_schema | columns | character_set_name | string | FIELD | +| another_catalog | information_schema | columns | collation_name | string | FIELD | +| another_catalog | information_schema | columns | column_comment | string | FIELD | +| another_catalog | information_schema | columns | column_default | string | FIELD | +| another_catalog | information_schema | columns | column_key | string | FIELD | +| another_catalog | information_schema | columns | column_name | string | FIELD | +| another_catalog | information_schema | columns | column_type | string | FIELD | +| another_catalog | information_schema | columns | data_type | string | FIELD | +| another_catalog | information_schema | columns | datetime_precision | bigint | FIELD | +| another_catalog | information_schema | columns | extra | string | FIELD | +| another_catalog | information_schema | columns | generation_expression | string | FIELD | +| another_catalog | information_schema | columns | greptime_data_type | string | FIELD | +| another_catalog | information_schema | columns | is_nullable | string | FIELD | +| another_catalog | information_schema | columns | numeric_precision | bigint | FIELD | +| another_catalog | information_schema | columns | numeric_scale | bigint | FIELD | +| another_catalog | information_schema | columns | ordinal_position | bigint | FIELD | +| another_catalog | information_schema | columns | privileges | string | FIELD | +| another_catalog | information_schema | columns | semantic_type | string | FIELD | +| another_catalog | information_schema | columns | srs_id | bigint | FIELD | +| another_catalog | information_schema | columns | table_catalog | string | FIELD | +| another_catalog | information_schema | columns | table_name | string | FIELD | +| another_catalog | information_schema | columns | table_schema | string | FIELD | +| another_catalog | information_schema | tables | auto_increment | bigint unsigned | FIELD | +| another_catalog | information_schema | tables | avg_row_length | bigint unsigned | FIELD | +| another_catalog | information_schema | tables | check_time | datetime | FIELD | +| another_catalog | information_schema | tables | checksum | bigint unsigned | FIELD | +| another_catalog | information_schema | tables | create_options | string | FIELD | +| another_catalog | information_schema | tables | create_time | datetime | FIELD | +| another_catalog | information_schema | tables | data_free | bigint unsigned | FIELD | +| another_catalog | information_schema | tables | data_length | bigint unsigned | FIELD | +| another_catalog | information_schema | tables | engine | string | FIELD | +| another_catalog | information_schema | tables | index_length | bigint unsigned | FIELD | +| another_catalog | information_schema | tables | max_data_length | bigint unsigned | FIELD | +| another_catalog | information_schema | tables | max_index_length | bigint unsigned | FIELD | +| another_catalog | information_schema | tables | row_format | string | FIELD | +| another_catalog | information_schema | tables | table_catalog | string | FIELD | +| another_catalog | information_schema | tables | table_collation | string | FIELD | +| another_catalog | information_schema | tables | table_comment | string | FIELD | +| another_catalog | information_schema | tables | table_id | int unsigned | FIELD | +| another_catalog | information_schema | tables | table_name | string | FIELD | +| another_catalog | information_schema | tables | table_rows | bigint unsigned | FIELD | +| another_catalog | information_schema | tables | table_schema | string | FIELD | +| another_catalog | information_schema | tables | table_type | string | FIELD | +| another_catalog | information_schema | tables | temporary | string | FIELD | +| another_catalog | information_schema | tables | update_time | datetime | FIELD | +| another_catalog | information_schema | tables | version | bigint unsigned | FIELD | ++-----------------+--------------------+---------------+--------------------------+-----------------+---------------+"; check_output_stream(output, expected).await; } diff --git a/tests/cases/standalone/common/system/information_schema.result b/tests/cases/standalone/common/system/information_schema.result index 77077b9a3a0f..3f38df1c43ed 100644 --- a/tests/cases/standalone/common/system/information_schema.result +++ b/tests/cases/standalone/common/system/information_schema.result @@ -4,45 +4,46 @@ create database information_schema; Error: 1004(InvalidArguments), Schema information_schema already exists -- scripts table has different table ids in different modes +-- SQLNESS REPLACE (\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}) DATETIME select * from information_schema.tables where table_name != 'scripts' order by table_schema, table_name; -+---------------+--------------------+---------------------------------------+-----------------+----------+-------------+ -| table_catalog | table_schema | table_name | table_type | table_id | engine | -+---------------+--------------------+---------------------------------------+-----------------+----------+-------------+ -| greptime | information_schema | build_info | LOCAL TEMPORARY | 8 | | -| greptime | information_schema | character_sets | LOCAL TEMPORARY | 9 | | -| greptime | information_schema | check_constraints | LOCAL TEMPORARY | 12 | | -| greptime | information_schema | cluster_info | LOCAL TEMPORARY | 31 | | -| greptime | information_schema | collation_character_set_applicability | LOCAL TEMPORARY | 11 | | -| greptime | information_schema | collations | LOCAL TEMPORARY | 10 | | -| greptime | information_schema | column_privileges | LOCAL TEMPORARY | 6 | | -| greptime | information_schema | column_statistics | LOCAL TEMPORARY | 7 | | -| greptime | information_schema | columns | LOCAL TEMPORARY | 4 | | -| greptime | information_schema | engines | LOCAL TEMPORARY | 5 | | -| greptime | information_schema | events | LOCAL TEMPORARY | 13 | | -| greptime | information_schema | files | LOCAL TEMPORARY | 14 | | -| greptime | information_schema | global_status | LOCAL TEMPORARY | 25 | | -| greptime | information_schema | key_column_usage | LOCAL TEMPORARY | 16 | | -| greptime | information_schema | optimizer_trace | LOCAL TEMPORARY | 17 | | -| greptime | information_schema | parameters | LOCAL TEMPORARY | 18 | | -| greptime | information_schema | partitions | LOCAL TEMPORARY | 28 | | -| greptime | information_schema | profiling | LOCAL TEMPORARY | 19 | | -| greptime | information_schema | referential_constraints | LOCAL TEMPORARY | 20 | | -| greptime | information_schema | region_peers | LOCAL TEMPORARY | 29 | | -| greptime | information_schema | routines | LOCAL TEMPORARY | 21 | | -| greptime | information_schema | runtime_metrics | LOCAL TEMPORARY | 27 | | -| greptime | information_schema | schema_privileges | LOCAL TEMPORARY | 22 | | -| greptime | information_schema | schemata | LOCAL TEMPORARY | 15 | | -| greptime | information_schema | session_status | LOCAL TEMPORARY | 26 | | -| greptime | information_schema | table_constraints | LOCAL TEMPORARY | 30 | | -| greptime | information_schema | table_privileges | LOCAL TEMPORARY | 23 | | -| greptime | information_schema | tables | LOCAL TEMPORARY | 3 | | -| greptime | information_schema | triggers | LOCAL TEMPORARY | 24 | | -| greptime | public | numbers | LOCAL TEMPORARY | 2 | test_engine | -+---------------+--------------------+---------------------------------------+-----------------+----------+-------------+ ++---------------+--------------------+---------------------------------------+-----------------+----------+-------------+-----------------+--------------+------------------+----------------+-------------+---------+------------+------------+-----------+----------------+-------------------------+-------------+------------+-----------------+----------+----------------+---------------+-----------+ +| table_catalog | table_schema | table_name | table_type | table_id | data_length | max_data_length | index_length | max_index_length | avg_row_length | engine | version | row_format | table_rows | data_free | auto_increment | create_time | update_time | check_time | table_collation | checksum | create_options | table_comment | temporary | ++---------------+--------------------+---------------------------------------+-----------------+----------+-------------+-----------------+--------------+------------------+----------------+-------------+---------+------------+------------+-----------+----------------+-------------------------+-------------+------------+-----------------+----------+----------------+---------------+-----------+ +| greptime | information_schema | build_info | LOCAL TEMPORARY | 8 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | character_sets | LOCAL TEMPORARY | 9 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | check_constraints | LOCAL TEMPORARY | 12 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | cluster_info | LOCAL TEMPORARY | 31 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | collation_character_set_applicability | LOCAL TEMPORARY | 11 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | collations | LOCAL TEMPORARY | 10 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | column_privileges | LOCAL TEMPORARY | 6 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | column_statistics | LOCAL TEMPORARY | 7 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | columns | LOCAL TEMPORARY | 4 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | engines | LOCAL TEMPORARY | 5 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | events | LOCAL TEMPORARY | 13 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | files | LOCAL TEMPORARY | 14 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | global_status | LOCAL TEMPORARY | 25 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | key_column_usage | LOCAL TEMPORARY | 16 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | optimizer_trace | LOCAL TEMPORARY | 17 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | parameters | LOCAL TEMPORARY | 18 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | partitions | LOCAL TEMPORARY | 28 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | profiling | LOCAL TEMPORARY | 19 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | referential_constraints | LOCAL TEMPORARY | 20 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | region_peers | LOCAL TEMPORARY | 29 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | routines | LOCAL TEMPORARY | 21 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | runtime_metrics | LOCAL TEMPORARY | 27 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | schema_privileges | LOCAL TEMPORARY | 22 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | schemata | LOCAL TEMPORARY | 15 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | session_status | LOCAL TEMPORARY | 26 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | table_constraints | LOCAL TEMPORARY | 30 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | table_privileges | LOCAL TEMPORARY | 23 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | tables | LOCAL TEMPORARY | 3 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | information_schema | triggers | LOCAL TEMPORARY | 24 | 0 | 0 | 0 | 0 | 0 | | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | +| greptime | public | numbers | LOCAL TEMPORARY | 2 | 0 | 0 | 0 | 0 | 0 | test_engine | 11 | Fixed | 0 | 0 | 0 | DATETIME | | | | 0 | | | Y | ++---------------+--------------------+---------------------------------------+-----------------+----------+-------------+-----------------+--------------+------------------+----------------+-------------+---------+------------+------------+-----------+----------------+-------------------------+-------------+------------+-----------------+----------+----------------+---------------+-----------+ select * from information_schema.columns order by table_schema, table_name, column_name; @@ -340,12 +341,30 @@ select * from information_schema.columns order by table_schema, table_name, colu | greptime | information_schema | table_privileges | table_catalog | 2 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | No | string | | | | greptime | information_schema | table_privileges | table_name | 4 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | No | string | | | | greptime | information_schema | table_privileges | table_schema | 3 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | No | string | | | -| greptime | information_schema | tables | engine | 6 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | Yes | string | | | +| greptime | information_schema | tables | auto_increment | 16 | | | 20 | 0 | | | | | | select,insert | | UInt64 | bigint unsigned | FIELD | | Yes | bigint unsigned | | | +| greptime | information_schema | tables | avg_row_length | 10 | | | 20 | 0 | | | | | | select,insert | | UInt64 | bigint unsigned | FIELD | | Yes | bigint unsigned | | | +| greptime | information_schema | tables | check_time | 19 | | | | | 3 | | | | | select,insert | | DateTime | datetime | FIELD | | Yes | datetime | | | +| greptime | information_schema | tables | checksum | 21 | | | 20 | 0 | | | | | | select,insert | | UInt64 | bigint unsigned | FIELD | | Yes | bigint unsigned | | | +| greptime | information_schema | tables | create_options | 22 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | Yes | string | | | +| greptime | information_schema | tables | create_time | 17 | | | | | 3 | | | | | select,insert | | DateTime | datetime | FIELD | | Yes | datetime | | | +| greptime | information_schema | tables | data_free | 15 | | | 20 | 0 | | | | | | select,insert | | UInt64 | bigint unsigned | FIELD | | Yes | bigint unsigned | | | +| greptime | information_schema | tables | data_length | 6 | | | 20 | 0 | | | | | | select,insert | | UInt64 | bigint unsigned | FIELD | | Yes | bigint unsigned | | | +| greptime | information_schema | tables | engine | 11 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | Yes | string | | | +| greptime | information_schema | tables | index_length | 8 | | | 20 | 0 | | | | | | select,insert | | UInt64 | bigint unsigned | FIELD | | Yes | bigint unsigned | | | +| greptime | information_schema | tables | max_data_length | 7 | | | 20 | 0 | | | | | | select,insert | | UInt64 | bigint unsigned | FIELD | | Yes | bigint unsigned | | | +| greptime | information_schema | tables | max_index_length | 9 | | | 20 | 0 | | | | | | select,insert | | UInt64 | bigint unsigned | FIELD | | Yes | bigint unsigned | | | +| greptime | information_schema | tables | row_format | 13 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | Yes | string | | | | greptime | information_schema | tables | table_catalog | 1 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | No | string | | | +| greptime | information_schema | tables | table_collation | 20 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | Yes | string | | | +| greptime | information_schema | tables | table_comment | 23 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | Yes | string | | | | greptime | information_schema | tables | table_id | 5 | | | 10 | 0 | | | | | | select,insert | | UInt32 | int unsigned | FIELD | | Yes | int unsigned | | | | greptime | information_schema | tables | table_name | 3 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | No | string | | | +| greptime | information_schema | tables | table_rows | 14 | | | 20 | 0 | | | | | | select,insert | | UInt64 | bigint unsigned | FIELD | | Yes | bigint unsigned | | | | greptime | information_schema | tables | table_schema | 2 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | No | string | | | | greptime | information_schema | tables | table_type | 4 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | No | string | | | +| greptime | information_schema | tables | temporary | 24 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | Yes | string | | | +| greptime | information_schema | tables | update_time | 18 | | | | | 3 | | | | | select,insert | | DateTime | datetime | FIELD | | Yes | datetime | | | +| greptime | information_schema | tables | version | 12 | | | 20 | 0 | | | | | | select,insert | | UInt64 | bigint unsigned | FIELD | | Yes | bigint unsigned | | | | greptime | information_schema | triggers | action_condition | 9 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | No | string | | | | greptime | information_schema | triggers | action_order | 8 | | | 19 | 0 | | | | | | select,insert | | Int64 | bigint | FIELD | | No | bigint | | | | greptime | information_schema | triggers | action_orientation | 11 | 2147483647 | 2147483647 | | | | utf8 | utf8_bin | | | select,insert | | String | string | FIELD | | No | string | | | diff --git a/tests/cases/standalone/common/system/information_schema.sql b/tests/cases/standalone/common/system/information_schema.sql index 89db8514e5da..7be288c5eaa3 100644 --- a/tests/cases/standalone/common/system/information_schema.sql +++ b/tests/cases/standalone/common/system/information_schema.sql @@ -2,6 +2,7 @@ create database information_schema; -- scripts table has different table ids in different modes +-- SQLNESS REPLACE (\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}) DATETIME select * from information_schema.tables where table_name != 'scripts' diff --git a/tests/cases/standalone/common/view/create.result b/tests/cases/standalone/common/view/create.result index 855eb08bb7ed..bfbff6b970eb 100644 --- a/tests/cases/standalone/common/view/create.result +++ b/tests/cases/standalone/common/view/create.result @@ -70,53 +70,54 @@ SHOW FULL TABLES; +------------+------------+ -- SQLNESS REPLACE (\s\d+\s) ID +-- SQLNESS REPLACE (\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}) DATETIME SELECT * FROM INFORMATION_SCHEMA.TABLES ORDER BY TABLE_NAME, TABLE_TYPE; -+---------------+----------------------+---------------------------------------+-----------------+----------+-------------+ -| table_catalog | table_schema | table_name | table_type | table_id | engine | -+---------------+----------------------+---------------------------------------+-----------------+----------+-------------+ -| greptime | information_schema | build_info | LOCAL TEMPORARY |ID | | -| greptime | information_schema | character_sets | LOCAL TEMPORARY |ID | | -| greptime | information_schema | check_constraints | LOCAL TEMPORARY |ID | | -| greptime | information_schema | cluster_info | LOCAL TEMPORARY |ID | | -| greptime | information_schema | collation_character_set_applicability | LOCAL TEMPORARY |ID | | -| greptime | information_schema | collations | LOCAL TEMPORARY |ID | | -| greptime | information_schema | column_privileges | LOCAL TEMPORARY |ID | | -| greptime | information_schema | column_statistics | LOCAL TEMPORARY |ID | | -| greptime | information_schema | columns | LOCAL TEMPORARY |ID | | -| greptime | information_schema | engines | LOCAL TEMPORARY |ID | | -| greptime | information_schema | events | LOCAL TEMPORARY |ID | | -| greptime | information_schema | files | LOCAL TEMPORARY |ID | | -| greptime | information_schema | global_status | LOCAL TEMPORARY |ID | | -| greptime | information_schema | key_column_usage | LOCAL TEMPORARY |ID | | -| greptime | public | numbers | LOCAL TEMPORARY |ID | test_engine | -| greptime | information_schema | optimizer_trace | LOCAL TEMPORARY |ID | | -| greptime | information_schema | parameters | LOCAL TEMPORARY |ID | | -| greptime | information_schema | partitions | LOCAL TEMPORARY |ID | | -| greptime | information_schema | profiling | LOCAL TEMPORARY |ID | | -| greptime | information_schema | referential_constraints | LOCAL TEMPORARY |ID | | -| greptime | information_schema | region_peers | LOCAL TEMPORARY |ID | | -| greptime | information_schema | routines | LOCAL TEMPORARY |ID | | -| greptime | information_schema | runtime_metrics | LOCAL TEMPORARY |ID | | -| greptime | information_schema | schema_privileges | LOCAL TEMPORARY |ID | | -| greptime | information_schema | schemata | LOCAL TEMPORARY |ID | | -| greptime | information_schema | session_status | LOCAL TEMPORARY |ID | | -| greptime | information_schema | table_constraints | LOCAL TEMPORARY |ID | | -| greptime | information_schema | table_privileges | LOCAL TEMPORARY |ID | | -| greptime | information_schema | tables | LOCAL TEMPORARY |ID | | -| greptime | schema_for_view_test | test_table | BASE TABLE |ID | mito | -| greptime | schema_for_view_test | test_view | VIEW |ID | | -| greptime | information_schema | triggers | LOCAL TEMPORARY |ID | | -+---------------+----------------------+---------------------------------------+-----------------+----------+-------------+ ++---------------+----------------------+---------------------------------------+-----------------+----------+-------------+-----------------+--------------+------------------+----------------+-------------+---------+------------+------------+-----------+----------------+-------------------------+-------------+------------+-----------------+----------+----------------+---------------+-----------+ +| table_catalog | table_schema | table_name | table_type | table_id | data_length | max_data_length | index_length | max_index_length | avg_row_length | engine | version | row_format | table_rows | data_free | auto_increment | create_time | update_time | check_time | table_collation | checksum | create_options | table_comment | temporary | ++---------------+----------------------+---------------------------------------+-----------------+----------+-------------+-----------------+--------------+------------------+----------------+-------------+---------+------------+------------+-----------+----------------+-------------------------+-------------+------------+-----------------+----------+----------------+---------------+-----------+ +| greptime | information_schema | build_info | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | character_sets | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | check_constraints | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | cluster_info | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | collation_character_set_applicability | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | collations | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | column_privileges | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | column_statistics | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | columns | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | engines | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | events | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | files | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | global_status | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | key_column_usage | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | public | numbers | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | test_engine |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | optimizer_trace | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | parameters | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | partitions | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | profiling | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | referential_constraints | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | region_peers | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | routines | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | runtime_metrics | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | schema_privileges | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | schemata | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | session_status | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | table_constraints | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | table_privileges | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | information_schema | tables | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | +| greptime | schema_for_view_test | test_table | BASE TABLE |ID |ID |ID |ID |ID |ID | mito |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | N | +| greptime | schema_for_view_test | test_view | VIEW |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | 1970-01-01T00:00:00 | | | |ID | | | N | +| greptime | information_schema | triggers | LOCAL TEMPORARY |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | DATETIME | | | |ID | | | Y | ++---------------+----------------------+---------------------------------------+-----------------+----------+-------------+-----------------+--------------+------------------+----------------+-------------+---------+------------+------------+-----------+----------------+-------------------------+-------------+------------+-----------------+----------+----------------+---------------+-----------+ -- SQLNESS REPLACE (\s\d+\s) ID SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'VIEW'; -+---------------+----------------------+------------+------------+----------+--------+ -| table_catalog | table_schema | table_name | table_type | table_id | engine | -+---------------+----------------------+------------+------------+----------+--------+ -| greptime | schema_for_view_test | test_view | VIEW |ID | | -+---------------+----------------------+------------+------------+----------+--------+ ++---------------+----------------------+------------+------------+----------+-------------+-----------------+--------------+------------------+----------------+--------+---------+------------+------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+-----------+ +| table_catalog | table_schema | table_name | table_type | table_id | data_length | max_data_length | index_length | max_index_length | avg_row_length | engine | version | row_format | table_rows | data_free | auto_increment | create_time | update_time | check_time | table_collation | checksum | create_options | table_comment | temporary | ++---------------+----------------------+------------+------------+----------+-------------+-----------------+--------------+------------------+----------------+--------+---------+------------+------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+-----------+ +| greptime | schema_for_view_test | test_view | VIEW |ID |ID |ID |ID |ID |ID | |ID | Fixed |ID |ID |ID | 1970-01-01T00:00:00 | | | |ID | | | N | ++---------------+----------------------+------------+------------+----------+-------------+-----------------+--------------+------------------+----------------+--------+---------+------------+------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+-----------+ SHOW COLUMNS FROM test_view; diff --git a/tests/cases/standalone/common/view/create.sql b/tests/cases/standalone/common/view/create.sql index a778180939a8..c4d1a57b5fcb 100644 --- a/tests/cases/standalone/common/view/create.sql +++ b/tests/cases/standalone/common/view/create.sql @@ -33,6 +33,7 @@ SHOW TABLES; SHOW FULL TABLES; -- SQLNESS REPLACE (\s\d+\s) ID +-- SQLNESS REPLACE (\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}) DATETIME SELECT * FROM INFORMATION_SCHEMA.TABLES ORDER BY TABLE_NAME, TABLE_TYPE; -- SQLNESS REPLACE (\s\d+\s) ID