db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject svn commit: r551033 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/compile/CastNode.java engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java
Date Wed, 27 Jun 2007 04:20:03 GMT
Author: mamta
Date: Tue Jun 26 21:20:01 2007
New Revision: 551033

URL: http://svn.apache.org/viewvc?view=rev&rev=551033
Log:
DERBY-2776 Internally generated CAST nodes should not pick up the collation of the current
schema. In order to implement this, the CAST
nodes generated directly by the user sql (parser) will set a flag on the cast node to indicate
that they are externally generated CAST
nodes. During the bind phase of a CAST node, we will check if the node is externally generated.
If yes, then we will have it pick up 
the collation of the compilation schema otherwise we will leave the collation unchanged.


Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CastNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
    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/CastNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CastNode.java?view=diff&rev=551033&r1=551032&r2=551033
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CastNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CastNode.java Tue Jun
26 21:20:01 2007
@@ -31,7 +31,6 @@
 import org.apache.derby.iapi.sql.compile.C_NodeTypes;
 
 import org.apache.derby.iapi.types.DataTypeUtilities;
-import org.apache.derby.iapi.types.StringDataValue;
 import org.apache.derby.iapi.types.TypeId;
 import org.apache.derby.iapi.reference.Limits;
 
@@ -76,6 +75,17 @@
 	TypeId	destCTI = null;
 	TypeId	sourceCTI = null;
 	boolean forDataTypeFunction = false;
+	/** This variable gets set by the parser to indiciate that this CAST node 
+	 * has been generated by the parser. This means that we should use the 
+	 * collation info of the current compilation schmea for this node's 
+	 * collation setting. If this variable does not get set to true, then it 
+	 * means that this CAST node has been an internally generated node and we 
+	 * should not touch the collation info set for this CAST node because it 
+	 * has been already set correctly by the class that generated this CAST 
+	 * node. Collation info is part of the DataTypeDescriptor that's defined
+	 * on the ValueNode (the super class of this CastNode class)
+	 */ 
+	boolean externallyGeneratedCastNode = false;
 
 	/*
 	** Static array of valid casts.  Dimentions
@@ -363,7 +373,7 @@
 
 		//If the result type of cast is string data type, then that data type 
 		//should get it's collation type from the current schema. 
-		if (destCTI.isStringTypeId()) {
+		if (externallyGeneratedCastNode && destCTI.isStringTypeId()) {
 			//set the collation type to be same as the current schema's 
 			//collation type. Collation derivation is already initialized
 			//to correct value by default which is "IMPLICIT"
@@ -1002,6 +1012,21 @@
 		}
 
 		return returnNode;
+	}
+
+	/** This method gets called by the parser to indiciate that this CAST node 
+	 * has been generated by the parser. This means that we should use the 
+	 * collation info of the current compilation schmea for this node's 
+	 * collation setting. If this method does not get called, then it means
+	 * that this CAST node has been an internally generated node and we should
+	 * not touch the collation of this CAST node because it has been already 
+	 * set correctly by the class that generated this CAST node. 
+	 * 
+	 * @param b true to use function conversion rules
+	 */
+	public void setForExternallyGeneratedCASTnode()
+	{
+		externallyGeneratedCastNode = true;
 	}
 
 	/** set this to be a dataTypeScalarFunction

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj?view=diff&rev=551033&r1=551032&r2=551033
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj Tue Jun
26 21:20:01 2007
@@ -6666,6 +6666,7 @@
 									dts,
 									getContextManager());
 			((CastNode) value).setForDataTypeFunction(true);
+			((CastNode) value).setForExternallyGeneratedCASTnode();
 
 			return value;
 	  }
@@ -6681,6 +6682,7 @@
 												getContextManager());
 
 		((CastNode) value).setForDataTypeFunction(true);
+		((CastNode) value).setForExternallyGeneratedCASTnode();
 		return value;
 	}
 }
@@ -7229,11 +7231,13 @@
      */
         <TIME> <LEFT_PAREN> value = additiveExpression(null,0, false) <RIGHT_PAREN>
 	{
-		return (ValueNode) nodeFactory.getNode(
+		ValueNode castValue = (ValueNode) nodeFactory.getNode(
 							C_NodeTypes.CAST_NODE,
                                                         value,
                                                         DataTypeDescriptor.getBuiltInDataTypeDescriptor(
Types.TIME),
                                                         getContextManager());
+		((CastNode) castValue).setForExternallyGeneratedCASTnode();
+		return castValue;
         }
 |
         <DATE> <LEFT_PAREN> value = additiveExpression(null,0, false) <RIGHT_PAREN>
@@ -9308,6 +9312,7 @@
 									value,
 									dts,
 									getContextManager());
