zzwqqq commented on code in PR #5211:
URL: https://github.com/apache/calcite/pull/5211#discussion_r3860829167
##########
core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableModifyRule.java:
##########
@@ -44,18 +93,89 @@ protected EnumerableTableModifyRule(Config config) {
@Override public @Nullable RelNode convert(RelNode rel) {
final TableModify modify = (TableModify) rel;
+ final RelOptCluster cluster = modify.getCluster();
final ModifiableTable modifiableTable =
modify.getTable().unwrap(ModifiableTable.class);
if (modifiableTable == null) {
return null;
}
final RelTraitSet traitSet =
modify.getTraitSet().replace(EnumerableConvention.INSTANCE);
+ RelNode input = convert(modify.getInput(), traitSet);
+ if (modify.isInsert() || modify.isUpdate()) {
+ // INSERT assigns stored columns; UPDATE assigns columns in the SET list.
+ RelDataType assignmentType = modify.isInsert()
+ ? RelOptTableImpl.realRowType(modify.getTable())
+ : modify.getCatalogReader().createTypeFromProjection(
+ modify.getTable().getRowType(),
+ requireNonNull(modify.getUpdateColumnList(),
"updateColumnList"));
+ if (modify.isFlattened()) {
+ // TableModify flattens its input, so flatten the target fields too.
+ assignmentType =
+ SqlTypeUtil.flattenRecordType(cluster.getTypeFactory(),
assignmentType, null);
+ }
+
+ final RexBuilder rexBuilder = cluster.getRexBuilder();
+ final List<RexNode> projects =
+ new ArrayList<>(rexBuilder.identityProjects(input.getRowType()));
+ final List<RexNode> checks = new ArrayList<>();
+ // UPDATE appends SET values to the old row; INSERT has only new values.
+ final int assignmentOffset = projects.size() -
assignmentType.getFieldCount();
+ for (RelDataTypeField field : assignmentType.getFieldList()) {
+ final int sourceOrdinal = assignmentOffset + field.getIndex();
+ final RexNode source = projects.get(sourceOrdinal);
+ final RelDataType targetType = field.getType();
+ final SqlTypeName targetName = targetType.getSqlTypeName();
+ if (SqlTypeUtil.inCharOrBinaryFamilies(targetType)) {
+ if (targetType.getPrecision() < 0) {
+ continue;
+ }
+ // Check character and binary lengths because their casts may
truncate.
Review Comment:
Thanks for reviewing. Just to make sure I understand: are you suggesting a
hook for each target type that can validate or convert a value before it is
assigned to the target column? Would you expect the generated code for
EnumerableTableModify to call this hook at execution time, or would the hook
build a Rex expression in the input plan?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]