@@ -5701,13 +5701,23 @@ byte_increment(unsigned char *ptr, int len)
5701
5701
* and "9" is seen as largest by the collation, and append that to the given
5702
5702
* prefix before trying to find a string that compares as larger.
5703
5703
*
5704
- * If we max out the righthand byte, truncate off the last character
5705
- * and start incrementing the next. For example, if "z" were the last
5706
- * character in the sort order, then we could produce "foo" as a
5707
- * string greater than "fonz".
5704
+ * To search for a greater string, we repeatedly "increment" the rightmost
5705
+ * character, using an encoding-specific character incrementer function.
5706
+ * When it's no longer possible to increment the last character, we truncate
5707
+ * off that character and start incrementing the next-to-rightmost.
5708
+ * For example, if "z" were the last character in the sort order, then we
5709
+ * could produce "foo" as a string greater than "fonz".
5708
5710
*
5709
5711
* This could be rather slow in the worst case, but in most cases we
5710
5712
* won't have to try more than one or two strings before succeeding.
5713
+ *
5714
+ * Note that it's important for the character incrementer not to be too anal
5715
+ * about producing every possible character code, since in some cases the only
5716
+ * way to get a larger string is to increment a previous character position.
5717
+ * So we don't want to spend too much time trying every possible character
5718
+ * code at the last position. A good rule of thumb is to be sure that we
5719
+ * don't try more than 256*K values for a K-byte character (and definitely
5720
+ * not 256^K, which is what an exhaustive search would approach).
5711
5721
*/
5712
5722
Const *
5713
5723
make_greater_string (const Const * str_const , FmgrInfo * ltproc , Oid collation )
@@ -5779,17 +5789,19 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation)
5779
5789
}
5780
5790
}
5781
5791
5792
+ /* Select appropriate character-incrementer function */
5782
5793
if (datatype == BYTEAOID )
5783
- charinc = & byte_increment ;
5794
+ charinc = byte_increment ;
5784
5795
else
5785
5796
charinc = pg_database_encoding_character_incrementer ();
5786
5797
5798
+ /* And search ... */
5787
5799
while (len > 0 )
5788
5800
{
5789
- int charlen ;
5801
+ int charlen ;
5790
5802
unsigned char * lastchar ;
5791
- Const * workstr_const ;
5792
5803
5804
+ /* Identify the last character --- for bytea, just the last byte */
5793
5805
if (datatype == BYTEAOID )
5794
5806
charlen = 1 ;
5795
5807
else
@@ -5799,9 +5811,15 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation)
5799
5811
/*
5800
5812
* Try to generate a larger string by incrementing the last character
5801
5813
* (for BYTEA, we treat each byte as a character).
5814
+ *
5815
+ * Note: the incrementer function is expected to return true if it's
5816
+ * generated a valid-per-the-encoding new character, otherwise false.
5817
+ * The contents of the character on false return are unspecified.
5802
5818
*/
5803
- if (charinc (lastchar , charlen ))
5819
+ while (charinc (lastchar , charlen ))
5804
5820
{
5821
+ Const * workstr_const ;
5822
+
5805
5823
if (datatype == BYTEAOID )
5806
5824
workstr_const = string_to_bytea_const (workstr , len );
5807
5825
else
@@ -5825,7 +5843,8 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation)
5825
5843
}
5826
5844
5827
5845
/*
5828
- * Truncate off the last character or byte.
5846
+ * No luck here, so truncate off the last character and try to
5847
+ * increment the next one.
5829
5848
*/
5830
5849
len -= charlen ;
5831
5850
workstr [len ] = '\0' ;
0 commit comments