xtern commented on code in PR #2446:
URL: https://github.com/apache/ignite-3/pull/2446#discussion_r1297269659


##########
modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlToRelConvertor.java:
##########
@@ -69,6 +83,111 @@ public IgniteSqlToRelConvertor(
         }
     }
 
+    @Override protected RelNode convertInsert(SqlInsert call) {
+        datasetStack.push(call);
+
+        RelNode rel = super.convertInsert(call);
+
+        datasetStack.pop();
+
+        return rel;
+    }
+
+    private static class DefaultChecker extends SqlShuttle {
+        private boolean hasDefaults(SqlCall call) {
+            try {
+                call.accept(this);
+                return false;
+            } catch (ControlFlowException e) {
+                return true;
+            }
+        }
+
+        @Override public @Nullable SqlNode visit(SqlCall call) {
+            if (call.getKind() == SqlKind.DEFAULT) {
+                throw new ControlFlowException();
+            }
+
+            return super.visit(call);
+        }
+    }
+
+    @Override public RelNode convertValues(SqlCall values, RelDataType 
targetRowType) {
+        DefaultChecker checker = new DefaultChecker();
+
+        boolean hasDefaults = checker.hasDefaults(values);
+
+        if (hasDefaults) {
+            SqlValidatorScope scope = validator.getOverScope(values);
+            assert scope != null;
+            Blackboard bb = createBlackboard(scope, null, false);
+
+            convertValuesImplEx(bb, values, targetRowType);
+            return bb.root();
+        } else {
+            // a bit lightweight than default processing one.
+            return super.convertValues(values, targetRowType);
+        }
+    }
+
+    private void convertValuesImplEx(Blackboard bb, SqlCall values, 
RelDataType targetRowType) {
+        SqlCall insertOp = datasetStack.peek();
+        assert insertOp instanceof SqlInsert;
+        assert values == ((SqlInsert) insertOp).getSource();
+        RelOptTable targetTable = getTargetTable(insertOp);
+        assert targetTable != null;
+
+        IgniteTable ignTable = targetTable.unwrap(IgniteTable.class);
+
+        List<RelDataTypeField> tblFields = 
targetTable.getRowType().getFieldList();
+        List<String> targetFields = targetRowType.getFieldNames();
+
+        for (SqlNode rowConstructor : values.getOperandList()) {
+            SqlCall rowConstructor0 = (SqlCall) rowConstructor;
+
+            List<Pair<RexNode, String>> exps = new 
ArrayList<>(targetFields.size());
+
+            int mapping[] = new int[targetFields.size()];
+
+            int pos = 0;
+
+            for (String fld : targetFields) {
+                int tblPos = 0;
+                for (RelDataTypeField tblFld : tblFields) {
+                    if (tblFld.getName().equals(fld)) {
+                        mapping[pos++] = tblPos;
+                        break;
+                    }
+                    ++tblPos;
+                }
+            }
+
+            pos = 0;
+            for (String fld : targetFields) {
+                SqlNode operand = rowConstructor0.getOperandList().get(pos);
+
+                if (operand.getKind() == SqlKind.DEFAULT) {
+                    RexNode def = 
ignTable.descriptor().newColumnDefaultValue(targetTable, mapping[pos], bb);
+
+                    exps.add(Pair.of(def, SqlValidatorUtil.alias(operand, 
pos)));
+                } else {
+                    exps.add(Pair.of(bb.convertExpression(operand), 
SqlValidatorUtil.alias(operand, pos)));
+                }
+
+                ++pos;
+            }

Review Comment:
   it seems to me that we can avoid last cycle.
   Using something like this:
   ```suggestion
               for (String fld : targetFields) {
                   for (int tblPos = 0; tblPos < tblFields.size(); tblPos++) {
                       if (!tblFields.get(tblPos).getName().equals(fld)) {
                           continue;
                       }
   
                       SqlNode operand = 
rowConstructor0.getOperandList().get(pos);
   
                       if (operand.getKind() == SqlKind.DEFAULT) {
                           RexNode def = 
ignTable.descriptor().newColumnDefaultValue(targetTable, tblPos, bb);
   
                           exps.add(Pair.of(def, 
SqlValidatorUtil.alias(operand, pos)));
                       } else {
                           exps.add(Pair.of(bb.convertExpression(operand), 
SqlValidatorUtil.alias(operand, pos)));
                       }
   
                       ++pos;
   
                       break;
                   }
               }
   ```



-- 
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]

Reply via email to