MediaWiki  master
MySQLPlatform.php
Go to the documentation of this file.
1 <?php
20 namespace Wikimedia\Rdbms\Platform;
21 
23 
28 class MySQLPlatform extends SQLPlatform {
35  public function addIdentifierQuotes( $s ) {
36  // Characters in the range \u0001-\uFFFF are valid in a quoted identifier
37  // Remove NUL bytes and escape backticks by doubling
38  return '`' . str_replace( [ "\0", '`' ], [ '', '``' ], $s ) . '`';
39  }
40 
45  public function isQuotedIdentifier( $name ) {
46  return strlen( $name ) && $name[0] == '`' && substr( $name, -1, 1 ) == '`';
47  }
48 
49  public function buildStringCast( $field ) {
50  return "CAST( $field AS BINARY )";
51  }
52 
57  public function buildIntegerCast( $field ) {
58  return 'CAST( ' . $field . ' AS SIGNED )';
59  }
60 
61  protected function normalizeJoinType( string $joinType ) {
62  switch ( strtoupper( $joinType ) ) {
63  case 'STRAIGHT_JOIN':
64  case 'STRAIGHT JOIN':
65  return 'STRAIGHT_JOIN';
66 
67  default:
68  return parent::normalizeJoinType( $joinType );
69  }
70  }
71 
76  public function useIndexClause( $index ) {
77  return "FORCE INDEX (" . $this->indexName( $index ) . ")";
78  }
79 
84  public function ignoreIndexClause( $index ) {
85  return "IGNORE INDEX (" . $this->indexName( $index ) . ")";
86  }
87 
88  public function deleteJoinSqlText( $delTable, $joinTable, $delVar, $joinVar, $conds ) {
89  if ( !$conds ) {
90  throw new DBLanguageError( __METHOD__ . ' called with empty $conds' );
91  }
92 
93  $delTable = $this->tableName( $delTable );
94  $joinTable = $this->tableName( $joinTable );
95  $sql = "DELETE $delTable FROM $delTable, $joinTable WHERE $delVar=$joinVar ";
96 
97  if ( $conds != '*' ) {
98  $sql .= ' AND ' . $this->makeList( $conds, self::LIST_AND );
99  }
100 
101  return $sql;
102  }
103 
104  public function isTransactableQuery( $sql ) {
105  return parent::isTransactableQuery( $sql ) &&
106  !preg_match( '/^SELECT\s+(GET|RELEASE|IS_FREE)_LOCK\‍(/', $sql );
107  }
108 
109  public function buildExcludedValue( $column ) {
110  /* @see DatabaseMysqlBase::doUpsert() */
111  // Within "INSERT INTO ON DUPLICATE KEY UPDATE" statements:
112  // - MySQL>= 8.0.20 supports and prefers "VALUES ... AS".
113  // - MariaDB >= 10.3.3 supports and prefers VALUE().
114  // - Both support the old VALUES() function
115  // https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html
116  // https://mariadb.com/kb/en/insert-on-duplicate-key-update/
117  return "VALUES($column)";
118  }
119 
120  public function lockSQLText( $lockName, $timeout ) {
121  $encName = $this->quoter->addQuotes( $this->makeLockName( $lockName ) );
122  // Unlike NOW(), SYSDATE() gets the time at invocation rather than query start.
123  // The precision argument is silently ignored for MySQL < 5.6 and MariaDB < 5.3.
124  // https://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_sysdate
125  // https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html
126  return "SELECT IF(GET_LOCK($encName,$timeout),UNIX_TIMESTAMP(SYSDATE(6)),NULL) AS acquired";
127  }
128 
129  public function lockIsFreeSQLText( $lockName ) {
130  $encName = $this->quoter->addQuotes( $this->makeLockName( $lockName ) );
131  return "SELECT IS_FREE_LOCK($encName) AS unlocked";
132  }
133 
134  public function unlockSQLText( $lockName ) {
135  $encName = $this->quoter->addQuotes( $this->makeLockName( $lockName ) );
136  return "SELECT RELEASE_LOCK($encName) AS released";
137  }
138 
139  public function makeLockName( $lockName ) {
140  // https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html#function_get-lock
141  // MySQL 5.7+ enforces a 64 char length limit.
142  return ( strlen( $lockName ) > 64 ) ? sha1( $lockName ) : $lockName;
143  }
144 }
const LIST_AND
Definition: Defines.php:43
buildExcludedValue( $column)
Build a reference to a column value from the conflicting proposed upsert() row.
deleteJoinSqlText( $delTable, $joinTable, $delVar, $joinVar, $conds)
buildStringCast( $field)
Field or column to cast string 1.28 in IDatabase, moved to ISQLPlatform in 1.39Stability: stableto ov...
normalizeJoinType(string $joinType)
Validate and normalize a join type.
isTransactableQuery( $sql)
Determine whether a SQL statement is sensitive to isolation level.
addIdentifierQuotes( $s)
MySQL uses backticks for identifier quoting instead of the sql standard "double quotes".
indexName( $index)
Allows for index remapping in queries where this is not consistent across DBMS.
makeList(array $a, $mode=self::LIST_COMMA)
Makes an encoded list of strings from an array.
tableName( $name, $format='quoted')
Format a table name ready for use in constructing an SQL query.This does two important things: it quo...
foreach( $mmfl['setupFiles'] as $fileName) if( $queue) if(empty( $mmfl['quiet'])) $s