You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by ru...@apache.org on 2026/09/17 14:57:05 UTC

(calcite) branch main updated: [CALCITE-7787] Make Geode pdxSerializablePackagePath schema operand opt-in via system property

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

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


The following commit(s) were added to refs/heads/main by this push:
     new 9634752f1a [CALCITE-7787] Make Geode pdxSerializablePackagePath schema operand opt-in via system property
9634752f1a is described below

commit 9634752f1aa66e5e0e131c4908d3f440c90e054c
Author: Ruben Quesada Lopez <ru...@gmail.com>
AuthorDate: Wed Sep 16 12:20:31 2026 +0100

    [CALCITE-7787] Make Geode pdxSerializablePackagePath schema operand opt-in via system property
---
 .../calcite/config/CalciteSystemProperty.java      |   9 ++
 .../adapter/geode/rel/GeodeSchemaFactory.java      |   7 +-
 .../geode/simple/GeodeSimpleSchemaFactory.java     |   3 +
 .../calcite/adapter/geode/util/GeodeUtils.java     |  21 ++++
 .../adapter/geode/rel/GeodeSchemaFactoryTest.java  | 117 +++++++++++++++++++++
 site/_docs/history.md                              |   6 ++
 6 files changed, 161 insertions(+), 2 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/config/CalciteSystemProperty.java b/core/src/main/java/org/apache/calcite/config/CalciteSystemProperty.java
