Search in sources :

Example 1 with SortController

use of org.apache.derby.iapi.store.access.SortController in project derby by apache.

the class InsertResultSet method emptyIndexes.

/**
 * Empty the indexes after doing a bulk insert replace
 * where the table has 0 rows after the replace.
 * RESOLVE: This method is ugly!  Prior to 2.0, we simply
 * scanned back across the table to build the indexes.  We
 * changed this in 2.0 to populate the sorters via a call back
 * as we populated the table.  Doing a 0 row replace into a
 * table with indexes is a degenerate case, hence we allow
 * ugly and unoptimized code.
 *
 * @exception StandardException		Thrown on failure
 */
private void emptyIndexes(long newHeapConglom, InsertConstantAction constants, TableDescriptor td, DataDictionary dd, ExecRow fullTemplate) throws StandardException {
    int numIndexes = constants.irgs.length;
    ExecIndexRow[] idxRows = new ExecIndexRow[numIndexes];
    ExecRow baseRows;
    ColumnOrdering[][] order = new ColumnOrdering[numIndexes][];
    int numColumns = td.getNumberOfColumns();
    collation = new int[numIndexes][];
    // Create the BitSet for mapping the partial row to the full row
    FormatableBitSet bitSet = new FormatableBitSet(numColumns + 1);
    // Need to check each index for referenced columns
    int numReferencedColumns = 0;
    for (int index = 0; index < numIndexes; index++) {
        int[] baseColumnPositions = constants.irgs[index].baseColumnPositions();
        for (int bcp = 0; bcp < baseColumnPositions.length; bcp++) {
            if (!bitSet.get(baseColumnPositions[bcp])) {
                bitSet.set(baseColumnPositions[bcp]);
                numReferencedColumns++;
            }
        }
    }
    // We can finally create the partial base row
    baseRows = activation.getExecutionFactory().getValueRow(numReferencedColumns);
    // Fill in each base row with nulls of the correct data type
    int colNumber = 0;
    for (int index = 0; index < numColumns; index++) {
        if (bitSet.get(index + 1)) {
            colNumber++;
            // NOTE: 1-based column numbers
            baseRows.setColumn(colNumber, fullTemplate.getColumn(index + 1).cloneValue(false));
        }
    }
    needToDropSort = new boolean[numIndexes];
    sortIds = new long[numIndexes];
    /* Do the initial set up before scanning the heap.
		 * For each index, build a single index row and a sorter.
		 */
    for (int index = 0; index < numIndexes; index++) {
        // create a single index row template for each index
        idxRows[index] = constants.irgs[index].getIndexRowTemplate();
        // Get an index row based on the base row
        // (This call is only necessary here because we need to pass a
        // template to the sorter.)
        constants.irgs[index].getIndexRow(baseRows, rl, idxRows[index], bitSet);
        /* For non-unique indexes, we order by all columns + the RID.
			 * For unique indexes, we just order by the columns.
			 * We create a unique index observer for unique indexes
			 * so that we can catch duplicate key
			 */
        ConglomerateDescriptor cd;
        // Get the ConglomerateDescriptor for the index
        cd = td.getConglomerateDescriptor(constants.indexCIDS[index]);
        int[] baseColumnPositions = constants.irgs[index].baseColumnPositions();
        boolean[] isAscending = constants.irgs[index].isAscending();
        int numColumnOrderings;
        SortObserver sortObserver;
        final IndexRowGenerator indDes = cd.getIndexDescriptor();
        if (indDes.isUnique() || indDes.isUniqueDeferrable()) {
            numColumnOrderings = indDes.isUnique() ? baseColumnPositions.length : baseColumnPositions.length + 1;
            String indexOrConstraintName = cd.getConglomerateName();
            boolean deferred = false;
            boolean uniqueDeferrable = false;
            UUID uniqueDeferrableConstraintId = null;
            if (cd.isConstraint()) {
                // so, the index is backing up a constraint
                ConstraintDescriptor conDesc = dd.getConstraintDescriptor(td, cd.getUUID());
                indexOrConstraintName = conDesc.getConstraintName();
                deferred = lcc.isEffectivelyDeferred(lcc.getCurrentSQLSessionContext(activation), conDesc.getUUID());
                uniqueDeferrable = conDesc.deferrable();
                uniqueDeferrableConstraintId = conDesc.getUUID();
            }
            sortObserver = new UniqueIndexSortObserver(lcc, uniqueDeferrableConstraintId, // don't clone rows
            false, uniqueDeferrable, deferred, indexOrConstraintName, idxRows[index], true, td.getName());
        } else {
            numColumnOrderings = baseColumnPositions.length + 1;
            sortObserver = new BasicSortObserver(false, false, idxRows[index], true);
        }
        order[index] = new ColumnOrdering[numColumnOrderings];
        for (int ii = 0; ii < isAscending.length; ii++) {
            order[index][ii] = new IndexColumnOrder(ii, isAscending[ii]);
        }
        if (numColumnOrderings > isAscending.length) {
            order[index][isAscending.length] = new IndexColumnOrder(isAscending.length);
        }
        // create the sorters
        sortIds[index] = tc.createSort((Properties) null, idxRows[index].getRowArrayClone(), order[index], sortObserver, // not in order
        false, // est rows
        rowCount, // est row size, -1 means no idea
        -1);
        needToDropSort[index] = true;
    }
    // Populate sorters and get the output of each sorter into a row
    // source.  The sorters have the indexed columns only and the columns
    // are in the correct order.
    rowSources = new RowLocationRetRowSource[numIndexes];
    // Fill in the RowSources
    SortController[] sorter = new SortController[numIndexes];
    for (int index = 0; index < numIndexes; index++) {
        sorter[index] = tc.openSort(sortIds[index]);
        sorter[index].completedInserts();
        rowSources[index] = tc.openSortRowSource(sortIds[index]);
    }
    long[] newIndexCongloms = new long[numIndexes];
    // Populate each index
    for (int index = 0; index < numIndexes; index++) {
        ConglomerateController indexCC;
        Properties properties = new Properties();
        ConglomerateDescriptor cd;
        // Get the ConglomerateDescriptor for the index
        cd = td.getConglomerateDescriptor(constants.indexCIDS[index]);
        // Build the properties list for the new conglomerate
        indexCC = tc.openCompiledConglomerate(false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE, constants.indexSCOCIs[index], indexDCOCIs[index]);
        // Get the properties on the old index
        indexCC.getInternalTablePropertySet(properties);
        /* Create the properties that language supplies when creating the
			 * the index.  (The store doesn't preserve these.)
			 */
        int indexRowLength = idxRows[index].nColumns();
        properties.put("baseConglomerateId", Long.toString(newHeapConglom));
        if (cd.getIndexDescriptor().isUnique()) {
            properties.put("nUniqueColumns", Integer.toString(indexRowLength - 1));
        } else {
            properties.put("nUniqueColumns", Integer.toString(indexRowLength));
        }
        if (cd.getIndexDescriptor().isUniqueWithDuplicateNulls() && !cd.getIndexDescriptor().hasDeferrableChecking()) {
            properties.put("uniqueWithDuplicateNulls", Boolean.toString(true));
        }
        properties.put("rowLocationColumn", Integer.toString(indexRowLength - 1));
        properties.put("nKeyFields", Integer.toString(indexRowLength));
        indexCC.close();
        collation[index] = constants.irgs[index].getColumnCollationIds(td.getColumnDescriptorList());
        // We can finally drain the sorter and rebuild the index
        // Populate the index.
        newIndexCongloms[index] = tc.createAndLoadConglomerate("BTREE", idxRows[index].getRowArray(), // default column sort order
        null, collation[index], properties, TransactionController.IS_DEFAULT, rowSources[index], (long[]) null);
        /* Update the DataDictionary
			 *
			 * Update sys.sysconglomerates with new conglomerate #, if the
			 * conglomerate is shared by duplicate indexes, all the descriptors
			 * for those indexes need to be updated with the new number.
			 */
        dd.updateConglomerateDescriptor(td.getConglomerateDescriptors(constants.indexCIDS[index]), newIndexCongloms[index], tc);
        // Drop the old conglomerate
        tc.dropConglomerate(constants.indexCIDS[index]);
    }
}
Also used : ColumnOrdering(org.apache.derby.iapi.store.access.ColumnOrdering) ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController) Properties(java.util.Properties) LanguageProperties(org.apache.derby.iapi.sql.LanguageProperties) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow) ConglomerateDescriptor(org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor) SortObserver(org.apache.derby.iapi.store.access.SortObserver) IndexRowGenerator(org.apache.derby.iapi.sql.dictionary.IndexRowGenerator) ConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet) UUID(org.apache.derby.catalog.UUID) SortController(org.apache.derby.iapi.store.access.SortController)

