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 ) )"
+ );
}
///////////////////////////////////////////////////////////////////////////////////