package net.sourceforge.mayfly.acceptance; import java.sql.SQLException; public class StoredProcedureTest extends SqlTestCase { public void testJavaFunctionNoAlias() throws Exception { execute("create table foo(a integer)"); execute("insert into foo(a) values(-7)"); execute("insert into foo(a) values(5)"); String query = "select \"java.lang.Math.abs\"(a) from foo"; if (dialect.callJavaMethodAsStoredProcedure()) { assertResultSet( new String[] { " 5 ", " 7 " }, query(query)); } else { expectQueryFailure(query, "This feature is not yet implemented in Mayfly"); } } public void testWithAlias() throws Exception { String createAlias = "create alias sample for " + "\"" + getClass().getName() + ".sampleProcedure\""; if (dialect.haveCreateAlias()) { execute(createAlias); execute("create table foo(a integer, b integer)"); execute("insert into foo(a, b) values(2, 3)"); execute("insert into foo(a, b) values(20, -1)"); assertResultSet( new String[] { " 13 ", " 401 " }, query("select sample(a, b) from foo")); } else { expectExecuteFailure(createAlias, "expected create command but got alias"); } } static public int sampleProcedure(int a, int b) { return a * a + b * b; } public void testOverloadedOnArgumentCount() throws Exception { if (!dialect.haveCreateAlias()) { return; } execute("create table foo(a integer)"); execute("insert into foo(a) values(5)"); createAlias("overloaded"); String query = "select overloaded(a) from foo"; if (dialect.complainAboutStoredProcedureOverloadingOnArgumentTypeOrCount()) { expectQueryFailure(query, "multiple methods found for stored procedure.\n" + "class: " + getClass().getName() + "\n" + "method: overloaded"); } else { /* I'm not really sure how hypersonic is picking a method or how it is behaving in general. So I'm not going to assert on what it returns. */ query(query); } } static public int overloaded(int a) { return a; } static public int overloaded(int a, int b) { return a + b; } public void testOverloadedOnArgumentType() throws Exception { if (!dialect.haveCreateAlias()) { return; } execute("create table foo(a integer)"); execute("insert into foo(a) values(5)"); createAlias("onType"); String query = "select onType(a) from foo"; if (dialect.complainAboutStoredProcedureOverloadingOnArgumentTypeOrCount()) { expectQueryFailure(query, "multiple methods found for stored procedure.\n" + "class: " + getClass().getName() + "\n" + "method: onType"); } else { /* I'm not really sure how hypersonic is picking a method or how it is behaving in general. So I'm not going to assert on what it returns. */ query(query); } } static public int onType(int a) { return a; } static public int onType(double a) { return 1234; } public void testWrongNumberOfArguments() throws Exception { if (!dialect.haveCreateAlias()) { return; } execute("create table foo(a integer)"); execute("insert into foo(a) values(5)"); createAlias("twoArguments"); String query = "select twoArguments(a) from foo"; if (dialect.complainAboutDubiousStoredProcedure()) { expectQueryFailure(query, "stored procedure expected 2 arguments but got 1.\n" + "class: " + getClass().getName() + "\n" + "method: onType"); } else { /* I'm not really sure how hypersonic is picking a method or how it is behaving in general. So I'm not going to assert on what it returns. */ query(query); } } static public int twoArguments(int a, int b) { return a + b; } public void testMethodNotStatic() throws Exception { if (!dialect.haveCreateAlias()) { return; } execute("create table foo(a integer)"); execute("insert into foo(a) values(5)"); String query = "select notStatic(a) from foo"; String expectedMessage = "stored procedure method must be static.\n" + "class: " + getClass().getName() + "\n" + "method: notStatic"; try { createAlias("notStatic"); query(query); failForMissingException(query, expectedMessage); } catch (SQLException e) { assertMessage(expectedMessage, e); } } public int notStatic(int a) { return a; } public void testMethodNotPublic() throws Exception { if (!dialect.haveCreateAlias()) { return; } execute("create table foo(a integer)"); execute("insert into foo(a) values(5)"); String query = "select notPublic(a) from foo"; String expectedMessage = "stored procedure method must be public.\n" + "class: " + getClass().getName() + "\n" + "method: notPublic"; // Might be too much trouble to give a message other than "not found (maybe not public?)" try { createAlias("notPublic"); query(query); failForMissingException(query, expectedMessage); } catch (SQLException e) { assertMessage(expectedMessage, e); } } static int notPublic(int a) { return a; } private void createAlias(String methodAndAliasName) throws SQLException { execute("create alias " + methodAndAliasName + " for " + "\"" + getClass().getName() + "." + methodAndAliasName + "\""); } // types on arguments (int vs float vs string vs ?) // types on return type // in WHERE, not just in select // case-sensitive on method (I think that is right; it is in quotes, after all) // case-insensitive on alias (for analogous reasons) }