index c3c5590347..e5680a2783 100644
--- a/core/src/main/java/org/apache/calcite/config/CalciteSystemProperty.java
+++ b/core/src/main/java/org/apache/calcite/config/CalciteSystemProperty.java
@@ -559,6 +559,15 @@ public final class CalciteSystemProperty<T> {
   public static final CalciteSystemProperty<Boolean> ENABLE_SPARK_ENGINE =
       booleanProperty("calcite.enable.spark", false);
 
+  /**
+   * Whether the Geode schema operand {@code pdxSerializablePackagePath} is enabled.
+   *
+   * <p>The operand configures Geode's {@code ReflectionBasedAutoSerializer} class-name pattern.
+   * It is disabled by default; set this property to {@code "true"} to opt back in.
+   */
+  public static final CalciteSystemProperty<Boolean> GEODE_PDX_PACKAGE_PATH_ALLOWED =
+      booleanProperty("calcite.geode.pdxSerializablePackagePath.allowed", false);
+
   private static CalciteSystemProperty<Boolean> booleanProperty(String key,
       boolean defaultValue) {
     // Note that "" -> true (convenient for command-lines flags like '-Dflag')
diff --git a/geode/src/main/java/org/apache/calcite/adapter/geode/rel/GeodeSchemaFactory.java b/geode/src/main/java/org/apache/calcite/adapter/geode/rel/GeodeSchemaFactory.java
index 5c1f5a679b..26e57cf898 100644
--- a/geode/src/main/java/org/apache/calcite/adapter/geode/rel/GeodeSchemaFactory.java
+++ b/geode/src/main/java/org/apache/calcite/adapter/geode/rel/GeodeSchemaFactory.java
@@ -16,6 +16,7 @@
  */
 package org.apache.calcite.adapter.geode.rel;
 
+import org.apache.calcite.adapter.geode.util.GeodeUtils;
 import org.apache.calcite.model.ModelHandler;
 import org.apache.calcite.runtime.SpatialTypeFunctions;
 import org.apache.calcite.schema.Schema;
@@ -52,7 +53,9 @@ public GeodeSchemaFactory() {
     String locatorHost = (String) map.get(LOCATOR_HOST);
     int locatorPort = Integer.valueOf((String) map.get(LOCATOR_PORT));
     String[] regionNames = ((String) map.get(REGIONS)).split(COMMA_DELIMITER);
-    String pbxSerializablePackagePath = (String) map.get(PDX_SERIALIZABLE_PACKAGE_PATH);
+    String pdxSerializablePackagePath = (String) map.get(PDX_SERIALIZABLE_PACKAGE_PATH);
+    // The operand is disabled by default; see CalciteSystemProperty.GEODE_PDX_PACKAGE_PATH_ALLOWED
+    GeodeUtils.checkPdxPackagePathOperand(pdxSerializablePackagePath);
 
     boolean allowSpatialFunctions = true;
     if (map.containsKey(ALLOW_SPATIAL_FUNCTIONS)) {
@@ -65,7 +68,7 @@ public GeodeSchemaFactory() {
     }
 
     return new GeodeSchema(
-        createClientCache(locatorHost, locatorPort, pbxSerializablePackagePath, true),
+        createClientCache(locatorHost, locatorPort, pdxSerializablePackagePath, true),
         Arrays.asList(regionNames));
   }
 }
diff --git a/geode/src/main/java/org/apache/calcite/adapter/geode/simple/GeodeSimpleSchemaFactory.java b/geode/src/main/java/org/apache/calcite/adapter/geode/simple/GeodeSimpleSchemaFactory.java
index 1a867d33a3..9425f51a49 100644
--- a/geode/src/main/java/org/apache/calcite/adapter/geode/simple/GeodeSimpleSchemaFactory.java
+++ b/geode/src/main/java/org/apache/calcite/adapter/geode/simple/GeodeSimpleSchemaFactory.java
@@ -16,6 +16,7 @@
  */
 package org.apache.calcite.adapter.geode.simple;
 
+import org.apache.calcite.adapter.geode.util.GeodeUtils;
 import org.apache.calcite.schema.Schema;
 import org.apache.calcite.schema.SchemaFactory;
 import org.apache.calcite.schema.SchemaPlus;
@@ -45,6 +46,8 @@ public GeodeSimpleSchemaFactory() {
     int locatorPort = Integer.valueOf((String) map.get(LOCATOR_PORT));
     String[] regionNames = ((String) map.get(REGIONS)).split(COMMA_DELIMITER);
     String pdxSerializablePackagePath = (String) map.get(PDX_SERIALIZABLE_PACKAGE_PATH);
+    // The operand is disabled by default; see CalciteSystemProperty.GEODE_PDX_PACKAGE_PATH_ALLOWED
+    GeodeUtils.checkPdxPackagePathOperand(pdxSerializablePackagePath);
 
     return new GeodeSimpleSchema(locatorHost, locatorPort, regionNames, pdxSerializablePackagePath);
   }
diff --git a/geode/src/main/java/org/apache/calcite/adapter/geode/util/GeodeUtils.java b/geode/src/main/java/org/apache/calcite/adapter/geode/util/GeodeUtils.java
index 2aa212dc5a..3cc43ca4b2 100644
--- a/geode/src/main/java/org/apache/calcite/adapter/geode/util/GeodeUtils.java
+++ b/geode/src/main/java/org/apache/calcite/adapter/geode/util/GeodeUtils.java
@@ -17,6 +17,7 @@
 package org.apache.calcite.adapter.geode.util;
 
 import org.apache.calcite.avatica.util.DateTimeUtils;
+import org.apache.calcite.config.CalciteSystemProperty;
 import org.apache.calcite.linq4j.tree.Primitive;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeField;
@@ -68,6 +69,26 @@ public class GeodeUtils {
   private GeodeUtils() {
   }
 
+  /** Checks whether the {@code pdxSerializablePackagePath} schema operand is enabled.
+   *
+   * <p>The operand configures Geode's {@link ReflectionBasedAutoSerializer}. It is disabled by
+   * default; deployments that need it can opt back in by setting the system property
+   * {@code calcite.geode.pdxSerializablePackagePath.allowed} to {@code "true"}.
+   *
+   * @param pdxSerializablePackagePath operand value, or null if not set
+   * @see CalciteSystemProperty#GEODE_PDX_PACKAGE_PATH_ALLOWED
+   */
+  public static void checkPdxPackagePathOperand(
+      @Nullable String pdxSerializablePackagePath) {
+    if (pdxSerializablePackagePath == null
+        || CalciteSystemProperty.GEODE_PDX_PACKAGE_PATH_ALLOWED.value()) {
+      return;
+    }
+    throw new IllegalStateException("Operand 'pdxSerializablePackagePath'"
+        + " is disabled by default; set system property"
+        + " 'calcite.geode.pdxSerializablePackagePath.allowed' to 'true' to enable it");
+  }
+
   /**
    * Creates a Geode client instance connected to locator and configured to
    * support PDX instances.
diff --git a/geode/src/test/java/org/apache/calcite/adapter/geode/rel/GeodeSchemaFactoryTest.java b/geode/src/test/java/org/apache/calcite/adapter/geode/rel/GeodeSchemaFactoryTest.java
new file mode 100644
index 0000000000..e2aa9edcfb
--- /dev/null
+++ b/geode/src/test/java/org/apache/calcite/adapter/geode/rel/GeodeSchemaFactoryTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.calcite.adapter.geode.rel;
+
+import org.apache.calcite.adapter.geode.simple.GeodeSimpleSchemaFactory;
+import org.apache.calcite.adapter.geode.util.GeodeUtils;
+import org.apache.calcite.config.CalciteSystemProperty;
+import org.apache.calcite.jdbc.CalciteSchema;
+import org.apache.calcite.schema.SchemaPlus;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.Isolated;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+/** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-7787">[CALCITE-7787]
+ * Make Geode pdxSerializablePackagePath schema operand opt-in via system property</a>.
+ * Verifies that the {@code pdxSerializablePackagePath} operand is disabled by
+ * default in both Geode schema factories, and enabled only when the
+ * {@code calcite.geode.pdxSerializablePackagePath.allowed} system property is set.
+ *
+ * <p>Marked {@link Isolated} because one test toggles the JVM-wide cached value
+ * of {@link CalciteSystemProperty#GEODE_PDX_PACKAGE_PATH_ALLOWED}.
+ */
+@Isolated
+class GeodeSchemaFactoryTest {
+  private static Map<String, Object> operand() {
+    final Map<String, Object> operand = new HashMap<>();
+    operand.put(GeodeSchemaFactory.LOCATOR_HOST, "localhost");
+    operand.put(GeodeSchemaFactory.LOCATOR_PORT, "10334");
+    operand.put(GeodeSchemaFactory.REGIONS, "region");
+    operand.put(GeodeSchemaFactory.PDX_SERIALIZABLE_PACKAGE_PATH, "com.example.*");
+    return operand;
+  }
+
+  private static SchemaPlus rootSchema() {
+    return CalciteSchema.createRootSchema(false, false).plus();
+  }
+
+  /** Temporarily sets {@link CalciteSystemProperty#GEODE_PDX_PACKAGE_PATH_ALLOWED}
+   * to {@code true}, returning an {@link AutoCloseable} that restores the
+   * original value when closed. The system property is read once at class-load
+   * time; this helper flips the cached value for the duration of a single test.
+   */
+  private static AutoCloseable overrideGeodePdxPackagePathAllowed() {
+    final Field field;
+    try {
+      field = CalciteSystemProperty.class.getDeclaredField("value");
+    } catch (NoSuchFieldException e) {
+      throw new AssertionError(e);
+    }
+    field.setAccessible(true);
+    final CalciteSystemProperty<Boolean> property =
+        CalciteSystemProperty.GEODE_PDX_PACKAGE_PATH_ALLOWED;
+    final Object original;
+    try {
+      original = field.get(property);
+      field.set(property, true);
+    } catch (IllegalAccessException e) {
+      throw new AssertionError(e);
+    }
+    return () -> field.set(property, original);
+  }
+
+  @Test void testPdxPackagePathOperandDisabledByDefault() {
+    IllegalStateException e =
+        assertThrows(IllegalStateException.class, () ->
+            new GeodeSchemaFactory().create(rootSchema(), "geode", operand()));
+    assertThat(e.getMessage(), containsString("pdxSerializablePackagePath"));
+  }
+
+  @Test void testSimpleFactoryPdxPackagePathOperandDisabledByDefault() {
+    IllegalStateException e =
+        assertThrows(IllegalStateException.class, () ->
+            new GeodeSimpleSchemaFactory().create(rootSchema(), "geode", operand()));
+    assertThat(e.getMessage(), containsString("pdxSerializablePackagePath"));
+  }
+
+  @Test void testPdxPackagePathOperandEnabled() throws Exception {
+    try (AutoCloseable ignored = overrideGeodePdxPackagePathAllowed()) {
+      new GeodeSchemaFactory().create(rootSchema(), "geode", operand());
+    }
+  }
+
+  @Test void testSimpleFactoryPdxPackagePathOperandEnabledt() throws Exception {
+    try (AutoCloseable ignored = overrideGeodePdxPackagePathAllowed()) {
+      new GeodeSimpleSchemaFactory().create(rootSchema(), "geode", operand());
+    }
+  }
+
+  /** A null operand is always accepted, independent of the opt-in property. */
+  @Test void testPdxPackagePathOperandNullIsAlwaysAccepted() {
+    assertDoesNotThrow(() -> GeodeUtils.checkPdxPackagePathOperand(null));
+  }
+}
diff --git a/site/_docs/history.md b/site/_docs/history.md
index a2c769c234..cc4e1e9ebb 100644
--- a/site/_docs/history.md
+++ b/site/_docs/history.md
@@ -119,6 +119,12 @@ #### Breaking Changes
 `-Dcalcite.enable.spark=true`. The `spark` connection property alone no longer
 activates it; a connection using `spark=true` without the opt-in will fail.
 
+* [<a href="https://issues.apache.org/jira/browse/CALCITE-7787">CALCITE-7787</a>]
+The Geode schema operand `pdxSerializablePackagePath` (honored by `GeodeSchemaFactory`
+and `GeodeSimpleSchemaFactory`) now requires the operator-level opt-in system property
+`-Dcalcite.geode.pdxSerializablePackagePath.allowed=true`. A model that sets the operand
+without the opt-in will fail. Java callers of `GeodeUtils.createClientCache` are unaffected.
+
 #### New features
 {: #new-features-1-43-0}