@Override
  public void onMatch(RelOptRuleCall call) {
    final TableScan tableScan = call.rel(0);
    if (!visited.add(tableScan)) {
      // Already visited
      return;
    }
    final String tableQName =
        ((RelOptHiveTable)tableScan.getTable()).getHiveTableMD().getFullyQualifiedName();
    final ValidWriteIdList tableCurrentTxnList =
        currentTxnList.getTableValidWriteIdList(tableQName);
    final ValidWriteIdList tableMaterializationTxnList =
        materializationTxnList.getTableValidWriteIdList(tableQName);
    if (TxnIdUtils.checkEquivalentWriteIds(tableCurrentTxnList, tableMaterializationTxnList)) {
      // This table has not been modified since materialization was created,
      // nothing to do
      return;
    }
    // ROW__ID: struct<transactionid:bigint,bucketid:int,rowid:bigint>
    int rowIDPos = tableScan.getTable().getRowType().getField(
        VirtualColumn.ROWID.getName(), false, false).getIndex();
    RexNode rowIDFieldAccess = rexBuilder.makeFieldAccess(
        rexBuilder.makeInputRef(tableScan.getTable().getRowType().getFieldList().get(rowIDPos).getType(), rowIDPos),
        0);
    // Now we create the filter with the transactions information.
    // In particular, each table in the materialization will only have contents such that:
    // ROW_ID.writeid <= high_watermark and ROW_ID.writeid not in (open/invalid_ids)
    // Hence, we add that condition on top of the source table.
    // The rewriting will then have the possibility to create partial rewritings that read
    // the materialization and the source tables, and hence, produce an incremental
    // rebuild that is more efficient than the full rebuild.
    final RelBuilder relBuilder = call.builder();
    relBuilder.push(tableScan);
    List<RexNode> conds = new ArrayList<>();
    RelDataType bigIntType = relBuilder.getTypeFactory().createSqlType(SqlTypeName.BIGINT);
    final RexNode literalHighWatermark = rexBuilder.makeLiteral(
        tableMaterializationTxnList.getHighWatermark(), bigIntType, false);
    conds.add(
        rexBuilder.makeCall(
            SqlStdOperatorTable.LESS_THAN_OR_EQUAL,
            ImmutableList.of(rowIDFieldAccess, literalHighWatermark)));
    for (long invalidTxn : tableMaterializationTxnList.getInvalidWriteIds()) {
      final RexNode literalInvalidTxn = rexBuilder.makeLiteral(
          invalidTxn, bigIntType, false);
      conds.add(
          rexBuilder.makeCall(
              SqlStdOperatorTable.NOT_EQUALS,
              ImmutableList.of(rowIDFieldAccess, literalInvalidTxn)));
    }
    relBuilder.filter(conds);
    call.transformTo(relBuilder.build());
  }
This rule will rewrite the materialized view with information about
its invalidation data. In particular, if any of the tables used by the
materialization has been updated since the materialization was created,
it will introduce a filter operator on top of that table in the materialization
definition, making explicit the data contained in it so the rewriting
algorithm can use this information to rewrite the query as a combination of the
outdated materialization data and the new original data in the source tables.
If the data in the source table matches the current data in the snapshot,
no filter is created.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HiveAugmentMaterializationRule.java