Example #1
0
 /**
  * Store the stored representation of the column value in the stream.
  *
  * <p>For more detailed description of the ACCESS_B2I_V3_ID and ACCESS_B2I_V4_ID formats see
  * documentation at top of file.
  *
  * @see java.io.Externalizable#writeExternal
  */
 public void writeExternal_v10_3(ObjectOutput out) throws IOException {
   // First part of ACCESS_B2I_V4_ID format is the ACCESS_B2I_V3_ID format.
   writeExternal_v10_2(out);
   if (conglom_format_id == StoredFormatIds.ACCESS_B2I_V4_ID
       || conglom_format_id == StoredFormatIds.ACCESS_B2I_V5_ID) {
     // Now append sparse array of collation ids
     ConglomerateUtil.writeCollationIdArray(collation_ids, out);
   }
 }
Example #2
0
  /**
   * Restore the in-memory representation from the stream.
   *
   * <p>
   *
   * @exception ClassNotFoundException Thrown if the stored representation is serialized and a class
   *     named in the stream could not be found.
   * @see java.io.Externalizable#readExternal
   */
  private final void localReadExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    super.readExternal(in);
    baseConglomerateId = in.readLong();
    rowLocationColumn = in.readInt();

    // read the column sort order info
    FormatableBitSet ascDescBits = new FormatableBitSet();
    ascDescBits.readExternal(in);
    ascDescInfo = new boolean[ascDescBits.getLength()];
    for (int i = 0; i < ascDescBits.getLength(); i++) ascDescInfo[i] = ascDescBits.isSet(i);

    // In memory maintain a collation id per column in the template.
    collation_ids = new int[format_ids.length];
    if (SanityManager.DEBUG) {
      SanityManager.ASSERT(!hasCollatedTypes);
    }

    // initialize all the entries to COLLATION_TYPE_UCS_BASIC,
    // and then reset as necessary.  For version ACCESS_B2I_V3_ID,
    // this is the default and no resetting is necessary.
    for (int i = 0; i < format_ids.length; i++)
      collation_ids[i] = StringDataValue.COLLATION_TYPE_UCS_BASIC;

    // initialize the unique with null setting to false, to be reset
    // below when read from disk.  For version ACCESS_B2I_V3_ID and
    // ACCESS_B2I_V4_ID, this is the default and no resetting is necessary.
    setUniqueWithDuplicateNulls(false);

    if (conglom_format_id == StoredFormatIds.ACCESS_B2I_V4_ID
        || conglom_format_id == StoredFormatIds.ACCESS_B2I_V5_ID) {
      // current format id, read collation info from disk
      if (SanityManager.DEBUG) {
        // length must include row location column and at least
        // one other field.
        SanityManager.ASSERT(collation_ids.length >= 2, "length = " + collation_ids.length);
      }

      hasCollatedTypes = ConglomerateUtil.readCollationIdArray(collation_ids, in);
    } else if (conglom_format_id != StoredFormatIds.ACCESS_B2I_V3_ID) {
      // Currently only V3, V4 and V5 should be possible in a Derby DB.
      // Actual work for V3 is handled by default code above, so no
      // special work is necessary.

      if (SanityManager.DEBUG) {
        SanityManager.THROWASSERT("Unexpected format id: " + conglom_format_id);
      }
    }
    if (conglom_format_id == StoredFormatIds.ACCESS_B2I_V5_ID) {
      setUniqueWithDuplicateNulls(in.readBoolean());
    }
  }
Example #3
0
  /**
   * 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();
  }