This is an automated email from the ASF dual-hosted git repository.
krisztiankasa pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new eab6809fbbb HIVE-27867: Incremental materialized view throws NPE whew
Iceberg source table is empty (Krisztian Kasa, reviewed by Denys Kuzmenko)
eab6809fbbb is described below
commit eab6809fbbb6274efea07a6649dab19269f48850
Author: Krisztian Kasa <[email protected]>
AuthorDate: Thu Nov 30 06:07:14 2023 +0100
HIVE-27867: Incremental materialized view throws NPE whew Iceberg source
table is empty (Krisztian Kasa, reviewed by Denys Kuzmenko)
---
.../HiveAugmentSnapshotMaterializationRule.java | 38 +++++----
.../rules/views/HiveMaterializedViewUtils.java | 6 +-
.../views/HivePushdownSnapshotFilterRule.java | 5 +-
...TestHiveAugmentSnapshotMaterializationRule.java | 90 ++++++++++++++++++++++
.../views/TestHivePushdownSnapshotFilterRule.java | 82 ++++++++++++++++++++
.../calcite/rules/views/TestRuleBase.java | 84 ++++++++++++++++++++
6 files changed, 284 insertions(+), 21 deletions(-)
diff --git
a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HiveAugmentSnapshotMaterializationRule.java
b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HiveAugmentSnapshotMaterializationRule.java
index 26ff609ab6e..003b7c86ef6 100644
---
a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HiveAugmentSnapshotMaterializationRule.java
+++
b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HiveAugmentSnapshotMaterializationRule.java
@@ -17,13 +17,14 @@
package org.apache.hadoop.hive.ql.optimizer.calcite.rules.views;
-import com.google.common.collect.ImmutableList;
+import com.google.common.annotations.VisibleForTesting;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelRule;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
@@ -37,12 +38,13 @@ import
org.apache.hadoop.hive.ql.optimizer.calcite.HiveRelFactories;
import org.apache.hadoop.hive.ql.optimizer.calcite.RelOptHiveTable;
import org.apache.hadoop.hive.ql.optimizer.calcite.translator.TypeConverter;
-import java.util.ArrayList;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
+import static java.util.Collections.singletonList;
+
/**
* This rule will rewrite the materialized view with information about
* its invalidation data. In particular, if any of the tables used by the
@@ -90,12 +92,13 @@ public class HiveAugmentSnapshotMaterializationRule extends
RelRule<HiveAugmentS
private static RelDataType snapshotIdType = null;
- private static RelDataType snapshotIdType(RelBuilder relBuilder) {
+ @VisibleForTesting
+ static RelDataType snapshotIdType(RelDataTypeFactory typeFactory) {
if (snapshotIdType == null) {
try {
- snapshotIdType = relBuilder.getTypeFactory().createSqlType(
+ snapshotIdType = typeFactory.createSqlType(
TypeConverter.convert(VirtualColumn.SNAPSHOT_ID.getTypeInfo(),
- relBuilder.getTypeFactory()).getSqlTypeName());
+ typeFactory).getSqlTypeName());
} catch (CalciteSemanticException e) {
throw new RuntimeException(e);
}
@@ -125,11 +128,17 @@ public class HiveAugmentSnapshotMaterializationRule
extends RelRule<HiveAugmentS
Table table = hiveTable.getHiveTableMD();
SnapshotContext mvMetaTableSnapshot =
mvMetaStoredSnapshot.get(table.getFullyQualifiedName());
- if
(mvMetaTableSnapshot.equals(table.getStorageHandler().getCurrentSnapshotContext(table)))
{
+ if (table.getStorageHandler() == null) {
+ throw new UnsupportedOperationException(String.format("Table %s does not
have Storage handler defined. " +
+ "Mixing native and non-native tables in a materialized view
definition is currently not supported!",
+ table.getFullyQualifiedName()));
+ }
+ if (Objects.equals(mvMetaTableSnapshot,
table.getStorageHandler().getCurrentSnapshotContext(table))) {
return;
}
-
table.setVersionIntervalFrom(Long.toString(mvMetaTableSnapshot.getSnapshotId()));
+ Long snapshotId = mvMetaTableSnapshot != null ?
mvMetaTableSnapshot.getSnapshotId() : null;
+ table.setVersionIntervalFrom(Objects.toString(snapshotId, null));
RexBuilder rexBuilder = call.builder().getRexBuilder();
int snapshotIdIndex = tableScan.getTable().getRowType().getField(
@@ -139,14 +148,11 @@ public class HiveAugmentSnapshotMaterializationRule
extends RelRule<HiveAugmentS
final RelBuilder relBuilder = call.builder();
relBuilder.push(tableScan);
- List<RexNode> conds = new ArrayList<>();
- final RexNode literalHighWatermark = rexBuilder.makeLiteral(
- mvMetaTableSnapshot.getSnapshotId(), snapshotIdType(relBuilder),
false);
- conds.add(
- rexBuilder.makeCall(
- SqlStdOperatorTable.LESS_THAN_OR_EQUAL,
- ImmutableList.of(snapshotIdInputRef, literalHighWatermark)));
- relBuilder.filter(conds);
+ final RexNode snapshotIdLiteral = rexBuilder.makeLiteral(
+ snapshotId, snapshotIdType(relBuilder.getTypeFactory()), false);
+ final RexNode predicateWithSnapShotId = rexBuilder.makeCall(
+ SqlStdOperatorTable.LESS_THAN_OR_EQUAL, snapshotIdInputRef,
snapshotIdLiteral);
+ relBuilder.filter(singletonList(predicateWithSnapShotId));
call.transformTo(relBuilder.build());
}
}
\ No newline at end of file
diff --git
a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HiveMaterializedViewUtils.java
b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HiveMaterializedViewUtils.java
index b00067f9fd2..8c612e48af2 100644
---
a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HiveMaterializedViewUtils.java
+++
b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HiveMaterializedViewUtils.java
@@ -16,6 +16,7 @@
*/
package org.apache.hadoop.hive.ql.optimizer.calcite.rules.views;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.math.BigDecimal;
@@ -79,7 +80,6 @@ import
org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType
import
org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject;
import org.apache.hadoop.hive.ql.session.SessionState;
import org.apache.hive.common.util.TxnIdUtils;
-import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -284,8 +284,8 @@ public class HiveMaterializedViewUtils {
/**
* Method to apply a rule to a query plan.
*/
- @NotNull
- private static RelNode applyRule(
+ @VisibleForTesting
+ static RelNode applyRule(
RelNode basePlan, RelOptRule relOptRule) {
final HepProgramBuilder programBuilder = new HepProgramBuilder();
programBuilder.addRuleInstance(relOptRule);
diff --git
a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HivePushdownSnapshotFilterRule.java
b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HivePushdownSnapshotFilterRule.java
index 2de1046d219..055ff91d510 100644
---
a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HivePushdownSnapshotFilterRule.java
+++
b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/HivePushdownSnapshotFilterRule.java
@@ -38,6 +38,7 @@ import
org.apache.hadoop.hive.ql.optimizer.calcite.HiveRelFactories;
import org.apache.hadoop.hive.ql.optimizer.calcite.RelOptHiveTable;
import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveFilter;
+import java.util.Objects;
import java.util.Set;
/**
@@ -116,7 +117,7 @@ public class HivePushdownSnapshotFilterRule extends
RelRule<HivePushdownSnapshot
return false;
}
- long snapshotId = literal.getValueAs(Long.class);
+ Long snapshotId = literal.getValueAs(Long.class);
RelOptTable relOptTable = getRelOptTableOf(op2);
if (relOptTable == null) {
@@ -124,7 +125,7 @@ public class HivePushdownSnapshotFilterRule extends
RelRule<HivePushdownSnapshot
}
RelOptHiveTable hiveTable = (RelOptHiveTable) relOptTable;
-
hiveTable.getHiveTableMD().setVersionIntervalFrom(Long.toString(snapshotId));
+
hiveTable.getHiveTableMD().setVersionIntervalFrom(Objects.toString(snapshotId,
null));
return true;
}
diff --git
a/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/TestHiveAugmentSnapshotMaterializationRule.java
b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/TestHiveAugmentSnapshotMaterializationRule.java
new file mode 100644
index 00000000000..746343d8145
--- /dev/null
+++
b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/TestHiveAugmentSnapshotMaterializationRule.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.optimizer.calcite.rules.views;
+
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.rel.RelNode;
+import org.apache.hadoop.hive.common.type.SnapshotContext;
+import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveFilter;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.mockito.Mockito.doReturn;
+
+@RunWith(MockitoJUnitRunner.class)
+public class TestHiveAugmentSnapshotMaterializationRule extends TestRuleBase {
+
+ @Test
+ public void testWhenSnapshotAndTableAreEmptyNoFilterAdded() {
+ RelNode tableScan = createTS();
+ RelOptRule rule =
HiveAugmentSnapshotMaterializationRule.with(Collections.emptyMap());
+
+ RelNode newRoot = HiveMaterializedViewUtils.applyRule(tableScan, rule);
+
+ assertThat(newRoot, is(tableScan));
+ }
+
+ @Test
+ public void
testWhenNoSnapshotButTableHasNewDataAFilterWithDefaultSnapshotIDAdded() {
+ doReturn(new
SnapshotContext(42)).when(table2storageHandler).getCurrentSnapshotContext(table2);
+ RelNode tableScan = createTS();
+ RelOptRule rule =
HiveAugmentSnapshotMaterializationRule.with(Collections.emptyMap());
+
+ RelNode newRoot = HiveMaterializedViewUtils.applyRule(tableScan, rule);
+
+ assertThat(newRoot, instanceOf(HiveFilter.class));
+ HiveFilter filter = (HiveFilter) newRoot;
+ assertThat(filter.getCondition().toString(), is("<=($3, null)"));
+ }
+
+ @Test
+ public void testWhenMVAndTableCurrentSnapshotAreTheSameNoFilterAdded() {
+ doReturn(new
SnapshotContext(42)).when(table2storageHandler).getCurrentSnapshotContext(table2);
+ RelNode tableScan = createTS();
+ Map<String, SnapshotContext> mvSnapshot = new HashMap<>();
+ mvSnapshot.put(table2.getFullyQualifiedName(), new SnapshotContext(42));
+ RelOptRule rule = HiveAugmentSnapshotMaterializationRule.with(mvSnapshot);
+
+ RelNode newRoot = HiveMaterializedViewUtils.applyRule(tableScan, rule);
+
+ assertThat(newRoot, is(tableScan));
+ }
+
+ @Test
+ public void
testWhenMVSnapshotIsDifferentThanTableCurrentSnapshotHasNewDataAFilterWithMVSnapshotIdAdded()
{
+ doReturn(new
SnapshotContext(10)).when(table2storageHandler).getCurrentSnapshotContext(table2);
+ RelNode tableScan = createTS();
+ Map<String, SnapshotContext> mvSnapshot = new HashMap<>();
+ mvSnapshot.put(table2.getFullyQualifiedName(), new SnapshotContext(42));
+ RelOptRule rule = HiveAugmentSnapshotMaterializationRule.with(mvSnapshot);
+
+ RelNode newRoot = HiveMaterializedViewUtils.applyRule(tableScan, rule);
+
+ assertThat(newRoot, instanceOf(HiveFilter.class));
+ HiveFilter filter = (HiveFilter) newRoot;
+ assertThat(filter.getCondition().toString(), is("<=($3, 42)"));
+ }
+}
\ No newline at end of file
diff --git
a/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/TestHivePushdownSnapshotFilterRule.java
b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/TestHivePushdownSnapshotFilterRule.java
new file mode 100644
index 00000000000..c60d83a8df4
--- /dev/null
+++
b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/TestHivePushdownSnapshotFilterRule.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.optimizer.calcite.rules.views;
+
+import org.apache.calcite.plan.RelOptSchema;
+import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.tools.RelBuilder;
+import org.apache.hadoop.hive.ql.optimizer.calcite.HiveRelFactories;
+import org.apache.hadoop.hive.ql.optimizer.calcite.RelOptHiveTable;
+import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveTableScan;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+
+@RunWith(MockitoJUnitRunner.class)
+public class TestHivePushdownSnapshotFilterRule extends TestRuleBase {
+
+ @Mock
+ private RelOptSchema schemaMock;
+
+ @Test
+ public void
testFilterIsRemovedAndVersionIntervalFromIsSetWhenFilterHasSnapshotIdPredicate()
{
+ RelNode tableScan = createTS();
+
+ RelBuilder relBuilder =
HiveRelFactories.HIVE_BUILDER.create(relOptCluster, schemaMock);
+ RelNode root = relBuilder.push(tableScan)
+ .filter(REX_BUILDER.makeCall(SqlStdOperatorTable.LESS_THAN_OR_EQUAL,
+
REX_BUILDER.makeInputRef(HiveAugmentSnapshotMaterializationRule.snapshotIdType(TYPE_FACTORY),
3),
+ REX_BUILDER.makeLiteral(42,
TYPE_FACTORY.createSqlType(SqlTypeName.INTEGER), false)))
+ .build();
+
+ System.out.println(RelOptUtil.toString(root));
+
+ RelNode newRoot = HiveMaterializedViewUtils.applyRule(root,
HivePushdownSnapshotFilterRule.INSTANCE);
+
+ assertThat(newRoot, instanceOf(HiveTableScan.class));
+ HiveTableScan newScan = (HiveTableScan) newRoot;
+ RelOptHiveTable optHiveTable = (RelOptHiveTable) newScan.getTable();
+ assertThat(optHiveTable.getHiveTableMD().getVersionIntervalFrom(),
is("42"));
+ }
+
+ @Test
+ public void testFilterLeftIntactWhenItDoesNotHaveSnapshotIdPredicate() {
+ RelNode tableScan = createTS();
+
+ RelBuilder relBuilder =
HiveRelFactories.HIVE_BUILDER.create(relOptCluster, schemaMock);
+ RelNode root = relBuilder.push(tableScan)
+ .filter(REX_BUILDER.makeCall(SqlStdOperatorTable.LESS_THAN_OR_EQUAL,
+
REX_BUILDER.makeInputRef(TYPE_FACTORY.createSqlType(SqlTypeName.INTEGER), 1),
+ REX_BUILDER.makeLiteral(42,
TYPE_FACTORY.createSqlType(SqlTypeName.INTEGER), false)))
+ .build();
+
+ System.out.println(RelOptUtil.toString(root));
+
+ RelNode newRoot = HiveMaterializedViewUtils.applyRule(root,
HivePushdownSnapshotFilterRule.INSTANCE);
+
+ assertThat(newRoot.getDigest(), is(root.getDigest()));
+ }
+}
diff --git
a/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/TestRuleBase.java
b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/TestRuleBase.java
new file mode 100644
index 00000000000..2d1d8133dd7
--- /dev/null
+++
b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/views/TestRuleBase.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.optimizer.calcite.rules.views;
+
+import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.ql.metadata.HiveStorageHandler;
+import org.apache.hadoop.hive.ql.metadata.Table;
+import org.apache.hadoop.hive.ql.metadata.VirtualColumn;
+import org.apache.hadoop.hive.ql.optimizer.calcite.HiveTypeSystemImpl;
+import org.apache.hadoop.hive.ql.optimizer.calcite.RelOptHiveTable;
+import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveRelNode;
+import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveTableScan;
+import org.apache.hadoop.hive.ql.parse.CalcitePlanner;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.mockito.Mock;
+
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.mockito.Mockito.doReturn;
+
+public class TestRuleBase {
+ protected static final RexBuilder REX_BUILDER = new RexBuilder(new
JavaTypeFactoryImpl(new HiveTypeSystemImpl()));
+ protected static final RelDataTypeFactory TYPE_FACTORY =
REX_BUILDER.getTypeFactory();
+
+ protected static RelOptCluster relOptCluster;
+ @Mock
+ protected RelOptHiveTable table2Mock;
+ protected static RelDataType table2Type;
+ protected static Table table2;
+ @Mock
+ protected static HiveStorageHandler table2storageHandler;
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ RelOptPlanner planner = CalcitePlanner.createPlanner(new HiveConf());
+ relOptCluster = RelOptCluster.create(planner, REX_BUILDER);
+ List<RelDataType> t2Schema = asList(
+ TYPE_FACTORY.createSqlType(SqlTypeName.INTEGER),
+ TYPE_FACTORY.createSqlType(SqlTypeName.VARCHAR),
+ TYPE_FACTORY.createSqlType(SqlTypeName.INTEGER),
+ HiveAugmentSnapshotMaterializationRule.snapshotIdType(TYPE_FACTORY));
+ table2Type = TYPE_FACTORY.createStructType(t2Schema, asList("d", "e", "f",
VirtualColumn.SNAPSHOT_ID.getName()));
+ table2 = new Table();
+ table2.setTTable(new org.apache.hadoop.hive.metastore.api.Table());
+ table2.setDbName("default");
+ table2.setTableName("t2");
+ }
+
+ @Before
+ public void setup() {
+ doReturn(table2Type).when(table2Mock).getRowType();
+ doReturn(table2).when(table2Mock).getHiveTableMD();
+ table2.setStorageHandler(table2storageHandler);
+ }
+
+ protected HiveTableScan createTS() {
+ return new HiveTableScan(relOptCluster,
relOptCluster.traitSetOf(HiveRelNode.CONVENTION),
+ table2Mock, "t2", null, false, false);
+ }
+}