mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 08:40:39 +01:00
Feature CORE-1945 - Custom attribute for collation to sort numbers in numeric order
This commit is contained in:
parent
42f58df7ab
commit
cd49fc3faa
@ -277,6 +277,25 @@ Format: SPECIALS-FIRST={0 | 1}
|
||||
Example: SPECIALS-FIRST=1
|
||||
|
||||
|
||||
NUMERIC: Specify how numbers are sorted.
|
||||
Valid for: UNICODE collations.
|
||||
Format: NUMERIC={0 | 1} (0 is the default)
|
||||
|
||||
NUMERIC=0 sorts number in alphabetic order. Example:
|
||||
1
|
||||
10
|
||||
100
|
||||
2
|
||||
20
|
||||
|
||||
NUMERIC=1 sorts number in numeric order. Example:
|
||||
1
|
||||
2
|
||||
10
|
||||
20
|
||||
100
|
||||
|
||||
|
||||
Collation changes
|
||||
-----------------
|
||||
|
||||
|
@ -937,10 +937,10 @@ UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
|
||||
texttype* tt, USHORT attributes,
|
||||
Firebird::IntlUtil::SpecificAttributesMap& specificAttributes, const Firebird::string& configInfo)
|
||||
{
|
||||
string locale;
|
||||
int attributeCount = 0;
|
||||
bool error;
|
||||
|
||||
string locale;
|
||||
if (specificAttributes.get(IntlUtil::convertAsciiToUtf16("LOCALE"), locale))
|
||||
++attributeCount;
|
||||
|
||||
@ -954,6 +954,16 @@ UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string numeric;
|
||||
if (specificAttributes.get(IntlUtil::convertAsciiToUtf16("NUMERIC"), numeric))
|
||||
{
|
||||
++attributeCount;
|
||||
|
||||
numeric = IntlUtil::convertUtf16ToAscii(numeric, &error);
|
||||
if (error || !(numeric == "0" || numeric == "1"))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
locale = IntlUtil::convertUtf16ToAscii(locale, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
@ -1015,6 +1025,14 @@ UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
|
||||
else
|
||||
tt->texttype_flags = TEXTTYPE_DIRECT_MATCH;
|
||||
|
||||
bool isNumeric = numeric == "1";
|
||||
if (isNumeric)
|
||||
{
|
||||
icu->ucolSetAttribute(compareCollator, UCOL_NUMERIC_COLLATION, UCOL_ON, &status);
|
||||
icu->ucolSetAttribute(partialCollator, UCOL_NUMERIC_COLLATION, UCOL_ON, &status);
|
||||
icu->ucolSetAttribute(sortCollator, UCOL_NUMERIC_COLLATION, UCOL_ON, &status);
|
||||
}
|
||||
|
||||
USet* contractions = icu->usetOpen(0, 0);
|
||||
// status not verified here.
|
||||
icu->ucolGetContractions(partialCollator, contractions, &status);
|
||||
@ -1028,6 +1046,7 @@ UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
|
||||
obj->sortCollator = sortCollator;
|
||||
obj->contractions = contractions;
|
||||
obj->contractionsCount = icu->usetGetItemCount(contractions);
|
||||
obj->numeric = isNumeric;
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -1108,6 +1127,19 @@ USHORT UnicodeUtil::Utf16Collation::stringToKey(USHORT srcLen, const USHORT* src
|
||||
}
|
||||
}
|
||||
|
||||
if (numeric)
|
||||
{
|
||||
const USHORT* p = src + srcLen - 1;
|
||||
|
||||
for (; p >= src; --p)
|
||||
{
|
||||
if (!(*p >= '0' && *p <= '9'))
|
||||
break;
|
||||
}
|
||||
|
||||
srcLen = p - src + 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,7 @@ public:
|
||||
UCollator* sortCollator;
|
||||
USet* contractions;
|
||||
int contractionsCount;
|
||||
bool numeric;
|
||||
};
|
||||
|
||||
friend class Utf16Collation;
|
||||
|
Loading…
Reference in New Issue
Block a user