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