You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ma...@apache.org on 2007/07/06 06:32:02 UTC

svn commit: r553727 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java

Author: mamta
Date: Thu Jul  5 21:31:59 2007
New Revision: 553727

URL: http://svn.apache.org/viewvc?view=rev&rev=553727
Log:
DERBY-2777

Currently, the parameters in TRIM clause always pickup their collation from the compilation schema. That logic is not
complete. I am fixing that logic here along with addition of some tests.

For the sake of explanation, let me use the following syntax for TRIM clause
TRIM (leftOperand FROM receiver)
With the fix in this patch, if receiver is a parameter, it will set it's collation using following logic
1)check if leftOperand is not a parameter. If yes, then receiver will pick up collation from leftOperand. If not, goto step 2
2)receiver picks up the collation of the compilation schema because everything in the TRIM clause is ?

Next, if leftOperand is a parameter, it will set it's collation using receiver. By this time, even if receiver is a
parameter, we have set correct collation for receiver and hence leftOperand can simply rely on receiver for correct
collation IF leftOperand is a parameter.


Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java?view=diff&rev=553727&r1=553726&r2=553727
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java Thu Jul  5 21:31:59 2007
@@ -505,6 +505,10 @@
 	}
 	/**
 	 * Bind trim expression. 
+	 * The variable receiver is the string that needs to be trimmed.
+	 * The variable leftOperand is the character that needs to be trimmed from
+	 *     receiver.
+	 *     
 	 * @return	The new top of the expression tree.
 	 *
 	 * @exception StandardException		Thrown on error
@@ -528,9 +532,19 @@
 			*/
 	
 			receiver.setType(getVarcharDescriptor());
-			//collation of ? operand should be same as the compilation schema
-			receiver.setCollationUsingCompilationSchema(
-					StringDataValue.COLLATION_DERIVATION_IMPLICIT);
+            //check if this parameter can pick up it's collation from the 
+			//character that will be used for trimming. If not(meaning the
+			//character to be trimmed is also a parameter), then it will take 
+			//it's collation from the compilation schema.
+            if (!leftOperand.requiresTypeFromContext()) {
+            	receiver.getTypeServices().setCollationDerivation(
+            			leftOperand.getTypeServices().getCollationDerivation());
+            	receiver.getTypeServices().setCollationType(
+            			leftOperand.getTypeServices().getCollationType());
+            } else {
+    			receiver.setCollationUsingCompilationSchema(
+    					StringDataValue.COLLATION_DERIVATION_IMPLICIT);            	
+            }
 		}
 
 		/* Is there a ? parameter on the left? */
@@ -538,9 +552,14 @@
 		{
 			/* Set the left operand type to varchar. */
 			leftOperand.setType(getVarcharDescriptor());
-			//collation of ? operand should be same as the compilation schema
-			leftOperand.setCollationUsingCompilationSchema(
-					StringDataValue.COLLATION_DERIVATION_IMPLICIT);
+			//collation of ? operand should be picked up from the context.
+            //By the time we come here, receiver will have correct collation
+            //set on it and hence we can rely on it to get correct collation
+            //for the ? for the character that needs to be used for trimming.
+			leftOperand.getTypeServices().setCollationDerivation(
+					receiver.getTypeServices().getCollationDerivation());
+			leftOperand.getTypeServices().setCollationType(
+        			receiver.getTypeServices().getCollationType());            	
 		}
 
 		bindToBuiltIn();

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java?view=diff&rev=553727&r1=553726&r2=553727
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java Thu Jul  5 21:31:59 2007
@@ -830,6 +830,34 @@
     rs = ps.executeQuery();
     JDBC.assertFullResultSet(rs,new String[][] {{"SYSCOLUMNS"}});
 
+    //Similar testing for TRIM
+    //Following won't work because the character string constant 'a' is 
+    //picking up the collation of the current schema which is territory based.
+    //And the ? in TRIM will pick up it's collation from 'a' and hence the
+    //comparison between territory based character string returned from TRIM
+    //function will fail against UCS_BASIC based TABLENAME on the right
+    checkPreparedStatementError(conn, "SELECT TABLENAME FROM SYS.SYSTABLES WHERE " +
+    		" TRIM('a' FROM ?) = TABLENAME", "42818");
+    //The problem can be fixed by using CAST on TABLENAME so the resultant of
+    //CAST string will compare fine with the output of TRIM. Note CAST always
+    //picks up the collation of the compilation schema.
+    ps = conn.prepareStatement("SELECT TABLENAME FROM SYS.SYSTABLES WHERE " +
+    		" TRIM('a' FROM ?) = CAST(TABLENAME AS CHAR(10))");
+    ps.setString(1, "aSYSCOLUMNS");
+    rs = ps.executeQuery();
+    JDBC.assertFullResultSet(rs,new String[][] {{"SYSCOLUMNS"}});
+    //Another test for TRIM
+    //Following will not fail because the ? in TRIM will pick up collation
+    //from it's first parameter which is a SUBSTR on TABLENAME and hence the 
+    //result of TRIM will have UCS_BASIC collation which matches the collation
+    //on the right.
+    ps = conn.prepareStatement("SELECT TABLENAME FROM SYS.SYSTABLES WHERE " +
+    		" TRIM(LEADING SUBSTR(TABLENAME, LENGTH(TABLENAME)) FROM ?) = TABLENAME");
+    ps.setString(1, "SYSCOLUMNS");
+    rs = ps.executeQuery();
+    //No rows returned because the result of TRIM is going to be 'YSCOLUMNS'
+    JDBC.assertEmpty(rs);
+    
     //Do parameter testing with IN and subquery
     //Following will work just fine because ? will take it's collation from the
     //context which in this case will be collation of TABLENAME which has