Search in sources :

Example 66 with ConglomerateController

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

the class DataDictionaryImpl method addRemovePermissionsDescriptor.

/**
 * Add or remove a permission to/from the permission database.
 *
 * @param add if true then the permission is added, if false the permission is removed
 * @param perm
 * @param grantee
 * @param tc
 *
 * @return True means revoke has removed a privilege from system
 * table and hence the caller of this method should send invalidation
 * actions to PermssionDescriptor's dependents.
 */
public boolean addRemovePermissionsDescriptor(boolean add, PermissionsDescriptor perm, String grantee, TransactionController tc) throws StandardException {
    int catalogNumber = perm.getCatalogNumber();
    // It is possible for grant statements to look like following
    // grant execute on function f_abs to mamata2, mamata3;
    // grant all privileges on t11 to mamata2, mamata3;
    // This means that dd.addRemovePermissionsDescriptor will be called
    // twice for TablePermsDescriptor and twice for RoutinePermsDescriptor,
    // once for each grantee.
    // First it's called for mamta2. When a row is inserted for mamta2
    // into the correct system table for the permission descriptor, the
    // permission descriptor's uuid gets populated with the uuid of
    // the row that just got inserted into the system table for mamta2
    // Now, when dd.addRemovePermissionsDescriptor gets called again for
    // mamta3, the permission descriptor's uuid will still be set to
    // the uuid that was used for mamta2. If we do not reset the
    // uuid to null, we will think that there is a duplicate row getting
    // inserted for the same uuid. In order to get around this, we should
    // reset the UUID of passed PermissionDescriptor everytime this method
    // is called. This way, there will be no leftover values from previous
    // call of this method.
    perm.setUUID(null);
    perm.setGrantee(grantee);
    TabInfoImpl ti = getNonCoreTI(catalogNumber);
    PermissionsCatalogRowFactory rf = (PermissionsCatalogRowFactory) ti.getCatalogRowFactory();
    int primaryIndexNumber = rf.getPrimaryKeyIndexNumber();
    ConglomerateController heapCC = tc.openConglomerate(ti.getHeapConglomerate(), // do not keep open across commits
    false, 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
    RowLocation rl = null;
    try {
        rl = heapCC.newRowLocationTemplate();
    } finally {
        heapCC.close();
        heapCC = null;
    }
    ExecIndexRow key = rf.buildIndexKeyRow(primaryIndexNumber, perm);
    ExecRow existingRow = ti.getRow(tc, key, primaryIndexNumber);
    if (existingRow == null) {
        if (!add) {
            // permission and hence uuid can't be non-null
            return false;
        } else {
            // We didn't find an entry in system catalog and this is grant so
            // so that means we have to enter a new row in system catalog for
            // this grant.
            ExecRow row = ti.getCatalogRowFactory().makeRow(perm, (TupleDescriptor) null);
            int insertRetCode = ti.insertRow(row, tc);
            if (SanityManager.DEBUG) {
                SanityManager.ASSERT(insertRetCode == TabInfoImpl.ROWNOTDUPLICATE, "Race condition in inserting table privilege.");
            }
        }
    } else {
        // add/remove these permissions to/from the existing permissions
        boolean[] colsChanged = new boolean[existingRow.nColumns()];
        boolean[] indicesToUpdate = new boolean[rf.getNumIndexes()];
        int changedColCount = 0;
        if (add) {
            changedColCount = rf.orPermissions(existingRow, perm, colsChanged);
        } else {
            changedColCount = rf.removePermissions(existingRow, perm, colsChanged);
        }
        if (changedColCount == 0) {
            // just return
            return false;
        }
        if (!add) {
            // set the uuid of the passed permission descriptor to
            // corresponding rows's uuid in permissions system table. The
            // permission descriptor's uuid is required to have the
            // dependency manager send the revoke privilege action to
            // all the dependent objects on that permission descriptor.
            rf.setUUIDOfThePassedDescriptor(existingRow, perm);
        }
        if (changedColCount < 0) {
            // No permissions left in the current row
            ti.deleteRow(tc, key, primaryIndexNumber);
        } else if (changedColCount > 0) {
            int[] colsToUpdate = new int[changedColCount];
            changedColCount = 0;
            for (int i = 0; i < colsChanged.length; i++) {
                if (colsChanged[i])
                    colsToUpdate[changedColCount++] = i + 1;
            }
            if (SanityManager.DEBUG) {
                SanityManager.ASSERT(changedColCount == colsToUpdate.length, "return value of " + rf.getClass().getName() + ".orPermissions does not match the number of booleans it set in colsChanged.");
            }
            ti.updateRow(key, existingRow, primaryIndexNumber, indicesToUpdate, colsToUpdate, tc);
        }
    }
    // Remove cached permissions data. The cache may hold permissions data for this key even if
    // the row in the permissions table is new. In that case the cache may have an entry indicating no
    // permissions
    removePermEntryInCache(perm);
    // any invalidation actions to anyone and hence return false
    if (add) {
        return false;
    } else {
        return true;
    }
}
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) SQLLongint(org.apache.derby.iapi.types.SQLLongint)

