The docblock of db_query_temporary makes zero sense:
* @param $tablename
* The name of the temporary table to select into. This name will not be
* prefixed as there is no risk of collision.
There is a risk of collision in at least three cases:
* two modules could want to use the same $tablename
* some db engines doesn't support temporary tables and will emulate them using real tables. In that case, two concurrent connections could want to create temporary tables.
* in case of connection pooling (for example pgpool on front of postgresql), PHP runners can share the same connection to the database, so temporary tables could persist and name collision can occur
I suggest we change db_query_temporary() so that $table_name is only a hint, and the real table name used be returned by that function. Thoughts?
Comments
Comment #1
Crell commentedThis makes sense to me. It fits the way field and table aliases work, and safety is generally a good thing. Let's do. :-)
Comment #2
Crell commentedSounds like a possible duplicate of #279041: Temporary Table Creation Should First Check if Table Exists.
Comment #3
damien tournoud commentedHere is a patch for discussion.
Comment #4
damien tournoud commentedLet's try again.
Comment #5
stewsnoozeI had thought of something simple like this. In most cases the caller would actually get the tablename they requested.
Comment #6
damien tournoud commentedWho cares about the table name? And oups, I probably forgot to update the tests.
Comment #7
damien tournoud commentedComment #8
stewsnoozeI was working on this for a while today.
I think that the tests in testTemporaryQuery() would be flawed if we implemented this patch. Effectively we would need to make sure that creating two temporary tables will not clash.
I ended up actually doing the calls to db_query_temporary() in testTemporaryQuery() rather than in a drupalGet as I needed the temporary tables to stick around for a while to make sure they both existed. I think your patch has stronger legs than mine but we need to make sure the tests check properly for the new functionality
Comment #9
stewsnoozeAlso I'm pretty new here!
Comment #10
damien tournoud commented@stewsnooze: welcome, it's great to see new core contributors :)
Here is actually a working patch. I extended the tests to check that two temporary tables can be created in the same request.
Comment #11
damien tournoud commentedLet's see if the test bot wants to pick it up.
Comment #12
Crell commentedThe rest of the DB layer uses keyword_$i, not keyword$i for auto-generated strings such as placeholders. Let's do that here, too. Also, should we perhaps use db_temporary_$i, since we've already reserved the db_ namespace?
Otherwise, this looks good to me on visual inspection. Forcing people to pass around the table name themselves is more loosely coupled than passing a name in in the first place, so +1 on just standardizing on that form. A quick reroll and we should be able to commit this.
Comment #13
Crell commentedComment #14
damien tournoud commentedHere we are, reroll per Crell comments in #12.
Comment #15
Crell commentedI like it, and so does the bot. :-)
The next step should probably be to finish off #332353: [DBTNG + simpletest] missing db_select()->temporary() so that we have parity between static and dynamic queries.
Comment #16
dries commentedAnd so do I. Committed to CVS HEAD. Thanks DamZ. Onto #332353 now. :-)