You are viewing a plain text version of this content. The canonical link for it is here.
Posted to torque-dev@db.apache.org by tf...@apache.org on 2006/10/17 08:56:35 UTC
svn commit: r464836 - in /db/torque:
runtime/trunk/src/java/org/apache/torque/adapter/
runtime/trunk/src/java/org/apache/torque/util/
runtime/trunk/src/test/org/apache/torque/adapter/ site/trunk/xdocs/
Author: tfischer
Date: Mon Oct 16 23:56:34 2006
New Revision: 464836
URL: http://svn.apache.org/viewvc?view=rev&rev=464836
Log:
When the same column name appeared in two joined tables, and a limit or offset was used in the query, and the query was issued on oracle, an sql error resulted till now. This is fixed.
Fiexes TORQUE-10
Added:
db/torque/runtime/trunk/src/test/org/apache/torque/adapter/DBOracleTest.java
Modified:
db/torque/runtime/trunk/src/java/org/apache/torque/adapter/DBOracle.java
db/torque/runtime/trunk/src/java/org/apache/torque/util/UniqueList.java
db/torque/site/trunk/xdocs/changes.xml
Modified: db/torque/runtime/trunk/src/java/org/apache/torque/adapter/DBOracle.java
URL: http://svn.apache.org/viewvc/db/torque/runtime/trunk/src/java/org/apache/torque/adapter/DBOracle.java?view=diff&rev=464836&r1=464835&r2=464836
==============================================================================
--- db/torque/runtime/trunk/src/java/org/apache/torque/adapter/DBOracle.java (original)
+++ db/torque/runtime/trunk/src/java/org/apache/torque/adapter/DBOracle.java Mon Oct 16 23:56:34 2006
@@ -1,7 +1,7 @@
package org.apache.torque.adapter;
/*
- * Copyright 2001-2005 The Apache Software Foundation.
+ * Copyright 2001-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.
@@ -21,8 +21,12 @@
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.HashSet;
+import java.util.ListIterator;
+import java.util.Set;
import org.apache.torque.util.Query;
+import org.apache.torque.util.UniqueList;
/**
* This code should be used for an Oracle database pool.
@@ -220,6 +224,98 @@
query.setPreLimit(preLimit.toString());
query.setPostLimit(postLimit.toString());
query.setLimit(null);
+
+ // the query must not contain same column names or aliases.
+ // Find double column names and aliases and create unique aliases
+ // TODO: does not work for functions yet
+ UniqueList selectColumns = query.getSelectClause();
+ int replacementSuffix = 0;
+ Set columnNames = new HashSet();
+ // first pass: only remember aliased columns
+ // No replacements need to take place because double aliases
+ // are not allowed anyway
+ // So alias names will be retained
+ for (ListIterator columnIt = selectColumns.listIterator();
+ columnIt.hasNext(); )
+ {
+ String selectColumn = (String) columnIt.next();
+
+ // check for sql function
+ if ((selectColumn.indexOf('(') != -1)
+ || (selectColumn.indexOf(')') != -1))
+ {
+ // Sql function. Disregard.
+ continue;
+ }
+
+ // check if alias name exists
+ int spacePos = selectColumn.lastIndexOf(' ');
+ if (spacePos == -1)
+ {
+ // no alias, disregard for now
+ continue;
+ }
+
+ String aliasName = selectColumn.substring(spacePos + 1);
+ columnNames.add(aliasName);
+ }
+
+ // second pass. Regard ordinary columns only
+ for (ListIterator columnIt = selectColumns.listIterator();
+ columnIt.hasNext(); )
+ {
+ String selectColumn = (String) columnIt.next();
+
+ // check for sql function
+ if ((selectColumn.indexOf('(') != -1)
+ || (selectColumn.indexOf(')') != -1))
+ {
+ // Sql function. Disregard.
+ continue;
+ }
+
+ {
+ int spacePos = selectColumn.lastIndexOf(' ');
+ if (spacePos != -1)
+ {
+ // alias, already processed in first pass
+ continue;
+ }
+ }
+ // split into column name and tableName
+ String column;
+ {
+ int dotPos = selectColumn.lastIndexOf('.');
+ if (dotPos != -1)
+ {
+ column = selectColumn.substring(dotPos + 1);
+ }
+ else
+ {
+ column = selectColumn;
+ }
+ }
+ if (columnNames.contains(column))
+ {
+ // column needs to be aliased
+ // get replacement name
+ String aliasName;
+ do
+ {
+ aliasName = "a" + replacementSuffix;
+ ++replacementSuffix;
+ }
+ while (columnNames.contains(aliasName));
+
+ selectColumn = selectColumn + " " + aliasName;
+ columnIt.set(selectColumn);
+ columnNames.add(aliasName);
+ }
+ else
+ {
+ columnNames.add(column);
+ }
+ }
}
/**
Modified: db/torque/runtime/trunk/src/java/org/apache/torque/util/UniqueList.java
URL: http://svn.apache.org/viewvc/db/torque/runtime/trunk/src/java/org/apache/torque/util/UniqueList.java?view=diff&rev=464836&r1=464835&r2=464836
==============================================================================
--- db/torque/runtime/trunk/src/java/org/apache/torque/util/UniqueList.java (original)
+++ db/torque/runtime/trunk/src/java/org/apache/torque/util/UniqueList.java Mon Oct 16 23:56:34 2006
@@ -1,7 +1,7 @@
package org.apache.torque.util;
/*
- * Copyright 2001-2005 The Apache Software Foundation.
+ * Copyright 2001-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.
@@ -31,6 +31,22 @@
*/
private static final long serialVersionUID = 4467847559423445120L;
+ /**
+ * Constructs an empty UniqueList.
+ */
+ public UniqueList()
+ {
+ }
+
+ /**
+ * Copy-constructor. Creates a shallow copy of an UniqueList.
+ * @param list the uniqueList to copy
+ */
+ public UniqueList(UniqueList list)
+ {
+ this.addAll(list);
+ }
+
/**
* Adds an Object to the list.
*
Added: db/torque/runtime/trunk/src/test/org/apache/torque/adapter/DBOracleTest.java
URL: http://svn.apache.org/viewvc/db/torque/runtime/trunk/src/test/org/apache/torque/adapter/DBOracleTest.java?view=auto&rev=464836
==============================================================================
--- db/torque/runtime/trunk/src/test/org/apache/torque/adapter/DBOracleTest.java (added)
+++ db/torque/runtime/trunk/src/test/org/apache/torque/adapter/DBOracleTest.java Mon Oct 16 23:56:34 2006
@@ -0,0 +1,72 @@
+package org.apache.torque.adapter;
+
+/*
+ * Copyright 2001-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 junit.framework.TestCase;
+
+import org.apache.torque.util.Query;
+import org.apache.torque.util.UniqueList;
+
+public class DBOracleTest extends TestCase
+{
+ /**
+ * Tests whether replacing the select columns in limit/offset
+ * treatment works (double column names must be aliased)
+ */
+ public void testSelectColumnsForLimitOffset()
+ {
+ Query query = new Query();
+ UniqueList input = new UniqueList();
+ input.add("c1");
+ input.add("c2");
+ input.add("c1 a1");
+ input.add("c1 a2");
+ input.add("t.c1 a4");
+
+ // A list with no duplicates must remain unchanged
+ query.setSelectClause(new UniqueList(input));
+ new DBOracle().generateLimits(query, 0, 1);
+ assertEquals(input, query.getSelectClause());
+
+ // double column names must be aliased
+ input.set(1, "t.c1");
+ query.setSelectClause(new UniqueList(input));
+ new DBOracle().generateLimits(query, 0, 1);
+ UniqueList expected = new UniqueList(input);
+ expected.set(1, "t.c1 a0");
+ assertEquals(expected, query.getSelectClause());
+
+ // a column name which is the same as an alias name must be replaced
+ input.set(1, "c2");
+ input.set(0, "t.a1");
+ query.setSelectClause(new UniqueList(input));
+ new DBOracle().generateLimits(query, 0, 1);
+ expected = new UniqueList(input);
+ expected.set(0, "t.a1 a0");
+ assertEquals(query.getSelectClause(), expected);
+
+ // triple column names must be made unique
+ input.set(1, "t2.a1");
+ query.setSelectClause(new UniqueList(input));
+ new DBOracle().generateLimits(query, 0, 1);
+ expected = new UniqueList(input);
+ expected.set(0, "t.a1 a0");
+ expected.set(1, "t2.a1 a3");
+ assertEquals(expected, query.getSelectClause());
+ }
+
+}
Modified: db/torque/site/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/db/torque/site/trunk/xdocs/changes.xml?view=diff&rev=464836&r1=464835&r2=464836
==============================================================================
--- db/torque/site/trunk/xdocs/changes.xml (original)
+++ db/torque/site/trunk/xdocs/changes.xml Mon Oct 16 23:56:34 2006
@@ -29,6 +29,10 @@
<release version="3.2.1-dev" date="in SVN">
+ <action type="fix" dev="tfischer" issue="TORQUE-10">
+ Limit and Offset work now correctly if applied to joined
+ tables which cintain the same column name in oracle.
+ </action>
<action type="fix" dev="tfischer" issue="TORQUE-56" due-to="Gustavo Fernandez">
The variable CLASS_NAME in the map builders is now filled correctly if
the build property torque.subpackage.map is set.
---------------------------------------------------------------------
To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
For additional commands, e-mail: torque-dev-help@db.apache.org