Search in sources :

Example 1 with FragmentRoot

use of org.apache.drill.exec.physical.base.FragmentRoot in project drill by apache.

the class SplittingParallelizer method generateWorkUnits.

/**
   * Split plan into multiple plans based on parallelization
   * Ideally it is applicable only to plans with two major fragments: Screen and UnionExchange
   * But there could be cases where we can remove even multiple exchanges like in case of "order by"
   * End goal is to get single major fragment: Screen with chain that ends up with a single minor fragment
   * from Leaf Exchange. This way each plan can run independently without any exchange involvement
   * @param options
   * @param foremanNode - not really applicable
   * @param queryId
   * @param reader
   * @param rootNode
   * @param planningSet
   * @param session
   * @param queryContextInfo
   * @return
   * @throws ExecutionSetupException
   */
private List<QueryWorkUnit> generateWorkUnits(OptionList options, DrillbitEndpoint foremanNode, QueryId queryId, PhysicalPlanReader reader, Fragment rootNode, PlanningSet planningSet, UserSession session, QueryContextInformation queryContextInfo) throws ExecutionSetupException {
    // now we generate all the individual plan fragments and associated assignments. Note, we need all endpoints
    // assigned before we can materialize, so we start a new loop here rather than utilizing the previous one.
    List<QueryWorkUnit> workUnits = Lists.newArrayList();
    int plansCount = 0;
    DrillbitEndpoint[] endPoints = null;
    long initialAllocation = 0;
    long maxAllocation = 0;
    final Iterator<Wrapper> iter = planningSet.iterator();
    while (iter.hasNext()) {
        Wrapper wrapper = iter.next();
        Fragment node = wrapper.getNode();
        boolean isLeafFragment = node.getReceivingExchangePairs().size() == 0;
        final PhysicalOperator physicalOperatorRoot = node.getRoot();
        // get all the needed info from leaf fragment
        if ((physicalOperatorRoot instanceof Exchange) && isLeafFragment) {
            // need to get info about
            // number of minor fragments
            // assignedEndPoints
            // allocation
            plansCount = wrapper.getWidth();
            initialAllocation = (wrapper.getInitialAllocation() != 0) ? wrapper.getInitialAllocation() / plansCount : 0;
            maxAllocation = (wrapper.getMaxAllocation() != 0) ? wrapper.getMaxAllocation() / plansCount : 0;
            endPoints = new DrillbitEndpoint[plansCount];
            for (int mfId = 0; mfId < plansCount; mfId++) {
                endPoints[mfId] = wrapper.getAssignedEndpoint(mfId);
            }
        }
    }
    if (plansCount == 0) {
        // no exchange, return list of single QueryWorkUnit
        workUnits.add(generateWorkUnit(options, foremanNode, queryId, reader, rootNode, planningSet, session, queryContextInfo));
        return workUnits;
    }
    for (Wrapper wrapper : planningSet) {
        Fragment node = wrapper.getNode();
        final PhysicalOperator physicalOperatorRoot = node.getRoot();
        if (physicalOperatorRoot instanceof Exchange) {
            // get to 0 MajorFragment
            continue;
        }
        boolean isRootNode = rootNode == node;
        if (isRootNode && wrapper.getWidth() != 1) {
            throw new ForemanSetupException(String.format("Failure while trying to setup fragment. " + "The root fragment must always have parallelization one. In the current case, the width was set to %d.", wrapper.getWidth()));
        }
        // this fragment is always leaf, as we are removing all the exchanges
        boolean isLeafFragment = true;
        FragmentHandle handle = //
        FragmentHandle.newBuilder().setMajorFragmentId(//
        wrapper.getMajorFragmentId()).setMinorFragmentId(// minor fragment ID is going to be always 0, as plan will be split
        0).setQueryId(//
        queryId).build();
        // Create a minorFragment for each major fragment.
        for (int minorFragmentId = 0; minorFragmentId < plansCount; minorFragmentId++) {
            // those fragments should be empty
            List<PlanFragment> fragments = Lists.newArrayList();
            PlanFragment rootFragment = null;
            FragmentRoot rootOperator = null;
            IndexedFragmentNode iNode = new IndexedFragmentNode(minorFragmentId, wrapper);
            wrapper.resetAllocation();
            // two visitors here
            // 1. To remove exchange
            // 2. To reset operator IDs as exchanges were removed
            PhysicalOperator op = physicalOperatorRoot.accept(ExchangeRemoverMaterializer.INSTANCE, iNode).accept(OperatorIdVisitor.INSTANCE, 0);
            Preconditions.checkArgument(op instanceof FragmentRoot);
            FragmentRoot root = (FragmentRoot) op;
            // get plan as JSON
            String plan;
            String optionsData;
            try {
                plan = reader.writeJson(root);
                optionsData = reader.writeJson(options);
            } catch (JsonProcessingException e) {
                throw new ForemanSetupException("Failure while trying to convert fragment into json.", e);
            }
            PlanFragment fragment = //
            PlanFragment.newBuilder().setForeman(//
            endPoints[minorFragmentId]).setFragmentJson(//
            plan).setHandle(//
            handle).setAssignment(//
            endPoints[minorFragmentId]).setLeafFragment(//
            isLeafFragment).setContext(queryContextInfo).setMemInitial(//
            initialAllocation).setMemMax(// TODO - for some reason OOM is using leaf fragment max allocation divided by width
            wrapper.getMaxAllocation()).setOptionsJson(optionsData).setCredentials(session.getCredentials()).addAllCollector(CountRequiredFragments.getCollectors(root)).build();
            if (isRootNode) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Root fragment:\n {}", DrillStringUtils.unescapeJava(fragment.toString()));
                }
                rootFragment = fragment;
                rootOperator = root;
            } else {
                if (logger.isDebugEnabled()) {
                    logger.debug("Remote fragment:\n {}", DrillStringUtils.unescapeJava(fragment.toString()));
                }
                throw new ForemanSetupException(String.format("There should not be non-root/remote fragment present in plan split, but there is:", DrillStringUtils.unescapeJava(fragment.toString())));
            }
            // fragments should be always empty here
            workUnits.add(new QueryWorkUnit(rootOperator, rootFragment, fragments));
        }
    }
    return workUnits;
}
Also used : Wrapper(org.apache.drill.exec.planner.fragment.Wrapper) QueryWorkUnit(org.apache.drill.exec.work.QueryWorkUnit) FragmentRoot(org.apache.drill.exec.physical.base.FragmentRoot) FragmentHandle(org.apache.drill.exec.proto.ExecProtos.FragmentHandle) PlanFragment(org.apache.drill.exec.proto.BitControl.PlanFragment) Fragment(org.apache.drill.exec.planner.fragment.Fragment) IndexedFragmentNode(org.apache.drill.exec.planner.fragment.Materializer.IndexedFragmentNode) DrillbitEndpoint(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint) PlanFragment(org.apache.drill.exec.proto.BitControl.PlanFragment) Exchange(org.apache.drill.exec.physical.base.Exchange) DrillbitEndpoint(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint) PhysicalOperator(org.apache.drill.exec.physical.base.PhysicalOperator) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) ForemanSetupException(org.apache.drill.exec.work.foreman.ForemanSetupException)

