/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.runtime.client.query; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.teiid.core.types.JDBCSQLTypeInfo; import org.teiid.designer.query.IQueryFactory; import org.teiid.designer.query.IQueryParser; import org.teiid.designer.query.IQueryResolver; import org.teiid.designer.query.IQueryService; import org.teiid.designer.query.metadata.IQueryMetadataInterface; import org.teiid.designer.query.sql.ICommandCollectorVisitor; import org.teiid.designer.query.sql.IElementCollectorVisitor; import org.teiid.designer.query.sql.IFunctionCollectorVisitor; import org.teiid.designer.query.sql.IGroupCollectorVisitor; import org.teiid.designer.query.sql.IGroupsUsedByElementsVisitor; import org.teiid.designer.query.sql.IPredicateCollectorVisitor; import org.teiid.designer.query.sql.IReferenceCollectorVisitor; import org.teiid.designer.query.sql.IResolverVisitor; import org.teiid.designer.query.sql.ISQLStringVisitor; import org.teiid.designer.query.sql.ISQLStringVisitorCallback; import org.teiid.designer.query.sql.IValueIteratorProviderCollectorVisitor; import org.teiid.designer.query.sql.lang.ICommand; import org.teiid.designer.query.sql.lang.IExpression; import org.teiid.designer.query.sql.symbol.IGroupSymbol; import org.teiid.designer.query.sql.symbol.ISymbol; import org.teiid.designer.runtime.version.spi.ITeiidServerVersion; import org.teiid.designer.udf.FunctionMethodDescriptor; import org.teiid.designer.udf.FunctionParameterDescriptor; import org.teiid.designer.udf.IFunctionLibrary; import org.teiid.designer.validator.IUpdateValidator; import org.teiid.designer.validator.IUpdateValidator.TransformUpdateType; import org.teiid.designer.validator.IValidator; import org.teiid.designer.xml.IMappingDocumentFactory; import org.teiid.language.SQLConstants; import org.teiid.metadata.FunctionMethod; import org.teiid.metadata.FunctionMethod.Determinism; import org.teiid.metadata.FunctionParameter; import org.teiid.query.function.FunctionDescriptor; import org.teiid.query.function.FunctionLibrary; import org.teiid.query.function.FunctionTree; import org.teiid.query.function.SystemFunctionManager; import org.teiid.query.function.UDFSource; import org.teiid.query.parser.QueryParser; import org.teiid.query.resolver.QueryResolver; import org.teiid.query.resolver.util.ResolverUtil; import org.teiid.query.resolver.util.ResolverVisitor; import org.teiid.query.sql.ProcedureReservedWords; import org.teiid.query.sql.lang.Command; import org.teiid.query.sql.symbol.GroupSymbol; import org.teiid.query.sql.visitor.CallbackSQLStringVisitor; import org.teiid.query.sql.visitor.CommandCollectorVisitor; import org.teiid.query.sql.visitor.ElementCollectorVisitor; import org.teiid.query.sql.visitor.FunctionCollectorVisitor; import org.teiid.query.sql.visitor.GroupCollectorVisitor; import org.teiid.query.sql.visitor.GroupsUsedByElementsVisitor; import org.teiid.query.sql.visitor.SQLStringVisitor; import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor; import org.teiid.query.validator.PredicateCollectorVisitor; import org.teiid.query.validator.ReferenceCollectorVisitor; import org.teiid.query.validator.UpdateValidator; import org.teiid.query.validator.UpdateValidator.UpdateType; import org.teiid.query.validator.Validator; import org.teiid.runtime.client.proc.ProcedureService; import org.teiid.runtime.client.xml.MappingDocumentFactory; /** * */ public class QueryService implements IQueryService { private final ITeiidServerVersion teiidVersion; private QueryParser queryParser; private final SystemFunctionManager systemFunctionManager; private SyntaxFactory factory; /** * @param teiidVersion */ public QueryService(ITeiidServerVersion teiidVersion) { this.teiidVersion = teiidVersion; systemFunctionManager = new SystemFunctionManager(teiidVersion, getClass().getClassLoader()); } /** * @return a query parser applicable to the given teiid instance version */ @Override public IQueryParser getQueryParser() { if (queryParser == null) { queryParser = new QueryParser(teiidVersion); } return queryParser; } @Override public boolean isReservedWord(String word) { return SQLConstants.isReservedWord(teiidVersion, word); } @Override public boolean isProcedureReservedWord(String word) { return ProcedureReservedWords.isProcedureReservedWord(teiidVersion, word); } @Override public Set<String> getReservedWords() { return SQLConstants.getReservedWords(teiidVersion); } @Override public Set<String> getNonReservedWords() { return SQLConstants.getNonReservedWords(teiidVersion); } @Override public String getJDBCSQLTypeName(int jdbcType) { return JDBCSQLTypeInfo.getTypeName(teiidVersion, jdbcType); } @Override public IFunctionLibrary createFunctionLibrary() { return new FunctionLibrary(teiidVersion, systemFunctionManager.getSystemFunctions(), new FunctionTree[0]); } @Override public IFunctionLibrary createFunctionLibrary(List<FunctionMethodDescriptor> functionMethodDescriptors) { // Dynamically return a function library for each call rather than cache it here. Map<String, FunctionTree> functionTrees = new HashMap<String, FunctionTree>(); for (FunctionMethodDescriptor descriptor : functionMethodDescriptors) { List<FunctionParameter> inputParameters = new ArrayList<FunctionParameter>(); for (FunctionParameterDescriptor paramDescriptor : descriptor.getInputParameters()) { inputParameters.add(new FunctionParameter(teiidVersion, paramDescriptor.getName(), paramDescriptor.getType())); } FunctionParameter outputParameter = new FunctionParameter(teiidVersion, descriptor.getOutputParameter().getName(), descriptor.getOutputParameter().getType()); FunctionMethod fMethod = new FunctionMethod(descriptor.getName(), descriptor.getDescription(), descriptor.getCategory(), descriptor.getInvocationClass(), descriptor.getInvocationMethod(), inputParameters.toArray(new FunctionParameter[0]), outputParameter); fMethod.setPushDown(descriptor.getPushDownLiteral()); fMethod.setVarArgs(descriptor.isVariableArgs()); if (descriptor.isDeterministic()) { fMethod.setDeterminism(Determinism.DETERMINISTIC); } else { fMethod.setDeterminism(Determinism.NONDETERMINISTIC); } FunctionTree tree = functionTrees.get(descriptor.getSchema()); UDFSource udfSource = new UDFSource(Collections.EMPTY_LIST, getClass().getClassLoader()); if (tree == null) { tree = new FunctionTree(teiidVersion, descriptor.getSchema(), udfSource, false); functionTrees.put(descriptor.getSchema(), tree); } FunctionDescriptor fd = tree.addFunction(descriptor.getSchema(), udfSource, fMethod, false); fd.setMetadataID(descriptor.getMetadataID()); } return new FunctionLibrary(teiidVersion, systemFunctionManager.getSystemFunctions(), functionTrees.values().toArray(new FunctionTree[0])); } @Override public IQueryFactory createQueryFactory() { if (factory == null) factory = new SyntaxFactory(teiidVersion); return factory; } @Override public IMappingDocumentFactory getMappingDocumentFactory() { getQueryParser(); return new MappingDocumentFactory(teiidVersion); } @Override public String getSymbolName(IExpression expression) { if (expression instanceof ISymbol) { return ((ISymbol)expression).getName(); } return "expr"; //$NON-NLS-1$ } @Override public String getSymbolShortName(String name) { int index = name.lastIndexOf(ISymbol.SEPARATOR); if (index >= 0) { return name.substring(index + 1); } return name; } @Override public String getSymbolShortName(IExpression expression) { if (expression instanceof ISymbol) { return ((ISymbol)expression).getShortName(); } return "expr"; //$NON-NLS-1$ } @Override public SQLStringVisitor getSQLStringVisitor() { return new SQLStringVisitor(teiidVersion); } @Override public ISQLStringVisitor getCallbackSQLStringVisitor(ISQLStringVisitorCallback visitorCallback) { return new CallbackSQLStringVisitor(teiidVersion, visitorCallback); } @Override public IGroupCollectorVisitor getGroupCollectorVisitor(boolean removeDuplicates) { return new GroupCollectorVisitor(teiidVersion, removeDuplicates); } @Override public IGroupsUsedByElementsVisitor getGroupsUsedByElementsVisitor() { return new GroupsUsedByElementsVisitor(); } @Override public IElementCollectorVisitor getElementCollectorVisitor(boolean removeDuplicates) { return new ElementCollectorVisitor(teiidVersion, removeDuplicates); } @Override public ICommandCollectorVisitor getCommandCollectorVisitor() { return new CommandCollectorVisitor(teiidVersion); } @Override public IFunctionCollectorVisitor getFunctionCollectorVisitor(boolean removeDuplicates) { return new FunctionCollectorVisitor(teiidVersion, removeDuplicates); } @Override public IPredicateCollectorVisitor getPredicateCollectorVisitor() { return new PredicateCollectorVisitor(teiidVersion); } @Override public IReferenceCollectorVisitor getReferenceCollectorVisitor() { return new ReferenceCollectorVisitor(teiidVersion); } @Override public IValueIteratorProviderCollectorVisitor getValueIteratorProviderCollectorVisitor() { return new ValueIteratorProviderCollectorVisitor(teiidVersion); } @Override public IResolverVisitor getResolverVisitor() { return new ResolverVisitor(teiidVersion); } @Override public IValidator getValidator() { return new Validator(); } @Override public IUpdateValidator getUpdateValidator(IQueryMetadataInterface metadata, TransformUpdateType tInsertType, TransformUpdateType tUpdateType, TransformUpdateType tDeleteType) { UpdateType insertType = UpdateType.valueOf(tInsertType.name()); UpdateType updateType = UpdateType.valueOf(tUpdateType.name()); UpdateType deleteType = UpdateType.valueOf(tDeleteType.name()); return new UpdateValidator(metadata, insertType, updateType, deleteType); } @Override public void resolveGroup(IGroupSymbol groupSymbol, IQueryMetadataInterface metadata) throws Exception { ResolverUtil.resolveGroup((GroupSymbol)groupSymbol, metadata); } @Override public void fullyQualifyElements(ICommand command) { ResolverUtil.fullyQualifyElements((Command)command); } @Override public IQueryResolver getQueryResolver() { getQueryParser(); return new QueryResolver((QueryParser)getQueryParser()); } @Override public ProcedureService getProcedureService() { return new ProcedureService(teiidVersion); } }