/**
   * This method parses the URL and adds properties to the the properties object. These include
   * required and any optional properties specified in the URL.
   *
   * @param The URL needed to be parsed.
   * @param The properties object which is to be updated with properties in the URL.
   * @throws SQLException if the URL is not in the expected format.
   */
  protected static void parseURL(String url, Properties info) throws SQLException {
    if (url == null) {
      String msg = Messages.getString(Messages.JDBC.urlFormat);
      throw new SQLException(msg);
    }
    try {
      JDBCURL jdbcURL = new JDBCURL(url);
      info.setProperty(TeiidURL.JDBC.VDB_NAME, jdbcURL.getVDBName());
      if (jdbcURL.getConnectionURL() != null) {
        info.setProperty(TeiidURL.CONNECTION.SERVER_URL, jdbcURL.getConnectionURL());
      }
      Properties optionalParams = jdbcURL.getProperties();
      JDBCURL.normalizeProperties(info);
      Enumeration<?> keys = optionalParams.keys();
      while (keys.hasMoreElements()) {
        String propName = (String) keys.nextElement();
        // Don't let the URL properties override the passed-in Properties object.
        if (!info.containsKey(propName)) {
          info.setProperty(propName, optionalParams.getProperty(propName));
        }
      }
      // add the property only if it is new because they could have
      // already been specified either through url or otherwise.
      if (!info.containsKey(TeiidURL.JDBC.VDB_VERSION) && jdbcURL.getVDBVersion() != null) {
        info.setProperty(TeiidURL.JDBC.VDB_VERSION, jdbcURL.getVDBVersion());
      }
      if (!info.containsKey(TeiidURL.CONNECTION.APP_NAME)) {
        info.setProperty(TeiidURL.CONNECTION.APP_NAME, TeiidURL.CONNECTION.DEFAULT_APP_NAME);
      }

    } catch (IllegalArgumentException iae) {
      throw new SQLException(Messages.getString(Messages.JDBC.urlFormat));
    }
  }
 static final <T> T transform(
     TeiidVersion teiidVersion, Object value, Class<T> targetType, Class<?> runtimeType)
     throws SQLException {
   if (value == null || targetType.isAssignableFrom(value.getClass())) {
     return targetType.cast(value);
   }
   if (targetType == byte[].class) {
     if (value instanceof Blob) {
       Blob blob = (Blob) value;
       long length = blob.length();
       if (length > Integer.MAX_VALUE) {
         throw new SQLException(
             Messages.getString(Messages.JDBC.DataTypeTransformer_blob_too_big));
       }
       return targetType.cast(blob.getBytes(1, (int) length));
     } else if (value instanceof String) {
       return targetType.cast(((String) value).getBytes());
     } else if (value instanceof BinaryTypeImpl) {
       return targetType.cast(((BinaryTypeImpl) value).getBytesDirect());
     }
   } else if (targetType == String.class) {
     if (value instanceof SQLXML) {
       return targetType.cast(((SQLXML) value).getString());
     } else if (value instanceof Clob) {
       Clob c = (Clob) value;
       long length = c.length();
       if (length == 0) {
         // there is a bug in SerialClob with 0 length
         return targetType.cast(""); // $NON-NLS-1$
       }
       return targetType.cast(
           c.getSubString(1, length > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) length));
     }
   }
   try {
     DefaultDataTypeManager dataTypeManager = getDataTypeManager(teiidVersion);
     return (T)
         dataTypeManager.transformValue(
             dataTypeManager.convertToRuntimeType(value, true), runtimeType);
   } catch (Exception e) {
     String valueStr = value.toString();
     if (valueStr.length() > 20) {
       valueStr = valueStr.substring(0, 20) + "..."; // $NON-NLS-1$
     }
     String msg =
         Messages.getString(
             Messages.JDBC.DataTypeTransformer_Err_converting,
             valueStr,
             targetType.getSimpleName());
     throw new SQLException(msg, e);
   }
 }
 /**
  * This method transforms a value of the source type into a value of the target type.
  *
  * @param value Incoming value of source type
  * @return Outgoing value of target type
  * @throws Exception if value is an incorrect input type or the transformation fails
  */
 public Object transformDirect(Object value) throws Exception {
   try {
     return Byte.valueOf(((String) value).trim());
   } catch (NumberFormatException e) {
     throw new TeiidClientException(Messages.gs(Messages.TEIID.TEIID10074, value));
   }
 }
  @Override
  public ConnectionImpl connect(String url, Properties info) throws SQLException {
    ConnectionType conn = JDBCURL.acceptsUrl(url);
    if (conn == null) {
      return null;
    }
    if (info == null) {
      // create a properties obj if it is null
      info = new Properties();
    } else {
      // don't modify the original
      info = PropertiesUtils.clone(info);
    }
    parseURL(url, info);

    ConnectionImpl myConnection = null;

    /*
     * Add the teiid server version to the properties
     */
    info.setProperty(ITeiidServerVersion.TEIID_VERSION_PROPERTY, getTeiidVersion().toString());

    try {
      myConnection = socketProfile.connect(url, info);
    } catch (SQLException e) {
      logger.log(Level.SEVERE, "Could not create connection", e); // $NON-NLS-1$
      throw e;
    }

    // logging
    String logMsg = Messages.getString(Messages.JDBC.Connection_success);
    logger.fine(logMsg);

    return myConnection;
  }
    @Override
    public void execute(
        VDBMetaData vdb,
        MetadataStore store,
        ValidatorReport report,
        MetadataValidator metadataValidator) {
      for (Schema schema : store.getSchemaList()) {
        if (vdb.getImportedModels().contains(schema.getName())) {
          continue;
        }
        ModelMetaData model = vdb.getModel(schema.getName());

        if (schema.getTables().isEmpty()
            && schema.getProcedures().isEmpty()
            && schema.getFunctions().isEmpty()) {
          metadataValidator.log(
              report, model, Messages.gs(Messages.TEIID.TEIID31070, model.getName()));
        }

        for (Table t : schema.getTables().values()) {
          if (t.getColumns() == null || t.getColumns().size() == 0) {
            metadataValidator.log(
                report, model, Messages.gs(Messages.TEIID.TEIID31071, t.getFullName()));
          }
          Set<String> names = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
          validateConstraintNames(metadataValidator, report, model, t.getAllKeys(), names);
          validateConstraintNames(
              metadataValidator, report, model, t.getFunctionBasedIndexes(), names);
        }

        // procedure validation is handled in parsing routines.

        if (!schema.getFunctions().isEmpty()) {
          ActivityReport<ReportItem> funcReport =
              new ActivityReport<ReportItem>(
                  "Translator metadata load " + model.getName()); // $NON-NLS-1$
          FunctionMetadataValidator.validateFunctionMethods(
              teiidVersion, schema.getFunctions().values(), report);
          if (report.hasItems()) {
            metadataValidator.log(
                report, model, Messages.gs(Messages.TEIID.TEIID31073, funcReport));
          }
        }
      }
    }
  /**
   * @see org.teiid.query.resolver.CommandResolver#resolveCommand(org.teiid.query.sql.lang.Command,
   *     TempMetadataAdapter, boolean)
   */
  @Override
  public void resolveCommand(
      Command command, TempMetadataAdapter metadata, boolean resolveNullLiterals) throws Exception {

    DynamicCommand dynamicCmd = (DynamicCommand) command;

    Iterator columns = dynamicCmd.getAsColumns().iterator();

    Set<GroupSymbol> groups = new HashSet<GroupSymbol>();

    // if there is no into group, just create temp metadata ids
    if (dynamicCmd.getIntoGroup() == null) {
      while (columns.hasNext()) {
        ElementSymbol column = (ElementSymbol) columns.next();
        column.setMetadataID(new TempMetadataID(column.getShortName(), column.getType()));
      }
    } else if (dynamicCmd.getIntoGroup().isTempGroupSymbol()) {
      while (columns.hasNext()) {
        ElementSymbol column = (ElementSymbol) columns.next();
        GroupSymbol gs = getTeiidParser().createASTNode(ASTNodes.GROUP_SYMBOL);
        gs.setName(dynamicCmd.getIntoGroup().getName());
        column.setGroupSymbol(gs);
      }
    }

    ResolverVisitor visitor = new ResolverVisitor(getTeiidParser().getVersion());
    visitor.resolveLanguageObject(
        dynamicCmd, groups, dynamicCmd.getExternalGroupContexts(), metadata);
    String sqlType = getDataTypeManager().getDataTypeName(dynamicCmd.getSql().getType());
    String targetType = DataTypeManagerService.DefaultDataTypes.STRING.getId();

    if (!targetType.equals(sqlType)
        && !getDataTypeManager().isImplicitConversion(sqlType, targetType)) {
      throw new QueryResolverException(Messages.gs(Messages.TEIID.TEIID30100, sqlType));
    }

    if (dynamicCmd.getUsing() != null && !dynamicCmd.getUsing().isEmpty()) {
      for (SetClause clause : dynamicCmd.getUsing().getClauses()) {
        ElementSymbol id = clause.getSymbol();
        GroupSymbol gs = getTeiidParser().createASTNode(ASTNodes.GROUP_SYMBOL);
        gs.setName(ProcedureReservedWords.DVARS);
        id.setGroupSymbol(gs);
        id.setType(clause.getValue().getType());
        id.setMetadataID(new TempMetadataID(id.getName(), id.getType()));
      }
    }

    GroupSymbol intoSymbol = dynamicCmd.getIntoGroup();
    if (intoSymbol != null) {
      if (!intoSymbol.isImplicitTempGroupSymbol()) {
        ResolverUtil.resolveGroup(intoSymbol, metadata);
      } else {
        List symbols = dynamicCmd.getAsColumns();
        ResolverUtil.resolveImplicitTempGroup(metadata, intoSymbol, symbols);
      }
    }
  }
 static {
   try {
     DriverManager.registerDriver(INSTANCE);
   } catch (SQLException e) {
     // Logging
     String logMsg = Messages.getString(Messages.JDBC.Err_registering, e.getMessage());
     logger.log(Level.SEVERE, logMsg);
   }
 }
 private MappingBaseNode getRecursiveRootNode(MappingRecursiveElement elem) {
   if (hasSource(elem.getMappingClass())) {
     return this;
   }
   MappingBaseNode parent = this.getParentNode();
   if (parent != null) {
     return parent.getRecursiveRootNode(elem);
   }
   throw new RuntimeException(Messages.gs(Messages.TEIID.TEIID30457, elem));
 }
