r85884 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r85883‎ | r85884 | r85885 >
Date:16:34, 12 April 2011
Author:platonides
Status:resolved (Comments)
Tags:brion 
Comment:
Abstract tableName() by adding new function isQuotedIdentifier() to databases.
This fixes bug in DatabaseOracle.php tableName() on line 671 and allows it to call
the parent implementation instead of copying it with different quotes.
Adapt Mssql addIdentifierQuotes(). Replace its addIdentifierQuotes calls with addQuotes
as it's what it really is. The serialize() is probably unneeded, since I don't think it will
ever be called with objects but I kept it anyway.
Modified paths:
  • /trunk/phase3/includes/db/Database.php (modified) (history)
  • /trunk/phase3/includes/db/DatabaseMssql.php (modified) (history)
  • /trunk/phase3/includes/db/DatabaseMysql.php (modified) (history)
  • /trunk/phase3/includes/db/DatabaseOracle.php (modified) (history)
  • /trunk/phase3/includes/db/DatabaseSqlite.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/db/DatabaseMysql.php
@@ -329,6 +329,10 @@
330330 return "`" . $this->strencode( $s ) . "`";
331331 }
332332
 333+ public function isQuotedIdentifier( $name ) {
 334+ return $name[0] == '`' && substr( $name, -1, 1 ) == '`';
 335+ }
 336+
