Copilot commented on code in PR #10793:
URL: https://github.com/apache/gravitino/pull/10793#discussion_r3129699078


##########
scripts/h2/schema-1.3.0-h2.sql:
##########
@@ -0,0 +1,564 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file--
+--  distributed with this work for additional information

Review Comment:
   The Apache license header line appears to have an extra "--" appended ("See 
the NOTICE file--"), which deviates from the standard ASF header text. Please 
fix the header to match the standard form.



##########
core/src/main/java/org/apache/gravitino/storage/relational/mapper/OwnerMetaMapper.java:
##########
@@ -95,4 +97,12 @@ void softDeleteOwnerRelByOwnerIdAndType(
       method = "deleteOwnerMetasByLegacyTimeline")
   Integer deleteOwnerMetasByLegacyTimeline(
       @Param("legacyTimeline") Long legacyTimeline, @Param("limit") int limit);
+
+  @SelectProvider(
+      type = OwnerMetaSQLProviderFactory.class,
+      method = "selectOwnerByMetadataObjectId")
+  OwnerInfo selectOwnerByMetadataObjectId(@Param("metadataObjectId") long 
metadataObjectId);

Review Comment:
   This mapper method exposes `selectOwnerByMetadataObjectId` without a 
`metadataObjectType` parameter, but IDs are not globally unique across entity 
types in the relational store. Exposing a type-less lookup can lead to 
incorrect owner resolution; consider changing the API to require 
`metadataObjectType` (and updating the SQL provider accordingly).



##########
core/src/main/java/org/apache/gravitino/storage/relational/po/auth/EntityChangeRecord.java:
##########
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.storage.relational.po.auth;
+
+/** Entity change poller result -- one row per entity_change_log entry. */
+public class EntityChangeRecord {
+  private String metalakeName;
+  private String entityType;
+  private String fullName;
+  private String operateType;
+  private long createdAt;
+

Review Comment:
   `EntityChangeRecord` does not include the table primary key (`id`). Without 
returning a stable unique key, consumers cannot safely page through 
`entity_change_log` when multiple rows share the same `created_at` (millisecond 
collisions) and a `LIMIT` is applied. Consider adding `id` to this record so 
polling can resume using a composite cursor like `(created_at, id)`.



##########
scripts/mysql/upgrade-1.2.0-to-1.3.0-mysql.sql:
##########
@@ -0,0 +1,86 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"). You may not use this file except in compliance
+-- with the License.  You may obtain a copy of the License at
+--
+--  http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied.  See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+--
+
+-- Role privilege tracking (strong consistency -- Step 3 version check)
+ALTER TABLE `role_meta`
+    ADD COLUMN `updated_at` BIGINT NOT NULL DEFAULT 0
+    COMMENT 'Set to currentTimeMillis() on any privilege grant/revoke for this 
role.
+             JcasbinAuthorizer compares db.updated_at vs cached updated_at per 
request
+             to decide whether to reload JCasbin policies for this role.';
+
+-- User role assignment tracking (strong consistency -- Step 1a version check)
+ALTER TABLE `user_meta`
+    ADD COLUMN `updated_at` BIGINT NOT NULL DEFAULT 0
+    COMMENT 'Set to currentTimeMillis() on any role assign/revoke for this 
user.
+             JcasbinAuthorizer compares db.updated_at vs cached updated_at per 
request
+             to decide whether to reload the user-role mapping.';
+
+-- Group role assignment tracking (strong consistency -- Step 1b version check)
+ALTER TABLE `group_meta`
+    ADD COLUMN `updated_at` BIGINT NOT NULL DEFAULT 0
+    COMMENT 'Set to currentTimeMillis() on any role assign/revoke for this 
group.
+             JcasbinAuthorizer compares db.updated_at vs cached updated_at per 
request
+             to decide whether to reload the group-role mapping.';
+
+-- Ownership mutation tracking (eventual consistency -- owner change poller)
+ALTER TABLE `owner_meta`
+    ADD COLUMN `updated_at` BIGINT NOT NULL DEFAULT 0
+    COMMENT 'Set to currentTimeMillis() on any ownership transfer.
+             The owner change poller reads updated_at > maxSeen to find 
changed rows
+             and invalidates only the specific metadataObjectIds in 
ownerRelCache.';
+
+-- Covering indexes for high-frequency read predicates
+CREATE INDEX idx_user_meta_name_del_upd
+    ON user_meta (metalake_id, user_name, deleted_at, updated_at);
+CREATE INDEX idx_group_meta_del_upd
+    ON group_meta (group_id, deleted_at, updated_at);
+CREATE INDEX idx_role_meta_del_upd
+    ON role_meta (role_id, deleted_at, updated_at);
+CREATE INDEX idx_owner_meta_obj_del_upd
+    ON owner_meta (metadata_object_id, deleted_at, updated_at);
+CREATE INDEX idx_owner_meta_del_upd_obj
+    ON owner_meta (deleted_at, updated_at, metadata_object_id);
+
+-- Backfill: set updated_at = audit_info-extracted time (use 1 as safe default 
for existing rows)
+UPDATE `role_meta`  SET `updated_at` = 1 WHERE `updated_at` = 0 AND 
`deleted_at` = 0;
+UPDATE `user_meta`  SET `updated_at` = 1 WHERE `updated_at` = 0 AND 
`deleted_at` = 0;
+UPDATE `group_meta` SET `updated_at` = 1 WHERE `updated_at` = 0 AND 
`deleted_at` = 0;
+UPDATE `owner_meta` SET `updated_at` = 1 WHERE `updated_at` = 0 AND 
`deleted_at` = 0;

Review Comment:
   The comment says "Backfill: set updated_at = audit_info-extracted time" but 
the statement actually sets `updated_at = 1` for existing non-deleted rows. 
This is misleading for operators reading the upgrade script; please either 
adjust the comment to match the behavior or implement the stated extraction 
logic.



##########
scripts/h2/upgrade-1.2.0-to-1.3.0-h2.sql:
##########
@@ -0,0 +1,54 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file--
+--  distributed with this work for additional information

Review Comment:
   The Apache license header line appears to have an extra "--" appended ("See 
the NOTICE file--"), which deviates from the standard ASF header text. Please 
fix the header to match the standard form.



##########
scripts/postgresql/schema-1.3.0-postgresql.sql:
##########
@@ -0,0 +1,956 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+--  distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"). You may not use this file except in compliance
+-- with the License.  You may obtain a copy of the License at
+--
+--  http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied.  See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+--
+
+-- Note: Database and schema creation is not included in this script. Please 
create the database and
+-- schema before running this script. for example in psql:
+-- CREATE DATABASE example_db;
+-- \c example_db
+-- CREATE SCHEMA example_schema;
+-- set search_path to example_schema;
+
+CREATE TABLE IF NOT EXISTS metalake_meta (
+    metalake_id BIGINT NOT NULL,
+    metalake_name VARCHAR(128) NOT NULL,
+    metalake_comment VARCHAR(256) DEFAULT '',
+    properties TEXT DEFAULT NULL,
+    audit_info TEXT NOT NULL,
+    schema_version TEXT NOT NULL,
+    current_version INT NOT NULL DEFAULT 1,
+    last_version INT NOT NULL DEFAULT 1,
+    deleted_at BIGINT NOT NULL DEFAULT 0,
+    PRIMARY KEY (metalake_id),
+    UNIQUE (metalake_name, deleted_at)
+);
+COMMENT ON TABLE metalake_meta IS 'metalake metadata';
+
+COMMENT ON COLUMN metalake_meta.metalake_id IS 'metalake id';
+COMMENT ON COLUMN metalake_meta.metalake_name IS 'metalake name';
+COMMENT ON COLUMN metalake_meta.metalake_comment IS 'metalake comment';
+COMMENT ON COLUMN metalake_meta.properties IS 'metalake properties';
+COMMENT ON COLUMN metalake_meta.audit_info IS 'metalake audit info';
+COMMENT ON COLUMN metalake_meta.schema_version IS 'metalake schema version 
info';
+COMMENT ON COLUMN metalake_meta.current_version IS 'metalake current version';
+COMMENT ON COLUMN metalake_meta.last_version IS 'metalake last version';
+COMMENT ON COLUMN metalake_meta.deleted_at IS 'metalake deleted at';
+
+
+CREATE TABLE IF NOT EXISTS catalog_meta (
+    catalog_id BIGINT NOT NULL,
+    catalog_name VARCHAR(128) NOT NULL,
+    metalake_id BIGINT NOT NULL,
+    type VARCHAR(64) NOT NULL,
+    provider VARCHAR(64) NOT NULL,
+    catalog_comment VARCHAR(256) DEFAULT '',
+    properties TEXT DEFAULT NULL,
+    audit_info TEXT NOT NULL,
+    current_version INT NOT NULL DEFAULT 1,
+    last_version INT NOT NULL DEFAULT 1,
+    deleted_at BIGINT NOT NULL DEFAULT 0,
+    PRIMARY KEY (catalog_id),
+    UNIQUE (metalake_id, catalog_name, deleted_at)
+);
+
+COMMENT ON TABLE catalog_meta IS 'catalog metadata';
+
+COMMENT ON COLUMN catalog_meta.catalog_id IS 'catalog id';
+COMMENT ON COLUMN catalog_meta.catalog_name IS 'catalog name';
+COMMENT ON COLUMN catalog_meta.metalake_id IS 'metalake id';
+COMMENT ON COLUMN catalog_meta.type IS 'catalog type';
+COMMENT ON COLUMN catalog_meta.provider IS 'catalog provider';
+COMMENT ON COLUMN catalog_meta.catalog_comment IS 'catalog comment';
+COMMENT ON COLUMN catalog_meta.properties IS 'catalog properties';
+COMMENT ON COLUMN catalog_meta.audit_info IS 'catalog audit info';
+COMMENT ON COLUMN catalog_meta.current_version IS 'catalog current version';
+COMMENT ON COLUMN catalog_meta.last_version IS 'catalog last version';
+COMMENT ON COLUMN catalog_meta.deleted_at IS 'catalog deleted at';
+
+
+CREATE TABLE IF NOT EXISTS schema_meta (
+    schema_id BIGINT NOT NULL,
+    schema_name VARCHAR(128) NOT NULL,
+    metalake_id BIGINT NOT NULL,
+    catalog_id BIGINT NOT NULL,
+    schema_comment VARCHAR(256) DEFAULT '',
+    properties TEXT DEFAULT NULL,
+    audit_info TEXT NOT NULL,
+    current_version INT NOT NULL DEFAULT 1,
+    last_version INT NOT NULL DEFAULT 1,
+    deleted_at BIGINT NOT NULL DEFAULT 0,
+    PRIMARY KEY (schema_id),
+    UNIQUE (catalog_id, schema_name, deleted_at)
+);
+
+CREATE INDEX IF NOT EXISTS schema_meta_idx_metalake_id ON schema_meta 
(metalake_id);
+COMMENT ON TABLE schema_meta IS 'schema metadata';
+
+COMMENT ON COLUMN schema_meta.schema_id IS 'schema id';
+COMMENT ON COLUMN schema_meta.schema_name IS 'schema name';
+COMMENT ON COLUMN schema_meta.metalake_id IS 'metalake id';
+COMMENT ON COLUMN schema_meta.catalog_id IS 'catalog id';
+COMMENT ON COLUMN schema_meta.schema_comment IS 'schema comment';
+COMMENT ON COLUMN schema_meta.properties IS 'schema properties';
+COMMENT ON COLUMN schema_meta.audit_info IS 'schema audit info';
+COMMENT ON COLUMN schema_meta.current_version IS 'schema current version';
+COMMENT ON COLUMN schema_meta.last_version IS 'schema last version';
+COMMENT ON COLUMN schema_meta.deleted_at IS 'schema deleted at';
+
+
+CREATE TABLE IF NOT EXISTS table_meta (
+    table_id BIGINT NOT NULL,
+    table_name VARCHAR(128) NOT NULL,
+    metalake_id BIGINT NOT NULL,
+    catalog_id BIGINT NOT NULL,
+    schema_id BIGINT NOT NULL,
+    audit_info TEXT NOT NULL,
+    current_version INT NOT NULL DEFAULT 1,
+    last_version INT NOT NULL DEFAULT 1,
+    deleted_at BIGINT NOT NULL DEFAULT 0,
+    PRIMARY KEY (table_id),
+    UNIQUE (schema_id, table_name, deleted_at)
+);
+
+CREATE INDEX IF NOT EXISTS table_meta_idx_metalake_id ON table_meta 
(metalake_id);
+CREATE INDEX IF NOT EXISTS table_meta_idx_catalog_id ON table_meta 
(catalog_id);
+COMMENT ON TABLE table_meta IS 'table metadata';
+
+COMMENT ON COLUMN table_meta.table_id IS 'table id';
+COMMENT ON COLUMN table_meta.table_name IS 'table name';
+COMMENT ON COLUMN table_meta.metalake_id IS 'metalake id';
+COMMENT ON COLUMN table_meta.catalog_id IS 'catalog id';
+COMMENT ON COLUMN table_meta.schema_id IS 'schema id';
+COMMENT ON COLUMN table_meta.audit_info IS 'table audit info';
+COMMENT ON COLUMN table_meta.current_version IS 'table current version';
+COMMENT ON COLUMN table_meta.last_version IS 'table last version';
+COMMENT ON COLUMN table_meta.deleted_at IS 'table deleted at';
+
+CREATE TABLE IF NOT EXISTS table_column_version_info (
+    id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    metalake_id BIGINT NOT NULL,
+    catalog_id BIGINT NOT NULL,
+    schema_id BIGINT NOT NULL,
+    table_id BIGINT NOT NULL,
+    table_version INT NOT NULL,
+    column_id BIGINT NOT NULL,
+    column_name VARCHAR(128) NOT NULL,
+    column_position INT NOT NULL,
+    column_type TEXT NOT NULL,
+    column_comment VARCHAR(256) DEFAULT '',
+    column_nullable SMALLINT NOT NULL DEFAULT 1,
+    column_auto_increment SMALLINT NOT NULL DEFAULT 0,
+    column_default_value TEXT DEFAULT NULL,
+    column_op_type SMALLINT NOT NULL,
+    deleted_at BIGINT NOT NULL DEFAULT 0,
+    audit_info TEXT NOT NULL,
+    PRIMARY KEY (id),
+    UNIQUE (table_id, table_version, column_id, deleted_at)
+);
+CREATE INDEX table_column_version_info_idx_mid ON table_column_version_info 
(metalake_id);
+CREATE INDEX table_column_version_info_idx_cid ON table_column_version_info 
(catalog_id);
+CREATE INDEX table_column_version_info_idx_sid ON table_column_version_info 
(schema_id);
+COMMENT ON TABLE table_column_version_info IS 'table column version 
information';
+
+COMMENT ON COLUMN table_column_version_info.id IS 'auto increment id';
+COMMENT ON COLUMN table_column_version_info.metalake_id IS 'metalake id';
+COMMENT ON COLUMN table_column_version_info.catalog_id IS 'catalog id';
+COMMENT ON COLUMN table_column_version_info.schema_id IS 'schema id';
+COMMENT ON COLUMN table_column_version_info.table_id IS 'table id';
+COMMENT ON COLUMN table_column_version_info.table_version IS 'table version';
+COMMENT ON COLUMN table_column_version_info.column_id IS 'column id';
+COMMENT ON COLUMN table_column_version_info.column_name IS 'column name';
+COMMENT ON COLUMN table_column_version_info.column_position IS 'column 
position, starting from 0';
+COMMENT ON COLUMN table_column_version_info.column_type IS 'column type';
+COMMENT ON COLUMN table_column_version_info.column_comment IS 'column comment';
+COMMENT ON COLUMN table_column_version_info.column_nullable IS 'column 
nullable, 0 is not nullable, 1 is nullable';
+COMMENT ON COLUMN table_column_version_info.column_auto_increment IS 'column 
auto increment, 0 is not auto increment, 1 is auto increment';
+COMMENT ON COLUMN table_column_version_info.column_default_value IS 'column 
default value';
+COMMENT ON COLUMN table_column_version_info.column_op_type IS 'column 
operation type, 1 is create, 2 is update, 3 is delete';
+COMMENT ON COLUMN table_column_version_info.deleted_at IS 'column deleted at';
+COMMENT ON COLUMN table_column_version_info.audit_info IS 'column audit info';
+
+
+CREATE TABLE IF NOT EXISTS fileset_meta (
+    fileset_id BIGINT NOT NULL,
+    fileset_name VARCHAR(128) NOT NULL,
+    metalake_id BIGINT NOT NULL,
+    catalog_id BIGINT NOT NULL,
+    schema_id BIGINT NOT NULL,
+    type VARCHAR(64) NOT NULL,
+    audit_info TEXT NOT NULL,
+    current_version INT NOT NULL DEFAULT 1,
+    last_version INT NOT NULL DEFAULT 1,
+    deleted_at BIGINT NOT NULL DEFAULT 0,
+    PRIMARY KEY (fileset_id),
+    UNIQUE (schema_id, fileset_name, deleted_at)
+);
+
+CREATE INDEX IF NOT EXISTS fileset_meta_idx_metalake_id ON fileset_meta 
(metalake_id);
+CREATE INDEX IF NOT EXISTS fileset_meta_idx_catalog_id ON fileset_meta 
(catalog_id);
+COMMENT ON TABLE fileset_meta IS 'fileset metadata';
+
+COMMENT ON COLUMN fileset_meta.fileset_id IS 'fileset id';
+COMMENT ON COLUMN fileset_meta.fileset_name IS 'fileset name';
+COMMENT ON COLUMN fileset_meta.metalake_id IS 'metalake id';
+COMMENT ON COLUMN fileset_meta.catalog_id IS 'catalog id';
+COMMENT ON COLUMN fileset_meta.schema_id IS 'schema id';
+COMMENT ON COLUMN fileset_meta.type IS 'fileset type';
+COMMENT ON COLUMN fileset_meta.audit_info IS 'fileset audit info';
+COMMENT ON COLUMN fileset_meta.current_version IS 'fileset current version';
+COMMENT ON COLUMN fileset_meta.last_version IS 'fileset last version';
+COMMENT ON COLUMN fileset_meta.deleted_at IS 'fileset deleted at';
+
+
+CREATE TABLE IF NOT EXISTS fileset_version_info (
+    id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    metalake_id BIGINT NOT NULL,
+    catalog_id BIGINT NOT NULL,
+    schema_id BIGINT NOT NULL,
+    fileset_id BIGINT NOT NULL,
+    version INT NOT NULL,
+    fileset_comment VARCHAR(256) DEFAULT '',
+    properties TEXT DEFAULT NULL,
+    storage_location_name VARCHAR(256) NOT NULL DEFAULT 'default',
+    storage_location TEXT NOT NULL,
+    deleted_at BIGINT NOT NULL DEFAULT 0,
+    PRIMARY KEY (id),
+    UNIQUE (fileset_id, version, storage_location_name, deleted_at)
+);
+
+CREATE INDEX IF NOT EXISTS fileset_version_info_idx_metalake_id ON 
fileset_version_info (metalake_id);
+CREATE INDEX IF NOT EXISTS fileset_version_info_idx_idx_catalog_id ON 
fileset_version_info (catalog_id);
+CREATE INDEX IF NOT EXISTS fileset_version_info_idx_idx_schema_id ON 
fileset_version_info (schema_id);
+COMMENT ON TABLE fileset_version_info IS 'fileset version information';
+
+COMMENT ON COLUMN fileset_version_info.id IS 'auto increment id';
+COMMENT ON COLUMN fileset_version_info.metalake_id IS 'metalake id';
+COMMENT ON COLUMN fileset_version_info.catalog_id IS 'catalog id';
+COMMENT ON COLUMN fileset_version_info.schema_id IS 'schema id';
+COMMENT ON COLUMN fileset_version_info.fileset_id IS 'fileset id';
+COMMENT ON COLUMN fileset_version_info.version IS 'fileset info version';
+COMMENT ON COLUMN fileset_version_info.fileset_comment IS 'fileset comment';
+COMMENT ON COLUMN fileset_version_info.properties IS 'fileset properties';
+COMMENT ON COLUMN fileset_version_info.storage_location_name IS 'fileset 
storage location name';
+COMMENT ON COLUMN fileset_version_info.storage_location IS 'fileset storage 
location';
+COMMENT ON COLUMN fileset_version_info.deleted_at IS 'fileset deleted at';
+
+
+CREATE TABLE IF NOT EXISTS topic_meta (
+    topic_id BIGINT NOT NULL,
+    topic_name VARCHAR(128) NOT NULL,
+    metalake_id BIGINT NOT NULL,
+    catalog_id BIGINT NOT NULL,
+    schema_id BIGINT NOT NULL,
+    comment VARCHAR(256) DEFAULT '',
+    properties TEXT DEFAULT NULL,
+    audit_info TEXT NOT NULL,
+    current_version INT NOT NULL DEFAULT 1,
+    last_version INT NOT NULL DEFAULT 1,
+    deleted_at BIGINT NOT NULL DEFAULT 0,
+    PRIMARY KEY (topic_id),
+    UNIQUE (schema_id, topic_name, deleted_at)
+);
+
+CREATE INDEX IF NOT EXISTS topic_meta_idx_metalake_id ON topic_meta 
(metalake_id);
+CREATE INDEX IF NOT EXISTS topic_meta_idx_catalog_id ON topic_meta 
(catalog_id);
+COMMENT ON TABLE topic_meta IS 'topic metadata';
+
+COMMENT ON COLUMN topic_meta.topic_id IS 'topic id';
+COMMENT ON COLUMN topic_meta.topic_name IS 'topic name';
+COMMENT ON COLUMN topic_meta.metalake_id IS 'metalake id';
+COMMENT ON COLUMN topic_meta.catalog_id IS 'catalog id';
+COMMENT ON COLUMN topic_meta.schema_id IS 'schema id';
+COMMENT ON COLUMN topic_meta.comment IS 'topic comment';
+COMMENT ON COLUMN topic_meta.properties IS 'topic properties';
+COMMENT ON COLUMN topic_meta.audit_info IS 'topic audit info';
+COMMENT ON COLUMN topic_meta.current_version IS 'topic current version';
+COMMENT ON COLUMN topic_meta.last_version IS 'topic last version';
+COMMENT ON COLUMN topic_meta.deleted_at IS 'topic deleted at';
+
+
+CREATE TABLE IF NOT EXISTS user_meta (
+    user_id BIGINT NOT NULL,
+    user_name VARCHAR(128) NOT NULL,
+    metalake_id BIGINT NOT NULL,
+    audit_info TEXT NOT NULL,
+    current_version INT NOT NULL DEFAULT 1,
+    last_version INT NOT NULL DEFAULT 1,
+    deleted_at BIGINT NOT NULL DEFAULT 0,
+    updated_at BIGINT NOT NULL DEFAULT 0,
+    PRIMARY KEY (user_id),
+    UNIQUE (metalake_id, user_name, deleted_at)
+);

Review Comment:
   The 1.3.0 PostgreSQL schema script adds `updated_at` columns but does not 
create the new covering indexes (e.g., `idx_user_meta_name_del_upd`, 
`idx_group_meta_del_upd`, `idx_role_meta_del_upd`, 
`idx_owner_meta_obj_del_upd`) that the 1.2.0→1.3.0 upgrade script creates. 
Fresh installs on 1.3.0 will miss these indexes and can regress auth/cache read 
performance; please add the corresponding `CREATE INDEX IF NOT EXISTS ...` 
statements to the schema script.



##########
scripts/h2/schema-1.3.0-h2.sql:
##########
@@ -0,0 +1,564 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file--
+--  distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"). You may not use this file except in compliance
+-- with the License.  You may obtain a copy of the License at
+--
+--  http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied.  See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+--
+
+CREATE TABLE IF NOT EXISTS `metalake_meta` (
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `metalake_name` VARCHAR(128) NOT NULL COMMENT 'metalake name',
+    `metalake_comment` VARCHAR(256) DEFAULT '' COMMENT 'metalake comment',
+    `properties` CLOB DEFAULT NULL COMMENT 'metalake properties',
+    `audit_info` CLOB NOT NULL COMMENT 'metalake audit info',
+    `schema_version` CLOB NOT NULL COMMENT 'metalake schema version info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'metalake 
current version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'metalake last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'metalake 
deleted at',
+    PRIMARY KEY (metalake_id),
+    CONSTRAINT uk_mn_del UNIQUE (metalake_name, deleted_at)
+) ENGINE = InnoDB;
+
+
+CREATE TABLE IF NOT EXISTS `catalog_meta` (
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `catalog_name` VARCHAR(128) NOT NULL COMMENT 'catalog name',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `type` VARCHAR(64) NOT NULL COMMENT 'catalog type',
+    `provider` VARCHAR(64) NOT NULL COMMENT 'catalog provider',
+    `catalog_comment` VARCHAR(256) DEFAULT '' COMMENT 'catalog comment',
+    `properties` CLOB DEFAULT NULL COMMENT 'catalog properties',
+    `audit_info` CLOB NOT NULL COMMENT 'catalog audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'catalog current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'catalog last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'catalog 
deleted at',
+    PRIMARY KEY (catalog_id),
+    CONSTRAINT uk_mid_cn_del UNIQUE (metalake_id, catalog_name, deleted_at)
+) ENGINE=InnoDB;
+
+
+CREATE TABLE IF NOT EXISTS `schema_meta` (
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `schema_name` VARCHAR(128) NOT NULL COMMENT 'schema name',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_comment` VARCHAR(256) DEFAULT '' COMMENT 'schema comment',
+    `properties` CLOB DEFAULT NULL COMMENT 'schema properties',
+    `audit_info` CLOB NOT NULL COMMENT 'schema audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'schema current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'schema last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'schema 
deleted at',
+    PRIMARY KEY (schema_id),
+    CONSTRAINT uk_cid_sn_del UNIQUE (catalog_id, schema_name, deleted_at),
+    -- Aliases are used here, and indexes with the same name in H2 can only be 
created once.
+    KEY idx_smid (metalake_id)
+) ENGINE=InnoDB;
+
+CREATE TABLE IF NOT EXISTS `table_meta` (
+    `table_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'table id',
+    `table_name` VARCHAR(128) NOT NULL COMMENT 'table name',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `audit_info` CLOB NOT NULL COMMENT 'table audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'table current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'table last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'table deleted 
at',
+    PRIMARY KEY (table_id),
+    CONSTRAINT uk_sid_tn_del UNIQUE (schema_id, table_name, deleted_at),
+    -- Aliases are used here, and indexes with the same name in H2 can only be 
created once.
+    KEY idx_tmid (metalake_id),
+    KEY idx_tcid (catalog_id)
+) ENGINE=InnoDB;
+
+
+CREATE TABLE IF NOT EXISTS `table_column_version_info` (
+    `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'auto increment 
id',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `table_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'table id',
+    `table_version` INT UNSIGNED NOT NULL COMMENT 'table version',
+    `column_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'column id',
+    `column_name` VARCHAR(128) NOT NULL COMMENT 'column name',
+    `column_position` INT UNSIGNED NOT NULL COMMENT 'column position, starting 
from 0',
+    `column_type` CLOB NOT NULL COMMENT 'column type',
+    `column_comment` VARCHAR(256) DEFAULT '' COMMENT 'column comment',
+    `column_nullable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'column nullable, 
0 is not nullable, 1 is nullable',
+    `column_auto_increment` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'column auto 
increment, 0 is not auto increment, 1 is auto increment',
+    `column_default_value` CLOB DEFAULT NULL COMMENT 'column default value',
+    `column_op_type` TINYINT(1) NOT NULL COMMENT 'column operation type, 1 is 
create, 2 is update, 3 is delete',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'column 
deleted at',
+    `audit_info` CLOB NOT NULL COMMENT 'column audit info',
+    PRIMARY KEY (`id`),
+    UNIQUE KEY `uk_tid_ver_cid_del` (`table_id`, `table_version`, `column_id`, 
`deleted_at`),
+    KEY `idx_tcmid` (`metalake_id`),
+    KEY `idx_tccid` (`catalog_id`),
+    KEY `idx_tcsid` (`schema_id`)
+) ENGINE=InnoDB;
+
+
+CREATE TABLE IF NOT EXISTS `fileset_meta` (
+    `fileset_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'fileset id',
+    `fileset_name` VARCHAR(128) NOT NULL COMMENT 'fileset name',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `type` VARCHAR(64) NOT NULL COMMENT 'fileset type',
+    `audit_info` CLOB NOT NULL COMMENT 'fileset audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'fileset current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'fileset last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'fileset 
deleted at',
+    PRIMARY KEY (fileset_id),
+    CONSTRAINT uk_sid_fn_del UNIQUE (schema_id, fileset_name, deleted_at),
+    -- Aliases are used here, and indexes with the same name in H2 can only be 
created once.
+    KEY idx_fmid (metalake_id),
+    KEY idx_fcid (catalog_id)
+) ENGINE=InnoDB;
+
+
+CREATE TABLE IF NOT EXISTS `fileset_version_info` (
+    `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'auto increment 
id',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `fileset_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'fileset id',
+    `version` INT UNSIGNED NOT NULL COMMENT 'fileset info version',
+    `fileset_comment` VARCHAR(256) DEFAULT '' COMMENT 'fileset comment',
+    `properties` CLOB DEFAULT NULL COMMENT 'fileset properties',
+    `storage_location_name` VARCHAR(128) NOT NULL DEFAULT 'default' COMMENT 
'fileset storage location name',
+    `storage_location` CLOB DEFAULT NULL COMMENT 'fileset storage location',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'fileset 
deleted at',
+    PRIMARY KEY (id),
+    CONSTRAINT uk_fid_ver_del UNIQUE (fileset_id, version, 
storage_location_name, deleted_at),
+    -- Aliases are used here, and indexes with the same name in H2 can only be 
created once.
+    KEY idx_fvmid (metalake_id),
+    KEY idx_fvcid (catalog_id)
+) ENGINE=InnoDB;
+
+CREATE TABLE IF NOT EXISTS `topic_meta` (
+    `topic_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'topic id',
+    `topic_name` VARCHAR(128) NOT NULL COMMENT 'topic name',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `comment` VARCHAR(256) DEFAULT '' COMMENT 'topic comment',
+    `properties` CLOB DEFAULT NULL COMMENT 'topic properties',
+    `audit_info` CLOB NOT NULL COMMENT 'topic audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'topic current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'topic last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'topic deleted 
at',
+    PRIMARY KEY (topic_id),
+    CONSTRAINT uk_cid_tn_del UNIQUE (schema_id, topic_name, deleted_at),
+    -- Aliases are used here, and indexes with the same name in H2 can only be 
created once.
+    KEY idx_tvmid (metalake_id),
+    KEY idx_tvcid (catalog_id)
+) ENGINE=InnoDB;
+
+CREATE TABLE IF NOT EXISTS `user_meta` (
+    `user_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'user id',
+    `user_name` VARCHAR(128) NOT NULL COMMENT 'username',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `audit_info` CLOB NOT NULL COMMENT 'user audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'user current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'user last version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'user deleted 
at',
+    `updated_at` BIGINT NOT NULL DEFAULT 0 COMMENT 'updated_at',
+    PRIMARY KEY (`user_id`),
+    CONSTRAINT `uk_mid_us_del` UNIQUE (`metalake_id`, `user_name`, 
`deleted_at`)
+) ENGINE=InnoDB;

Review Comment:
   The 1.3.0 H2 schema script adds `updated_at` columns but does not create the 
covering indexes that the 1.2.0→1.3.0 upgrade script creates (e.g., 
`idx_user_meta_name_del_upd`, `idx_group_meta_del_upd`, 
`idx_role_meta_del_upd`, `idx_owner_meta_obj_del_upd`). This means fresh 
H2-backed test/dev installs on 1.3.0 won’t match the intended indexing; please 
add the missing index statements here too.



##########
scripts/mysql/schema-1.3.0-mysql.sql:
##########
@@ -0,0 +1,551 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file--
+--  distributed with this work for additional information

Review Comment:
   The Apache license header line appears to have an extra "--" appended ("See 
the NOTICE file--"), which deviates from the standard ASF header text. Please 
fix the header to match the standard form.



##########
core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/OwnerMetaBaseSQLProvider.java:
##########
@@ -236,4 +237,18 @@ public String deleteOwnerMetasByLegacyTimeline(
         + OWNER_TABLE_NAME
         + " WHERE deleted_at > 0 AND deleted_at < #{legacyTimeline} LIMIT 
#{limit}";
   }
+
+  public String selectOwnerByMetadataObjectId(@Param("metadataObjectId") long 
metadataObjectId) {
+    return "SELECT owner_id as ownerId, owner_type as ownerType FROM "
+        + OWNER_TABLE_NAME
+        + " WHERE metadata_object_id = #{metadataObjectId} AND deleted_at = 0"

Review Comment:
   `selectOwnerByMetadataObjectId` filters only by `metadata_object_id` and not 
`metadata_object_type`. In this codebase, entity IDs are per-entity-type (e.g., 
schema_id/table_id/view_id are independent), so the same numeric ID can exist 
for multiple types; this query can therefore return the wrong owner. Consider 
adding `metadataObjectType` to the mapper/provider method signature and 
including it in the WHERE clause (and updating callers) to ensure correctness.



##########
core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/OwnerMetaBaseSQLProvider.java:
##########
@@ -236,4 +237,18 @@ public String deleteOwnerMetasByLegacyTimeline(
         + OWNER_TABLE_NAME
         + " WHERE deleted_at > 0 AND deleted_at < #{legacyTimeline} LIMIT 
#{limit}";
   }
+
+  public String selectOwnerByMetadataObjectId(@Param("metadataObjectId") long 
metadataObjectId) {
+    return "SELECT owner_id as ownerId, owner_type as ownerType FROM "
+        + OWNER_TABLE_NAME
+        + " WHERE metadata_object_id = #{metadataObjectId} AND deleted_at = 0"
+        + " ORDER BY updated_at DESC, id DESC LIMIT 1";
+  }
+
+  public String selectChangedOwners(@Param("updatedAtAfter") long 
updatedAtAfter) {
+    return "SELECT metadata_object_id as metadataObjectId, updated_at as 
updatedAt"
+        + " FROM "
+        + OWNER_TABLE_NAME
+        + " WHERE deleted_at = 0 AND updated_at > #{updatedAtAfter} ORDER BY 
updated_at, id LIMIT 1000";

Review Comment:
   `selectChangedOwners` pages by `updated_at > #{updatedAtAfter}` with a fixed 
LIMIT and uses `updated_at` as the sole cursor. If more than the LIMIT rows 
share the same `updated_at`, subsequent polls that advance `updatedAtAfter` to 
that value will permanently skip the remaining rows (since they are `=` not 
`>`). To avoid missed invalidations, consider using a stable composite cursor 
(e.g., `(updated_at, id)`) and ordering by `(updated_at, id)`, and/or returning 
`id` so callers can resume safely.



##########
core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/EntityChangeLogBaseSQLProvider.java:
##########
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.storage.relational.mapper.provider.base;
+
+import static 
org.apache.gravitino.storage.relational.mapper.EntityChangeLogMapper.ENTITY_CHANGE_LOG_TABLE_NAME;
+
+import org.apache.ibatis.annotations.Param;
+
+public class EntityChangeLogBaseSQLProvider {
+
+  public String selectEntityChanges(
+      @Param("createdAtAfter") long createdAtAfter, @Param("maxRows") int 
maxRows) {
+    return "SELECT metalake_name as metalakeName, entity_type as entityType,"
+        + " full_name as fullName, operate_type as operateType, created_at as 
createdAt"
+        + " FROM "
+        + ENTITY_CHANGE_LOG_TABLE_NAME
+        + " WHERE created_at > #{createdAtAfter} ORDER BY created_at LIMIT 
#{maxRows}";

Review Comment:
   `selectEntityChanges` pages by `created_at > #{createdAtAfter}` and orders 
only by `created_at`. If multiple rows share the same millisecond timestamp and 
the result set is truncated by `LIMIT`, advancing `createdAtAfter` to the last 
seen value can cause rows with the same `created_at` to be skipped permanently. 
For correctness in HA invalidation, consider ordering by `(created_at, id)` and 
using a composite cursor (or include `id` in the result so callers can safely 
resume).



##########
scripts/mysql/schema-1.3.0-mysql.sql:
##########
@@ -0,0 +1,551 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file--
+--  distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"). You may not use this file except in compliance
+-- with the License.  You may obtain a copy of the License at
+--
+--  http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied.  See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+--
+
+CREATE TABLE IF NOT EXISTS `metalake_meta` (
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `metalake_name` VARCHAR(128) NOT NULL COMMENT 'metalake name',
+    `metalake_comment` VARCHAR(256) DEFAULT '' COMMENT 'metalake comment',
+    `properties` MEDIUMTEXT DEFAULT NULL COMMENT 'metalake properties',
+    `audit_info` MEDIUMTEXT NOT NULL COMMENT 'metalake audit info',
+    `schema_version` MEDIUMTEXT NOT NULL COMMENT 'metalake schema version 
info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'metalake 
current version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'metalake last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'metalake 
deleted at',
+    PRIMARY KEY (`metalake_id`),
+    UNIQUE KEY `uk_mn_del` (`metalake_name`, `deleted_at`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT 'metalake 
metadata';
+
+CREATE TABLE IF NOT EXISTS `catalog_meta` (
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `catalog_name` VARCHAR(128) NOT NULL COMMENT 'catalog name',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `type` VARCHAR(64) NOT NULL COMMENT 'catalog type',
+    `provider` VARCHAR(64) NOT NULL COMMENT 'catalog provider',
+    `catalog_comment` VARCHAR(256) DEFAULT '' COMMENT 'catalog comment',
+    `properties` MEDIUMTEXT DEFAULT NULL COMMENT 'catalog properties',
+    `audit_info` MEDIUMTEXT NOT NULL COMMENT 'catalog audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'catalog current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'catalog last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'catalog 
deleted at',
+    PRIMARY KEY (`catalog_id`),
+    UNIQUE KEY `uk_mid_cn_del` (`metalake_id`, `catalog_name`, `deleted_at`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT 'catalog 
metadata';
+
+CREATE TABLE IF NOT EXISTS `schema_meta` (
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `schema_name` VARCHAR(128) NOT NULL COMMENT 'schema name',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_comment` VARCHAR(256) DEFAULT '' COMMENT 'schema comment',
+    `properties` MEDIUMTEXT DEFAULT NULL COMMENT 'schema properties',
+    `audit_info` MEDIUMTEXT NOT NULL COMMENT 'schema audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'schema current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'schema last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'schema 
deleted at',
+    PRIMARY KEY (`schema_id`),
+    UNIQUE KEY `uk_cid_sn_del` (`catalog_id`, `schema_name`, `deleted_at`),
+    KEY `idx_mid` (`metalake_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT 'schema 
metadata';
+
+CREATE TABLE IF NOT EXISTS `table_meta` (
+    `table_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'table id',
+    `table_name` VARCHAR(128) NOT NULL COMMENT 'table name',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `audit_info` MEDIUMTEXT NOT NULL COMMENT 'table audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'table current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'table last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'table deleted 
at',
+    PRIMARY KEY (`table_id`),
+    UNIQUE KEY `uk_sid_tn_del` (`schema_id`, `table_name`, `deleted_at`),
+    KEY `idx_mid` (`metalake_id`),
+    KEY `idx_cid` (`catalog_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT 'table 
metadata';
+
+CREATE TABLE IF NOT EXISTS `table_column_version_info` (
+    `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'auto increment 
id',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `table_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'table id',
+    `table_version` INT UNSIGNED NOT NULL COMMENT 'table version',
+    `column_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'column id',
+    `column_name` VARCHAR(128) NOT NULL COMMENT 'column name',
+    `column_position` INT UNSIGNED NOT NULL COMMENT 'column position, starting 
from 0',
+    `column_type` TEXT NOT NULL COMMENT 'column type',
+    `column_comment` VARCHAR(256) DEFAULT '' COMMENT 'column comment',
+    `column_nullable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'column nullable, 
0 is not nullable, 1 is nullable',
+    `column_auto_increment` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'column auto 
increment, 0 is not auto increment, 1 is auto increment',
+    `column_default_value` TEXT DEFAULT NULL COMMENT 'column default value',
+    `column_op_type` TINYINT(1) NOT NULL COMMENT 'column operation type, 1 is 
create, 2 is update, 3 is delete',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'column 
deleted at',
+    `audit_info` MEDIUMTEXT NOT NULL COMMENT 'column audit info',
+    PRIMARY KEY (`id`),
+    UNIQUE KEY `uk_tid_ver_cid_del` (`table_id`, `table_version`, `column_id`, 
`deleted_at`),
+    KEY `idx_mid` (`metalake_id`),
+    KEY `idx_cid` (`catalog_id`),
+    KEY `idx_sid` (`schema_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT 'table 
column version info';
+
+CREATE TABLE IF NOT EXISTS `fileset_meta` (
+    `fileset_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'fileset id',
+    `fileset_name` VARCHAR(128) NOT NULL COMMENT 'fileset name',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `type` VARCHAR(64) NOT NULL COMMENT 'fileset type',
+    `audit_info` MEDIUMTEXT NOT NULL COMMENT 'fileset audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'fileset current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'fileset last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'fileset 
deleted at',
+    PRIMARY KEY (`fileset_id`),
+    UNIQUE KEY `uk_sid_fn_del` (`schema_id`, `fileset_name`, `deleted_at`),
+    KEY `idx_mid` (`metalake_id`),
+    KEY `idx_cid` (`catalog_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT 'fileset 
metadata';
+
+CREATE TABLE IF NOT EXISTS `fileset_version_info` (
+    `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'auto increment 
id',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `fileset_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'fileset id',
+    `version` INT UNSIGNED NOT NULL COMMENT 'fileset info version',
+    `fileset_comment` VARCHAR(256) DEFAULT '' COMMENT 'fileset comment',
+    `properties` MEDIUMTEXT DEFAULT NULL COMMENT 'fileset properties',
+    `storage_location_name` VARCHAR(256) NOT NULL DEFAULT 'default' COMMENT 
'fileset storage location name',
+    `storage_location` MEDIUMTEXT NOT NULL COMMENT 'fileset storage location',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'fileset 
deleted at',
+    PRIMARY KEY (`id`),
+    UNIQUE KEY `uk_fid_ver_sto_del` (`fileset_id`, `version`, 
`storage_location_name`, `deleted_at`),
+    KEY `idx_mid` (`metalake_id`),
+    KEY `idx_cid` (`catalog_id`),
+    KEY `idx_sid` (`schema_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT 'fileset 
version info';
+
+CREATE TABLE IF NOT EXISTS `topic_meta` (
+    `topic_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'topic id',
+    `topic_name` VARCHAR(128) NOT NULL COMMENT 'topic name',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `catalog_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'catalog id',
+    `schema_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'schema id',
+    `comment` VARCHAR(256) DEFAULT '' COMMENT 'topic comment',
+    `properties` MEDIUMTEXT DEFAULT NULL COMMENT 'topic properties',
+    `audit_info` MEDIUMTEXT NOT NULL COMMENT 'topic audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'topic current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'topic last 
version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'topic deleted 
at',
+    PRIMARY KEY (`topic_id`),
+    UNIQUE KEY `uk_sid_tn_del` (`schema_id`, `topic_name`, `deleted_at`),
+    KEY `idx_mid` (`metalake_id`),
+    KEY `idx_cid` (`catalog_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT 'topic 
metadata';
+
+CREATE TABLE IF NOT EXISTS `user_meta` (
+    `user_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'user id',
+    `user_name` VARCHAR(128) NOT NULL COMMENT 'username',
+    `metalake_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'metalake id',
+    `audit_info` MEDIUMTEXT NOT NULL COMMENT 'user audit info',
+    `current_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'user current 
version',
+    `last_version` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT 'user last version',
+    `deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'user deleted 
at',
+    `updated_at` BIGINT NOT NULL DEFAULT 0,
+    PRIMARY KEY (`user_id`),
+    UNIQUE KEY `uk_mid_us_del` (`metalake_id`, `user_name`, `deleted_at`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT 'user 
metadata';

Review Comment:
   The 1.3.0 MySQL schema script defines `updated_at` columns but does not 
include the new covering indexes introduced in the upgrade script 
(`idx_user_meta_name_del_upd`, `idx_group_meta_del_upd`, 
`idx_role_meta_del_upd`, `idx_owner_meta_obj_del_upd`, 
`idx_owner_meta_del_upd_obj`). New deployments that initialize directly from 
this schema will be missing the intended indexes; please add these index 
definitions to the schema script as well.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to