Example 67 with ConglomerateController

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

the class DataDictionaryImpl method updateCurrentSequenceValue.

/**
 * Set the current value of an ANSI/ISO sequence. This method does not perform
 * any sanity checking but assumes that the caller knows what they are doing. If the
 * old value on disk is not what we expect it to be, then we are in a race with another
 * session. They won and we don't update the value on disk. However, if the old value
 * is null, that is a signal to us that we should update the value on disk anyway.
 *
 * @param tc			Transaction Controller to use.
 * @param rowLocation Row in SYSSEQUENCES to update.
 * @param wait True if we should wait for locks
 * @param oldValue What we expect to find in the CURRENTVALUE column.
 * @param newValue What to stuff into the CURRENTVALUE column.
 *
 * @return Returns true if the value was successfully updated, false if we lost a race with another session.
 *
 * @exception StandardException thrown on failure.
 */
public boolean updateCurrentSequenceValue(TransactionController tc, RowLocation rowLocation, boolean wait, Long oldValue, Long newValue) throws StandardException {
    int columnNum = SYSSEQUENCESRowFactory.SYSSEQUENCES_CURRENT_VALUE;
    FormatableBitSet columnToUpdate = new FormatableBitSet(SYSSEQUENCESRowFactory.SYSSEQUENCES_COLUMN_COUNT);
    TabInfoImpl ti = getNonCoreTI(SYSSEQUENCES_CATALOG_NUM);
    ConglomerateController heapCC = null;
    SYSSEQUENCESRowFactory rf = (SYSSEQUENCESRowFactory) ti.getCatalogRowFactory();
    ExecRow row = rf.makeEmptyRow();
    // FormatableBitSet is 0 based.
    // current value.
    columnToUpdate.set(columnNum - 1);
    try {
        /* if wait is true then we need to do a wait while trying to
			   open/fetch from the conglomerate. note we use wait both to
			   open as well as fetch from the conglomerate.
			*/
        heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false, (TransactionController.OPENMODE_FORUPDATE | ((wait) ? 0 : TransactionController.OPENMODE_LOCK_NOWAIT)), TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
        boolean baseRowExists = heapCC.fetch(rowLocation, row.getRowArray(), columnToUpdate, wait);
        // 
        if (!baseRowExists) {
            return false;
        }
        NumberDataValue oldValueOnDisk = (NumberDataValue) row.getColumn(columnNum);
        SQLLongint expectedOldValue;
        if (oldValue == null) {
            expectedOldValue = new SQLLongint();
        } else {
            expectedOldValue = new SQLLongint(oldValue.longValue());
        }
        // only update value if what's on disk is what we expected
        if ((oldValue == null) || (expectedOldValue.compare(oldValueOnDisk) == 0)) {
            SQLLongint newValueOnDisk;
            if (newValue == null) {
                newValueOnDisk = new SQLLongint();
            } else {
                newValueOnDisk = new SQLLongint(newValue.longValue());
            }
            row.setColumn(columnNum, newValueOnDisk);
            heapCC.replace(rowLocation, row.getRowArray(), columnToUpdate);
            return true;
        } else {
            return false;
        }
    } finally {
        if (heapCC != null) {
            heapCC.close();
        }
    }
}
Also used : ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController) SQLLongint(org.apache.derby.iapi.types.SQLLongint) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet) NumberDataValue(org.apache.derby.iapi.types.NumberDataValue) SQLLongint(org.apache.derby.iapi.types.SQLLongint)

Example 68 with ConglomerateController

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

the class DataDictionaryImpl method getConstraints.

/**
 * Return an List which of the relevant column matching
 * the indexed criteria.  If nothing matches, returns an
 * empty List (never returns null).
 *
 * @param uuid	The id of the constraint
 * @param indexId		The index id in SYS.SYSCONSTRAINTS
 * @param columnNum		The column to retrieve
 *
 * @return a list of UUIDs in an List.
 *
 * @exception StandardException		Thrown on error
 */
