Search in sources :

Example 1 with IndexLister

use of org.apache.derby.iapi.sql.dictionary.IndexLister in project derby by apache.

the class AlterTableConstantAction method getAffectedIndexes.

/**
 * Get info on the indexes on the table being compressed.
 *
 * @exception StandardException		Thrown on error
 */
private void getAffectedIndexes() throws StandardException {
    IndexLister indexLister = td.getIndexLister();
    /* We have to get non-distinct index row generaters and conglom numbers
		 * here and then compress it to distinct later because drop column
		 * will need to change the index descriptor directly on each index
		 * entry in SYSCONGLOMERATES, on duplicate indexes too.
		 */
    compressIRGs = indexLister.getIndexRowGenerators();
    numIndexes = compressIRGs.length;
    indexConglomerateNumbers = indexLister.getIndexConglomerateNumbers();
    if (// then it's drop column
    !(compressTable || truncateTable)) {
        ArrayList<ConstantAction> newCongloms = new ArrayList<ConstantAction>();
        for (int i = 0; i < compressIRGs.length; i++) {
            int[] baseColumnPositions = compressIRGs[i].baseColumnPositions();
            int j;
            for (j = 0; j < baseColumnPositions.length; j++) if (baseColumnPositions[j] == droppedColumnPosition)
                break;
            if (// not related
            j == baseColumnPositions.length)
                continue;
            if (baseColumnPositions.length == 1 || (behavior == StatementType.DROP_CASCADE && compressIRGs[i].isUnique())) {
                numIndexes--;
                /* get first conglomerate with this conglom number each time
					 * and each duplicate one will be eventually all dropped
					 */
                ConglomerateDescriptor cd = td.getConglomerateDescriptor(indexConglomerateNumbers[i]);
                dropConglomerate(cd, td, true, newCongloms, activation, activation.getLanguageConnectionContext());
                // mark it
                compressIRGs[i] = null;
                continue;
            }
            // a constraint, because constraints have already been handled
            if (compressIRGs[i].isUnique()) {
                ConglomerateDescriptor cd = td.getConglomerateDescriptor(indexConglomerateNumbers[i]);
                throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT, dm.getActionString(DependencyManager.DROP_COLUMN), columnInfo[0].name, "UNIQUE INDEX", cd.getConglomerateName());
            }
        }
        /* If there are new backing conglomerates which must be
			 * created to replace a dropped shared conglomerate
			 * (where the shared conglomerate was dropped as part
			 * of a "drop conglomerate" call above), then create
			 * them now.  We do this *after* dropping all dependent
			 * conglomerates because we don't want to waste time
			 * creating a new conglomerate if it's just going to be
			 * dropped again as part of another "drop conglomerate"
			 * call.
			 */
        createNewBackingCongloms(newCongloms, indexConglomerateNumbers);
        IndexRowGenerator[] newIRGs = new IndexRowGenerator[numIndexes];
        long[] newIndexConglomNumbers = new long[numIndexes];
        collation = new int[numIndexes][];
        for (int i = 0, j = 0; i < numIndexes; i++, j++) {
            while (compressIRGs[j] == null) j++;
            // Setup collation id array to be passed in on call to create index.
            collation[i] = compressIRGs[j].getColumnCollationIds(td.getColumnDescriptorList());
            int[] baseColumnPositions = compressIRGs[j].baseColumnPositions();
            newIRGs[i] = compressIRGs[j];
            newIndexConglomNumbers[i] = indexConglomerateNumbers[j];
            boolean[] isAscending = compressIRGs[j].isAscending();
            boolean reMakeArrays = false;
            boolean rewriteBaseColumnPositions = false;
            int size = baseColumnPositions.length;
            for (int k = 0; k < size; k++) {
                if (baseColumnPositions[k] > droppedColumnPosition) {
                    baseColumnPositions[k]--;
                    rewriteBaseColumnPositions = true;
                } else if (baseColumnPositions[k] == droppedColumnPosition) {
                    // mark it
                    baseColumnPositions[k] = 0;
                    reMakeArrays = true;
                }
            }
            if (rewriteBaseColumnPositions) {
                compressIRGs[j].setBaseColumnPositions(baseColumnPositions);
            }
            if (reMakeArrays) {
                size--;
                int[] newBCP = new int[size];
                boolean[] newIsAscending = new boolean[size];
                int[] newCollation = new int[collation[i].length - 1];
                for (int k = 0, step = 0; k < size; k++) {
                    if (step == 0 && baseColumnPositions[k + step] == 0)
                        step++;
                    newBCP[k] = baseColumnPositions[k + step];
                    newIsAscending[k] = isAscending[k + step];
                    newCollation[k] = collation[i][k + step];
                }
                IndexDescriptor id = compressIRGs[j].getIndexDescriptor();
                id.setBaseColumnPositions(newBCP);
                id.setIsAscending(newIsAscending);
                id.setNumberOfOrderedColumns(id.numberOfOrderedColumns() - 1);
                collation[i] = newCollation;
            }
        }
        compressIRGs = newIRGs;
        indexConglomerateNumbers = newIndexConglomNumbers;
    } else {
        collation = new int[numIndexes][];
        for (int i = 0; i < numIndexes; i++) {
            collation[i] = compressIRGs[i].getColumnCollationIds(td.getColumnDescriptorList());
        }
    }
    /* Now we are done with updating each index descriptor entry directly
		 * in SYSCONGLOMERATES (for duplicate index as well), from now on, our
		 * work should apply ONLY once for each real conglomerate, so we
		 * compress any duplicate indexes now.
		 */
    Object[] compressIndexResult = compressIndexArrays(indexConglomerateNumbers, compressIRGs);
    if (compressIndexResult != null) {
        indexConglomerateNumbers = (long[]) compressIndexResult[1];
        compressIRGs = (IndexRowGenerator[]) compressIndexResult[2];
        numIndexes = indexConglomerateNumbers.length;
    }
    indexedCols = new FormatableBitSet(compressTable || truncateTable ? td.getNumberOfColumns() + 1 : td.getNumberOfColumns());
    for (int index = 0; index < numIndexes; index++) {
        int[] colIds = compressIRGs[index].getIndexDescriptor().baseColumnPositions();
        for (int index2 = 0; index2 < colIds.length; index2++) {
            indexedCols.set(colIds[index2]);
        }
    }
}
Also used : ArrayList(java.util.ArrayList) IndexLister(org.apache.derby.iapi.sql.dictionary.IndexLister) IndexDescriptor(org.apache.derby.catalog.IndexDescriptor) ConglomerateDescriptor(org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor) ConstantAction(org.apache.derby.iapi.sql.execute.ConstantAction) IndexRowGenerator(org.apache.derby.iapi.sql.dictionary.IndexRowGenerator) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet)

