Search in sources :

Example 46 with ExecIndexRow

use of org.apache.derby.iapi.sql.execute.ExecIndexRow in project derby by apache.

the class SYSCHECKSRowFactory method makeRow.

// ///////////////////////////////////////////////////////////////////////////
// 
// METHODS
// 
// ///////////////////////////////////////////////////////////////////////////
/**
 * Make a SYSCHECKS row
 *
 * @param td CheckConstraintDescriptorImpl
 *
 * @return	Row suitable for inserting into SYSCHECKS.
 *
 * @exception   StandardException thrown on failure
 */
public ExecRow makeRow(TupleDescriptor td, TupleDescriptor parent) throws StandardException {
    DataValueDescriptor col;
    ExecIndexRow row;
    ReferencedColumns rcd = null;
    String checkDefinition = null;
    String constraintID = null;
    if (td != null) {
        CheckConstraintDescriptor cd = (CheckConstraintDescriptor) td;
        /*
			** We only allocate a new UUID if the descriptor doesn't already have one.
			** For descriptors replicated from a Source system, we already have an UUID.
			*/
        constraintID = cd.getUUID().toString();
        checkDefinition = cd.getConstraintText();
        rcd = cd.getReferencedColumnsDescriptor();
    }
    /* Build the row */
    row = getExecutionFactory().getIndexableRow(SYSCHECKS_COLUMN_COUNT);
    /* 1st column is CONSTRAINTID (UUID - char(36)) */
    row.setColumn(SYSCHECKS_CONSTRAINTID, new SQLChar(constraintID));
    /* 2nd column is CHECKDEFINITION */
    row.setColumn(SYSCHECKS_CHECKDEFINITION, dvf.getLongvarcharDataValue(checkDefinition));
    /* 3rd column is REFERENCEDCOLUMNS
		 *  (user type org.apache.derby.catalog.ReferencedColumns)
		 */
    row.setColumn(SYSCHECKS_REFERENCEDCOLUMNS, new UserType(rcd));
    return row;
}
Also used : ReferencedColumns(org.apache.derby.catalog.ReferencedColumns) SQLChar(org.apache.derby.iapi.types.SQLChar) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) CheckConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor) SubCheckConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.SubCheckConstraintDescriptor) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow) UserType(org.apache.derby.iapi.types.UserType)

Example 47 with ExecIndexRow

use of org.apache.derby.iapi.sql.execute.ExecIndexRow in project derby by apache.

the class TabInfoImpl method updateRow.

/**
 * Updates a set of base rows in a catalog with the same key on an index
 * and updates all the corresponding index rows.
 *
 *	@param	key			key row
 *	@param	newRows		new version of the array of rows
 *	@param	indexNumber	index that key operates
 *	@param	indicesToUpdate	array of booleans, one for each index on the catalog.
 *							if a boolean is true, that means we must update the
 *							corresponding index because changes in the newRow
 *							affect it.
 *	@param  colsToUpdate	array of ints indicating which columns (1 based)
 *							to update.  If null, do all.
 *	@param	tc			transaction controller
 *
 * @exception StandardException		Thrown on failure
 */
