I posted an example on the Writing secure code page, and the patch is attached. Simply, str_repeat is going to scale better than two function calls that create two different structures. Additionally, the current code issues a warning when no parameters are provided. The following pages (among others) should be modified if this change is applied:

http://drupal.org/writing-secure-code
http://drupal.org/node/101496

I am open to stylistic changes, so please let me know if you want mt to spell out the ternary with an if/else.

Thanks!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Dries’s picture

Adding a line of documentation, and using a regular if-statement would improve readability a lot, IMO.

jrchamp’s picture

This patch uses a regular if-statement and has an added line of documentation (hopefully it is in line with what you had in mind). Also, I reversed the order of the str_repeat so that it is clear that the first one is assumed and any additional ones are appended. This mindset seems to be more straightforward than "repeat all but the last one, then append the last one".

Please let me know if the documentation I added is inadequate, the formatting is incorrect, or you notice any other issue. Thank you!

Crell’s picture

Version: 7.x-dev » 6.x-dev

db_placeholders() is deprecated in Drupal 7 and will be removed as soon as it is expunged from core. This could be a useful performance enhancement for Drupal 6. I defer to Gabor on that front.

jrchamp’s picture

Alright. Here is the same patch, instead against the Drupal 6 tag.

[edit] How do I get in touch with Gabor?

jrchamp’s picture

@Crell: Thanks to #474072: Use taxonomy_load functions in blogapi.module, db_placeholders() is expunged from core. Should I open an issue with a patch which simply removes it from core?

Crell’s picture

@jrchamp: Please do!

Crell’s picture

Wait, never mind, it's already been taken care of: #508756: RIP db_placeholders()

The rest of this issue is still relevant for Drupal 6, though.

mikeytown2’s picture

Category: task » bug
Priority: Minor » Critical
Issue tags: +Performance
FileSize
1.37 KB

array_fill "Throws a E_WARNING if num is less than one."

Fresh install of 6.17 on ubuntu 10.04 throws this error

warning: array_fill(): Number of elements must be positive in includes/database.inc on line 253.
warning: implode(): Invalid arguments passed in includes/database.inc on line 253.

http://api.drupal.org/api/function/db_placeholders/6

Re-rolled #4

mikeytown2’s picture

Category: bug » task
Priority: Critical » Normal

not a bug. This was the issue I was having
http://drupal.org/node/833486
Patch is still valid

jrchamp’s picture

Technically, it is a bug that a situation exists where an empty array is passed in which causes array_fill to throw a warning.

The solution depends on viewpoint. The calling function could verify that it has some work to perform (i.e. verify that the array is not empty) before passing in the values. Or the calling function should expect the parameters to be validated by the function being called (which has the benefit of collapsing the logic in to the function itself, but does not prevent the *useless* query from being executed which is likely worse for performance).

Of course, the patch on this issue returns empty string for the 0 case, which - although it avoids the array_fill and implode warnings - has the disadvantage of still resulting in an SQL syntax error. This might not be a problem. Rather, it could be viewed as "here is a place which doesn't adequately determine whether it should even execute a query before it does so". I believe this is the best viewpoint, because avoiding wasteful queries is a big +1. If, however, the goal is to silence such syntax errors, the zero case for this function should return the string containing the empty string as follows:

  return "''";
Damien Tournoud’s picture

Status: Needs review » Needs work

I'm not at all convinced that this way is any better.

Damien Tournoud’s picture

Status: Needs work » Needs review

Wasn't meaning to change the status.

jrchamp’s picture

I believe this is better for the following reasons:

  • Average code execution in my testing is up to twice as fast
  • Warnings are not wastefully triggered by the zero case (4300x as fast)
  • The code is easier to read

I have attached a modified version which saves time in the zero case and is much more competitive (similar to HEAD) in the one case.

jrchamp’s picture

Rerolled.

Status: Needs review » Needs work
Issue tags: -Performance

The last submitted patch, db_placeholders_performance-485618-14.patch, failed testing.

jrchamp’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work
Issue tags: +Performance

The last submitted patch, db_placeholders_performance-485618-14.patch, failed testing.

jrchamp’s picture

Status: Needs work » Needs review
FileSize
945 bytes

Status: Needs review » Needs work

The last submitted patch, db_placeholders_performance-485618-18.patch, failed testing.

jrchamp’s picture

Rerolling again. I don't understand why this keeps failing.

jrchamp’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, db_placeholders_performance-485618-20.patch, failed testing.

jrchamp’s picture

Status: Needs work » Needs review
FileSize
990 bytes

I can't get the test bot to be happy with the patch, Drupal 7 is out and this probably doesn't matter in the larger scheme of things.

It might still be good to update http://drupal.org/writing-secure-code

Status: Needs review » Needs work

The last submitted patch, db_placeholders_performance-485618-23.patch, failed testing.

jrchamp’s picture

Status: Needs work » Needs review
FileSize
810 bytes

Git reroll.

Status: Needs review » Needs work

The last submitted patch, db_placeholders_performance-485618-25.patch, failed testing.

mikeytown2’s picture

Status: Needs work » Needs review
FileSize
810 bytes

Re-roll #25

pdrake’s picture

Status: Needs review » Reviewed & tested by the community

This patch applied cleanly and works well for me.

Gábor Hojtsy’s picture

Status: Reviewed & tested by the community » Needs review

Warnings are not wastefully triggered by the zero case (4300x as fast)

Not sure about this one. I've seen several debugging sessions where warnings about the zero case for an IN query helped debug the issue. Sounds like your change would kill the messages there, so people would just get an empty result set back instead of any errors(?). While the issue is not in fact here but the caller invoking with an empty placeholder set. If we gracefully swallow that error, we just make it harder to debug the issues no?

pdrake’s picture

While the PHP Warning(s) about array_fill() requiring a positive number of elements and invalid arguments passed to implode() will no longer occur, with an IN query, the database will still error with an invalid syntax message which should be sufficient.

mahendra.sharma’s picture

db_placeholders_performance.patch queued for re-testing.

hefox’s picture

I recall the PHP warnings indicating something is wrong (in some cases it didn't produce a mysql error perhaps). Should db_placeholders really silently handle being called with wrong arguments? IMO no, trying to optimize error condition seems wrong.

Other than that, patch looks nice, plan to try it out

Status: Needs review » Closed (outdated)

Automatically closed because Drupal 6 is no longer supported. If the issue verifiably applies to later versions, please reopen with details and update the version.