@Override
protected IScalarEvaluator createEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args)
throws AlgebricksException {
final ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
final SequenceBuilder sb = new SequenceBuilder();
final SequencePointable seq = new SequencePointable();
final SequencePointable seq2 = new SequencePointable();
final VoidPointable p = (VoidPointable) VoidPointable.FACTORY.createPointable();
final LongPointable longp = (LongPointable) LongPointable.FACTORY.createPointable();
return new AbstractTaggedValueArgumentScalarEvaluator(args) {
@Override
protected void evaluate(TaggedValuePointable[] args, IPointable result) throws SystemException {
try {
TaggedValuePointable tvp2 = args[1];
if (tvp2.getTag() != ValueTag.XS_INTEGER_TAG) {
throw new SystemException(ErrorCode.FORG0006);
}
tvp2.getValue(longp);
abvs.reset();
sb.reset(abvs);
TaggedValuePointable tvp1 = args[0];
TaggedValuePointable tvp3 = args[2];
if (tvp1.getTag() == ValueTag.SEQUENCE_TAG) {
tvp1.getValue(seq);
int seqLen = seq.getEntryCount();
if (longp.getLong() < 1) {
// Add to the beginning.
addArgumentToSequence(tvp3);
}
if (seqLen > 0) {
for (int j = 0; j < seqLen; ++j) {
if (longp.getLong() == j + 1) {
addArgumentToSequence(tvp3);
}
seq.getEntry(j, p);
sb.addItem(p);
}
}
if (longp.getLong() > seqLen) {
// Add to the end.
addArgumentToSequence(tvp3);
}
} else {
if (longp.getLong() <= 1) {
addArgumentToSequence(tvp3);
sb.addItem(tvp1);
} else {
sb.addItem(tvp1);
addArgumentToSequence(tvp3);
}
}
sb.finish();
result.set(abvs);
} catch (IOException e) {
throw new SystemException(ErrorCode.SYSE0001);
}
}
private void addArgumentToSequence(TaggedValuePointable tvp) throws IOException {
if (tvp.getTag() == ValueTag.SEQUENCE_TAG) {
tvp.getValue(seq2);
int seqLen = seq2.getEntryCount();
if (seqLen > 0) {
for (int j = 0; j < seqLen; ++j) {
seq2.getEntry(j, p);
sb.addItem(p);
}
}
} else {
sb.addItem(tvp);
}
}
};
}