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; }
@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()); }
@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()); }
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()); }
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; }
@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); } }
@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); } }
/** * 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; }
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(); }
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)); } } } }
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; }
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()); } } }
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); } } } } }