Example 2 with FragmentRoot

use of org.apache.drill.exec.physical.base.FragmentRoot in project drill by apache.

the class TestComparisonFunctions method runTest.

public void runTest(@Injectable final DrillbitContext bitContext, @Injectable UserClientConnection connection, String expression, int expectedResults) throws Throwable {
    mockDrillbitContext(bitContext);
    final String planString = Resources.toString(Resources.getResource(COMPARISON_TEST_PHYSICAL_PLAN), Charsets.UTF_8).replaceAll("EXPRESSION", expression);
    if (reader == null) {
        reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(c);
    }
    if (registry == null) {
        registry = new FunctionImplementationRegistry(c);
    }
    final FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    final PhysicalPlan plan = reader.readPhysicalPlan(planString);
    final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
    while (exec.next()) {
        assertEquals(String.format("Expression: %s;", expression), expectedResults, exec.getSelectionVector2().getCount());
    //      for (ValueVector vv: exec) {
    //        vv.close();
    //      }
    }
    exec.close();
    context.close();
    if (context.getFailureCause() != null) {
        throw context.getFailureCause();
    }
    assertTrue(!context.isFailed());
}
Also used : PhysicalPlan(org.apache.drill.exec.physical.PhysicalPlan) FragmentContext(org.apache.drill.exec.ops.FragmentContext) FragmentRoot(org.apache.drill.exec.physical.base.FragmentRoot) FunctionImplementationRegistry(org.apache.drill.exec.expr.fn.FunctionImplementationRegistry)

