1
0
Fork 0

fixed a bug in RTRIM implementation, fixed issue #9558 (#9563)

This commit is contained in:
Jan 2019-07-25 14:57:33 +02:00 committed by KVS85
parent fc1d13756d
commit c2c6fcb52c
3 changed files with 56 additions and 20 deletions

View File

@ -1,6 +1,8 @@
v3.5.0-rc.6 (2019-XX-XX)
------------------------
* Fixed issue #9558: RTRIM not working as expected.
* Added startup error for bad temporary directory setting.
If the temporary directory (--temp.path) setting is identical to the database

View File

@ -2395,7 +2395,7 @@ AqlValue Functions::Right(ExpressionContext*, transaction::Methods* trx,
}
namespace {
void ltrimInternal(uint32_t& startOffset, uint32_t& endOffset, icu::UnicodeString& unicodeStr,
void ltrimInternal(int32_t& startOffset, int32_t& endOffset, icu::UnicodeString& unicodeStr,
uint32_t numWhitespaces, UChar32* spaceChars) {
for (; startOffset < endOffset; startOffset = unicodeStr.moveIndex32(startOffset, 1)) {
bool found = false;
@ -2412,22 +2412,26 @@ void ltrimInternal(uint32_t& startOffset, uint32_t& endOffset, icu::UnicodeStrin
}
} // for
}
void rtrimInternal(uint32_t& startOffset, uint32_t& endOffset, icu::UnicodeString& unicodeStr,
void rtrimInternal(int32_t& startOffset, int32_t& endOffset, icu::UnicodeString& unicodeStr,
uint32_t numWhitespaces, UChar32* spaceChars) {
for (uint32_t codeUnitPos = unicodeStr.moveIndex32(unicodeStr.length(), -1);
startOffset < codeUnitPos;
codeUnitPos = unicodeStr.moveIndex32(codeUnitPos, -1)) {
if (unicodeStr.length() == 0) {
return;
}
for (int32_t codePos = unicodeStr.moveIndex32(endOffset, -1);
startOffset <= codePos;
codePos = unicodeStr.moveIndex32(codePos, -1)) {
bool found = false;
for (uint32_t pos = 0; pos < numWhitespaces; pos++) {
if (unicodeStr.char32At(codeUnitPos) == spaceChars[pos]) {
if (unicodeStr.char32At(codePos) == spaceChars[pos]) {
found = true;
--endOffset;
break;
}
}
endOffset = unicodeStr.moveIndex32(codeUnitPos, 1);
if (!found) {
if (!found || codePos == 0) {
break;
}
} // for
@ -2475,7 +2479,7 @@ AqlValue Functions::Trim(ExpressionContext* expressionContext, transaction::Meth
return AqlValue(AqlValueHintNull());
}
uint32_t startOffset = 0, endOffset = unicodeStr.length();
int32_t startOffset = 0, endOffset = unicodeStr.length();
if (howToTrim <= 1) {
ltrimInternal(startOffset, endOffset, unicodeStr, numWhitespaces, spaceChars.get());
@ -2521,7 +2525,7 @@ AqlValue Functions::LTrim(ExpressionContext* expressionContext, transaction::Met
return AqlValue(AqlValueHintNull());
}
uint32_t startOffset = 0, endOffset = unicodeStr.length();
int32_t startOffset = 0, endOffset = unicodeStr.length();
ltrimInternal(startOffset, endOffset, unicodeStr, numWhitespaces, spaceChars.get());
@ -2561,7 +2565,7 @@ AqlValue Functions::RTrim(ExpressionContext* expressionContext, transaction::Met
return AqlValue(AqlValueHintNull());
}
uint32_t startOffset = 0, endOffset = unicodeStr.length();
int32_t startOffset = 0, endOffset = unicodeStr.length();
rtrimInternal(startOffset, endOffset, unicodeStr, numWhitespaces, spaceChars.get());

View File

@ -1480,12 +1480,18 @@ function ahuacatlStringFunctionsTestSuite () {
// //////////////////////////////////////////////////////////////////////////////
testRtrim: function () {
var expected = [ ' foo',
'\t\r\nabc',
'\ta\rb\nc',
'\r\nThis\nis\r\na\ttest'
];
var expected = [ '',
'',
'',
' foo',
'\t\r\nabc',
'\ta\rb\nc',
'\r\nThis\nis\r\na\ttest'
];
var actual = getQueryResults(`FOR t IN [
'',
' ',
' ',
' foo ',
'\t\r\nabc\n\r\t',
'\ta\rb\nc ',
@ -1499,11 +1505,21 @@ function ahuacatlStringFunctionsTestSuite () {
// //////////////////////////////////////////////////////////////////////////////
testRtrimSpecial1: function () {
var expected = [ ' foo',
'\t\r\nabc\n\r\t',
'\ta\rb\nc',
'\r\nThis\nis\r\na\ttest' ];
var expected = [ '',
'',
'',
'',
'\t',
' foo',
'\t\r\nabc\n\r\t',
'\ta\rb\nc',
'\r\nThis\nis\r\na\ttest' ];
var actual = getQueryResults(`FOR t IN [
'',
'\r',
'\r\n',
' \r\n',
'\t\r\n',
' foo ',
'\t\r\nabc\n\r\t',
'\ta\rb\nc ',
@ -1529,6 +1545,20 @@ function ahuacatlStringFunctionsTestSuite () {
assertEqual(expected, actual);
},
testRtrimChars: function () {
var expected = [ '10000', '1000', '100', '10', '1', '', '' ];
var actual = getQueryResults(`FOR t IN [
'10000x',
'1000x',
'100x',
'10x',
'1x',
'x',
''
] RETURN NOOPT((RTRIM(t, 'x') ))`);
assertEqual(expected, actual);
},
// //////////////////////////////////////////////////////////////////////////////
// / @brief test find_first function
// //////////////////////////////////////////////////////////////////////////////