use of org.voltdb.ParameterSet in project voltdb by VoltDB.
the class AdHocPlannedStmtBatch method flattenPlanArrayToBuffer.
/**
* For convenience, serialization is accomplished with this single method,
* but deserialization is piecemeal via the static methods userParamsFromBuffer
* and planArrayFromBuffer with no dummy "AdHocPlannedStmtBatch receiver" instance required.
*/
public ByteBuffer flattenPlanArrayToBuffer() throws IOException {
// sizeof batch
int size = 0;
ParameterSet userParamCache = null;
if (userParamSet == null) {
userParamCache = ParameterSet.emptyParameterSet();
} else {
Object[] typedUserParams = new Object[userParamSet.length];
int ii = 0;
for (AdHocPlannedStatement cs : plannedStatements) {
for (VoltType paramType : cs.core.parameterTypes) {
if (ii >= typedUserParams.length) {
String errorMsg = "Too few actual arguments were passed for the parameters in the sql statement(s): (" + typedUserParams.length + " vs. " + ii + ")";
// Volt-TYPE-Exception is slightly cheating, here, should there be a more general VoltArgumentException?
throw new VoltTypeException(errorMsg);
}
typedUserParams[ii] = ParameterConverter.tryToMakeCompatible(paramType.classFromType(), userParamSet[ii]);
// System.out.println("DEBUG typed parameter: " + work.userParamSet[ii] +
// "using type: " + paramType + "as: " + typedUserParams[ii]);
ii++;
}
}
// exactly once in userParams.
if (ii < typedUserParams.length) {
// Volt-TYPE-Exception is slightly cheating, here, should there be a more general VoltArgumentException?
String errorMsg = "Too many actual arguments were passed for the parameters in the sql statement(s): (" + typedUserParams.length + " vs. " + ii + ")";
throw new VoltTypeException(errorMsg);
}
userParamCache = ParameterSet.fromArrayNoCopy(typedUserParams);
}
size += userParamCache.getSerializedSize();
// sizeof batch
size += 2;
for (AdHocPlannedStatement cs : plannedStatements) {
size += cs.getSerializedSize();
}
ByteBuffer buf = ByteBuffer.allocate(size);
userParamCache.flattenToBuffer(buf);
buf.putShort((short) plannedStatements.size());
for (AdHocPlannedStatement cs : plannedStatements) {
cs.flattenToBuffer(buf);
}
return buf;
}
use of org.voltdb.ParameterSet in project voltdb by VoltDB.
the class SysprocFragmentTask method processFragmentTask.
// Extracted the sysproc portion of ExecutionSite processFragmentTask(), then
// modified to work in the new world
public FragmentResponseMessage processFragmentTask(SiteProcedureConnection siteConnection) {
final FragmentResponseMessage currentFragResponse = new FragmentResponseMessage(m_fragmentMsg, m_initiator.getHSId());
currentFragResponse.setStatus(FragmentResponseMessage.SUCCESS, null);
for (int frag = 0; frag < m_fragmentMsg.getFragmentCount(); frag++) {
final long fragmentId = VoltSystemProcedure.hashToFragId(m_fragmentMsg.getPlanHash(frag));
// equivalent to dep.depId:
// final int outputDepId = m_fragmentMsg.getOutputDepId(frag);
final VoltTrace.TraceEventBatch traceLog = VoltTrace.log(VoltTrace.Category.SPSITE);
if (traceLog != null) {
traceLog.add(() -> VoltTrace.beginDuration("runfragmenttask", "txnId", TxnEgo.txnIdToString(getTxnId()), "partition", Integer.toString(siteConnection.getCorrespondingPartitionId()), "fragmentId", String.valueOf(fragmentId)));
}
ParameterSet params = m_fragmentMsg.getParameterSetForFragment(frag);
try {
// run the overloaded sysproc planfragment. pass an empty dependency
// set since remote (non-aggregator) fragments don't receive dependencies.
final DependencyPair dep = siteConnection.executeSysProcPlanFragment(m_txnState, m_inputDeps, fragmentId, params);
// @Shutdown returns null, handle it here
if (dep != null) {
currentFragResponse.addDependency(dep);
}
} catch (final EEException e) {
hostLog.l7dlog(Level.TRACE, LogKeys.host_ExecutionSite_ExceptionExecutingPF.name(), new Object[] { Encoder.hexEncode(m_fragmentMsg.getFragmentPlan(frag)) }, e);
currentFragResponse.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, e);
if (currentFragResponse.getTableCount() == 0) {
// Make sure the response has at least 1 result with a valid DependencyId
currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(m_fragmentMsg.getOutputDepId(0), m_rawDummyResult, 0, m_rawDummyResult.length));
}
break;
} catch (final SQLException e) {
hostLog.l7dlog(Level.TRACE, LogKeys.host_ExecutionSite_ExceptionExecutingPF.name(), new Object[] { Encoder.hexEncode(m_fragmentMsg.getFragmentPlan(frag)) }, e);
currentFragResponse.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, e);
if (currentFragResponse.getTableCount() == 0) {
// Make sure the response has at least 1 result with a valid DependencyId
currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(m_fragmentMsg.getOutputDepId(0), m_rawDummyResult, 0, m_rawDummyResult.length));
}
break;
} catch (final SpecifiedException e) {
// Note that with SpecifiedException, the error code here might get changed before
// the client/user sees it. It really just needs to indicate failure.
//
// Key point here vs the next catch block for VAE is to not wrap the subclass of
// SerializableException here to preserve it during the serialization.
//
currentFragResponse.setStatus(FragmentResponseMessage.USER_ERROR, e);
if (currentFragResponse.getTableCount() == 0) {
// Make sure the response has at least 1 result with a valid DependencyId
currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(m_fragmentMsg.getOutputDepId(0), m_rawDummyResult, 0, m_rawDummyResult.length));
}
} catch (final VoltAbortException e) {
currentFragResponse.setStatus(FragmentResponseMessage.USER_ERROR, new SerializableException(CoreUtils.throwableToString(e)));
if (currentFragResponse.getTableCount() == 0) {
// Make sure the response has at least 1 result with a valid DependencyId
currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(m_fragmentMsg.getOutputDepId(0), m_rawDummyResult, 0, m_rawDummyResult.length));
}
break;
}
if (traceLog != null) {
traceLog.add(VoltTrace::endDuration);
}
}
return currentFragResponse;
}
use of org.voltdb.ParameterSet in project voltdb by VoltDB.
the class AdHocBase method adHocSQLFromInvocationForDebug.
/**
* Get a string containing the SQL statements and any parameters for a given
* batch passed to an ad-hoc query. Used for debugging and logging.
*/
public static String adHocSQLFromInvocationForDebug(StoredProcedureInvocation invocation) {
assert (invocation.getProcName().startsWith("@AdHoc"));
ParameterSet params = invocation.getParams();
assert (params.size() == 2 || params.size() == 3);
// the final param is the byte array we need
byte[] serializedBatchData = (byte[]) params.getParam(params.size() - 1);
Pair<Object[], AdHocPlannedStatement[]> data = decodeSerializedBatchData(serializedBatchData);
Object[] userparams = data.getFirst();
AdHocPlannedStatement[] statements = data.getSecond();
StringBuilder sb = new StringBuilder();
if (statements.length == 0) {
sb.append("ADHOC INVOCATION HAS NO SQL");
} else if (statements.length == 1) {
sb.append(adHocSQLStringFromPlannedStatement(statements[0], userparams));
} else {
// > 1
sb.append("BEGIN ADHOC_SQL_BATCH {\n");
for (AdHocPlannedStatement stmt : statements) {
sb.append(adHocSQLStringFromPlannedStatement(stmt, userparams)).append("\n");
}
sb.append("} END ADHOC_SQL_BATCH");
}
return sb.toString();
}
use of org.voltdb.ParameterSet in project voltdb by VoltDB.
the class TestSpSchedulerDedupe method createMsg.
private Iv2InitiateTaskMessage createMsg(long txnId, boolean readOnly, boolean singlePart, long destHSId) {
// Mock an invocation for MockSPName.
StoredProcedureInvocation spi = mock(StoredProcedureInvocation.class);
when(spi.getProcName()).thenReturn(MockSPName);
ParameterSet bleh = mock(ParameterSet.class);
when(spi.getParams()).thenReturn(bleh);
Iv2InitiateTaskMessage task = new // initHSID
Iv2InitiateTaskMessage(// initHSID
destHSId, // coordHSID
Long.MIN_VALUE, // truncationHandle
txnId - 1, // txnId
txnId, // uniqueID
UniqueIdGenerator.makeIdFromComponents(System.currentTimeMillis(), 0, 0), // readonly
readOnly, // single-part
singlePart, // invocation
spi, // client interface handle
Long.MAX_VALUE, // connectionId
Long.MAX_VALUE, // isForReplay
false);
// sp: sphandle == txnid
task.setTxnId(txnId);
task.setSpHandle(txnId);
return task;
}
use of org.voltdb.ParameterSet in project voltdb by VoltDB.
the class PlannerTool method planSql.
public synchronized AdHocPlannedStatement planSql(String sqlIn, StatementPartitioning partitioning, boolean isExplainMode, final Object[] userParams, boolean isSwapTables) {
CacheUse cacheUse = CacheUse.FAIL;
if (m_plannerStats != null) {
m_plannerStats.startStatsCollection();
}
boolean hasUserQuestionMark = false;
boolean wrongNumberParameters = false;
try {
if ((sqlIn == null) || (sqlIn.length() == 0)) {
throw new RuntimeException("Can't plan empty or null SQL.");
}
// remove any spaces or newlines
String sql = sqlIn.trim();
// if the cases tended to have mostly overlapping queries.
if (partitioning.isInferred()) {
// Check the literal cache for a match.
AdHocPlannedStatement cachedPlan = m_cache.getWithSQL(sqlIn);
if (cachedPlan != null) {
cacheUse = CacheUse.HIT1;
return cachedPlan;
} else {
cacheUse = CacheUse.MISS;
}
}
// Reset plan node id counter
AbstractPlanNode.resetPlanNodeIds();
//////////////////////
// PLAN THE STMT
//////////////////////
TrivialCostModel costModel = new TrivialCostModel();
DatabaseEstimates estimates = new DatabaseEstimates();
QueryPlanner planner = new QueryPlanner(sql, "PlannerTool", "PlannerToolProc", m_database, partitioning, m_hsql, estimates, !VoltCompiler.DEBUG_MODE, AD_HOC_JOINED_TABLE_LIMIT, costModel, null, null, DeterminismMode.FASTER);
CompiledPlan plan = null;
String[] extractedLiterals = null;
String parsedToken = null;
try {
if (isSwapTables) {
planner.planSwapTables();
} else {
planner.parse();
}
parsedToken = planner.parameterize();
// check the parameters count
// check user input question marks with input parameters
int inputParamsLengh = userParams == null ? 0 : userParams.length;
if (planner.getAdhocUserParamsCount() != inputParamsLengh) {
wrongNumberParameters = true;
if (!isExplainMode) {
throw new PlanningErrorException(String.format("Incorrect number of parameters passed: expected %d, passed %d", planner.getAdhocUserParamsCount(), inputParamsLengh));
}
}
hasUserQuestionMark = planner.getAdhocUserParamsCount() > 0;
// do not put wrong parameter explain query into cache
if (!wrongNumberParameters && partitioning.isInferred()) {
// QueryPlanner.
assert (parsedToken != null);
extractedLiterals = planner.extractedParamLiteralValues();
List<BoundPlan> boundVariants = m_cache.getWithParsedToken(parsedToken);
if (boundVariants != null) {
assert (!boundVariants.isEmpty());
BoundPlan matched = null;
for (BoundPlan boundPlan : boundVariants) {
if (boundPlan.allowsParams(extractedLiterals)) {
matched = boundPlan;
break;
}
}
if (matched != null) {
CorePlan core = matched.m_core;
ParameterSet params = null;
if (planner.compiledAsParameterizedPlan()) {
params = planner.extractedParamValues(core.parameterTypes);
} else if (hasUserQuestionMark) {
params = ParameterSet.fromArrayNoCopy(userParams);
} else {
// No constants AdHoc queries
params = ParameterSet.emptyParameterSet();
}
AdHocPlannedStatement ahps = new AdHocPlannedStatement(sql.getBytes(Constants.UTF8ENCODING), core, params, null);
ahps.setBoundConstants(matched.m_constants);
// parameterized plan from the cache does not have exception
m_cache.put(sql, parsedToken, ahps, extractedLiterals, hasUserQuestionMark, false);
cacheUse = CacheUse.HIT2;
return ahps;
}
}
}
// If not caching or there was no cache hit, do the expensive full planning.
plan = planner.plan();
assert (plan != null);
if (plan != null && plan.getStatementPartitioning() != null) {
partitioning = plan.getStatementPartitioning();
}
} catch (Exception e) {
/*
* Don't log PlanningErrorExceptions or HSQLParseExceptions, as
* they are at least somewhat expected.
*/
String loggedMsg = "";
if (!((e instanceof PlanningErrorException) || (e instanceof HSQLParseException))) {
logException(e, "Error compiling query");
loggedMsg = " (Stack trace has been written to the log.)";
}
throw new RuntimeException("Error compiling query: " + e.toString() + loggedMsg, e);
}
if (plan == null) {
throw new RuntimeException("Null plan received in PlannerTool.planSql");
}
//////////////////////
// OUTPUT THE RESULT
//////////////////////
CorePlan core = new CorePlan(plan, m_catalogHash);
AdHocPlannedStatement ahps = new AdHocPlannedStatement(plan, core);
// do not put wrong parameter explain query into cache
if (!wrongNumberParameters && partitioning.isInferred()) {
// Note either the parameter index (per force to a user-provided parameter) or
// the actual constant value of the partitioning key inferred from the plan.
// Either or both of these two values may simply default
// to -1 and to null, respectively.
core.setPartitioningParamIndex(partitioning.getInferredParameterIndex());
core.setPartitioningParamValue(partitioning.getInferredPartitioningValue());
assert (parsedToken != null);
// Again, plans with inferred partitioning are the only ones supported in the cache.
m_cache.put(sqlIn, parsedToken, ahps, extractedLiterals, hasUserQuestionMark, planner.wasBadPameterized());
}
return ahps;
} finally {
if (m_plannerStats != null) {
m_plannerStats.endStatsCollection(m_cache.getLiteralCacheSize(), m_cache.getCoreCacheSize(), cacheUse, -1);
}
}
}
Aggregations