MySQL Lists are EOL. Please join:

List:Internals« Previous MessageNext Message »
From:Sergei Golubchik Date:July 16 2009 6:25pm
Subject:Re: GSoC Week 10 - I_S/P_S storage engine
View as plain text  
Hi, scut_tang!

On Jul 14, scut_tang wrote:
> KEY CONCERNS
> ============
> 1. When I call "SELECT * FROM INFOSCHEMA.ENGINES/COLLATIONS", they are
>    crashed at table->field[0]->store(...).

It crashes in

Program received signal SIGSEGV, Segmentation fault.
0x00007f126c734686 in memmove () from /lib/libc.so.6

because of

(gdb) up
#1  0x0000000000694ac7 in well_formed_copy_nchars (to_cs=0x115d4a0, 
    to=0x2ddc2 <Address 0x2ddc2 out of bounds>, to_length=256, 
    from_cs=0x115d4a0, from=0xcf9b40 "FEDERATED", from_length=9, nchars=64, 
    well_formed_error_pos=0x4096caa8, cannot_convert_error_pos=0x4096caa0,
    from_end_pos=0x4096ca98) at sql_string.cc:1001

note: "to=0x2ddc2 <Address 0x2ddc2 out of bounds>"
it tries to copy to an invalid address. now

(gdb) up
#2  0x00000000006710b2 in Field_varstring::store (this=0x1de65e0, 
    from=0xcf9b40 "FEDERATED", length=9, cs=0x115d4a0) at field.cc:6874
6874                                           &from_end_pos);

the complete statement is

  copy_length= well_formed_copy_nchars(field_charset,
                                       (char*) ptr + length_bytes,
                                       field_length,
                                       cs, from, length,
                                       field_length / field_charset->mbmaxlen,
                                       &well_formed_error_pos,
                                       &cannot_convert_error_pos,
                                       &from_end_pos);

and you can see that ptr + length_bytes results in this invalid address,
apparently ptr is invalid.

Which is not surprising as you create all fields with ptr==0:

.....
   case MYSQL_TYPE_LONG:
           new_field = new Field_long((uchar *)0, item->max_length, null_ptr, 0,
                           Field::NONE, item->name, 0, item->unsigned_flag);
           break;
.....

first argument (uchar *)0) is ptr.
You need to set ptr (and null_ptr) appropriately.

Second problem - you have to set share->column_bitmap_size and allocate
all_set bitmap.

Third problem - you have to call dbug_tmp_use_all_columns() before
field->store().

when it's done, "SELECT * FROM INFOSCHEMA.COLLATIONS" works.

(it crashes on the second query on your assert in
ha_infoschema::rnd_init

782       DBUG_ASSERT(m_table == NULL);

but it's a separate issue :)

>    SHOW CREATE TABLE INFOSCHEMA.TABLES crashed too, and add

Now it works - at least SHOW CREATE TABLE INFOSCHEMA.COLLATIONS works,
I didn't try TABLES as it's not visible in SHOW TABLES FROM INFOSCHEMA
yet.

That is, SHOW CREATE TABLE almost work - it shows garbage default
values, because you don't allocate a separate record[] buffer for them.

Allocate three record buffers, point share->default_values to record[2]
and initialize it appropriately. I suppose going over all fields,
and calling field->reset() will create a properly initialized default
record, you'll only need to do

  store_record(share, default_values);

which will memcpy your initialized record[0] to default_values.

>    I think all these crashes are caused by the incomplete filled
>    table_share. Sergei, could you check infoschema_discover?

done.

And please, fix the formatting: use spaces, not tabs. Indent by 2 (two!)
spaces, see how the code is formatted elsewhere.

> 2. I don't use init_tmp_table_share in infoschema_discover, because it
>    won't work. When I used it, MySQL returned "table does not exist".
>    I think some fields filled by init_tmp_table_share are not fit for us.

no time for it today, I'll look at it later.

Below is the patch that fixes SELECT * FROM INFOSCHEMA.COLLATIONS
===========================================================
=== modified file 'storage/infoschema/ha_infoschema.cc'
--- storage/infoschema/ha_infoschema.cc 2009-07-16 11:18:01 +0000
+++ storage/infoschema/ha_infoschema.cc 2009-07-16 18:20:58 +0000
@@ -42,8 +42,7 @@
 
 handlerton *infoschema_hton = NULL;
 
-TABLE_SHARE * infoschema_discover(handlerton *hton, THD *thd, const char *db,
-               const char *name);
+TABLE_SHARE * infoschema_discover(handlerton *, THD *, const char *, const char *);
 
 int infoschema_find_files(handlerton *hton, THD *thd,
                const char *db,
@@ -460,10 +459,24 @@
        share->null_fields = null_count;
        share->blob_fields = blob_count;
        share->db_plugin = ha_lock_engine(0, infoschema_hton);
-       share->reclength = reclength;
+  share->null_bytes = (null_count + 7) / 8;
 
+  reclength+= share->null_bytes;
+  share->reclength = reclength;
        share->rec_buff_length = ALIGN_SIZE(reclength + ENGINE_UNIQUE_HASH_LENGTH + 1);
 
+  my_bitmap_map *bitmaps;
+  share->column_bitmap_size= bitmap_buffer_size(share->fields);
+  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
+                                             share->column_bitmap_size)))
+  {
+    free_table_share(share);
+    DBUG_RETURN(NULL);
+  }
+  bitmap_init(&share->all_set, bitmaps, share->fields, FALSE);
+  bitmap_set_all(&share->all_set);
+
+
        /** Talbe index definition. */
        share->keys = 0;
        share->key_info = NULL;
@@ -480,7 +493,25 @@
        }
 
        share->default_values = record;
-       share->null_bytes = (share->null_fields + 7) / 8;
+
+  /* now, let's fix Field's pointers */
+  for (null_count= reclength= fieldnr= 0; fieldnr < field_count; fieldnr++)
+  {
+    Field *field= share->field[fieldnr];
+
+    field->ptr= record + share->null_bytes + reclength;
+    if (!(field->flags & NOT_NULL_FLAG))
+    {
+      field->null_ptr= record + null_count / 8;
+      field->null_bit= 1 << (null_count & 7);
+    }
+    if(field->type() == MYSQL_TYPE_BLOB)
+      reclength += field->row_pack_length() + share->blob_ptr_size;
+    else
+      reclength += field->pack_length();
+    if (!(field->flags & NOT_NULL_FLAG))
+      null_count++;
+  }
 
        thd->status_var.opened_shares++;
 

=== modified file 'storage/infoschema/table_collations.cc'
--- storage/infoschema/table_collations.cc      2009-07-16 11:18:01 +0000
+++ storage/infoschema/table_collations.cc      2009-07-16 18:04:13 +0000
@@ -103,6 +103,7 @@
                                                wild_case_compare(scs, tmp_cl->name,
wild)))
                        {
                                const char *tmp_buff;
+                                my_bitmap_map *old= dbug_tmp_use_all_columns(table,
table->write_set);
                                restore_record(table, s->default_values);
                                table->field[0]->store(tmp_cl->name,
strlen(tmp_cl->name), scs);
                                table->field[1]->store(tmp_cl->csname ,
strlen(tmp_cl->csname), scs);
@@ -113,6 +114,7 @@
                                table->field[4]->store(tmp_buff, strlen(tmp_buff),
scs);
                                table->field[5]->store((longlong)
tmp_cl->strxfrm_multiply, TRUE);
                                cs_two++;
+                                dbug_tmp_restore_column_map(table->write_set, old);
                                DBUG_RETURN(0);
                        }
                }
===========================================================

Regards / Mit vielen Grüßen,
Sergei

-- 
   __  ___     ___ ____  __
  /  |/  /_ __/ __/ __ \/ /   Sergei Golubchik <serg@stripped>
 / /|_/ / // /\ \/ /_/ / /__  Principal Software Engineer/Server Architect
/_/  /_/\_, /___/\___\_\___/  Sun Microsystems GmbH, HRB München 161028
       <___/                  Sonnenallee 1, 85551 Kirchheim-Heimstetten
Geschäftsführer: Thomas Schroeder, Wolfgang Engels, Wolf Frenkel
Vorsitzender des Aufsichtsrates: Martin Häring
Thread
OS/2 3.23.32: merge test failingYuri Dario27 Jan
  • Re: GSoC Week 10 - I_S/P_S storage engineSergei Golubchik18 Jul
  • Re: GSoC Week 10 - I_S/P_S storage engineSergei Golubchik18 Jul
Re: OS/2 3.23.32: merge test failingYuri Dario27 Jan