Search in sources :

Example 21 with FunctionDescriptor

use of org.teiid.query.function.FunctionDescriptor in project teiid by teiid.

the class QueryRewriter method simplifyParseFormatFunction.

private Criteria simplifyParseFormatFunction(CompareCriteria crit) {
    // TODO: this can be relaxed for order preserving operations
    if (!(crit.getOperator() == CompareCriteria.EQ || crit.getOperator() == CompareCriteria.NE)) {
        return crit;
    }
    boolean isFormat = false;
    Function leftFunction = (Function) crit.getLeftExpression();
    String funcName = leftFunction.getName();
    String inverseFunction = null;
    if (StringUtil.startsWithIgnoreCase(funcName, "parse")) {
        // $NON-NLS-1$
        String type = funcName.substring(5);
        if (!PARSE_FORMAT_TYPES.contains(type)) {
            return crit;
        }
        // $NON-NLS-1$
        inverseFunction = "format" + type;
    } else if (StringUtil.startsWithIgnoreCase(funcName, "format")) {
        // $NON-NLS-1$
        String type = funcName.substring(6);
        if (!PARSE_FORMAT_TYPES.contains(type)) {
            return crit;
        }
        // $NON-NLS-1$
        inverseFunction = "parse" + type;
        isFormat = true;
    } else {
        return crit;
    }
    Expression rightExpr = crit.getRightExpression();
    if (!(rightExpr instanceof Constant)) {
        return crit;
    }
    Expression leftExpr = leftFunction.getArgs()[0];
    Expression formatExpr = leftFunction.getArgs()[1];
    if (!(formatExpr instanceof Constant)) {
        return crit;
    }
    String format = (String) ((Constant) formatExpr).getValue();
    FunctionLibrary funcLib = this.metadata.getFunctionLibrary();
    FunctionDescriptor descriptor = funcLib.findFunction(inverseFunction, new Class[] { rightExpr.getType(), formatExpr.getType() });
    if (descriptor == null) {
        return crit;
    }
    Object value = ((Constant) rightExpr).getValue();
    try {
        Object result = descriptor.invokeFunction(new Object[] { context, ((Constant) rightExpr).getValue(), format }, null, this.context);
        result = leftFunction.getFunctionDescriptor().invokeFunction(new Object[] { context, result, format }, null, this.context);
        if (Constant.COMPARATOR.compare(value, result) != 0) {
            return getSimpliedCriteria(crit, leftExpr, crit.getOperator() != CompareCriteria.EQ, true);
        }
    } catch (FunctionExecutionException e) {
        // Not all numeric formats are invertable, so just return the criteria as it may still be valid
        return crit;
    } catch (BlockedException e) {
        return crit;
    }
    // parseFunctions are all potentially narrowing
    if (!isFormat) {
        return crit;
    }
    // TODO: if format is not lossy, then invert the function
    return crit;
}
Also used : FunctionExecutionException(org.teiid.api.exception.query.FunctionExecutionException) FunctionLibrary(org.teiid.query.function.FunctionLibrary) LanguageObject(org.teiid.query.sql.LanguageObject) FunctionDescriptor(org.teiid.query.function.FunctionDescriptor) BlockedException(org.teiid.common.buffer.BlockedException)

Example 22 with FunctionDescriptor

use of org.teiid.query.function.FunctionDescriptor in project teiid by teiid.

the class EvaluatableVisitor method visit.

public void visit(Function obj) {
    FunctionDescriptor fd = obj.getFunctionDescriptor();
    this.setDeterminismLevel(fd.getDeterministic());
    if (fd.getDeterministic() == Determinism.NONDETERMINISTIC || fd.getPushdown() == PushDown.MUST_PUSHDOWN) {
        if (obj.isEval()) {
            evaluationNotPossible(EvaluationLevel.PROCESSING);
        } else {
            evaluationNotPossible(EvaluationLevel.PUSH_DOWN);
        }
    } else if (obj.getName().equalsIgnoreCase(FunctionLibrary.LOOKUP) || // TODO: if we had the context here we could plan better for non-prepared requests
    fd.getDeterministic().compareTo(Determinism.COMMAND_DETERMINISTIC) <= 0) {
        evaluationNotPossible(EvaluationLevel.PROCESSING);
    } else if (fd.getProcedure() != null) {
        // a function defined by a procedure
        evaluationNotPossible(EvaluationLevel.PROCESSING);
    }
}
Also used : FunctionDescriptor(org.teiid.query.function.FunctionDescriptor)