public List<UUID> getConstraints(UUID uuid, int indexId, int columnNum) throws StandardException {
    ExecIndexRow indexRow1;
    ExecRow outRow;
    RowLocation baseRowLocation;
    ConglomerateController heapCC = null;
    ScanController scanController = null;
    TransactionController tc;
    TabInfoImpl ti = getNonCoreTI(SYSCONSTRAINTS_CATALOG_NUM);
    SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti.getCatalogRowFactory();
    TableDescriptor td = null;
    List<UUID> slist = new ArrayList<UUID>();
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(indexId == SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX1_ID || indexId == SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_INDEX3_ID, "bad index id, must be one of the indexes on a uuid");
        SanityManager.ASSERT(columnNum > 0 && columnNum <= SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_COLUMN_COUNT, "invalid column number for column to be retrieved");
    }
    try {
        /* Use tableIDOrderable in both start and stop positions for scan */
        DataValueDescriptor orderable = getIDValueAsCHAR(uuid);
        /* Set up the start/stop position for the scan */
        ExecIndexRow keyRow = (ExecIndexRow) exFactory.getIndexableRow(1);
        keyRow.setColumn(1, orderable);
        // Get the current transaction controller
        tc = getTransactionCompile();
        outRow = rf.makeEmptyRow();
        heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false, 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
        // create an index row template
        indexRow1 = getIndexRowFromHeapRow(ti.getIndexRowGenerator(indexId), heapCC.newRowLocationTemplate(), outRow);
        // just interested in one column
        DataValueDescriptor[] rowTemplate = new DataValueDescriptor[SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_COLUMN_COUNT];
        FormatableBitSet columnToGetSet = new FormatableBitSet(SYSCONSTRAINTSRowFactory.SYSCONSTRAINTS_COLUMN_COUNT);
        columnToGetSet.set(columnNum - 1);
        rowTemplate[columnNum - 1] = new SQLChar();
        // Scan the index and go to the data pages for qualifying rows
        scanController = tc.openScan(// conglomerate to open
        ti.getIndexConglomerate(indexId), // don't hold open across commit
        false, // for read
        0, TransactionController.MODE_RECORD, // RESOLVE: should be level 2
        TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
        (FormatableBitSet) null, // start position - exact key match.
        keyRow.getRowArray(), // startSearchOperation
        ScanController.GE, // scanQualifier (none)
        null, // stop position - exact key match.
        keyRow.getRowArray(), // stopSearchOperation
        ScanController.GT);
        while (scanController.fetchNext(indexRow1.getRowArray())) {
            baseRowLocation = (RowLocation) indexRow1.getColumn(indexRow1.nColumns());
            // get the row and grab the uuid
            boolean base_row_exists = heapCC.fetch(baseRowLocation, rowTemplate, columnToGetSet);
            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");
            }
            slist.add(uuidFactory.recreateUUID((String) ((DataValueDescriptor) rowTemplate[columnNum - 1]).getObject()));
        }
    } finally {
        if (heapCC != null) {
            heapCC.close();
        }
        if (scanController != null) {
            scanController.close();
        }
    }
    return slist;
}
Also used : ScanController(org.apache.derby.iapi.store.access.ScanController) ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController) ArrayList(java.util.ArrayList) SQLChar(org.apache.derby.iapi.types.SQLChar) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow) TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) TransactionController(org.apache.derby.iapi.store.access.TransactionController) UUID(org.apache.derby.catalog.UUID) RowLocation(org.apache.derby.iapi.types.RowLocation)

Example 69 with ConglomerateController

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

the class DataDictionaryImpl method visitRoleGrants.

/**
 * Scan the {roleid, grantee, grantor} index on SYSROLES,
 * locate rows containing authId in column columnNo.
 *
 * The action argument can be either <code>EXISTS</code> or
 * <code>DROP</code> (to check for existence, or to drop that row).
 *
 * If the scan proves too slow, we should add more indexes.  only.
 *
 * @param ti <code>TabInfoImpl</code> for SYSROLES.
 * @param rf row factory for SYSROLES
 * @param columnNo the column number to match <code>authId</code> against
 * @param tc transaction controller
 * @param action drop matching rows (<code>DROP</code>), or return
 *        <code>true</code> if there is a matching row
 *        (<code>EXISTS</code>)
 *
 * @return action=EXISTS: return {@code true} if there is a matching row
 *      else return {@code false}.
 * @exception StandardException
 */