Example 3 with FragmentRoot

use of org.apache.drill.exec.physical.base.FragmentRoot in project drill by apache.

the class TestCastFunctions method testCastBigInt.

//private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TestSimpleFunctions.class);
@Test
public // cast to bigint.
void testCastBigInt(@Injectable final DrillbitContext bitContext, @Injectable UserClientConnection connection) throws Throwable {
    mockDrillbitContext(bitContext);
    final PhysicalPlanReader reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(CONFIG);
    final PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastBigInt.json"), Charsets.UTF_8));
    final FunctionImplementationRegistry registry = new FunctionImplementationRegistry(CONFIG);
    final FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
    while (exec.next()) {
        final BigIntVector c0 = exec.getValueVectorById(new SchemaPath("varchar_cast", ExpressionPosition.UNKNOWN), BigIntVector.class);
        final BigIntVector.Accessor a0 = c0.getAccessor();
        int count = 0;
        for (int i = 0; i < c0.getAccessor().getValueCount(); i++) {
            BigIntHolder holder0 = new BigIntHolder();
            a0.get(i, holder0);
            assertEquals(1256, holder0.value);
            ++count;
        }
        assertEquals(5, count);
    }
    exec.close();
    context.close();
    if (context.getFailureCause() != null) {
        throw context.getFailureCause();
    }
    assertTrue(!context.isFailed());
}
Also used : PhysicalPlan(org.apache.drill.exec.physical.PhysicalPlan) BigIntHolder(org.apache.drill.exec.expr.holders.BigIntHolder) FragmentContext(org.apache.drill.exec.ops.FragmentContext) SchemaPath(org.apache.drill.common.expression.SchemaPath) PhysicalPlanReader(org.apache.drill.exec.planner.PhysicalPlanReader) FragmentRoot(org.apache.drill.exec.physical.base.FragmentRoot) FunctionImplementationRegistry(org.apache.drill.exec.expr.fn.FunctionImplementationRegistry) BigIntVector(org.apache.drill.exec.vector.BigIntVector) Test(org.junit.Test)

Example 4 with FragmentRoot

use of org.apache.drill.exec.physical.base.FragmentRoot in project drill by apache.

the class TestCastFunctions method testCastInt.

@Test
public //cast to int
void testCastInt(@Injectable final DrillbitContext bitContext, @Injectable UserClientConnection connection) throws Throwable {
    mockDrillbitContext(bitContext);
    final PhysicalPlanReader reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(CONFIG);
    final PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastInt.json"), Charsets.UTF_8));
    final FunctionImplementationRegistry registry = new FunctionImplementationRegistry(CONFIG);
    final FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
    while (exec.next()) {
        final IntVector c0 = exec.getValueVectorById(new SchemaPath("varchar_cast", ExpressionPosition.UNKNOWN), IntVector.class);
        final IntVector.Accessor a0 = c0.getAccessor();
        int count = 0;
        for (int i = 0; i < c0.getAccessor().getValueCount(); i++) {
            final IntHolder holder0 = new IntHolder();
            a0.get(i, holder0);
            assertEquals(1256, holder0.value);
            ++count;
        }
        assertEquals(5, count);
    }
    exec.close();
    context.close();
    if (context.getFailureCause() != null) {
        throw context.getFailureCause();
    }
    assertTrue(!context.isFailed());
}
Also used : PhysicalPlan(org.apache.drill.exec.physical.PhysicalPlan) FragmentContext(org.apache.drill.exec.ops.FragmentContext) BigIntVector(org.apache.drill.exec.vector.BigIntVector) IntVector(org.apache.drill.exec.vector.IntVector) SchemaPath(org.apache.drill.common.expression.SchemaPath) PhysicalPlanReader(org.apache.drill.exec.planner.PhysicalPlanReader) IntHolder(org.apache.drill.exec.expr.holders.IntHolder) BigIntHolder(org.apache.drill.exec.expr.holders.BigIntHolder) FragmentRoot(org.apache.drill.exec.physical.base.FragmentRoot) FunctionImplementationRegistry(org.apache.drill.exec.expr.fn.FunctionImplementationRegistry) Test(org.junit.Test)

