Пример #1
0
 public static VDBMetaData unmarshell(InputStream content) throws XMLStreamException {
   XMLInputFactory inputFactory = XMLType.getXmlInputFactory();
   XMLStreamReader reader = inputFactory.createXMLStreamReader(content);
   try {
     // elements
     while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
       Element element = Element.forName(reader.getLocalName());
       switch (element) {
         case VDB:
           VDBMetaData vdb = new VDBMetaData();
           Properties props = getAttributes(reader);
           vdb.setName(props.getProperty(Element.NAME.getLocalName()));
           vdb.setVersion(Integer.parseInt(props.getProperty(Element.VERSION.getLocalName())));
           parseVDB(reader, vdb);
           return vdb;
         default:
           throw new XMLStreamException(
               AdminPlugin.Util.gs(
                   "unexpected_element1", reader.getName(), Element.VDB.getLocalName()),
               reader.getLocation());
       }
     }
   } finally {
     try {
       content.close();
     } catch (IOException e) {
       Logger.getLogger(VDBMetadataParser.class.getName())
           .log(Level.FINE, "Exception closing vdb stream", e);
     }
   }
   return null;
 }
Пример #2
0
  @Test
  public void testOptionalFKFail() throws Exception {
    String ddl =
        "CREATE FOREIGN TABLE G1(g1e1 integer, g1e2 varchar);\n"
            + "CREATE FOREIGN TABLE G2( g2e1 integer, g2e2 varchar, PRIMARY KEY(g2e1, g2e2),"
            + "FOREIGN KEY (g2e1, g2e2) REFERENCES G1)";

    MetadataFactory s = helpParse(ddl, "model");
    Map<String, Table> tableMap = s.getSchema().getTables();
    assertEquals(2, tableMap.size());

    assertTrue("Table not found", tableMap.containsKey("G1"));
    assertTrue("Table not found", tableMap.containsKey("G2"));

    Table table = tableMap.get("G2");
    ForeignKey fk = table.getForeignKeys().get(0);
    assertEquals(fk.getColumns(), table.getColumns());
    assertEquals("G1", fk.getReferenceTableName());

    VDBMetaData vdb = new VDBMetaData();
    vdb.setName("myVDB"); // $NON-NLS-1$
    ModelMetaData modelOne = new ModelMetaData();
    modelOne.setName("model"); // $NON-NLS-1$
    vdb.addModel(modelOne);

    ValidatorReport report = new MetadataValidator().validate(vdb, s.asMetadataStore());

    assertTrue(report.hasItems());
  }
Пример #3
0
  @Test
  public void testFKAccrossSchemas() throws Exception {
    String ddl = "CREATE FOREIGN TABLE G1(g1e1 integer, g1e2 varchar, PRIMARY KEY(g1e1, g1e2));\n";

    String ddl2 =
        "CREATE FOREIGN TABLE G2( g2e1 integer, g2e2 varchar, PRIMARY KEY(g2e1, g2e2),"
            + "FOREIGN KEY (g2e1, g2e2) REFERENCES model.G1)";

    MetadataFactory f1 = helpParse(ddl, "model");
    MetadataFactory f2 = helpParse(ddl2, "model2");

    VDBMetaData vdb = new VDBMetaData();
    vdb.setName("myVDB"); // $NON-NLS-1$
    ModelMetaData modelOne = new ModelMetaData();
    modelOne.setName("model"); // $NON-NLS-1$
    vdb.addModel(modelOne);

    ModelMetaData modelTwo = new ModelMetaData();
    modelTwo.setName("model2"); // $NON-NLS-1$
    vdb.addModel(modelTwo);

    MetadataStore s = f1.asMetadataStore();
    f2.mergeInto(s);

    ValidatorReport report = new MetadataValidator().validate(vdb, s);

    assertFalse(report.hasItems());

    Table table = s.getSchema("model2").getTable("G2");
    ForeignKey fk = table.getForeignKeys().get(0);
    assertEquals(fk.getColumns(), table.getColumns());
    assertEquals("G1", fk.getReferenceTableName());

    assertEquals(fk.getPrimaryKey().getColumns(), s.getSchema("model").getTable("G1").getColumns());
  }
