phpbar.de logo

Mailinglisten-Archive

Re: substring_index
Archiv Mailingliste mysql-de

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: substring_index



Gerhard Pfeiffer schrieb am Freitag, den  3. September 1999:
> mysql> select substring_index(aktion_2,', ', -3) from foobar;
> +------------------------------------+
> | substring_index(aktion_2,', ', -3) |
> +------------------------------------+
> | 0, 0, alle, 19                     |
> +------------------------------------+
> 1 row in set (0.01 sec)
> 
> mysql> select substring_index(aktion_2,', ', -2) from foobar;
> +------------------------------------+
> | substring_index(aktion_2,', ', -2) |
> +------------------------------------+
> | alle, 19                           |
> +------------------------------------+
> 1 row in set (0.00 sec)                                                        
> 
> 
> Wieso? Eigentlich waere imho doch zu erwarten, dass er bei dem select mit
> -3 das erste '0, ' noch wegschneidet.
> Wo liegt der Fehler? Bei mir oder mysql?

Ich bin mir sicher, Du hast da einen Bug entdeckt!

> mysql-Version ist 3.22.19

Bei mir auch noch V3.22.19b und ich bekomme den gleichen Fehler.

Ich hab' eben in den Source-Code geschaut und in der Datei
sql/item_strfunc.cc findet man dann die C-Funktion
Item_func_substr_index.
MySQL kann sich dann verzählen, wenn der Trenner mehr als ein Zeichen
enthält (in Deinem Beispiel ', ', also zwei Zeichen) und man rückwärts
sucht, weil dann bei der Suche im String fälschlich immer diese Länge
von der letzten Suchposition abgezogen wird (statt nur -1, um einfach
ab der nächsten Position weiterzusuchen), so daß "zu kurze" Elemente
einfach übersprungen werden.

Beispiel:
 substring_index('1____2____3____4', '____', -2)    -->  '2____3____4'
                   ^3    ^2  ^1
 substring_index('1____2____33____4', '____', -2)   -->  '2____33____4'
                   ^3     ^2  ^1
 substring_index('1____2____333____4', '____', -2)  -->  '2____333____4'
                   ^3      ^2  ^1
 Der erste Trenner wird an Position 1 gefunden, und dann fälschlich
 erst ab Position 2 weiter nach links gesucht, so daß erst an Position
 3 die nächsts Fundstelle des Trenners ist.

 substring_index('1____2____3333____4', '____', -2) -->  '3333____4'
                        ^3  ^2  ^1
 Sobald die Worte zwischen den Trennern mindestens genauso lang sind,
 wird der Fehler nicht mehr sichtbar.

Ich kann's leider grad nicht testen, aber dieser Patch sollte den
Fehler beheben:
--- item_strfunc.cc.orig        Fri Sep  3 15:04:36 1999
+++ item_strfunc.cc     Fri Sep  3 15:05:13 1999
_(at)__(at)_ -450,7 +450,7 _(at)__(at)_
   }
   else
   {                                    // Start counting at end
-    for (offset=res->length() ; ; offset-=delimeter_length)
+    for (offset=res->length() ; ; offset-=1)
     {
       if ((int) (offset=res->strrstr(*delimeter,offset)) < 0)
        return res;                     // Didn't find, return org string

Willst Du einen "offiziellen" Bugreport an Monty schreiben (bist ja
der Entdecker :) oder soll ich?

Ciao,
  Martin
-- 
Martin Ramsch <m.ramsch_(at)_computer.org> <URL: http://home.pages.de/~ramsch/ >
PGP KeyID=0xE8EF4F75 FiPr=52 44 5E F3 B0 B1 38 26  E4 EC 80 58 7B 31 3A D7

---
*** Abmelden von dieser Mailingliste funktioniert per E-Mail
*** an mysql-de-request_(at)_lists.4t2.com mit Betreff/Subject: unsubscribe


Home | Main Index | Thread Index

php::bar PHP Wiki   -   Listenarchive