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