Skip to content

Commit

Permalink
flyway#1154 - Drop functions with length attributes in DB2
Browse files Browse the repository at this point in the history
  • Loading branch information
markus.umefjord@gmail.com committed Jan 8, 2016
1 parent 7f142af commit 46e1e99
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 40 deletions.
@@ -1,12 +1,12 @@
/**
* Copyright 2010-2015 Boxfuse GmbH
*
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand All @@ -22,33 +22,76 @@
import org.flywaydb.core.internal.util.StringUtils;

import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;

/**
* Db2-specific function.
*/
public class DB2Function extends Function {
/**
* Creates a new Db2 function.
*
* @param jdbcTemplate The Jdbc Template for communicating with the DB.
* @param dbSupport The database-specific support.
* @param schema The schema this function lives in.
* @param name The name of the function.
* @param args The arguments of the function.
*/
public DB2Function(JdbcTemplate jdbcTemplate, DbSupport dbSupport, Schema schema, String name, String... args) {
super(jdbcTemplate, dbSupport, schema, name, args);
}

@Override
protected void doDrop() throws SQLException {
jdbcTemplate.execute("DROP FUNCTION "
+ dbSupport.quote(schema.getName(), name)
+ "(" + StringUtils.arrayToCommaDelimitedString(args) + ")");
}

@Override
public String toString() {
return super.toString() + "(" + StringUtils.arrayToCommaDelimitedString(args) + ")";
}

//Functions with Decfloat and Binary cannot be dropped with specified arguments, but may be dropped without arguments if their
//names are unique => This means that if you have overloaded functions with these types, the drop statements will fail.
// A possible workaround is to use unique names for functions with these types.
private static final Collection<String> typesWithLength = Arrays.asList(
"character",
"char",
"varchar",
"graphic",
"vargraphic",
"decimal",
"float",
"varbinary");

/**
* Creates a new Db2 function.
*
* @param jdbcTemplate The Jdbc Template for communicating with the DB.
* @param dbSupport The database-specific support.
* @param schema The schema this function lives in.
* @param name The name of the function.
* @param args The arguments of the function.
*/
public DB2Function(JdbcTemplate jdbcTemplate, DbSupport dbSupport, Schema schema, String name, String... args) {
super(jdbcTemplate, dbSupport, schema, name, args);
}

@Override
protected void doDrop() throws SQLException {
try {
jdbcTemplate.execute("DROP FUNCTION "
+ dbSupport.quote(schema.getName(), name)
+ "(" + argsToCommaSeparatedString(args) + ")");
} catch (SQLException e) {
//Fallback - try to drop it without arguments - will catch most cases that are not supported above, including
//functions with types "decfloat(16)", "decfloat(34)" and "binary large object"
jdbcTemplate.execute("DROP FUNCTION " + dbSupport.quote(schema.getName(), name));
}
}

/**
* Creates a comma separated string of the arguments, with special treatment of types that have or may have length. In that
* case we need to add empty parenthesis to get a match.
*
* @param args The argument list
* @return A comma separated string that can be included in the function drop statement
*/
private String argsToCommaSeparatedString(String[] args) {
StringBuilder buf = new StringBuilder();
for (String arg : args) {
if (buf.length() > 0) {
buf.append(",");
}
buf.append(arg);
if (typesWithLength.contains(arg.toLowerCase())) {
buf.append("()"); //Add parenthesis to match on "wildcard" length
}
}
return buf.toString();
}

@Override
public String toString() {
return super.toString() + "(" + StringUtils.arrayToCommaDelimitedString(args) + ")";
}
}
Expand Up @@ -14,20 +14,70 @@
-- limitations under the License.
--

CREATE FUNCTION TEST_FUNC ( PARAM1 INTEGER )
CREATE FUNCTION TEST_FUNC(PARAM1 INTEGER)
RETURNS INTEGER
LANGUAGE SQL
RETURN
1;
LANGUAGE SQL
RETURN
1;

CREATE FUNCTION TEST_FUNC ( PARAM1 INTEGER, PARAM2 INTEGER )
CREATE FUNCTION TEST_FUNC(PARAM1 INTEGER, PARAM2 INTEGER)
RETURNS INTEGER
LANGUAGE SQL
RETURN
1;
LANGUAGE SQL
RETURN
1;

CREATE FUNCTION TEST_FUNC ( PARAM1 INTEGER, PARAM2 INTEGER, PARAM3 INTEGER )
CREATE FUNCTION TEST_FUNC(PARAM1 INTEGER, PARAM2 INTEGER, PARAM3 INTEGER)
RETURNS INTEGER
LANGUAGE SQL
RETURN
1;
LANGUAGE SQL
RETURN
1;

CREATE OR REPLACE FUNCTION F_CHAR(ARG CHAR(3))
RETURNS INTEGER
LANGUAGE SQL
RETURN 1;

CREATE OR REPLACE FUNCTION F_VARCHAR(ARG VARCHAR(3))
RETURNS INTEGER
LANGUAGE SQL
RETURN 1;

CREATE OR REPLACE FUNCTION F_GRAPHIC(ARG GRAPHIC(3))
RETURNS INTEGER
LANGUAGE SQL
RETURN 1;

CREATE OR REPLACE FUNCTION F_VARGRAPHIC(ARG VARGRAPHIC(3))
RETURNS INTEGER
LANGUAGE SQL
RETURN 1;

CREATE OR REPLACE FUNCTION F_DECIMAL(ARG DECIMAL(3, 2))
RETURNS INTEGER
LANGUAGE SQL
RETURN 1;

CREATE OR REPLACE FUNCTION F_FLOAT(ARG FLOAT(3))
RETURNS INTEGER
LANGUAGE SQL
RETURN 1;

CREATE OR REPLACE FUNCTION F_DECFLOAT16(ARG DECFLOAT(16))
RETURNS INTEGER
LANGUAGE SQL
RETURN 1;

CREATE OR REPLACE FUNCTION F_DECFLOAT34(ARG DECFLOAT(34))
RETURNS INTEGER
LANGUAGE SQL
RETURN 1;

CREATE OR REPLACE FUNCTION F_BINARY(ARG BINARY LARGE OBJECT(3))
RETURNS INTEGER
LANGUAGE SQL
RETURN 1;

CREATE OR REPLACE FUNCTION F_NVARCHAR(ARG NVARCHAR(3))
RETURNS INTEGER
LANGUAGE SQL
RETURN 1;

0 comments on commit 46e1e99

Please sign in to comment.