You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by to...@apache.org on 2006/03/01 01:41:55 UTC

svn commit: r381850 - in /db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker: accesslayer/sql/EnclosingSelectStatement.java accesslayer/sql/SqlGeneratorDefaultImpl.java query/EnclosingReportQuery.java util/BrokerHelper.java

Author: tomdz
Date: Tue Feb 28 16:41:55 2006
New Revision: 381850

URL: http://svn.apache.org/viewcvs?rev=381850&view=rev
Log:
Jakob's COUNT DISTINCT enhancement that uses sub-selects instead of concatenation

Added:
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/EnclosingSelectStatement.java
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/query/EnclosingReportQuery.java
Modified:
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/SqlGeneratorDefaultImpl.java
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/BrokerHelper.java

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/EnclosingSelectStatement.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/EnclosingSelectStatement.java?rev=381850&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/EnclosingSelectStatement.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/EnclosingSelectStatement.java Tue Feb 28 16:41:55 2006
@@ -0,0 +1,77 @@
+package org.apache.ojb.broker.accesslayer.sql;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.ojb.broker.metadata.FieldDescriptor;
+import org.apache.ojb.broker.query.Query;
+
+
+/**
+ * Wraps a SelectStatement to support SQLSubSelect.
+ * select count(*) from (select ... from ... where... ) ojb_enc
+ *
+ * @author <a href="mailto:jbraeuchi@gmx.ch">Jakob Braeuchi</a>
+ * @version $Id:  $
+ */
+public class EnclosingSelectStatement implements SelectStatement
+{
+    private SelectStatement enclosedSql;
+    private String sql;
+
+    public EnclosingSelectStatement(SelectStatement enclosedSql, String sql)
+    {
+        this.enclosedSql = enclosedSql;
+        this.sql = sql;
+    }
+
+    /**
+     * @see org.apache.ojb.broker.accesslayer.sql.SqlStatement#getStatement()
+     */
+    public String getStatement()
+    {
+        StringBuffer buf = new StringBuffer("select ");
+        buf.append(sql);
+        buf.append(" from (");
+        buf.append(enclosedSql.getStatement());
+        buf.append(" ) ojb_enc");
+
+        return buf.toString();
+    }
+
+    /**
+     * @see org.apache.ojb.broker.accesslayer.sql.SelectStatement#getColumnIndex(org.apache.ojb.broker.metadata.FieldDescriptor)
+     */
+    public int getColumnIndex(FieldDescriptor fld)
+    {
+        return enclosedSql.getColumnIndex(fld);
+    }
+
+    /**
+     * @see org.apache.ojb.broker.accesslayer.sql.SelectStatement#getQueryInstance()
+     */
+    public Query getQueryInstance()
+    {
+        return enclosedSql.getQueryInstance();
+    }
+
+    /**
+     * @see org.apache.ojb.broker.accesslayer.sql.SelectStatement#isUseOjbClassColumn()
+     */
+    public boolean isUseOjbClassColumn()
+    {
+        return enclosedSql.isUseOjbClassColumn();
+    }
+}

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/SqlGeneratorDefaultImpl.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/SqlGeneratorDefaultImpl.java?rev=381850&r1=381849&r2=381850&view=diff
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/SqlGeneratorDefaultImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/SqlGeneratorDefaultImpl.java Tue Feb 28 16:41:55 2006
@@ -25,6 +25,7 @@
 import org.apache.ojb.broker.platforms.Platform;
 import org.apache.ojb.broker.query.BetweenCriteria;
 import org.apache.ojb.broker.query.Criteria;
+import org.apache.ojb.broker.query.EnclosingReportQuery;
 import org.apache.ojb.broker.query.ExistsCriteria;
 import org.apache.ojb.broker.query.FieldCriteria;
 import org.apache.ojb.broker.query.InCriterion;