Example 23 with FunctionDescriptor

use of org.teiid.query.function.FunctionDescriptor in project teiid by teiid.

the class TestExpressionEvaluator method testUser.

@Test
public void testUser() throws Exception {
    // $NON-NLS-1$
    Function func = new Function("user", new Expression[] {});
    // $NON-NLS-1$
    FunctionDescriptor desc = RealMetadataFactory.SFM.getSystemFunctionLibrary().findFunction("user", new Class[] {});
    func.setFunctionDescriptor(desc);
    FakeDataManager dataMgr = new FakeDataManager();
    CommandContext context = new CommandContext(new Long(1), null, null, null, 0);
    // $NON-NLS-1$
    context.setUserName("logon");
    assertEquals(context.getUserName(), new Evaluator(Collections.emptyMap(), dataMgr, context).evaluate(func, Collections.emptyList()));
}
Also used : CommandContext(org.teiid.query.util.CommandContext) FakeDataManager(org.teiid.query.processor.FakeDataManager) FunctionDescriptor(org.teiid.query.function.FunctionDescriptor) Evaluator(org.teiid.query.eval.Evaluator) Test(org.junit.Test)

Example 24 with FunctionDescriptor

use of org.teiid.query.function.FunctionDescriptor in project teiid by teiid.

the class TestGroupingNode method helpTestLookupFunctionInAggregate.

private void helpTestLookupFunctionInAggregate(int batchSize) throws Exception {
    BufferManagerImpl mgr = BufferManagerFactory.createBufferManager();
    mgr.setProcessorBatchSize(batchSize);
    // Set up
    GroupingNode node = new GroupingNode(1);
    List outputElements = new ArrayList();
    // $NON-NLS-1$
    ElementSymbol col1 = new ElementSymbol("col1");
    col1.setType(Integer.class);
    // $NON-NLS-1$
    ElementSymbol col2 = new ElementSymbol("col2");
    col2.setType(Integer.class);
    // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    Function func = new Function("lookup", new Expression[] { new Constant("pm1.g1"), new Constant("e2"), new Constant("e1"), col2 });
    // $NON-NLS-1$
    FunctionDescriptor desc = RealMetadataFactory.SFM.getSystemFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, Integer.class });
    func.setFunctionDescriptor(desc);
    func.setType(DataTypeManager.DefaultDataClasses.INTEGER);
    outputElements.add(col1);
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("COUNT", false, func));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("SUM", false, func));
    // $NON-NLS-1$ //$NON-NLS-2$
    outputElements.add(new AggregateSymbol("SUM", true, func));
    node.setElements(outputElements);
    List groupingElements = new ArrayList();
    groupingElements.add(col1);
    node.setOrderBy(new OrderBy(groupingElements).getOrderByItems());
    // $NON-NLS-1$ //$NON-NLS-2$
    CommandContext context = new CommandContext("pid", "test", null, null, 1);
    FakeDataManager dataMgr = new FakeDataManager();
    dataMgr.setThrowBlocked(true);
    Map valueMap = new HashMap();
    valueMap.put(new Integer(0), new Integer(1));
    valueMap.put(new Integer(1), new Integer(2));
    valueMap.put(new Integer(2), new Integer(3));
    valueMap.put(new Integer(3), new Integer(4));
    valueMap.put(new Integer(4), new Integer(5));
    // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    dataMgr.defineCodeTable("pm1.g1", "e1", "e2", valueMap);
    List[] expected = new List[] { Arrays.asList(new Object[] { null, new Integer(1), new Long(4), new Long(4) }), Arrays.asList(new Object[] { new Integer(0), new Integer(1), new Long(5), new Long(5) }), Arrays.asList(new Object[] { new Integer(1), new Integer(1), new Long(3), new Long(3) }), Arrays.asList(new Object[] { new Integer(2), new Integer(4), new Long(9), new Long(5) }), Arrays.asList(new Object[] { new Integer(3), new Integer(1), new Long(1), new Long(1) }), Arrays.asList(new Object[] { new Integer(4), new Integer(2), new Long(7), new Long(7) }), Arrays.asList(new Object[] { new Integer(5), new Integer(1), new Long(4), new Long(4) }), Arrays.asList(new Object[] { new Integer(6), new Integer(2), new Long(9), new Long(9) }) };
    helpProcess(mgr, node, context, expected, dataMgr);
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) OrderBy(org.teiid.query.sql.lang.OrderBy) AggregateSymbol(org.teiid.query.sql.symbol.AggregateSymbol) BufferManagerImpl(org.teiid.common.buffer.impl.BufferManagerImpl) CommandContext(org.teiid.query.util.CommandContext) FakeDataManager(org.teiid.query.processor.FakeDataManager) HashMap(java.util.HashMap) Constant(org.teiid.query.sql.symbol.Constant) ArrayList(java.util.ArrayList) FunctionDescriptor(org.teiid.query.function.FunctionDescriptor) Function(org.teiid.query.sql.symbol.Function) AggregateFunction(org.teiid.query.function.aggregate.AggregateFunction) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) SymbolMap(org.teiid.query.sql.util.SymbolMap)

