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/06/21 21:32:17 UTC

svn commit: r416082 - in /db/torque: runtime/trunk/src/java/org/apache/torque/util/SQLBuilder.java runtime/trunk/src/test/org/apache/torque/util/SqlBuilderTest.java site/trunk/xdocs/changes.xml

Author: tfischer
Date: Wed Jun 21 12:32:17 2006
New Revision: 416082

URL: http://svn.apache.org/viewvc?rev=416082&view=rev
Log:
Refined guesswork for detecting column names out of functions, clauses etc. 
This is important e.g. for orderBy Statements like "order by table.column in (1,2,3)" or "order by 100 < table.column".
Also added a test case to check the expected behaviour.
Thanks to Jacob Champlin for an early version of the patch.
Fixes TORQUE-33.

Added:
    db/torque/runtime/trunk/src/test/org/apache/torque/util/SqlBuilderTest.java
Modified:
    db/torque/runtime/trunk/src/java/org/apache/torque/util/SQLBuilder.java
    db/torque/site/trunk/xdocs/changes.xml

Modified: db/torque/runtime/trunk/src/java/org/apache/torque/util/SQLBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/runtime/trunk/src/java/org/apache/torque/util/SQLBuilder.java?rev=416082&r1=416081&r2=416082&view=diff
==============================================================================
--- db/torque/runtime/trunk/src/java/org/apache/torque/util/SQLBuilder.java (original)
+++ db/torque/runtime/trunk/src/java/org/apache/torque/util/SQLBuilder.java Wed Jun 21 12:32:17 2006
@@ -47,6 +47,10 @@
 {
     /** Logging */
     protected static Log log = LogFactory.getLog(SQLBuilder.class);
+    
+    /** Function Characters */
+    public static final String[] COLUMN_CHARS = {".", "*"};
+    public static final String[] DELIMITERS = {" ", ",", "(", ")", "<", ">"};
 
     /**
      * Fully qualify a table name with an optional schema reference
@@ -131,66 +135,37 @@
             return name;
         }
 
-        final int leftParent = name.lastIndexOf('(');
-        final int rightParent = name.indexOf(')');
-
-        // Do we have Parentheses?
-        if (leftParent < 0)
-        {
-            if (rightParent < 0)
-            {
-                // No left, no right => No function ==> return it
-                return name;
-            }
-        }
-
-        // We have a left parenthesis. Is the right one behind it?
-        if (rightParent > leftParent)
-        {
-            // Yes. Strip off the function, return the column name
-            return name.substring(leftParent + 1, rightParent);
-        }
-
-        // Bracket mismatch or wrong order ==> Exception
-        throwMalformedColumnNameException(
-                "removeSQLFunction",
-                name);
-
-        return null; // Ugh
-    }
-
-    /**
-     * Removes possible qualifiers (like DISTINCT) from a column name
-     *
-     * @param name The column name, possibly containing qualifiers
-     *
-     * @return The column name
-     *
-     * @throws TorqueException If the column name was malformed
-     */
-    private static String removeQualifiers(final String name)
-            throws TorqueException
-    {
-        // Empty name => return it
-        if (StringUtils.isEmpty(name))
+        // Find Table.Column
+        int dotIndex = name.indexOf('.');
+        if (dotIndex == -1)
+        {
+            dotIndex = name.indexOf("*");
+        }
+        if (dotIndex == -1)
+        {
+            throw new TorqueException("removeSQLFunction() : Column name " 
+                    + name
+                    + " does not contain a . or a *");
+        }
+        String pre = name.substring(0, dotIndex);
+        String post = name.substring(dotIndex + 1, name.length());
+        int startIndex = StringUtils.lastIndexOfAny(pre, DELIMITERS);
+        int endIndex = StringUtils.indexOfAny(post, DELIMITERS);
+        if (startIndex < 0 && endIndex < 0)
         {
             return name;
         }
-
-        final int spacePos = name.trim().lastIndexOf(' ');
-
-        // Do we have spaces, indicating that qualifiers are used ?
-        if (spacePos > 0)
+        else
         {
-            // Qualifiers are first, tablename is piece after last space
-            return name.trim().substring(spacePos + 1);
+            if (endIndex < 0)
+            {
+                endIndex = post.length();
+            }
+            // if startIndex == -1 the formula is correct
+            return name.substring(startIndex + 1, dotIndex + 1 + endIndex);
         }
-
-        // no spaces, nothing changed
-        return name;
     }
 
-
     /**
      * Returns a table name from an identifier. Each identifier is to be qualified
      * as [schema.]table.column. This could also contain FUNCTION([schema.]table.column).
@@ -204,7 +179,7 @@
     public static String getTableName(final String name, final String dbName)
             throws TorqueException
     {
-        final String testName = removeQualifiers(removeSQLFunction(name));
+        final String testName = removeSQLFunction(name);
 
         if (StringUtils.isEmpty(testName))
         {

Added: db/torque/runtime/trunk/src/test/org/apache/torque/util/SqlBuilderTest.java
URL: http://svn.apache.org/viewvc/db/torque/runtime/trunk/src/test/org/apache/torque/util/SqlBuilderTest.java?rev=416082&view=auto
==============================================================================
--- db/torque/runtime/trunk/src/test/org/apache/torque/util/SqlBuilderTest.java (added)
+++ db/torque/runtime/trunk/src/test/org/apache/torque/util/SqlBuilderTest.java Wed Jun 21 12:32:17 2006
@@ -0,0 +1,131 @@
+package org.apache.torque.util;
+
+/*
+ * 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 org.apache.torque.BaseTestCase;
+import org.apache.torque.TorqueException;
+
+/**
+ * Tests for SqlExpression
+ *
+ * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
+ * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a>
+ * @version $Id: SqlExpressionTest.java 239636 2005-08-24 12:38:09Z henning $
+ */
+public class SqlBuilderTest extends BaseTestCase
+{
+    /**
+     * Creates a new instance.
+     *
+     * @param name the name of the test case to run
+     */
+    public SqlBuilderTest(String name)
+    {
+        super(name);
+    }
+
+    public void testExtractTableName() throws TorqueException
+    {
+        // standard cases with / without schema
+        String columnName = "table.column";
+        String tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals("table", tableName);
+
+        columnName = "schema.table.column";
+        tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals("schema.table", tableName);
+
+        // functions
+        columnName = "function(table.column)";
+        tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals("table", tableName);
+
+        columnName = "function(1,table.column,2)";
+        tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals("table", tableName);
+
+        // comparisons
+        columnName = "table.column < 10";
+        tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals("table", tableName);
+
+        columnName = "table.column<10";
+        tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals("table", tableName);
+
+        columnName = "10 > table.column";
+        tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals("table", tableName);
+
+        columnName = "10>table.column";
+        tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals("table", tableName);
+
+        columnName = "10>table.column";
+        tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals("table", tableName);
+
+        // in clause
+        columnName = "table.column in (1,2,3)";
+        tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals("table", tableName);
+
+        // wildcard
+        columnName = "*";
+        tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals(null, tableName);
+
+        // function with wildcard
+        columnName = "count(*)";
+        tableName = SQLBuilder.getTableName(columnName, null);
+        assertEquals(null, tableName);
+ 
+        // empty String and null
+        columnName = "";
+        try
+        {
+            tableName = SQLBuilder.getTableName(columnName, null);
+            fail("getTableName() should fail for empty column name");
+        }
+        catch (TorqueException e)
+        {
+        }
+
+        columnName = null;
+        try
+        {
+            tableName = SQLBuilder.getTableName(columnName, null);
+            fail("getTableName() should fail for null as column name");
+        }
+        catch (TorqueException e)
+        {
+        }
+        
+        // failure: no dot or wildcard
+        columnName = "column";
+        try
+        {
+            tableName = SQLBuilder.getTableName(columnName, null);
+            fail("getTableName() should fail for column name "
+                    + "without a dot or wildcard");
+        }
+        catch (TorqueException e)
+        {
+        }
+        
+    }
+}

Modified: db/torque/site/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/db/torque/site/trunk/xdocs/changes.xml?rev=416082&r1=416081&r2=416082&view=diff
==============================================================================
--- db/torque/site/trunk/xdocs/changes.xml (original)
+++ db/torque/site/trunk/xdocs/changes.xml Wed Jun 21 12:32:17 2006
@@ -29,6 +29,12 @@
 
   <release version="3.2.1-dev" date="in SVN">
   
+    <action type="add" dev="tfischer" issue="TORQUE-33" due-to="Jacob Champlin">
+      Refined guesswork for detecting column names out of functions, clauses
+      etc. This is important e.g. for orderBy Statements like
+      &quot;order by table.column in (1,2,3)&quot; or 
+      &quot;order by 100 &lt; table.column&quot;.
+    </action>
     <action type="add" dev="tfischer" issue="TORQUE-30" due-to="Patrick Carl">
       Added the CASCADE option to drop table statements for HSQLDB.
       This will not work with HSQLDB 1.7. Consult the HSQLDB Howto for 



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