public int execute(PostgresQueryContext context, QueryBindings bindings, int maxrows) throws IOException {
PostgresServerSession server = context.getServer();
PostgresMessenger messenger = server.getMessenger();
int nrows = 0;
Queue<ResultSet> dynamicResultSets = null;
ServerJavaRoutine call = javaRoutine(context, bindings);
call.push();
boolean anyOutput = false, success = false;
try {
call.setInputs();
call.invoke();
dynamicResultSets = call.getDynamicResultSets();
if (getColumnTypes() != null) {
PostgresOutputter<ServerJavaRoutine> outputter;
switch (server.getOutputFormat()) {
case JSON:
case JSON_WITH_META_DATA:
outputter = new PostgresJavaRoutineJsonOutputter(context, this,
dynamicResultSets);
break;
default:
outputter = new PostgresJavaRoutineResultsOutputter(context, this);
break;
}
outputter.beforeData();
outputter.output(call);
nrows++;
anyOutput = true;
outputter.afterData();
}
if (!dynamicResultSets.isEmpty()) {
PostgresDynamicResultSetOutputter outputter =
new PostgresDynamicResultSetOutputter(context, this);
while (!dynamicResultSets.isEmpty()) {
ResultSet rs = dynamicResultSets.remove();
if (anyOutput) {
// Postgres protocol does not allow for
// multiple result sets, except as the result
// of multiple commands. So pretend that's what we've
// got. Even with that, most clients seem to only expose the
// last result set.
messenger.beginMessage(PostgresMessages.COMMAND_COMPLETE_TYPE.code());
messenger.writeString("CALL " + nrows);
messenger.sendMessage();
nrows = 0;
}
try {
outputter.setMetaData(rs.getMetaData(), context);
outputter.sendDescription();
while (rs.next()) {
outputter.output(rs);
nrows++;
}
}
catch (SQLException ex) {
throw new ExternalRoutineInvocationException(invocation.getRoutineName(), ex);
}
finally {
try {
rs.close();
}
catch (SQLException ex) {
}
}
anyOutput = true;
}
}
success = true;
}
finally {
call.pop(success);
}
{
messenger.beginMessage(PostgresMessages.COMMAND_COMPLETE_TYPE.code());
messenger.writeString("CALL " + nrows);
messenger.sendMessage();