/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.sql.embedded; import com.foundationdb.sql.embedded.JDBCParameterMetaData.ParameterType; import com.foundationdb.ais.model.Parameter; import com.foundationdb.ais.model.TableName; import com.foundationdb.server.error.UnsupportedSQLException; import com.foundationdb.server.service.monitor.SessionMonitor.StatementTypes; import com.foundationdb.server.types.TInstance; import com.foundationdb.sql.parser.CallStatementNode; import com.foundationdb.sql.parser.ParameterNode; import com.foundationdb.sql.parser.StaticMethodCallNode; import com.foundationdb.sql.server.ServerCallInvocation; import com.foundationdb.sql.types.DataTypeDescriptor; import java.util.Arrays; import java.util.List; abstract class ExecutableCallStatement extends ExecutableStatement { protected ServerCallInvocation invocation; protected JDBCParameterMetaData parameterMetaData; protected ExecutableCallStatement(ServerCallInvocation invocation, JDBCParameterMetaData parameterMetaData) { this.invocation = invocation; this.parameterMetaData = parameterMetaData; } public static ExecutableStatement executableStatement(CallStatementNode call, List<ParameterNode> sqlParams, EmbeddedQueryContext context) { StaticMethodCallNode methodCall = (StaticMethodCallNode)call.methodCall().getJavaValueNode(); ServerCallInvocation invocation = ServerCallInvocation.of(context.getServer(), methodCall); return executableStatement(invocation, call, sqlParams, context); } public static ExecutableStatement executableStatement(TableName routineName, EmbeddedQueryContext context) { ServerCallInvocation invocation = ServerCallInvocation.of(context.getServer(), routineName); return executableStatement(invocation, null, null, context); } protected static ExecutableStatement executableStatement(ServerCallInvocation invocation, CallStatementNode call, List<ParameterNode> sqlParams, EmbeddedQueryContext context) { int nparams = (sqlParams == null) ? invocation.size() : sqlParams.size(); JDBCParameterMetaData parameterMetaData = parameterMetaData(invocation, nparams, context); switch (invocation.getCallingConvention()) { case LOADABLE_PLAN: return ExecutableLoadableOperator.executableStatement(invocation, parameterMetaData, call, context); case JAVA: return ExecutableJavaMethod.executableStatement(invocation, parameterMetaData, context); case SCRIPT_FUNCTION_JAVA: case SCRIPT_FUNCTION_JSON: return ExecutableScriptFunctionJavaRoutine.executableStatement(invocation, parameterMetaData, context); case SCRIPT_BINDINGS: case SCRIPT_BINDINGS_JSON: return ExecutableScriptBindingsRoutine.executableStatement(invocation, parameterMetaData, context); default: throw new UnsupportedSQLException("Unknown routine", call); } } protected static JDBCParameterMetaData parameterMetaData(ServerCallInvocation invocation, int nparams, EmbeddedQueryContext context) { ParameterType[] ptypes = new ParameterType[nparams]; for (int i = 0; i < nparams; i++) { int usage = invocation.parameterUsage(i); if (usage < 0) continue; Parameter parameter = invocation.getRoutineParameter(usage); TInstance type = parameter.getType(); int jdbcType = type.typeClass().jdbcType(); DataTypeDescriptor sqlType = type.dataTypeDescriptor(); ptypes[i] = new ParameterType(parameter, sqlType, jdbcType, type); } return new JDBCParameterMetaData(context.getTypesTranslator(), Arrays.asList(ptypes)); } public ServerCallInvocation getInvocation() { return invocation; } @Override public JDBCParameterMetaData getParameterMetaData() { return parameterMetaData; } @Override public StatementTypes getStatementType() { return StatementTypes.CALL_STMT; } }