@@ -185,7 +186,19 @@
      */
     public SelectStatement getPreparedSelectStatement(Query query, ClassDescriptor cld)
     {
-        SelectStatement sql = new SqlSelectStatement(platform, cld, query, logger);
+        SelectStatement sql;
+
+        if (query instanceof EnclosingReportQuery)
+        {
+            EnclosingReportQuery encQuery = (EnclosingReportQuery) query;
+            SelectStatement encSql = new SqlSelectStatement(platform, cld, encQuery.getQuery(), logger);
+            sql = new EnclosingSelectStatement(encSql, encQuery.getSql());
+        }
+        else
+        {
+            sql = new SqlSelectStatement(platform, cld, query, logger);
+        }
+
         if (logger.isDebugEnabled())
         {
             logger.debug("SQL:" + sql.getStatement());

Added: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/query/EnclosingReportQuery.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/query/EnclosingReportQuery.java?rev=381850&view=auto
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/query/EnclosingReportQuery.java (added)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/query/EnclosingReportQuery.java Tue Feb 28 16:41:55 2006
@@ -0,0 +1,97 @@
+package org.apache.ojb.broker.query;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Wrap a Query to support SQLSubSelect.
+ * select count(*) from (select ... from ... where... )
+ *
+ * @author <a href="mailto:jbraeuchi@gmx.ch">Jakob Braeuchi</a>
+ * @version $Id:  $
+ */
+public class EnclosingReportQuery extends AbstractQueryImpl implements ReportQuery
+{
+    private Query query;
+    private String sql;
+
+    private Map attrFieldDescriptors = new HashMap();
+    private String[] joinAttributes = new String[]{};
+    public EnclosingReportQuery(Query aQuery, String anSql)
+    {
+        query = aQuery;
+        sql = anSql;
+    }
+
+    public Query getQuery()
+    {
+        return query;
+    }
+
+    public Class getSearchClass()
+    {
+        return query.getSearchClass();
+    }
+
+    public String getSql()
+    {
+        return sql;
+    }
+
+    public Map getAttributeFieldDescriptors()
+    {
+        return attrFieldDescriptors;
+    }
+
+    public String[] getAttributes()
+    {
+        return new String[]{sql};
+    }
+
+    public String[] getColumns()
+    {
+        return getAttributes();
+    }
+
+    public int[] getJdbcTypes()
+    {
+        return null;
+    }
+
+    public String[] getJoinAttributes()
+    {
+        return joinAttributes;
+    }
+
+    /**
+     * Get Criteria of enclosed Query.
+     */
+    public Criteria getCriteria()
+    {
+        return query.getCriteria();
+    }
+
+    /**
+     * Get Having-Criteria of enclosed Query.
+     */
+    public Criteria getHavingCriteria()
+    {
+        return query.getHavingCriteria();
+    }
+
+}

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/BrokerHelper.java
URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/BrokerHelper.java?rev=381850&r1=381849&r2=381850&view=diff
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/BrokerHelper.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/BrokerHelper.java Tue Feb 28 16:41:55 2006
@@ -51,6 +51,7 @@
 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
 import org.apache.ojb.broker.platforms.Platform;
 import org.apache.ojb.broker.query.Criteria;
+import org.apache.ojb.broker.query.EnclosingReportQuery;
 import org.apache.ojb.broker.query.MtoNQuery;
 import org.apache.ojb.broker.query.Query;
 import org.apache.ojb.broker.query.QueryByCriteria;
@@ -599,60 +600,22 @@
         // BRJ: copied Criteria without groupby, orderby, and prefetched relationships
         if (aQuery.getCriteria() != null)
         {
-            countCrit = new Criteria(aQuery.getCriteria(),false,false,false);
+            countCrit = new Criteria(aQuery.getCriteria(), false, false, false);
         }
 
         if (aQuery.isDistinct())
         {
-            // BRJ: Count distinct is dbms dependent
-            // hsql/sapdb: select count (distinct(person_id || project_id)) from person_project
-            // mysql: select count (distinct person_id,project_id) from person_project
-            // [tomdz]
-            // Some databases have no support for multi-column count distinct (e.g. Derby)
-            // Here we use a SELECT count(*) FROM (SELECT DISTINCT ...) instead 
-            //
-            // concatenation of pk-columns is a simple way to obtain a single column
-            // but concatenation is also dbms dependent:
-            //
-            // SELECT count(distinct concat(row1, row2, row3)) mysql
-            // SELECT count(distinct (row1 || row2 || row3)) ansi
-            // SELECT count(distinct (row1 + row2 + row3)) ms sql-server
-
-            FieldDescriptor[] pkFields   = m_broker.getClassDescriptor(searchClass).getPkFields();
-            String[]          keyColumns = new String[pkFields.length];
-
-            if (pkFields.length > 1)
-            {
-                // TODO: Use ColumnName. This is a temporary solution because
-                // we cannot yet resolve multiple columns in the same attribute.
-                for (int idx = 0; idx < pkFields.length; idx++)
-                {
-                    keyColumns[idx] = pkFields[idx].getColumnName();
-                }
-            }
-            else
+            FieldDescriptor[] pkFields = m_broker.getClassDescriptor(searchClass).getPkFields();
+
+            columns = new String[pkFields.length];
+            for (int idx = 0; idx < pkFields.length; idx++)
             {
-                for (int idx = 0; idx < pkFields.length; idx++)
-                {
-                    keyColumns[idx] = pkFields[idx].getAttributeName();
-                }
+                 columns[idx] = pkFields[idx].getAttributeName();
             }
-            // [tomdz]
-            // TODO: Add support for databases that do not support COUNT DISTINCT over multiple columns
-//            if (getPlatform().supportsMultiColumnCountDistinct())
-//            {
-//                columns[0] = "count(distinct " + getPlatform().concatenate(keyColumns) + ")";
-//            }
-//            else
-//            {
-//                columns = keyColumns;
-//            }
-
-            columns[0] = "count(distinct " + getPlatform().concatenate(keyColumns) + ")";
         }
         else
         {
-            columns[0] = "count(*)";
+            columns = new String[] { "count(*)" };
         }
 
         // BRJ: we have to preserve indirection table !
@@ -694,17 +657,15 @@
             countQuery.setJoinAttributes(joinAttributes);
         }
 
-        // [tomdz]
-        // TODO:
-        // For those databases that do not support COUNT DISTINCT over multiple columns
-        // we wrap the normal SELECT DISTINCT that we just created, into a SELECT count(*)
-        // For this however we need a report query that gets its data from a sub query instead
-        // of a table (target class)
-//        if (aQuery.isDistinct() && !getPlatform().supportsMultiColumnCountDistinct())
-//        {
-//        }
-
-        return countQuery;
+        if (aQuery.isDistinct())
+        {
+            countQuery.setDistinct(true);
+            return new EnclosingReportQuery(countQuery, "count(*)");
+        }
+        else
+        {
+            return countQuery;
+        }
     }
 
     /**



---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org