Projet

Général

Profil

Paste
Télécharger (3,38 ko) Statistiques
| Branche: | Révision:

root / drupal7 / includes / database / pgsql / select.inc @ 76597ebf

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 ambigious 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 handeld 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