Example 25 with FunctionDescriptor

use of org.teiid.query.function.FunctionDescriptor in project teiid by teiid.

the class TestProjectNode method testProjectWithLookupFunction.

@Test
public void testProjectWithLookupFunction() throws Exception {
    // $NON-NLS-1$
    ElementSymbol es1 = new ElementSymbol("e1");
    es1.setType(DataTypeManager.DefaultDataClasses.STRING);
    List elements = new ArrayList();
    elements.add(es1);
    // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    Function func = new Function("lookup", new Expression[] { new Constant("pm1.g1"), new Constant("e2"), new Constant("e1"), es1 });
    // $NON-NLS-1$
    FunctionDescriptor desc = RealMetadataFactory.SFM.getSystemFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, String.class });
    func.setFunctionDescriptor(desc);
    func.setType(DataTypeManager.DefaultDataClasses.STRING);
    // $NON-NLS-1$
    ExpressionSymbol expr = new ExpressionSymbol("expr", func);
    List projectElements = new ArrayList();
    projectElements.add(expr);
    List[] data = new List[] { // $NON-NLS-1$
    Arrays.asList(new Object[] { "1" }), // $NON-NLS-1$
    Arrays.asList(new Object[] { "2" }) };
    List[] expected = new List[] { // $NON-NLS-1$
    Arrays.asList(new Object[] { "a" }), // $NON-NLS-1$
    Arrays.asList(new Object[] { "b" }) };
    FakeDataManager dataMgr = new FakeDataManager();
    dataMgr.setThrowBlocked(true);
    Map valueMap = new HashMap();
    // $NON-NLS-1$ //$NON-NLS-2$
    valueMap.put("1", "a");
    // $NON-NLS-1$ //$NON-NLS-2$
    valueMap.put("2", "b");
    // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    dataMgr.defineCodeTable("pm1.g1", "e1", "e2", valueMap);
    helpTestProject(projectElements, data, elements, expected, dataMgr);
}
Also used : ElementSymbol(org.teiid.query.sql.symbol.ElementSymbol) Function(org.teiid.query.sql.symbol.Function) FakeDataManager(org.teiid.query.processor.FakeDataManager) HashMap(java.util.HashMap) Constant(org.teiid.query.sql.symbol.Constant) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) FunctionDescriptor(org.teiid.query.function.FunctionDescriptor) ExpressionSymbol(org.teiid.query.sql.symbol.ExpressionSymbol) HashMap(java.util.HashMap) Map(java.util.Map) Test(org.junit.Test)

Aggregations

FunctionDescriptor (org.teiid.query.function.FunctionDescriptor)27 Test (org.junit.Test)11 Constant (org.teiid.query.sql.symbol.Constant)11 Function (org.teiid.query.sql.symbol.Function)11 ElementSymbol (org.teiid.query.sql.symbol.ElementSymbol)9 ArrayList (java.util.ArrayList)7 FunctionLibrary (org.teiid.query.function.FunctionLibrary)7 List (java.util.List)6 FakeDataManager (org.teiid.query.processor.FakeDataManager)6 LanguageObject (org.teiid.query.sql.LanguageObject)5 Expression (org.teiid.query.sql.symbol.Expression)5 HashMap (java.util.HashMap)4 Map (java.util.Map)4 FunctionExecutionException (org.teiid.api.exception.query.FunctionExecutionException)3 BlockedException (org.teiid.common.buffer.BlockedException)3 ExpressionSymbol (org.teiid.query.sql.symbol.ExpressionSymbol)3 QueryResolverException (org.teiid.api.exception.query.QueryResolverException)2 TeiidComponentException (org.teiid.core.TeiidComponentException)2 TeiidProcessingException (org.teiid.core.TeiidProcessingException)2 Evaluator (org.teiid.query.eval.Evaluator)2