PLEASE NOTE: These forums are no longer utilized and are provided as an archive for informational purposes only. All support issues will be handled via email using our support ticket system. For more detailed information on this change, please see this blog post.

Insert form: $wpdb->insert_id vs. $wpdb->get_var("SELECT LAST_INSERT_ID();");

  1. MMC
    Member

    Had a weird issue, we're using GF 1.3.11 on WP 2.9.2

    Development server running Ubuntu:
    PHP 5.3.2-1ubuntu4.2 with Suhosin-Patch
    MySQL 5.1.45-log MySQL Community Server (GPL)

    Production server running Debian:
    PHP Version 5.2.6-1+lenny8 with Suhosin-Patch
    MySQL 5.0.51a-24+lenny4-log (Debian) running Debian

    On the dev server GF works fine.

    On the production server, when creating a new form, the new form data in the rg_form_meta table is saved with form_id=0 so after creating a new form, when you go back to it later it has no fields and the UI shows the default "Untitled Form" box. Then when you try and create a new form, new forms have the form data that was previously saved to the new form and is now "missing". And new forms you try and create give the "A form already exists with that name" error.

    I installed GF on another site running WP 2.8.5 on the same production server that the bugs appeared on, and it works fine.

    I dug around in the code and found in RGFormsModel::insert_form() that the following is being returned:
    return $wpdb->get_var("SELECT LAST_INSERT_ID();");

    On the production server with WP 2.9.2 this is returning 0, and thus saving the form data with ID 0 and causing the whole thing to bug out. When I change it to use WPDB's insert_id (which stores the return value of mysql_insert_id($wpdb->dbh) right after an insert) it works. Like so:
    return $wpdb->insert_id;

    I've had a hard time reproducing this issue, even with another copy of WP on the same server, so I'm not sure what the exact problem is.

    However, the fix works flawlessly on both WP installs (the one experiencing the bug and the one that doesn't). I'm curious why SELECT LAST_INSERT_ID() is used instead of using WPDB's insert_id var, especially since it prevents running two queries to get the same data (WPDB runs a function to get he last insert id and the GF runs a different one to attempt to get the same data). I don't want to inadvertently break something if -- for example -- calling SELECT LAST_INSERT_ID() itself is being used to fix another bug.

    Posted 13 years ago on Wednesday September 8, 2010 | Permalink
  2. MMC
    Member

    Just to expand, I think this is a bug. From what I could tell, it's because $wpdb->get_var("SELECT LAST_INSERT_ID();"); performs a separate query to the database for all connections, so if there's a select, update or a different insert via another db connection it will pick up that insert id (usually 0, because there are so many selects). Whereas $wpdb sets $wpdb->insert_id specifically using the current connection resource and immediately after the insert takes place.

    Posted 13 years ago on Thursday September 9, 2010 | Permalink
  3. Using $wpdb->insert_id does seem to be the better solution. I will have that changed in the next release. There isn't any special reason why the LAST_INSERT_ID() is used, so you can go ahead and make the change on your end in the meantime.
    Thanks for the detailed post.

    Posted 13 years ago on Thursday September 9, 2010 | Permalink
  4. MMC
    Member

    Great :)

    Just wanted to point out that there's two other places in RGFormsModel where the LAST_INSERT_ID query is used, and I didn't find it in any other files.

    Specifically lines 361, 577, and 1027 in forms_model.php (version 1.3.11)

    Posted 13 years ago on Thursday September 9, 2010 | Permalink