Exemple #9
0
 @Override
 public void setMetadataID(Object metadataID) {
   if (metadataID == null) {
     throw new IllegalArgumentException(Messages.getString(Messages.ERR.ERR_015_010_0016));
   }
   if (this.isImplicitTempGroupSymbol()) {
     this.isTempTable = true;
   }
   this.metadataID = metadataID;
 }
 private Column addColumn(String name, Class<?> type, Table table, MetadataFactory mf)
     throws Exception {
   if (type == null) {
     throw new Exception(Messages.gs(Messages.TEIID.TEIID31086, name, table.getFullName()));
   }
   Column column =
       mf.addColumn(
           name, DataTypeManagerService.getInstance(teiidVersion).getDataTypeName(type), table);
   column.setUpdatable(table.supportsUpdate());
   return column;
 }
Exemple #11
0
 @Override
 public void addChildNode(MappingNode childNode) {
   if (childNode instanceof MappingAllNode) addAllNode((MappingAllNode) childNode);
   else if (childNode instanceof MappingChoiceNode) addChoiceNode((MappingChoiceNode) childNode);
   else if (childNode instanceof MappingCriteriaNode)
     addCriteriaNode((MappingCriteriaNode) childNode);
   else if (childNode instanceof MappingElement) addChildElement((MappingElement) childNode);
   else if (childNode instanceof MappingSequenceNode)
     addSequenceNode((MappingSequenceNode) childNode);
   else if (childNode instanceof MappingSourceNode) addSourceNode((MappingSourceNode) childNode);
   else throw new RuntimeException(Messages.gs(Messages.TEIID.TEIID30457, childNode));
 }
 private void validateConstraintNames(
     MetadataValidator metadataValidator,
     ValidatorReport report,
     ModelMetaData model,
     Collection<KeyRecord> keys,
     Set<String> names) {
   for (KeyRecord record : keys) {
     if (record.getName() == null) {
       continue;
     }
     if (!names.add(record.getName())) {
       metadataValidator.log(
           report, model, Messages.gs(Messages.TEIID.TEIID31152, record.getFullName()));
     }
   }
 }
 @Override
 public void writeBatch(
     ObjectOutput out, String[] types, List<? extends List<?>> batch, byte version)
     throws IOException {
   if (batch == null) {
     out.writeInt(-1);
   } else {
     if (version > 0 && batch.size() > 0) {
       out.writeInt(-batch.size() - 1);
       out.writeByte(version);
     } else {
       out.writeInt(batch.size());
     }
     if (batch.size() > 0) {
       int columns = types.length;
       out.writeInt(columns);
       for (int i = 0; i < columns; i++) {
         ColumnSerializer serializer = getSerializer(types[i], version);
         try {
           serializer.writeColumn(out, i, batch);
         } catch (ClassCastException e) {
           Object obj = null;
           String objectClass = null;
           objectSearch:
           for (int row = 0; row < batch.size(); row++) {
             obj = batch.get(row).get(i);
             if (obj != null) {
               objectClass = obj.getClass().getName();
               break objectSearch;
             }
           }
           throw new RuntimeException(
               Messages.gs(
                   Messages.TEIID.TEIID20001,
                   new Object[] {types[i], new Integer(i), objectClass}),
               e);
         }
       }
     }
   }
 }
 protected static Geometry transformGeometry(CoordinateTransform ct, Geometry geom)
     throws Exception {
   if (geom instanceof Polygon) {
     return transformPolygon(ct, (Polygon) geom);
   } else if (geom instanceof Point) {
     return transformPoint(ct, (Point) geom);
   } else if (geom instanceof LinearRing) {
     return transformLinearRing(ct, (LinearRing) geom);
   } else if (geom instanceof LineString) {
     return transformLineString(ct, (LineString) geom);
   } else if (geom instanceof MultiPolygon) {
     return transformMultiPolygon(ct, (MultiPolygon) geom);
   } else if (geom instanceof MultiPoint) {
     return transformMultiPoint(ct, (MultiPoint) geom);
   } else if (geom instanceof MultiLineString) {
     return transformMultiLineString(ct, (MultiLineString) geom);
   } else if (geom instanceof GeometryCollection) {
     return transformGeometryCollection(ct, (GeometryCollection) geom);
   } else {
     throw new Exception(Messages.gs(Messages.TEIID.TEIID31164, geom.getGeometryType()));
   }
 }
 public void addChoiceNode(MappingChoiceNode elem) {
   throw new RuntimeException(Messages.gs(Messages.TEIID.TEIID30452));
 }
    @Override
    public void execute(
        VDBMetaData vdb,
        MetadataStore store,
        ValidatorReport report,
        MetadataValidator metadataValidator) {
      for (Schema schema : store.getSchemaList()) {
        if (vdb.getImportedModels().contains(schema.getName())) {
          continue;
        }
        ModelMetaData model = vdb.getModel(schema.getName());
        for (Table t : schema.getTables().values()) {
          if (t.isPhysical() && !model.isSource()) {
            metadataValidator.log(
                report,
                model,
                Messages.gs(Messages.TEIID.TEIID31075, t.getFullName(), model.getName()));
          }
        }

        Set<String> names = new HashSet<String>();
        for (Procedure p : schema.getProcedures().values()) {
          boolean hasReturn = false;
          names.clear();
          for (int i = 0; i < p.getParameters().size(); i++) {
            ProcedureParameter param = p.getParameters().get(i);
            if (param.isVarArg() && param != p.getParameters().get(p.getParameters().size() - 1)) {
              // check that the rest of the parameters are optional
              // this accommodates variadic multi-source procedures
              // effective this and the resolving logic ensure that you can used named parameters
              // for everything,
              // or call the vararg procedure as normal
              if (isTeiidOrGreater(Version.TEIID_8_10)) {
                for (int j = i + 1; j < p.getParameters().size(); j++) {
                  ProcedureParameter param1 = p.getParameters().get(j);
                  if ((param1.getType() == Type.In || param1.getType() == Type.InOut)
                      && (param1.isVarArg()
                          || (param1.getNullType() != NullType.Nullable
                              && param1.getDefaultValue() == null))) {
                    metadataValidator.log(
                        report, model, Messages.gs(Messages.TEIID.TEIID31112, p.getFullName()));
                  }
                }
              } else {
                metadataValidator.log(
                    report, model, Messages.gs(Messages.TEIID.TEIID31112, p.getFullName()));
              }
            }
            if (param.getType() == ProcedureParameter.Type.ReturnValue) {
              if (hasReturn) {
                metadataValidator.log(
                    report, model, Messages.gs(Messages.TEIID.TEIID31107, p.getFullName()));
              }
              hasReturn = true;
            } else if (p.isFunction()
                && param.getType() != ProcedureParameter.Type.In
                && teiidVersion.isGreaterThanOrEqualTo(Version.TEIID_8_11)) {
              metadataValidator.log(
                  report,
                  model,
                  Messages.gs(Messages.TEIID.TEIID31165, p.getFullName(), param.getFullName()));
            }
            if (!names.add(param.getName())) {
              metadataValidator.log(
                  report,
                  model,
                  Messages.gs(Messages.TEIID.TEIID31106, p.getFullName(), param.getFullName()));
            }
          }
          if (!p.isVirtual() && !model.isSource()) {
            metadataValidator.log(
                report,
                model,
                Messages.gs(Messages.TEIID.TEIID31077, p.getFullName(), model.getName()));
          }

          if (p.isFunction() && teiidVersion.isGreaterThanOrEqualTo(Version.TEIID_8_11)) {
            if (!hasReturn) {
              metadataValidator.log(
                  report, model, Messages.gs(Messages.TEIID.TEIID31166, p.getFullName()));
            }
            if (p.isVirtual() && p.getQueryPlan() == null) {
              metadataValidator.log(
                  report, model, Messages.gs(Messages.TEIID.TEIID31167, p.getFullName()));
            }
          }
        }

        for (FunctionMethod func : schema.getFunctions().values()) {
          for (FunctionParameter param : func.getInputParameters()) {
            if (param.isVarArg()
                && param != func.getInputParameters().get(func.getInputParameterCount() - 1)) {
              metadataValidator.log(
                  report, model, Messages.gs(Messages.TEIID.TEIID31112, func.getFullName()));
            }
          }
          if (func.getPushdown().equals(FunctionMethod.PushDown.MUST_PUSHDOWN)
              && !model.isSource()) {
            metadataValidator.log(
                report,
                model,
                Messages.gs(Messages.TEIID.TEIID31078, func.getFullName(), model.getName()));
          }
        }
      }
    }
    @Override
    public void execute(
        VDBMetaData vdb,
        MetadataStore store,
        ValidatorReport report,
        MetadataValidator metadataValidator) {
      IQueryMetadataInterface metadata = vdb.getAttachment(IQueryMetadataInterface.class);
      metadata = new TempMetadataAdapter(metadata, new TempMetadataStore());
      for (Schema schema : store.getSchemaList()) {
        if (vdb.getImportedModels().contains(schema.getName())) {
          continue;
        }
        ModelMetaData model = vdb.getModel(schema.getName());
        MetadataFactory mf =
            new MetadataFactory(
                teiidVersion, vdb.getName(), vdb.getVersion(), metadataValidator.typeMap, model) {
              @Override
              protected void setUUID(AbstractMetadataRecord record) {
                if (count >= 0) {
                  count = Integer.MIN_VALUE;
                }
                super.setUUID(record);
              }
            };
        mf.setBuiltinDataTypes(store.getDatatypes());
        for (AbstractMetadataRecord record : schema.getResolvingOrder()) {
          if (record instanceof Table) {
            Table t = (Table) record;
            // no need to verify the transformation of the xml mapping document,
            // as this is very specific and designer already validates it.
            if (t.getTableType() == Table.Type.Document
                || t.getTableType() == Table.Type.XmlMappingClass
                || t.getTableType() == Table.Type.XmlStagingTable) {
              continue;
            }
            if (t.isVirtual() && t.getTableType() != Table.Type.TemporaryTable) {
              if (t.getSelectTransformation() == null) {
                metadataValidator.log(
                    report,
                    model,
                    Messages.gs(Messages.TEIID.TEIID31079, t.getFullName(), model.getName()));
              } else {
                metadataValidator.validate(vdb, model, t, report, metadata, mf);
              }
            }
          } else if (record instanceof Procedure) {
            Procedure p = (Procedure) record;

            boolean test = p.isVirtual();
            if (teiidVersion.isLessThan(Version.TEIID_8_11)) test = test && !p.isFunction();

            if (test) {
              if (p.getQueryPlan() == null) {
                metadataValidator.log(
                    report,
                    model,
                    Messages.gs(Messages.TEIID.TEIID31081, p.getFullName(), model.getName()));
              } else {
                metadataValidator.validate(vdb, model, p, report, metadata, mf);
              }
            }
          }
        }
      }
    }
 public void addSequenceNode(MappingSequenceNodeImpl elem) {
   throw new RuntimeException(Messages.gs(Messages.TEIID.TEIID30452));
 }
  private void validate(
      VDBMetaData vdb,
      ModelMetaData model,
      AbstractMetadataRecord record,
      ValidatorReport report,
      IQueryMetadataInterface metadata,
      MetadataFactory mf) {
    ValidatorReport resolverReport = null;
    try {
      if (record instanceof Procedure) {
        Procedure p = (Procedure) record;
        Command command = queryParser.parseProcedure(p.getQueryPlan(), false);
        GroupSymbol gs = createASTNode(ASTNodes.GROUP_SYMBOL);
        gs.setName(p.getFullName());
        QueryResolver resolver = new QueryResolver(queryParser);
        resolver.resolveCommand(command, gs, ICommand.TYPE_STORED_PROCEDURE, metadata, false);
        Validator validator = new Validator();
        resolverReport = validator.validate(command, metadata);
        determineDependencies(p, command);
      } else if (record instanceof Table) {
        Table t = (Table) record;

        GroupSymbol symbol = createASTNode(ASTNodes.GROUP_SYMBOL);
        symbol.setName(t.getFullName());
        ResolverUtil.resolveGroup(symbol, metadata);
        String selectTransformation = t.getSelectTransformation();

        boolean columnsIsEmpty = t.getColumns() == null || t.getColumns().isEmpty();

        // Consider columns if teid 8.11 or lower
        boolean considerColumns_811 =
            isTeiidOrGreater(Version.TEIID_8_12_4) ? true : columnsIsEmpty;
        // Consider columns if teiid 8.12.4+
        boolean considerColumns_8124 =
            isTeiidOrGreater(Version.TEIID_8_12_4) ? columnsIsEmpty : true;

        if (t.isVirtual() && considerColumns_811) {
          QueryCommand command = (QueryCommand) queryParser.parseCommand(selectTransformation);
          QueryResolver resolver = new QueryResolver(queryParser);
          resolver.resolveCommand(command, metadata);
          Validator validator = new Validator();
          resolverReport = validator.validate(command, metadata);

          if (!resolverReport.hasItems() && considerColumns_8124) {
            List<Expression> symbols = command.getProjectedSymbols();
            for (Expression column : symbols) {
              try {
                addColumn(Symbol.getShortName(column), column.getType(), t, mf);
              } catch (Exception e) {
                log(report, model, e.getMessage());
              }
            }
          }

          if (considerColumns_8124) {
            determineDependencies(t, command);
            if (t.getInsertPlan() != null && t.isInsertPlanEnabled()) {
              validateUpdatePlan(
                  model, report, metadata, t, t.getInsertPlan(), Command.TYPE_INSERT);
            }
            if (t.getUpdatePlan() != null && t.isUpdatePlanEnabled()) {
              validateUpdatePlan(
                  model, report, metadata, t, t.getUpdatePlan(), Command.TYPE_UPDATE);
            }
            if (t.getDeletePlan() != null && t.isDeletePlanEnabled()) {
              validateUpdatePlan(
                  model, report, metadata, t, t.getDeletePlan(), Command.TYPE_DELETE);
            }
          }
        }

        boolean addCacheHint = false;
        if (t.isMaterialized() && t.getMaterializedTable() == null) {
          List<KeyRecord> fbis = t.getFunctionBasedIndexes();
          List<GroupSymbol> groups = Arrays.asList(symbol);
          if (fbis != null && !fbis.isEmpty()) {
            for (KeyRecord fbi : fbis) {
              for (int j = 0; j < fbi.getColumns().size(); j++) {
                Column c = fbi.getColumns().get(j);
                if (c.getParent() != fbi) {
                  continue;
                }
                String exprString = c.getNameInSource();
                try {
                  Expression ex = queryParser.parseExpression(exprString);
                  ResolverVisitor resolverVisitor = new ResolverVisitor(teiidVersion);
                  resolverVisitor.resolveLanguageObject(ex, groups, metadata);
                  if (!ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(ex)
                      .isEmpty()) {
                    log(
                        report,
                        model,
                        Messages.gs(Messages.TEIID.TEIID31114, exprString, fbi.getFullName()));
                  }
                  EvaluatableVisitor ev = new EvaluatableVisitor(teiidVersion);
                  PreOrPostOrderNavigator.doVisit(ex, ev, PostOrderNavigator.PRE_ORDER);
                  if (ev.getDeterminismLevel().compareTo(Determinism.VDB_DETERMINISTIC) < 0) {
                    log(
                        report,
                        model,
                        Messages.gs(Messages.TEIID.TEIID31115, exprString, fbi.getFullName()));
                  }
                } catch (QueryResolverException e) {
                  log(
                      report,
                      model,
                      Messages.gs(
                          Messages.TEIID.TEIID31116,
                          exprString,
                          fbi.getFullName(),
                          e.getMessage()));
                }
              }
            }
          }
        } else {
          addCacheHint = true;
        }

        // this seems to parse, resolve and validate.
        QueryResolver resolver = new QueryResolver(queryParser);
        QueryNode node =
            resolver.resolveView(
                symbol,
                new QueryNode(t.getSelectTransformation()),
                SQLConstants.Reserved.SELECT,
                metadata);
        CacheHint cacheHint = node.getCommand().getCacheHint();
        Long ttl = -1L;
        if (cacheHint != null
            && cacheHint.getTtl() != null
            && addCacheHint
            && t.getProperty(MATVIEW_TTL, false) == null) {
          ttl = cacheHint.getTtl();
          t.setProperty(MATVIEW_TTL, String.valueOf(ttl));
        }
      }
      if (resolverReport != null && resolverReport.hasItems()) {
        for (ValidatorFailure v : resolverReport.getItems()) {
          log(
              report,
              model,
              v.getStatus() == IValidatorFailure.VFStatus.ERROR ? Severity.ERROR : Severity.WARNING,
              v.getMessage());
        }
      }
      processReport(model, record, report, resolverReport);
    } catch (Exception e) {
      log(
          report,
          model,
          Messages.gs(Messages.TEIID.TEIID31080, record.getFullName(), e.getMessage()));
    }
  }
    @Override
    public void execute(
        VDBMetaData vdb,
        MetadataStore store,
        ValidatorReport report,
        MetadataValidator metadataValidator) {
      for (Schema schema : store.getSchemaList()) {
        if (vdb.getImportedModels().contains(schema.getName())) {
          continue;
        }
        ModelMetaData model = vdb.getModel(schema.getName());

        for (Table t : schema.getTables().values()) {
          if (t.isVirtual()) {
            if (t.isMaterialized() && t.getMaterializedTable() != null) {
              String matTableName = t.getMaterializedTable().getFullName();
              int index = matTableName.indexOf(Table.NAME_DELIM_CHAR);
              if (index == -1) {
                metadataValidator.log(
                    report,
                    model,
                    Messages.gs(Messages.TEIID.TEIID31088, matTableName, t.getFullName()));
              } else {
                String schemaName = matTableName.substring(0, index);
                Schema matSchema = store.getSchema(schemaName);
                if (matSchema == null) {
                  metadataValidator.log(
                      report,
                      model,
                      Messages.gs(
                          Messages.TEIID.TEIID31089, schemaName, matTableName, t.getFullName()));
                } else {
                  Table matTable = matSchema.getTable(matTableName.substring(index + 1));
                  if (matTable == null) {
                    metadataValidator.log(
                        report,
                        model,
                        Messages.gs(
                            Messages.TEIID.TEIID31090,
                            matTableName.substring(index + 1),
                            schemaName,
                            t.getFullName()));
                  } else {
                    t.setMaterializedTable(matTable);
                  }
                }
              }
            }
          }

          for (KeyRecord record : t.getAllKeys()) {
            if (record.getColumns() == null || record.getColumns().isEmpty()) {
              metadataValidator.log(
                  report,
                  model,
                  Messages.gs(Messages.TEIID.TEIID31149, t.getFullName(), record.getName()));
            }
          }

          List<ForeignKey> fks = t.getForeignKeys();
          if (fks == null || fks.isEmpty()) {
            continue;
          }

          for (ForeignKey fk : fks) {
            // Only applicable to older teiid releases than 8.9
            if (fk.getReferenceKey() != null
                && !metadataValidator.isTeiidOrGreater(Version.TEIID_8_9)) {
              // ensure derived fields are set
              fk.setReferenceKey(fk.getReferenceKey());
              continue;
            }

            String referenceTableName = fk.getReferenceTableName();
            Table referenceTable = null;
            if (fk.getReferenceKey() == null) {
              if (referenceTableName == null) {
                metadataValidator.log(
                    report, model, Messages.gs(Messages.TEIID.TEIID31091, t.getFullName()));
                continue;
              }

              // TODO there is an ambiguity here because we don't properly track the name parts
              // so we have to first check for a table name that may contain .
              referenceTable = schema.getTable(referenceTableName);
            } else {
              referenceTableName = fk.getReferenceKey().getParent().getFullName();
            }

            String referenceSchemaName = schema.getName();
            int index = referenceTableName.indexOf(Table.NAME_DELIM_CHAR);
            if (referenceTable == null) {
              if (index != -1) {
                referenceSchemaName = referenceTableName.substring(0, index);
                Schema referenceSchema = store.getSchema(referenceSchemaName);
                if (referenceSchema == null) {
                  metadataValidator.log(
                      report,
                      model,
                      Messages.gs(Messages.TEIID.TEIID31093, referenceSchemaName, t.getFullName()));
                  continue;
                }
                referenceTable = referenceSchema.getTable(referenceTableName.substring(index + 1));
              }
              if (referenceTable == null) {
                metadataValidator.log(
                    report,
                    model,
                    Messages.gs(
                        Messages.TEIID.TEIID31092,
                        t.getFullName(),
                        referenceTableName.substring(index + 1),
                        referenceSchemaName));
                continue;
              }
            }

            KeyRecord uniqueKey = null;
            List<String> referenceColumns = fk.getReferenceColumns();
            if (fk.getReferenceKey() != null) {
              // index metadata logic sets the key prior to having the column names
              List<Column> cols = fk.getReferenceKey().getColumns();
              referenceColumns = new ArrayList<String>();
              for (Column col : cols) {
                referenceColumns.add(col.getName());
              }
            }
            if (referenceColumns == null || referenceColumns.isEmpty()) {
              if (referenceTable.getPrimaryKey() == null) {
                metadataValidator.log(
                    report,
                    model,
                    Messages.gs(
                        Messages.TEIID.TEIID31094,
                        t.getFullName(),
                        referenceTableName.substring(index + 1),
                        referenceSchemaName));
              } else {
                uniqueKey = referenceTable.getPrimaryKey();
              }

            } else {
              for (KeyRecord record : referenceTable.getUniqueKeys()) {
                if (keyMatches(fk.getReferenceColumns(), record)) {
                  uniqueKey = record;
                  break;
                }
              }
              if (uniqueKey == null
                  && referenceTable.getPrimaryKey() != null
                  && keyMatches(fk.getReferenceColumns(), referenceTable.getPrimaryKey())) {
                uniqueKey = referenceTable.getPrimaryKey();
              }
            }
            if (uniqueKey == null) {
              metadataValidator.log(
                  report,
                  model,
                  Messages.gs(
                      Messages.TEIID.TEIID31095,
                      t.getFullName(),
                      referenceTableName.substring(index + 1),
                      referenceSchemaName,
                      fk.getReferenceColumns()));
            } else {
              fk.setReferenceKey(uniqueKey);
            }
          }
        }
      }
    }