Esempio n. 1
0
  public boolean iterateCursor(String rsName)
      throws TeiidComponentException, TeiidProcessingException {

    CursorState state = getCursorState(rsName);

    state.currentRow = state.ts.nextTuple();
    return (state.currentRow != null);
  }
Esempio n. 2
0
  /** Update the cursors that were pointing to head after a rotation of the head log file. */
  private void updateOpenedCursorsOnHeadAfterRotation(
      List<Pair<AbortableLogCursor<K, V>, CursorState<K, V>>> cursors) throws ChangelogException {
    for (Pair<AbortableLogCursor<K, V>, CursorState<K, V>> pair : cursors) {
      final CursorState<K, V> cursorState = pair.getSecond();

      // Need to update the cursor only if it is pointing to the head log file
      if (cursorState.isValid() && isHeadLogFile(cursorState.logFile)) {
        final K previousKey = logFiles.lowerKey(recordParser.getMaxKey());
        final LogFile<K, V> logFile = findLogFileFor(previousKey);
        final AbortableLogCursor<K, V> cursor = pair.getFirst();
        cursor.reinitializeTo(
            new CursorState<K, V>(logFile, cursorState.filePosition, cursorState.record));
      }
    }
  }
Esempio n. 3
0
  /**
   * @param command
   * @param rsName
   * @param procAssignments
   * @param mode
   * @param usesLocalTemp - only matters in HOLD mode
   * @throws TeiidComponentException
   * @throws TeiidProcessingException
   */
  public void executePlan(
      ProcessorPlan command,
      String rsName,
      Map<ElementSymbol, ElementSymbol> procAssignments,
      CreateCursorResultSetInstruction.Mode mode,
      boolean usesLocalTemp)
      throws TeiidComponentException, TeiidProcessingException {

    CursorState state = (CursorState) this.cursorStates.getValue(rsName);
    if (state == null || rsName == null) {
      if (this.currentState != null && this.currentState.processor.getProcessorPlan() != command) {
        // sanity check for non-deterministic paths
        removeState(this.currentState);
        this.currentState = null;
      }
      if (this.currentState == null) {
        // this may not be the first time the plan is being run
        command.reset();

        CommandContext subContext = getContext().clone();
        subContext.setVariableContext(this.currentVarContext);
        state = new CursorState();
        state.usesLocalTemp = usesLocalTemp;
        state.processor = new QueryProcessor(command, subContext, this.bufferMgr, this);
        state.ts = new BatchIterator(state.processor);
        if (mode == Mode.HOLD
            && procAssignments != null
            && state.processor.getOutputElements().size() - procAssignments.size() > 0) {
          state.resultsBuffer =
              bufferMgr.createTupleBuffer(
                  state
                      .processor
                      .getOutputElements()
                      .subList(
                          0, state.processor.getOutputElements().size() - procAssignments.size()),
                  getContext().getConnectionId(),
                  TupleSourceType.PROCESSOR);
        } else if ((this.blockContext != null || this.programs.peek().isTrappingExceptions())
            && (mode == Mode.HOLD || rsName != null)) {
          state.resultsBuffer =
              bufferMgr.createTupleBuffer(
                  state.processor.getOutputElements(),
                  getContext().getConnectionId(),
                  TupleSourceType.PROCESSOR);
        }
        this.currentState = state;
      }
      // force execution to the first batch to ensure that the plan is executed in the context of
      // the procedure
      this.currentState.ts.hasNext();
      if (procAssignments != null) {
        // proc assignments force us to scroll through the entire results and save as we go
        while (this.currentState.ts.hasNext()) {
          if (this.currentState.currentRow != null && this.currentState.resultsBuffer != null) {
            this.currentState.resultsBuffer.addTuple(
                this.currentState.currentRow.subList(
                    0, this.currentState.resultsBuffer.getSchema().size()));
            this.currentState.currentRow = null;
          }
          this.currentState.currentRow = this.currentState.ts.nextTuple();
        }
        // process assignments
        Assertion.assertTrue(this.currentState.currentRow != null);
        for (Map.Entry<ElementSymbol, ElementSymbol> entry : procAssignments.entrySet()) {
          if (entry.getValue() == null
              || !metadata.elementSupports(
                  entry.getValue().getMetadataID(), SupportConstants.Element.UPDATE)) {
            continue;
          }
          int index = this.currentState.processor.getOutputElements().indexOf(entry.getKey());
          getCurrentVariableContext()
              .setValue(
                  entry.getValue(),
                  DataTypeManager.transformValue(
                      this.currentState.currentRow.get(index), entry.getValue().getType()));
        }
      } else if (this.currentState.resultsBuffer != null) {
        // result should be saved, typically to respect txn semantics
        while (this.currentState.ts.hasNext()) {
          List<?> tuple = this.currentState.ts.nextTuple();
          this.currentState.resultsBuffer.addTuple(tuple);
        }
        getCurrentVariableContext().setValue(ProcedurePlan.ROWCOUNT, 0);
      } else if (mode == Mode.UPDATE) {
        List<?> t = this.currentState.ts.nextTuple();
        if (this.currentState.ts.hasNext()) {
          throw new AssertionError(
              "Invalid update count result - more than 1 row returned"); //$NON-NLS-1$
        }
        removeState(this.currentState);
        this.currentState = null;
        int rowCount = 0;
        if (t != null) {
          rowCount = (Integer) t.get(0);
        }
        getCurrentVariableContext().setValue(ProcedurePlan.ROWCOUNT, rowCount);
        return;
      }
      if (rsName == null && mode == Mode.NOHOLD) {
        // unnamed without hold
        // process fully, but don't save
        // TODO: could set the rowcount in this case
        while (this.currentState.ts.hasNext()) {
          this.currentState.ts.nextTuple();
        }
        this.currentState = null;
        getCurrentVariableContext().setValue(ProcedurePlan.ROWCOUNT, 0);
        return;
      }
      if (this.currentState.resultsBuffer != null) {
        // close the results buffer and use a buffer backed tuplesource
        this.currentState.resultsBuffer.close();
        this.currentState.ts = this.currentState.resultsBuffer.createIndexedTupleSource(true);
      }
      CursorState old = (CursorState) this.cursorStates.setValue(rsName, this.currentState);
      if (old != null) {
        removeState(old);
      }
      this.currentState = null;
    }
  }
