private void helpFindFunction(String fname, Class<?>[] types, FunctionDescriptor expected) { FunctionDescriptor actual = library.findFunction(fname, types); assertEquals("Function names do not match: ", expected.getName().toLowerCase(), actual.getName().toLowerCase()); //$NON-NLS-1$ assertEquals("Arg lengths do not match: ", expected.getTypes().length, actual.getTypes().length); //$NON-NLS-1$ }
@Override public void addInputDirect(List<?> tuple, CommandContext commandContext) throws TeiidComponentException, TeiidProcessingException { if (values == null) { values = new Object[argIndexes.length + (fd.requiresContext()?1:0)]; } if (fd.requiresContext()) { values[0] = commandContext; } for (int i = 0; i < argIndexes.length; i++) { values[i + (fd.requiresContext()?1:0)] = tuple.get(argIndexes[i]); } fd.invokeFunction(values, commandContext, instance); }
/** * Return a copy of the given FunctionDescriptor with the sepcified return type. * @param fd FunctionDescriptor to be copied. * @param returnType The return type to apply to the copied FunctionDescriptor. * @return The copy of FunctionDescriptor. */ public FunctionDescriptor copyFunctionChangeReturnType(FunctionDescriptor fd, Class<?> returnType) { if(fd != null) { FunctionDescriptor fdImpl = fd; FunctionDescriptor copy = fdImpl.clone(); copy.setReturnType(returnType); return copy; } return fd; }
if (fd.getMethod().isVarArgs() && fd.getTypes().length == types.length && library.isVarArgArrayParam(fd.getMethod(), types, types.length - 1, fd.getTypes()[types.length - 1])) { fd = fd.clone(); fd.setCalledWithVarArgArrayParam(true); if(fd.isSystemFunction(FunctionLibrary.CONVERT) || fd.isSystemFunction(FunctionLibrary.CAST)) { String dataType = (String) ((Constant)args[1]).getValue(); Class<?> dataTypeClass = metadata.getDataTypeClass(dataType); } else if(fd.isSystemFunction(FunctionLibrary.LOOKUP)) { ResolverUtil.ResolvedLookup lookup = ResolverUtil.resolveLookup(function, metadata); fd = library.copyFunctionChangeReturnType(fd, lookup.getReturnElement().getType()); } else if (fd.isSystemFunction(FunctionLibrary.ARRAY_GET)) { if (args[0].getType() != null && args[0].getType().isArray()) { fd = library.copyFunctionChangeReturnType(fd, args[0].getType().getComponentType()); } else if (Boolean.valueOf(fd.getMethod().getProperty(TEIID_PASS_THROUGH_TYPE, false))) { function.setType(fd.getReturnType()); if (CoreConstants.SYSTEM_MODEL.equals(fd.getSchema())) { if (StringUtil.startsWithIgnoreCase(function.getName(), SYS_PREFIX)) { function.setName(function.getName().substring(SYS_PREFIX.length())); && !StringUtil.startsWithIgnoreCase(function.getName(), function.getFunctionDescriptor().getSchema() + ElementSymbol.SEPARATOR)) { function.setName(function.getFunctionDescriptor().getSchema() + ElementSymbol.SEPARATOR + function.getName());
if (!isNullDependent()) { for (int i = requiresContext?1:0; i < values.length; i++) { if (values[i] == null) { checkMethod(); Thread.currentThread().setContextClassLoader(originalCL); if (context != null && getDeterministic().ordinal() <= Determinism.USER_DETERMINISTIC.ordinal()) { context.setDeterminismLevel(getDeterministic()); return importValue(result, getReturnType(), context); } catch(ArithmeticException e) { throw new FunctionExecutionException(QueryPlugin.Event.TEIID30384, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30384, getFullName())); } catch(InvocationTargetException e) { if (e.getTargetException() instanceof BlockedException) { throw (BlockedException)e.getTargetException(); throw new FunctionExecutionException(QueryPlugin.Event.TEIID30384, e.getTargetException(), QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30384, getFullName())); } catch(IllegalAccessException e) { throw new FunctionExecutionException(QueryPlugin.Event.TEIID30385, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30385, method.toString()));
int start = 0; if (fd.requiresContext()) { values = new Object[args.length+1]; values[0] = context; if (fd.getPushdown() == PushDown.MUST_PUSHDOWN) { try { return evaluatePushdown(function, tuple, values); if (fd.getProcedure() != null) { try { return evaluateProcedure(function, tuple, values); return fd.invokeFunction(values, context, null);
Object[] values) throws TeiidComponentException, TeiidProcessingException { final FunctionDescriptor fd = function.getFunctionDescriptor(); if (fd.getMethod() == null) { throw new FunctionExecutionException(QueryPlugin.Event.TEIID30341, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30341, fd.getFullName())); if (fd.getMethod().getParent() == null || !fd.getMethod().getParent().isPhysical()) { if (caps.supportsCapability(Capability.SELECT_WITHOUT_FROM) && caps.supportsFunction(fd.getMethod().getFullName())) { schema = mmd.getName(); break; throw new FunctionExecutionException(QueryPlugin.Event.TEIID30341, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30341, fd.getFullName())); if (!CapabilitiesUtil.supports(Capability.SELECT_WITHOUT_FROM, fd.getMethod().getParent(), context.getMetadata(), context.getQueryProcessorFactory().getCapabiltiesFinder())) { if (elements != null) { Integer index = (Integer) elements.get(function); throw new FunctionExecutionException(QueryPlugin.Event.TEIID30341, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30341, fd.getFullName())); schema = fd.getSchema(); command.setProcessorPlan(new SimpleProcessorPlan(command, schema, fd, Arrays.asList(new Constant(null, fd.getReturnType())))); } else { ((Function)((ExpressionSymbol)ss.getCommand().getProjectedSymbols().get(0)).getExpression()).setArgs(functionArgs);
Constant const2 = (Constant)rightExpr; try { Object result = descriptor.invokeFunction(new Object[] { const2.getValue(), const1.getValue() }, null, this.context ); combinedConst = new Constant(result, descriptor.getReturnType()); } catch(FunctionExecutionException e) { throw new QueryValidatorException(QueryPlugin.Event.TEIID30373, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30373, e.getMessage())); Function conversion = new Function(descriptor.getName(), new Expression[] { rightExpr, const1 }); conversion.setType(leftExpr.getType()); conversion.setFunctionDescriptor(descriptor);
private boolean containsNullDependent(Collection<AggregateSymbol> aggregates) { for (AggregateSymbol aggregateSymbol : aggregates) { //we don't consider count here as we dealing with the original aggregates, not the mapped expressions if (aggregateSymbol.getFunctionDescriptor() != null && aggregateSymbol.getFunctionDescriptor().isNullDependent()) { return true; } } return false; }
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); } }
@Override public void visit(Function f) { FunctionDescriptor fd = f.getFunctionDescriptor(); if (f.isEval()) { try { if (modelId != null && fd.getPushdown() == PushDown.MUST_PUSHDOWN && fd.getMethod() != null && CapabilitiesUtil.isSameConnector(modelId, fd.getMethod().getParent(), metadata, capFinder)) { f.setEval(false); } else if (fd.getDeterministic() == Determinism.NONDETERMINISTIC && CapabilitiesUtil.supportsScalarFunction(modelId, f, metadata, capFinder)) { f.setEval(false); } } catch (QueryMetadataException e) { throw new TeiidRuntimeException(e); } catch (TeiidComponentException e) { throw new TeiidRuntimeException(e); } } } @Override
FunctionDescriptor result = new FunctionDescriptor(method, types, outputType, invocationMethod, requiresContext, source.getClassLoader()); if (validateClass && method.getAggregateAttributes() != null && (method.getPushdown() == PushDown.CAN_PUSHDOWN || method.getPushdown() == PushDown.CANNOT_PUSHDOWN)) { try { result.newInstance(); } catch (FunctionExecutionException e) { result.setHasWrappedArgs(hasWrappedArg); return result;
/** * Insert a conversion function at specified index. This is a convenience * method to insert a conversion into the function tree. * @param index Argument index to insert conversion function at * @param functionDescriptor Conversion function descriptor */ public void insertConversion(int index, FunctionDescriptor functionDescriptor) { // Get target type for conversion Class<?> t = functionDescriptor.getReturnType(); String typeName = DataTypeManager.getDataTypeName(t); // Pull old expression at index Expression newArg[] = new Expression[] { args[index], new Constant(typeName) }; // Replace old expression with new expression, using old as arg Function func = new Function(functionDescriptor.getName(), newArg); args[index] = func; // Set function descriptor and type of new function func.setFunctionDescriptor(functionDescriptor); func.setType(t); func.makeImplicit(); }
AggregateFunction translate(AggregateSymbol symbol) { List<org.teiid.language.Expression> params = new ArrayList<org.teiid.language.Expression>(symbol.getArgs().length); for (Expression expression : symbol.getArgs()) { params.add(translate(expression)); } String name = symbol.getAggregateFunction().name(); if (symbol.getFunctionDescriptor() != null) { name = Symbol.getShortName(symbol.getFunctionDescriptor().getName()); } else if (symbol.getAggregateFunction() == AggregateSymbol.Type.USER_DEFINED) { name = symbol.getName(); } else if (symbol.getAggregateFunction() == Type.COUNT_BIG && !supportsCountBig) { name = Type.COUNT.name(); } AggregateFunction af = new AggregateFunction(name, symbol.isDistinct(), params, symbol.getType()); af.setCondition(translate(symbol.getCondition())); af.setOrderBy(translate(symbol.getOrderBy(), false)); if (symbol.getFunctionDescriptor() != null) { af.setMetadataObject(symbol.getFunctionDescriptor().getMethod()); } return af; }
private void validateAggregateFunctionEvaluation(AggregateSymbol as) throws QueryPlannerException { if (as.getFunctionDescriptor() != null && as.getFunctionDescriptor().getPushdown() == PushDown.MUST_PUSHDOWN) { throw new QueryPlannerException(QueryPlugin.Event.TEIID31211, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31211, as.getFunctionDescriptor().getFullName())); } }
public void visit(Function obj) { if (FunctionLibrary.LOOKUP.equalsIgnoreCase(obj.getName())) { try { ResolverUtil.ResolvedLookup lookup = ResolverUtil.resolveLookup(obj, this.getMetadata()); List<Symbol> symbols = new LinkedList<Symbol>(); symbols.add(lookup.getGroup()); symbols.add(lookup.getKeyElement()); symbols.add(lookup.getReturnElement()); validateEntitlements(symbols, DataPolicy.PermissionType.READ, Context.QUERY); } catch (TeiidComponentException e) { handleException(e, obj); } catch (TeiidProcessingException e) { handleException(e, obj); } } else { String schema = obj.getFunctionDescriptor().getSchema(); if (schema != null && !isSystemSchema(schema)) { Map<String, Function> map = new HashMap<String, Function>(); map.put(obj.getFunctionDescriptor().getFullName(), obj); validateEntitlements(PermissionType.EXECUTE, Context.FUNCTION, map); } } }
if (!(obj instanceof AggregateSymbol)) { Function f = (Function)obj; if (f.getFunctionDescriptor().getPushdown() != PushDown.MUST_PUSHDOWN && f.getFunctionDescriptor().getDeterministic() != Determinism.NONDETERMINISTIC) { return; //don't need to consider
private void checkMethod() throws FunctionExecutionException { // If descriptor is missing invokable method, find this VM's descriptor // give name and types from fd if(invocationMethod == null) { throw new FunctionExecutionException(QueryPlugin.Event.TEIID30382, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30382, getFullName())); } }