This is an automated email from the ASF dual-hosted git repository.

singhpk234 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git


The following commit(s) were added to refs/heads/main by this push:
     new b836bee11 Move idempotency_records schema to v4 and add H2 support 
(#3386)
b836bee11 is described below

commit b836bee112cf4bdbe4e9e1fb5dbdec6881dc5c0f
Author: Huaxin Gao <[email protected]>
AuthorDate: Mon Jan 26 14:20:48 2026 -0800

    Move idempotency_records schema to v4 and add H2 support (#3386)
    
    * Move idempotency_records schema to v4 and add H2 support
    
    * address comments and fix test failures
    
    * fix format
    
    * add comment to resource_id
---
 .../{postgres/schema-v3.sql => h2/schema-v4.sql}   | 51 +++++++++++-----------
 .../src/main/resources/postgres/schema-v3.sql      | 28 ------------
 .../postgres/{schema-v3.sql => schema-v4.sql}      |  3 +-
 ...gerWithJdbcBasePersistenceImplV4SchemaTest.java | 29 ++++++++++++
 .../idempotency/PostgresIdempotencyStoreIT.java    |  4 +-
 5 files changed, 58 insertions(+), 57 deletions(-)

diff --git 
a/persistence/relational-jdbc/src/main/resources/postgres/schema-v3.sql 
b/persistence/relational-jdbc/src/main/resources/h2/schema-v4.sql
similarity index 78%
copy from persistence/relational-jdbc/src/main/resources/postgres/schema-v3.sql
copy to persistence/relational-jdbc/src/main/resources/h2/schema-v4.sql
index ed99b6120..0f2ac75cc 100644
--- a/persistence/relational-jdbc/src/main/resources/postgres/schema-v3.sql
+++ b/persistence/relational-jdbc/src/main/resources/h2/schema-v4.sql
@@ -15,21 +15,25 @@
 -- KIND, either express or implied.  See the License for the
 -- specific language governing permissions and limitations
 -- under the License.
+--
 
 -- Changes from v2:
 --  * Added `events` table
+--  * Added `idempotency_records` table for REST idempotency
 
 CREATE SCHEMA IF NOT EXISTS POLARIS_SCHEMA;
-SET search_path TO POLARIS_SCHEMA;
+SET SCHEMA POLARIS_SCHEMA;
 
 CREATE TABLE IF NOT EXISTS version (
-    version_key TEXT PRIMARY KEY,
+    version_key VARCHAR PRIMARY KEY,
     version_value INTEGER NOT NULL
 );
-INSERT INTO version (version_key, version_value)
-VALUES ('version', 3)
-ON CONFLICT (version_key) DO UPDATE
-SET version_value = EXCLUDED.version_value;
+
+MERGE INTO version (version_key, version_value)
+    KEY (version_key)
+    VALUES ('version', 3);
+
+-- H2 supports COMMENT, but some modes may ignore it
 COMMENT ON TABLE version IS 'the version of the JDBC schema in use';
 
 CREATE TABLE IF NOT EXISTS entities (
@@ -46,23 +50,21 @@ CREATE TABLE IF NOT EXISTS entities (
     purge_timestamp BIGINT NOT NULL,
     to_purge_timestamp BIGINT NOT NULL,
     last_update_timestamp BIGINT NOT NULL,
-    properties JSONB not null default '{}'::JSONB,
-    internal_properties JSONB not null default '{}'::JSONB,
+    properties TEXT NOT NULL DEFAULT '{}',
+    internal_properties TEXT NOT NULL DEFAULT '{}',
     grant_records_version INT NOT NULL,
     location_without_scheme TEXT,
     PRIMARY KEY (realm_id, id),
     CONSTRAINT constraint_name UNIQUE (realm_id, catalog_id, parent_id, 
type_code, name)
 );
 
+CREATE INDEX IF NOT EXISTS idx_locations ON entities(realm_id, catalog_id, 
location_without_scheme);
+
 -- TODO: create indexes based on all query pattern.
 CREATE INDEX IF NOT EXISTS idx_entities ON entities (realm_id, catalog_id, id);
-CREATE INDEX IF NOT EXISTS idx_locations
-    ON entities USING btree (realm_id, parent_id, location_without_scheme)
-    WHERE location_without_scheme IS NOT NULL;
 
 COMMENT ON TABLE entities IS 'all the entities';
 
-COMMENT ON COLUMN entities.realm_id IS 'realm_id used for multi-tenancy';
 COMMENT ON COLUMN entities.catalog_id IS 'catalog id';
 COMMENT ON COLUMN entities.id IS 'entity id';
 COMMENT ON COLUMN entities.parent_id IS 'entity id of parent';
@@ -89,7 +91,6 @@ CREATE TABLE IF NOT EXISTS grant_records (
 );
 
 COMMENT ON TABLE grant_records IS 'grant records for entities';
-
 COMMENT ON COLUMN grant_records.securable_catalog_id IS 'catalog id of the 
securable';
 COMMENT ON COLUMN grant_records.securable_id IS 'entity id of the securable';
 COMMENT ON COLUMN grant_records.grantee_catalog_id IS 'catalog id of the 
grantee';
@@ -115,7 +116,7 @@ CREATE TABLE IF NOT EXISTS policy_mapping_record (
     policy_type_code INTEGER NOT NULL,
     policy_catalog_id BIGINT NOT NULL,
     policy_id BIGINT NOT NULL,
-    parameters JSONB NOT NULL DEFAULT '{}'::JSONB,
+    parameters TEXT NOT NULL DEFAULT '{}',
     PRIMARY KEY (realm_id, target_catalog_id, target_id, policy_type_code, 
policy_catalog_id, policy_id)
 );
 
@@ -131,34 +132,32 @@ CREATE TABLE IF NOT EXISTS events (
     principal_name TEXT,
     resource_type TEXT NOT NULL,
     resource_identifier TEXT NOT NULL,
-    additional_properties JSONB NOT NULL DEFAULT '{}'::JSONB,
+    additional_properties TEXT NOT NULL,
     PRIMARY KEY (event_id)
 );
 
--- Idempotency records (key-only idempotency; durable replay)
 CREATE TABLE IF NOT EXISTS idempotency_records (
     realm_id TEXT NOT NULL,
     idempotency_key TEXT NOT NULL,
     operation_type TEXT NOT NULL,
-    resource_id TEXT NOT NULL,
+    resource_id TEXT NOT NULL, -- normalized request-derived resource 
identifier (not a generated entity id)
 
     -- Finalization/replay
-    http_status INTEGER,                 -- NULL while IN_PROGRESS; set only 
on finalized 2xx/terminal 4xx
-    error_subtype TEXT,                  -- optional: e.g., already_exists, 
namespace_not_empty, idempotency_replay_failed
-    response_summary TEXT,               -- minimal body to reproduce 
equivalent response (JSON string)
-    response_headers TEXT,               -- small whitelisted headers to 
replay (JSON string)
-    finalized_at TIMESTAMP,              -- when http_status was written
+    http_status INTEGER,       -- NULL while IN_PROGRESS; set only on 
finalized 2xx/terminal 4xx
+    error_subtype TEXT,        -- optional: e.g., already_exists, 
namespace_not_empty, idempotency_replay_failed
+    response_summary TEXT,     -- minimal body to reproduce equivalent 
response (JSON string)
+    response_headers TEXT,     -- small whitelisted headers to replay (JSON 
string)
+    finalized_at TIMESTAMP,    -- when http_status was written
 
     -- Liveness/ops
     created_at TIMESTAMP NOT NULL,
     updated_at TIMESTAMP NOT NULL,
-    heartbeat_at TIMESTAMP,              -- updated by owner while IN_PROGRESS
-    executor_id TEXT,                    -- owner pod/worker id
+    heartbeat_at TIMESTAMP,  -- updated by owner while IN_PROGRESS
+    executor_id TEXT,        -- owner pod/worker id
     expires_at TIMESTAMP,
 
     PRIMARY KEY (realm_id, idempotency_key)
 );
 
--- Helpful indexes
 CREATE INDEX IF NOT EXISTS idx_idemp_realm_expires
-    ON idempotency_records (realm_id, expires_at);
+    ON idempotency_records (realm_id, expires_at);
\ No newline at end of file
diff --git 
a/persistence/relational-jdbc/src/main/resources/postgres/schema-v3.sql 
b/persistence/relational-jdbc/src/main/resources/postgres/schema-v3.sql
index ed99b6120..96897f510 100644
--- a/persistence/relational-jdbc/src/main/resources/postgres/schema-v3.sql
+++ b/persistence/relational-jdbc/src/main/resources/postgres/schema-v3.sql
@@ -134,31 +134,3 @@ CREATE TABLE IF NOT EXISTS events (
     additional_properties JSONB NOT NULL DEFAULT '{}'::JSONB,
     PRIMARY KEY (event_id)
 );
-
--- Idempotency records (key-only idempotency; durable replay)
-CREATE TABLE IF NOT EXISTS idempotency_records (
-    realm_id TEXT NOT NULL,
-    idempotency_key TEXT NOT NULL,
-    operation_type TEXT NOT NULL,
-    resource_id TEXT NOT NULL,
-
-    -- Finalization/replay
-    http_status INTEGER,                 -- NULL while IN_PROGRESS; set only 
on finalized 2xx/terminal 4xx
-    error_subtype TEXT,                  -- optional: e.g., already_exists, 
namespace_not_empty, idempotency_replay_failed
-    response_summary TEXT,               -- minimal body to reproduce 
equivalent response (JSON string)
-    response_headers TEXT,               -- small whitelisted headers to 
replay (JSON string)
-    finalized_at TIMESTAMP,              -- when http_status was written
-
-    -- Liveness/ops
-    created_at TIMESTAMP NOT NULL,
-    updated_at TIMESTAMP NOT NULL,
-    heartbeat_at TIMESTAMP,              -- updated by owner while IN_PROGRESS
-    executor_id TEXT,                    -- owner pod/worker id
-    expires_at TIMESTAMP,
-
-    PRIMARY KEY (realm_id, idempotency_key)
-);
-
--- Helpful indexes
-CREATE INDEX IF NOT EXISTS idx_idemp_realm_expires
-    ON idempotency_records (realm_id, expires_at);
diff --git 
a/persistence/relational-jdbc/src/main/resources/postgres/schema-v3.sql 
b/persistence/relational-jdbc/src/main/resources/postgres/schema-v4.sql
similarity index 97%
copy from persistence/relational-jdbc/src/main/resources/postgres/schema-v3.sql
copy to persistence/relational-jdbc/src/main/resources/postgres/schema-v4.sql
index ed99b6120..47d4ea883 100644
--- a/persistence/relational-jdbc/src/main/resources/postgres/schema-v3.sql
+++ b/persistence/relational-jdbc/src/main/resources/postgres/schema-v4.sql
@@ -18,6 +18,7 @@
 
 -- Changes from v2:
 --  * Added `events` table
+--  * Added `idempotency_records` table for REST idempotency
 
 CREATE SCHEMA IF NOT EXISTS POLARIS_SCHEMA;
 SET search_path TO POLARIS_SCHEMA;
@@ -140,7 +141,7 @@ CREATE TABLE IF NOT EXISTS idempotency_records (
     realm_id TEXT NOT NULL,
     idempotency_key TEXT NOT NULL,
     operation_type TEXT NOT NULL,
-    resource_id TEXT NOT NULL,
+    resource_id TEXT NOT NULL,            -- normalized request-derived 
resource identifier (not a generated entity id)
 
     -- Finalization/replay
     http_status INTEGER,                 -- NULL while IN_PROGRESS; set only 
on finalized 2xx/terminal 4xx
diff --git 
a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplV4SchemaTest.java
 
b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplV4SchemaTest.java
new file mode 100644
index 000000000..e26a0fccc
--- /dev/null
+++ 
b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/AtomicMetastoreManagerWithJdbcBasePersistenceImplV4SchemaTest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.polaris.persistence.relational.jdbc;
+
+public class AtomicMetastoreManagerWithJdbcBasePersistenceImplV4SchemaTest
+    extends AtomicMetastoreManagerWithJdbcBasePersistenceImplTest {
+
+  @Override
+  public int schemaVersion() {
+    return 4;
+  }
+}
diff --git 
a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/idempotency/PostgresIdempotencyStoreIT.java
 
b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/idempotency/PostgresIdempotencyStoreIT.java
index 918c9f72d..3d92ceba7 100644
--- 
a/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/idempotency/PostgresIdempotencyStoreIT.java
+++ 
b/persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/idempotency/PostgresIdempotencyStoreIT.java
@@ -77,9 +77,9 @@ public class PostgresIdempotencyStoreIT {
     try (InputStream is =
         Thread.currentThread()
             .getContextClassLoader()
-            .getResourceAsStream("postgres/schema-v3.sql")) {
+            .getResourceAsStream("postgres/schema-v4.sql")) {
       if (is == null) {
-        throw new IllegalStateException("schema-v3.sql not found on 
classpath");
+        throw new IllegalStateException("schema-v4.sql not found on 
classpath");
       }
       ops.executeScript(is);
     }

Reply via email to