You are here

public function Connection::preprocessQuery in Drupal driver for SQL Server and SQL Azure 4.2.x

Same name and namespace in other branches
  1. 3.1.x src/Driver/Database/sqlsrv/Connection.php \Drupal\sqlsrv\Driver\Database\sqlsrv\Connection::preprocessQuery()
  2. 4.0.x src/Driver/Database/sqlsrv/Connection.php \Drupal\sqlsrv\Driver\Database\sqlsrv\Connection::preprocessQuery()
  3. 4.1.x src/Driver/Database/sqlsrv/Connection.php \Drupal\sqlsrv\Driver\Database\sqlsrv\Connection::preprocessQuery()

Massage a query to make it compliant with SQL Server.

Parameters

mixed $query: Query string.

Return value

string Query string in MS SQL format.

1 call to Connection::preprocessQuery()
Connection::prepareStatement in src/Driver/Database/sqlsrv/Connection.php

File

src/Driver/Database/sqlsrv/Connection.php, line 842

Class

Connection
Sqlsvr implementation of \Drupal\Core\Database\Connection.

Namespace

Drupal\sqlsrv\Driver\Database\sqlsrv

Code

public function preprocessQuery($query) {

  // Last chance to modify some SQL Server-specific syntax.
  $replacements = [];

  // Add prefixes to Drupal-specific functions.

  /** @var \Drupal\sqlsrv\Driver\Database\sqlsrv\Schema $schema */
  $schema = $this
    ->schema();
  $defaultSchema = $schema
    ->GetDefaultSchema();
  foreach ($schema
    ->DrupalSpecificFunctions() as $function) {
    $replacements['/\\b(?<![:.])(' . preg_quote($function) . ')\\(/i'] = "{$defaultSchema}.\$1(";
  }

  // Rename some functions.
  $funcs = [
    'LENGTH' => 'LEN',
    'POW' => 'POWER',
  ];
  foreach ($funcs as $function => $replacement) {
    $replacements['/\\b(?<![:.])(' . preg_quote($function) . ')\\(/i'] = $replacement . '(';
  }

  // Replace the ANSI concatenation operator with SQL Server poor one.
  $replacements['/\\|\\|/'] = '+';

  // Now do all the replacements at once.
  $query = preg_replace(array_keys($replacements), array_values($replacements), $query);

  // Substitute the LEAST operator with something that works in SQL Server.
  while (($pos1 = strpos($query, 'LEAST(')) !== FALSE) {
    $name_length = 5;
    $pos2 = $this
      ->findParenMatch($query, $pos1 + $name_length);
    $argument_list = substr($query, $pos1 + $name_length + 1, $pos2 - $name_length - 1 - $pos1);
    $arguments = explode(', ', $argument_list);
    $new_arguments = implode('), (', $arguments);
    $replace = '(SELECT MIN(i) FROM (VALUES (' . $new_arguments . ')) AS T(i)) sqlsrv_least';
    $query = substr($query, 0, $pos1) . $replace . substr($query, $pos2 + 1);
  }
  return $query;
}