use of org.voltdb.ClientResponseImpl in project voltdb by VoltDB.
the class ExplainProc method run.
public CompletableFuture<ClientResponse> run(String procedureNames) {
// Go to the catalog and fetch all the "explain plan" strings of the queries in the procedure.
CatalogContext context = VoltDB.instance().getCatalogContext();
/*
* TODO: We don't actually support multiple proc names in an ExplainProc call,
* so I THINK that the string is always a single procname symbol and all this
* splitting and iterating is a no-op.
*/
List<String> procNames = SQLLexer.splitStatements(procedureNames);
int size = procNames.size();
VoltTable[] vt = new VoltTable[size];
for (int i = 0; i < size; i++) {
String procName = procNames.get(i);
// look in the catalog
Procedure proc = context.procedures.get(procName);
if (proc == null) {
// check default procs and send them off to be explained using the regular
// adhoc explain process
proc = context.m_defaultProcs.checkForDefaultProcedure(procName);
if (proc != null) {
String sql = DefaultProcedureManager.sqlForDefaultProc(proc);
List<String> sqlStatements = new ArrayList<>(1);
sqlStatements.add(sql);
return runNonDDLAdHoc(context, sqlStatements, true, null, ExplainMode.EXPLAIN_DEFAULT_PROC, false, new Object[0]);
}
return makeQuickResponse(ClientResponse.GRACEFUL_FAILURE, "Procedure " + procName + " not in catalog");
}
vt[i] = new VoltTable(new VoltTable.ColumnInfo("SQL_STATEMENT", VoltType.STRING), new VoltTable.ColumnInfo("EXECUTION_PLAN", VoltType.STRING));
for (Statement stmt : proc.getStatements()) {
vt[i].addRow(stmt.getSqltext(), Encoder.hexDecodeToString(stmt.getExplainplan()));
}
}
ClientResponseImpl response = new ClientResponseImpl(ClientResponseImpl.SUCCESS, ClientResponse.UNINITIALIZED_APP_STATUS_CODE, null, vt, null);
CompletableFuture<ClientResponse> fut = new CompletableFuture<>();
fut.complete(response);
return fut;
}
use of org.voltdb.ClientResponseImpl in project voltdb by VoltDB.
the class ExplainView method run.
public CompletableFuture<ClientResponse> run(String fullViewNames) {
CatalogContext context = VoltDB.instance().getCatalogContext();
/*
* TODO: We don't actually support multiple view names in an ExplainView call,
* so I THINK that the string is always a single view symbol and all this
* splitting and iterating is a no-op.
*/
List<String> viewNames = SQLLexer.splitStatements(fullViewNames);
int size = viewNames.size();
VoltTable[] vt = new VoltTable[size];
CatalogMap<Table> tables = context.database.getTables();
for (int i = 0; i < size; i++) {
String viewName = viewNames.get(i);
// look in the catalog
// get the view table from the catalog
Table viewTable = tables.getIgnoreCase(viewName);
if (viewTable == null) {
return makeQuickResponse(ClientResponse.GRACEFUL_FAILURE, "View " + viewName + " does not exist.");
}
vt[i] = new VoltTable(new VoltTable.ColumnInfo("TASK", VoltType.STRING), new VoltTable.ColumnInfo("EXECUTION_PLAN", VoltType.STRING));
try {
ArrayList<String[]> viewExplanation = ViewExplainer.explain(viewTable);
for (String[] row : viewExplanation) {
vt[i].addRow(row[0], row[1]);
}
} catch (Exception e) {
return makeQuickResponse(ClientResponse.GRACEFUL_FAILURE, e.getMessage());
}
}
ClientResponseImpl response = new ClientResponseImpl(ClientResponseImpl.SUCCESS, ClientResponse.UNINITIALIZED_APP_STATUS_CODE, null, vt, null);
CompletableFuture<ClientResponse> fut = new CompletableFuture<>();
fut.complete(response);
return fut;
}
use of org.voltdb.ClientResponseImpl in project voltdb by VoltDB.
the class SnapshotUtil method transformRestoreParamsToJSON.
/*
* Do parameter checking for the pre-JSON version of @SnapshotRestore old version
*/
public static ClientResponseImpl transformRestoreParamsToJSON(StoredProcedureInvocation task) {
Object[] params = task.getParams().toArray();
if (params.length == 1) {
try {
JSONObject jsObj = new JSONObject((String) params[0]);
String path = jsObj.optString(JSON_PATH);
String dupPath = jsObj.optString(JSON_DUPLICATES_PATH);
if (!path.isEmpty() && dupPath.isEmpty()) {
jsObj.put(JSON_DUPLICATES_PATH, path);
}
task.setParams(jsObj.toString());
} catch (JSONException e) {
Throwables.propagate(e);
}
return null;
} else if (params.length == 2) {
if (params[0] == null) {
return new ClientResponseImpl(ClientResponseImpl.GRACEFUL_FAILURE, new VoltTable[0], "@SnapshotRestore parameter 0 was null", task.getClientHandle());
}
if (params[1] == null) {
return new ClientResponseImpl(ClientResponseImpl.GRACEFUL_FAILURE, new VoltTable[0], "@SnapshotRestore parameter 1 was null", task.getClientHandle());
}
if (!(params[0] instanceof String)) {
return new ClientResponseImpl(ClientResponseImpl.GRACEFUL_FAILURE, new VoltTable[0], "@SnapshotRestore param 0 (path) needs to be a string, but was type " + params[0].getClass().getSimpleName(), task.getClientHandle());
}
if (!(params[1] instanceof String)) {
return new ClientResponseImpl(ClientResponseImpl.GRACEFUL_FAILURE, new VoltTable[0], "@SnapshotRestore param 1 (nonce) needs to be a string, but was type " + params[1].getClass().getSimpleName(), task.getClientHandle());
}
JSONObject jsObj = new JSONObject();
try {
jsObj.put(SnapshotUtil.JSON_PATH, params[0]);
if (VoltDB.instance().isRunningWithOldVerbs()) {
jsObj.put(SnapshotUtil.JSON_PATH_TYPE, SnapshotPathType.SNAP_PATH);
}
jsObj.put(SnapshotUtil.JSON_NONCE, params[1]);
jsObj.put(SnapshotUtil.JSON_DUPLICATES_PATH, params[0]);
} catch (JSONException e) {
Throwables.propagate(e);
}
task.setParams(jsObj.toString());
return null;
} else {
return new ClientResponseImpl(ClientResponseImpl.GRACEFUL_FAILURE, new VoltTable[0], "@SnapshotRestore supports a single json document parameter or two parameters (path, nonce), " + params.length + " parameters provided", task.getClientHandle());
}
}
use of org.voltdb.ClientResponseImpl in project voltdb by VoltDB.
the class ProcedureTask method processInitiateTask.
/** Mostly copy-paste of old ExecutionSite.processInitiateTask() */
protected InitiateResponseMessage processInitiateTask(Iv2InitiateTaskMessage task, SiteProcedureConnection siteConnection) {
final InitiateResponseMessage response = new InitiateResponseMessage(task);
try {
Object[] callerParams = null;
/*
* Parameters are lazily deserialized. We may not find out until now
* that the parameter set is corrupt
*/
try {
callerParams = task.getParameters();
} catch (RuntimeException e) {
Writer result = new StringWriter();
PrintWriter pw = new PrintWriter(result);
e.printStackTrace(pw);
response.setResults(new ClientResponseImpl(ClientResponse.GRACEFUL_FAILURE, new VoltTable[] {}, "Exception while deserializing procedure params, procedure=" + m_procName + "\n" + result.toString()));
}
if (callerParams == null) {
return response;
}
ClientResponseImpl cr = null;
ProcedureRunner runner = siteConnection.getProcedureRunner(m_procName);
if (runner == null) {
String error = "Procedure " + m_procName + " is not present in the catalog. " + "This can happen if a catalog update removing the procedure occurred " + "after the procedure was submitted " + "but before the procedure was executed.";
RateLimitedLogger.tryLogForMessage(System.currentTimeMillis(), 60, TimeUnit.SECONDS, hostLog, Level.WARN, error + " %s", "This log message is rate limited to once every 60 seconds.");
response.setResults(new ClientResponseImpl(ClientResponse.UNEXPECTED_FAILURE, new VoltTable[] {}, error));
return response;
}
// Check partitioning of single-partition and n-partition transactions.
if (runner.checkPartition(m_txnState, siteConnection.getCurrentHashinator())) {
runner.setupTransaction(m_txnState);
// execute the procedure
cr = runner.call(callerParams);
// pass in the first value in the hashes array if it's not null
Integer hash = null;
int[] hashes = cr.getHashes();
if (hashes != null && hashes.length > 0) {
hash = hashes[0];
}
m_txnState.setHash(hash);
//Don't pay the cost of returning the result tables for a replicated write
//With reads don't apply the optimization just in case
// if (!task.shouldReturnResultTables() && !task.isReadOnly()) {
// cr.dropResultTable();
// }
response.setResults(cr);
// have the real results
if ((!task.isReadOnly()) && task.isSinglePartition()) {
m_txnState.storeResults(cr);
}
} else {
// mis-partitioned invocation, reject it and let the ClientInterface restart it
response.setMispartitioned(true, task.getStoredProcedureInvocation(), TheHashinator.getCurrentVersionedConfig());
}
} catch (final ExpectedProcedureException e) {
execLog.l7dlog(Level.TRACE, LogKeys.org_voltdb_ExecutionSite_ExpectedProcedureException.name(), e);
response.setResults(new ClientResponseImpl(ClientResponse.GRACEFUL_FAILURE, new VoltTable[] {}, e.toString()));
} catch (final Exception e) {
// Should not be able to reach here. VoltProcedure.call caught all invocation target exceptions
// and converted them to error responses. Java errors are re-thrown, and not caught by this
// exception clause. A truly unexpected exception reached this point. Crash. It's a defect.
hostLog.l7dlog(Level.ERROR, LogKeys.host_ExecutionSite_UnexpectedProcedureException.name(), e);
VoltDB.crashLocalVoltDB(e.getMessage(), true, e);
}
return response;
}
use of org.voltdb.ClientResponseImpl in project voltdb by VoltDB.
the class AdHocNTBase method processExplainPlannedStmtBatch.
static CompletableFuture<ClientResponse> processExplainPlannedStmtBatch(AdHocPlannedStmtBatch planBatch) {
/**
* Take the response from the async ad hoc planning process and put the explain
* plan in a table with the right format.
*/
Database db = VoltDB.instance().getCatalogContext().database;
int size = planBatch.getPlannedStatementCount();
VoltTable[] vt = new VoltTable[size];
for (int i = 0; i < size; ++i) {
vt[i] = new VoltTable(new VoltTable.ColumnInfo("EXECUTION_PLAN", VoltType.STRING));
String str = planBatch.explainStatement(i, db);
vt[i].addRow(str);
}
ClientResponseImpl response = new ClientResponseImpl(ClientResponseImpl.SUCCESS, ClientResponse.UNINITIALIZED_APP_STATUS_CODE, null, vt, null);
CompletableFuture<ClientResponse> fut = new CompletableFuture<>();
fut.complete(response);
return fut;
}
Aggregations