📄 altertableconstantaction.java
字号:
} } compressIRGs = newIRGs; indexConglomerateNumbers = newIndexConglomNumbers; } /* 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]); } } } /** * Set up to update all of the indexes on a table when doing a bulk insert * on an empty table. * * @exception StandardException thrown on error */ private void setUpAllSorts(ExecRow sourceRow, RowLocation rl) throws StandardException { ordering = new ColumnOrdering[numIndexes][]; needToDropSort = new boolean[numIndexes]; sortIds = new long[numIndexes]; /* 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 indexRows[index] = compressIRGs[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.) compressIRGs[index].getIndexRow(sourceRow, rl, indexRows[index], (FormatableBitSet) null); /* For non-unique indexes, we order by all columns + the RID. * For unique indexes, we just order by the columns. * No need to try to enforce uniqueness here as * index should be valid. */ int[] baseColumnPositions = compressIRGs[index].baseColumnPositions(); boolean[] isAscending = compressIRGs[index].isAscending(); int numColumnOrderings; SortObserver sortObserver = null; /* We can only reuse the wrappers when doing an * external sort if there is only 1 index. Otherwise, * we could get in a situation where 1 sort reuses a * wrapper that is still in use in another sort. */ boolean reuseWrappers = (numIndexes == 1); numColumnOrderings = baseColumnPositions.length + 1; sortObserver = new BasicSortObserver(false, false, indexRows[index], reuseWrappers); ordering[index] = new ColumnOrdering[numColumnOrderings]; for (int ii =0; ii < numColumnOrderings - 1; ii++) { ordering[index][ii] = new IndexColumnOrder(ii, isAscending[ii]); } ordering[index][numColumnOrderings - 1] = new IndexColumnOrder(numColumnOrderings - 1); // create the sorters sortIds[index] = tc.createSort( (Properties)null, indexRows[index].getRowArrayClone(), ordering[index], sortObserver, false, // not in order estimatedRowCount, // est rows -1 // est row size, -1 means no idea ); } sorters = new SortController[numIndexes]; // Open the sorts for (int index = 0; index < numIndexes; index++) { sorters[index] = tc.openSort(sortIds[index]); needToDropSort[index] = true; } } // RowSource interface /** * @see RowSource#getValidColumns */ public FormatableBitSet getValidColumns() { // All columns are valid return null; } /** * @see RowSource#getNextRowFromRowSource * @exception StandardException on error */ public DataValueDescriptor[] getNextRowFromRowSource() throws StandardException { currentRow = null; // Time for a new bulk fetch? if ((! doneScan) && (currentCompressRow == bulkFetchSize || !validRow[currentCompressRow])) { int bulkFetched = 0; bulkFetched = compressHeapGSC.fetchNextGroup(baseRowArray, compressRL); doneScan = (bulkFetched != bulkFetchSize); currentCompressRow = 0; rowCount += bulkFetched; for (int index = 0; index < bulkFetched; index++) { validRow[index] = true; } for (int index = bulkFetched; index < bulkFetchSize; index++) { validRow[index] = false; } } if (validRow[currentCompressRow]) { if (compressTable) currentRow = baseRow[currentCompressRow]; else { if (currentRow == null) currentRow = activation.getExecutionFactory().getValueRow(baseRowArray[currentCompressRow].length - 1); for (int i = 0; i < currentRow.nColumns(); i++) { currentRow.setColumn(i + 1, i < columnPosition - 1 ? baseRow[currentCompressRow].getColumn(i+1) : baseRow[currentCompressRow].getColumn(i+1+1)); } } currentCompressRow++; } if (currentRow != null) { /* Let the target preprocess the row. For now, this * means doing an in place clone on any indexed columns * to optimize cloning and so that we don't try to drain * a stream multiple times. */ if (compressIRGs.length > 0) { /* Do in-place cloning of all of the key columns */ currentRow = currentRow.getClone(indexedCols); } return currentRow.getRowArray(); } return null; } /** * @see RowSource#needsToClone */ public boolean needsToClone() { return(true); } /** * @see RowSource#closeRowSource */ public void closeRowSource() { // Do nothing here - actual work will be done in close() } // RowLocationRetRowSource interface /** * @see RowLocationRetRowSource#needsRowLocation */ public boolean needsRowLocation() { // Only true if table has indexes return (numIndexes > 0); } /** * @see RowLocationRetRowSource#rowLocation * @exception StandardException on error */ public void rowLocation(RowLocation rl) throws StandardException { /* Set up sorters, etc. if 1st row and there are indexes */ if (compressIRGs.length > 0) { objectifyStreamingColumns(); /* Put the row into the indexes. If sequential, * then we only populate the 1st sorter when compressing * the heap. */ int maxIndex = compressIRGs.length; if (maxIndex > 1 && sequential) { maxIndex = 1; } for (int index = 0; index < maxIndex; index++) { insertIntoSorter(index, rl); } } } private void objectifyStreamingColumns() throws StandardException { // Objectify any the streaming columns that are indexed. for (int i = 0; i < currentRow.getRowArray().length; i++) { /* Object array is 0-based, * indexedCols is 1-based. */ if (! indexedCols.get(i + 1)) { continue; } if (currentRow.getRowArray()[i] instanceof StreamStorable) { ((DataValueDescriptor) currentRow.getRowArray()[i]).getObject(); } } } private void insertIntoSorter(int index, RowLocation rl) throws StandardException { // Get a new object Array for the index indexRows[index].getNewObjectArray(); // Associate the index row with the source row compressIRGs[index].getIndexRow(currentRow, (RowLocation) rl.cloneObject(), indexRows[index], (FormatableBitSet) null); // Insert the index row into the matching sorter sorters[index].insert(indexRows[index].getRowArray()); } /** * @see ResultSet#cleanUp * * @exception StandardException Thrown on error */ public void cleanUp() throws StandardException { if (compressHeapCC != null) { compressHeapCC.close(); compressHeapCC = null; } if (compressHeapGSC != null) { closeBulkFetchScan(); } // Close each sorter if (sorters != null) { for (int index = 0; index < compressIRGs.length; index++) { if (sorters[index] != null) { sorters[index].close(); } sorters[index] = null; } } if (needToDropSort != null) { for (int index = 0; index < needToDropSort.length; index++) { if (needToDropSort[index]) { tc.dropSort(sortIds[index]); needToDropSort[index] = false; } } } } // class implementation /** * Return the "semi" row count of a table. We are only interested in * whether the table has 0, 1 or > 1 rows. * * * @return Number of rows (0, 1 or > 1) in table. * * @exception StandardException Thrown on failure */ private int getSemiRowCount(TransactionController tc) throws StandardException { int numRows = 0; ScanController sc = tc.openScan(td.getHeapConglomerateId(), false, // hold 0, // open read only TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE, RowUtil.EMPTY_ROW_BITSET, // scanColumnList null, // start position ScanController.GE, // startSearchOperation null, // scanQualifier null, //stop position - through last row ScanController.GT); // stopSearchOperation while (sc.next()) { numRows++; // We're only interested in whether the table has 0, 1 or > 1 rows if (numRows == 2) { break; } } sc.close(); return numRows; } /** * Update a new column with its default. * We could do the scan ourself here, but * instead we get a nested connection and * issue the appropriate update statement. * * @param columnName column name * @param defaultText default text * @param lcc the language connection context * * @exception StandardException if update to default fails */ private void updateNewColumnToDefault ( Activation activation, String columnName, String defaultText, LanguageConnectionContext lcc ) throws StandardException { /* Need to use delimited identifiers for all object names * to ensure correctness. */ String updateStmt = "UPDATE \"" + td.getSchemaName() + "\".\"" + td.getName() + "\" SET \"" + columnName + "\" = " + defaultText; AlterTableConstantAction.executeUpdate(lcc, updateStmt); } private static void executeUpdate(LanguageConnectionContext lcc, String updateStmt) throws StandardException { PreparedStatement ps = lcc.prepareInternalStatement(updateStmt); ResultSet rs = ps.execute(lcc, true); rs.close(); rs.finish(); } /** * computes the minimum/maximum value in a column of a table. */ private long getColumnMax(Activation activation,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -