@Override protected IScalarEvaluator createEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) throws AlgebricksException { final ArrayBackedValueStorage abvs = new ArrayBackedValueStorage(); final SequenceBuilder sb = new SequenceBuilder(); final SequencePointable seq = (SequencePointable) SequencePointable.FACTORY.createPointable(); final VoidPointable p = (VoidPointable) VoidPointable.FACTORY.createPointable(); return new AbstractTaggedValueArgumentScalarEvaluator(args) { @Override protected void evaluate(TaggedValuePointable[] args, IPointable result) throws SystemException { try { abvs.reset(); sb.reset(abvs); for (int i = 0; i < args.length; ++i) { TaggedValuePointable tvp = args[i]; if (tvp.getTag() == ValueTag.SEQUENCE_TAG) { tvp.getValue(seq); int seqLen = seq.getEntryCount(); for (int j = 0; j < seqLen; ++j) { seq.getEntry(j, p); sb.addItem(p); } } else { sb.addItem(tvp); } } sb.finish(); result.set(abvs); } catch (IOException e) { throw new SystemException(ErrorCode.SYSE0001); } } }; }
@Override protected IScalarEvaluator createEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) throws AlgebricksException { final UTF8StringPointable stringp1 = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable(); final UTF8StringPointable stringp2 = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable(); final UTF8StringPointable stringp3 = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable(); final ICharacterIterator charIterator1 = new UTF8StringCharacterIterator(stringp1); final ICharacterIterator charIterator2 = new UTF8StringCharacterIterator(stringp2); final SequencePointable seqp = (SequencePointable) SequencePointable.FACTORY.createPointable(); final TaggedValuePointable tvp = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable(); return new AbstractTaggedValueArgumentScalarEvaluator(args) { @Override protected void evaluate(TaggedValuePointable[] args, IPointable result) throws SystemException { // Default result is false. byte[] booleanResult = new byte[2]; booleanResult[0] = ValueTag.XS_BOOLEAN_TAG; booleanResult[1] = 0; TaggedValuePointable tvp1 = args[0]; TaggedValuePointable tvp2 = args[1]; // Only accept strings as input. if (tvp1.getTag() == ValueTag.SEQUENCE_TAG) { tvp1.getValue(seqp); if (seqp.getEntryCount() == 0) { XDMConstants.setEmptyString(tvp); tvp.getValue(stringp1); } else { throw new SystemException(ErrorCode.FORG0006); } } else { if (!FunctionHelper.isDerivedFromString(tvp1.getTag())) { throw new SystemException(ErrorCode.FORG0006); } tvp1.getValue(stringp1); } if (tvp2.getTag() == ValueTag.SEQUENCE_TAG) { tvp2.getValue(seqp); if (seqp.getEntryCount() == 0) { XDMConstants.setEmptyString(tvp); tvp.getValue(stringp2); } else { throw new SystemException(ErrorCode.FORG0006); } } else { if (!FunctionHelper.isDerivedFromString(tvp2.getTag())) { throw new SystemException(ErrorCode.FORG0006); } tvp2.getValue(stringp2); } int stringLength1 = stringp1.getStringLength(); int stringLength2 = stringp2.getStringLength(); charIterator1.reset(); charIterator2.reset(); // Third parameter is optional. if (args.length > 2) { TaggedValuePointable tvp3 = args[2]; if (!FunctionHelper.isDerivedFromString(tvp3.getTag())) { throw new SystemException(ErrorCode.FORG0006); } tvp3.getValue(stringp3); } // TODO use the third value as collation int stringCharOffset = stringLength1 - stringLength2; // Only check if stringp2 can fit into stringp1. if (stringCharOffset >= 0) { // Only need to run comparisons if they both have a non empty string. if (stringLength1 > 0 && stringLength2 > 0) { // Move string one's cursor for comparison for (; stringCharOffset > 0; --stringCharOffset) { charIterator1.next(); } int c1; int c2; while (true) { c1 = charIterator1.next(); c2 = charIterator2.next(); if (c1 != c2) { // Characters do not match break; } if (c1 == ICharacterIterator.EOS_CHAR && c2 == ICharacterIterator.EOS_CHAR) { // Checked the full length of search string. booleanResult[1] = 1; break; } } } else if (stringLength2 == 0) { booleanResult[1] = 1; } } result.set(booleanResult, 0, 2); } }; }