use of org.apache.drill.exec.physical.impl.MockRecordBatch in project drill by apache.
the class TestLateralJoinCorrectness method testLeftLateralJoin_WithMatchingAndEmptyBatch.
/**
* Test to see if there are multiple rows in left batch and for some rows right side produces multiple batches such
* that some are with records and some are empty then we are not duplicating those left side records based on left
* join type. In this case all the output will be produces only in 1 record batch.
*
* @throws Exception
*/
@Test
public void testLeftLateralJoin_WithMatchingAndEmptyBatch() throws Exception {
// Get the left container with dummy data for Lateral Join
final RowSet.SingleRowSet leftRowSet2 = fixture.rowSetBuilder(leftSchema).addRow(1, 10, "item10").addRow(2, 20, "item20").build();
final RowSet.SingleRowSet nonEmptyRightRowSet2 = fixture.rowSetBuilder(rightSchema).addRow(2, 6, 60, "item61").addRow(2, 7, 70, "item71").addRow(2, 8, 80, "item81").build();
leftContainer.add(leftRowSet2.container());
// Get the left IterOutcomes for Lateral Join
leftOutcomes.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
// Create Left MockRecordBatch
final CloseableRecordBatch leftMockBatch = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, leftContainer, leftOutcomes, leftContainer.get(0).getSchema());
// Get the right container with dummy data
rightContainer.add(emptyRightRowSet.container());
rightContainer.add(nonEmptyRightRowSet.container());
rightContainer.add(nonEmptyRightRowSet2.container());
rightContainer.add(emptyRightRowSet.container());
rightContainer.add(emptyRightRowSet.container());
rightOutcomes.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
rightOutcomes.add(RecordBatch.IterOutcome.OK);
rightOutcomes.add(RecordBatch.IterOutcome.OK);
rightOutcomes.add(RecordBatch.IterOutcome.OK);
rightOutcomes.add(RecordBatch.IterOutcome.EMIT);
final CloseableRecordBatch rightMockBatch = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, rightContainer, rightOutcomes, rightContainer.get(0).getSchema());
final LateralJoinPOP popConfig = new LateralJoinPOP(null, null, JoinRelType.LEFT, DrillLateralJoinRelBase.IMPLICIT_COLUMN, Lists.newArrayList());
final LateralJoinBatch ljBatch = new LateralJoinBatch(popConfig, fixture.getFragmentContext(), leftMockBatch, rightMockBatch);
try {
// 3 for first left row and 1 for second left row
final int expectedOutputRecordCount = 6;
assertTrue(RecordBatch.IterOutcome.OK_NEW_SCHEMA == ljBatch.next());
assertTrue(RecordBatch.IterOutcome.OK == ljBatch.next());
assertTrue(ljBatch.getRecordCount() == expectedOutputRecordCount);
assertTrue(RecordBatch.IterOutcome.NONE == ljBatch.next());
} catch (AssertionError | Exception error) {
fail();
} finally {
// Close all the resources for this test case
ljBatch.close();
leftMockBatch.close();
rightMockBatch.close();
leftRowSet2.clear();
nonEmptyRightRowSet2.clear();
}
}
use of org.apache.drill.exec.physical.impl.MockRecordBatch in project drill by apache.
the class TestLateralJoinCorrectness method testMultiLevelLateral.
/**
* This test generates an operator tree for multi level LATERAL by stacking 2 LATERAL and finally an UNNEST pair
* (using MockRecord Batch) as left and right child of lower level LATERAL. Then we call next() on top level
* LATERAL to simulate the operator tree and compare the outcome and record count generated with expected values.
* @throws Exception
*/
@Test
public void testMultiLevelLateral() throws Exception {
// ** Prepare first pair of left batch and right batch for Lateral_1 **
final LateralJoinPOP popConfig_1 = new LateralJoinPOP(null, null, JoinRelType.INNER, DrillLateralJoinRelBase.IMPLICIT_COLUMN, Lists.newArrayList());
// Create a left batch with implicit column for lower lateral left unnest
TupleMetadata leftSchemaWithImplicit = new SchemaBuilder().add(popConfig_1.getImplicitRIDColumn(), TypeProtos.MinorType.INT).add("id_left", TypeProtos.MinorType.INT).add("cost_left", TypeProtos.MinorType.INT).add("name_left", TypeProtos.MinorType.VARCHAR).buildSchema();
final RowSet.SingleRowSet emptyLeftRowSet_1 = fixture.rowSetBuilder(leftSchemaWithImplicit).build();
final RowSet.SingleRowSet nonEmptyLeftRowSet_1 = fixture.rowSetBuilder(leftSchemaWithImplicit).addRow(1, 1, 10, "item1").build();
final RowSet.SingleRowSet nonEmptyLeftRowSet_2 = fixture.rowSetBuilder(leftSchemaWithImplicit).addRow(1, 2, 20, "item2").build();
leftContainer.add(emptyLeftRowSet_1.container());
leftContainer.add(nonEmptyLeftRowSet_1.container());
leftContainer.add(nonEmptyLeftRowSet_2.container());
// Get the left IterOutcomes for Lateral Join
leftOutcomes.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
leftOutcomes.add(RecordBatch.IterOutcome.OK);
leftOutcomes.add(RecordBatch.IterOutcome.EMIT);
final CloseableRecordBatch leftMockBatch_1 = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, leftContainer, leftOutcomes, leftContainer.get(0).getSchema());
// Get the right container with dummy data
final RowSet.SingleRowSet nonEmptyRightRowSet_1 = fixture.rowSetBuilder(rightSchema).addRow(1, 5, 51, "item51").addRow(1, 6, 61, "item61").addRow(1, 7, 71, "item71").build();
rightContainer.add(emptyRightRowSet.container());
rightContainer.add(nonEmptyRightRowSet.container());
rightContainer.add(nonEmptyRightRowSet_1.container());
rightOutcomes.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
rightOutcomes.add(RecordBatch.IterOutcome.EMIT);
rightOutcomes.add(RecordBatch.IterOutcome.EMIT);
final CloseableRecordBatch rightMockBatch_1 = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, rightContainer, rightOutcomes, rightContainer.get(0).getSchema());
final LateralJoinBatch lowerLateral = new LateralJoinBatch(popConfig_1, fixture.getFragmentContext(), leftMockBatch_1, rightMockBatch_1);
// ** Prepare second pair of left and right batch for Lateral_2 **
// Create left input schema
TupleMetadata leftSchema2 = new SchemaBuilder().add("id_left_1", TypeProtos.MinorType.INT).add("cost_left_1", TypeProtos.MinorType.INT).add("name_left_1", TypeProtos.MinorType.VARCHAR).buildSchema();
final RowSet.SingleRowSet emptyLeftRowSet2 = fixture.rowSetBuilder(leftSchema2).build();
final RowSet.SingleRowSet nonEmptyLeftRowSet2 = fixture.rowSetBuilder(leftSchema2).addRow(6, 60, "item6").build();
// Get the left container with dummy data
final List<VectorContainer> leftContainer2 = new ArrayList<>(5);
leftContainer2.add(emptyLeftRowSet2.container());
leftContainer2.add(nonEmptyLeftRowSet2.container());
// Get the left outcomes with dummy data
final List<RecordBatch.IterOutcome> leftOutcomes2 = new ArrayList<>(5);
leftOutcomes2.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
leftOutcomes2.add(RecordBatch.IterOutcome.OK);
final CloseableRecordBatch leftMockBatch_2 = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, leftContainer2, leftOutcomes2, leftContainer2.get(0).getSchema());
final LateralJoinBatch upperLateral = new LateralJoinBatch(popConfig_1, fixture.getFragmentContext(), leftMockBatch_2, lowerLateral);
try {
final int expectedOutputRecordCount = 6;
assertTrue(RecordBatch.IterOutcome.OK_NEW_SCHEMA == upperLateral.next());
assertTrue(RecordBatch.IterOutcome.OK == upperLateral.next());
int actualOutputRecordCount = upperLateral.getRecordCount();
assertTrue(RecordBatch.IterOutcome.NONE == upperLateral.next());
assertTrue(actualOutputRecordCount == expectedOutputRecordCount);
} catch (AssertionError | Exception error) {
fail();
} finally {
// Close all the resources for this test case
upperLateral.close();
leftMockBatch_2.close();
lowerLateral.close();
leftMockBatch_1.close();
rightMockBatch_1.close();
leftContainer2.clear();
leftOutcomes2.clear();
}
}
use of org.apache.drill.exec.physical.impl.MockRecordBatch in project drill by apache.
the class TestLateralJoinCorrectness method testBuildSchemaEmptyLNonEmptyRBatch.
/**
* This case should never happen since With empty left there cannot be non-empty right batch, the
* {@link LateralJoinBatch#buildSchema()} phase should fail() with {@link IllegalStateException}
*
* @throws Exception
*/
@Test
public void testBuildSchemaEmptyLNonEmptyRBatch() throws Exception {
// Get the left container with dummy data for Lateral Join
leftContainer.add(emptyLeftRowSet.container());
// Get the left IterOutcomes for Lateral Join
leftOutcomes.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
// Create Left MockRecordBatch
final CloseableRecordBatch leftMockBatch = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, leftContainer, leftOutcomes, leftContainer.get(0).getSchema());
// Get the right container with dummy data
rightContainer.add(nonEmptyRightRowSet.container());
rightOutcomes.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
final CloseableRecordBatch rightMockBatch = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, rightContainer, rightOutcomes, rightContainer.get(0).getSchema());
final LateralJoinBatch ljBatch = new LateralJoinBatch(ljPopConfig, fixture.getFragmentContext(), leftMockBatch, rightMockBatch);
try {
assertTrue(RecordBatch.IterOutcome.OK_NEW_SCHEMA == ljBatch.next());
fail();
} catch (AssertionError | Exception error) {
// Expected since first right batch is supposed to be empty
assertTrue(error instanceof IllegalStateException);
} finally {
// Close all the resources for this test case
ljBatch.close();
leftMockBatch.close();
rightMockBatch.close();
}
}
use of org.apache.drill.exec.physical.impl.MockRecordBatch in project drill by apache.
the class TestLateralJoinCorrectness method testMultiLevelLateral_SchemaChange_RightUnnest.
/**
* This test generates an operator tree for multi level LATERAL by stacking 2 LATERAL and finally an UNNEST pair
* (using MockRecord Batch) as left and right child of lower level LATERAL. In this setup the test try to simulate
* the SchemaChange happening at upper level LATERAL left incoming second batch, which also results into the
* SchemaChange of right UNNEST of lower level LATERAL. This test validates that the schema change is handled
* correctly by both upper and lower level LATERAL.
*
* @throws Exception
*/
@Test
public void testMultiLevelLateral_SchemaChange_RightUnnest() throws Exception {
// ** Prepare first pair of left batch and right batch for lower level LATERAL Lateral_1 **
final LateralJoinPOP popConfig_1 = new LateralJoinPOP(null, null, JoinRelType.INNER, DrillLateralJoinRelBase.IMPLICIT_COLUMN, Lists.newArrayList());
TupleMetadata leftSchemaWithImplicit = new SchemaBuilder().add(popConfig_1.getImplicitRIDColumn(), TypeProtos.MinorType.INT).add("id_left", TypeProtos.MinorType.INT).add("cost_left", TypeProtos.MinorType.INT).add("name_left", TypeProtos.MinorType.VARCHAR).buildSchema();
final RowSet.SingleRowSet emptyLeftRowSet_1 = fixture.rowSetBuilder(leftSchemaWithImplicit).build();
final RowSet.SingleRowSet nonEmptyLeftRowSet_1 = fixture.rowSetBuilder(leftSchemaWithImplicit).addRow(1, 1, 10, "item1").build();
final RowSet.SingleRowSet nonEmptyLeftRowSet2 = fixture.rowSetBuilder(leftSchemaWithImplicit).addRow(1, 1111, 10001, "NewRecord").build();
leftContainer.add(emptyLeftRowSet_1.container());
leftContainer.add(nonEmptyLeftRowSet_1.container());
leftContainer.add(nonEmptyLeftRowSet2.container());
// Get the left IterOutcomes for Lateral Join
leftOutcomes.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
leftOutcomes.add(RecordBatch.IterOutcome.EMIT);
leftOutcomes.add(RecordBatch.IterOutcome.EMIT);
final CloseableRecordBatch leftMockBatch_1 = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, leftContainer, leftOutcomes, leftContainer.get(0).getSchema());
// Get the right container with dummy data
TupleMetadata rightSchema2 = new SchemaBuilder().add(popConfig_1.getImplicitRIDColumn(), TypeProtos.MinorType.INT).add("id_right_new", TypeProtos.MinorType.INT).add("cost_right_new", TypeProtos.MinorType.VARCHAR).add("name_right_new", TypeProtos.MinorType.VARCHAR).buildSchema();
final RowSet.SingleRowSet emptyRightRowSet_rightSchema2 = fixture.rowSetBuilder(rightSchema2).build();
final RowSet.SingleRowSet nonEmptyRightRowSet_rightSchema2 = fixture.rowSetBuilder(rightSchema2).addRow(1, 5, "51", "item51").addRow(1, 6, "61", "item61").addRow(1, 7, "71", "item71").build();
rightContainer.add(emptyRightRowSet.container());
rightContainer.add(nonEmptyRightRowSet.container());
rightContainer.add(emptyRightRowSet_rightSchema2.container());
rightContainer.add(nonEmptyRightRowSet_rightSchema2.container());
rightOutcomes.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
rightOutcomes.add(RecordBatch.IterOutcome.EMIT);
rightOutcomes.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
rightOutcomes.add(RecordBatch.IterOutcome.EMIT);
final CloseableRecordBatch rightMockBatch_1 = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, rightContainer, rightOutcomes, rightContainer.get(0).getSchema());
final LateralJoinBatch lowerLevelLateral = new LateralJoinBatch(popConfig_1, fixture.getFragmentContext(), leftMockBatch_1, rightMockBatch_1);
// ** Prepare second pair of left and right batch for upper level Lateral_2 **
// Create left input schema for first batch
TupleMetadata leftSchema3 = new SchemaBuilder().add("id_left_new", TypeProtos.MinorType.INT).add("cost_left_new", TypeProtos.MinorType.INT).add("name_left_new", TypeProtos.MinorType.VARCHAR).buildSchema();
final RowSet.SingleRowSet emptyLeftRowSet_leftSchema3 = fixture.rowSetBuilder(leftSchema3).build();
final RowSet.SingleRowSet nonEmptyLeftRowSet_leftSchema3 = fixture.rowSetBuilder(leftSchema3).addRow(6, 60, "item6").build();
// Get left input schema for second left batch
TupleMetadata leftSchema4 = new SchemaBuilder().add("id_left_new_new", TypeProtos.MinorType.INT).add("cost_left_new_new", TypeProtos.MinorType.VARCHAR).add("name_left_new_new", TypeProtos.MinorType.VARCHAR).buildSchema();
final RowSet.SingleRowSet nonEmptyLeftRowSet_leftSchema4 = fixture.rowSetBuilder(leftSchema4).addRow(100, "100", "item100").build();
// Build Left container for upper level LATERAL operator
final List<VectorContainer> leftContainer2 = new ArrayList<>(5);
// Get the left container with dummy data
leftContainer2.add(emptyLeftRowSet_leftSchema3.container());
leftContainer2.add(nonEmptyLeftRowSet_leftSchema3.container());
leftContainer2.add(nonEmptyLeftRowSet_leftSchema4.container());
// Get the left container outcomes for upper level LATERAL operator
final List<RecordBatch.IterOutcome> leftOutcomes2 = new ArrayList<>(5);
leftOutcomes2.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
leftOutcomes2.add(RecordBatch.IterOutcome.OK);
leftOutcomes2.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
final CloseableRecordBatch leftMockBatch_2 = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, leftContainer2, leftOutcomes2, leftContainer2.get(0).getSchema());
final LateralJoinBatch upperLevelLateral = new LateralJoinBatch(popConfig_1, fixture.getFragmentContext(), leftMockBatch_2, lowerLevelLateral);
try {
// 3 for first batch on left side and another 3 for next left batch
final int expectedOutputRecordCount = 6;
int actualOutputRecordCount = 0;
assertTrue(RecordBatch.IterOutcome.OK_NEW_SCHEMA == upperLevelLateral.next());
assertTrue(RecordBatch.IterOutcome.OK == upperLevelLateral.next());
actualOutputRecordCount += upperLevelLateral.getRecordCount();
assertTrue(RecordBatch.IterOutcome.OK_NEW_SCHEMA == upperLevelLateral.next());
actualOutputRecordCount += upperLevelLateral.getRecordCount();
assertTrue(RecordBatch.IterOutcome.OK == upperLevelLateral.next());
actualOutputRecordCount += upperLevelLateral.getRecordCount();
assertTrue(RecordBatch.IterOutcome.NONE == upperLevelLateral.next());
assertTrue(actualOutputRecordCount == expectedOutputRecordCount);
} catch (AssertionError | Exception error) {
fail();
} finally {
// Close all the resources for this test case
upperLevelLateral.close();
leftMockBatch_2.close();
lowerLevelLateral.close();
leftMockBatch_1.close();
rightMockBatch_1.close();
leftContainer2.clear();
leftOutcomes2.clear();
}
}
use of org.apache.drill.exec.physical.impl.MockRecordBatch in project drill by apache.
the class TestLateralJoinCorrectness method testHandlingEMITFromLeft.
/**
* When multiple left batch is received with same schema but with OK_NEW_SCHEMA, then LATERAL detects that
* correctly and suppresses schema change operation by producing output in same batch created with initial schema.
* The schema change was only for columns which are not produced by the UNNEST or right branch.
*
* @throws Exception
*/
@Test
public void testHandlingEMITFromLeft() throws Exception {
final RowSet.SingleRowSet leftRowSet2 = fixture.rowSetBuilder(leftSchema).addRow(3, 30, "item30").build();
// Create data for right input
final RowSet.SingleRowSet nonEmptyRightRowSet2 = fixture.rowSetBuilder(rightSchema).addRow(1, 4, 41, "item41").addRow(1, 5, 51, "item51").build();
// Get the left container with dummy data for Lateral Join
leftContainer.add(emptyLeftRowSet.container());
leftContainer.add(nonEmptyLeftRowSet.container());
leftContainer.add(leftRowSet2.container());
// Get the left IterOutcomes for Lateral Join
leftOutcomes.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
leftOutcomes.add(RecordBatch.IterOutcome.EMIT);
leftOutcomes.add(RecordBatch.IterOutcome.EMIT);
// Create Left MockRecordBatch
final CloseableRecordBatch leftMockBatch = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, leftContainer, leftOutcomes, leftContainer.get(0).getSchema());
// Get the right container with dummy data
rightContainer.add(emptyRightRowSet.container());
rightContainer.add(nonEmptyRightRowSet.container());
rightContainer.add(nonEmptyRightRowSet2.container());
rightOutcomes.add(RecordBatch.IterOutcome.OK_NEW_SCHEMA);
rightOutcomes.add(RecordBatch.IterOutcome.EMIT);
rightOutcomes.add(RecordBatch.IterOutcome.EMIT);
final CloseableRecordBatch rightMockBatch = new MockRecordBatch(fixture.getFragmentContext(), operatorContext, rightContainer, rightOutcomes, rightContainer.get(0).getSchema());
final LateralJoinBatch ljBatch = new LateralJoinBatch(ljPopConfig, fixture.getFragmentContext(), leftMockBatch, rightMockBatch);
try {
int totalRecordCount = 0;
assertTrue(RecordBatch.IterOutcome.OK_NEW_SCHEMA == ljBatch.next());
// 1st output batch is received for first EMIT from LEFT side
assertTrue(RecordBatch.IterOutcome.EMIT == ljBatch.next());
totalRecordCount += ljBatch.getRecordCount();
// 2nd output batch is received for second EMIT from LEFT side
assertTrue(RecordBatch.IterOutcome.EMIT == ljBatch.next());
totalRecordCount += ljBatch.getRecordCount();
// Compare the total records generated in 2 output batches with expected count.
assertTrue(totalRecordCount == (nonEmptyLeftRowSet.rowCount() * nonEmptyRightRowSet.rowCount() + leftRowSet2.rowCount() * nonEmptyRightRowSet2.rowCount()));
assertTrue(RecordBatch.IterOutcome.NONE == ljBatch.next());
} catch (AssertionError | Exception error) {
fail();
} finally {
// Close all the resources for this test case
ljBatch.close();
leftMockBatch.close();
rightMockBatch.close();
leftRowSet2.clear();
nonEmptyRightRowSet2.clear();
}
}
Aggregations