feat(catalog): add public-global information schema scope (#9957)

Signed-off-by: shuiyisong <xixing.sys@gmail.com>
This commit is contained in:
shuiyisong
2026-10-26 07:23:30 +00:00
committed by GitHub
parent e87573e286
commit 513b9cee58
8 changed files with 117 additions and 72 deletions
@@ -139,7 +139,7 @@ lazy_static! {
}
macro_rules! setup_memory_table {
($name: expr) => {
($name: expr, $scope: ident) => {
paste! {
{
let (schema, columns) = get_schema_columns($name);
@@ -147,7 +147,8 @@ macro_rules! setup_memory_table {
consts::[<INFORMATION_SCHEMA_ $name _TABLE_ID>],
$name,
schema,
columns
columns,
InformationSchemaTableScope::$scope
)) as _)
}
}
@@ -165,7 +166,9 @@ pub struct MakeInformationTableRequest {
pub enum InformationSchemaTableScope {
/// Every query is filtered to the catalog supplied when constructing the provider.
Catalog,
/// The table contains catalog-independent or shared data, including compatibility stubs.
/// Catalog-independent data that is safe for authenticated non-admin users to read.
PublicGlobal,
/// Shared data without a non-admin visibility guarantee, including compatibility stubs.
Global,
}
@@ -173,6 +176,7 @@ impl InformationSchemaTableScope {
pub const fn as_str(self) -> &'static str {
match self {
Self::Catalog => "catalog",
Self::PublicGlobal => "public_global",
Self::Global => "global",
}
}
@@ -228,30 +232,30 @@ impl InformationSchemaProvider {
self.catalog_name.clone(),
self.catalog_manager.clone(),
)) as _),
ENGINES => setup_memory_table!(ENGINES),
COLUMN_PRIVILEGES => setup_memory_table!(COLUMN_PRIVILEGES),
COLUMN_STATISTICS => setup_memory_table!(COLUMN_STATISTICS),
BUILD_INFO => setup_memory_table!(BUILD_INFO),
CHARACTER_SETS => setup_memory_table!(CHARACTER_SETS),
COLLATIONS => setup_memory_table!(COLLATIONS),
ENGINES => setup_memory_table!(ENGINES, PublicGlobal),
COLUMN_PRIVILEGES => setup_memory_table!(COLUMN_PRIVILEGES, Global),
COLUMN_STATISTICS => setup_memory_table!(COLUMN_STATISTICS, Global),
BUILD_INFO => setup_memory_table!(BUILD_INFO, PublicGlobal),
CHARACTER_SETS => setup_memory_table!(CHARACTER_SETS, PublicGlobal),
COLLATIONS => setup_memory_table!(COLLATIONS, PublicGlobal),
COLLATION_CHARACTER_SET_APPLICABILITY => {
setup_memory_table!(COLLATION_CHARACTER_SET_APPLICABILITY)
setup_memory_table!(COLLATION_CHARACTER_SET_APPLICABILITY, PublicGlobal)
}
CHECK_CONSTRAINTS => setup_memory_table!(CHECK_CONSTRAINTS),
EVENTS => setup_memory_table!(EVENTS),
FILES => setup_memory_table!(FILES),
OPTIMIZER_TRACE => setup_memory_table!(OPTIMIZER_TRACE),
PARAMETERS => setup_memory_table!(PARAMETERS),
PROFILING => setup_memory_table!(PROFILING),
REFERENTIAL_CONSTRAINTS => setup_memory_table!(REFERENTIAL_CONSTRAINTS),
ROUTINES => setup_memory_table!(ROUTINES),
SCHEMA_PRIVILEGES => setup_memory_table!(SCHEMA_PRIVILEGES),
TABLE_PRIVILEGES => setup_memory_table!(TABLE_PRIVILEGES),
GLOBAL_STATUS => setup_memory_table!(GLOBAL_STATUS),
SESSION_STATUS => setup_memory_table!(SESSION_STATUS),
PLUGINS => setup_memory_table!(PLUGINS),
USER_PRIVILEGES => setup_memory_table!(USER_PRIVILEGES),
PROCESSLIST => setup_memory_table!(PROCESSLIST),
CHECK_CONSTRAINTS => setup_memory_table!(CHECK_CONSTRAINTS, Global),
EVENTS => setup_memory_table!(EVENTS, Global),
FILES => setup_memory_table!(FILES, Global),
OPTIMIZER_TRACE => setup_memory_table!(OPTIMIZER_TRACE, Global),
PARAMETERS => setup_memory_table!(PARAMETERS, Global),
PROFILING => setup_memory_table!(PROFILING, Global),
REFERENTIAL_CONSTRAINTS => setup_memory_table!(REFERENTIAL_CONSTRAINTS, Global),
ROUTINES => setup_memory_table!(ROUTINES, Global),
SCHEMA_PRIVILEGES => setup_memory_table!(SCHEMA_PRIVILEGES, Global),
TABLE_PRIVILEGES => setup_memory_table!(TABLE_PRIVILEGES, Global),
GLOBAL_STATUS => setup_memory_table!(GLOBAL_STATUS, Global),
SESSION_STATUS => setup_memory_table!(SESSION_STATUS, Global),
PLUGINS => setup_memory_table!(PLUGINS, Global),
USER_PRIVILEGES => setup_memory_table!(USER_PRIVILEGES, Global),
PROCESSLIST => setup_memory_table!(PROCESSLIST, Global),
KEY_COLUMN_USAGE => Some(Arc::new(InformationSchemaKeyColumnUsage::new(
self.catalog_name.clone(),
self.catalog_manager.clone(),
@@ -374,7 +378,6 @@ impl InformationSchemaProvider {
// Only put these tables under `greptime` catalog to prevent info leak.
if self.catalog_name == DEFAULT_CATALOG_NAME {
table_names.extend([
BUILD_INFO,
REGION_PEERS,
CLUSTER_INFO,
PROCEDURE_INFO,
@@ -387,6 +390,7 @@ impl InformationSchemaProvider {
}
table_names.extend([
BUILD_INFO,
TABLES,
VIEWS,
SCHEMATA,
@@ -605,14 +609,15 @@ mod tests {
#[test]
fn every_registered_information_schema_table_has_scope() {
use InformationSchemaTableScope::{Catalog, Global};
use InformationSchemaTableScope::{Catalog, Global, PublicGlobal};
let manager: Arc<dyn CatalogManager> = MemoryCatalogManager::new();
let backend = Arc::new(MemoryKvBackend::default());
let factories: HashMap<_, InformationSchemaTableFactoryRef> = [
("future_catalog_table", Catalog),
("future_global_table", Global),
(ENGINES, Catalog),
("future_public_table", PublicGlobal),
(BUILD_INFO, Global),
]
.into_iter()
.map(|(name, scope)| {
@@ -638,7 +643,13 @@ mod tests {
#[cfg(feature = "enterprise")]
RECYCLE_BIN,
"future_catalog_table",
];
let public_global_tables = [
ENGINES,
CHARACTER_SETS,
COLLATIONS,
COLLATION_CHARACTER_SET_APPLICABILITY,
"future_public_table",
];
for (catalog, with_process_manager) in [
@@ -654,31 +665,42 @@ mod tests {
with_process_manager.then(|| Arc::new(ProcessManager::new(String::new(), None))),
backend.clone(),
);
assert_eq!(
provider
.table(ENGINES)
.unwrap()
.table_info()
.meta
.options
.extra_options
.get(SEMANTIC_TABLE_SCOPE)
.map(String::as_str),
Some(Global.as_str()),
);
for name in [
BUILD_INFO,
ENGINES,
CHARACTER_SETS,
COLLATIONS,
COLLATION_CHARACTER_SET_APPLICABILITY,
] {
assert_eq!(
provider
.table(name)
.unwrap()
.table_info()
.meta
.options
.extra_options
.get(SEMANTIC_TABLE_SCOPE)
.map(String::as_str),
Some(PublicGlobal.as_str()),
"{catalog}.{name}"
);
}
// An extension replacing a built-in supplies the replacement table's scope.
let provider = provider.with_extra_table_factories(factories.clone());
let expected_count =
43 + usize::from(with_process_manager) + usize::from(cfg!(feature = "enterprise"))
44 + usize::from(with_process_manager) + usize::from(cfg!(feature = "enterprise"))
- if catalog == DEFAULT_CATALOG_NAME {
0
} else {
9
8
};
assert_eq!(provider.tables().len(), expected_count);
for (name, table) in provider.tables() {
let scope = if catalog_tables.contains(&name.as_str()) {
Catalog
} else if public_global_tables.contains(&name.as_str()) {
PublicGlobal
} else {
Global
};
+12 -2
View File
@@ -40,6 +40,7 @@ pub(crate) struct MemoryTable {
pub(crate) table_name: &'static str,
pub(crate) schema: SchemaRef,
pub(crate) columns: Vec<VectorRef>,
scope: InformationSchemaTableScope,
}
impl MemoryTable {
@@ -49,12 +50,14 @@ impl MemoryTable {
table_name: &'static str,
schema: SchemaRef,
columns: Vec<VectorRef>,
scope: InformationSchemaTableScope,
) -> Self {
Self {
table_id,
table_name,
schema,
columns,
scope,
}
}
@@ -107,7 +110,7 @@ impl DfPartitionStream for MemoryTable {
impl InformationTable for MemoryTable {
fn scope(&self) -> InformationSchemaTableScope {
InformationSchemaTableScope::Global
self.scope
}
}
@@ -172,6 +175,7 @@ mod tests {
Arc::new(StringVector::from(vec!["a1", "a2"])),
Arc::new(StringVector::from(vec!["b1", "b2"])),
],
InformationSchemaTableScope::Global,
);
assert_eq!(42, table.table_id());
@@ -201,7 +205,13 @@ mod tests {
ColumnSchema::new("b", ConcreteDataType::string_datatype(), false),
]));
let table = MemoryTable::new(42, "test", schema.clone(), vec![]);
let table = MemoryTable::new(
42,
"test",
schema.clone(),
vec![],
InformationSchemaTableScope::Global,
);
assert_eq!(42, table.table_id());
assert_eq!("test", table.table_name());
+8 -3
View File
@@ -50,8 +50,9 @@ pub const SEMANTIC_PER_TABLE_INDEX_KEY: &str = "greptime.internal.semantic.per_t
// ---- Common keys (all signals) ----
/// Information-schema visibility: `catalog` for providers that filter rows to
/// their catalog, or `global` for catalog-independent data. Only registered
/// system-table metadata is trusted for authorization.
/// their catalog, `public_global` for shared data safe for non-admin reads, or
/// `global` for shared data without that guarantee. Only registered system-table
/// metadata is trusted for authorization.
pub const SEMANTIC_TABLE_SCOPE: &str = "greptime.semantic.table_scope";
/// Signal kind: one of [`SIGNAL_TYPE_TRACE`] / [`SIGNAL_TYPE_LOG`] /
@@ -288,7 +289,7 @@ pub fn validate_semantic_option(key: &str, value: &str) -> bool {
return !value.is_empty() && value.split(',').all(|column| !column.trim().is_empty());
}
match key {
SEMANTIC_TABLE_SCOPE => matches!(value, "catalog" | "global"),
SEMANTIC_TABLE_SCOPE => matches!(value, "catalog" | "public_global" | "global"),
SEMANTIC_PIPELINE
| SEMANTIC_SOURCE_VERSION
| SEMANTIC_METRIC_UNIT
@@ -412,6 +413,10 @@ mod tests {
fn test_validate_semantic_option() {
// Enum keys reject out-of-domain values.
assert!(validate_semantic_option(SEMANTIC_TABLE_SCOPE, "catalog"));
assert!(validate_semantic_option(
SEMANTIC_TABLE_SCOPE,
"public_global"
));
assert!(validate_semantic_option(SEMANTIC_TABLE_SCOPE, "global"));
assert!(!validate_semantic_option(SEMANTIC_TABLE_SCOPE, "cluster"));
assert!(!validate_semantic_option(SEMANTIC_TABLE_SCOPE, "unknown"));
@@ -68,17 +68,23 @@ ORDER BY table_name;
SELECT table_name, semantic_options
FROM information_schema.table_semantics
WHERE table_schema = 'information_schema'
AND table_name IN ('build_info', 'partitions', 'process_list', 'table_semantics')
AND table_name IN ('build_info', 'engines', 'character_sets', 'collations',
'collation_character_set_applicability', 'partitions',
'process_list', 'table_semantics')
ORDER BY table_name;
+-----------------+---------------------------+
| table_name | semantic_options |
+-----------------+---------------------------+
| build_info | {"table_scope":"global"} |
| partitions | {"table_scope":"catalog"} |
| process_list | {"table_scope":"global"} |
| table_semantics | {"table_scope":"catalog"} |
+-----------------+---------------------------+
+---------------------------------------+---------------------------------+
| table_name | semantic_options |
+---------------------------------------+---------------------------------+
| build_info | {"table_scope":"public_global"} |
| character_sets | {"table_scope":"public_global"} |
| collation_character_set_applicability | {"table_scope":"public_global"} |
| collations | {"table_scope":"public_global"} |
| engines | {"table_scope":"public_global"} |
| partitions | {"table_scope":"catalog"} |
| process_list | {"table_scope":"global"} |
| table_semantics | {"table_scope":"catalog"} |
+---------------------------------------+---------------------------------+
-- Predicate pushdown on a promoted column.
SELECT table_name, signal_type
@@ -39,7 +39,9 @@ ORDER BY table_name;
SELECT table_name, semantic_options
FROM information_schema.table_semantics
WHERE table_schema = 'information_schema'
AND table_name IN ('build_info', 'partitions', 'process_list', 'table_semantics')
AND table_name IN ('build_info', 'engines', 'character_sets', 'collations',
'collation_character_set_applicability', 'partitions',
'process_list', 'table_semantics')
ORDER BY table_name;
-- Predicate pushdown on a promoted column.
@@ -135,16 +135,16 @@ SHOW TABLE STATUS;
+++++++++++++++++++
|Name|Engine|Version|Row_format|Rows|Avg_row_length|Data_length|Max_data_length|Index_length|Data_free|Auto_increment|Create_time|Update_time|Check_time|Collation|Checksum|Create_options|Comment|
+++++++++++++++++++
|build_info||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||
|character_sets||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||
|build_info||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=public_global||
|character_sets||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=public_global||
|check_constraints||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||
|cluster_info||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||
|collation_character_set_applicability||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||
|collations||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||
|collation_character_set_applicability||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=public_global||
|collations||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=public_global||
|column_privileges||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||
|column_statistics||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||
|columns||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=catalog||
|engines||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||
|engines||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=public_global||
|events||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||
|files||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||
|flow_statistics||11|Fixed|0|0|0|0|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=catalog||
@@ -15,16 +15,16 @@ order by table_schema, table_name;
+++++++++++++++++++++++++
|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|LOCALTEMPORARY|8|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|character_sets|LOCALTEMPORARY|9|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|build_info|LOCALTEMPORARY|8|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=public_global||Y|
|greptime|information_schema|character_sets|LOCALTEMPORARY|9|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=public_global||Y|
|greptime|information_schema|check_constraints|LOCALTEMPORARY|12|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|cluster_info|LOCALTEMPORARY|31|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|collation_character_set_applicability|LOCALTEMPORARY|11|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|collations|LOCALTEMPORARY|10|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|collation_character_set_applicability|LOCALTEMPORARY|11|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=public_global||Y|
|greptime|information_schema|collations|LOCALTEMPORARY|10|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=public_global||Y|
|greptime|information_schema|column_privileges|LOCALTEMPORARY|6|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|column_statistics|LOCALTEMPORARY|7|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|columns|LOCALTEMPORARY|4|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=catalog||Y|
|greptime|information_schema|engines|LOCALTEMPORARY|5|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|engines|LOCALTEMPORARY|5|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=public_global||Y|
|greptime|information_schema|events|LOCALTEMPORARY|13|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|files|LOCALTEMPORARY|14|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|flow_statistics|LOCALTEMPORARY|45|0|0|0|0|0||11|Fixed|0|0|0|DATETIME|DATETIME||utf8_bin|0|greptime.semantic.table_scope=catalog||Y|
@@ -96,16 +96,16 @@ ORDER BY TABLE_NAME, TABLE_TYPE;
+++++++++++++++++++++++++
|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|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|character_sets|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|build_info|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=public_global||Y|
|greptime|information_schema|character_sets|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=public_global||Y|
|greptime|information_schema|check_constraints|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|cluster_info|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|collation_character_set_applicability|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|collations|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|collation_character_set_applicability|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=public_global||Y|
|greptime|information_schema|collations|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=public_global||Y|
|greptime|information_schema|column_privileges|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|column_statistics|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|columns|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=catalog||Y|
|greptime|information_schema|engines|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|engines|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=public_global||Y|
|greptime|information_schema|events|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|files|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=global||Y|
|greptime|information_schema|flow_statistics|LOCALTEMPORARY|ID|ID|ID|ID|ID|ID||ID|Fixed|ID|ID|ID|DATETIME|DATETIME||utf8_bin|ID|greptime.semantic.table_scope=catalog||Y|