As a result of #1868972: db_query_temporary() fails to create a table when the SQL has leading whitespace, db_query_temporary() cannot be used on a non-SELECT query at all.

Before it would work (basically it would run the query it was given, although not using any kind of temporary tables at all), but after that issue there will be an error. This change was made in Drupal 8, and (perhaps slightly against my better judgment) is now in Drupal 7 as well.

Drupal 6 already documents that the function should only be used for SELECT queries, but Drupal 7 and Drupal 8 don't. We could add similar documentation to this function as db_query() already has, although the difference is with db_query() it's basically just a recommendation (for cross-database-driver compatibility) but now for db_query_temporary() it's a requirement.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

David_Rothstein’s picture

Issue summary: View changes
jweowu’s picture

It's true that you could pass non-SELECT queries before and have them executed, but there was no purpose to doing so. Anyone choosing to call db_query_temporary() rather than db_query() is doing so in order to get results into a temporary table, so any use of this function which fails to carry out that critical aspect is surely a bug.

Unless we're considering code that just passes arbitrary queries to db_query_temporary() (and then checks to see if the table exists?), but I'd be worried if anyone's writing code like that.

Note that for some databases, the new code will actually be a little more flexible. With Postgres, for example, you could now pass it "A SELECT, TABLE, or VALUES command, or an EXECUTE command that runs a prepared SELECT, TABLE, or VALUES query".

MySQL will still be restricted to SELECT, so that fact is of no use to core or contrib code, but it may warrant a mention if the docstring is being edited?

David_Rothstein’s picture

Right, so I tried this with db_query_temporary("TRUNCATE {cache}") (on MySQL) and before the patch it would execute the query just like db_query() itself does (though of course not actually do anything with temporary tables). After the patch it results in a PDOException.

I agree that anyone doing that is doing something wrong already (because it doesn't make much sense to use that function), but still seems like it would be useful to document the correct usage.

jweowu’s picture

Yes, I agree 100% with documenting the correct usage.

jweowu’s picture

As far as the function docstring goes, is this all we need to change?

I concluded that commenting on the abilities of the various different databases is probably an unnecessary complication (especially as getting temporary data from other queries with this function was never an option before).

People can still use db_query() to run a hand-written CREATE TEMPORARY TABLE query if they need to do something database-specific; so although this function could accept non-SELECT query strings in some situations, it feels okay to document SELECT as a requirement.

jhodgdon’s picture

Status: Active » Reviewed & tested by the community

This looks like the correct fix to me. Thanks!

webchick’s picture

Version: 8.x-dev » 7.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Great, thanks!

Committed and pushed to 8.x. Moving down to 7.x.

  • Commit 86b3e05 on 8.x by webchick:
    Issue #2259361 by jweowu | David_Rothstein: Document that...
jweowu’s picture

Status: Patch (to be ported) » Needs review
FileSize
1.1 KB

7.x version. Documentation is identical to 8.x.

jhodgdon’s picture

Status: Needs review » Reviewed & tested by the community

Thanks! Looks like the right port for D7.

  • Commit 4172af5 on 7.x by jhodgdon:
    Issue #2259361 by jweowu, David_Rothstein: Document that...
jhodgdon’s picture

Status: Reviewed & tested by the community » Fixed

Thanks again! Committed to 7.x.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.