MediaWiki  master
MySQLPlatform.php
Go to the documentation of this file.
1 <?php
20 namespace Wikimedia\Rdbms\Platform;
21 
24 
29 class MySQLPlatform extends SQLPlatform {
36  public function addIdentifierQuotes( $s ) {
37  // Characters in the range \u0001-\uFFFF are valid in a quoted identifier
38  // Remove NUL bytes and escape backticks by doubling
39  return '`' . str_replace( [ "\0", '`' ], [ '', '``' ], $s ) . '`';
40  }
41 
46  public function isQuotedIdentifier( $name ) {
47  return strlen( $name ) > 1 && $name[0] === '`' && $name[-1] === '`';
48  }
49 
50  public function buildStringCast( $field ) {
51  return "CAST( $field AS BINARY )";
52  }
53 
58  public function buildIntegerCast( $field ) {
59  return 'CAST( ' . $field . ' AS SIGNED )';
60  }
61 
62  protected function normalizeJoinType( string $joinType ) {
63  switch ( strtoupper( $joinType ) ) {
64  case 'STRAIGHT_JOIN':
65  case 'STRAIGHT JOIN':
66  return 'STRAIGHT_JOIN';
67 
68  default:
69  return parent::normalizeJoinType( $joinType );
70  }
71  }
72 
77  public function useIndexClause( $index ) {
78  return "FORCE INDEX (" . $this->indexName( $index ) . ")";
79  }
80 
85  public function ignoreIndexClause( $index ) {
86  return "IGNORE INDEX (" . $this->indexName( $index ) . ")";
87  }
88 
89  public function deleteJoinSqlText( $delTable, $joinTable, $delVar, $joinVar, $conds ) {
90  if ( !$conds ) {
91  throw new DBLanguageError( __METHOD__ . ' called with empty $conds' );
92  }
93 
94  $delTable = $this->tableName( $delTable );
95  $joinTable = $this->tableName( $joinTable );
96  $sql = "DELETE $delTable FROM $delTable, $joinTable WHERE $delVar=$joinVar ";
97 
98  if ( $conds != '*' ) {
99  $sql .= ' AND ' . $this->makeList( $conds, self::LIST_AND );
100  }
101 
102  return $sql;
103  }
104 
105  public function isTransactableQuery( Query $sql ) {
106  return parent::isTransactableQuery( $sql ) &&
107  // TODO: Use query verb
108  !preg_match( '/^SELECT\s+(GET|RELEASE|IS_FREE)_LOCK\‍(/', $sql->getSQL() );
109  }
110 
111  public function buildExcludedValue( $column ) {
112  /* @see DatabaseMySQL::upsert() */
113  // Within "INSERT INTO ON DUPLICATE KEY UPDATE" statements:
114  // - MySQL>= 8.0.20 supports and prefers "VALUES ... AS".
115  // - MariaDB >= 10.3.3 supports and prefers VALUE().
116  // - Both support the old VALUES() function
117  // https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html
118  // https://mariadb.com/kb/en/insert-on-duplicate-key-update/
119  return "VALUES($column)";
120  }
121 
122  public function lockSQLText( $lockName, $timeout ) {
123  $encName = $this->quoter->addQuotes( $this->makeLockName( $lockName ) );
124  // Unlike NOW(), SYSDATE() gets the time at invocation rather than query start.
125  // The precision argument is silently ignored for MySQL < 5.6 and MariaDB < 5.3.
126  // https://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_sysdate
127  // https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html
128  return "SELECT IF(GET_LOCK($encName,$timeout),UNIX_TIMESTAMP(SYSDATE(6)),NULL) AS acquired";
129  }
130 
131  public function lockIsFreeSQLText( $lockName ) {
132  $encName = $this->quoter->addQuotes( $this->makeLockName( $lockName ) );
133  return "SELECT IS_FREE_LOCK($encName) AS unlocked";
134  }
135 
136  public function unlockSQLText( $lockName ) {
137  $encName = $this->quoter->addQuotes( $this->makeLockName( $lockName ) );
138  return "SELECT RELEASE_LOCK($encName) AS released";
139  }
140 
141  public function makeLockName( $lockName ) {
142  // https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html#function_get-lock
143  // MySQL 5.7+ enforces a 64 char length limit.
144  return ( strlen( $lockName ) > 64 ) ? sha1( $lockName ) : $lockName;
145  }
146 }
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(Query $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...
Holds information on Query to be executed.
Definition: Query.php:31