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