/**
   * 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 */);
    }
  }