Пример #4
0
  public static void marshell(VDBMetaData vdb, OutputStream out)
      throws XMLStreamException, IOException {
    XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(out);

    writer.writeStartDocument();
    writer.writeStartElement(Element.VDB.getLocalName());
    writeAttribute(writer, Element.NAME.getLocalName(), vdb.getName());
    writeAttribute(writer, Element.VERSION.getLocalName(), String.valueOf(vdb.getVersion()));

    if (vdb.getDescription() != null) {
      writeElement(writer, Element.DESCRIPTION, vdb.getDescription());
    }
    writeProperties(writer, vdb.getProperties());

    for (VDBImport vdbImport : vdb.getVDBImports()) {
      writer.writeStartElement(Element.IMPORT_VDB.getLocalName());
      writeAttribute(writer, Element.NAME.getLocalName(), vdbImport.getName());
      writeAttribute(
          writer, Element.VERSION.getLocalName(), String.valueOf(vdbImport.getVersion()));
      writeAttribute(
          writer,
          Element.IMPORT_POLICIES.getLocalName(),
          String.valueOf(vdbImport.isImportDataPolicies()));
      writer.writeEndElement();
    }

    // models
    Collection<ModelMetaData> models = vdb.getModelMetaDatas().values();
    for (ModelMetaData model : models) {
      writeModel(writer, model);
    }

    // override translators
    for (Translator translator : vdb.getOverrideTranslators()) {
      writeTranslator(writer, translator);
    }

    // data-roles
    for (DataPolicy dp : vdb.getDataPolicies()) {
      writeDataPolicy(writer, dp);
    }

    // entry
    // designer only
    for (EntryMetaData em : vdb.getEntries()) {
      writer.writeStartElement(Element.ENTRY.getLocalName());
      writeAttribute(writer, Element.PATH.getLocalName(), em.getPath());
      if (em.getDescription() != null) {
        writeElement(writer, Element.DESCRIPTION, em.getDescription());
      }
      writeProperties(writer, em.getProperties());
      writer.writeEndElement();
    }

    writer.writeEndElement();
    writer.writeEndDocument();
    writer.close();
    out.close();
  }
  @Test
  public void testAnyAuthenticated() {
    DQPWorkContext message = new DQPWorkContext();
    message.setSession(Mockito.mock(SessionMetadata.class));
    VDBMetaData vdb = new VDBMetaData();
    DataPolicyMetadata dpm = new DataPolicyMetadata();
    dpm.setAnyAuthenticated(true);
    vdb.addDataPolicy(dpm);
    Mockito.stub(message.getSession().getVdb()).toReturn(vdb);

    Map<String, DataPolicy> map = message.getAllowedDataPolicies();
    assertEquals(1, map.size());
  }
Пример #6
0
 private Command aliasCommand(AccessNode aNode, Command command, Object modelID)
     throws TeiidComponentException, QueryPlannerException {
   try {
     command = (Command) command.clone();
     boolean aliasGroups =
         modelID != null
             && (CapabilitiesUtil.supportsGroupAliases(modelID, metadata, capFinder)
                 || CapabilitiesUtil.supports(
                     Capability.QUERY_FROM_INLINE_VIEWS, modelID, metadata, capFinder));
     boolean aliasColumns =
         modelID != null
             && (CapabilitiesUtil.supports(
                     Capability.QUERY_SELECT_EXPRESSION, modelID, metadata, capFinder)
                 || CapabilitiesUtil.supports(
                     Capability.QUERY_FROM_INLINE_VIEWS, modelID, metadata, capFinder));
     AliasGenerator visitor = new AliasGenerator(aliasGroups, !aliasColumns);
     SourceHint sh = command.getSourceHint();
     if (sh != null && aliasGroups) {
       VDBMetaData vdb = context.getDQPWorkContext().getVDB();
       ModelMetaData model = vdb.getModel(aNode.getModelName());
       List<String> sourceNames = model.getSourceNames();
       SpecificHint sp = null;
       if (sourceNames.size() == 1) {
         sp = sh.getSpecificHint(sourceNames.get(0));
       }
       if (sh.isUseAliases() || (sp != null && sp.isUseAliases())) {
         visitor.setAliasMapping(context.getAliasMapping());
       }
     }
     List<Reference> references = ReferenceCollectorVisitor.getReferences(command);
     if (!references.isEmpty()) {
       Set<String> correleatedGroups = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
       for (Reference ref : references) {
         if (ref.isCorrelated() && ref.getExpression().getGroupSymbol() != null) {
           correleatedGroups.add(ref.getExpression().getGroupSymbol().getName());
         }
       }
       visitor.setCorrelationGroups(correleatedGroups);
     }
     command.acceptVisitor(visitor);
   } catch (QueryMetadataException err) {
     throw new TeiidComponentException(QueryPlugin.Event.TEIID30249, err);
   } catch (TeiidRuntimeException e) {
     if (e.getCause() instanceof QueryPlannerException) {
       throw (QueryPlannerException) e.getCause();
     }
     throw e;
   }
   return command;
 }
