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