The page says only "Output is number of modified records" (logical_relations.md, Property Maintenance). Neither it nor algebra.proto says what type that number has, whether it can be null, or how many columns an UpdateRel outputs. A root has to name every output column, so a producer has to choose.
Isthmus writes a plain UPDATE as an UpdateRel whose root names the table's columns. Reading that plan back, substrait-java's core derives the table's schema, while Isthmus converts the same plan into a Calcite TableModify of one ROWCOUNT BIGINT column. Written to the page instead, with one root name, the core refuses it: "Plan.Root names count (1) must match input record type depth-first named-field count (2)". Whether the core should derive that schema is a substrait-java question; what the page should say is not.
So which is meant: one count column, and of which type; the modified records; or WriteRel's OutputMode on UpdateRel too, with a count left to an aggregate above it? I lean to the last, because it makes the two relations answer the same question the same way, but then the spec also has to say what an unset mode means for the plans already written. Happy to send the docs change once it is decided.
the plan Isthmus produced, and how it was read back
{"relations":[{"root":{"input":{"update":{"namedTable":{"names":["T_RN"]},"tableSchema":{"names":["C0","C1"],"struct":{"types":[{"i64":{"nullability":"NULLABILITY_REQUIRED"}},{"i64":{"nullability":"NULLABILITY_NULLABLE"}}],"nullability":"NULLABILITY_REQUIRED"}},"condition":{"literal":{"boolean":true}},"transformations":[{"transformation":{"literal":{"i64":"0"}},"columnTarget":1}]}},"names":["C0","C1"]}}],"version":{"minorNumber":102,"producer":"isthmus"},"executionBehavior":{"variableEvalMode":"VARIABLE_EVALUATION_MODE_PER_PLAN"}}
UPDATE t_rn SET c1 = 0 over t_rn (c0 BIGINT NOT NULL, c1 BIGINT), Isthmus at substrait-java ade72bc2. The core's answer is new ProtoPlanConverter().from(plan) and the root's record type, [i64, i64?]; Isthmus's is the row type of the Calcite plan it converts the same plan into. substrait-go, substrait-python, DataFusion, DuckDB, substrait-java's Spark module and Acero report UpdateRel as unsupported, and substrait-validator returns no schema for it.
The page says only "Output is number of modified records" (
logical_relations.md, Property Maintenance). Neither it noralgebra.protosays what type that number has, whether it can be null, or how many columns anUpdateReloutputs. A root has to name every output column, so a producer has to choose.Isthmus writes a plain
UPDATEas anUpdateRelwhose root names the table's columns. Reading that plan back, substrait-java's core derives the table's schema, while Isthmus converts the same plan into a CalciteTableModifyof oneROWCOUNT BIGINTcolumn. Written to the page instead, with one root name, the core refuses it: "Plan.Root names count (1) must match input record type depth-first named-field count (2)". Whether the core should derive that schema is a substrait-java question; what the page should say is not.So which is meant: one count column, and of which type; the modified records; or
WriteRel'sOutputModeonUpdateReltoo, with a count left to an aggregate above it? I lean to the last, because it makes the two relations answer the same question the same way, but then the spec also has to say what an unset mode means for the plans already written. Happy to send the docs change once it is decided.the plan Isthmus produced, and how it was read back
{"relations":[{"root":{"input":{"update":{"namedTable":{"names":["T_RN"]},"tableSchema":{"names":["C0","C1"],"struct":{"types":[{"i64":{"nullability":"NULLABILITY_REQUIRED"}},{"i64":{"nullability":"NULLABILITY_NULLABLE"}}],"nullability":"NULLABILITY_REQUIRED"}},"condition":{"literal":{"boolean":true}},"transformations":[{"transformation":{"literal":{"i64":"0"}},"columnTarget":1}]}},"names":["C0","C1"]}}],"version":{"minorNumber":102,"producer":"isthmus"},"executionBehavior":{"variableEvalMode":"VARIABLE_EVALUATION_MODE_PER_PLAN"}}UPDATE t_rn SET c1 = 0overt_rn (c0 BIGINT NOT NULL, c1 BIGINT), Isthmus at substrait-javaade72bc2. The core's answer isnew ProtoPlanConverter().from(plan)and the root's record type,[i64, i64?]; Isthmus's is the row type of the Calcite plan it converts the same plan into. substrait-go, substrait-python, DataFusion, DuckDB, substrait-java's Spark module and Acero reportUpdateRelas unsupported, and substrait-validator returns no schema for it.