From e567af06c3297455e8b76854cab40f484bd97ca1 Mon Sep 17 00:00:00 2001 From: pesse Date: Fri, 11 Jan 2019 09:50:21 +0100 Subject: [PATCH 01/10] Improve hasOutput check to a real PL/SQL type-check Thanks Jacek for the hint! It's also less verbose now. --- .../outputBuffer/OutputBufferProvider.java | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java index 15ba696..ab4d1b2 100644 --- a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java +++ b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java @@ -1,13 +1,13 @@ package org.utplsql.api.outputBuffer; import oracle.jdbc.OracleConnection; +import oracle.jdbc.OracleTypes; import org.utplsql.api.Version; import org.utplsql.api.exception.InvalidVersionException; import org.utplsql.api.reporter.Reporter; +import java.sql.CallableStatement; import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; public class OutputBufferProvider { @@ -42,26 +42,29 @@ public static OutputBuffer getCompatibleOutputBuffer(Version databaseVersion, Re private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) throws SQLException { - String sql = "select is_output_reporter " + - " from table(ut_runner.get_reporters_list)" + - " where ? = substr(reporter_object_name, length(reporter_object_name)-?+1)"; - try ( PreparedStatement stmt = oraConn.prepareStatement(sql)) { + String sql = + "declare " + + " l_result boolean;" + + "begin " + + " begin " + + " execute immediate '" + + " begin " + + " :x :=' || DBMS_ASSERT.SQL_OBJECT_NAME( ? ) || '() is of (ut_output_reporter_base);" + + " end;'" + + " using out l_result;" + + " exception when others then null;" + + " end;" + + " ? := case l_result when true then 1 else 0 end;" + + "end;"; + + try ( CallableStatement stmt = oraConn.prepareCall(sql)) { stmt.setQueryTimeout(3); stmt.setString(1, reporter.getTypeName()); - stmt.setInt(2, reporter.getTypeName().length()); - - try ( ResultSet rs = stmt.executeQuery() ) { - if ( rs.next() ) { - String isReporterResult = rs.getString(1); + stmt.registerOutParameter(2, OracleTypes.INTEGER); - if ( isReporterResult == null ) - throw new IllegalArgumentException("The given type " + reporter.getTypeName() + " is not a valid Reporter!"); - else - return isReporterResult.equalsIgnoreCase("Y"); - } - else - throw new SQLException("Could not check Reporter validity"); - } + stmt.execute(); + int result = stmt.getInt(2); + return result == 1; } } From 082a6dee2bf11b570085598ab93ae2e449862c25 Mon Sep 17 00:00:00 2001 From: pesse Date: Tue, 15 Jan 2019 22:05:25 +0100 Subject: [PATCH 02/10] Add 3.1.3-release to test matrix --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b9acd06..17f24f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,7 @@ env: - UTPLSQL_VERSION="v3.0.4" - UTPLSQL_VERSION="v3.1.1" - UTPLSQL_VERSION="v3.1.2" + - UTPLSQL_VERSION="v3.1.3" - UTPLSQL_VERSION="develop" UTPLSQL_FILE="utPLSQL" From 01b9e97a8178086b1c50107c566845722d5e5fb7 Mon Sep 17 00:00:00 2001 From: pesse Date: Tue, 15 Jan 2019 22:10:01 +0100 Subject: [PATCH 03/10] Add some debug information to track down that problem on travis --- .../org/utplsql/api/outputBuffer/OutputBufferProvider.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java index ab4d1b2..f961bbe 100644 --- a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java +++ b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java @@ -42,6 +42,7 @@ public static OutputBuffer getCompatibleOutputBuffer(Version databaseVersion, Re private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) throws SQLException { + System.out.println("Checking Reporter hasOutput: " + reporter.getTypeName()); String sql = "declare " + " l_result boolean;" + @@ -64,6 +65,8 @@ private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) stmt.execute(); int result = stmt.getInt(2); + + System.out.println("Output-check: " + result); return result == 1; } } From ef68fc343f83a1cafcdcbdc11e89c125b2e96bec Mon Sep 17 00:00:00 2001 From: pesse Date: Tue, 15 Jan 2019 22:33:57 +0100 Subject: [PATCH 04/10] Out-params of EXECUTE IMMEDIATE in 11.2 cannot be BOOLEAN --- .../org/utplsql/api/outputBuffer/OutputBufferProvider.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java index f961bbe..2395830 100644 --- a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java +++ b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java @@ -45,17 +45,17 @@ private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) System.out.println("Checking Reporter hasOutput: " + reporter.getTypeName()); String sql = "declare " + - " l_result boolean;" + + " l_result int;" + "begin " + " begin " + " execute immediate '" + " begin " + - " :x :=' || DBMS_ASSERT.SQL_OBJECT_NAME( ? ) || '() is of (ut_output_reporter_base);" + + " :x := case ' || DBMS_ASSERT.SQL_OBJECT_NAME( ? ) || '() is of (ut_output_reporter_base) when true then 1 else 0 end;" + " end;'" + " using out l_result;" + " exception when others then null;" + " end;" + - " ? := case l_result when true then 1 else 0 end;" + + " ? := l_result;" + "end;"; try ( CallableStatement stmt = oraConn.prepareCall(sql)) { From 5f130fad2d2066856f2f5e4ef1df3df9c20751bc Mon Sep 17 00:00:00 2001 From: pesse Date: Tue, 15 Jan 2019 22:47:00 +0100 Subject: [PATCH 05/10] We actually *want* an SQL issue to raise an exception --- .../org/utplsql/api/outputBuffer/OutputBufferProvider.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java index 2395830..a011c54 100644 --- a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java +++ b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java @@ -42,7 +42,6 @@ public static OutputBuffer getCompatibleOutputBuffer(Version databaseVersion, Re private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) throws SQLException { - System.out.println("Checking Reporter hasOutput: " + reporter.getTypeName()); String sql = "declare " + " l_result int;" + @@ -53,7 +52,6 @@ private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) " :x := case ' || DBMS_ASSERT.SQL_OBJECT_NAME( ? ) || '() is of (ut_output_reporter_base) when true then 1 else 0 end;" + " end;'" + " using out l_result;" + - " exception when others then null;" + " end;" + " ? := l_result;" + "end;"; @@ -66,7 +64,7 @@ private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) stmt.execute(); int result = stmt.getInt(2); - System.out.println("Output-check: " + result); + System.out.println("Output-check for " + reporter.getTypeName() + ": " + result); return result == 1; } } From cf9b502fc7cf638983a45acab0172936830e7f1e Mon Sep 17 00:00:00 2001 From: pesse Date: Tue, 15 Jan 2019 23:08:19 +0100 Subject: [PATCH 06/10] Poking around... --- .../java/org/utplsql/api/outputBuffer/OutputBufferProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java index a011c54..3ac0aa0 100644 --- a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java +++ b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java @@ -49,7 +49,7 @@ private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) " begin " + " execute immediate '" + " begin " + - " :x := case ' || DBMS_ASSERT.SQL_OBJECT_NAME( ? ) || '() is of (ut_output_reporter_base) when true then 1 else 0 end;" + + " :x := case (' || DBMS_ASSERT.SQL_OBJECT_NAME( ? ) || '() is of (ut_output_reporter_base)) when true then 1 else 0 end;" + " end;'" + " using out l_result;" + " end;" + From 85014b82611b5175af2fc617727f02402b5e4d47 Mon Sep 17 00:00:00 2001 From: pesse Date: Tue, 15 Jan 2019 23:32:30 +0100 Subject: [PATCH 07/10] Do sanitizing on java level --- .../utplsql/api/outputBuffer/OutputBufferProvider.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java index 3ac0aa0..5503e66 100644 --- a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java +++ b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java @@ -42,6 +42,10 @@ public static OutputBuffer getCompatibleOutputBuffer(Version databaseVersion, Re private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) throws SQLException { + String reporterName = reporter.getTypeName(); + if ( !reporterName.matches("^[a-zA-Z0-9_]+$")) + throw new IllegalArgumentException(String.format("Reporter-Name %s is not valid", reporterName)); + String sql = "declare " + " l_result int;" + @@ -49,7 +53,7 @@ private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) " begin " + " execute immediate '" + " begin " + - " :x := case (' || DBMS_ASSERT.SQL_OBJECT_NAME( ? ) || '() is of (ut_output_reporter_base)) when true then 1 else 0 end;" + + " :x := case ' || ? || '() is of (ut_output_reporter_base) when true then 1 else 0 end;" + " end;'" + " using out l_result;" + " end;" + @@ -58,13 +62,13 @@ private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) try ( CallableStatement stmt = oraConn.prepareCall(sql)) { stmt.setQueryTimeout(3); - stmt.setString(1, reporter.getTypeName()); + stmt.setString(1, reporterName); stmt.registerOutParameter(2, OracleTypes.INTEGER); stmt.execute(); int result = stmt.getInt(2); - System.out.println("Output-check for " + reporter.getTypeName() + ": " + result); + System.out.println("Output-check for " + reporterName + ": " + result); return result == 1; } } From 1a1732a0a2a83d0a32565e80d5d6e1bea6855f87 Mon Sep 17 00:00:00 2001 From: pesse Date: Wed, 16 Jan 2019 00:25:29 +0100 Subject: [PATCH 08/10] Add valid_sql_name to sanitization --- .../org/utplsql/api/outputBuffer/OutputBufferProvider.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java index 5503e66..14c3f39 100644 --- a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java +++ b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java @@ -53,7 +53,7 @@ private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) " begin " + " execute immediate '" + " begin " + - " :x := case ' || ? || '() is of (ut_output_reporter_base) when true then 1 else 0 end;" + + " :x := case ' || dbms_assert.valid_sql_name( ? ) || '() is of (ut_output_reporter_base) when true then 1 else 0 end;" + " end;'" + " using out l_result;" + " end;" + @@ -67,8 +67,6 @@ private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) stmt.execute(); int result = stmt.getInt(2); - - System.out.println("Output-check for " + reporterName + ": " + result); return result == 1; } } From 41f0a479c0e7450ada6d4286e9e80815839aaca3 Mon Sep 17 00:00:00 2001 From: pesse Date: Wed, 16 Jan 2019 07:32:57 +0100 Subject: [PATCH 09/10] Reporter-name should always be a simple SQL name --- .../java/org/utplsql/api/outputBuffer/OutputBufferProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java index 14c3f39..33736c3 100644 --- a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java +++ b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java @@ -53,7 +53,7 @@ private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) " begin " + " execute immediate '" + " begin " + - " :x := case ' || dbms_assert.valid_sql_name( ? ) || '() is of (ut_output_reporter_base) when true then 1 else 0 end;" + + " :x := case ' || dbms_assert.simple_sql_name( ? ) || '() is of (ut_output_reporter_base) when true then 1 else 0 end;" + " end;'" + " using out l_result;" + " end;" + From 55c4d836d20263e599c31320539afb955c531401 Mon Sep 17 00:00:00 2001 From: pesse Date: Wed, 16 Jan 2019 07:51:47 +0100 Subject: [PATCH 10/10] We don't need the java sanitization anymore --- .../org/utplsql/api/outputBuffer/OutputBufferProvider.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java index 33736c3..54a2a0b 100644 --- a/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java +++ b/src/main/java/org/utplsql/api/outputBuffer/OutputBufferProvider.java @@ -42,10 +42,6 @@ public static OutputBuffer getCompatibleOutputBuffer(Version databaseVersion, Re private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) throws SQLException { - String reporterName = reporter.getTypeName(); - if ( !reporterName.matches("^[a-zA-Z0-9_]+$")) - throw new IllegalArgumentException(String.format("Reporter-Name %s is not valid", reporterName)); - String sql = "declare " + " l_result int;" + @@ -62,7 +58,7 @@ private static boolean hasOutput( Reporter reporter, OracleConnection oraConn ) try ( CallableStatement stmt = oraConn.prepareCall(sql)) { stmt.setQueryTimeout(3); - stmt.setString(1, reporterName); + stmt.setString(1, reporter.getTypeName()); stmt.registerOutParameter(2, OracleTypes.INTEGER); stmt.execute();