select.inc 3.4 KB

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