List:Internals« Previous MessageNext Message »
From:Jan Lindström Date:October 26 2006 9:53am
Subject:Auto increment fields on 5.1.x
View as plain text  
Hello,

Consider following SQL-queries:

create table t1(a int not null auto_increment primary key)
engine=soliddb;
insert into t1 values (null),(3),(null);

at the moment 5.1.12-bk executes insert as follows:

Breakpoint 2, ha_soliddb::write_row (this=0x97f2b08, buf=0x97f2c38 "�")
    at ha_soliddb.cc:3750
3750            su_err_t* errh = NULL;
(gdb) c
Continuing.

Breakpoint 1, ha_soliddb::get_auto_increment (this=0x97f2b08, offset=1,
increment=1,
    nb_desired_values=3, first_value=0x8ffe7140,
nb_reserved_values=0x8ffe7138)
    at ha_soliddb.cc:10276
10276           DBUG_ENTER("ha_soliddb:get_auto_increment");
(gdb) c
Continuing.

Breakpoint 2, ha_soliddb::write_row (this=0x97f2b08, buf=0x97f2c38 "�
\003")
    at ha_soliddb.cc:3750
3750            su_err_t* errh = NULL;
(gdb) c
Continuing.

Breakpoint 2, ha_soliddb::write_row (this=0x97f2b08, buf=0x97f2c38 "�")
    at ha_soliddb.cc:3750
3750            su_err_t* errh = NULL;
(gdb) c
Continuing.

Breakpoint 1, ha_soliddb::get_auto_increment (this=0x97f2b08, offset=1,
increment=1,
    nb_desired_values=3, first_value=0x8ffe7140,
nb_reserved_values=0x8ffe7138)
    at ha_soliddb.cc:10276
10276           DBUG_ENTER("ha_soliddb:get_auto_increment");

Now my question is why MySQL calls ::get_auto_increment function second
time for a above insert? Handler has already generated exactly desired
number of auto_increment values for the MySQL server. My implementation
for ::get_auto_increment is as follows:

/*#***********************************************************************\
 *
 *              ::get_auto_increment
 *
 * Reserves an interval of auto_increment values from the handler.
 * offset and increment means that we want values to be of the form
 * offset + N * increment, where N>=0 is integer.
 * If the function sets *first_value to ~(ulonglong)0 it means an error.
 * If the function sets *nb_reserved_values to ULONGLONG_MAX it means it
has
 * reserved to "positive infinite".
 *
 * Parameters :
 *
 *     ulonglong  offset, in, use
 *     ulonglong  increment, in, use
 *     ulonglong  nb_desired_values, in, use
 *     ulonglong* first_value, out
 *     ulonglong* nb_reserved_values, out
 *
 * Return value : -
 *
 * Globals used : THD* current_thd
 */
void ha_soliddb::get_auto_increment(
        ulonglong offset,
        ulonglong increment,
        ulonglong nb_desired_values,
        ulonglong *first_value,
        ulonglong *nb_reserved_values)
{
        DBUG_ENTER("ha_soliddb:get_auto_increment");

        ss_int8_t i8;
        SOLID_CONN* con;
        ulonglong solid_value = 0;
        struct system_variables* variables;
        bool result = FALSE;
        rs_relh_t*  relh = NULL;
        long        seq_id=0;
        rs_auth_t*  auth;
        rs_atype_t* atype;
        rs_aval_t*  aval;
        solid_bool  p_finishedp;
        rs_err_t*   p_errh = NULL;
        ulonglong   n_value;
        THD*        thd = current_thd;
        
        ss_dassert(first_value != NULL);
        ss_dassert(nb_reserved_values != NULL);

        con = (SOLID_CONN*)thd->ha_data[ht->slot];

        ss_dassert(con != NULL);
        relh = solid_rsrelh;
        ss_dassert(relh != NULL);
        auth = rs_sysi_auth(con->cd);
        ss_dassert(auth != NULL);
        rs_auth_setsystempriv(con->cd, auth, TRUE);

        seq_id = rs_relh_readautoincrement_seqid(con->cd, relh);
        *first_value = ~(ulonglong)0;
        
        atype = rs_atype_initbigint(con->cd);
        aval = rs_aval_create(con->cd, atype);

        result = tb_seq_next(con->cd, con->trans, seq_id,
                             FALSE, atype, aval, &p_finishedp, &p_errh);

        if (result) {
            i8 = rs_aval_getint8(con->cd, atype, aval);
            
            solid_value = SsInt8GetNativeUint8(i8);

            for (n_value = 0; result && n_value < nb_desired_values;
n_value++, solid_value++) {

                solid_value = solid_next_insert_id(solid_value-1,
increment, offset);
                    
                if (n_value == 0) {
                    *first_value = solid_value;
                }
            }

            *nb_reserved_values = n_value;
                
            SsInt8SetNativeUint8(&i8, solid_value);
            rs_aval_setint8_raw(con->cd, atype, aval, i8, &p_errh);
            
            result = tb_seq_set(con->cd, con->trans, seq_id,
                                FALSE, atype, aval, &p_finishedp,
&p_errh);
        }

        rs_aval_free(con->cd, atype, aval);
        rs_atype_free(con->cd, atype);
        rs_auth_setsystempriv(con->cd, auth, FALSE);

        if (p_errh) {
            ss_pprintf_1(("solidDB: [Error]::get_auto_increment: %s\n",
su_err_geterrstr(p_errh)));
            su_err_done(p_errh);
        }

        DBUG_VOID_RETURN;
}

In ::write_row I have:

...
        if (table->next_number_field && buf == table->record[0]) {
            /* This is the case where the table has an
		    auto-increment column */

            update_auto_increment();
        }

	/* do the insert */

R: Jan Lindström
Solid Information Technology Ltd

Thread
Auto increment fields on 5.1.xJan Lindström26 Oct
  • Re: Auto increment fields on 5.1.xGuilhem Bichot30 Oct