Nach der Tabelleninitialisierung ruft der MySQL Server die
        Handler-Funktion
        rnd_next()
        für jede zu untersuchende Zeile einmal auf, bis seine
        Suchbedingung erfüllt oder das Ende der Datei erreicht ist. Im
        letzteren Fall gibt er HA_ERR_END_OF_FILE
        zurück.
      
        Die Funktion rnd_next() nimmt einen
        Byte-Array-Parameter namens *buf entgegen.
        Dieser *buf-Parameter muss mit dem Inhalt der
        Tabellenzeile im internen Format von MySQL gefüllt sein.
      
        Der Server verwendet drei Datenformate: Zeilen mit fester
        Länge, Zeilen mit variabler Länge und variabel lange Zeilen
        mit BLOB-Zeigern. In jedem der Formate erscheinen die Spalten in
        derselben Reihenfolge wie in der CREATE TABLE-Anweisung. (Die
        Tabellendefinition wird in der .frm-Datei
        gespeichert und Optimierer und Handler können beide die
        Metadaten der Tabelle aus derselben Quelle holen, nämlich aus
        ihrer TABLE-Struktur.)
      
Jedes Format beginnt mit einer „NULL-Bitmap“, die für jede nullfähige Spalte ein Bit enthält. Eine Tabelle mit 8 nullfähigen Spalten hat somit eine 1 Byte große Bitmap, während eine Tabelle mit 9 bis 16 nullfähigen Spalten eine 2 Byte große Bitmap besitzt, und so weiter. Eine Ausnahme bilden die Tabellen mit fester Breite: Da sie ein zusätzliches Startbit haben, würde eine solche Tabelle mit 8 nullfähigen Spalten dennoch eine 2 Byte große Bitmap aufweisen.
        Hinter der NULL-Bitmap kommen nacheinander die Spalten an die
        Reihe. Jede Spalte hat die in Kapitel 11, Datentypen,
        angegebene Größe. Im Server sind die Spaltendatentypen in der
        Datei sql/field.cc definiert. In einem
        Format mit fester Zeilenbreite werden die Spalten einfach
        nacheinander angeordnet. In einem Format mit variabler
        Zeilenlänge werden die VARCHAR-Spalten mit
        einer Länge von 1 oder 2 Byte, gefolgt von einem
        Zeichen-String, kodiert. In einer variabel langen Zeile mit
        BLOB-Spalten wird jeder BLOB in zwei Teilen
        dargestellt: Zuerst kommt ein Integer, der die tatsächliche
        Länge des BLOB darstellt, und dann ein
        Zeiger auf den Speicherplatz des BLOB.
      
        Beispiele für die Konvertierung (oder das
        „Packen“) von Zeilen finden Sie ab der Funktion
        rnd_next() in jedem Tabellen-Handler. So
        zeigt beispielsweise in ha_tina.cc der Code
        von find_current_row(), wie die
        TABLE-Struktur (auf welche die Tabelle
        verweist) und ein String-Objekt namens Buffer genutzt werden
        können, um Zeichendaten aus einer CSV-Datei zu packen. Um eine
        Zeile auf die Platte zurückzuspeichern, ist die umgekehrte
        Konvertierung erforderlich: Die Zeilen müssen dann aus dem
        internen Format wieder zurückkonvertiert werden.
      
        Das folgende Beispiel stammt wieder aus der Speicher-Engine
        CSV:
      
int ha_tina::rnd_next(byte *buf)
{
   DBUG_ENTER("ha_tina::rnd_next");
 
   statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status);
 
   current_position= next_position;
   if (!share->mapped_file)
     DBUG_RETURN(HA_ERR_END_OF_FILE);
   if (HA_ERR_END_OF_FILE == find_current_row(buf) )
     DBUG_RETURN(HA_ERR_END_OF_FILE);
 
   records++;
   DBUG_RETURN(0);
}  
        Die Funktion find_current_row() übernimmt
        die Konvertierung aus dem internen Zeilenformat in ein
        CSV-Zeilenformat:
      
int ha_tina::find_current_row(byte *buf)
{
   byte *mapped_ptr= (byte *)share->mapped_file + current_position;
   byte *end_ptr;
   DBUG_ENTER("ha_tina::find_current_row");
 
   /* EOF soll als Newline gelten*/
   if ((end_ptr=  find_eoln(share->mapped_file, current_position,
                            share->file_stat.st_size)) == 0)
     DBUG_RETURN(HA_ERR_END_OF_FILE);
 
   for (Field **field=table->field ; *field ; field++)
   {
     buffer.length(0);
     mapped_ptr++; // Inkrementiere hinter dem ersten Anführungszeichen
     for(;mapped_ptr != end_ptr; mapped_ptr++)
     {
       // Ist notwendig, um Zeilenvorschübe zu konvertieren!
       if (*mapped_ptr == '"' &&
           (((mapped_ptr[1] == ',') && (mapped_ptr[2] == '"')) ||
            (mapped_ptr == end_ptr -1 )))
       {
         mapped_ptr += 2; // Gehe hinter das , und das "
         break;
       }
       if (*mapped_ptr == '\\' && mapped_ptr != (end_ptr - 1))
       {
         mapped_ptr++;
         if (*mapped_ptr == 'r')
           buffer.append('\r');
         else if (*mapped_ptr == 'n' )
           buffer.append('\n');
         else if ((*mapped_ptr == '\\') || (*mapped_ptr == '"'))
           buffer.append(*mapped_ptr);
         else  /* Dies kann nur bei einer extern erzeugten Datei passieren */
         {
           buffer.append('\\');
           buffer.append(*mapped_ptr);
         }
       }
       else
         buffer.append(*mapped_ptr);
     }
     (*field)->store(buffer.ptr(), buffer.length(), system_charset_info);
   }
   next_position= (end_ptr - share->mapped_file)+1;
   /* Vielleicht \N für null verwenden? */
   memset(buf, 0, table->s->null_bytes); /* Nullen werden nicht implementiert! */
 
   DBUG_RETURN(0);
}  
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.