Пример #7
0
 @Override
 public VDBMetaData clone() {
   try {
     VDBMetaData clone = (VDBMetaData) super.clone();
     clone.models = new LinkedHashMap<String, ModelMetaData>(this.models);
     if (this.attachments != null) {
       clone.attachments = null;
       clone.getAttachments().putAll(this.getAttachments());
     }
     return clone;
   } catch (CloneNotSupportedException e) {
     throw new TeiidRuntimeException(e);
   }
 }
Пример #8
0
 @Override
 public VDBMetaData clone() {
   try {
     VDBMetaData clone = (VDBMetaData) super.clone();
     clone.models = new LinkedHashMap<String, ModelMetaData>(this.models);
     synchronized (this.attachments) {
       clone.attachments =
           Collections.synchronizedMap(new LinkedHashMap<Class<?>, Object>(attachments));
     }
     return clone;
   } catch (CloneNotSupportedException e) {
     throw new TeiidRuntimeException(e);
   }
 }
Пример #9
0
 /**
  * Create an unauthenticated session
  *
  * @param userName
  * @param app
  * @param vdb
  * @return
  */
 public static SessionMetadata createTemporarySession(
     String userName, String app, VDBMetaData vdb) {
   long creationTime = System.currentTimeMillis();
   SessionMetadata newSession = new SessionMetadata();
   newSession.setSessionToken(new SessionToken(userName));
   newSession.setSessionId(newSession.getSessionToken().getSessionID());
   newSession.setUserName(userName);
   newSession.setCreatedTime(creationTime);
   newSession.setApplicationName(app);
   newSession.setVDBName(vdb.getName());
   newSession.setVDBVersion(vdb.getVersion());
   newSession.setVdb(vdb);
   newSession.setEmbedded(true);
   return newSession;
 }
Пример #10
0
 private static boolean isVisible(VDBMetaData vdb, Schema schema) {
   String schemaName = schema.getName();
   Model model = vdb.getModel(schemaName);
   if (model == null) {
     return true;
   }
   return model.isVisible();
 }
Пример #11
0
  public void metadataLoadFinished() {
    if (this.metadataloadFinished) {
      return;
    }
    this.metadataloadFinished = true;

    MetadataStore mergedStore = getMetadataStore();
    // the order of the models is important for resolving ddl
    // TODO we might consider not using the intermediate MetadataStore
    List<Schema> schemas = mergedStore.getSchemaList();
    schemas.clear();
    for (ModelMetaData model : this.vdb.getModelMetaDatas().values()) {
      Schema s = mergedStore.getSchema(model.getName());
      if (s != null) {
        schemas.add(s);
      } else {
        mergedStore.getSchemas().remove(model.getName());
      }
    }
    if (this.children != null && !this.children.isEmpty()) {
      for (CompositeVDB child : this.children.values()) {
        MetadataStore childStore = child.getMetadataStore();
        if (childStore != null) {
          mergedStore.merge(childStore);
        }
      }
    }

    TransformationMetadata metadata =
        buildTransformationMetaData(
            mergedVDB,
            getVisibilityMap(),
            mergedStore,
            getUDF(),
            systemFunctions,
            this.additionalStores);
    QueryMetadataInterface qmi = metadata;
    Map<String, String> multiSourceModels =
        MultiSourceMetadataWrapper.getMultiSourceModels(mergedVDB);
    if (multiSourceModels != null && !multiSourceModels.isEmpty()) {
      qmi = new MultiSourceMetadataWrapper(metadata, multiSourceModels);
    }
    mergedVDB.addAttchment(QueryMetadataInterface.class, qmi);
    mergedVDB.addAttchment(TransformationMetadata.class, metadata);
    mergedVDB.addAttchment(MetadataStore.class, mergedStore);
  }
    @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));
          }
        }
      }
    }
