private TempMetadataStore resolveEmbeddedCommand(
      TempMetadataAdapter metadata, GroupContext groupContext, Command cmd)
      throws TeiidComponentException, QueryResolverException {
    QueryResolver.setChildMetadata(cmd, metadata.getMetadataStore(), groupContext);

    return QueryResolver.resolveCommand(cmd, metadata.getMetadata());
  }
Example #2
0
 public QueryMetadataInterface getSessionMetadata() {
   if (isSession()) {
     TempMetadataAdapter tma = new TempMetadataAdapter(new BasicQueryMetadata(), this.tempStore);
     tma.session = true;
     return tma;
   }
   return this.actualMetadata.getSessionMetadata();
 }
  public void resolveBlock(
      CreateProcedureCommand command,
      Block block,
      GroupContext originalExternalGroups,
      TempMetadataAdapter original)
      throws QueryResolverException, QueryMetadataException, TeiidComponentException {
    LogManager.logTrace(
        org.teiid.logging.LogConstants.CTX_QUERY_RESOLVER,
        new Object[] {"Resolving block", block}); // $NON-NLS-1$

    // create a new variable and metadata context for this block so that discovered metadata is not
    // visible else where
    TempMetadataStore store = original.getMetadataStore().clone();
    TempMetadataAdapter metadata = new TempMetadataAdapter(original.getMetadata(), store);
    GroupContext externalGroups = new GroupContext(originalExternalGroups, null);

    // create a new variables group for this block
    GroupSymbol variables =
        ProcedureContainerResolver.addScalarGroup(
            ProcedureReservedWords.VARIABLES, store, externalGroups, new LinkedList<Expression>());

    for (Statement statement : block.getStatements()) {
      resolveStatement(command, statement, externalGroups, variables, metadata);
    }

    if (block.getExceptionGroup() != null) {
      // create a new variable and metadata context for this block so that discovered metadata is
      // not visible else where
      store = original.getMetadataStore().clone();
      metadata = new TempMetadataAdapter(original.getMetadata(), store);
      externalGroups = new GroupContext(originalExternalGroups, null);

      // create a new variables group for this block
      variables =
          ProcedureContainerResolver.addScalarGroup(
              ProcedureReservedWords.VARIABLES,
              store,
              externalGroups,
              new LinkedList<Expression>());
      isValidGroup(metadata, block.getExceptionGroup());

      if (block.getExceptionStatements() != null) {
        ProcedureContainerResolver.addScalarGroup(
            block.getExceptionGroup(), store, externalGroups, exceptionGroup, false);
        for (Statement statement : block.getExceptionStatements()) {
          resolveStatement(command, statement, externalGroups, variables, metadata);
        }
      }
    }
  }
  /**
   * @see org.teiid.query.resolver.CommandResolver#resolveCommand(org.teiid.query.sql.lang.Command,
   *     TempMetadataAdapter, boolean)
   */
  public void resolveCommand(
      Command command, TempMetadataAdapter metadata, boolean resolveNullLiterals)
      throws QueryMetadataException, QueryResolverException, TeiidComponentException {

    // by creating a new group context here it means that variables will resolve with a higher
    // precedence than input/changing
    GroupContext externalGroups = command.getExternalGroupContexts();

    List<ElementSymbol> symbols = new LinkedList<ElementSymbol>();

    String countVar =
        ProcedureReservedWords.VARIABLES + Symbol.SEPARATOR + ProcedureReservedWords.ROWCOUNT;
    ElementSymbol updateCount = new ElementSymbol(countVar);
    updateCount.setType(DataTypeManager.DefaultDataClasses.INTEGER);
    symbols.add(updateCount);

    ProcedureContainerResolver.addScalarGroup(
        ProcedureReservedWords.VARIABLES, metadata.getMetadataStore(), externalGroups, symbols);

    if (command instanceof TriggerAction) {
      TriggerAction ta = (TriggerAction) command;
      CreateProcedureCommand cmd = new CreateProcedureCommand(ta.getBlock());
      cmd.setVirtualGroup(ta.getView());
      // TODO: this is not generally correct - we should update the api to set the appropriate type
      cmd.setUpdateType(Command.TYPE_INSERT);
      resolveBlock(cmd, ta.getBlock(), ta.getExternalGroupContexts(), metadata);
      return;
    }

    CreateProcedureCommand procCommand = (CreateProcedureCommand) command;

    resolveBlock(procCommand, procCommand.getBlock(), externalGroups, metadata);
  }
  private boolean isAssignable(TempMetadataAdapter metadata, SPParameter param)
      throws TeiidComponentException, QueryMetadataException {
    if (!(param.getExpression() instanceof ElementSymbol)) {
      return false;
    }
    ElementSymbol symbol = (ElementSymbol) param.getExpression();

    return metadata.elementSupports(symbol.getMetadataID(), SupportConstants.Element.UPDATE);
  }
 private void collectDeclareVariable(
     DeclareStatement obj,
     GroupSymbol variables,
     TempMetadataAdapter metadata,
     GroupContext externalGroups)
     throws QueryResolverException, TeiidComponentException {
   ElementSymbol variable = obj.getVariable();
   String typeName = obj.getVariableType();
   GroupSymbol gs = variable.getGroupSymbol();
   if (gs == null) {
     String outputName = variable.getShortName();
     variable.setGroupSymbol(new GroupSymbol(ProcedureReservedWords.VARIABLES));
     variable.setOutputName(outputName);
   } else {
     if (gs.getSchema() != null
         || !gs.getShortName().equalsIgnoreCase(ProcedureReservedWords.VARIABLES)) {
       handleUnresolvableDeclaration(
           variable,
           QueryPlugin.Util.getString(
               "ERR.015.010.0031",
               new Object[] {ProcedureReservedWords.VARIABLES, variable})); // $NON-NLS-1$
     }
   }
   boolean exists = false;
   try {
     ResolverVisitor.resolveLanguageObject(variable, null, externalGroups, metadata);
     exists = true;
   } catch (QueryResolverException e) {
     // ignore, not already defined
   }
   if (exists) {
     handleUnresolvableDeclaration(
         variable,
         QueryPlugin.Util.getString("ERR.015.010.0032", variable.getOutputName())); // $NON-NLS-1$
   }
   variable.setType(DataTypeManager.getDataTypeClass(typeName));
   variable.setGroupSymbol(variables);
   TempMetadataID id =
       new TempMetadataID(
           variable.getName(),
           typeName.equalsIgnoreCase(SQLConstants.NonReserved.EXCEPTION)
               ? Exception.class
               : variable.getType());
   id.setUpdatable(true);
   variable.setMetadataID(id);
   // TODO: this will cause the variables group to loose it's cache of resolved symbols
   metadata
       .getMetadataStore()
       .addElementToTempGroup(ProcedureReservedWords.VARIABLES, variable.clone());
 }
  private void isValidGroup(TempMetadataAdapter metadata, String groupName)
      throws QueryResolverException {
    if (metadata.getMetadataStore().getTempGroupID(groupName) != null) {
      throw new QueryResolverException(
          QueryPlugin.Event.TEIID30124,
          QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30124, groupName));
    }

    // check - cursor name should not start with #
    if (GroupSymbol.isTempGroupName(groupName)) {
      throw new QueryResolverException(
          QueryPlugin.Event.TEIID30125,
          QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30125, groupName));
    }
  }
