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 ka...@apache.org on 2013/12/05 13:08:59 UTC
svn commit: r1548104 - in /db/derby/code/trunk/java:
engine/org/apache/derby/impl/sql/compile/CastNode.java
testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java
Author: kahatlen
Date: Thu Dec 5 12:08:59 2013
New Revision: 1548104
URL: http://svn.apache.org/r1548104
Log:
DERBY-6421: Cast to UDT in CHECK constraint causes NPE or assert failure
Delay binding of target UDT in CastNode till bind time.
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CastNode.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.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?rev=1548104&r1=1548103&r2=1548104&view=diff
==============================================================================
--- 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 Thu Dec 5 12:08:59 2013
@@ -55,7 +55,10 @@ class CastNode extends ValueNode
private int targetCharType;
TypeId sourceCTI = null;
private boolean forDataTypeFunction = false;
-
+
+ /** The original, unbound descriptor for the target type, if it is a UDT. */
+ private DataTypeDescriptor targetUDT;
+
/** This variable gets set by the parser to indicate that this CAST node
* has been generated by the parser. This means that we should use the
* collation info of the current compilation schema for this node's
@@ -99,7 +102,17 @@ class CastNode extends ValueNode
ContextManager cm) throws StandardException {
super(cm);
this.castOperand = castOperand;
- setType(castTarget);
+
+ // DERBY-6421: setType() tries to bind user defined types. We don't
+ // want to do any binding here, since we could be called during
+ // parsing. If the target type is a UDT, just store it for now and
+ // do the binding later when bindExpression() or bindCastNodeOnly()
+ // is called.
+ if (castTarget.getTypeId().isUserDefinedTypeId()) {
+ targetUDT = castTarget;
+ } else {
+ setType(castTarget);
+ }
}
/**
@@ -192,6 +205,11 @@ class CastNode extends ValueNode
fromList, subqueryList,
aggregates);
+ // Bind the target UDT.
+ if (targetUDT != null) {
+ setType(targetUDT);
+ }
+
if (getTypeServices() == null) //CHAR or VARCHAR function without specifying target length
{
DataTypeDescriptor opndType = castOperand.getTypeServices();
@@ -355,6 +373,10 @@ class CastNode extends ValueNode
void bindCastNodeOnly()
throws StandardException
{
+ // Bind the target UDT.
+ if (targetUDT != null) {
+ setType(targetUDT);
+ }
/*
** The result type is always castTarget.
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java?rev=1548104&r1=1548103&r2=1548104&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java Thu Dec 5 12:08:59 2013
@@ -28,6 +28,8 @@ import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
import java.util.HashMap;
import junit.framework.Test;
@@ -48,7 +50,6 @@ public class UDTTest extends GeneratedC
///////////////////////////////////////////////////////////////////////////////////
public static final String OBJECT_EXISTS = "X0Y68";
- public static final String SYNTAX_ERROR = "42X01";
public static final String VIEW_DEPENDS_ON_TYPE = "X0Y23";
public static final String TRIGGER_DEPENDS_ON_TYPE = "X0Y24";
@@ -1219,6 +1220,25 @@ public class UDTTest extends GeneratedC
assertEquals( "[ 0, 0 ]", obj.toString() );
}
+ /**
+ * Verify that you can cast a value to an UDT in a generation clause or
+ * a CHECK constraint. Regression test case for DERBY-6421.
+ */
+ public void test_18_derby6421() throws SQLException {
+ setAutoCommit(false);
+
+ Statement s = createStatement();
+ s.execute("create type d6421_type external name 'java.util.ArrayList' "
+ + "language java");
+ s.execute("create table d6421_table "
+ + "(x generated always as (cast(null as d6421_type)), "
+ + "check (cast(null as d6421_type) is null))");
+
+ // This insert used to cause assert failure (in sane builds) or
+ // NullPointerException (in insane builds).
+ s.execute("insert into d6421_table values default");
+ }
+
///////////////////////////////////////////////////////////////////////////////////
//
// PROCEDURES AND FUNCTIONS