Skip to content

Commit ff9f094

Browse files
committed
Fix #8078 - SIMILAR TO with constant pattern using ‘|’, ‘*’, ‘?’ or ‘{0,N}’ doesn't work as expected.
1 parent 3496c5d commit ff9f094

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/jrd/optimizer/Optimizer.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3158,6 +3158,8 @@ ValueExprNode* Optimizer::optimizeLikeSimilar(ComparativeBoolNode* cmpNode)
31583158

31593159
MoveBuffer prefixBuffer;
31603160
ULONG charLen = 0;
3161+
bool specialCharFound = false;
3162+
FB_SIZE_T prevPrefixSize = 0;
31613163

31623164
while (IntlUtil::readOneChar(matchCharset, &patternPtr, patternEnd, &charLen))
31633165
{
@@ -3172,9 +3174,36 @@ ValueExprNode* Optimizer::optimizeLikeSimilar(ComparativeBoolNode* cmpNode)
31723174
}
31733175
}
31743176
else if (charLen == 1 && SimilarToRegex::isSpecialChar(*patternPtr))
3177+
{
3178+
const auto patternChar = *patternPtr;
3179+
3180+
// If there are any branches, we assume there is no commom prefix.
3181+
if (patternChar == '|')
3182+
return nullptr;
3183+
3184+
if (!specialCharFound)
3185+
{
3186+
switch (patternChar)
3187+
{
3188+
// These patterns may make the previous char optional.
3189+
case '*':
3190+
case '?':
3191+
case '{':
3192+
prefixBuffer.resize(prevPrefixSize);
3193+
break;
3194+
}
3195+
3196+
specialCharFound = true;
3197+
}
3198+
31753199
break;
3200+
}
31763201

3177-
prefixBuffer.push(patternPtr, charLen);
3202+
if (!specialCharFound)
3203+
{
3204+
prevPrefixSize = prefixBuffer.getCount();
3205+
prefixBuffer.push(patternPtr, charLen);
3206+
}
31783207
}
31793208

31803209
if (prefixBuffer.isEmpty())

0 commit comments

Comments
 (0)