use of org.teiid.core.types.ArrayImpl in project teiid by teiid.
the class FunctionDescriptor method invokeFunction.
/**
* Invoke the function described in the function descriptor, using the
* values provided. Return the result of the function.
* @param values Values that should match 1-to-1 with the types described in the
* function descriptor
* @param context
* @param functionTarget TODO
* @param fd Function descriptor describing the name and types of the arguments
* @return Result of invoking the function
*/
public Object invokeFunction(Object[] values, CommandContext context, Object functionTarget) throws FunctionExecutionException, BlockedException {
if (!isNullDependent()) {
for (int i = requiresContext ? 1 : 0; i < values.length; i++) {
if (values[i] == null) {
return null;
}
}
}
checkMethod();
// Invoke the method and return the result
try {
if (hasWrappedArgs) {
for (int i = 0; i < values.length; i++) {
Object val = values[i];
if (val != null && types[i] == DataTypeManager.DefaultDataClasses.VARBINARY) {
values[i] = ((BinaryType) val).getBytesDirect();
}
}
}
if (method.isVarArgs()) {
if (calledWithVarArgArrayParam) {
ArrayImpl av = (ArrayImpl) values[values.length - 1];
if (av != null) {
Object[] vals = av.getValues();
values[values.length - 1] = vals;
if (hasWrappedArgs && types[types.length - 1] == DataTypeManager.DefaultDataClasses.VARBINARY) {
vals = Arrays.copyOf(vals, vals.length);
for (int i = 0; i < vals.length; i++) {
if (vals[i] != null) {
vals[i] = ((BinaryType) vals[i]).getBytesDirect();
}
}
values[values.length - 1] = vals;
}
Class<?> arrayType = invocationMethod.getParameterTypes()[types.length - 1];
if (arrayType.getComponentType() != Object.class && vals.getClass() != arrayType) {
Object varArgs = Array.newInstance(arrayType.getComponentType(), vals.length);
for (int i = 0; i < vals.length; i++) {
Array.set(varArgs, i, vals[i]);
}
values[values.length - 1] = varArgs;
}
}
} else {
int i = invocationMethod.getParameterTypes().length;
Object[] newValues = Arrays.copyOf(values, i);
Object varArgs = null;
if (invocationMethod.getParameterTypes()[i - 1].getComponentType() != Object.class) {
int varArgCount = values.length - i + 1;
varArgs = Array.newInstance(invocationMethod.getParameterTypes()[i - 1].getComponentType(), varArgCount);
for (int j = 0; j < varArgCount; j++) {
Array.set(varArgs, j, values[i - 1 + j]);
}
} else {
varArgs = Arrays.copyOfRange(values, i - 1, values.length);
}
newValues[i - 1] = varArgs;
values = newValues;
}
}
Object result = null;
ClassLoader originalCL = Thread.currentThread().getContextClassLoader();
try {
if (this.classLoader != null) {
Thread.currentThread().setContextClassLoader(this.classLoader);
}
result = invocationMethod.invoke(functionTarget, values);
} finally {
Thread.currentThread().setContextClassLoader(originalCL);
}
if (context != null && getDeterministic().ordinal() <= Determinism.USER_DETERMINISTIC.ordinal()) {
context.setDeterminismLevel(getDeterministic());
}
return importValue(result, getReturnType());
} 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()));
} catch (TransformationException e) {
throw new FunctionExecutionException(e);
}
}
use of org.teiid.core.types.ArrayImpl in project teiid by teiid.
the class WindowFunctionProjectNode method nextBatchDirect.
@Override
protected TupleBatch nextBatchDirect() throws BlockedException, TeiidComponentException, TeiidProcessingException {
if (phase == Phase.COLLECT) {
saveInput();
phase = Phase.PROCESS;
partitionMapping = new STree[this.windows.size()];
valueMapping = new STree[this.windows.size()];
rowValueMapping = new STree[this.windows.size()];
}
if (phase == Phase.PROCESS) {
buildResults();
phase = Phase.OUTPUT;
}
if (phase == Phase.OUTPUT) {
if (outputTs == null) {
outputTs = tb.createIndexedTupleSource(true);
}
while (outputTs.hasNext()) {
List<?> tuple = outputTs.nextTuple();
Integer rowId = (Integer) tuple.get(tuple.size() - 1);
int size = getElements().size();
ArrayList<Object> outputRow = new ArrayList<Object>(size);
for (int i = 0; i < size; i++) {
outputRow.add(null);
}
for (int[] entry : passThrough) {
outputRow.set(entry[0], tuple.get(entry[1]));
}
List<Map.Entry<WindowSpecification, WindowSpecificationInfo>> specs = new ArrayList<Map.Entry<WindowSpecification, WindowSpecificationInfo>>(windows.entrySet());
for (int specIndex = 0; specIndex < specs.size(); specIndex++) {
Map.Entry<WindowSpecification, WindowSpecificationInfo> entry = specs.get(specIndex);
List<?> idRow = Arrays.asList(rowId);
List<WindowFunctionInfo> functions = entry.getValue().rowValuefunctions;
if (!functions.isEmpty()) {
List<?> valueRow = rowValueMapping[specIndex].find(idRow);
for (int i = 0; i < functions.size(); i++) {
WindowFunctionInfo wfi = functions.get(i);
Object value = valueRow.get(i + 1);
// the offset, default, and partition
if (wfi.function.getFunction().getAggregateFunction() == Type.LEAD || wfi.function.getFunction().getAggregateFunction() == Type.LAG) {
ArrayImpl array = (ArrayImpl) value;
Object[] args = array.getValues();
int offset = 1;
Object defaultValue = null;
if (args.length > 2) {
offset = (int) args[1];
if (args.length > 3) {
defaultValue = args[2];
}
}
List<?> newIdRow = Arrays.asList(rowId + (wfi.function.getFunction().getAggregateFunction() == Type.LAG ? -offset : offset));
List<?> newValueRow = rowValueMapping[specIndex].find(newIdRow);
if (newValueRow == null) {
value = defaultValue;
} else {
Object[] newArgs = ((ArrayImpl) newValueRow.get(i + 1)).getValues();
// make sure it's the same partition
if (args[args.length - 1].equals(newArgs[newArgs.length - 1])) {
value = newArgs[0];
} else {
value = defaultValue;
}
}
}
outputRow.set(wfi.outputIndex, value);
}
}
functions = entry.getValue().functions;
if (!functions.isEmpty()) {
if (partitionMapping[specIndex] != null) {
idRow = partitionMapping[specIndex].find(idRow);
idRow = idRow.subList(1, 2);
} else {
idRow = SINGLE_VALUE_ID;
}
List<?> valueRow = valueMapping[specIndex].find(idRow);
for (int i = 0; i < functions.size(); i++) {
WindowFunctionInfo wfi = functions.get(i);
outputRow.set(wfi.outputIndex, valueRow.get(i + 1));
}
}
}
this.addBatchRow(outputRow);
if (this.isBatchFull()) {
return pullBatch();
}
}
terminateBatches();
}
return this.pullBatch();
}
use of org.teiid.core.types.ArrayImpl in project teiid by teiid.
the class XMLTableNode method processRow.
private List<?> processRow() throws ExpressionEvaluationException, BlockedException, TeiidComponentException, TeiidProcessingException {
List<Object> tuple = new ArrayList<Object>(projectedColumns.size());
for (XMLColumn proColumn : projectedColumns) {
if (proColumn.isOrdinal()) {
if (rowCount > Integer.MAX_VALUE) {
throw new TeiidRuntimeException(new TeiidProcessingException(QueryPlugin.Event.TEIID31174, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31174)));
}
tuple.add((int) rowCount);
} else {
try {
XPathExpression path = proColumn.getPathExpression();
XPathDynamicContext dynamicContext = path.createDynamicContext(item);
final SequenceIterator pathIter = path.iterate(dynamicContext);
Item colItem = pathIter.next();
if (colItem == null) {
if (proColumn.getDefaultExpression() != null) {
tuple.add(getEvaluator(Collections.emptyMap()).evaluate(proColumn.getDefaultExpression(), null));
} else {
tuple.add(null);
}
continue;
}
if (proColumn.getSymbol().getType() == DataTypeManager.DefaultDataClasses.XML) {
SequenceIterator pushBack = new PushBackSequenceIterator(pathIter, colItem);
XMLType value = table.getXQueryExpression().createXMLType(pushBack, this.getBufferManager(), false, getContext());
tuple.add(value);
continue;
}
if (proColumn.getSymbol().getType().isArray()) {
ArrayList<Object> vals = new ArrayList<Object>();
vals.add(getValue(proColumn.getSymbol().getType().getComponentType(), colItem, this.table.getXQueryExpression().getConfig(), getContext()));
Item next = null;
while ((next = pathIter.next()) != null) {
vals.add(getValue(proColumn.getSymbol().getType().getComponentType(), next, this.table.getXQueryExpression().getConfig(), getContext()));
}
Object value = new ArrayImpl(vals.toArray((Object[]) Array.newInstance(proColumn.getSymbol().getType().getComponentType(), vals.size())));
tuple.add(value);
continue;
} else if (pathIter.next() != null) {
throw new TeiidProcessingException(QueryPlugin.Event.TEIID30171, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30171, proColumn.getName()));
}
Object value = getValue(proColumn.getSymbol().getType(), colItem, this.table.getXQueryExpression().getConfig(), getContext());
tuple.add(value);
} catch (XPathException e) {
throw new TeiidProcessingException(QueryPlugin.Event.TEIID30172, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30172, proColumn.getName()));
}
}
}
item = null;
return tuple;
}
use of org.teiid.core.types.ArrayImpl in project teiid by teiid.
the class DependentProcedureCriteriaProcessor method prepareNextCommand.
protected boolean prepareNextCommand(VariableContext context) throws BlockedException, TeiidComponentException, TeiidProcessingException {
if (this.critInProgress == null) {
critInProgress = prepareCriteria();
}
for (int j = 0; j < inputReferences.size(); j++) {
Reference ref = (Reference) inputReferences.get(j);
context.remove(ref.getExpression());
}
if (critInProgress == QueryRewriter.FALSE_CRITERIA) {
critInProgress = null;
consumedCriteria();
return false;
}
boolean validRow = true;
for (Iterator<Criteria> i = Criteria.separateCriteriaByAnd(critInProgress).iterator(); i.hasNext() && validRow; ) {
Criteria crit = i.next();
Object value = null;
boolean nullAllowed = false;
Reference parameter = null;
if (crit instanceof IsNullCriteria) {
parameter = (Reference) ((IsNullCriteria) crit).getExpression();
nullAllowed = true;
} else if (crit instanceof CompareCriteria) {
CompareCriteria compare = (CompareCriteria) crit;
value = compare.getRightExpression();
if (compare.getLeftExpression() instanceof Array) {
Array array = (Array) compare.getLeftExpression();
if (value instanceof Expression) {
value = eval.evaluate((Expression) value, null);
}
if (value == null) {
validRow = false;
break;
}
ArrayImpl valueArray = (ArrayImpl) value;
for (int j = 0; j < array.getExpressions().size(); j++) {
validRow = setParam(context, valueArray.getValues()[j], nullAllowed, (Reference) array.getExpressions().get(j));
if (!validRow) {
break;
}
}
continue;
}
parameter = (Reference) compare.getLeftExpression();
} else {
// $NON-NLS-1$
Assertion.failed("Unknown predicate type");
}
validRow = setParam(context, value, nullAllowed, parameter);
}
critInProgress = null;
consumedCriteria();
if (!validRow) {
return false;
}
for (int j = 0; j < inputReferences.size(); j++) {
Object defaultValue = inputDefaults.get(j);
Reference ref = (Reference) inputReferences.get(j);
if (defaultValue != null && !context.containsVariable(ref.getExpression())) {
context.setValue(ref.getExpression(), defaultValue);
}
}
return true;
}
use of org.teiid.core.types.ArrayImpl in project teiid by teiid.
the class DependentValueSource method getValueIterator.
/**
* @throws TeiidComponentException
* @see org.teiid.query.sql.util.ValueIteratorSource#getValueIterator(org.teiid.query.sql.symbol.Expression)
*/
public TupleSourceValueIterator getValueIterator(Expression valueExpression) throws TeiidComponentException {
IndexedTupleSource its = buffer.createIndexedTupleSource();
int index = 0;
if (valueExpression != null) {
if (valueExpression instanceof Array) {
final Array array = (Array) valueExpression;
List<Expression> exprs = array.getExpressions();
final int[] indexes = new int[exprs.size()];
for (int i = 0; i < exprs.size(); i++) {
indexes[i] = getIndex(exprs.get(i));
}
return new TupleSourceValueIterator(its, index) {
@Override
public Object next() throws TeiidComponentException {
List<?> tuple = super.nextTuple();
Object[] a = (Object[]) java.lang.reflect.Array.newInstance(array.getComponentType(), indexes.length);
for (int i = 0; i < indexes.length; i++) {
a[i] = tuple.get(indexes[i]);
if (a[i] == null) {
// TODO: this is a hack
return null;
}
}
return new ArrayImpl(a);
}
};
}
index = getIndex(valueExpression);
}
return new TupleSourceValueIterator(its, index);
}
Aggregations