This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-6808-9ffcd749417738b7e21fc0f591aa9a498794a441 in repository https://gitbox.apache.org/repos/asf/texera.git
commit 8e23e3adae4190263721b8fbcd178e7a88266e45 Author: Kary Zheng <[email protected]> AuthorDate: Wed Jul 22 17:34:19 2026 -0700 fix(LogicalOp): register SklearnLogisticRegression(CV) subtypes exactly once (#6808) ### What changes were proposed in this PR? `LogicalOp`'s `@JsonSubTypes` registered `SklearnLogisticRegressionOpDesc` and `SklearnLogisticRegressionCVOpDesc` **twice each** (two separate active `new Type(...)` pairs). Any consumer that enumerates `@JsonSubTypes.value()` — operator discovery, metadata/schema generation, the operator palette — therefore saw each of these two operators twice. This PR removes the duplicate pair, keeping exactly one registration of each: ```diff - new Type(value = classOf[SklearnLogisticRegressionOpDesc], name = "SklearnLogisticRegression"), - new Type( - value = classOf[SklearnLogisticRegressionCVOpDesc], - name = "SklearnLogisticRegressionCV" - ), ``` ### Any related issues, documentation, discussions? Closes #6793 ### How was this PR tested? Added a `LogicalOpSpec` regression test that reads the `@JsonSubTypes` annotation and asserts no subtype **class** or **name** is registered more than once. Verified the test **fails** on the pre-fix (duplicated) registry and **passes** after the fix; full `LogicalOpSpec` is green (5/5). ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Claude Opus 4.8) --------- Co-authored-by: Claude Opus 4.8 <[email protected]> --- .../org/apache/texera/amber/operator/LogicalOp.scala | 5 ----- .../org/apache/texera/amber/operator/LogicalOpSpec.scala | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/LogicalOp.scala b/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/LogicalOp.scala index bb32f96abb..efa4614418 100644 --- a/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/LogicalOp.scala +++ b/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/LogicalOp.scala @@ -355,11 +355,6 @@ trait StateTransferFunc value = classOf[SklearnTrainingLogisticRegressionCVOpDesc], name = "SklearnTrainingLogisticRegressionCV" ), - new Type(value = classOf[SklearnLogisticRegressionOpDesc], name = "SklearnLogisticRegression"), - new Type( - value = classOf[SklearnLogisticRegressionCVOpDesc], - name = "SklearnLogisticRegressionCV" - ), new Type(value = classOf[SklearnRidgeOpDesc], name = "SklearnRidge"), new Type(value = classOf[SklearnRidgeCVOpDesc], name = "SklearnRidgeCV"), new Type(value = classOf[SklearnSDGOpDesc], name = "SklearnSDG"), diff --git a/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/LogicalOpSpec.scala b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/LogicalOpSpec.scala index a91c50b4ad..606f86a8d2 100644 --- a/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/LogicalOpSpec.scala +++ b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/LogicalOpSpec.scala @@ -71,4 +71,19 @@ class LogicalOpSpec extends AnyFlatSpec { } assert(ex.getMessage == "operator DistinctOpDesc does not support reconfiguration") } + + "LogicalOp @JsonSubTypes" should "register each operator subtype exactly once" in { + // SklearnLogisticRegression / ...CV were each listed twice, so consumers + // enumerating the registry saw them twice. + val subTypes = classOf[LogicalOp] + .getAnnotation(classOf[com.fasterxml.jackson.annotation.JsonSubTypes]) + assert(subTypes != null, "LogicalOp is missing its @JsonSubTypes annotation") + val types = subTypes.value() + val dupClasses = + types.map(_.value()).groupBy(identity).collect { case (c, ts) if ts.length > 1 => c.getName } + val dupNames = + types.map(_.name()).groupBy(identity).collect { case (n, ts) if ts.length > 1 => n } + assert(dupClasses.isEmpty, s"duplicate subtype classes: ${dupClasses.mkString(", ")}") + assert(dupNames.isEmpty, s"duplicate subtype names: ${dupNames.mkString(", ")}") + } }
