-
Notifications
You must be signed in to change notification settings - Fork 1
/
select.inc
138 lines (116 loc) · 4.46 KB
/
select.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?php
/**
* @file
* Select builder for DB2 database engine.
*/
/**
* @ingroup database
* @{
*/
class SelectQuery_ibm extends SelectQuery {
public function __toString() {
// For convenience, we compile the query ourselves if the caller forgot
// to do it. This allows constructs like "(string) $query" to work. When
// the query will be executed, it will be recompiled using the proper
// placeholder generator anyway.
if (!$this->compiled()) {
$this->compile($this->connection, $this);
}
// Create a sanitized comment string to prepend to the query.
$comments = $this->connection->makeComment($this->comments);
// SELECT
$query = $comments . 'SELECT ';
if ($this->distinct) {
$query .= 'DISTINCT ';
}
// FIELDS and EXPRESSIONS
$fields = array();
foreach ($this->tables as $alias => $table) {
if (!empty($table['all_fields'])) {
$fields[] = $this->connection->escapeTable($alias) . '.*';
}
}
foreach ($this->fields as $alias => $field) {
// Always use the AS keyword for field aliases, as some
// databases require it (e.g., DB2).
$fields[] = (isset($field['table']) ? $this->connection->escapeTable($field['table']) . '.' : '') . $this->connection->escapeField($field['field']) . ' AS ' . $this->connection->escapeAlias($field['alias']);
}
foreach ($this->expressions as $alias => $expression) {
$fields[] = $expression['expression'] . ' AS ' . $this->connection->escapeAlias($expression['alias']);
}
$query .= implode(', ', $fields);
// FROM - We presume all queries have a FROM, as any query that doesn't won't need the query builder anyway.
$query .= "\nFROM ";
foreach ($this->tables as $alias => $table) {
$query .= "\n";
if (isset($table['join type'])) {
$query .= $table['join type'] . ' JOIN ';
}
// If the table is a subquery, compile it and integrate it into this query.
if ($table['table'] instanceof SelectQueryInterface) {
// Run preparation steps on this sub-query before converting to string.
$subquery = $table['table'];
$subquery->preExecute();
$table_string = '(' . (string) $subquery . ')';
}
else {
$table_string = '{' . $this->connection->escapeTable($table['table']) . '}';
}
// Don't use the AS keyword for table aliases, as some
// databases don't support it (e.g., DB2).
$query .= $table_string . ' ' . $this->connection->escapeTable($table['alias']);
if (!empty($table['condition'])) {
$query .= ' ON ' . $table['condition'];
}
}
// WHERE
if (count($this->where)) {
// There is an implicit string cast on $this->condition.
$query .= "\nWHERE " . $this->where;
}
// GROUP BY
if ($this->group) {
$query .= "\nGROUP BY " . implode(', ', $this->group);
}
// HAVING
if (count($this->having)) {
// There is an implicit string cast on $this->having.
$query .= "\nHAVING " . $this->having;
}
// ORDER BY
if ($this->order) {
$query .= "\nORDER BY ";
$fields = array();
foreach ($this->order as $field => $direction) {
$fields[] = $field . ' ' . $direction;
}
$query .= implode(', ', $fields);
}
// UNION is a little odd, as the select queries to combine are passed into
// this query, but syntactically they all end up on the same level.
if ($this->union) {
foreach ($this->union as $union) {
$query .= ' ' . $union['type'] . ' ' . (string) $union['query'];
}
}
if ($this->forUpdate) {
$query .= ' FOR UPDATE';
}
// RANGE
// DB2 is using a different range syntax than all other else
// core-supported database, which rewrite the entire query structure, so
// we need to override this method with alternate logic as LAST STEP.
if (!empty($this->range)) {
$query = 'SELECT * FROM (SELECT SUB1.*, ROWNUM AS ' . OCI_RANGE_ROWNUM_PLACEHOLDER . ' FROM (' . $query . ') SUB1) WHERE ' . OCI_RANGE_ROWNUM_PLACEHOLDER . ' BETWEEN ' . ((int) $this->range['start'] + 1) . ' AND ' . ((int) $this->range['start'] + (int) $this->range['length']);
}
return $query;
}
public function groupBy($field) {
// DB2 don't allow GROUP BY with field alias, use original name.
$this->group[$field] = isset($this->fields[$field]['field']) ? $this->fields[$field]['field'] : $field;
return $this;
}
}
/**
* @} End of "ingroup database".
*/