Пример #13
0
 public static boolean shouldInvalidate(VDBMetaData vdb) {
   boolean invalidate = true;
   if (vdb != null) {
     String val = vdb.getPropertyValue("lazy-invalidate"); // $NON-NLS-1$
     if (val != null) {
       invalidate = !Boolean.valueOf(val);
     }
   }
   return invalidate;
 }
Пример #14
0
 private static void parseVDB(XMLStreamReader reader, VDBMetaData vdb) throws XMLStreamException {
   while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) {
     Element element = Element.forName(reader.getLocalName());
     switch (element) {
       case DESCRIPTION:
         vdb.setDescription(reader.getElementText());
         break;
       case PROPERTY:
         parseProperty(reader, vdb);
         break;
       case MODEL:
         ModelMetaData model = new ModelMetaData();
         parseModel(reader, model);
         vdb.addModel(model);
         break;
       case TRANSLATOR:
         VDBTranslatorMetaData translator = new VDBTranslatorMetaData();
         parseTranslator(reader, translator);
         vdb.addOverideTranslator(translator);
         break;
       case DATA_ROLE:
         DataPolicyMetadata policy = new DataPolicyMetadata();
         parseDataRole(reader, policy);
         vdb.addDataPolicy(policy);
         break;
       case IMPORT_VDB:
         VDBImportMetadata vdbImport = new VDBImportMetadata();
         Properties props = getAttributes(reader);
         vdbImport.setName(props.getProperty(Element.NAME.getLocalName()));
         vdbImport.setVersion(Integer.parseInt(props.getProperty(Element.VERSION.getLocalName())));
         vdbImport.setImportDataPolicies(
             Boolean.parseBoolean(
                 props.getProperty(Element.IMPORT_POLICIES.getLocalName(), "true")));
         vdb.getVDBImports().add(vdbImport);
         ignoreTillEnd(reader);
         break;
       case ENTRY:
         EntryMetaData entry = new EntryMetaData();
         parseEntry(reader, entry);
         vdb.getEntries().add(entry);
         break;
       default:
         throw new XMLStreamException(
             AdminPlugin.Util.gs(
                 "unexpected_element5",
                 reader.getName(),
                 Element.DESCRIPTION.getLocalName(),
                 Element.PROPERTY.getLocalName(),
                 Element.MODEL.getLocalName(),
                 Element.TRANSLATOR.getLocalName(),
                 Element.DATA_ROLE.getLocalName()),
             reader.getLocation());
     }
   }
 }