333337 function ping() {
334338 $ping = mysql_ping( $this->mConn );
335339 if ( $ping ) {
Index: trunk/phase3/includes/db/DatabaseOracle.php
@@ -648,46 +648,7 @@
649649 break;
650650 }
651651
652 - /*
653 - The rest of procedure is equal to generic Databse class
654 - except for the quoting style
655 - */
656 - if ( $name[0] == '"' && substr( $name, - 1, 1 ) == '"' ) {
657 - return $name;
658 - }
659 - if ( preg_match( '/(^|\s)(DISTINCT|JOIN|ON|AS)(\s|$)/i', $name ) !== 0 ) {
660 - return $name;
661 - }
662 - $dbDetails = array_reverse( explode( '.', $name, 2 ) );
663 - if ( isset( $dbDetails[1] ) ) {
664 - @list( $table, $database ) = $dbDetails;
665 - } else {
666 - @list( $table ) = $dbDetails;
667 - }
668 -
669 - $prefix = $this->mTablePrefix;
670 -
671 - if ( isset( $database ) ) {
672 - $table = ( $table[0] == '`' ? $table : "`{$table}`" );
673 - }
674 -
675 - if ( !isset( $database ) && isset( $wgSharedDB ) && $table[0] != '"'
676 - && isset( $wgSharedTables )
677 - && is_array( $wgSharedTables )
678 - && in_array( $table, $wgSharedTables )
679 - ) {
680 - $database = $wgSharedDB;
681 - $prefix = isset( $wgSharedPrefix ) ? $wgSharedPrefix : $prefix;
682 - }
683 -
684 - if ( isset( $database ) ) {
685 - $database = ( $database[0] == '"' ? $database : "\"{$database}\"" );
686 - }
687 - $table = ( $table[0] == '"') ? $table : "\"{$prefix}{$table}\"" ;
688 -
689 - $tableName = ( isset( $database ) ? "{$database}.{$table}" : "{$table}" );
690 -
691 - return strtoupper( $tableName );
 652+ return parent::tableName( strtoupper( $name ) );
692653 }
693654
694655 /**
Index: trunk/phase3/includes/db/Database.php
@@ -1521,7 +1521,7 @@
15221522 # Note that we check the end so that we will still quote any use of
15231523 # use of `database`.table. But won't break things if someone wants
15241524 # to query a database table with a dot in the name.
1525 - if ( $name[0] == '`' && substr( $name, -1, 1 ) == '`' ) {
 1525+ if ( $this->isQuotedIdentifier( $name ) ) {
15261526 return $name;
15271527 }
15281528
@@ -1550,14 +1550,14 @@
15511551 # A database name has been specified in input. Quote the table name
15521552 # because we don't want any prefixes added.
15531553 if ( isset( $database ) ) {
1554 - $table = ( $table[0] == '`' ? $table : "`{$table}`" );
 1554+ $table = ( $this->isQuotedIdentifier( $table ) ? $table : $this->addIdentifierQuotes( $table ) );
15551555 }
15561556
15571557 # Note that we use the long format because php will complain in in_array if
15581558 # the input is not an array, and will complain in is_array if it is not set.
15591559 if ( !isset( $database ) # Don't use shared database if pre selected.
15601560 && isset( $wgSharedDB ) # We have a shared database
1561 - && $table[0] != '`' # Paranoia check to prevent shared tables listing '`table`'
 1561+ && !$this->isQuotedIdentifier( $table ) # Paranoia check to prevent shared tables listing '`table`'
15621562 && isset( $wgSharedTables )
15631563 && is_array( $wgSharedTables )
15641564 && in_array( $table, $wgSharedTables ) ) { # A shared table is selected
@@ -1567,9 +1567,9 @@
15681568
15691569 # Quote the $database and $table and apply the prefix if not quoted.
15701570 if ( isset( $database ) ) {
1571 - $database = ( $database[0] == '`' ? $database : "`{$database}`" );
 1571+ $database = ( $this->isQuotedIdentifier( $database ) ? $database : $this->addIdentifierQuotes( $database ) );
15721572 }
1573 - $table = ( $table[0] == '`' ? $table : "`{$prefix}{$table}`" );
 1573+ $table = ( $this->isQuotedIdentifier( $table ) ? $table : $this->addIdentifierQuotes( "{$prefix}{$table}" ) );
15741574
15751575 # Merge our database and table into our final table name.
15761576 $tableName = ( isset( $database ) ? "{$database}.{$table}" : "{$table}" );
@@ -1747,6 +1747,15 @@
17481748 }
17491749
17501750 /**
 1751+ * Returns if the given identifier looks quoted or not according to
 1752+ * the database convention for quoting identifiers .
 1753+ * @return boolean
 1754+ */
 1755+ public function isQuotedIdentifier( $name ) {
 1756+ return $name[0] == '"' && substr( $name, -1, 1 ) == '"';
 1757+ }
 1758+
 1759+ /**
17511760 * Backwards compatibility, identifier quoting originated in DatabasePostgres
17521761 * which used quote_ident which does not follow our naming conventions
17531762 * was renamed to addIdentifierQuotes.
Index: trunk/phase3/includes/db/DatabaseMssql.php
@@ -452,14 +452,14 @@
453453 $sql .= ',';
454454 }
455455 if ( is_string( $value ) ) {
456 - $sql .= $this->addIdentifierQuotes( $value );
 456+ $sql .= $this->addQuotes( $value );
457457 } elseif ( is_null( $value ) ) {
458458 $sql .= 'null';
459459 } elseif ( is_array( $value ) || is_object( $value ) ) {
460460 if ( is_object( $value ) && strtolower( get_class( $value ) ) == 'blob' ) {
461 - $sql .= $this->addIdentifierQuotes( $value->fetch() );
 461+ $sql .= $this->addQuotes( $value );
462462 } else {
463 - $sql .= $this->addIdentifierQuotes( serialize( $value ) );
 463+ $sql .= $this->addQuotes( serialize( $value ) );
464464 }
465465 } else {
466466 $sql .= $value;
@@ -989,6 +989,15 @@
990990 }
991991 }
992992
 993+ public function addIdentifierQuotes( $s ) {
 994+ // http://msdn.microsoft.com/en-us/library/aa223962.aspx
 995+ return '[' . $s . ']';
 996+ }
 997+
 998+ public function isQuotedIdentifier( $name ) {
 999+ return $name[0] == '[' && substr( $name, -1, 1 ) == ']';
 1000+ }
 1001+
9931002 function selectDB( $db ) {
9941003 return ( $this->query( "SET DATABASE $db" ) !== false );
9951004 }
Index: trunk/phase3/includes/db/DatabaseSqlite.php
@@ -257,7 +257,7 @@
258258 function tableName( $name ) {
259259 // table names starting with sqlite_ are reserved
260260 if ( strpos( $name, 'sqlite_' ) === 0 ) return $name;
261 - return str_replace( '`', '', parent::tableName( $name ) );
 261+ return str_replace( '"', '', parent::tableName( $name ) );
262262 }
263263
264264 /**

Follow-up revisions

RevisionCommit summaryAuthorDate
r85886No need to quote just to avoid the prefixes.platonides16:57, 12 April 2011
r85888Add parameter to tableName() to get the bare table name.platonides17:00, 12 April 2011
r85907Follow up r85888: Add the parameter to DatabasePostgres.php and DatabaseOracl...platonides18:59, 12 April 2011
r87178Followup r85884...reedy23:18, 30 April 2011

Comments

#Comment by Catrope (talk | contribs)   21:45, 30 April 2011
<Reedy>	Platonides, about?
<Reedy>	You seem to have broken table aliasing in [[Special:Code/MediaWiki/85884|r85884]] (and possibly later commits)
<Reedy>	api.php?action=query&list=allusers&augroup=sysop
<Reedy>	Ending up with stuff like INNER JOIN `mw_`mw_user_groups` ug1` ON ((ug1.ug_user=user_id) AND ug1.ug_group = 'sysop')
<RoanKattouw>	Even without prefixes, I get INNER JOIN ``user_groups` ug1`

I quickly tried whether reverting this rev (r85884) along with r85886, r85888, r85905, r85907 and r87143 but I got a few (fairly trivial conflicts) and it removes other useful things (such as arrays for ORDER BY) so that's not a great way of fixing this. Would be great if you could Just Fix It, or revert the feature cleanly.

#Comment by Aaron Schulz (talk | contribs)   21:03, 27 June 2011

Are there still problems with this?

#Comment by Aaron Schulz (talk | contribs)   21:51, 1 September 2011

Seems OK now...

Status & tagging log