kasakrisz commented on code in PR #4943:
URL: https://github.com/apache/hive/pull/4943#discussion_r1487363349


##########
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HiveRowIsDeletedPropagator.java:
##########
@@ -92,86 +159,155 @@ public RelNode visit(HiveTableScan scan) {
         .build();
   }
 
-  /**
-   * Create a new Project with original projected columns plus add 
rowIsDeleted as last column referencing
-   * the last column of the input {@link RelNode}.
-   * @param project - {@link HiveProject to transform}
-   * @return new Project
-   */
-  @Override
-  public RelNode visit(HiveProject project) {
-    RelNode newProject = visitChild(project, 0, project.getInput());
+  // Add the new columns(_deleted, _inserted) to the original project
+  public RelNode visit(HiveProject project, Context context) {
+    RelNode newProject = visitChild(project, 0, project.getInput(), context);
     RelNode projectInput = newProject.getInput(0);
-    int rowIsDeletedIndex = projectInput.getRowType().getFieldCount() - 1;
+
     List<RexNode> newProjects = new 
ArrayList<>(project.getRowType().getFieldCount() + 1);
     newProjects.addAll(project.getProjects());
-
-    RexNode rowIsDeleted = relBuilder.getRexBuilder().makeInputRef(
-            
projectInput.getRowType().getFieldList().get(rowIsDeletedIndex).getType(), 
rowIsDeletedIndex);
-    newProjects.add(rowIsDeleted);
+    newProjects.add(createInputRef(projectInput, 2));
+    newProjects.add(createInputRef(projectInput, 1));
 
     return relBuilder
-            .push(projectInput)
-            .project(newProjects)
-            .build();
-  }
-
-  /**
-   * Create new Join and a Project on top of it.
-   * @param join - {@link HiveJoin} to transform
-   * @return - new Join with a Project on top
-   */
-  @Override
-  public RelNode visit(HiveJoin join) {
-    // Propagate rowISDeleted to left input
-    RelNode tmpJoin = visitChild(join, 0, join.getInput(0));
-    RelNode leftInput = tmpJoin.getInput(0);
-    RelDataType leftRowType = tmpJoin.getInput(0).getRowType();
-    int leftRowIsDeletedIndex = leftRowType.getFieldCount() - 1;
-    // Propagate rowISDeleted to right input
-    tmpJoin = visitChild(join, 1, join.getInput(1));
-    RelNode rightInput = tmpJoin.getInput(1);
-    RelDataType rightRowType = rightInput.getRowType();
-    int rightRowIsDeletedIndex = rightRowType.getFieldCount() - 1;
-
-    // Create input ref to rowIsDeleted columns in left and right inputs
+        .push(projectInput)
+        .project(newProjects)
+        .build();
+  }
+
+  // Union rewrite algorithm pulls up all the predicates on rowId on top of 
top Join operator:
+  // Example:
+  //   HiveUnion(all=[true])
+  //    ...
+  //    HiveFilter(condition=[OR(<(1, $14.writeid), <(1, $6.writeid))])
+  //      HiveJoin(condition=[=($0, $8)], joinType=[inner], algorithm=[none], 
cost=[not available])
+  // Check the filter condition and collect operands of OR expressions 
referencing only one column
+  public RelNode visit(HiveFilter filter, Context context) {
+    RexNode condition = filter.getCondition();
+
+    // The condition might be a single predicate on the rowId (if only one 
table changed)
+    RexInputRef rexInputRef = findPossibleRowIdRef(filter.getCondition());
+    if (rexInputRef != null) {
+      context.rowIdPredicates.put(rexInputRef.getIndex(), 
filter.getCondition());
+      return visitChild(filter, 0, filter.getInput(0), context);
+    }
+
+    if (!condition.isA(SqlKind.OR)) {
+      return visitChild(filter, 0, filter.getInput(0), context);
+    }
+
+    for (RexNode operand : ((RexCall)condition).operands) {
+      RexInputRef inputRef = findPossibleRowIdRef(operand);
+      if (inputRef == null) {
+        continue;
+      }
+      context.rowIdPredicates.put(inputRef.getIndex(), operand);
+    }
+
+    return visitChild(filter, 0, filter.getInput(0), context);
+  }
+
+  private RexInputRef findPossibleRowIdRef(RexNode operand) {
+    Set<RexInputRef> inputRefs = findRexInputRefs(operand);
+    if (inputRefs.size() != 1) {
+      return null;
+    }
+
+    // This is a candidate for predicate on rowId
+    return inputRefs.iterator().next();
+  }
+
+  // Propagate new column to each side of the join.
+  // Create a project to combine the propagated expressions.
+  // Create a filter to remove rows which are joined from a deleted and a 
newly inserted row.
+  public RelNode visit(HiveJoin join, Context context) {
+    // Propagate columns to left input
+    RelNode tmpJoin = visitChild(join, 0, join.getInput(0), context);
+    RelNode newLeftInput = tmpJoin.getInput(0);
+    RelDataType newLeftRowType = newLeftInput.getRowType();
+    // Propagate columns to right input.
+    // All column references should be shifted in candidate predicates to the 
left
+    Context rightContext = new Context();
+    int originalLeftFieldCount = join.getInput(0).getRowType().getFieldCount();
+    for (Map.Entry<Integer, RexNode> entry : 
context.rowIdPredicates.entrySet()) {
+      if (entry.getKey() > originalLeftFieldCount) {
+        rightContext.rowIdPredicates.put(entry.getKey() - 
originalLeftFieldCount,
+          new InputRefShifter(originalLeftFieldCount, -originalLeftFieldCount, 
relBuilder).apply(entry.getValue()));
+      }
+    }
+    tmpJoin = visitChild(join, 1, join.getInput(1), rightContext);
+    RelNode newRightInput = tmpJoin.getInput(1);
+    RelDataType newRightRowType = newRightInput.getRowType();
+
+    // Create input refs to propagated columns in left and right inputs
+    int rightAnyDeletedIndex = newRightRowType.getFieldCount() - 2;

Review Comment:
   No. At this point the new right input schema has at least two new columns.



-- 
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: gitbox-unsubscr...@hive.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscr...@hive.apache.org
For additional commands, e-mail: gitbox-h...@hive.apache.org

Reply via email to