/** * Lock the base table. * * <p>Assumes that segment of the base container is the same as the segment of the btree segment. * * <p>RESOLVE - we really want to get the lock without opening the container. raw store will be * providing this. * * @param xact_manager Transaction to associate the lock with. * @exception StandardException Standard exception policy. */ public final ConglomerateController lockTable( TransactionManager xact_manager, int open_mode, int lock_level, int isolation_level) throws StandardException { open_mode |= TransactionController.OPENMODE_FOR_LOCK_ONLY; // open the base conglomerate - just to get the table lock. ConglomerateController cc = xact_manager.openConglomerate( this.baseConglomerateId, false, open_mode, lock_level, isolation_level); return (cc); }
/** * Initialize the scan for use. * * <p>Any changes to this method may have to be reflected in close as well. * * <p>The btree init opens the container (super.init), and stores away the state of the * qualifiers. The actual searching for the first position is delayed until the first next() call. * * @exception StandardException Standard exception policy. */ public void init( TransactionManager xact_manager, Transaction rawtran, int open_mode, int lock_level, LockingPolicy locking_policy, int isolation_level, boolean open_for_locking, FormatableBitSet scanColumnList, B2I conglomerate, B2IUndo undo) throws StandardException { // open and lock the base table. int base_open_mode = open_mode | TransactionController.OPENMODE_FOR_LOCK_ONLY; // open the base conglomerate - just to get lock base_cc_for_locking = xact_manager.openConglomerate( conglomerate.baseConglomerateId, false, base_open_mode, lock_level, isolation_level); BTreeLockingPolicy b2i_locking_policy = conglomerate.getBtreeLockingPolicy( rawtran, lock_level, open_mode, isolation_level, base_cc_for_locking, this); super.init( xact_manager, rawtran, false, open_mode, lock_level, b2i_locking_policy, scanColumnList, (DataValueDescriptor[]) null, // no start position supported ScanController.NA, // no start position supported (Qualifier[][]) null, // no qualifier supported (DataValueDescriptor[]) null, // no stop position supported ScanController.NA, // no stop position supported conglomerate, undo, (StaticCompiledOpenConglomInfo) null, (DynamicCompiledOpenConglomInfo) null); }
/** * Create an empty secondary index b-tree, using the generic b-tree to do the generic part of the * creation process. * * <p>This routine opens the newly created container, adds a single page, and makes this page the * root by inserting a LeafControlRow onto this page at slot 0 and marking in that control row * that the page is a root page. * * <p>The following properties are specific to the b-tree secondary index: * * <UL> * <LI>"baseConglomerateId" (integer). The conglomerate id of the base conglomerate is never * actually accessed by the b-tree secondary index implementation, it only serves as a * namespace for row locks. This property is required. * <LI>"rowLocationColumn" (integer). The zero-based index into the row which the b-tree * secondary index will assume holds a @see RowLocation of the base row in the base * conglomerate. This value will be used for acquiring locks. In this implementation * RowLocationColumn must be the last key column. This property is required. * </UL> * * A secondary index i (a, b) on table t (a, b, c) would have rows which looked like (a, b, * row_location). baseConglomerateId is set to the conglomerate id of t. rowLocationColumns is set * to 2. allowsDuplicates would be set to false, @see BTree#create. To create a unique secondary * index set uniquenessColumns to 2, this means that the btree code will compare the key values * but not the row id when determing uniqueness. To create a nonunique secondary index set * uniquenessColumns to 3, this would mean that the uniqueness test would include the row location * and since all row locations will be unique all rows inserted into the index will be * differentiated (at least) by row location. * * @see BTree#create * @exception StandardException Standard exception policy. */ public void create( TransactionManager xact_manager, int segmentId, long input_conglomid, DataValueDescriptor[] template, ColumnOrdering[] columnOrder, int[] collationIds, Properties properties, int temporaryFlag) throws StandardException { String property_value = null; Transaction rawtran = xact_manager.getRawStoreXact(); if (properties == null) { throw (StandardException.newException( SQLState.BTREE_PROPERTY_NOT_FOUND, PROPERTY_BASECONGLOMID)); } // Get baseConglomerateId // property_value = properties.getProperty(PROPERTY_BASECONGLOMID); if (property_value == null) { throw (StandardException.newException( SQLState.BTREE_PROPERTY_NOT_FOUND, PROPERTY_BASECONGLOMID)); } if (SanityManager.DEBUG) { if (property_value == null) SanityManager.THROWASSERT(PROPERTY_BASECONGLOMID + "property not passed to B2I.create()"); } baseConglomerateId = Long.parseLong(property_value); // Get rowLocationColumn // property_value = properties.getProperty(PROPERTY_ROWLOCCOLUMN); if (SanityManager.DEBUG) { if (property_value == null) SanityManager.THROWASSERT(PROPERTY_ROWLOCCOLUMN + "property not passed to B2I.create()"); } if (property_value == null) { throw (StandardException.newException( SQLState.BTREE_PROPERTY_NOT_FOUND, PROPERTY_BASECONGLOMID)); } rowLocationColumn = Integer.parseInt(property_value); // Currently the row location column must be the last column (makes) // comparing the columns in the index easier. if (SanityManager.DEBUG) { SanityManager.ASSERT( rowLocationColumn == template.length - 1, "rowLocationColumn is not the last column in the index"); SanityManager.ASSERT(template[rowLocationColumn] instanceof RowLocation); // There must be at least one key column if (rowLocationColumn < 1) SanityManager.THROWASSERT( "rowLocationColumn (" + rowLocationColumn + ") expected to be >= 1"); } /* convert the sorting order information into a boolean array map. * If the sorting order for the columns is not provided, we * assign the default as Ascending Order. * array length is equal to template length, because column order * length changes whether it is unique or is non unique. store assumes * template length arrays. So, we make template length array and make * the last column as ascending instead of having lot of execeptions * code. */ ascDescInfo = new boolean[template.length]; for (int i = 0; i < ascDescInfo.length; i++) { if (columnOrder != null && i < columnOrder.length) ascDescInfo[i] = columnOrder[i].getIsAscending(); else ascDescInfo[i] = true; // default values - ascending order } // get collation ids from input collation ids, store it in the // conglom state. collation_ids = ConglomerateUtil.createCollationIds(template.length, collationIds); hasCollatedTypes = hasCollatedColumns(collation_ids); // Do the generic part of creating the b-tree. super.create( rawtran, segmentId, input_conglomid, template, properties, getTypeFormatId(), temporaryFlag); // open the base conglomerate - to get the lock ConglomerateController base_cc = xact_manager.openConglomerate( baseConglomerateId, false, TransactionController.OPENMODE_FOR_LOCK_ONLY, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE); OpenBTree open_btree = new OpenBTree(); BTreeLockingPolicy b2i_locking_policy = new B2ITableLocking3( rawtran, TransactionController.MODE_TABLE, rawtran.newLockingPolicy( LockingPolicy.MODE_CONTAINER, TransactionController.ISOLATION_SERIALIZABLE, true), base_cc, open_btree); // The following call will "open" the new btree. Create is // an interesting case. What we really want is read only table lock // on the base conglomerate and update locks on the index. For now // just get the update lock on the base table, this is done by the // lockTable() call made by base class. open_btree.init( (TransactionManager) xact_manager, // current user xact (TransactionManager) xact_manager, // current xact (ContainerHandle) null, // have init open the container. rawtran, false, (ContainerHandle.MODE_FORUPDATE), TransactionController.MODE_TABLE, b2i_locking_policy, // get table level lock. this, (LogicalUndo) null, // no logical undo necessary, as // initEmptyBtree() // work will be done single user and // rows will not move. (DynamicCompiledOpenConglomInfo) null); // Open the newly created container, and insert the first control row. LeafControlRow.initEmptyBtree(open_btree); open_btree.close(); base_cc.close(); }