+		((CastNode) treeTop).setForExternallyGeneratedCASTnode();
 
 		/* We need to generate a SQL->Java conversion tree above us if
 		 * the dataTypeCast is a user type.
@@ -11308,12 +11313,14 @@
 {
 	<END>
 	{
-		return ((ValueNode) nodeFactory.getNode(
+		ValueNode value = (ValueNode) nodeFactory.getNode(
 										C_NodeTypes.CAST_NODE,
 										(ValueNode) nodeFactory.getNode(C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE,
 																		getContextManager()),
 										DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.CHAR, 1),	
-										getContextManager()));
+										getContextManager());
+		((CastNode) value).setForExternallyGeneratedCASTnode();
+		return value;
 	}
 |
 	<ELSE> expr = thenElseExpression() <END>
@@ -11368,12 +11375,14 @@
 	LOOKAHEAD ( {getToken(1).kind == NULL} )
 	<NULL>
 	{
-		return((ValueNode) nodeFactory.getNode(
+		ValueNode value = (ValueNode) nodeFactory.getNode(
 										C_NodeTypes.CAST_NODE,
 										(ValueNode) nodeFactory.getNode(C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE,
 																		getContextManager()),
 										DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.CHAR, 1),	
-										getContextManager()));
+										getContextManager());
+		((CastNode) value).setForExternallyGeneratedCASTnode();
+		return value;
 	}
 |
 	expr = additiveExpression(null, 0, false)

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=551033&r1=551032&r2=551033
==============================================================================
--- 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
Tue Jun 26 21:20:01 2007
@@ -545,6 +545,21 @@
     		" ((CASE WHEN 1=1 THEN TABLENAME ELSE 'c' END) AS CHAR(12)) = " +
 			" 'SYSCOLUMNS'",
     		new String[][] {{"SYSCOLUMNS"} });   
+    //Another test for CASE WHEN THEN ELSE DERBY-2776
+    //The data type for THEN is not same as the data type for ELSE.
+    //THEN is of type CHAR and ELSE is of type VARCHAR. VARCHAR has higher
+    //precedence hence the type associated with the return type of CASE will
+    //be VARCHAR. Also, since the collation type of THEN and ELSE match,
+    //which is TERRITORY BASED, the return type of CASE will have the collation
+    //of TERRITORY BASED. This collation is same as the rhs of the = operation
+    //and hence following sql will pass. 
+    checkLangBasedQuery(s, "SELECT count(*) FROM CUSTOMER WHERE CASE WHEN " +
+    		" 1=1 THEN NAMECHAR ELSE NAME END = NAMECHAR",
+    		new String[][] {{"7"} });   
+    //The query below will work for the same reason. 
+    checkLangBasedQuery(s, "SELECT count(*) FROM SYS.SYSTABLES WHERE CASE " +
+    		" WHEN 1=1 THEN TABLENAME ELSE TABLEID END = TABLENAME",
+    		new String[][] {{"21"} });   
 
     //Do some testing using CONCATENATION
     //following will fail because result string of concatenation has 
@@ -894,15 +909,16 @@
 
 private void setUpTable(Statement s) throws SQLException {
 
-    s.execute("CREATE TABLE CUSTOMER(ID INT, NAME VARCHAR(40))");
+    s.execute("CREATE TABLE CUSTOMER(ID INT, NAME VARCHAR(40), NAMECHAR CHAR(40))");
     
     Connection conn = s.getConnection();
 
-    PreparedStatement ps = conn.prepareStatement("INSERT INTO CUSTOMER VALUES(?,?)");
+    PreparedStatement ps = conn.prepareStatement("INSERT INTO CUSTOMER VALUES(?,?,?)");
     for (int i = 0; i < NAMES.length; i++)
     {
             ps.setInt(1, i);
             ps.setString(2, NAMES[i]);
+            ps.setString(3, NAMES[i]);
             ps.executeUpdate();
     }
 



Mime
View raw message