Package org.apache.derby.iapi.sql.compile

Examples of org.apache.derby.iapi.sql.compile.AccessPath


    */
    if (requiredRowOrdering != null)
    {
      if (pullMe.considerSortAvoidancePath())
      {
        AccessPath ap = pullMe.getBestSortAvoidancePath();
        double     prevEstimatedCost = 0.0d;

        /*
        ** Subtract the sort avoidance cost estimate of the
        ** optimizable being removed from the total sort
        ** avoidance cost estimate.
        **
        ** The total cost is the sum of all the costs, but the
        ** total number of rows is the number of rows returned
        ** by the innermost optimizable.
        */
        if (joinPosition == 0)
        {
          prevRowCount = outermostCostEstimate.rowCount();
          prevSingleScanRowCount =
            outermostCostEstimate.singleScanRowCount();

          /* If we are choosing a new outer table, then
           * we rest the starting cost to the outermostCost.
           * (Thus avoiding any problems with floating point
           * accuracy and going negative.)
           */
          prevEstimatedCost =
            outermostCostEstimate.getEstimatedCost();
        }
        else
        {
          CostEstimate localCE =
            optimizableList.
              getOptimizable(prevPosition).
                getBestSortAvoidancePath().
                  getCostEstimate();
          prevRowCount = localCE.rowCount();
          prevSingleScanRowCount = localCE.singleScanRowCount();
          prevEstimatedCost =
            currentSortAvoidanceCost.getEstimatedCost() -
            ap.getCostEstimate().getEstimatedCost();
        }

        // See discussion above for "newCost"; same applies here.
        if (prevEstimatedCost <= 0.0)
        {
View Full Code Here


        throws StandardException
  {
    /* CHOOSE BEST CONGLOMERATE HERE */
    ConglomerateDescriptor  conglomerateDescriptor = null;
    ConglomerateDescriptor  bestConglomerateDescriptor = null;
    AccessPath bestAp = optimizable.getBestAccessPath();
    int lockMode = optimizable.getCurrentAccessPath().getLockMode();


    /*
    ** If the current conglomerate better than the best so far?
    ** The pecking order is:
    **    o  covering index useful for predicates
    **      (if there are predicates)
    **    o  index useful for predicates (if there are predicates)
    **    o  covering index
    **    o  table scan
    */

    /*
    ** If there is more than one conglomerate descriptor
    ** choose any index that is potentially useful.
    */
    if (predList != null &&
      predList.useful(optimizable, cd))
    {
      /*
      ** Do not let a non-covering matching index scan supplant a
      ** covering matching index scan.
      */
      boolean newCoveringIndex = optimizable.isCoveringIndex(cd);
      if ( ( ! bestAp.getCoveringIndexScan()) ||
          bestAp.getNonMatchingIndexScan() ||
        newCoveringIndex )
      {
        bestAp.setCostEstimate(
          estimateTotalCost(
                  predList,
                  cd,
                  outerCost,
                  optimizable
                  )
                );
        bestAp.setConglomerateDescriptor(cd);
        bestAp.setNonMatchingIndexScan(false);
        bestAp.setCoveringIndexScan(newCoveringIndex);

        bestAp.setLockMode(optimizable.getCurrentAccessPath().getLockMode());

        optimizable.rememberJoinStrategyAsBest(bestAp);
      }

      return;
    }

    /* Remember the "last" covering index.
     * NOTE - Since we don't have costing, we just go for the
     * last one since that's as good as any
     */
    if (optimizable.isCoveringIndex(cd))
    {
      bestAp.setCostEstimate(
                estimateTotalCost(predList,
                          cd,
                          outerCost,
                          optimizable)
                );
      bestAp.setConglomerateDescriptor(cd);
      bestAp.setNonMatchingIndexScan(true);
      bestAp.setCoveringIndexScan(true);

      bestAp.setLockMode(optimizable.getCurrentAccessPath().getLockMode());

      optimizable.rememberJoinStrategyAsBest(bestAp);
      return;
    }

    /*
    ** If this is the heap, and the best conglomerate so far is a
    ** non-covering, non-matching index scan, pick the heap.
    */
    if ( ( ! bestAp.getCoveringIndexScan()) &&
       bestAp.getNonMatchingIndexScan() &&
       ( ! cd.isIndex() )
       )
    {
      bestAp.setCostEstimate(
                  estimateTotalCost(predList,
                            cd,
                            outerCost,
                            optimizable)
                  );

      bestAp.setConglomerateDescriptor(cd);

      bestAp.setLockMode(optimizable.getCurrentAccessPath().getLockMode());

      optimizable.rememberJoinStrategyAsBest(bestAp);

      /*
      ** No need to set non-matching index scan and covering
      ** index scan, as these are already correct.
      */
      return;
    }


    /*
    ** If all else fails, and no conglomerate has been picked yet,
    ** pick this one.
    */
    bestConglomerateDescriptor = bestAp.getConglomerateDescriptor();
    if (bestConglomerateDescriptor == null)
    {
      bestAp.setCostEstimate(
                  estimateTotalCost(predList,
                             cd,
                            outerCost,
                            optimizable)
                  );

      bestAp.setConglomerateDescriptor(cd);

      /*
      ** We have determined above that this index is neither covering
      ** nor matching.
      */
      bestAp.setCoveringIndexScan(false);
      bestAp.setNonMatchingIndexScan(cd.isIndex());

      bestAp.setLockMode(optimizable.getCurrentAccessPath().getLockMode());

      optimizable.rememberJoinStrategyAsBest(bestAp);
    }

    return;
 
View Full Code Here

      }
      return;
    }

    /* Pick the cheapest cost for this particular optimizable. */
    AccessPath ap = optimizable.getBestAccessPath();
    CostEstimate bestCostEstimate = ap.getCostEstimate();

    if ((bestCostEstimate == null) ||
      bestCostEstimate.isUninitialized() ||
      (estimatedCost.compare(bestCostEstimate) < 0))
    {
      ap.setConglomerateDescriptor(cd);
      ap.setCostEstimate(estimatedCost);
      ap.setCoveringIndexScan(optimizable.isCoveringIndex(cd));

      /*
      ** It's a non-matching index scan either if there is no
      ** predicate list, or nothing in the predicate list is useful
      ** for limiting the scan.
      */
      ap.setNonMatchingIndexScan(
                  (predList == null) ||
                  ( ! ( predList.useful(optimizable, cd) ) )
                  );
      ap.setLockMode(optimizable.getCurrentAccessPath().getLockMode());
      optimizable.rememberJoinStrategyAsBest(ap);
    }

    /*
    ** Keep track of the best sort-avoidance path if there is a
    ** required row ordering.
    */
    if (requiredRowOrdering != null)
    {
      /*
      ** The current optimizable can avoid a sort only if the
      ** outer one does, also (if there is an outer one).
      */
      if (joinPosition == 0 ||
        optimizableList.getOptimizable(
                    proposedJoinOrder[joinPosition - 1]).
                        considerSortAvoidancePath())
      {
        /*
        ** There is a required row ordering - does the proposed access
        ** path avoid a sort?
        */
        if (requiredRowOrdering.sortRequired(currentRowOrdering,
                            assignedTableMap,
                            optimizableList)
                    ==RequiredRowOrdering.NOTHING_REQUIRED)
        {
          ap = optimizable.getBestSortAvoidancePath();
          bestCostEstimate = ap.getCostEstimate();

          /* Is this the cheapest sort-avoidance path? */
          if ((bestCostEstimate == null) ||
            bestCostEstimate.isUninitialized() ||
            (estimatedCost.compare(bestCostEstimate) < 0))
          {
            ap.setConglomerateDescriptor(cd);
            ap.setCostEstimate(estimatedCost);
            ap.setCoveringIndexScan(
                      optimizable.isCoveringIndex(cd));

            /*
            ** It's a non-matching index scan either if there is no
            ** predicate list, or nothing in the predicate list is
            ** useful for limiting the scan.
            */
            ap.setNonMatchingIndexScan(
                    (predList == null) ||
                    ( ! (predList.useful(optimizable, cd)) )
                    );
            ap.setLockMode(
              optimizable.getCurrentAccessPath().getLockMode());
            optimizable.rememberJoinStrategyAsBest(ap);
            optimizable.rememberSortAvoidancePath();

            /*
 
View Full Code Here

     * table and the old access path did not have a join strategy
     * associated with it in that case.  So, we now choose the new
     * access path if it is the same cost or cheaper than the current
     * access path.
     */
    AccessPath ap = optimizable.getBestAccessPath();
    CostEstimate bestCostEstimate = ap.getCostEstimate();

    if ((bestCostEstimate == null) ||
      bestCostEstimate.isUninitialized() ||
      (estimatedCost.compare(bestCostEstimate) <= 0))
    {
      ap.setCostEstimate(estimatedCost);
      optimizable.rememberJoinStrategyAsBest(ap);
    }

    /*
    ** Keep track of the best sort-avoidance path if there is a
    ** required row ordering.
    */
    if (requiredRowOrdering != null)
    {
      /*
      ** The current optimizable can avoid a sort only if the
      ** outer one does, also (if there is an outer one).
      */
      if (joinPosition == 0 ||
        optimizableList.getOptimizable(
                    proposedJoinOrder[joinPosition - 1]).
                        considerSortAvoidancePath())
      {
        /*
        ** There is a required row ordering - does the proposed access
        ** path avoid a sort?
        */
        if (requiredRowOrdering.sortRequired(currentRowOrdering,
                            assignedTableMap,
                            optimizableList)
                    == RequiredRowOrdering.NOTHING_REQUIRED)
        {
          ap = optimizable.getBestSortAvoidancePath();
          bestCostEstimate = ap.getCostEstimate();

          /* Is this the cheapest sort-avoidance path? */
          if ((bestCostEstimate == null) ||
            bestCostEstimate.isUninitialized() ||
            (estimatedCost.compare(bestCostEstimate) < 0))
          {
            ap.setCostEstimate(estimatedCost);
            optimizable.rememberJoinStrategyAsBest(ap);
            optimizable.rememberSortAvoidancePath();

            /*
            ** Remember the current row ordering as best
View Full Code Here

              int colNum = crs[0].getColumnNumber();
             
              /* Check if we have an access path, this will be
               * null in a join case (See Beetle 4423)
               */
              AccessPath accessPath= getTrulyTheBestAccessPath();
              if (accessPath == null)
                return;
              IndexDescriptor id = accessPath.
                        getConglomerateDescriptor().
                        getIndexDescriptor();
              int[] keyColumns = id.baseColumnPositions();
              boolean[] isAscending = id.isAscending();
              for (int i = 0; i < keyColumns.length; i++)
View Full Code Here

                  RowOrdering rowOrdering)
          throws StandardException
  {
    int  numStrat = optimizer.getNumberOfJoinStrategies();
    boolean found = false;
    AccessPath ap = getCurrentAccessPath();

    /*
    ** Most Optimizables have no ordering, so tell the rowOrdering that
    ** this Optimizable is unordered, if appropriate.
    */
    if (userSpecifiedJoinStrategy != null)
    {
      /*
      ** User specified a join strategy, so we should look at only one
      ** strategy.  If there is a current strategy, we have already
      ** looked at the strategy, so go back to null.
      */
      if (ap.getJoinStrategy() != null)
      {
          ap.setJoinStrategy((JoinStrategy) null);

        found = false;
      }
      else
      {
        ap.setJoinStrategy(
                optimizer.getJoinStrategy(userSpecifiedJoinStrategy));

        if (ap.getJoinStrategy() == null)
        {
          throw StandardException.newException(SQLState.LANG_INVALID_JOIN_STRATEGY,
            userSpecifiedJoinStrategy, getBaseTableName());
        }

        found = true;
      }
    }
    else if (joinStrategyNumber < numStrat)
    {
      /* Step through the join strategies. */
      ap.setJoinStrategy(optimizer.getJoinStrategy(joinStrategyNumber));

      joinStrategyNumber++;

      found = true;

      optimizer.trace(Optimizer.CONSIDERING_JOIN_STRATEGY, tableNumber, 0, 0.0,
              ap.getJoinStrategy());
    }

    /*
    ** Tell the RowOrdering about columns that are equal to constant
    ** expressions.
 
View Full Code Here

      }

      return;
    }

    AccessPath bestPath = getTrulyTheBestAccessPath();
    AccessPathImpl ap = null;
    if (action == ADD_PLAN)
    {
      // If we get to this method before ever optimizing this node, then
      // there will be no best path--so there's nothing to do.
      if (bestPath == null)
        return;

      // If the bestPlanMap already exists, search for an
      // AccessPath for the received key and use that if we can.
      if (bestPlanMap == null)
        bestPlanMap = new HashMap();
      else
        ap = (AccessPathImpl)bestPlanMap.get(planKey);

      // If we don't already have an AccessPath for the key,
      // create a new one.  If the key is an OptimizerImpl then
      // we might as well pass it in to the AccessPath constructor;
      // otherwise just pass null.
      if (ap == null)
      {
        if (planKey instanceof Optimizer)
          ap = new AccessPathImpl((Optimizer)planKey);
        else
          ap = new AccessPathImpl((Optimizer)null);
      }

      ap.copy(bestPath);
      bestPlanMap.put(planKey, ap);
      return;
    }

    // If we get here, we want to load the best plan from our map
    // into this Optimizable's trulyTheBestAccessPath field.

    // If we don't have any plans saved, then there's nothing to load.
    // This can happen if the key is an OptimizerImpl that tried some
    // join order for which there was no valid plan.
    if (bestPlanMap == null)
      return;

    ap = (AccessPathImpl)bestPlanMap.get(planKey);

    // It might be the case that there is no plan stored for
    // the key, in which case there's nothing to load.
    if ((ap == null) || (ap.getCostEstimate() == null))
      return;

    // We found a best plan in our map, so load it into this Optimizable's
    // trulyTheBestAccessPath field.
    bestPath.copy(ap);
    return;
  }
View Full Code Here

  /** @see Optimizable#rememberAsBest */
  public void rememberAsBest(int planType, Optimizer optimizer)
    throws StandardException
  {
    AccessPath bestPath = null;

    switch (planType)
    {
      case Optimizer.NORMAL_PLAN:
      bestPath = getBestAccessPath();
      break;

      case Optimizer.SORT_AVOIDANCE_PLAN:
      bestPath = getBestSortAvoidancePath();
      break;

      default:
      if (SanityManager.DEBUG)
      {
        SanityManager.THROWASSERT(
          "Invalid plan type " + planType);
      }
    }

    getTrulyTheBestAccessPath().copy(bestPath);

    // Since we just set trulyTheBestAccessPath for the current
    // join order of the received optimizer, take note of what
    // that path is, in case we need to "revert" back to this
    // path later.  See Optimizable.updateBestPlanMap().
    // Note: Since this call descends all the way down to base
    // tables, it can be relatively expensive when we have deeply
    // nested subqueries.  So in an attempt to save some work, we
    // skip the call if this node is a ProjectRestrictNode whose
    // child is an Optimizable--in that case the ProjectRestrictNode
    // will in turn call "rememberAsBest" on its child and so
    // the required call to updateBestPlanMap() will be
    // made at that time.  If we did it here, too, then we would
    // just end up duplicating the work.
    if (!(this instanceof ProjectRestrictNode))
      updateBestPlanMap(ADD_PLAN, optimizer);
    else
    {
      ProjectRestrictNode prn = (ProjectRestrictNode)this;
      if (!(prn.getChildResult() instanceof Optimizable))
        updateBestPlanMap(ADD_PLAN, optimizer);
    }
    
    /* also store the name of the access path; i.e index name/constraint
     * name if we're using an index to access the base table.
     */
    ConglomerateDescriptor cd =  bestPath.getConglomerateDescriptor();

    if (isBaseTable())
    {
      DataDictionary dd = getDataDictionary();
      TableDescriptor td = getTableDescriptor();
      getTrulyTheBestAccessPath().initializeAccessPathName(dd, td);
    }

    setCostEstimate(bestPath.getCostEstimate());

    bestPath.getOptimizer().trace(Optimizer.REMEMBERING_BEST_ACCESS_PATH,
              tableNumber, planType, 0.0, bestPath);
  }
View Full Code Here

                  OptimizablePredicateList predList,
                  RowOrdering rowOrdering)
          throws StandardException
  {
    String userSpecifiedIndexName = getUserSpecifiedIndexName();
    AccessPath ap = getCurrentAccessPath();
    ConglomerateDescriptor currentConglomerateDescriptor =
                        ap.getConglomerateDescriptor();

    optimizer.trace(Optimizer.CALLING_NEXT_ACCESS_PATH,
             ((predList == null) ? 0 : predList.size()),
             0, 0.0, getExposedName());

    /*
    ** Remove the ordering of the current conglomerate descriptor,
    ** if any.
    */
    rowOrdering.removeOptimizable(getTableNumber());

    // RESOLVE: This will have to be modified to step through the
    // join strategies as well as the conglomerates.

    if (userSpecifiedIndexName != null)
    {
      /*
      ** User specified an index name, so we should look at only one
      ** index.  If there is a current conglomerate descriptor, and there
      ** are no more join strategies, we've already looked at the index,
      ** so go back to null.
      */
      if (currentConglomerateDescriptor != null)
      {
        if ( ! super.nextAccessPath(optimizer,
                      predList,
                      rowOrdering) )
        {
          currentConglomerateDescriptor = null;
        }
      }
      else
      {
        optimizer.trace(Optimizer.LOOKING_FOR_SPECIFIED_INDEX,
                tableNumber, 0, 0.0, userSpecifiedIndexName);

        if (StringUtil.SQLToUpperCase(userSpecifiedIndexName).equals("NULL"))
        {
          /* Special case - user-specified table scan */
          currentConglomerateDescriptor =
            tableDescriptor.getConglomerateDescriptor(
                    tableDescriptor.getHeapConglomerateId()
                  );
        }
        else
        {
          /* User-specified index name */
          getConglomDescs();
       
          for (int index = 0; index < conglomDescs.length; index++)
          {
            currentConglomerateDescriptor = conglomDescs[index];
            String conglomerateName =
              currentConglomerateDescriptor.getConglomerateName();
            if (conglomerateName != null)
            {
              /* Have we found the desired index? */
              if (conglomerateName.equals(userSpecifiedIndexName))
              {
                break;
              }
            }
          }

          /* We should always find a match */
          if (SanityManager.DEBUG)
          {
            if (currentConglomerateDescriptor == null)
            {
              SanityManager.THROWASSERT(
                "Expected to find match for forced index " +
                userSpecifiedIndexName);
            }
          }
        }

        if ( ! super.nextAccessPath(optimizer,
                      predList,
                      rowOrdering))
        {
          if (SanityManager.DEBUG)
          {
            SanityManager.THROWASSERT("No join strategy found");
          }
        }
      }
    }
    else
    {
      if (currentConglomerateDescriptor != null)
      {
        /*
        ** Once we have a conglomerate descriptor, cycle through
        ** the join strategies (done in parent).
        */
        if ( ! super.nextAccessPath(optimizer,
                      predList,
                      rowOrdering))
        {
          /*
          ** When we're out of join strategies, go to the next
          ** conglomerate descriptor.
          */
          currentConglomerateDescriptor = getNextConglom(currentConglomerateDescriptor);

          /*
          ** New conglomerate, so step through join strategies
          ** again.
          */
          resetJoinStrategies(optimizer);

          if ( ! super.nextAccessPath(optimizer,
                        predList,
                        rowOrdering))
          {
            if (SanityManager.DEBUG)
            {
              SanityManager.THROWASSERT("No join strategy found");
            }
          }
        }
      }
      else
      {
        /* Get the first conglomerate descriptor */
        currentConglomerateDescriptor = getFirstConglom();

        if ( ! super.nextAccessPath(optimizer,
                      predList,
                      rowOrdering))
        {
          if (SanityManager.DEBUG)
          {
            SanityManager.THROWASSERT("No join strategy found");
          }
        }
      }
    }

    if (currentConglomerateDescriptor == null)
    {
      optimizer.trace(Optimizer.NO_MORE_CONGLOMERATES, tableNumber, 0, 0.0, null);
    }
    else
    {
      currentConglomerateDescriptor.setColumnNames(columnNames);
      optimizer.trace(Optimizer.CONSIDERING_CONGLOMERATE, tableNumber, 0, 0.0,
              currentConglomerateDescriptor);
    }

    /*
    ** Tell the rowOrdering that what the ordering of this conglomerate is
    */
    if (currentConglomerateDescriptor != null)
    {
      if ( ! currentConglomerateDescriptor.isIndex())
      {
        /* If we are scanning the heap, but there
         * is a full match on a unique key, then
         * we can say that the table IS NOT unordered.
         * (We can't currently say what the ordering is
         * though.)
         */
        if (! isOneRowResultSet(predList))
        {
          optimizer.trace(Optimizer.ADDING_UNORDERED_OPTIMIZABLE,
                   ((predList == null) ? 0 : predList.size()),
                   0, 0.0, null);

          rowOrdering.addUnorderedOptimizable(this);
        }
        else
        {
          optimizer.trace(Optimizer.SCANNING_HEAP_FULL_MATCH_ON_UNIQUE_KEY,
                   0, 0, 0.0, null);
        }
      }
      else
      {
        IndexRowGenerator irg =
              currentConglomerateDescriptor.getIndexDescriptor();

        int[] baseColumnPositions = irg.baseColumnPositions();
        boolean[] isAscending = irg.isAscending();

        for (int i = 0; i < baseColumnPositions.length; i++)
        {
          /*
          ** Don't add the column to the ordering if it's already
          ** an ordered column.  This can happen in the following
          ** case:
          **
          **    create index ti on t(x, y);
          **    select * from t where x = 1 order by y;
          **
          ** Column x is always ordered, so we want to avoid the
          ** sort when using index ti.  This is accomplished by
          ** making column y appear as the first ordered column
          ** in the list.
          */
          if ( ! rowOrdering.orderedOnColumn(isAscending[i] ?
                          RowOrdering.ASCENDING :
                          RowOrdering.DESCENDING,
                          getTableNumber(),
                          baseColumnPositions[i]))
          {
            rowOrdering.nextOrderPosition(isAscending[i] ?
                          RowOrdering.ASCENDING :
                          RowOrdering.DESCENDING);

            rowOrdering.addOrderedColumn(isAscending[i] ?
                          RowOrdering.ASCENDING :
                          RowOrdering.DESCENDING,
                          getTableNumber(),
                          baseColumnPositions[i]);
          }
        }
      } 
    }

    ap.setConglomerateDescriptor(currentConglomerateDescriptor);

    return currentConglomerateDescriptor != null;
  }
View Full Code Here

  }

  /** @see Optimizable#startOptimizing */
  public void startOptimizing(Optimizer optimizer, RowOrdering rowOrdering)
  {
    AccessPath ap = getCurrentAccessPath();
    AccessPath bestAp = getBestAccessPath();
    AccessPath bestSortAp = getBestSortAvoidancePath();

    ap.setConglomerateDescriptor((ConglomerateDescriptor) null);
    bestAp.setConglomerateDescriptor((ConglomerateDescriptor) null);
    bestSortAp.setConglomerateDescriptor((ConglomerateDescriptor) null);
    ap.setCoveringIndexScan(false);
    bestAp.setCoveringIndexScan(false);
    bestSortAp.setCoveringIndexScan(false);
    ap.setLockMode(0);
    bestAp.setLockMode(0);
    bestSortAp.setLockMode(0);

    /*
    ** Only need to do this for current access path, because the
    ** costEstimate will be copied to the best access paths as
    ** necessary.
 
View Full Code Here

TOP

Related Classes of org.apache.derby.iapi.sql.compile.AccessPath

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.