Example #1
0
  @Test
  public void testProcedureBatching() throws Exception {
    ProcedureExecution exec = new FakeProcedureExecution(2, 1);

    // this has two result set columns and 1 out parameter
    int total_columns = 3;
    StoredProcedure command =
        (StoredProcedure) helpGetCommand("{call pm2.spTest8(?)}", EXAMPLE_BQT); // $NON-NLS-1$
    command.getInputParameters().get(0).setExpression(new Constant(1));
    Call proc = new LanguageBridgeFactory(EXAMPLE_BQT).translate(command);

    ProcedureBatchHandler pbh = new ProcedureBatchHandler(proc, exec);

    assertEquals(total_columns, pbh.padRow(Arrays.asList(null, null)).size());

    List params = pbh.getParameterRow();

    assertEquals(total_columns, params.size());
    // check the parameter value
    assertEquals(Integer.valueOf(0), params.get(2));

    try {
      pbh.padRow(Arrays.asList(1));
      fail("Expected exception from resultset mismatch"); // $NON-NLS-1$
    } catch (TranslatorException err) {
      assertEquals(
          "TEIID30479 Could not process stored procedure results for EXEC spTest8(1).  Expected 2 result set columns, but was 1.  Please update your models to allow for stored procedure results batching.",
          err.getMessage()); // $NON-NLS-1$
    }
  }
Example #2
0
  private TupleSource handleCachedProcedure(final CommandContext context, StoredProcedure proc)
      throws TeiidComponentException, QueryMetadataException, TeiidProcessingException {
    String fullName = context.getMetadata().getFullName(proc.getProcedureID());
    LogManager.logDetail(
        LogConstants.CTX_DQP, "processing cached procedure request for", fullName); // $NON-NLS-1$
    LinkedList<Object> vals = new LinkedList<Object>();
    for (SPParameter param : proc.getInputParameters()) {
      vals.add(((Constant) param.getExpression()).getValue());
    }
    // collapse the hash to single byte for the key to restrict the possible results to 256
    int hash = vals.hashCode();
    hash |= (hash >>> 16);
    hash |= (hash >>> 8);
    hash &= 0x000000ff;
    final CacheID cid =
        new CacheID(
            new ParseInfo(),
            fullName + hash,
            context.getVdbName(),
            context.getVdbVersion(),
            context.getConnectionId(),
            context.getUserName());
    cid.setParameters(vals);
    CachedResults results = cache.get(cid);
    if (results != null) {
      TupleBuffer buffer = results.getResults();
      return buffer.createIndexedTupleSource();
    }
    // construct a query with a no cache hint
    final CacheHint hint = proc.getCacheHint();
    proc.setCacheHint(null);
    Option option = new Option();
    option.setNoCache(true);
    option.addNoCacheGroup(fullName);
    proc.setOption(option);
    StoredProcedure cloneProc = (StoredProcedure) proc.clone();
    int i = 0;
    for (SPParameter param : cloneProc.getInputParameters()) {
      param.setExpression(new Reference(i++));
    }
    final QueryProcessor qp =
        context
            .getQueryProcessorFactory()
            .createQueryProcessor(
                cloneProc.toString(), fullName.toUpperCase(), context, vals.toArray());
    final BatchCollector bc = qp.createBatchCollector();

    return new ProxyTupleSource() {
      boolean success = false;

      @Override
      protected TupleSource createTupleSource()
          throws TeiidComponentException, TeiidProcessingException {
        TupleBuffer tb = bc.collectTuples();
        CachedResults cr = new CachedResults();
        cr.setResults(tb, qp.getProcessorPlan());
        Determinism determinismLevel = qp.getContext().getDeterminismLevel();
        if (hint != null && hint.getDeterminism() != null) {
          LogManager.logTrace(
              LogConstants.CTX_DQP,
              new Object[] {
                "Cache hint modified the query determinism from ",
                determinismLevel,
                " to ",
                hint.getDeterminism()
              }); //$NON-NLS-1$ //$NON-NLS-2$
          determinismLevel = hint.getDeterminism();
        }
        cache.put(cid, determinismLevel, cr, hint != null ? hint.getTtl() : null);
        context.setDeterminismLevel(determinismLevel);
        success = true;
        return tb.createIndexedTupleSource();
      }

      @Override
      public void closeSource() {
        super.closeSource();
        qp.closeProcessing();
        if (!success && bc.getTupleBuffer() != null) {
          bc.getTupleBuffer().remove();
        }
      }
    };
  }