Example 2 with SortController

use of org.apache.derby.iapi.store.access.SortController in project derby by apache.

the class RAMTransaction method closeControllers.

/**
 ************************************************************************
 * Private/Protected methods of This class:
 **************************************************************************
 */
// XXX (nat) currently closes all controllers.
protected void closeControllers(boolean closeHeldControllers) throws StandardException {
    if (!scanControllers.isEmpty()) {
        // loop from end to beginning, removing scans which are not held.
        for (int i = scanControllers.size() - 1; i >= 0; i--) {
            ScanManager sc = scanControllers.get(i);
            if (sc.closeForEndTransaction(closeHeldControllers)) {
            // TODO - now counting on scan's removing themselves by
            // calling the closeMe() method.
            /* scanControllers.removeElementAt(i); */
            }
        }
        if (closeHeldControllers) {
            if (SanityManager.DEBUG) {
                SanityManager.ASSERT(scanControllers.isEmpty());
            }
            // just to make sure everything has been closed and removed.
            scanControllers.clear();
        }
    }
    if (!conglomerateControllers.isEmpty()) {
        // loop from end to beginning, removing scans which are not held.
        for (int i = conglomerateControllers.size() - 1; i >= 0; i--) {
            ConglomerateController cc = conglomerateControllers.get(i);
            if (cc.closeForEndTransaction(closeHeldControllers)) {
            // TODO - now counting on cc's removing themselves by
            // calling the closeMe() method.
            /* conglomerateControllers.removeElementAt(i); */
            }
        }
        if (closeHeldControllers) {
            if (SanityManager.DEBUG) {
                SanityManager.ASSERT(scanControllers.isEmpty());
            }
            // just to make sure everything has been closed and removed.
            conglomerateControllers.clear();
        }
    }
    if ((sortControllers != null) && !sortControllers.isEmpty()) {
        if (closeHeldControllers) {
            // element from the list.
            for (int i = sortControllers.size() - 1; i >= 0; i--) {
                SortController sc = sortControllers.get(i);
                sc.completedInserts();
            }
            sortControllers.clear();
        }
    }
    if ((sorts != null) && (!sorts.isEmpty())) {
        if (closeHeldControllers) {
            // element from the list.
            for (int i = sorts.size() - 1; i >= 0; i--) {
                Sort sort = sorts.get(i);
                if (sort != null)
                    sort.drop(this);
            }
            sorts.clear();
            freeSortIds.clear();
        }
    }
}
Also used : ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController) Sort(org.apache.derby.iapi.store.access.conglomerate.Sort) ScanManager(org.apache.derby.iapi.store.access.conglomerate.ScanManager) SortController(org.apache.derby.iapi.store.access.SortController)

