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 rh...@apache.org on 2008/10/31 14:51:54 UTC

svn commit: r709415 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/sql/compile/ engine/org/apache/derby/impl/sql/compile/ engine/org/apache/derby/loc/ shared/org/apache/derby/shared/common/reference/ testing/org/apache/derbyTesting/functi...

Author: rhillegas
Date: Fri Oct 31 06:51:53 2008
New Revision: 709415

URL: http://svn.apache.org/viewvc?rev=709415&view=rev
Log:
DERBY-481: Generation clauses may not invoke functions which run SQL.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java?rev=709415&r1=709414&r2=709415&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java Fri Oct 31 06:51:53 2008
@@ -100,6 +100,7 @@
 	public  static  final   int			MODIFIES_SQL_DATA_PROCEDURE_ILLEGAL	=	0x00000800;
 
 	public  static  final   int			NON_DETERMINISTIC_ILLEGAL		=	0x00001000;
+	public  static  final   int			SQL_IN_ROUTINES_ILLEGAL		=	0x00002000;
 
 	/** Standard SQL is legal */
 	public	static	final	int			SQL_LEGAL					=	(INTERNAL_SQL_ILLEGAL);
@@ -126,7 +127,8 @@
 
 	public	static	final	int			GENERATION_CLAUSE_RESTRICTION		= (
 		                                                                    CHECK_CONSTRAINT |
-																			NON_DETERMINISTIC_ILLEGAL
+																			NON_DETERMINISTIC_ILLEGAL |
+                                                                            SQL_IN_ROUTINES_ILLEGAL
 																			);
 
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java?rev=709415&r1=709414&r2=709415&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java Fri Oct 31 06:51:53 2008
@@ -1502,7 +1502,7 @@
 		// if we're in a context that forbids unreliable fragments, raise an error
 		if ( ( getCompilerContext().getReliability() & fragmentBitMask ) != 0 )
 		{
-            throwReliabilityException( fragmentType );
+            throwReliabilityException( fragmentType, fragmentBitMask );
 		}
 	}
 
@@ -1525,7 +1525,7 @@
 		if ( ( getCompilerContext().getReliability() & fragmentBitMask ) != 0 )
 		{
             String fragmentTypeTxt = MessageService.getTextMessage( fragmentType );
-            throwReliabilityException( fragmentTypeTxt );
+            throwReliabilityException( fragmentTypeTxt, fragmentBitMask );
 		}
 	}
 
@@ -1535,7 +1535,7 @@
      * @param fragmentType Type of fragment as a string, for inclusion in error messages.
      * @exception StandardException        Throws an error, always.
      */
