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;
}
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);
}
}
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()));
}
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);
}
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);
}
Aggregations