D6 CVS HEAD contain the following codes:
find drupal | xargs egrep -nH "WHERE.*= ''"
drupal/modules/node/node.admin.inc:364: $count = db_result(db_query("SELECT COUNT(*) FROM {node} n WHERE language != ''"));
drupal/modules/system/system.module:1194: $instances_present = db_fetch_object(db_query("SELECT aid FROM {actions} WHERE parameters != ''"));
drupal/modules/locale/locale.install:104: $ret[] = update_sql("DELETE FROM {locales_target} WHERE translation = ''");
drupal/modules/path/path.admin.inc:18: $count = db_result(db_query("SELECT COUNT(*) FROM {url_alias} WHERE language != ''"));
drupal/includes/actions.inc:242: $aid = db_result(db_query("SELECT aid FROM {actions} WHERE MD5(aid) = '%s' AND parameters != ''", $hash));
drupal/includes/actions.inc:259: $result = db_query("SELECT * FROM {actions} WHERE parameters = ''");
Using empty string '' as default string placeholder may cause cross database incompatible issue. It is most likely correct in case of MySQL and PgSQL, but not every database are handling in correct ANSI style:
- In case of Oracle, empty string
''is equal to NULL, and so the= ''will always return false. This is all due to Oracle internal handling, which may judge as buggy. This is a DB level problem, PDO can't help about this. - In case of MSSQL, fetching empty string
''by PHP will return as' '(a single space string). Surly that mostif ($value->string == '')checking after db_fetch_array() and db_fetch_object() will result as buggy. This is due to PHP MSSQL driver implementation. This is a PHP driver level problem, PDO also can't help about this.
We may solve this problem by using DB_DEFAULT as default string placeholder, rather than an empty string directly. E.g., in case of Oracle, DB_DEFAULT can define as '_OCI8_DEFAULT_' so it is no longer empty. This will waste some disk space, but code is now portable:
<?php
/**
* Indicates the default string placeholder.
*/
define('DB_DEFAULT', '_OCI8_DEFAULT_');
?>
In case of MySQL/PgSQL, as there is no problem in empty string handling, the mapping can just act as dummy. So no extra disk space will be wasted for cross database compatible:
<?php
/**
* Indicates the default string placeholder.
*/
define('DB_DEFAULT', '');
?>
We need to use DB_DEFAULT for both DB schema, DB level compare and also PHP level compare (just similar as compare with using ''). E.g.:
<?php
db_query("SELECT * FROM {actions} WHERE parameters = '%s'", DB_DEFAULT);
?>
Comments
Comment #1
hswong3i commentedOracle reference:
http://www.techonthenet.com/oracle/questions/empty_null.php
http://www.adp-gmbh.ch/ora/misc/null.html
MSSQL reference:
http://bugs.php.net/bug.php?id=26996
Comment #2
hswong3i commentedComment #3
hswong3i commentedAccording to latest Oracle driver research result, the bug for Oracle and MSSQL should able to handle within driver implementation. In case of Oracle:
DB_EMPTY_STRING_PLACEHOLDERwith random-password-like content:'', replace it asDB_EMPTY_STRING_PLACEHOLDER:''input, replace it asDB_EMPTY_STRING_PLACEHOLDER. So this replacement will preform for whatever SELECT/INSERT/UPDATE/DELETE queries automatically, if placeholder%suse correctly:''if it is equal toDB_EMPTY_STRING_PLACEHOLDER, during db_fetch_object(), db_fetch_array() or db_result():According to this handle, it will require for 2 restriction in global coding standard:
%ssyntax, so driver will able to catch it and handle its conversation within db_escape_string(). This will not conflict with PDO implementation, since we can simply replace all%d|%f|%s|%b|%cas ? in case of MySQL/PgSQL PDO implementation, rather than calling db_escape* in userspace manually. This simple preg_replace() should be cheaper than current _db_query_callback() handling.%sshould use correctly, especially for''. If''is written as inline query, the above catch-and-convert will not able to take action.Comment #4
hswong3i commented(This is part of my personal research project Siren's issue.)
Comment #5
hswong3i commentedComment #6
catch#225450: Database Layer: The Next Generation
Comment #7
dwhlabs commentedOracle reference
http://dwhlabs.com/Databaselab/Oracle/SQL/orac_TUTORIALS_SQL.aspx
About DWHlabs
DWHLabs is an online data management web portal. It offers studies on software topics like Data Modeling, Data Warehousing, Database, ERP, Middle Wear, Testing, and Open Source. Viewers can be a beginner, employee, trainer, consultant or a Professional personality. This application is a best platform to the viewers, where they can share files, participate in discussion boards, share their blogs, and find software training schools in INDIA and abroad, getting answers to the questions.