Search in sources :

Example 26 with FunctionMethod

use of org.teiid.metadata.FunctionMethod in project teiid by teiid.

the class CapabilitiesUtil method supportsScalarFunction.

public static boolean supportsScalarFunction(Object modelID, Function function, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException {
    FunctionMethod method = function.getFunctionDescriptor().getMethod();
    if (metadata.isVirtualModel(modelID) || method.getPushdown() == PushDown.CANNOT_PUSHDOWN) {
        return false;
    }
    SourceCapabilities caps = getCapabilities(modelID, metadata, capFinder);
    // capabilities check is only valid for non-schema scoped functions
    // technically the other functions are scoped to SYS or their function model, but that's
    // not formally part of their metadata yet
    Schema schema = method.getParent();
    // TODO: this call should be functionDescriptor.getFullName - but legacy function models are parsed without setting the parent model as the schema
    String fullName = method.getFullName();
    if (schema == null || !schema.isPhysical()) {
        if (!caps.supportsFunction(fullName)) {
            if (SourceSystemFunctions.CONCAT2.equalsIgnoreCase(fullName)) {
                // special handling for delayed rewrite of concat2
                return (schema == null && caps.supportsFunction(SourceSystemFunctions.CONCAT) && caps.supportsFunction(SourceSystemFunctions.IFNULL) && caps.supportsCapability(Capability.QUERY_SEARCHED_CASE));
            } else if (SourceSystemFunctions.FROM_UNIXTIME.equalsIgnoreCase(fullName)) {
                return (schema == null && caps.supportsFunction(SourceSystemFunctions.TIMESTAMPADD));
            } else if (SourceSystemFunctions.FROM_UNIXTIME.equalsIgnoreCase(fullName)) {
                return (schema == null && caps.supportsFunction(SourceSystemFunctions.TIMESTAMPDIFF));
            } else {
                return false;
            }
        }
        if (FunctionLibrary.isConvert(function)) {
            Class<?> fromType = function.getArg(0).getType();
            Class<?> targetType = function.getType();
            if (fromType == targetType) {
                // this should be removed in rewrite
                return true;
            }
            return caps.supportsConvert(DataTypeManager.getTypeCode(fromType), DataTypeManager.getTypeCode(targetType));
        }
    } else if (!isSameConnector(modelID, schema, metadata, capFinder)) {
        return caps.supportsFunction(fullName);
    }
    return true;
}
Also used : Schema(org.teiid.metadata.Schema) FunctionMethod(org.teiid.metadata.FunctionMethod) SourceCapabilities(org.teiid.query.optimizer.capabilities.SourceCapabilities)

Example 27 with FunctionMethod

use of org.teiid.metadata.FunctionMethod in project teiid by teiid.

the class CompositeVDB method getUDF.

private UDFMetaData getUDF() {
    UDFMetaData mergedUDF = new UDFMetaData();
    if (this.udf != null) {
        mergedUDF.addFunctions(this.udf);
    }
    for (Schema schema : store.getSchemas().values()) {
        Collection<FunctionMethod> funcs = schema.getFunctions().values();
        mergedUDF.addFunctions(schema.getName(), funcs);
    }
    if (this.cmr != null) {
        // system scoped common source functions
        for (ConnectorManager cm : this.cmr.getConnectorManagers().values()) {
            List<FunctionMethod> funcs = cm.getPushDownFunctions();
            mergedUDF.addFunctions(CoreConstants.SYSTEM_MODEL, funcs);
        }
    }
    if (this.children != null) {
        // udf model functions - also scoped to the model
        for (CompositeVDB child : this.children.values()) {
            UDFMetaData funcs = child.getUDF();
            if (funcs != null) {
                mergedUDF.addFunctions(funcs);
            }
        }
    }
    return mergedUDF;
}
Also used : Schema(org.teiid.metadata.Schema) FunctionMethod(org.teiid.metadata.FunctionMethod) ConnectorManager(org.teiid.dqp.internal.datamgr.ConnectorManager)

Example 28 with FunctionMethod

use of org.teiid.metadata.FunctionMethod in project teiid by teiid.

the class PIExecutionFactory method start.

@Override
public void start() throws TranslatorException {
    super.start();
    // $NON-NLS-1$
    convert.addTypeMapping("Int8", FunctionModifier.BYTE);
    // $NON-NLS-1$
    convert.addTypeMapping("Int16", FunctionModifier.SHORT);
    // $NON-NLS-1$
    convert.addTypeMapping("Int32", FunctionModifier.INTEGER);
    // $NON-NLS-1$
    convert.addTypeMapping("Int64", FunctionModifier.LONG);
    // $NON-NLS-1$
    convert.addTypeMapping("Single", FunctionModifier.FLOAT);
    // $NON-NLS-1$
    convert.addTypeMapping("Double", FunctionModifier.DOUBLE);
    // $NON-NLS-1$
    convert.addTypeMapping("Boolean", FunctionModifier.BOOLEAN);
    // $NON-NLS-1$
    convert.addTypeMapping("String", FunctionModifier.STRING);
    // $NON-NLS-1$
    convert.addTypeMapping("DateTime", FunctionModifier.TIMESTAMP);
    // $NON-NLS-1$
    convert.addTypeMapping("Time", FunctionModifier.TIME);
    // $NON-NLS-1$
    convert.addTypeMapping("Variant", FunctionModifier.OBJECT);
    convert.addConvert(FunctionModifier.TIMESTAMP, FunctionModifier.TIME, new FunctionModifier() {

        @Override
        public List<?> translate(Function function) {
            // $NON-NLS-1$ //$NON-NLS-2$
            return Arrays.asList("cast(format(", function.getParameters().get(0), ", 'hh:mm:ss.fff') as Time)");
        }
    });
    convert.addConvert(FunctionModifier.BOOLEAN, FunctionModifier.FLOAT, new FunctionModifier() {

        @Override
        public List<?> translate(Function function) {
            // $NON-NLS-1$ //$NON-NLS-2$
            return Arrays.asList("cast(cast(", function.getParameters().get(0), " as int8) as single)");
        }
    });
    convert.addConvert(FunctionModifier.BOOLEAN, FunctionModifier.DOUBLE, new FunctionModifier() {

        @Override
        public List<?> translate(Function function) {
            // $NON-NLS-1$ //$NON-NLS-2$
            return Arrays.asList("cast(cast(", function.getParameters().get(0), " as int8) as double)");
        }
    });
    registerFunctionModifier(SourceSystemFunctions.CONVERT, convert);
    registerFunctionModifier(SourceSystemFunctions.MOD, new FunctionModifier() {

        @Override
        public List<?> translate(Function function) {
            return // $NON-NLS-1$ //$NON-NLS-2$
            Arrays.asList(// $NON-NLS-1$ //$NON-NLS-2$
            "cast(", // $NON-NLS-1$ //$NON-NLS-2$
            function.getParameters().get(0), // $NON-NLS-1$ //$NON-NLS-2$
            " as int64)", // $NON-NLS-1$ //$NON-NLS-2$
            "%", "cast(", function.getParameters().get(1), " as int64)");
        }
    });
    // $NON-NLS-1$
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.DAYOFMONTH, new AliasModifier("DAY"));
    registerFunctionModifier(SourceSystemFunctions.LOCATE, new FunctionModifier() {

        @Override
        public List<?> translate(Function function) {
            if (function.getParameters().size() <= 2) {
                return Arrays.asList("INSTR(", function.getParameters().get(1), ",", function.getParameters().get(0), ")");
            }
            return Arrays.asList("INSTR(", function.getParameters().get(1), ",", function.getParameters().get(0), ",", function.getParameters().get(2), ")");
        }
    });
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.LCASE, new AliasModifier("LOWER"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.UCASE, new AliasModifier("UPPER"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new AliasModifier("SUBSTR"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.LENGTH, new AliasModifier("LEN"));
    // $NON-NLS-1$
    addPushDownFunction(PI, "COSH", FLOAT, FLOAT);
    // $NON-NLS-1$
    addPushDownFunction(PI, "TANH", FLOAT, FLOAT);
    // $NON-NLS-1$
    addPushDownFunction(PI, "SINH", FLOAT, FLOAT);
    // $NON-NLS-1$
    addPushDownFunction(PI, "FORMAT", STRING, FLOAT, STRING);
    // $NON-NLS-1$
    addPushDownFunction(PI, "FORMAT", STRING, INTEGER, STRING);
    // $NON-NLS-1$
    addPushDownFunction(PI, "ParentName", STRING, STRING, INTEGER);
    // $NON-NLS-1$
    addPushDownFunction(PI, "List", STRING, STRING).setVarArgs(true);
    // $NON-NLS-1$
    addPushDownFunction(PI, "DIGCODE", INTEGER, STRING, STRING);
    // $NON-NLS-1$
    addPushDownFunction(PI, "DIGSTRING", STRING, INTEGER);
    // $NON-NLS-1$
    addPushDownFunction(PI, "PE", STRING, OBJECT);
    // $NON-NLS-1$
    addPushDownFunction(PI, "ParentName", STRING, STRING, INTEGER);
    // $NON-NLS-1$
    addPushDownFunction(PI, "VarType", STRING, STRING);
    // $NON-NLS-1$
    addPushDownFunction(PI, "UOMID", STRING, STRING);
    // $NON-NLS-1$
    addPushDownFunction(PI, "UOMName", STRING, STRING);
    // $NON-NLS-1$
    addPushDownFunction(PI, "UOMAbbreviation", STRING, STRING);
    // $NON-NLS-1$
    addPushDownFunction(PI, "UOMClassName", STRING, STRING);
    // $NON-NLS-1$
    addPushDownFunction(PI, "UOMCanonicallD", STRING, STRING);
    // $NON-NLS-1$
    addPushDownFunction(PI, "UOMConvert", DOUBLE, DOUBLE, STRING, STRING);
    // $NON-NLS-1$
    FunctionMethod f = addPushDownFunction(PI, "interval", TIMESTAMP, STRING);
    // $NON-NLS-1$
    f.setProperty(SQLConversionVisitor.TEIID_NATIVE_QUERY, "$1");
}
Also used : Function(org.teiid.language.Function) FunctionModifier(org.teiid.translator.jdbc.FunctionModifier) AliasModifier(org.teiid.translator.jdbc.AliasModifier) FunctionMethod(org.teiid.metadata.FunctionMethod) ArrayList(java.util.ArrayList) List(java.util.List)

Example 29 with FunctionMethod

use of org.teiid.metadata.FunctionMethod in project teiid by teiid.

the class TranslationHelper method loadUDFs.

public static void loadUDFs(String udf, TranslationUtility util) {
    try {
        Collection<FunctionMethod> methods = FunctionMetadataReader.loadFunctionMethods(TranslationHelper.class.getResource(udf).openStream());
        // $NON-NLS-1$
        util.addUDF("foo", methods);
    } catch (IOException e) {
        // $NON-NLS-1$
        throw new TeiidRuntimeException("failed to load UDF");
    } catch (XMLStreamException e) {
        // $NON-NLS-1$
        throw new TeiidRuntimeException("failed to load UDF");
    }
}
Also used : XMLStreamException(javax.xml.stream.XMLStreamException) FunctionMethod(org.teiid.metadata.FunctionMethod) IOException(java.io.IOException) TeiidRuntimeException(org.teiid.core.TeiidRuntimeException)

Example 30 with FunctionMethod

use of org.teiid.metadata.FunctionMethod in project teiid by teiid.

the class MongoDBExecutionFactory method start.

@SuppressWarnings("nls")
@Override
public void start() throws TranslatorException {
    super.start();
    // $NON-NLS-1$ //$NON-NLS-2$
    registerFunctionModifier("+", new AliasModifier("$add"));
    // $NON-NLS-1$ //$NON-NLS-2$
    registerFunctionModifier("-", new AliasModifier("$subtract"));
    // $NON-NLS-1$ //$NON-NLS-2$
    registerFunctionModifier("*", new AliasModifier("$multiply"));
    // $NON-NLS-1$ //$NON-NLS-2$
    registerFunctionModifier("/", new AliasModifier("$divide"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.CONCAT, new AliasModifier("$concat"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new AliasModifier("$substr"));
    registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new FunctionModifier() {

        @Override
        public List<?> translate(Function function) {
            // $NON-NLS-1$
            function.setName("$substr");
            ArrayList<Expression> params = new ArrayList<Expression>();
            params.add(function.getParameters().get(0));
            // MongoDB is zero base index; Teiid is 1 based;
            params.add(LanguageFactory.INSTANCE.createFunction("-", new Expression[] { function.getParameters().get(1), LanguageFactory.INSTANCE.createLiteral(1, TypeFacility.RUNTIME_TYPES.INTEGER) }, TypeFacility.RUNTIME_TYPES.INTEGER));
            if (function.getParameters().size() == 2) {
                function.getParameters().add(LanguageFactory.INSTANCE.createLiteral(DataTypeManager.MAX_STRING_LENGTH, TypeFacility.RUNTIME_TYPES.INTEGER));
            }
            params.add(function.getParameters().get(2));
            function.getParameters().clear();
            function.getParameters().addAll(params);
            return null;
        }
    });
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.LCASE, new AliasModifier("$toLower"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.UCASE, new AliasModifier("$toUpper"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.DAYOFYEAR, new AliasModifier("$dayOfYear"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.DAYOFMONTH, new AliasModifier("$dayOfMonth"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.DAYOFWEEK, new AliasModifier("$dayOfWeek"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.YEAR, new AliasModifier("$year"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.MONTH, new AliasModifier("$month"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.WEEK, new AliasModifier("$week"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.HOUR, new AliasModifier("$hour"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.MINUTE, new AliasModifier("$minute"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.SECOND, new AliasModifier("$second"));
    // $NON-NLS-1$
    registerFunctionModifier(SourceSystemFunctions.IFNULL, new AliasModifier("$ifNull"));
    FunctionMethod method = null;
    method = addPushDownFunction(MONGO, FUNC_GEO_INTERSECTS, TypeFacility.RUNTIME_NAMES.BOOLEAN, TypeFacility.RUNTIME_NAMES.STRING, TypeFacility.RUNTIME_NAMES.STRING, // $NON-NLS-1$
    TypeFacility.RUNTIME_NAMES.DOUBLE + "[][]");
    method.setProperty(AVOID_PROJECTION, "true");
    method = addPushDownFunction(MONGO, FUNC_GEO_INTERSECTS, TypeFacility.RUNTIME_NAMES.BOOLEAN, // $NON-NLS-1$
    TypeFacility.RUNTIME_NAMES.GEOMETRY);
    method.setProperty(AVOID_PROJECTION, "true");
    method = addPushDownFunction(MONGO, FUNC_GEO_WITHIN, TypeFacility.RUNTIME_NAMES.BOOLEAN, TypeFacility.RUNTIME_NAMES.STRING, TypeFacility.RUNTIME_NAMES.STRING, // $NON-NLS-1$
    TypeFacility.RUNTIME_NAMES.DOUBLE + "[][]");
    method.setProperty(AVOID_PROJECTION, "true");
    method = addPushDownFunction(MONGO, FUNC_GEO_WITHIN, TypeFacility.RUNTIME_NAMES.BOOLEAN, // $NON-NLS-1$
    TypeFacility.RUNTIME_NAMES.GEOMETRY);
    method.setProperty(AVOID_PROJECTION, "true");
    if (getVersion().compareTo(MongoDBExecutionFactory.TWO_6) >= 0) {
        method = addPushDownFunction(MONGO, FUNC_GEO_NEAR, TypeFacility.RUNTIME_NAMES.BOOLEAN, // $NON-NLS-1$
        TypeFacility.RUNTIME_NAMES.STRING, // $NON-NLS-1$
        TypeFacility.RUNTIME_NAMES.DOUBLE + "[]", TypeFacility.RUNTIME_NAMES.INTEGER, TypeFacility.RUNTIME_NAMES.INTEGER);
        method.setProperty(AVOID_PROJECTION, "true");
        method = addPushDownFunction(MONGO, FUNC_GEO_NEAR, TypeFacility.RUNTIME_NAMES.BOOLEAN, TypeFacility.RUNTIME_NAMES.GEOMETRY, TypeFacility.RUNTIME_NAMES.INTEGER, TypeFacility.RUNTIME_NAMES.INTEGER);
        method.setProperty(AVOID_PROJECTION, "true");
        method = addPushDownFunction(MONGO, FUNC_GEO_NEAR_SPHERE, TypeFacility.RUNTIME_NAMES.BOOLEAN, // $NON-NLS-1$
        TypeFacility.RUNTIME_NAMES.STRING, // $NON-NLS-1$
        TypeFacility.RUNTIME_NAMES.DOUBLE + "[]", TypeFacility.RUNTIME_NAMES.INTEGER, TypeFacility.RUNTIME_NAMES.INTEGER);
        method.setProperty(AVOID_PROJECTION, "true");
        method = addPushDownFunction(MONGO, FUNC_GEO_NEAR_SPHERE, TypeFacility.RUNTIME_NAMES.BOOLEAN, TypeFacility.RUNTIME_NAMES.GEOMETRY, TypeFacility.RUNTIME_NAMES.INTEGER, TypeFacility.RUNTIME_NAMES.INTEGER);
        method.setProperty(AVOID_PROJECTION, "true");
    } else {
        method = addPushDownFunction(MONGO, FUNC_GEO_NEAR, TypeFacility.RUNTIME_NAMES.BOOLEAN, // $NON-NLS-1$
        TypeFacility.RUNTIME_NAMES.STRING, // $NON-NLS-1$
        TypeFacility.RUNTIME_NAMES.DOUBLE + "[]", TypeFacility.RUNTIME_NAMES.INTEGER);
        method.setProperty(AVOID_PROJECTION, "true");
        method = addPushDownFunction(MONGO, FUNC_GEO_NEAR_SPHERE, TypeFacility.RUNTIME_NAMES.BOOLEAN, // $NON-NLS-1$
        TypeFacility.RUNTIME_NAMES.STRING, // $NON-NLS-1$
        TypeFacility.RUNTIME_NAMES.DOUBLE + "[]", TypeFacility.RUNTIME_NAMES.INTEGER);
        method.setProperty(AVOID_PROJECTION, "true");
    }
    method = addPushDownFunction(MONGO, FUNC_GEO_POLYGON_INTERSECTS, TypeFacility.RUNTIME_NAMES.BOOLEAN, TypeFacility.RUNTIME_NAMES.STRING, TypeFacility.RUNTIME_NAMES.DOUBLE, TypeFacility.RUNTIME_NAMES.DOUBLE, TypeFacility.RUNTIME_NAMES.DOUBLE, TypeFacility.RUNTIME_NAMES.DOUBLE);
    method.setProperty(AVOID_PROJECTION, "true");
    method = addPushDownFunction(MONGO, FUNC_GEO_POLYGON_INTERSECTS, TypeFacility.RUNTIME_NAMES.BOOLEAN, TypeFacility.RUNTIME_NAMES.GEOMETRY);
    method.setProperty(AVOID_PROJECTION, "true");
    method = addPushDownFunction(MONGO, FUNC_GEO_POLYGON_WITHIN, TypeFacility.RUNTIME_NAMES.BOOLEAN, TypeFacility.RUNTIME_NAMES.STRING, TypeFacility.RUNTIME_NAMES.DOUBLE, TypeFacility.RUNTIME_NAMES.DOUBLE, TypeFacility.RUNTIME_NAMES.DOUBLE, TypeFacility.RUNTIME_NAMES.DOUBLE);
    method.setProperty(AVOID_PROJECTION, "true");
    method = addPushDownFunction(MONGO, FUNC_GEO_POLYGON_WITHIN, TypeFacility.RUNTIME_NAMES.BOOLEAN, TypeFacility.RUNTIME_NAMES.GEOMETRY);
    method.setProperty(AVOID_PROJECTION, "true");
    // $NON-NLS-1$
    registerFunctionModifier(FUNC_GEO_NEAR, new AliasModifier("$near"));
    // $NON-NLS-1$
    registerFunctionModifier(FUNC_GEO_NEAR_SPHERE, new AliasModifier("$nearSphere"));
    // $NON-NLS-1$
    registerFunctionModifier(FUNC_GEO_WITHIN, new AliasModifier("$geoWithin"));
    // $NON-NLS-1$
    registerFunctionModifier(FUNC_GEO_INTERSECTS, new AliasModifier("$geoIntersects"));
    // $NON-NLS-1$
    registerFunctionModifier(FUNC_GEO_POLYGON_INTERSECTS, new GeoPolygonFunctionModifier("$geoIntersects"));
    // $NON-NLS-1$
    registerFunctionModifier(FUNC_GEO_POLYGON_WITHIN, new GeoPolygonFunctionModifier("$geoWithin"));
}
Also used : Function(org.teiid.language.Function) Expression(org.teiid.language.Expression) QueryExpression(org.teiid.language.QueryExpression) FunctionModifier(org.teiid.translator.jdbc.FunctionModifier) AliasModifier(org.teiid.translator.jdbc.AliasModifier) ArrayList(java.util.ArrayList) FunctionMethod(org.teiid.metadata.FunctionMethod) BasicDBList(com.mongodb.BasicDBList) List(java.util.List) ArrayList(java.util.ArrayList)

Aggregations

FunctionMethod (org.teiid.metadata.FunctionMethod)63 FunctionParameter (org.teiid.metadata.FunctionParameter)31 Test (org.junit.Test)15 ArrayList (java.util.ArrayList)9 Schema (org.teiid.metadata.Schema)6 TransformationMetadata (org.teiid.query.metadata.TransformationMetadata)6 IOException (java.io.IOException)5 MetadataStore (org.teiid.metadata.MetadataStore)5 List (java.util.List)4 TeiidRuntimeException (org.teiid.core.TeiidRuntimeException)4 BasicSourceCapabilities (org.teiid.query.optimizer.capabilities.BasicSourceCapabilities)4 Collection (java.util.Collection)3 HashMap (java.util.HashMap)3 LinkedList (java.util.LinkedList)3 XMLStreamException (javax.xml.stream.XMLStreamException)3 ConnectorManager (org.teiid.dqp.internal.datamgr.ConnectorManager)3 DeployVDBParameter (org.teiid.jdbc.FakeServer.DeployVDBParameter)3 AggregateAttributes (org.teiid.metadata.AggregateAttributes)3 Procedure (org.teiid.metadata.Procedure)3 UDFSource (org.teiid.query.function.UDFSource)3