void updateRow(ExecIndexRow key, ExecRow[] newRows, int indexNumber, boolean[] indicesToUpdate, int[] colsToUpdate, TransactionController tc) throws StandardException {
    ConglomerateController heapCC;
    ScanController drivingScan;
    ExecIndexRow drivingIndexRow;
    RowLocation baseRowLocation;
    ExecRow baseRow = crf.makeEmptyRow();
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(indicesToUpdate.length == crf.getNumIndexes(), "Wrong number of indices.");
    }
    RowChanger rc = getRowChanger(tc, colsToUpdate, baseRow);
    // Row level locking
    rc.openForUpdate(indicesToUpdate, TransactionController.MODE_RECORD, true);
    /* Open the heap conglomerate */
    heapCC = tc.openConglomerate(getHeapConglomerate(), false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
    drivingScan = tc.openScan(// conglomerate to open
    getIndexConglomerate(indexNumber), // don't hold open across commit
    false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
    (FormatableBitSet) null, // start position - first row
    key.getRowArray(), // startSearchOperation
    ScanController.GE, // scanQualifier
    null, // stop position - through last row
    key.getRowArray(), // stopSearchOperation
    ScanController.GT);
    // Get an index row based on the base row
    drivingIndexRow = getIndexRowFromHeapRow(getIndexRowGenerator(indexNumber), heapCC.newRowLocationTemplate(), crf.makeEmptyRow());
    int rowNum = 0;
    while (drivingScan.fetchNext(drivingIndexRow.getRowArray())) {
        baseRowLocation = (RowLocation) drivingIndexRow.getColumn(drivingIndexRow.nColumns());
        boolean base_row_exists = heapCC.fetch(baseRowLocation, baseRow.getRowArray(), (FormatableBitSet) null);
        if (SanityManager.DEBUG) {
            // it can not be possible for heap row to disappear while
            // holding scan cursor on index at ISOLATION_REPEATABLE_READ.
            SanityManager.ASSERT(base_row_exists, "base row not found");
        }
        rc.updateRow(baseRow, (rowNum == newRows.length - 1) ? newRows[rowNum] : newRows[rowNum++], baseRowLocation);
    }
    rc.finish();
    heapCC.close();
    drivingScan.close();
    rc.close();
}
Also used : ScanController(org.apache.derby.iapi.store.access.ScanController) ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) RowChanger(org.apache.derby.iapi.sql.execute.RowChanger) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow) RowLocation(org.apache.derby.iapi.types.RowLocation)

Example 48 with ExecIndexRow

use of org.apache.derby.iapi.sql.execute.ExecIndexRow in project derby by apache.

the class TabInfoImpl method insertRowListImpl.

/**
 *	  Insert logic to insert a list of rows into a table. This logic has two
 *	  odd features.
 *
 *	  <OL>
 *	  <LI>Returns an indication if any returned row was a duplicate.
 *	  <LI>Returns the RowLocation of the last row inserted.
 *	  </OL>
 *	  @param rowList the list of rows to insert
 *	  @param tc	transaction controller
 *	  @param rowLocationOut on output rowLocationOut[0] is set to the
 *	         last RowLocation inserted.
 *	  @return row number (&gt;= 0) if duplicate row inserted into an index
 *	  			ROWNOTDUPLICATE otherwise
 */
private int insertRowListImpl(ExecRow[] rowList, TransactionController tc, RowLocation[] rowLocationOut) throws StandardException {
    ConglomerateController heapController;
    RowLocation heapLocation;
    ExecIndexRow indexableRow;
    int insertRetCode;
    int retCode = ROWNOTDUPLICATE;
    int indexCount = crf.getNumIndexes();
    ConglomerateController[] indexControllers = new ConglomerateController[indexCount];
    // Open the conglomerates
    heapController = tc.openConglomerate(getHeapConglomerate(), false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
    for (int ictr = 0; ictr < indexCount; ictr++) {
        long conglomNumber = getIndexConglomerate(ictr);
        if (conglomNumber > -1) {
            indexControllers[ictr] = tc.openConglomerate(conglomNumber, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
        }
    }
    heapLocation = heapController.newRowLocationTemplate();
    rowLocationOut[0] = heapLocation;
    // loop through rows on this list, inserting them into system table
    for (int rowNumber = 0; rowNumber < rowList.length; rowNumber++) {
        ExecRow row = rowList[rowNumber];
        // insert the base row and get its new location
        heapController.insertAndFetchLocation(row.getRowArray(), heapLocation);
        for (int ictr = 0; ictr < indexCount; ictr++) {
            if (indexControllers[ictr] == null) {
                continue;
            }
            // Get an index row based on the base row
            indexableRow = getIndexRowFromHeapRow(getIndexRowGenerator(ictr), heapLocation, row);
            insertRetCode = indexControllers[ictr].insert(indexableRow.getRowArray());
            if (insertRetCode == ConglomerateController.ROWISDUPLICATE) {
                retCode = rowNumber;
            }
        }
    }
    // Close the open conglomerates
    for (int ictr = 0; ictr < indexCount; ictr++) {
        if (indexControllers[ictr] == null) {
            continue;
        }
        indexControllers[ictr].close();
    }
    heapController.close();
    return retCode;
}
Also used : ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) RowLocation(org.apache.derby.iapi.types.RowLocation) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow)

