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-8395-cd3c52351bd4731c12f9098737b1109e3eac41a4
in repository https://gitbox.apache.org/repos/asf/texera.git

commit 1cdc6256715772462d75d15079875cc056a78ca9
Author: Xinyuan Lin <[email protected]>
AuthorDate: Wed Sep 9 09:02:34 2026 +0000

    chore(workflow-core): remove the unused TupleUtils.json2tuple (#8395)
    
    ### What changes were proposed in this PR?
    
    Deletes `TupleUtils.json2tuple`, which has no production caller. Pure
    deletion, no behaviour change: **−114 lines**.
    
    Its sibling `tuple2json` is live — `ExecutionResultService` uses it —
    and stays, as does the object.
    
    ### History
    
    | | |
    | --- | --- |
    | **Introduced by** | #1328 (2021-09-08) — "[Operator Caching Step 3]
    add operator cache backend new files and config changes"; the cache read
    path called `val newTuple = json2tuple(line)` when rehydrating cached
    tuples |
    | **Usage removed by** | #3111 (2024-11-26) — "Update amber to depend on
    sub projects" deleted that call site while splitting amber into
    sub-projects |
    
    Dead for about two years.
    
    > Reviewer note: removing it frees three imports that only it used —
    `AttributeTypeUtils.{inferSchemaFromRows, parseField}`,
    `JSONUtils.{JSONToMap, objectMapper}` and `ArrayBuffer`. `TupleSpec`'s
    "produce identical strings" test was a `tuple2json → json2tuple`
    round-trip, so it cannot survive the removal and goes with it; that also
    orphans its `tuple2json` import, which `scalafix` flagged.
    
    ### Any related issues, documentation, discussions?
    
    Closes #8392
    
    ### How was this PR tested?
    
    Existing tests only — this PR adds none, since it removes a method and
    the tests that covered it.
    
    Locally, from the repo root with Java 17:
    
    - `sbt "WorkflowExecutionService/Test/compile"` — success.
    - `sbt "WorkflowCore/testOnly *TupleSpec *TupleUtilsSpec"` — 32 tests,
    all pass.
    - `sbt scalafmtCheckAll "scalafixAll --check"` — clean.
    
    Verification, re-runnable by a reviewer:
    
    ```
    git grep -n json2tuple    # only the deleted method and its tests
    git grep -n tuple2json    # the live sibling, untouched
    ```
    
    ### Was this PR authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Claude Opus 5)
---
 .../texera/amber/core/tuple/TupleUtils.scala       | 53 ----------------------
 .../apache/texera/amber/core/tuple/TupleSpec.scala | 17 -------
 .../texera/amber/core/tuple/TupleUtilsSpec.scala   | 44 ------------------
 3 files changed, 114 deletions(-)

diff --git 
a/common/workflow-core/src/main/scala/org/apache/texera/amber/core/tuple/TupleUtils.scala
 
b/common/workflow-core/src/main/scala/org/apache/texera/amber/core/tuple/TupleUtils.scala
index 10f34574db..1cf7642c81 100644
--- 
a/common/workflow-core/src/main/scala/org/apache/texera/amber/core/tuple/TupleUtils.scala
+++ 
b/common/workflow-core/src/main/scala/org/apache/texera/amber/core/tuple/TupleUtils.scala
@@ -21,11 +21,7 @@ package org.apache.texera.amber.core.tuple
 
 import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.node.ObjectNode
-import 
org.apache.texera.amber.core.tuple.AttributeTypeUtils.{inferSchemaFromRows, 
parseField}
 import org.apache.texera.amber.util.JSONUtils
-import org.apache.texera.amber.util.JSONUtils.{JSONToMap, objectMapper}
-
-import scala.collection.mutable.ArrayBuffer
 
 object TupleUtils {
 
@@ -39,53 +35,4 @@ object TupleUtils {
     objectNode
   }
 
-  def json2tuple(json: String): Tuple = {
-    var fieldNames = Set[String]()
-
-    val allFields: ArrayBuffer[Map[String, String]] = ArrayBuffer()
-
-    // Parse and flatten once; reused for schema inference and value 
extraction.
-    val root: JsonNode = objectMapper.readTree(json)
-    val data: Map[String, String] = JSONToMap(root)
-    if (root.isObject) {
-      fieldNames = fieldNames.++(data.keySet)
-      allFields += data
-    }
-
-    val sortedFieldNames = fieldNames.toList
-
-    val attributeTypes = inferSchemaFromRows(allFields.iterator.map(fields => {
-      val result = ArrayBuffer[Object]()
-      for (fieldName <- sortedFieldNames) {
-        if (fields.contains(fieldName)) {
-          result += fields(fieldName)
-        } else {
-          result += null
-        }
-      }
-      result.toArray
-    }))
-
-    val schema = Schema(
-      sortedFieldNames.indices
-        .map(i => new Attribute(sortedFieldNames(i), attributeTypes(i)))
-        .toList
-    )
-
-    try {
-      val fields = scala.collection.mutable.ArrayBuffer.empty[Any]
-
-      for (fieldName <- schema.getAttributeNames) {
-        if (data.contains(fieldName)) {
-          fields += parseField(data(fieldName), 
schema.getAttribute(fieldName).getType)
-        } else {
-          fields += null
-        }
-      }
-      Tuple.builder(schema).addSequentially(fields.toArray).build()
-    } catch {
-      case e: Exception => throw e
-    }
-  }
-
 }
diff --git 
a/common/workflow-core/src/test/scala/org/apache/texera/amber/core/tuple/TupleSpec.scala
 
b/common/workflow-core/src/test/scala/org/apache/texera/amber/core/tuple/TupleSpec.scala
index 73ff029dd6..3471d74004 100644
--- 
a/common/workflow-core/src/test/scala/org/apache/texera/amber/core/tuple/TupleSpec.scala
+++ 
b/common/workflow-core/src/test/scala/org/apache/texera/amber/core/tuple/TupleSpec.scala
@@ -19,7 +19,6 @@
 
 package org.apache.texera.amber.core.tuple
 
-import org.apache.texera.amber.core.tuple.TupleUtils.{json2tuple, tuple2json}
 import org.scalatest.flatspec.AnyFlatSpec
 
 import java.sql.Timestamp
@@ -104,22 +103,6 @@ class TupleSpec extends AnyFlatSpec {
     assert(outputTuple.length == 2);
   }
 
-  it should "produce identical strings" in {
-    val inputSchema =
-      Schema().add(stringAttribute).add(integerAttribute).add(boolAttribute)
-    val inputTuple = Tuple
-      .builder(inputSchema)
-      .add(integerAttribute, 1)
-      .add(stringAttribute, "string-attr")
-      .add(boolAttribute, true)
-      .build()
-
-    val line = tuple2json(inputTuple.schema, inputTuple.fieldVals).toString
-    val newTuple = json2tuple(line)
-    assert(line == tuple2json(newTuple.schema, newTuple.fieldVals).toString)
-
-  }
-
   it should "calculate hash" in {
     val inputSchema =
       Schema()
diff --git 
a/common/workflow-core/src/test/scala/org/apache/texera/amber/core/tuple/TupleUtilsSpec.scala
 
b/common/workflow-core/src/test/scala/org/apache/texera/amber/core/tuple/TupleUtilsSpec.scala
index 3ac9a50ac1..b59c480992 100644
--- 
a/common/workflow-core/src/test/scala/org/apache/texera/amber/core/tuple/TupleUtilsSpec.scala
+++ 
b/common/workflow-core/src/test/scala/org/apache/texera/amber/core/tuple/TupleUtilsSpec.scala
@@ -63,48 +63,4 @@ class TupleUtilsSpec extends AnyFlatSpec {
     val node = TupleUtils.tuple2json(new Schema(), Array.empty[Any])
     assert(node.size() == 0)
   }
-
-  // --- json2tuple 
------------------------------------------------------------
-
-  "TupleUtils.json2tuple" should "infer a schema from a flat JSON object's 
keys and types" in {
-    val tuple = TupleUtils.json2tuple("""{"name": "bob", "age": 30}""")
-    val names = tuple.getSchema.getAttributeNames.toSet
-    assert(names == Set("name", "age"))
-    assert(tuple.getField[Any]("name") == "bob")
-    // age is parsed via inferSchemaFromRows; the inferred type for "30" is
-    // a numeric type — assert we can read the field rather than locking in
-    // the precise inferred AttributeType.
-    assert(tuple.getField[Any]("age").toString == "30")
-  }
-
-  it should "round-trip a schema-and-values through tuple2json → json2tuple" 
in {
-    val schema = new Schema(
-      new Attribute("city", AttributeType.STRING),
-      new Attribute("score", AttributeType.INTEGER)
-    )
-    val original = TupleUtils.tuple2json(schema, Array[Any]("Irvine", 
Int.box(42))).toString
-    val parsed = TupleUtils.json2tuple(original)
-    val reSerialized =
-      TupleUtils.tuple2json(parsed.getSchema, 
parsed.getFields.toArray.asInstanceOf[Array[Any]])
-    // The exact column order isn't part of the json2tuple contract (it builds
-    // schemaFieldNames from a Set), so compare by JSON-tree equality.
-    val mapper = org.apache.texera.amber.util.JSONUtils.objectMapper
-    assert(mapper.readTree(reSerialized.toString) == mapper.readTree(original))
-  }
-
-  it should "drop non-object roots (e.g. a JSON array) into an empty tuple" in 
{
-    // The implementation only collects fields when the root `isObject`. A
-    // non-object root leaves `fieldNames` empty, so the result is a tuple
-    // over an empty schema with no fields — observed contract is no-throw,
-    // empty result.
-    val tuple = TupleUtils.json2tuple("""[1, 2, 3]""")
-    assert(tuple.getSchema.getAttributes.isEmpty)
-    assert(tuple.getFields.isEmpty)
-  }
-
-  it should "throw when given malformed JSON" in {
-    intercept[Exception] {
-      TupleUtils.json2tuple("{ this is not json }")
-    }
-  }
 }

Reply via email to