Пример #15
0
  private void buildCompositeState(VDBRepository vdbRepository) throws VirtualDatabaseException {
    if (vdb.getVDBImports().isEmpty()) {
      this.vdb.addAttchment(ConnectorManagerRepository.class, this.cmr);
      return;
    }

    VDBMetaData newMergedVDB = this.vdb.clone();
    ConnectorManagerRepository mergedRepo = this.cmr;
    if (!this.cmr.isShared()) {
      mergedRepo = new ConnectorManagerRepository();
      mergedRepo.getConnectorManagers().putAll(this.cmr.getConnectorManagers());
    }
    newMergedVDB.addAttchment(ConnectorManagerRepository.class, mergedRepo);
    ClassLoader[] toSearch = new ClassLoader[vdb.getVDBImports().size() + 1];
    toSearch[0] = this.vdb.getAttachment(ClassLoader.class);
    this.children = new LinkedHashMap<VDBKey, CompositeVDB>();
    newMergedVDB.setImportedModels(new TreeSet<String>(String.CASE_INSENSITIVE_ORDER));
    int i = 1;
    for (VDBImport vdbImport : vdb.getVDBImports()) {
      CompositeVDB importedVDB =
          vdbRepository.getCompositeVDB(new VDBKey(vdbImport.getName(), vdbImport.getVersion()));
      if (importedVDB == null) {
        throw new VirtualDatabaseException(
            RuntimePlugin.Event.TEIID40083,
            RuntimePlugin.Util.gs(
                RuntimePlugin.Event.TEIID40083,
                vdb.getName(),
                vdb.getVersion(),
                vdbImport.getName(),
                vdbImport.getVersion()));
      }
      VDBMetaData childVDB = importedVDB.getVDB();
      newMergedVDB.getVisibilityOverrides().putAll(childVDB.getVisibilityOverrides());
      toSearch[i++] = childVDB.getAttachment(ClassLoader.class);
      this.children.put(new VDBKey(childVDB.getName(), childVDB.getVersion()), importedVDB);

      if (vdbImport.isImportDataPolicies()) {
        for (DataPolicy dp : importedVDB.getVDB().getDataPolicies()) {
          DataPolicyMetadata role = (DataPolicyMetadata) dp;
          if (newMergedVDB.addDataPolicy(role) != null) {
            throw new VirtualDatabaseException(
                RuntimePlugin.Event.TEIID40084,
                RuntimePlugin.Util.gs(
                    RuntimePlugin.Event.TEIID40084,
                    vdb.getName(),
                    vdb.getVersion(),
                    vdbImport.getName(),
                    vdbImport.getVersion(),
                    role.getName()));
          }
          if (role.isGrantAll()) {
            role.setSchemas(childVDB.getModelMetaDatas().keySet());
          }
        }
      }

      // add models
      for (ModelMetaData m : childVDB.getModelMetaDatas().values()) {
        if (newMergedVDB.addModel(m) != null) {
          throw new VirtualDatabaseException(
              RuntimePlugin.Event.TEIID40085,
              RuntimePlugin.Util.gs(
                  RuntimePlugin.Event.TEIID40085,
                  vdb.getName(),
                  vdb.getVersion(),
                  vdbImport.getName(),
                  vdbImport.getVersion(),
                  m.getName()));
        }
        newMergedVDB.getImportedModels().add(m.getName());
        String visibilityOverride =
            newMergedVDB.getPropertyValue(m.getName() + ".visible"); // $NON-NLS-1$
        if (visibilityOverride != null) {
          boolean visible = Boolean.valueOf(visibilityOverride);
          newMergedVDB.setVisibilityOverride(m.getName(), visible);
        }
      }
      ConnectorManagerRepository childCmr =
          childVDB.getAttachment(ConnectorManagerRepository.class);
      if (childCmr == null) {
        throw new AssertionError("childVdb had not connector manager repository"); // $NON-NLS-1$
      }
      if (!this.cmr.isShared()) {
        for (Map.Entry<String, ConnectorManager> entry :
            childCmr.getConnectorManagers().entrySet()) {
          if (mergedRepo.getConnectorManagers().put(entry.getKey(), entry.getValue()) != null) {
            throw new VirtualDatabaseException(
                RuntimePlugin.Event.TEIID40086,
                RuntimePlugin.Util.gs(
                    RuntimePlugin.Event.TEIID40086,
                    vdb.getName(),
                    vdb.getVersion(),
                    vdbImport.getName(),
                    vdbImport.getVersion(),
                    entry.getKey()));
          }
        }
      }
    }
    if (toSearch[0] != null) {
      CombinedClassLoader ccl = new CombinedClassLoader(toSearch[0].getParent(), toSearch);
      this.mergedVDB.addAttchment(ClassLoader.class, ccl);
    }
    this.mergedVDB = newMergedVDB;
  }
    @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);
              }
            }
          }
        }
      }
    }
    @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);
            }
          }
        }
      }
    }