Example 3 with SortController

use of org.apache.derby.iapi.store.access.SortController in project derby by apache.

the class RAMTransaction method debugOpened.

/**
 * Return a string with debug information about opened congloms/scans/sorts.
 * <p>
 * Return a string with debugging information about current opened
 * congloms/scans/sorts which have not been close()'d.
 * Calls to this routine are only valid under code which is conditional
 * on SanityManager.DEBUG.
 * <p>
 *
 * @return String with debugging information.
 *
 * @exception  StandardException  Standard exception policy.
 */
public String debugOpened() throws StandardException {
    String str = null;
    if (SanityManager.DEBUG) {
        str = "";
        for (Iterator<ScanManager> it = scanControllers.iterator(); it.hasNext(); ) {
            ScanController sc = it.next();
            str += "open scan controller: " + sc + "\n";
        }
        for (Iterator<ConglomerateController> it = conglomerateControllers.iterator(); it.hasNext(); ) {
            ConglomerateController cc = (ConglomerateController) it.next();
            str += "open conglomerate controller: " + cc + "\n";
        }
        if (sortControllers != null) {
            for (Iterator<SortController> it = sortControllers.iterator(); it.hasNext(); ) {
                SortController sc = it.next();
                str += "open sort controller: " + sc + "\n";
            }
        }
        if (sorts != null) {
            for (int i = 0; i < sorts.size(); i++) {
                Sort sort = sorts.get(i);
                if (sort != null) {
                    str += "sorts created by createSort() in current xact:" + sort + "\n";
                }
            }
        }
        if (tempCongloms != null) {
            for (Iterator<Long> it = tempCongloms.keySet().iterator(); it.hasNext(); ) {
                Long conglomId = it.next();
                Conglomerate c = tempCongloms.get(conglomId);
                str += "temp conglomerate id = " + conglomId + ": " + c;
            }
        }
    }
    return (str);
}
Also used : GroupFetchScanController(org.apache.derby.iapi.store.access.GroupFetchScanController) ScanController(org.apache.derby.iapi.store.access.ScanController) ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController) ScanManager(org.apache.derby.iapi.store.access.conglomerate.ScanManager) Conglomerate(org.apache.derby.iapi.store.access.conglomerate.Conglomerate) Sort(org.apache.derby.iapi.store.access.conglomerate.Sort) SortController(org.apache.derby.iapi.store.access.SortController)

