Issue information

Issue ID
#3735
Status
Fixed
Severity
Medium
Started
Hercules Elf Bot
Nov 30, 2009 7:16
Last Post
Hercules Elf Bot
Nov 30, 2009 7:16
Confirmation
N/A

Hercules Elf Bot - Nov 30, 2009 7:16

Originally posted by [b]Paradox924X[/b]
http://www.eathena.ws/board/index.php?autocom=bugtracker&showbug=3735

trunk/src/map/mapreg_sql.c:
CODE
    if( val != 0 )
    {
        if( idb_put(mapreg_db,uid,(void*)val) )
       ; // already exists, delay write
        else
        if( name[1] == '@' )
       ; // nothing more to do
        else
        {// write new wariable to database
            char tmp_str[32*2+1];
            Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32));
            if( SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%d')", mapreg_table, tmp_str, i, val) )
                Sql_ShowDebug(mmysql_handle);
        }
    }
    else // val == 0
    {
        idb_remove(mapreg_db,uid);

        if( name[1] == '@' )
       ; // nothing more to do
        else
        {// Remove from database because it is unused.
            if( SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg_table, name, i) )
                Sql_ShowDebug(mmysql_handle);
        }
    }

    mapreg_dirty = true;

As seen in the code above, mapreg_dirty is being set to true without regard to if it is actually 'dirty' or not.
It only needs to be marked dirty when we are delaying the write. In fact, there's already an if check without a statement to execute.
See:
CODE
if( idb_put(mapreg_db,uid,(void*)val) )
; // already exists, delay write

This only affects SQL because of the delayed writes not always being necessary to SQL. In TXT, the flatfile writes cannot be efficiently made when a variable is updated so delayed writes are always required.
This issue is also present in stable.

stable/src/map/script.c:
CODE
#if !defined(TXT_ONLY) && defined(MAPREGSQL)
    int i = num >> 24;
    char* name = str_buf + str_data[num&0x00ffffff].str;

    if( val != 0 ) {
        if(idb_put(mapreg_db,num,(void*)val))
       ;
        else if(name[1] != '@') {
            char tmp_str[32*2+1];
            Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32));
            if( SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`%s`,`%s`,`%s`) VALUES ('%s','%d','%d')", mapregsql_db, mapregsql_db_varname, mapregsql_db_index, mapregsql_db_value, tmp_str, i, val) )
                Sql_ShowDebug(mmysql_handle);
        }
    } else { // val == 0
        if(name[1] != '@') { // Remove from database because it is unused.
            if( SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `%s`='%s' AND `%s`='%d'", mapregsql_db, mapregsql_db_varname, name, mapregsql_db_index, i) )
                Sql_ShowDebug(mmysql_handle);
        }
        idb_remove(mapreg_db,num);
    }
#else
    if(val != 0)
        idb_put(mapreg_db,num,(void*)val);
    else
        idb_remove(mapreg_db,num);
#endif

    mapreg_dirty = 1;