Example 49 with ExecIndexRow

use of org.apache.derby.iapi.sql.execute.ExecIndexRow in project derby by apache.

the class TabInfoImpl method getRowInternal.

/**
 * @exception StandardException		Thrown on failure
 */
private ExecRow getRowInternal(TransactionController tc, ConglomerateController heapCC, ExecIndexRow key, int indexNumber, RowLocation[] rl) throws StandardException {
    ScanController drivingScan;
    ExecIndexRow drivingIndexRow;
    RowLocation baseRowLocation;
    ExecRow baseRow = crf.makeEmptyRow();
    drivingScan = tc.openScan(getIndexConglomerate(indexNumber), // don't hold open across commit
    false, // open for read
    0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
    (FormatableBitSet) null, // start position - first row
    key.getRowArray(), // startSearchOperation
    ScanController.GE, // scanQualifier
    null, // stop position - through last row
    key.getRowArray(), // stopSearchOperation
    ScanController.GT);
    // Get an index row based on the base row
    drivingIndexRow = getIndexRowFromHeapRow(getIndexRowGenerator(indexNumber), heapCC.newRowLocationTemplate(), crf.makeEmptyRow());
    try {
        if (drivingScan.fetchNext(drivingIndexRow.getRowArray())) {
            rl[0] = baseRowLocation = (RowLocation) drivingIndexRow.getColumn(drivingIndexRow.nColumns());
            boolean base_row_exists = heapCC.fetch(baseRowLocation, baseRow.getRowArray(), (FormatableBitSet) null);
            if (SanityManager.DEBUG) {
                // it can not be possible for heap row to disappear while
                // holding scan cursor on index at ISOLATION_REPEATABLE_READ.
                SanityManager.ASSERT(base_row_exists, "base row not found");
            }
            return baseRow;
        } else {
            return null;
        }
    } finally {
        drivingScan.close();
    }
}
Also used : ScanController(org.apache.derby.iapi.store.access.ScanController) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow) RowLocation(org.apache.derby.iapi.types.RowLocation)

Example 50 with ExecIndexRow

use of org.apache.derby.iapi.sql.execute.ExecIndexRow in project derby by apache.

the class IndexStatisticsDaemonImpl method updateIndexStatsMinion.

/**
 * Updates the index statistics for the given table and the specified
 * indexes.
 * <p>
 * <strong>API note</strong>: Using {@code null} to update the statistics
 * for all conglomerates is preferred over explicitly passing an array with
 * all the conglomerates for the table. Doing so allows for some
 * optimizations, and will cause a disposable statistics check to be
 * performed.
 *
 * @param lcc language connection context used to perform the work
 * @param td the table to update index stats for
 * @param cds the conglomerates to update statistics for (non-index
 *      conglomerates will be ignored), {@code null} means all indexes
 * @param asBackgroundTask whether the updates are done automatically as
 *      part of a background task or if explicitly invoked by the user
 * @throws StandardException if something goes wrong
 */