private boolean visitRoleGrants(TabInfoImpl ti, SYSROLESRowFactory rf, int columnNo, String authId, TransactionController tc, int action) throws StandardException {
    ConglomerateController heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false, 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
    DataValueDescriptor authIdOrderable = new SQLVarchar(authId);
    ScanQualifier[][] scanQualifier = exFactory.getScanQualifier(1);
    scanQualifier[0][0].setQualifier(columnNo - 1, /* to zero-based */
    authIdOrderable, Orderable.ORDER_OP_EQUALS, false, false, false);
    ScanController sc = tc.openScan(ti.getIndexConglomerate(rf.SYSROLES_INDEX_ID_EE_OR_IDX), // don't hold open across commit
    false, // for update
    0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
    (FormatableBitSet) null, // start position -
    (DataValueDescriptor[]) null, // startSearchOperation - none
    0, // 
    scanQualifier, // stop position -through last row
    (DataValueDescriptor[]) null, // stopSearchOperation - none
    0);
    try {
        ExecRow outRow = rf.makeEmptyRow();
        ExecIndexRow indexRow = getIndexRowFromHeapRow(ti.getIndexRowGenerator(rf.SYSROLES_INDEX_ID_EE_OR_IDX), heapCC.newRowLocationTemplate(), outRow);
        while (sc.fetchNext(indexRow.getRowArray())) {
            if (action == DataDictionaryImpl.EXISTS) {
                return true;
            } else if (action == DataDictionaryImpl.DROP) {
                ti.deleteRow(tc, indexRow, rf.SYSROLES_INDEX_ID_EE_OR_IDX);
            }
        }
    } finally {
        if (sc != null) {
            sc.close();
        }
        if (heapCC != null) {
            heapCC.close();
        }
    }
    return false;
}
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) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) SQLVarchar(org.apache.derby.iapi.types.SQLVarchar) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow)

Example 70 with ConglomerateController

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

the class BTreePostCommit method openIndex.

/**
 * Open index for either table level or row level update.
 * <p>
 * @param lock_level For table level use TransactionManager.MODE_TABLE,
 *                   for row   level use TransactionManager.MODE_RECORD
 * @param lock_mode  For table level use LockingPolicy.MODE_CONTAINER,
 *                   for row   level use LockingPolicy.MODE_RECORD
 *
 * @exception  StandardException  Standard exception policy.
 */
private final OpenBTree openIndex(TransactionManager internal_xact, int lock_level, int lock_mode) throws StandardException {
    OpenBTree open_btree = new OpenBTree();
    ConglomerateController base_cc = btree.lockTable(internal_xact, (ContainerHandle.MODE_FORUPDATE | ContainerHandle.MODE_LOCK_NOWAIT), lock_level, TransactionController.ISOLATION_REPEATABLE_READ);
    open_btree.init((TransactionManager) null, internal_xact, // open the container
    (ContainerHandle) null, internal_xact.getRawStoreXact(), false, (ContainerHandle.MODE_FORUPDATE | ContainerHandle.MODE_LOCK_NOWAIT), lock_level, btree.getBtreeLockingPolicy(internal_xact.getRawStoreXact(), lock_level, lock_mode, TransactionController.ISOLATION_REPEATABLE_READ, base_cc, open_btree), btree, // No logical undo necessry.
    (LogicalUndo) null, (DynamicCompiledOpenConglomInfo) null);
    return (open_btree);
}
Also used : ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController)

Aggregations

ConglomerateController (org.apache.derby.iapi.store.access.ConglomerateController)73 RowLocation (org.apache.derby.iapi.types.RowLocation)40 ScanController (org.apache.derby.iapi.store.access.ScanController)32 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)32 SQLLongint (org.apache.derby.iapi.types.SQLLongint)24 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)22 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)18 Properties (java.util.Properties)14 ExecIndexRow (org.apache.derby.iapi.sql.execute.ExecIndexRow)14 StandardException (org.apache.derby.shared.common.error.StandardException)12 TransactionController (org.apache.derby.iapi.store.access.TransactionController)11 SQLChar (org.apache.derby.iapi.types.SQLChar)9 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)8 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)6 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)5 ColumnOrdering (org.apache.derby.iapi.store.access.ColumnOrdering)5 UUID (org.apache.derby.catalog.UUID)4 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)4 ConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor)4 IndexRowGenerator (org.apache.derby.iapi.sql.dictionary.IndexRowGenerator)4