Esempio n. 4
0
  /**
   * Process the procedure, using the stack of Programs supplied by the ProcessorEnvironment. With
   * each pass through the loop, the current Program is gotten off the top of the stack, and the
   * current instruction is gotten from that program; each call to an instruction's process method
   * may alter the Program Stack and/or the current instruction pointer of a Program, so it's
   * important that this method's loop refer to the call stack of the ProcessorEnvironment each
   * time, and not cache things in local variables. If the current Program's current instruction is
   * null, then it's time to pop that Program off the stack.
   *
   * @return List a single tuple containing one Integer: the update count resulting from the
   *     procedure execution.
   */
  private TupleSource processProcedure()
      throws TeiidComponentException, TeiidProcessingException, BlockedException {

    // execute plan
    ProgramInstruction inst = null;

    while (!this.programs.empty()) {
      Program program = peek();
      inst = program.getCurrentInstruction();
      if (inst == null) {
        LogManager.logTrace(
            org.teiid.logging.LogConstants.CTX_DQP, "Finished program", program); // $NON-NLS-1$
        // look ahead to see if we need to process in place
        VariableContext vc = this.cursorStates.getParentContext();
        CursorState last = (CursorState) this.cursorStates.getValue(null);
        if (last != null) {
          if (last.resultsBuffer == null && (last.usesLocalTemp || !txnTupleSources.isEmpty())) {
            last.resultsBuffer =
                bufferMgr.createTupleBuffer(
                    last.processor.getOutputElements(),
                    getContext().getConnectionId(),
                    TupleSourceType.PROCESSOR);
            last.returning = true;
          }
          if (last.returning) {
            while (last.ts.hasNext()) {
              List<?> tuple = last.ts.nextTuple();
              last.resultsBuffer.addTuple(tuple);
            }
            last.resultsBuffer.close();
            last.ts = last.resultsBuffer.createIndexedTupleSource(true);
            last.returning = false;
          }
        }
        this.pop(true);
        continue;
      }
      try {
        if (inst instanceof RepeatedInstruction) {
          LogManager.logTrace(
              org.teiid.logging.LogConstants.CTX_DQP,
              "Executing repeated instruction",
              inst); //$NON-NLS-1$
          RepeatedInstruction loop = (RepeatedInstruction) inst;
          if (loop.testCondition(this)) {
            LogManager.logTrace(
                org.teiid.logging.LogConstants.CTX_DQP,
                "Passed condition, executing program " + loop.getNestedProgram()); // $NON-NLS-1$
            inst.process(this);
            this.push(loop.getNestedProgram());
            continue;
          }
          LogManager.logTrace(
              org.teiid.logging.LogConstants.CTX_DQP,
              "Exiting repeated instruction",
              inst); //$NON-NLS-1$
          loop.postInstruction(this);
        } else {
          LogManager.logTrace(
              org.teiid.logging.LogConstants.CTX_DQP, "Executing instruction", inst); // $NON-NLS-1$
          inst.process(this);
          this.evaluator.close();
        }
      } catch (RuntimeException e) {
        throw e;
      } catch (TeiidComponentException e) {
        throw e;
      } catch (Exception e) {
        // processing or teiidsqlexception
        boolean atomic = program.isAtomic();
        while (program.getExceptionGroup() == null) {
          this.pop(false);
          if (this.programs.empty()) {
            // reached the top without a handler, so throw
            if (e instanceof TeiidProcessingException) {
              throw (TeiidProcessingException) e;
            }
            throw new ProcedureErrorInstructionException(QueryPlugin.Event.TEIID30167, e);
          }
          program = peek();
          atomic |= program.isAtomic();
        }
        this.pop(false); // allow the current program to go out of scope
        if (atomic) {
          TransactionContext tc = this.getContext().getTransactionContext();
          if (tc != null && tc.getTransactionType() != Scope.NONE) {
            // a non-completing atomic block under a higher level transaction

            // this will not work correctly until we support
            // checkpoints/subtransactions
            try {
              tc.getTransaction().setRollbackOnly();
            } catch (IllegalStateException e1) {
              throw new TeiidComponentException(e1);
            } catch (SystemException e1) {
              throw new TeiidComponentException(e1);
            }
          }
        }
        if (program.getExceptionProgram() == null) {
          continue;
        }
        Program exceptionProgram = program.getExceptionProgram();
        this.push(exceptionProgram);
        TeiidSQLException tse = TeiidSQLException.create(e);
        GroupSymbol gs = new GroupSymbol(program.getExceptionGroup());
        this.currentVarContext.setValue(exceptionSymbol(gs, 0), tse.getSQLState());
        this.currentVarContext.setValue(exceptionSymbol(gs, 1), tse.getErrorCode());
        this.currentVarContext.setValue(exceptionSymbol(gs, 2), tse.getTeiidCode());
        this.currentVarContext.setValue(exceptionSymbol(gs, 3), tse);
        this.currentVarContext.setValue(exceptionSymbol(gs, 4), tse.getCause());
        continue;
      }
      program.incrementProgramCounter();
    }
    CursorState last = (CursorState) this.cursorStates.getValue(null);
    if (last == null) {
      return CollectionTupleSource.createNullTupleSource();
    }
    return last.ts;
  }