[#1908] Compilation error in generated code when a MySQL procedure and function share the same name and signature

This commit is contained in:
Lukas Eder 2013-09-20 16:34:10 +02:00
parent 90b67fef15
commit 45ad210268
4 changed files with 69 additions and 10 deletions

View File

@ -53,11 +53,15 @@ import static org.jooq.util.mysql.mysql.tables.Proc.PROC;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.jooq.DSLContext;
import org.jooq.Field;
import org.jooq.Record;
import org.jooq.Record4;
import org.jooq.Record5;
import org.jooq.Record6;
import org.jooq.Result;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL;
@ -79,6 +83,7 @@ import org.jooq.util.mysql.information_schema.tables.ReferentialConstraints;
import org.jooq.util.mysql.information_schema.tables.Schemata;
import org.jooq.util.mysql.information_schema.tables.TableConstraints;
import org.jooq.util.mysql.information_schema.tables.Tables;
import org.jooq.util.mysql.mysql.enums.ProcType;
import org.jooq.util.mysql.mysql.tables.Proc;
/**
@ -308,26 +313,46 @@ public class MySQLDatabase extends AbstractDatabase {
protected List<RoutineDefinition> getRoutines0() throws SQLException {
List<RoutineDefinition> result = new ArrayList<RoutineDefinition>();
for (Record record : create().select(
Result<Record6<String, String, String, byte[], byte[], ProcType>> records =
create().select(
Proc.DB,
Proc.NAME,
Proc.COMMENT,
Proc.PARAM_LIST,
Proc.RETURNS)
Proc.RETURNS,
Proc.TYPE)
.from(PROC)
.where(DB.in(getInputSchemata()))
.orderBy(
DB,
Proc.NAME)
.fetch()) {
.fetch();
SchemaDefinition schema = getSchema(record.getValue(DB));
String name = record.getValue(Proc.NAME);
String comment = record.getValue(Proc.COMMENT);
String params = new String(record.getValue(Proc.PARAM_LIST));
String returns = new String(record.getValue(Proc.RETURNS));
Map<Record, Result<Record6<String, String, String, byte[], byte[], ProcType>>> groups =
records.intoGroups(new Field[] { Proc.DB, Proc.NAME });
result.add(new MySQLRoutineDefinition(schema, name, comment, params, returns));
// [#1908] This indirection is necessary as MySQL allows for overloading
// procedures and functions with the same signature.
for (Entry<Record, Result<Record6<String, String, String, byte[], byte[], ProcType>>> entry : groups.entrySet()) {
Result<?> overloads = entry.getValue();
for (int i = 0; i < overloads.size(); i++) {
Record record = overloads.get(i);
SchemaDefinition schema = getSchema(record.getValue(DB));
String name = record.getValue(Proc.NAME);
String comment = record.getValue(Proc.COMMENT);
String params = new String(record.getValue(Proc.PARAM_LIST));
String returns = new String(record.getValue(Proc.RETURNS));
ProcType type = record.getValue(Proc.TYPE);
if (overloads.size() > 1) {
result.add(new MySQLRoutineDefinition(schema, name, comment, params, returns, type, "_" + type.name()));
}
else {
result.add(new MySQLRoutineDefinition(schema, name, comment, params, returns, type, null));
}
}
}
return result;

View File

@ -55,6 +55,7 @@ import org.jooq.util.InOutDefinition;
import org.jooq.util.ParameterDefinition;
import org.jooq.util.SchemaDefinition;
import org.jooq.util.mysql.information_schema.tables.Parameters;
import org.jooq.util.mysql.mysql.enums.ProcType;
/**
* @author Lukas Eder
@ -65,12 +66,22 @@ public class MySQLRoutineDefinition extends AbstractRoutineDefinition {
private final String params;
private final String returns;
private final ProcType procType;
/**
* @deprecated - This constructor was deprecated with jOOQ 3.2
*/
@Deprecated
public MySQLRoutineDefinition(SchemaDefinition schema, String name, String comment, String params, String returns) {
super(schema, null, name, comment, null);
this(schema, name, comment, params, returns, null, null);
}
public MySQLRoutineDefinition(SchemaDefinition schema, String name, String comment, String params, String returns, ProcType procType, String overload) {
super(schema, null, name, comment, overload);
this.params = params;
this.returns = returns;
this.procType = procType;
}
@Override
@ -100,6 +111,7 @@ public class MySQLRoutineDefinition extends AbstractRoutineDefinition {
.from(PARAMETERS)
.where(Parameters.SPECIFIC_SCHEMA.eq(getSchema().getInputName()))
.and(Parameters.SPECIFIC_NAME.eq(getInputName()))
.and(Parameters.ROUTINE_TYPE.eq(procType.name()))
.orderBy(Parameters.ORDINAL_POSITION.asc())
.fetch()) {

View File

@ -894,4 +894,10 @@ public class MySQLTest extends jOOQAbstractTest<
assertEquals(d2, dates.getValue(1, 0));
assertEquals(d2, dates.getValue(1, 1));
}
@Test
public void testMySQLOverloadedProcedures() throws Exception {
assertEquals(1, (int) Routines.fp1908_FUNCTION(create().configuration(), 1));
assertEquals(2, (int) Routines.fp1908_PROCEDURE(create().configuration(), 1));
}
}

View File

@ -13,6 +13,9 @@ DROP FUNCTION IF EXISTS f_one/
DROP FUNCTION IF EXISTS f_number/
DROP FUNCTION IF EXISTS f317/
DROP PROCEDURE IF EXISTS fp1908/
DROP FUNCTION IF EXISTS fp1908/
DROP TRIGGER IF EXISTS t_triggers_trigger/
DROP TABLE IF EXISTS t_dates/
@ -423,4 +426,17 @@ CREATE FUNCTION f317 (p1 int, p2 int, p3 int, p4 int)
BEGIN
RETURN 1000 * p1 + 100 * p2 + p4;
END
/
CREATE PROCEDURE fp1908(in p1 integer, out p2 integer)
BEGIN
SET p2 = p1 + 1;
END
/
CREATE FUNCTION fp1908(p1 integer)
RETURNS INT
BEGIN
RETURN p1;
END
/