cms/drupal/includes/database/pgsql/select.inc
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Select builder for PostgreSQL database engine.
       
     6  */
       
     7 
       
     8 /**
       
     9  * @addtogroup database
       
    10  * @{
       
    11  */
       
    12 
       
    13 class SelectQuery_pgsql extends SelectQuery {
       
    14 
       
    15   public function orderRandom() {
       
    16     $alias = $this->addExpression('RANDOM()', 'random_field');
       
    17     $this->orderBy($alias);
       
    18     return $this;
       
    19   }
       
    20 
       
    21   /**
       
    22    * Overrides SelectQuery::orderBy().
       
    23    *
       
    24    * PostgreSQL adheres strictly to the SQL-92 standard and requires that when
       
    25    * using DISTINCT or GROUP BY conditions, fields and expressions that are
       
    26    * ordered on also need to be selected. This is a best effort implementation
       
    27    * to handle the cases that can be automated by adding the field if it is not
       
    28    * yet selected.
       
    29    *
       
    30    * @code
       
    31    *   $query = db_select('node', 'n');
       
    32    *   $query->join('node_revision', 'nr', 'n.vid = nr.vid');
       
    33    *   $query
       
    34    *     ->distinct()
       
    35    *     ->fields('n')
       
    36    *     ->orderBy('timestamp');
       
    37    * @endcode
       
    38    *
       
    39    * In this query, it is not possible (without relying on the schema) to know
       
    40    * whether timestamp belongs to node_revisions and needs to be added or
       
    41    * belongs to node and is already selected. Queries like this will need to be
       
    42    * corrected in the original query by adding an explicit call to
       
    43    * SelectQuery::addField() or SelectQuery::fields().
       
    44    *
       
    45    * Since this has a small performance impact, both by the additional
       
    46    * processing in this function and in the database that needs to return the
       
    47    * additional fields, this is done as an override instead of implementing it
       
    48    * directly in SelectQuery::orderBy().
       
    49    */
       
    50   public function orderBy($field, $direction = 'ASC') {
       
    51     // Call parent function to order on this.
       
    52     $return = parent::orderBy($field, $direction);
       
    53 
       
    54     // If there is a table alias specified, split it up.
       
    55     if (strpos($field, '.') !== FALSE) {
       
    56       list($table, $table_field) = explode('.', $field);
       
    57     }
       
    58     // Figure out if the field has already been added.
       
    59     foreach ($this->fields as $existing_field) {
       
    60       if (!empty($table)) {
       
    61         // If table alias is given, check if field and table exists.
       
    62         if ($existing_field['table'] == $table && $existing_field['field'] == $table_field) {
       
    63           return $return;
       
    64         }
       
    65       }
       
    66       else {
       
    67         // If there is no table, simply check if the field exists as a field or
       
    68         // an aliased field.
       
    69         if ($existing_field['alias'] == $field) {
       
    70           return $return;
       
    71         }
       
    72       }
       
    73     }
       
    74 
       
    75     // Also check expression aliases.
       
    76     foreach ($this->expressions as $expression) {
       
    77       if ($expression['alias'] == $field) {
       
    78         return $return;
       
    79       }
       
    80     }
       
    81 
       
    82     // If a table loads all fields, it can not be added again. It would
       
    83     // result in an ambiguous alias error because that field would be loaded
       
    84     // twice: Once through table_alias.* and once directly. If the field
       
    85     // actually belongs to a different table, it must be added manually.
       
    86     foreach ($this->tables as $table) {
       
    87       if (!empty($table['all_fields'])) {
       
    88         return $return;
       
    89       }
       
    90     }
       
    91 
       
    92     // If $field contains an characters which are not allowed in a field name
       
    93     // it is considered an expression, these can't be handled automatically
       
    94     // either.
       
    95     if ($this->connection->escapeField($field) != $field) {
       
    96       return $return;
       
    97     }
       
    98 
       
    99     // This is a case that can be handled automatically, add the field.
       
   100     $this->addField(NULL, $field);
       
   101     return $return;
       
   102   }
       
   103 }
       
   104 
       
   105 /**
       
   106  * @} End of "addtogroup database".
       
   107  */
       
   108