Example 4 with SortController

use of org.apache.derby.iapi.store.access.SortController in project derby by apache.

the class RAMTransaction method openSort.

/**
 *	@see TransactionController#openSort
 *	@exception StandardException Standard error policy.
 */
public SortController openSort(long id) throws StandardException {
    Sort sort;
    // if it doesn't exist.
    if (sorts == null || id >= sorts.size() || (sort = (sorts.get((int) id))) == null) {
        throw StandardException.newException(SQLState.AM_NO_SUCH_SORT, id);
    }
    // Open it.
    SortController sc = sort.open(this);
    // Keep track of it so we can release on close.
    if (sortControllers == null)
        sortControllers = new ArrayList<SortController>();
    sortControllers.add(sc);
    return sc;
}
Also used : ArrayList(java.util.ArrayList) Sort(org.apache.derby.iapi.store.access.conglomerate.Sort) SortController(org.apache.derby.iapi.store.access.SortController)

Example 5 with SortController

use of org.apache.derby.iapi.store.access.SortController in project derby by apache.

the class CreateIndexConstantAction method loadSorter.

/**
 * Scan the base conglomerate and insert the keys into a sorter,
 * returning a rowSource on the sorter.
 *
 * @return RowSource on the sorted index keys.
 *
 * @exception StandardException					thrown on error
 */
private RowLocationRetRowSource loadSorter(ExecRow[] baseRows, ExecIndexRow[] indexRows, TransactionController tc, GroupFetchScanController scan, long sortId, RowLocation[] rl) throws StandardException {
    SortController sorter;
    long rowCount = 0;
    sorter = tc.openSort(sortId);
    try {
        // Step through all the rows in the base table
        // prepare an array or rows for bulk fetch
        int bulkFetchSize = baseRows.length;
        if (SanityManager.DEBUG) {
            SanityManager.ASSERT(bulkFetchSize == indexRows.length, "number of base rows and index rows does not match");
            SanityManager.ASSERT(bulkFetchSize == rl.length, "number of base rows and row locations does not match");
        }
        DataValueDescriptor[][] baseRowArray = new DataValueDescriptor[bulkFetchSize][];
        for (int i = 0; i < bulkFetchSize; i++) baseRowArray[i] = baseRows[i].getRowArray();
        // rl[i] and baseRowArray[i] and indexRows[i] are all tied up
        // beneath the surface.  Fetching the base row and row location
        // from the table scan will automagically set up the indexRow
        // fetchNextGroup will return how many rows are actually fetched.
        int bulkFetched;
        while ((bulkFetched = scan.fetchNextGroup(baseRowArray, rl)) > 0) {
            for (int i = 0; i < bulkFetched; i++) {
                sorter.insert(indexRows[i].getRowArray());
                rowCount++;
            }
        }
        /*
			** We've just done a full scan on the heap, so set the number
			** of rows so the optimizer will have an accurate count.
			*/
        scan.setEstimatedRowCount(rowCount);
    } finally {
        sorter.completedInserts();
    }
    return new CardinalityCounter(tc.openSortRowSource(sortId));
}
Also used : DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) SortController(org.apache.derby.iapi.store.access.SortController)

Aggregations

SortController (org.apache.derby.iapi.store.access.SortController)8 Properties (java.util.Properties)4 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)4 ExecIndexRow (org.apache.derby.iapi.sql.execute.ExecIndexRow)3 ConglomerateController (org.apache.derby.iapi.store.access.ConglomerateController)3 SortObserver (org.apache.derby.iapi.store.access.SortObserver)3 Sort (org.apache.derby.iapi.store.access.conglomerate.Sort)3 TransactionController (org.apache.derby.iapi.store.access.TransactionController)2 ScanManager (org.apache.derby.iapi.store.access.conglomerate.ScanManager)2 ArrayList (java.util.ArrayList)1 UUID (org.apache.derby.catalog.UUID)1 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)1 LanguageProperties (org.apache.derby.iapi.sql.LanguageProperties)1 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)1 ConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor)1 IndexRowGenerator (org.apache.derby.iapi.sql.dictionary.IndexRowGenerator)1 ColumnOrdering (org.apache.derby.iapi.store.access.ColumnOrdering)1 GroupFetchScanController (org.apache.derby.iapi.store.access.GroupFetchScanController)1 ScanController (org.apache.derby.iapi.store.access.ScanController)1 Conglomerate (org.apache.derby.iapi.store.access.conglomerate.Conglomerate)1