Example #1
0
 public function selectSQLText($table, $vars, $conds = '', $fname = __METHOD__, $options = [], $join_conds = [])
 {
     // Change the FOR UPDATE option as necessary based on the join conditions. Then pass
     // to the parent function to get the actual SQL text.
     // In Postgres when using FOR UPDATE, only the main table and tables that are inner joined
     // can be locked. That means tables in an outer join cannot be FOR UPDATE locked. Trying to
     // do so causes a DB error. This wrapper checks which tables can be locked and adjusts it
     // accordingly.
     // MySQL uses "ORDER BY NULL" as an optimization hint, but that is illegal in PostgreSQL.
     if (is_array($options)) {
         $forUpdateKey = array_search('FOR UPDATE', $options, true);
         if ($forUpdateKey !== false && $join_conds) {
             unset($options[$forUpdateKey]);
             foreach ($join_conds as $table_cond => $join_cond) {
                 if (0 === preg_match('/^(?:LEFT|RIGHT|FULL)(?: OUTER)? JOIN$/i', $join_cond[0])) {
                     $options['FOR UPDATE'][] = $table_cond;
                 }
             }
         }
         if (isset($options['ORDER BY']) && $options['ORDER BY'] == 'NULL') {
             unset($options['ORDER BY']);
         }
     }
     return parent::selectSQLText($table, $vars, $conds, $fname, $options, $join_conds);
 }
Example #2
0
 /**
  * Change the FOR UPDATE option as necessary based on the join conditions. Then pass
  * to the parent function to get the actual SQL text.
  *
  * In Postgres when using FOR UPDATE, only the main table and tables that are inner joined
  * can be locked. That means tables in an outer join cannot be FOR UPDATE locked. Trying to do
  * so causes a DB error. This wrapper checks which tables can be locked and adjusts it accordingly.
  *
  * MySQL uses "ORDER BY NULL" as an optimization hint, but that syntax is illegal in PostgreSQL.
  * @see DatabaseBase::selectSQLText
  */
 function selectSQLText($table, $vars, $conds = '', $fname = __METHOD__, $options = array(), $join_conds = array())
 {
     if (is_array($options)) {
         $forUpdateKey = array_search('FOR UPDATE', $options, true);
         if ($forUpdateKey !== false && $join_conds) {
             unset($options[$forUpdateKey]);
             foreach ($join_conds as $table_cond => $join_cond) {
                 if (0 === preg_match('/^(?:LEFT|RIGHT|FULL)(?: OUTER)? JOIN$/i', $join_cond[0])) {
                     $options['FOR UPDATE'][] = $table_cond;
                 }
             }
         }
         if (isset($options['ORDER BY']) && $options['ORDER BY'] == 'NULL') {
             unset($options['ORDER BY']);
         }
     }
     return parent::selectSQLText($table, $vars, $conds, $fname, $options, $join_conds);
 }
Example #3
0
 /**
  * SELECT wrapper
  *
  * @param mixed $table Array or string, table name(s) (prefix auto-added)
  * @param mixed $vars Array or string, field name(s) to be retrieved
  * @param mixed $conds Array or string, condition(s) for WHERE
  * @param string $fname Calling function name (use __METHOD__) for logs/profiling
  * @param array $options Associative array of options (e.g. array('GROUP BY' => 'page_title')),
  *   see Database::makeSelectOptions code for list of supported stuff
  * @param array $join_conds Associative array of table join conditions (optional)
  *    (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
  * @return string The SQL text
  */
 public function selectSQLText($table, $vars, $conds = '', $fname = __METHOD__, $options = array(), $join_conds = array())
 {
     if (isset($options['EXPLAIN'])) {
         unset($options['EXPLAIN']);
     }
     $sql = parent::selectSQLText($table, $vars, $conds, $fname, $options, $join_conds);
     // try to rewrite aggregations of bit columns (currently MAX and MIN)
     if (strpos($sql, 'MAX(') !== false || strpos($sql, 'MIN(') !== false) {
         $bitColumns = array();
         if (is_array($table)) {
             foreach ($table as $t) {
                 $bitColumns += $this->getBitColumns($this->tableName($t));
             }
         } else {
             $bitColumns = $this->getBitColumns($this->tableName($table));
         }
         foreach ($bitColumns as $col => $info) {
             $replace = array("MAX({$col})" => "MAX(CAST({$col} AS tinyint))", "MIN({$col})" => "MIN(CAST({$col} AS tinyint))");
             $sql = str_replace(array_keys($replace), array_values($replace), $sql);
         }
     }
     return $sql;
 }