Dmitry Lychagin has uploaded a new change for review. https://asterix-gerrit.ics.uci.edu/2797
Change subject: [ASTERIXDB-2419][COMP] Replacement limit in regexp_replace() ...................................................................... [ASTERIXDB-2419][COMP] Replacement limit in regexp_replace() - user model changes: yes - storage format changes: no - interface changes: no Details: - Support replacement limit parameter in regexp_replace() Change-Id: I9bcf633ea6af1ade49daffec4784a70355c08a0e --- A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_replace/regexp_replace.6.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_replace/regexp_replace.6.adm M asterixdb/asterix-doc/src/main/markdown/builtins/2_string_common.md M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringIntToStringTypeComputer.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java R asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceWithFlagDescriptor.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/utils/RegExpMatcher.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java 9 files changed, 161 insertions(+), 69 deletions(-) git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/97/2797/1 diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_replace/regexp_replace.6.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_replace/regexp_replace.6.query.sqlpp new file mode 100644 index 0000000..94deadc --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_replace/regexp_replace.6.query.sqlpp @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +{ + 'result1':regexp_replace('abracadabra','bra','kkk',-1), + 'result2':regexp_replace('abracadabra','bra','kkk',0), + 'result3':regexp_replace('abracadabra','bra','kkk',1), + 'result4':regexp_replace('abracadabra_abracadabra','bra','kkk',2), + 'result5':regexp_replace('abracadabra_abracadabra','bra','kkk',5) +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_replace/regexp_replace.6.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_replace/regexp_replace.6.adm new file mode 100644 index 0000000..6fc838d --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_replace/regexp_replace.6.adm @@ -0,0 +1 @@ +{ "result1": "abracadabra", "result2": "abracadabra", "result3": "akkkcadabra", "result4": "akkkcadakkk_abracadabra", "result5": "akkkcadakkk_akkkcadakkk" } \ No newline at end of file diff --git a/asterixdb/asterix-doc/src/main/markdown/builtins/2_string_common.md b/asterixdb/asterix-doc/src/main/markdown/builtins/2_string_common.md index 6599dc3..1f9ac19 100644 --- a/asterixdb/asterix-doc/src/main/markdown/builtins/2_string_common.md +++ b/asterixdb/asterix-doc/src/main/markdown/builtins/2_string_common.md @@ -329,6 +329,7 @@ * Syntax: regexp_replace(string, string_pattern, string_replacement[, string_flags]) + regexp_replace(string, string_pattern, string_replacement[, replacement_limit]) * Checks whether the string `string` matches the given regular expression pattern `string_pattern` (a Java regular expression pattern), @@ -339,6 +340,7 @@ * `string_replacement` : a pattern `string` to be used as the replacement, * `string_flag` : (Optional) a `string` with flags to be used during replace. * The following modes are enabled with these flags: dotall (s), multiline (m), case_insensitive (i), and comments and whitespace (x). + * `replacement_limit`: (Optional) an `integer` specifying the maximum number of replacements to make * Return Value: * Returns a `string` that is obtained after the replacements, * `missing` if any argument is a `missing` value, diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java index 8f24864..4afeef1 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java @@ -1273,7 +1273,8 @@ addFunction(STRING_REGEXP_POSITION, StringInt32TypeComputer.INSTANCE, true); addFunction(STRING_REGEXP_POSITION_WITH_FLAG, StringInt32TypeComputer.INSTANCE, true); addFunction(STRING_REGEXP_REPLACE, StringStringTypeComputer.INSTANCE, true); - addFunction(STRING_REGEXP_REPLACE_WITH_FLAG, StringStringTypeComputer.INSTANCE, true); + addFunction(STRING_REGEXP_REPLACE_WITH_FLAG, + StringIntToStringTypeComputer.INSTANCE_STRING_REGEXP_REPLACE_WITH_FLAG, true); addFunction(STRING_REPLACE, StringStringTypeComputer.INSTANCE, true); addFunction(STRING_REPLACE_WITH_LIMIT, StringIntToStringTypeComputer.INSTANCE_TRIPLE_STRING, true); addFunction(STRING_REVERSE, StringStringTypeComputer.INSTANCE, true); diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringIntToStringTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringIntToStringTypeComputer.java index 466ba4d..0f376ba 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringIntToStringTypeComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringIntToStringTypeComputer.java @@ -18,6 +18,9 @@ */ package org.apache.asterix.om.typecomputer.impl; +import java.util.EnumSet; +import java.util.Set; + import org.apache.asterix.om.exceptions.TypeMismatchException; import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; import org.apache.asterix.om.types.ATypeTag; @@ -28,40 +31,73 @@ import org.apache.hyracks.api.exceptions.SourceLocation; public class StringIntToStringTypeComputer extends AbstractResultTypeComputer { - public static final StringIntToStringTypeComputer INSTANCE = new StringIntToStringTypeComputer(1); + public static final StringIntToStringTypeComputer INSTANCE = new StringIntToStringTypeComputer(0, 0, 1, 1); - public static final StringIntToStringTypeComputer INSTANCE_TRIPLE_STRING = new StringIntToStringTypeComputer(3); + public static final StringIntToStringTypeComputer INSTANCE_TRIPLE_STRING = + new StringIntToStringTypeComputer(0, 2, 3, 3); - private final int stringArgCount; + public static final StringIntToStringTypeComputer INSTANCE_STRING_REGEXP_REPLACE_WITH_FLAG = + new StringIntToStringTypeComputer(0, 3, 3, 3); - public StringIntToStringTypeComputer(int stringArgCount) { - this.stringArgCount = stringArgCount; + private final int stringArgIdxMin; + + private final int stringArgIdxMax; + + private final int intArgIdxMin; + + private final int intArgIdxMax; + + public StringIntToStringTypeComputer(int stringArgIdxMin, int stringArgIdxMax, int intArgIdxMin, int intArgIdxMax) { + this.stringArgIdxMin = stringArgIdxMin; + this.stringArgIdxMax = stringArgIdxMax; + this.intArgIdxMin = intArgIdxMin; + this.intArgIdxMax = intArgIdxMax; } @Override public void checkArgType(String funcName, int argIndex, IAType type, SourceLocation sourceLoc) throws AlgebricksException { ATypeTag tag = type.getTypeTag(); - if (argIndex < stringArgCount) { - if (tag != ATypeTag.STRING) { - throw new TypeMismatchException(sourceLoc, funcName, argIndex, tag, ATypeTag.STRING); + boolean expectedStringType = false; + if (stringArgIdxMin <= argIndex && argIndex <= stringArgIdxMax) { + if (tag == ATypeTag.STRING) { + return; } - } else { + expectedStringType = true; + } + + boolean expectedIntType = false; + if (intArgIdxMin <= argIndex && argIndex <= intArgIdxMax) { switch (tag) { case TINYINT: case SMALLINT: case INTEGER: case BIGINT: - break; - default: - throw new TypeMismatchException(sourceLoc, funcName, argIndex, tag, ATypeTag.TINYINT, - ATypeTag.SMALLINT, ATypeTag.INTEGER, ATypeTag.BIGINT); + return; } + expectedIntType = true; } + + throw new TypeMismatchException(sourceLoc, funcName, argIndex, tag, + getExpectedTypes(expectedStringType, expectedIntType)); } @Override public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException { return BuiltinType.ASTRING; } + + private ATypeTag[] getExpectedTypes(boolean expectedStringType, boolean expectedIntType) { + Set<ATypeTag> expectedTypes = EnumSet.noneOf(ATypeTag.class); + if (expectedStringType) { + expectedTypes.add(ATypeTag.STRING); + } + if (expectedIntType) { + expectedTypes.add(ATypeTag.TINYINT); + expectedTypes.add(ATypeTag.SMALLINT); + expectedTypes.add(ATypeTag.INTEGER); + expectedTypes.add(ATypeTag.BIGINT); + } + return expectedTypes.toArray(new ATypeTag[0]); + } } diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java index 5de007b..8a66e46 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java @@ -47,16 +47,16 @@ private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); private DataOutput dout = resultStorage.getDataOutput(); - private IPointable array0 = new VoidPointable(); - private IPointable array1 = new VoidPointable(); - private IPointable array2 = new VoidPointable(); - private IPointable array3 = new VoidPointable(); + private IPointable ptr0 = new VoidPointable(); + private IPointable ptr1 = new VoidPointable(); + private IPointable ptr2 = new VoidPointable(); + private IPointable ptr3 = new VoidPointable(); private IScalarEvaluator eval0; private IScalarEvaluator eval1; private IScalarEvaluator eval2; private IScalarEvaluator eval3; - private final FunctionIdentifier funcID; + protected final FunctionIdentifier funcID; protected final SourceLocation sourceLoc; private AMutableString resultBuffer = new AMutableString(""); @@ -64,10 +64,10 @@ private ISerializerDeserializer strSerde = SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ASTRING); - private final UTF8StringPointable strPtr1st = new UTF8StringPointable(); - private final UTF8StringPointable strPtr2nd = new UTF8StringPointable(); - private final UTF8StringPointable strPtr3rd = new UTF8StringPointable(); - private final UTF8StringPointable strPtr4th = new UTF8StringPointable(); + private final UTF8StringPointable strPtr0 = new UTF8StringPointable(); + private final UTF8StringPointable strPtr1 = new UTF8StringPointable(); + private final UTF8StringPointable strPtr2 = new UTF8StringPointable(); + private final UTF8StringPointable strPtr3 = new UTF8StringPointable(); public AbstractQuadStringStringEval(IHyracksTaskContext context, IScalarEvaluatorFactory eval0, IScalarEvaluatorFactory eval1, IScalarEvaluatorFactory eval2, IScalarEvaluatorFactory eval3, @@ -83,48 +83,19 @@ @SuppressWarnings("unchecked") @Override public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException { - eval0.evaluate(tuple, array0); - eval1.evaluate(tuple, array1); - eval2.evaluate(tuple, array2); - eval3.evaluate(tuple, array3); + eval0.evaluate(tuple, ptr0); + eval1.evaluate(tuple, ptr1); + eval2.evaluate(tuple, ptr2); + eval3.evaluate(tuple, ptr3); - byte[] bytes0 = array0.getByteArray(); - byte[] bytes1 = array1.getByteArray(); - byte[] bytes2 = array2.getByteArray(); - byte[] bytes3 = array3.getByteArray(); - - int start0 = array0.getStartOffset(); - int start1 = array1.getStartOffset(); - int start2 = array2.getStartOffset(); - int start3 = array3.getStartOffset(); - - int len0 = array0.getLength(); - int len1 = array1.getLength(); - int len2 = array2.getLength(); - int len3 = array3.getLength(); + processArgument(0, ptr0, strPtr0); + processArgument(1, ptr1, strPtr1); + processArgument(2, ptr2, strPtr2); + processArgument(3, ptr3, strPtr3); resultStorage.reset(); - // Type check. - if (bytes0[start0] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) { - throw new TypeMismatchException(sourceLoc, funcID, 0, bytes0[start0], ATypeTag.SERIALIZED_STRING_TYPE_TAG); - } - if (bytes1[start1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) { - throw new TypeMismatchException(sourceLoc, funcID, 1, bytes1[start1], ATypeTag.SERIALIZED_STRING_TYPE_TAG); - } - if (bytes2[start2] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) { - throw new TypeMismatchException(sourceLoc, funcID, 2, bytes2[start2], ATypeTag.SERIALIZED_STRING_TYPE_TAG); - } - if (bytes3[start3] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) { - throw new TypeMismatchException(sourceLoc, funcID, 3, bytes1[start3], ATypeTag.SERIALIZED_STRING_TYPE_TAG); - } - - strPtr1st.set(bytes0, start0 + 1, len0); - strPtr2nd.set(bytes1, start1 + 1, len1); - strPtr3rd.set(bytes2, start2 + 1, len2); - strPtr4th.set(bytes3, start3 + 1, len3); - try { - String res = compute(strPtr1st, strPtr2nd, strPtr3rd, strPtr4th); + String res = compute(strPtr0, strPtr1, strPtr2, strPtr3); resultBuffer.setValue(res); strSerde.serialize(resultBuffer, dout); } catch (IOException e) { @@ -133,7 +104,19 @@ result.set(resultStorage); } + protected void processArgument(int argIdx, IPointable argPtr, UTF8StringPointable outStrPtr) + throws HyracksDataException { + byte[] bytes = argPtr.getByteArray(); + int start = argPtr.getStartOffset(); + // Type check. + if (bytes[start] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) { + throw new TypeMismatchException(sourceLoc, funcID, argIdx, bytes[start], + ATypeTag.SERIALIZED_STRING_TYPE_TAG); + } + int len = argPtr.getLength(); + outStrPtr.set(bytes, start + 1, len); + } + protected abstract String compute(UTF8StringPointable strPtr1st, UTF8StringPointable strPtr2nd, UTF8StringPointable strPtr3rd, UTF8StringPointable strPtr4th) throws IOException; - } diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceWithFlagsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceWithFlagDescriptor.java similarity index 61% rename from asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceWithFlagsDescriptor.java rename to asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceWithFlagDescriptor.java index d901a22..707865c 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceWithFlagsDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceWithFlagDescriptor.java @@ -23,6 +23,8 @@ import org.apache.asterix.om.functions.BuiltinFunctions; import org.apache.asterix.om.functions.IFunctionDescriptor; import org.apache.asterix.om.functions.IFunctionDescriptorFactory; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.asterix.om.types.hierachy.ATypeHierarchy; import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; import org.apache.asterix.runtime.evaluators.functions.utils.RegExpMatcher; import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; @@ -30,15 +32,16 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; import org.apache.hyracks.api.context.IHyracksTaskContext; import org.apache.hyracks.api.exceptions.HyracksDataException; +import org.apache.hyracks.data.std.api.IPointable; import org.apache.hyracks.data.std.primitive.UTF8StringPointable; -public class StringRegExpReplaceWithFlagsDescriptor extends AbstractScalarFunctionDynamicDescriptor { +public class StringRegExpReplaceWithFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor { private static final long serialVersionUID = 1L; public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { @Override public IFunctionDescriptor createFunctionDescriptor() { - return new StringRegExpReplaceWithFlagsDescriptor(); + return new StringRegExpReplaceWithFlagDescriptor(); } }; @@ -50,14 +53,40 @@ @Override public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws HyracksDataException { return new AbstractQuadStringStringEval(ctx, args[0], args[1], args[2], args[3], - StringRegExpReplaceWithFlagsDescriptor.this.getIdentifier(), sourceLoc) { + StringRegExpReplaceWithFlagDescriptor.this.getIdentifier(), sourceLoc) { + private final UTF8StringPointable emptyFlags = UTF8StringPointable.generateUTF8Pointable(""); private final RegExpMatcher matcher = new RegExpMatcher(); + private int limit; + + @Override + protected void processArgument(int argIdx, IPointable argPtr, UTF8StringPointable outStrPtr) + throws HyracksDataException { + if (argIdx == 3) { + byte[] bytes = argPtr.getByteArray(); + int start = argPtr.getStartOffset(); + ATypeTag tt = ATypeTag.VALUE_TYPE_MAPPING[bytes[start]]; + switch (tt) { + case TINYINT: + case SMALLINT: + case INTEGER: + case BIGINT: + limit = ATypeHierarchy.getIntegerValue(funcID.getName(), argIdx, bytes, start, + true); + outStrPtr.set(emptyFlags); + return; + default: + limit = Integer.MAX_VALUE; + break; + } + } + super.processArgument(argIdx, argPtr, outStrPtr); + } @Override protected String compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr, UTF8StringPointable replacePtr, UTF8StringPointable flagsPtr) throws IOException { matcher.build(srcPtr, patternPtr, flagsPtr); - return matcher.replace(replacePtr); + return matcher.replace(replacePtr, limit); } }; } diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/utils/RegExpMatcher.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/utils/RegExpMatcher.java index 8d238df..050eb2e 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/utils/RegExpMatcher.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/utils/RegExpMatcher.java @@ -166,6 +166,20 @@ * @return a new string with contained regular expressions replaced. */ public String replace(UTF8StringPointable replaceStrPtr) { + return replace(replaceStrPtr, Integer.MAX_VALUE); + } + + /** + * Replaces the appearances of a regular expression defined pattern in a source string with a given + * replacement string. + * + * @param replaceStrPtr + * , the string for replacing the regular expression. + * @param replaceLimit + * , the maximum number of replacements to make + * @return a new string with contained regular expressions replaced. + */ + public String replace(UTF8StringPointable replaceStrPtr, int replaceLimit) { // Sets up a new replacement string if necessary. final boolean newReplace = replaceStrPtr != null && (replaceStr == null || lastReplaceStrPtr.compareTo(replaceStrPtr) != 0); @@ -176,7 +190,7 @@ // Does the actual replacement. resultBuf.setLength(0); - while (matcher.find()) { + for (int i = 0; i < replaceLimit && matcher.find(); i++) { matcher.appendReplacement(resultBuf, replaceStr); } matcher.appendTail(resultBuf); diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java index 04f4a1e..6b0b5d5 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java @@ -257,7 +257,7 @@ import org.apache.asterix.runtime.evaluators.functions.StringRegExpPositionDescriptor; import org.apache.asterix.runtime.evaluators.functions.StringRegExpPositionWithFlagDescriptor; import org.apache.asterix.runtime.evaluators.functions.StringRegExpReplaceDescriptor; -import org.apache.asterix.runtime.evaluators.functions.StringRegExpReplaceWithFlagsDescriptor; +import org.apache.asterix.runtime.evaluators.functions.StringRegExpReplaceWithFlagDescriptor; import org.apache.asterix.runtime.evaluators.functions.StringRepeatDescriptor; import org.apache.asterix.runtime.evaluators.functions.StringReplaceDescriptor; import org.apache.asterix.runtime.evaluators.functions.StringReplaceWithLimitDescriptor; @@ -624,7 +624,7 @@ fc.addGenerated(StringRegExpPositionDescriptor.FACTORY); fc.addGenerated(StringRegExpPositionWithFlagDescriptor.FACTORY); fc.addGenerated(StringRegExpReplaceDescriptor.FACTORY); - fc.addGenerated(StringRegExpReplaceWithFlagsDescriptor.FACTORY); + fc.addGenerated(StringRegExpReplaceWithFlagDescriptor.FACTORY); fc.addGenerated(StringInitCapDescriptor.FACTORY); fc.addGenerated(StringTrimDescriptor.FACTORY); fc.addGenerated(StringLTrimDescriptor.FACTORY); -- To view, visit https://asterix-gerrit.ics.uci.edu/2797 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I9bcf633ea6af1ade49daffec4784a70355c08a0e Gerrit-PatchSet: 1 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Dmitry Lychagin <[email protected]>