-    private void throwReliabilityException( String fragmentType ) throws StandardException
+    private void throwReliabilityException( String fragmentType, int fragmentBitMask ) throws StandardException
     {
         String sqlState;
 		/* Error string somewhat dependent on operation due to different
@@ -1547,7 +1547,16 @@
 		}
 		else if (getCompilerContext().getReliability() == CompilerContext.GENERATION_CLAUSE_RESTRICTION)
 		{
-            sqlState = SQLState.LANG_NON_DETERMINISTIC_GENERATION_CLAUSE;
+            switch ( fragmentBitMask )
+            {
+            case CompilerContext.SQL_IN_ROUTINES_ILLEGAL:
+                sqlState = SQLState.LANG_ROUTINE_CANT_PERMIT_SQL;
+                break;
+
+            default:
+                sqlState = SQLState.LANG_NON_DETERMINISTIC_GENERATION_CLAUSE;
+                break;
+            }
 		}
 		else
 		{

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java?rev=709415&r1=709414&r2=709415&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java Fri Oct 31 06:51:53 2008
@@ -221,6 +221,10 @@
             {
                 checkReliability( getMethodName(), CompilerContext.NON_DETERMINISTIC_ILLEGAL );
             }
+            if ( permitsSQL( routineInfo ) )
+            {
+                checkReliability( getMethodName(), CompilerContext.SQL_IN_ROUTINES_ILLEGAL );
+            }
 			
 
 
@@ -316,6 +320,24 @@
 	}
 
 	/**
+	 * Returns true if the routine permits SQL.
+	 */
+    private boolean permitsSQL( RoutineAliasInfo rai )
+    {
+        short       sqlAllowed = rai.getSQLAllowed();
+
+        switch( sqlAllowed )
+        {
+        case RoutineAliasInfo.MODIFIES_SQL_DATA:
+        case RoutineAliasInfo.READS_SQL_DATA:
+        case RoutineAliasInfo.CONTAINS_SQL:
+            return true;
+
+        default:    return false;
+        }
+    }
+    
+	/**
 	 * If this SQL function has parameters which are SQLToJavaValueNode over
 	 * JavaToSQLValueNode and the java value node underneath is a SQL function
 	 * defined with CALLED ON NULL INPUT, then we can get rid of the wrapper

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=709415&r1=709414&r2=709415&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Fri Oct 31 06:51:53 2008
@@ -1971,7 +1971,7 @@
 
             <msg>
                 <name>42XA2</name>
-                <text>'{0}' may not appear in a GENERATION CLAUSE because it may return unreliable results.</text>
+                <text>'{0}' cannot appear in a GENERATION CLAUSE because it may return unreliable results.</text>
                 <arg>value</arg>
             </msg>
 
@@ -1988,6 +1988,12 @@
             </msg>
 
             <msg>
+                <name>42XA5</name>
+                <text>Routine '{0}' may issue SQL and therefore cannot appear in a GENERATION CLAUSE.</text>
+                <arg>value</arg>
+            </msg>
+
+            <msg>
                 <name>42Y00</name>
                 <text>Class '{0}' does not implement org.apache.derby.iapi.db.AggregateDefinition and thus cannot be used as an aggregate expression.</text>
                 <arg>className</arg>

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=709415&r1=709414&r2=709415&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Fri Oct 31 06:51:53 2008
@@ -898,6 +898,7 @@
     String LANG_NON_DETERMINISTIC_GENERATION_CLAUSE                  = "42XA2";
     String LANG_CANT_OVERRIDE_GENERATION_CLAUSE                  = "42XA3";
     String LANG_CANT_REFERENCE_GENERATED_COLUMN                  = "42XA4";
+    String LANG_ROUTINE_CANT_PERMIT_SQL                                   = "42XA5";
 	String LANG_INVALID_USER_AGGREGATE_DEFINITION2                     = "42Y00";
 	String LANG_INVALID_CHECK_CONSTRAINT                               = "42Y01";
 	// String LANG_NO_ALTER_TABLE_COMPRESS_ON_TARGET_TABLE                = "42Y02";

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsTest.java?rev=709415&r1=709414&r2=709415&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsTest.java Fri Oct 31 06:51:53 2008
@@ -57,9 +57,11 @@
     ///////////////////////////////////////////////////////////////////////////////////
 
     private static  final   String  REDUNDANT_CLAUSE = "42613";
+    private static  final   String  ILLEGAL_AGGREGATE = "42XA1";
     private static  final   String  UNSTABLE_RESULTS = "42XA2";
     private static  final   String  CANT_OVERRIDE_GENERATION_CLAUSE = "42XA3";
     private static  final   String  CANT_REFERENCE_GENERATED_COLUMN = "42XA4";
+    private static  final   String  ROUTINE_CANT_ISSUE_SQL = "42XA5";
     private static  final   String  CONSTRAINT_VIOLATION = "23513";
     private static  final   String  FOREIGN_KEY_VIOLATION = "23503";
     private static  final   String  ILLEGAL_DUPLICATE = "23505";
@@ -1363,6 +1365,28 @@
              conn,
              "create table t_br_3( a int )"
              );
+        goodStatement
+            (
+             conn,
+             "create function f_br_reads_sql( a int )\n" +
+             "returns int\n" +
+             "language java\n" +
+             "deterministic\n" +
+             "parameter style java\n" +
+             "reads sql data\n" +
+             "external name 'java.lang.Math.abs'\n"
+             );
+        goodStatement
+            (
+             conn,
+             "create function f_br_contains_sql( a int )\n" +
+             "returns int\n" +
+             "language java\n" +
+             "deterministic\n" +
+             "parameter style java\n" +
+             "contains sql\n" +
+             "external name 'java.lang.Math.abs'\n"
+             );
         
         expectCompilationError
             (
@@ -1384,6 +1408,61 @@
              MISPLACED_SELECT,
              "alter table t_br_3 add column b int generated always as ( select a from t_br_1 )"
              );
+        expectCompilationError
+            (
+             ROUTINE_CANT_ISSUE_SQL,
+             "create table t_br_2( a int, b int generated always as ( f_br_reads_sql( a ) ) )"
+             );
+        expectCompilationError
+            (
+             ROUTINE_CANT_ISSUE_SQL,
+             "create table t_br_2( a int, b int generated always as ( f_br_contains_sql( a ) ) )"
+             );
+        expectCompilationError
+            (
+             ILLEGAL_AGGREGATE,
+             "create table t_br_2( a int, b int generated always as ( sum( a ) ) )"
+             );
+        expectCompilationError
+            (
+             ILLEGAL_AGGREGATE,
+             "create table t_br_2( a int, b int generated always as ( max( a ) ) )"
+             );
+        expectCompilationError
+            (
+             ILLEGAL_AGGREGATE,
+             "create table t_br_2( a int, b int generated always as ( min( a ) ) )"
+             );
+        expectCompilationError
+            (
+             ILLEGAL_AGGREGATE,
+             "create table t_br_2( a int, b int generated always as ( count( a ) ) )"
+             );
+        expectCompilationError
+            (
+             UNSTABLE_RESULTS,
+             "create table t_br_2( a int, b date generated always as ( current_date ) )"
+             );
+        expectCompilationError
+            (
+             UNSTABLE_RESULTS,
+             "create table t_br_2( a int, b time generated always as ( current_time ) )"
+             );
+        expectCompilationError
+            (
+             UNSTABLE_RESULTS,
+             "create table t_br_2( a int, b timestamp generated always as ( current_timestamp ) )"
+             );
+        expectCompilationError
+            (
+             UNSTABLE_RESULTS,
+             "create table t_br_2( a int, b varchar( 128 ) generated always as ( current_user ) )"
+             );
+        expectCompilationError
+            (
+             UNSTABLE_RESULTS,
+             "create table t_br_2( a int, b varchar( 128 ) generated always as ( session_user ) )"
+             );
     }
 
     ///////////////////////////////////////////////////////////////////////////////////