Example 5 with FragmentRoot

use of org.apache.drill.exec.physical.base.FragmentRoot in project drill by apache.

the class TestCastFunctions method testCastNested.

@Test
public //nested: cast is nested in another cast, or another function.
void testCastNested(@Injectable final DrillbitContext bitContext, @Injectable UserClientConnection connection) throws Throwable {
    mockDrillbitContext(bitContext);
    final PhysicalPlanReader reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(CONFIG);
    final PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastNested.json"), Charsets.UTF_8));
    final FunctionImplementationRegistry registry = new FunctionImplementationRegistry(CONFIG);
    final FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
    while (exec.next()) {
        final IntVector c0 = exec.getValueVectorById(new SchemaPath("add_cast", ExpressionPosition.UNKNOWN), IntVector.class);
        final IntVector.Accessor a0 = c0.getAccessor();
        int count = 0;
        for (int i = 0; i < c0.getAccessor().getValueCount(); i++) {
            final IntHolder holder0 = new IntHolder();
            a0.get(i, holder0);
            assertEquals(300, holder0.value);
            ++count;
        }
        assertEquals(5, count);
    }
    exec.close();
    context.close();
    if (context.getFailureCause() != null) {
        throw context.getFailureCause();
    }
    assertTrue(!context.isFailed());
}
Also used : PhysicalPlan(org.apache.drill.exec.physical.PhysicalPlan) FragmentContext(org.apache.drill.exec.ops.FragmentContext) BigIntVector(org.apache.drill.exec.vector.BigIntVector) IntVector(org.apache.drill.exec.vector.IntVector) SchemaPath(org.apache.drill.common.expression.SchemaPath) PhysicalPlanReader(org.apache.drill.exec.planner.PhysicalPlanReader) IntHolder(org.apache.drill.exec.expr.holders.IntHolder) BigIntHolder(org.apache.drill.exec.expr.holders.BigIntHolder) FragmentRoot(org.apache.drill.exec.physical.base.FragmentRoot) FunctionImplementationRegistry(org.apache.drill.exec.expr.fn.FunctionImplementationRegistry) Test(org.junit.Test)

Aggregations

FragmentRoot (org.apache.drill.exec.physical.base.FragmentRoot)45 FunctionImplementationRegistry (org.apache.drill.exec.expr.fn.FunctionImplementationRegistry)39 FragmentContext (org.apache.drill.exec.ops.FragmentContext)39 PhysicalPlan (org.apache.drill.exec.physical.PhysicalPlan)39 PhysicalPlanReader (org.apache.drill.exec.planner.PhysicalPlanReader)35 Test (org.junit.Test)29 SimpleRootExec (org.apache.drill.exec.physical.impl.SimpleRootExec)23 SchemaPath (org.apache.drill.common.expression.SchemaPath)15 ExecTest (org.apache.drill.exec.ExecTest)14 ValueVector (org.apache.drill.exec.vector.ValueVector)7 PhysicalOperator (org.apache.drill.exec.physical.base.PhysicalOperator)6 FragmentHandle (org.apache.drill.exec.proto.ExecProtos.FragmentHandle)6 BigIntVector (org.apache.drill.exec.vector.BigIntVector)6 IntVector (org.apache.drill.exec.vector.IntVector)6 Ignore (org.junit.Ignore)5 StoragePluginRegistryImpl (org.apache.drill.exec.store.StoragePluginRegistryImpl)4 BigIntHolder (org.apache.drill.exec.expr.holders.BigIntHolder)3 PlanFragment (org.apache.drill.exec.proto.BitControl.PlanFragment)3 DrillbitEndpoint (org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint)3 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)2