Example #8
0
 @Override
 public void resolveCommand(
     Command command, TempMetadataAdapter metadata, boolean resolveNullLiterals)
     throws QueryMetadataException, QueryResolverException, TeiidComponentException {
   Alter<? extends Command> alter = (Alter<? extends Command>) command;
   ResolverUtil.resolveGroup(alter.getTarget(), metadata);
   int type = Command.TYPE_QUERY;
   boolean viewTarget = true;
   if (alter instanceof AlterTrigger) {
     TriggerEvent event = ((AlterTrigger) alter).getEvent();
     switch (event) {
       case DELETE:
         type = Command.TYPE_DELETE;
         break;
       case INSERT:
         type = Command.TYPE_INSERT;
         break;
       case UPDATE:
         type = Command.TYPE_UPDATE;
         break;
     }
     if (((AlterTrigger) alter).isAfter()) {
       viewTarget = false;
     }
   } else if (alter instanceof AlterProcedure) {
     type = Command.TYPE_STORED_PROCEDURE;
     viewTarget = false;
   }
   if (viewTarget && !QueryResolver.isView(alter.getTarget(), metadata)) {
     throw new QueryResolverException(
         QueryPlugin.Event.TEIID30116,
         QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30116, alter.getTarget()));
   }
   if (alter.getDefinition() != null) {
     QueryResolver.resolveCommand(
         alter.getDefinition(), alter.getTarget(), type, metadata.getDesignTimeMetadata(), false);
   }
 }
  private void resolveStatement(
      CreateProcedureCommand command,
      Statement statement,
      GroupContext externalGroups,
      GroupSymbol variables,
      TempMetadataAdapter metadata)
      throws QueryResolverException, QueryMetadataException, TeiidComponentException {
    LogManager.logTrace(
        org.teiid.logging.LogConstants.CTX_QUERY_RESOLVER,
        new Object[] {"Resolving statement", statement}); // $NON-NLS-1$

    switch (statement.getType()) {
      case Statement.TYPE_IF:
        IfStatement ifStmt = (IfStatement) statement;
        Criteria ifCrit = ifStmt.getCondition();
        for (SubqueryContainer container :
            ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(ifCrit)) {
          resolveEmbeddedCommand(metadata, externalGroups, container.getCommand());
        }
        ResolverVisitor.resolveLanguageObject(ifCrit, null, externalGroups, metadata);
        resolveBlock(command, ifStmt.getIfBlock(), externalGroups, metadata);
        if (ifStmt.hasElseBlock()) {
          resolveBlock(command, ifStmt.getElseBlock(), externalGroups, metadata);
        }
        break;
      case Statement.TYPE_COMMAND:
        CommandStatement cmdStmt = (CommandStatement) statement;
        Command subCommand = cmdStmt.getCommand();

        TempMetadataStore discoveredMetadata =
            resolveEmbeddedCommand(metadata, externalGroups, subCommand);

        if (subCommand instanceof StoredProcedure) {
          StoredProcedure sp = (StoredProcedure) subCommand;
          for (SPParameter param : sp.getParameters()) {
            switch (param.getParameterType()) {
              case ParameterInfo.OUT:
              case ParameterInfo.RETURN_VALUE:
                if (param.getExpression() != null && !isAssignable(metadata, param)) {
                  throw new QueryResolverException(
                      QueryPlugin.Event.TEIID30121,
                      QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30121, param.getExpression()));
                }
                sp.setCallableStatement(true);
                break;
              case ParameterInfo.INOUT:
                if (!isAssignable(metadata, param)) {
                  continue;
                }
                sp.setCallableStatement(true);
                break;
            }
          }
        }

        if (discoveredMetadata != null) {
          metadata.getMetadataStore().getData().putAll(discoveredMetadata.getData());
        }

        // dynamic commands need to be updated as to their implicitly expected projected symbols
        if (subCommand instanceof DynamicCommand) {
          DynamicCommand dynCommand = (DynamicCommand) subCommand;

          if (dynCommand.getIntoGroup() == null && !dynCommand.isAsClauseSet()) {
            if ((command.getResultSetColumns() != null && command.getResultSetColumns().isEmpty())
                || !cmdStmt.isReturnable()
                || command.getResultSetColumns() == null) {
              // we're not interested in the resultset
              dynCommand.setAsColumns(Collections.EMPTY_LIST);
            } else {
              // should match the procedure
              dynCommand.setAsColumns(command.getResultSetColumns());
            }
          }
        }

        if (command.getResultSetColumns() == null
            && cmdStmt.isReturnable()
            && subCommand.returnsResultSet()
            && subCommand.getResultSetColumns() != null
            && !subCommand.getResultSetColumns().isEmpty()) {
          command.setResultSetColumns(subCommand.getResultSetColumns());
          if (command.getProjectedSymbols().isEmpty()) {
            command.setProjectedSymbols(subCommand.getResultSetColumns());
          }
        }

        break;
      case Statement.TYPE_ERROR:
      case Statement.TYPE_ASSIGNMENT:
      case Statement.TYPE_DECLARE:
      case Statement.TYPE_RETURN:
        ExpressionStatement exprStmt = (ExpressionStatement) statement;
        // first resolve the value.  this ensures the value cannot use the variable being defined
        if (exprStmt.getExpression() != null) {
          Expression expr = exprStmt.getExpression();
          for (SubqueryContainer container :
              ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(expr)) {
            resolveEmbeddedCommand(metadata, externalGroups, container.getCommand());
          }
          ResolverVisitor.resolveLanguageObject(expr, null, externalGroups, metadata);
        }

        // second resolve the variable
        switch (statement.getType()) {
          case Statement.TYPE_DECLARE:
            collectDeclareVariable(
                (DeclareStatement) statement, variables, metadata, externalGroups);
            break;
          case Statement.TYPE_ASSIGNMENT:
            AssignmentStatement assStmt = (AssignmentStatement) statement;
            ResolverVisitor.resolveLanguageObject(
                assStmt.getVariable(), null, externalGroups, metadata);
            if (!metadata.elementSupports(
                assStmt.getVariable().getMetadataID(), SupportConstants.Element.UPDATE)) {
              throw new QueryResolverException(
                  QueryPlugin.Event.TEIID30121,
                  QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30121, assStmt.getVariable()));
            }
            // don't allow variable assignments to be external
            assStmt.getVariable().setIsExternalReference(false);
            break;
          case Statement.TYPE_RETURN:
            ReturnStatement rs = (ReturnStatement) statement;
            if (rs.getExpression() != null) {
              if (command.getReturnVariable() == null) {
                throw new QueryResolverException(
                    QueryPlugin.Event.TEIID31125,
                    QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31125, rs));
              }
              rs.setVariable(command.getReturnVariable().clone());
            }
            // else - we don't currently require the use of return for backwards compatibility
            break;
        }

        // third ensure the type matches
        if (exprStmt.getExpression() != null) {
          Class<?> varType = exprStmt.getExpectedType();
          Class<?> exprType = exprStmt.getExpression().getType();
          if (exprType == null) {
            throw new QueryResolverException(
                QueryPlugin.Event.TEIID30123, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30123));
          }
          String varTypeName = DataTypeManager.getDataTypeName(varType);
          exprStmt.setExpression(
              ResolverUtil.convertExpression(exprStmt.getExpression(), varTypeName, metadata));
          if (statement.getType() == Statement.TYPE_ERROR) {
            ResolverVisitor.checkException(exprStmt.getExpression());
          }
        }
        break;
      case Statement.TYPE_WHILE:
        WhileStatement whileStmt = (WhileStatement) statement;
        Criteria whileCrit = whileStmt.getCondition();
        for (SubqueryContainer container :
            ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(whileCrit)) {
          resolveEmbeddedCommand(metadata, externalGroups, container.getCommand());
        }
        ResolverVisitor.resolveLanguageObject(whileCrit, null, externalGroups, metadata);
        resolveBlock(command, whileStmt.getBlock(), externalGroups, metadata);
        break;
      case Statement.TYPE_LOOP:
        LoopStatement loopStmt = (LoopStatement) statement;
        String groupName = loopStmt.getCursorName();

        isValidGroup(metadata, groupName);
        Command cmd = loopStmt.getCommand();
        resolveEmbeddedCommand(metadata, externalGroups, cmd);
        List<Expression> symbols = cmd.getProjectedSymbols();

        // add the loop cursor group into its own context
        TempMetadataStore store = metadata.getMetadataStore().clone();
        metadata = new TempMetadataAdapter(metadata.getMetadata(), store);
        externalGroups = new GroupContext(externalGroups, null);

        ProcedureContainerResolver.addScalarGroup(groupName, store, externalGroups, symbols, false);

        resolveBlock(command, loopStmt.getBlock(), externalGroups, metadata);
        break;
      case Statement.TYPE_COMPOUND:
        resolveBlock(command, (Block) statement, externalGroups, metadata);
        break;
    }
  }