? .DS_Store
? 470258.views.groupwise_max.patch
? 672462.views.file-header.patch
? views-510284-pluggable-areas_6.patch
? views-510284-pluggable-areas_7.patch
? modules/.DS_Store
Index: includes/plugins.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/plugins.inc,v
retrieving revision 1.152.2.9
diff -u -p -r1.152.2.9 plugins.inc
--- includes/plugins.inc	3 Dec 2009 01:47:31 -0000	1.152.2.9
+++ includes/plugins.inc	2 Jan 2010 14:43:19 -0000
@@ -248,6 +248,12 @@ function views_views_plugins() {
         'help' => t('Query will be generated and run using the Drupal database API.'),
         'handler' => 'views_plugin_query_default'
       ),
+      'views_query_aliased' => array(
+        'title' => t('SQL Aliased Query'),
+        'help' => t('Query will be generated and run using the Drupal database API, with all fields prefixed for correlated subqueries.'),
+        'parent' => 'views_query',
+        'handler' => 'views_plugin_query_aliased',
+      ),
     ),
     'cache' => array(
       'parent' => array(
Index: includes/view.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/view.inc,v
retrieving revision 1.151.2.25
diff -u -p -r1.151.2.25 view.inc
--- includes/view.inc	28 Dec 2009 21:34:25 -0000	1.151.2.25
+++ includes/view.inc	2 Jan 2010 14:43:20 -0000
@@ -505,7 +505,10 @@ class view extends views_db_object {
     }
 
     // Create and initialize the query object.
-    $plugin = !empty($views_data['table']['base']['query class']) ? $views_data['table']['base']['query class'] : 'views_query';
+    # temporary! quick hack to test groupwise stuff
+    //$plugin = !empty($views_data['table']['base']['query class']) ? $views_data['table']['base']['query class'] : 'views_query';
+    $plugin = 'views_query_aliased';
+    # end hack
     $this->query = views_get_plugin('query', $plugin);
 
     $this->query->init($this->base_table, $this->base_field);
Index: plugins/views_plugin_query_aliased.inc
===================================================================
RCS file: plugins/views_plugin_query_aliased.inc
diff -N plugins/views_plugin_query_aliased.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ plugins/views_plugin_query_aliased.inc	2 Jan 2010 14:43:21 -0000
@@ -0,0 +1,188 @@
+<?php
+// $Id$
+/**
+ * @file views_plugin_query_aliased.inc
+ * Adds a prefix to fields in the query; builds SQL to execute using the
+ * Drupal database API.
+ */
+
+/**
+ * Object used to create a SELECT query.
+ */
+class views_plugin_query_aliased extends views_plugin_query_default {
+
+  /**
+   * Our namespace.
+   */
+  var $namespace = "_INNER";
+
+  /**
+   * Constructor; Create the basic query object and fill with default values.
+   */
+  // This is a straight copy of the parent with the namespace added in wherever needed. 
+  function init($base_table = 'node', $base_field = 'nid') {       
+    $this->base_table = $base_table;  // Predefine these above, for clarity.
+    $this->base_field = $base_field;
+    $this->relationships[$base_table] = array(
+      'link' => NULL,
+      'table' => $base_table,
+      'alias' => $base_table . $this->namespace,
+      'base' => $base_table
+    );
+
+    // init the table queue with our primary table.
+    $this->table_queue[$base_table] = array(
+      'alias' => $base_table . $this->namespace,
+      'table' => $base_table,
+      'relationship' => $base_table,
+      'join' => NULL,
+    );
+
+    // init the tables with our primary table
+    $this->tables[$base_table][$base_table] = array(
+      'count' => 1,
+      'alias' => $base_table . $this->namespace,
+    );
+
+/**
+ * -- we no longer want the base field to appear automatigically.
+    if ($base_field) {
+      $this->fields[$base_field] = array(
+        'table' => $base_table,
+        'field' => $base_field,
+        'alias' => $base_field,
+      );
+    }
+ */
+
+    $this->count_field = array(
+      'table' => $base_table,
+      'field' => $base_field,
+      'alias' => $base_field . $this->namespace,
+      'count' => TRUE,
+    );
+  }
+
+  // ----------------------------------------------------------------
+  // Utility methods to set flags and data.
+
+  /**
+   * Set the namespace.
+   * @todo: Should this be set dynamically and safely in the event a crazy user nests these?
+   */
+  function set_namespace($namespace = '_INNER') {
+    $this->namespace = strtoupper($namespace);
+  }
+  
+  // ----------------------------------------------------------------
+  // Table/join adding
+
+  /**
+   * Add a table to the query, without ensuring the path.
+   *
+   */
+  function queue_table($table, $relationship = NULL, $join = NULL, $alias = NULL) {
+    // Set the alias.
+    if (!$alias && $join && $relationship && !empty($join->adjusted) && $table != $join->table) {
+      if ($relationship == $this->base_table) {
+        $alias = $table;
+      }
+      else {
+        $alias = $relationship . '_' . $table;
+      }
+    }
+    
+    // Check this again to make sure we don't blow up existing aliases for already
+    // adjusted joins.
+    if (isset($this->table_queue[$alias])) {
+      return $alias;
+    }
+
+    $alias = $this->mark_table($table, $relationship, $alias);
+
+    // If no alias is specified, give it the default.
+    if (!isset($alias)) {
+      $alias = $this->tables[$relationship][$table]['alias'] . $this->tables[$relationship][$table]['count'];
+    }
+    
+    // Groupwise: this is the only bit of work we do here.
+    $alias .= $this->namespace;
+    
+    return parent::queue_table($table, $relationship, $join, $alias);
+  }  
+
+  /**
+   * Generate a query and a countquery from all of the information supplied
+   * to the object.
+   *
+   * @param $get_count
+   *   Provide a countquery if this is true, otherwise provide a normal query.
+   */
+  // Mostly identical to parent.
+  function query($get_count = FALSE) {
+    // Check query distinct value.
+    if (empty($this->no_distinct) && $this->distinct && !empty($this->fields)) {
+      $base_field_alias = $this->add_field($this->base_table, $this->base_field, NULL, array('distinct' => TRUE));
+      $this->add_groupby($base_field_alias);
+    }
+
+    /**
+     * An optimized count query includes just the base field instead of all the fields.
+     * Determine of this query qualifies by checking for a groupby or distinct.
+     */
+    $fields_array = $this->fields;
+    if ($get_count && !$this->groupby) {
+      foreach ($fields_array as $field) {
+        if (!empty($field['distinct']) || !empty($field['function'])) {
+          $get_count_optimized = FALSE;
+          break;
+        }
+      }
+    }
+    else {
+      $get_count_optimized = FALSE;
+    }
+    if (!isset($get_count_optimized)) {
+      $get_count_optimized = TRUE;
+    }
+
+    dsm($this->table_queue);
+    // BUG: the keys here are aliases. But the views_join class can't see them.
+
+    $joins = $where = $having = $orderby = $groupby = '';
+    // Add all the tables to the query via joins. We assume all LEFT joins.
+    foreach ($this->table_queue as $table) {
+      if (is_object($table['join'])) {
+        $joins .= $table['join']->join($table, $this) . "\n";
+      }
+    }
+
+    list($distinct, $fields, $non_aggregates) = $this->compile_fields($fields_array);
+
+   if ($this->has_aggregate || $this->groupby) {
+     $groupby = "GROUP BY " . implode(', ', array_unique(array_merge($this->groupby, $non_aggregates))) . "\n";
+      if ($this->having) {
+        $having = $this->condition_sql('having');
+      }
+    }
+
+    if (!$get_count_optimized) {
+      // we only add the groupby if we're not counting.
+      if ($this->orderby) {
+        $orderby = "ORDER BY " . implode(', ', $this->orderby) . "\n";
+      }
+    }
+
+    $where = $this->condition_sql();
+
+    // Groupwise change: alias the base table. 
+    $query = "SELECT " . implode(",\n", array_merge($distinct, $fields)) . "\n FROM {" . $this->base_table . "} " . $this->base_table . $this->namespace . "\n$joins $where $groupby $having $orderby";
+
+    $replace = array('&gt;' => '>', '&lt;' => '<');
+    $query = strtr($query, $replace);
+
+    return $query;
+  }
+
+
+}
