예제 #1
0
  /**
   * Insert the given row into the given conglomerate and check for duplicate key error.
   *
   * @param row The row to insert
   * @exception StandardException Thrown on duplicate key error
   */
  private void insertAndCheckDups(ExecIndexRow row) throws StandardException {
    openIndexCC();

    int insertStatus = indexCC.insert(row.getRowArray());

    if (insertStatus == ConglomerateController.ROWISDUPLICATE) {
      /*
       ** We have a duplicate key error.
       */
      String indexOrConstraintName = indexName;
      // now get table name, and constraint name if needed
      LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
      DataDictionary dd = lcc.getDataDictionary();
      // get the descriptors
      ConglomerateDescriptor cd = dd.getConglomerateDescriptor(indexCID);

      UUID tableID = cd.getTableID();
      TableDescriptor td = dd.getTableDescriptor(tableID);
      String tableName = td.getName();

      if (indexOrConstraintName == null) // no index name passed in
      {
        ConstraintDescriptor conDesc = dd.getConstraintDescriptor(td, cd.getUUID());
        indexOrConstraintName = conDesc.getConstraintName();
      }

      throw StandardException.newException(
          SQLState.LANG_DUPLICATE_KEY_CONSTRAINT, indexOrConstraintName, tableName);
    }
    if (SanityManager.DEBUG) {
      if (insertStatus != 0) {
        SanityManager.THROWASSERT("Unknown insert status " + insertStatus);
      }
    }
  }
예제 #2
0
 /** Close our index Conglomerate Controller */
 private void closeIndexCC() throws StandardException {
   if (indexCC != null) indexCC.close();
   indexCC = null;
 }
예제 #3
0
  /**
   * Position our index scan to 'ourIndexRow'.
   *
   * <p>This creates the scan the first time it is called.
   *
   * @exception StandardException Thrown on error
   */
  private void setScan() throws StandardException {
    /*
     * -sf- Derby makes an assumption about system tables that isn't true
     * for Splice land, which results in WriteConflicts occurring
     * when you try to drop tables
     *
     * With indices, Derby only ever creates start and stop keys for the scan.
     * However, if the entire index is to be scanned, one or more column in the start/stop
     * key may be null. With db this was apparently treated acceptably, but in Splice
     * this results in garbage start and stop row keys, which in turn results in deleting
     * every row in the index instead of deleting just the rows of interest.
     *
     * Thus, the following hack. When the row is not entirely filled, we convert
     * the start/stop key into a single ANDed equals qualifier[], and use that instead
     */
    DataValueDescriptor[] ourRowDvds = ourIndexRow.getRowArray();
    int numNonNull = ourRowDvds.length;
    for (int i = 0; i < ourRowDvds.length; i++) {
      if (ourRowDvds[i].isNull()) {
        numNonNull--;
      }
    }
    Qualifier[][] qualifiers = null;
    if (numNonNull < ourRowDvds.length) {
      qualifiers = new Qualifier[1][];
      qualifiers[0] = new Qualifier[numNonNull];
      for (int dvdPos = 0, qualPos = 0; dvdPos < ourRowDvds.length; dvdPos++) {
        if (ourRowDvds[dvdPos].isNull()) continue;

        ScanQualifier qualifier = new GenericScanQualifier();
        qualifier.setQualifier(
            dvdPos, ourRowDvds[dvdPos], DataValueDescriptor.ORDER_OP_EQUALS, false, false, false);
        qualifiers[0][qualPos] = qualifier;
      }
    }
    /* Get the SC from the activation if re-using */
    if (!ownIndexSC) {
      indexSC = activation.getIndexScanController();
    } else if (indexSC == null) {
      RowLocation templateBaseRowLocation = baseCC.newRowLocationTemplate();
      /* DataDictionary doesn't have compiled info */
      if (indexSCOCI == null) {
        indexSC =
            tc.openScan(
                indexCID,
                false, /* hold */
                TransactionController.OPENMODE_FORUPDATE, /* forUpdate */
                lockMode,
                isolationLevel,
                (FormatableBitSet) null, /* all fields */
                ourIndexRow.getRowArray(), /* startKeyValue */
                ScanController.GE, /* startSearchOp */
                qualifiers, /* qualifier */
                ourIndexRow.getRowArray(), /* stopKeyValue */
                ScanController.GT /* stopSearchOp */);
      } else {
        indexSC =
            tc.openCompiledScan(
                false, /* hold */
                TransactionController.OPENMODE_FORUPDATE, /* forUpdate */
                lockMode,
                isolationLevel,
                (FormatableBitSet) null, /* all fields */
                ourIndexRow.getRowArray(), /* startKeyValue */
                ScanController.GE, /* startSearchOp */
                qualifiers, /* qualifier */
                ourIndexRow.getRowArray(), /* stopKeyValue */
                ScanController.GT, /* stopSearchOp */
                indexSCOCI,
                indexDCOCI);
      }
    } else {
      indexSC.reopenScan(
          ourIndexRow.getRowArray(), /* startKeyValue */
          ScanController.GE, /* startSearchOperator */
          qualifiers, /* qualifier */
          ourIndexRow.getRowArray(), /* stopKeyValue */
          ScanController.GT /* stopSearchOperator */);
    }
  }