private void updateIndexStatsMinion(LanguageConnectionContext lcc, TableDescriptor td, ConglomerateDescriptor[] cds, boolean asBackgroundTask) throws StandardException {
    // can only properly identify disposable stats if cds == null,
    // which means we are processing all indexes on the conglomerate.
    final boolean identifyDisposableStats = (cds == null);
    // Fetch descriptors if we're updating statistics for all indexes.
    if (cds == null) {
        cds = td.getConglomerateDescriptors();
    }
    // Extract/derive information from the table descriptor
    long[] conglomerateNumber = new long[cds.length];
    ExecIndexRow[] indexRow = new ExecIndexRow[cds.length];
    TransactionController tc = lcc.getTransactionExecute();
    ConglomerateController heapCC = tc.openConglomerate(td.getHeapConglomerateId(), false, 0, TransactionController.MODE_RECORD, asBackgroundTask ? TransactionController.ISOLATION_READ_UNCOMMITTED : TransactionController.ISOLATION_REPEATABLE_READ);
    // create a list of indexes that should have statistics, by looking
    // at all indexes on the conglomerate, and conditionally skipping
    // unique single column indexes.  This set is the "non disposable
    // stat list".
    UUID[] non_disposable_objectUUID = new UUID[cds.length];
    try {
        for (int i = 0; i < cds.length; i++) {
            // Skip non-index conglomerates
            if (!cds[i].isIndex()) {
                conglomerateNumber[i] = -1;
                continue;
            }
            IndexRowGenerator irg = cds[i].getIndexDescriptor();
            // or we are running in soft-upgrade-mode on a pre 10.9 db.
            if (skipDisposableStats) {
                if (irg.isUnique() && irg.numberOfOrderedColumns() == 1) {
                    conglomerateNumber[i] = -1;
                    continue;
                }
            }
            // at this point have found a stat for an existing
            // index which is not a single column unique index, add it
            // to the list of "non disposable stats"
            conglomerateNumber[i] = cds[i].getConglomerateNumber();
            non_disposable_objectUUID[i] = cds[i].getUUID();
            indexRow[i] = irg.getNullIndexRow(td.getColumnDescriptorList(), heapCC.newRowLocationTemplate());
        }
    } finally {
        heapCC.close();
    }
    if (identifyDisposableStats) {
        // Note this loop is not controlled by the skipDisposableStats
        // flag.  The above loop controls if we drop single column unique
        // index stats or not.  In all cases we are going to drop
        // stats with no associated index (orphaned stats).
        List<StatisticsDescriptor> existingStats = td.getStatistics();
        StatisticsDescriptor[] stats = (StatisticsDescriptor[]) existingStats.toArray(new StatisticsDescriptor[existingStats.size()]);
        // those entries that don't have a matching conglomerate in the
        for (int si = 0; si < stats.length; si++) {
            UUID referencedIndex = stats[si].getReferenceID();
            boolean isValid = false;
            for (int ci = 0; ci < conglomerateNumber.length; ci++) {
                if (referencedIndex.equals(non_disposable_objectUUID[ci])) {
                    isValid = true;
                    break;
                }
            }
            // mechanism in case of another bug like DERBY-5681 in Derby.
            if (!isValid) {
                String msg = "dropping disposable statistics entry " + stats[si].getUUID() + " for index " + stats[si].getReferenceID() + " (cols=" + stats[si].getColumnCount() + ")";
                logAlways(td, null, msg);
                trace(1, msg + " on table " + stats[si].getTableUUID());
                DataDictionary dd = lcc.getDataDictionary();
                if (!lcc.dataDictionaryInWriteMode()) {
                    dd.startWriting(lcc);
                }
                dd.dropStatisticsDescriptors(td.getUUID(), stats[si].getReferenceID(), tc);
                if (asBackgroundTask) {
                    lcc.internalCommit(true);
                }
            }
        }
    }
    // [x][0] = conglomerate number, [x][1] = start time, [x][2] = stop time
    long[][] scanTimes = new long[conglomerateNumber.length][3];
    int sci = 0;
    for (int indexNumber = 0; indexNumber < conglomerateNumber.length; indexNumber++) {
        if (conglomerateNumber[indexNumber] == -1)
            continue;
        // Check if daemon has been disabled.
        if (asBackgroundTask) {
            if (isShuttingDown()) {
                break;
            }
        }
        scanTimes[sci][0] = conglomerateNumber[indexNumber];
        scanTimes[sci][1] = System.currentTimeMillis();
        // Subtract one for the RowLocation added for indexes.
        int numCols = indexRow[indexNumber].nColumns() - 1;
        long[] cardinality = new long[numCols];
        KeyComparator cmp = new KeyComparator(indexRow[indexNumber]);
        /* Read uncommitted, with record locking. Actually CS store may
               not hold record locks */
        GroupFetchScanController gsc = tc.openGroupFetchScan(conglomerateNumber[indexNumber], // hold
        false, 0, // locking
        TransactionController.MODE_RECORD, TransactionController.ISOLATION_READ_UNCOMMITTED, // scancolumnlist-- want everything.
        null, // startkeyvalue-- start from the beginning.
        null, 0, // qualifiers, none!
        null, // stopkeyvalue,
        null, 0);
        try {
            int rowsFetched = 0;
            boolean giving_up_on_shutdown = false;
            while ((rowsFetched = cmp.fetchRows(gsc)) > 0) {
                // I/O that is processed as a convenient point.
                if (asBackgroundTask) {
                    if (isShuttingDown()) {
                        giving_up_on_shutdown = true;
                        break;
                    }
                }
                for (int i = 0; i < rowsFetched; i++) {
                    int whichPositionChanged = cmp.compareWithPrevKey(i);
                    if (whichPositionChanged >= 0) {
                        for (int j = whichPositionChanged; j < numCols; j++) cardinality[j]++;
                    }
                }
            }
            if (giving_up_on_shutdown)
                break;
            gsc.setEstimatedRowCount(cmp.getRowCount());
        } finally // try
        {
            gsc.close();
            gsc = null;
        }
        scanTimes[sci++][2] = System.currentTimeMillis();
        // We have scanned the indexes, so let's give this a few attempts
        // before giving up.
        int retries = 0;
        while (true) {
            try {
                writeUpdatedStats(lcc, td, non_disposable_objectUUID[indexNumber], cmp.getRowCount(), cardinality, asBackgroundTask);
                break;
            } catch (StandardException se) {
                retries++;
                if (se.isLockTimeout() && retries < 3) {
                    trace(2, "lock timeout when writing stats, retrying");
                    sleep(100 * retries);
                } else {
                    // o too many lock timeouts
                    throw se;
                }
            }
        }
    }
    log(asBackgroundTask, td, fmtScanTimes(scanTimes));
}
Also used : StatisticsDescriptor(org.apache.derby.iapi.sql.dictionary.StatisticsDescriptor) ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) GroupFetchScanController(org.apache.derby.iapi.store.access.GroupFetchScanController) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow) StandardException(org.apache.derby.shared.common.error.StandardException) IndexRowGenerator(org.apache.derby.iapi.sql.dictionary.IndexRowGenerator) TransactionController(org.apache.derby.iapi.store.access.TransactionController) UUID(org.apache.derby.catalog.UUID)

Aggregations

ExecIndexRow (org.apache.derby.iapi.sql.execute.ExecIndexRow)110 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)72 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)34 SQLVarchar (org.apache.derby.iapi.types.SQLVarchar)30 TupleDescriptor (org.apache.derby.iapi.sql.dictionary.TupleDescriptor)27 SQLChar (org.apache.derby.iapi.types.SQLChar)22 ConglomerateController (org.apache.derby.iapi.store.access.ConglomerateController)14 SQLLongint (org.apache.derby.iapi.types.SQLLongint)13 RowLocation (org.apache.derby.iapi.types.RowLocation)12 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)10 ScanController (org.apache.derby.iapi.store.access.ScanController)9 UUID (org.apache.derby.catalog.UUID)8 ArrayList (java.util.ArrayList)7 ColumnDescriptorList (org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList)6 ConglomerateDescriptorList (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptorList)6 ConstraintDescriptorList (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList)6 TransactionController (org.apache.derby.iapi.store.access.TransactionController)6 Properties (java.util.Properties)5 PermissionsDescriptor (org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor)5 TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)5