Example 2 with IndexLister

use of org.apache.derby.iapi.sql.dictionary.IndexLister in project derby by apache.

the class InsertNode method getAffectedIndexes.

/**
 * Get the list of indexes on the table being inserted into.  This
 * is used by INSERT.  This is an optimized version of what
 * UPDATE and DELETE use.
 *
 * @param td	TableDescriptor for the table being inserted into
 *				or deleted from
 *
 * @exception StandardException		Thrown on error
 */
private void getAffectedIndexes(TableDescriptor td) throws StandardException {
    IndexLister indexLister = td.getIndexLister();
    indicesToMaintain = indexLister.getDistinctIndexRowGenerators();
    indexConglomerateNumbers = indexLister.getDistinctIndexConglomerateNumbers();
    indexNames = indexLister.getDistinctIndexNames();
    /* Add dependencies on all indexes in the list */
    ConglomerateDescriptor[] cds = td.getConglomerateDescriptors();
    CompilerContext cc = getCompilerContext();
    for (int index = 0; index < cds.length; index++) {
        cc.createDependency(cds[index]);
    }
}
Also used : CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) IndexLister(org.apache.derby.iapi.sql.dictionary.IndexLister) ConglomerateDescriptor(org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)

Aggregations

ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)2 IndexLister (org.apache.derby.iapi.sql.dictionary.IndexLister)2 ArrayList (java.util.ArrayList)1 IndexDescriptor (org.apache.derby.catalog.IndexDescriptor)1 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)1 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)1 IndexRowGenerator (org.apache.derby.iapi.sql.dictionary.IndexRowGenerator)1 ConstantAction (org.apache.derby.iapi.sql.execute.ConstantAction)1