use of org.voltdb.catalog.StmtParameter in project voltdb by VoltDB.
the class ReportMaker method genrateStatementRow.
static String genrateStatementRow(CatalogMap<Table> tables, Procedure procedure, Statement statement) {
// get the proc annotation which should exist or be created just before this is called
ProcedureAnnotation procAnnotation = (ProcedureAnnotation) procedure.getAnnotation();
assert (procAnnotation != null);
StringBuilder sb = new StringBuilder();
sb.append(" <tr class='primaryrow2'>");
// name column
String anchor = (procedure.getTypeName() + "-" + statement.getTypeName()).toLowerCase();
sb.append("<td style='white-space: nowrap'><i id='p-" + anchor + "--icon' class='icon-chevron-right'></i> <a href='#' id='p-");
sb.append(anchor).append("' class='togglex'>");
sb.append(statement.getTypeName());
sb.append("</a></td>");
// sql column
sb.append("<td><tt>");
sb.append(escapeHtml4(statement.getSqltext()));
sb.append("</td></tt>");
// params column
sb.append("<td>");
List<StmtParameter> params = CatalogUtil.getSortedCatalogItems(statement.getParameters(), "index");
List<String> paramTypes = new ArrayList<String>();
for (StmtParameter param : params) {
paramTypes.add(VoltType.get((byte) param.getJavatype()).name());
}
if (paramTypes.size() == 0) {
sb.append("<i>None</i>");
}
sb.append(StringUtils.join(paramTypes, ", "));
sb.append("</td>");
// r/w column
sb.append("<td>");
if (statement.getReadonly()) {
tag(sb, "success", "Read");
} else {
tag(sb, "warning", "Write");
}
sb.append("</td>");
// attributes
sb.append("<td>");
if (!statement.getIscontentdeterministic() || !statement.getIsorderdeterministic()) {
tag(sb, "inverse", "Determinism");
}
if (statement.getSeqscancount() > 0) {
tag(sb, "important", "Scans");
}
sb.append("</td>");
sb.append("</tr>\n");
// BUILD THE DROPDOWN FOR THE PLAN/DETAIL TABLE
sb.append("<tr class='dropdown2'><td colspan='5' id='p-" + procedure.getTypeName().toLowerCase() + "-" + statement.getTypeName().toLowerCase() + "--dropdown'>\n");
sb.append("<div class='well well-small'><h4>Explain Plan:</h4>\n");
String plan = escapeHtml4(Encoder.hexDecodeToString(statement.getExplainplan()));
plan = plan.replace("\n", "<br/>");
plan = plan.replace(" ", " ");
for (String tableName : statement.getTablesread().split(",")) {
if (tableName.length() == 0) {
continue;
}
Table t = tables.get(tableName);
assert (t != null);
TableAnnotation ta = (TableAnnotation) t.getAnnotation();
assert (ta != null);
ta.statementsThatReadThis.add(statement);
ta.proceduresThatReadThis.add(procedure);
procAnnotation.tablesRead.add(t);
String uname = tableName.toUpperCase();
String link = "\"<a href='#s-" + tableName + "'>" + uname + "</a>\"";
plan = plan.replace(""" + uname + """, link);
}
for (String tableName : statement.getTablesupdated().split(",")) {
if (tableName.length() == 0) {
continue;
}
Table t = tables.get(tableName);
assert (t != null);
TableAnnotation ta = (TableAnnotation) t.getAnnotation();
assert (ta != null);
ta.statementsThatUpdateThis.add(statement);
ta.proceduresThatUpdateThis.add(procedure);
procAnnotation.tablesUpdated.add(t);
String uname = tableName.toUpperCase();
String link = "\"<a href='#s-" + tableName + "'>" + uname + "</a>\"";
plan = plan.replace(""" + uname + """, link);
}
for (String tableDotIndexPair : statement.getIndexesused().split(",")) {
if (tableDotIndexPair.length() == 0) {
continue;
}
String[] parts = tableDotIndexPair.split("\\.", 2);
assert (parts.length == 2);
if (parts.length != 2) {
continue;
}
String tableName = parts[0];
String indexName = parts[1];
Table t = tables.get(tableName);
assert (t != null);
Index i = t.getIndexes().get(indexName);
assert (i != null);
IndexAnnotation ia = (IndexAnnotation) i.getAnnotation();
if (ia == null) {
ia = new IndexAnnotation();
i.setAnnotation(ia);
}
ia.proceduresThatUseThis.add(procedure);
procAnnotation.indexesUsed.add(i);
String uindexName = indexName.toUpperCase();
String link = "\"<a href='#s-" + tableName + "-" + indexName + "'>" + uindexName + "</a>\"";
plan = plan.replace(""" + uindexName + """, link);
}
sb.append("<tt>").append(plan).append("</tt>");
sb.append("</div>\n");
sb.append("</td></tr>\n");
return sb.toString();
}
use of org.voltdb.catalog.StmtParameter in project voltdb by VoltDB.
the class ProcedureCompiler method compileSingleStmtProcedure.
static void compileSingleStmtProcedure(VoltCompiler compiler, HSQLInterface hsql, DatabaseEstimates estimates, Database db, ProcedureDescriptor procedureDescriptor) throws VoltCompiler.VoltCompilerException {
final String className = procedureDescriptor.m_className;
if (className.indexOf('@') != -1) {
throw compiler.new VoltCompilerException("User procedure names can't contain \"@\".");
}
// get the short name of the class (no package if a user procedure)
// use the Table.<builtin> name (allowing the period) if builtin.
String shortName = className;
if (procedureDescriptor.m_builtInStmt == false) {
String[] parts = className.split("\\.");
shortName = parts[parts.length - 1];
}
// add an entry to the catalog (using the full className)
final Procedure procedure = db.getProcedures().add(shortName);
for (String groupName : procedureDescriptor.m_authGroups) {
final Group group = db.getGroups().get(groupName);
if (group == null) {
throw compiler.new VoltCompilerException("Procedure " + className + " allows access by a role " + groupName + " that does not exist");
}
final GroupRef groupRef = procedure.getAuthgroups().add(groupName);
groupRef.setGroup(group);
}
procedure.setClassname(className);
// sysprocs don't use the procedure compiler
procedure.setSystemproc(false);
procedure.setDefaultproc(procedureDescriptor.m_builtInStmt);
procedure.setHasjava(false);
procedure.setTransactional(true);
// get the annotation
// first try to get one that has been passed from the compiler
ProcInfoData info = compiler.getProcInfoOverride(shortName);
// and create a ProcInfo.Data instance for it
if (info == null) {
info = new ProcInfoData();
if (procedureDescriptor.m_partitionString != null) {
info.partitionInfo = procedureDescriptor.m_partitionString;
info.singlePartition = true;
}
}
assert (info != null);
// ADD THE STATEMENT
// add the statement to the catalog
Statement catalogStmt = procedure.getStatements().add(VoltDB.ANON_STMT_NAME);
// compile the statement
StatementPartitioning partitioning = info.singlePartition ? StatementPartitioning.forceSP() : StatementPartitioning.forceMP();
// default to FASTER detmode because stmt procs can't feed read output into writes
StatementCompiler.compileFromSqlTextAndUpdateCatalog(compiler, hsql, db, estimates, catalogStmt, procedureDescriptor.m_singleStmt, procedureDescriptor.m_joinOrder, DeterminismMode.FASTER, partitioning);
// if the single stmt is not read only, then the proc is not read only
boolean procHasWriteStmts = (catalogStmt.getReadonly() == false);
// set the read onlyness of a proc
procedure.setReadonly(procHasWriteStmts == false);
int seqs = catalogStmt.getSeqscancount();
procedure.setHasseqscans(seqs > 0);
// set procedure parameter types
CatalogMap<ProcParameter> params = procedure.getParameters();
CatalogMap<StmtParameter> stmtParams = catalogStmt.getParameters();
// set the procedure parameter types from the statement parameter types
int paramCount = 0;
for (StmtParameter stmtParam : CatalogUtil.getSortedCatalogItems(stmtParams, "index")) {
// name each parameter "param1", "param2", etc...
ProcParameter procParam = params.add("param" + String.valueOf(paramCount));
procParam.setIndex(stmtParam.getIndex());
procParam.setIsarray(stmtParam.getIsarray());
procParam.setType(stmtParam.getJavatype());
paramCount++;
}
// parse the procinfo
procedure.setSinglepartition(info.singlePartition);
if (info.singlePartition) {
parsePartitionInfo(compiler, db, procedure, info.partitionInfo);
if (procedure.getPartitionparameter() >= params.size()) {
String msg = "PartitionInfo parameter not a valid parameter for procedure: " + procedure.getClassname();
throw compiler.new VoltCompilerException(msg);
}
// TODO: The planner does not currently validate that a single-statement plan declared as single-partition correctly uses
// the designated parameter as a partitioning filter, maybe some day.
// In theory, the PartitioningForStatement would confirm the use of (only) a parameter as a partition key --
// or if the partition key was determined to be some other hard-coded constant (expression?) it might display a warning
// message that the passed parameter is assumed to be equal to that constant (expression).
} else {
if (partitioning.getCountOfIndependentlyPartitionedTables() == 1) {
AbstractExpression statementPartitionExpression = partitioning.singlePartitioningExpressionForReport();
if (statementPartitionExpression != null) {
// The planner has uncovered an overlooked opportunity to run the statement SP.
String msg = "This procedure " + shortName + " would benefit from being partitioned, by ";
String tableName = "tableName", partitionColumnName = "partitionColumnName";
try {
assert (partitioning.getFullColumnName() != null);
String[] array = partitioning.getFullColumnName().split("\\.");
tableName = array[0];
partitionColumnName = array[1];
} catch (Exception ex) {
}
if (statementPartitionExpression instanceof ParameterValueExpression) {
paramCount = ((ParameterValueExpression) statementPartitionExpression).getParameterIndex();
} else {
String valueDescription = null;
Object partitionValue = partitioning.getInferredPartitioningValue();
if (partitionValue == null) {
// Statement partitioned on a runtime constant. This is likely to be cryptic, but hopefully gets the idea across.
valueDescription = "of " + statementPartitionExpression.explain("");
} else {
// A simple constant value COULD have been a parameter.
valueDescription = partitionValue.toString();
}
msg += "adding a parameter to be passed the value " + valueDescription + " and ";
}
msg += "adding a 'PARTITION ON TABLE " + tableName + " COLUMN " + partitionColumnName + " PARAMETER " + paramCount + "' clause to the " + "CREATE PROCEDURE statement. or using a separate PARTITION PROCEDURE statement";
compiler.addWarn(msg);
}
}
}
}
use of org.voltdb.catalog.StmtParameter in project voltdb by VoltDB.
the class PlannerTestAideDeCamp method compile.
/**
* Compile and cache the statement and plan and return the final plan graph.
*/
private List<AbstractPlanNode> compile(String sql, int paramCount, String joinOrder, boolean inferPartitioning, boolean forceSingle, DeterminismMode detMode) {
String stmtLabel = "stmt-" + String.valueOf(compileCounter++);
Statement catalogStmt = proc.getStatements().add(stmtLabel);
catalogStmt.setSqltext(sql);
catalogStmt.setSinglepartition(forceSingle);
// determine the type of the query
QueryType qtype = QueryType.SELECT;
catalogStmt.setReadonly(true);
if (sql.toLowerCase().startsWith("insert")) {
qtype = QueryType.INSERT;
catalogStmt.setReadonly(false);
}
if (sql.toLowerCase().startsWith("update")) {
qtype = QueryType.UPDATE;
catalogStmt.setReadonly(false);
}
if (sql.toLowerCase().startsWith("delete")) {
qtype = QueryType.DELETE;
catalogStmt.setReadonly(false);
}
catalogStmt.setQuerytype(qtype.getValue());
// name will look like "basename-stmt-#"
String name = catalogStmt.getParent().getTypeName() + "-" + catalogStmt.getTypeName();
DatabaseEstimates estimates = new DatabaseEstimates();
TrivialCostModel costModel = new TrivialCostModel();
StatementPartitioning partitioning;
if (inferPartitioning) {
partitioning = StatementPartitioning.inferPartitioning();
} else if (forceSingle) {
partitioning = StatementPartitioning.forceSP();
} else {
partitioning = StatementPartitioning.forceMP();
}
String procName = catalogStmt.getParent().getTypeName();
QueryPlanner planner = new QueryPlanner(sql, stmtLabel, procName, db, partitioning, hsql, estimates, false, StatementCompiler.DEFAULT_MAX_JOIN_TABLES, costModel, null, joinOrder, detMode);
CompiledPlan plan = null;
planner.parse();
plan = planner.plan();
assert (plan != null);
// Partitioning optionally inferred from the planning process.
if (partitioning.isInferred()) {
catalogStmt.setSinglepartition(partitioning.isInferredSingle());
}
// We will need to update the system catalogs with this new information
for (int i = 0; i < plan.parameters.length; ++i) {
StmtParameter catalogParam = catalogStmt.getParameters().add(String.valueOf(i));
ParameterValueExpression pve = plan.parameters[i];
catalogParam.setJavatype(pve.getValueType().getValue());
catalogParam.setIsarray(pve.getParamIsVector());
catalogParam.setIndex(i);
}
List<PlanNodeList> nodeLists = new ArrayList<>();
nodeLists.add(new PlanNodeList(plan.rootPlanGraph));
if (plan.subPlanGraph != null) {
nodeLists.add(new PlanNodeList(plan.subPlanGraph));
}
// Now update our catalog information
// HACK: We're using the node_tree's hashCode() as it's name. It would be really
// nice if the Catalog code give us an guid without needing a name first...
String json = null;
try {
JSONObject jobj = new JSONObject(nodeLists.get(0).toJSONString());
json = jobj.toString(4);
} catch (JSONException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
System.exit(-1);
return null;
}
//
try {
BuildDirectoryUtils.writeFile("statement-plans", name + "_json.txt", json, true);
BuildDirectoryUtils.writeFile("statement-plans", name + ".dot", nodeLists.get(0).toDOTString("name"), true);
} catch (Exception e) {
e.printStackTrace();
}
List<AbstractPlanNode> plannodes = new ArrayList<>();
for (PlanNodeList nodeList : nodeLists) {
plannodes.add(nodeList.getRootPlanNode());
}
m_currentPlan = plan;
return plannodes;
}
use of org.voltdb.catalog.StmtParameter in project voltdb by VoltDB.
the class ProcedureRunner method initSQLStmt.
public void initSQLStmt(SQLStmt stmt, Statement catStmt) {
int fragCount = catStmt.getFragments().size();
for (PlanFragment frag : catStmt.getFragments()) {
byte[] planHash = Encoder.hexDecode(frag.getPlanhash());
byte[] plan = Encoder.decodeBase64AndDecompressToBytes(frag.getPlannodetree());
long id = ActivePlanRepository.loadOrAddRefPlanFragment(planHash, plan, catStmt.getSqltext());
boolean transactional = frag.getNontransactional() == false;
SQLStmt.Frag stmtFrag = new SQLStmt.Frag(id, planHash, transactional);
if (fragCount == 1 || frag.getHasdependencies()) {
stmt.aggregator = stmtFrag;
} else {
stmt.collector = stmtFrag;
}
}
stmt.isReadOnly = catStmt.getReadonly();
stmt.isReplicatedTableDML = catStmt.getReplicatedtabledml();
stmt.site = m_site;
int numStatementParamTypes = catStmt.getParameters().size();
stmt.statementParamTypes = new byte[numStatementParamTypes];
for (StmtParameter param : catStmt.getParameters()) {
int index = param.getIndex();
// Array-typed params currently only arise from in-lists.
// Tweak the parameter's expected type accordingly.
VoltType expectType = VoltType.get((byte) param.getJavatype());
if (param.getIsarray()) {
if (expectType == VoltType.STRING) {
expectType = VoltType.INLIST_OF_STRING;
} else {
expectType = VoltType.INLIST_OF_BIGINT;
}
}
stmt.statementParamTypes[index] = expectType.getValue();
}
}
use of org.voltdb.catalog.StmtParameter in project voltdb by VoltDB.
the class StatementCompiler method compileStatementAndUpdateCatalog.
/**
* This static method conveniently does a few things for its caller:
* - Formats the statement by replacing newlines with spaces
* and appends a semicolon if needed
* - Updates the catalog Statement with metadata about the statement
* - Plans the statement and puts the serialized plan in the catalog Statement
* - Updates the catalog Statment with info about the statement's parameters
* Upon successful completion, catalog statement will have been updated with
* plan fragments needed to execute the statement.
*
* @param compiler The VoltCompiler instance
* @param hsql Pass through parameter to QueryPlanner
* @param catalog Pass through parameter to QueryPlanner
* @param db Pass through parameter to QueryPlanner
* @param estimates Pass through parameter to QueryPlanner
* @param catalogStmt Catalog statement to be updated with plan
* @param xml XML for statement, if it has been previously parsed
* (may be null)
* @param stmt Text of statement to be compiled
* @param joinOrder Pass through parameter to QueryPlanner
* @param detMode Pass through parameter to QueryPlanner
* @param partitioning Partition info for statement
*/
static boolean compileStatementAndUpdateCatalog(VoltCompiler compiler, HSQLInterface hsql, Database db, DatabaseEstimates estimates, Statement catalogStmt, VoltXMLElement xml, String stmt, String joinOrder, DeterminismMode detMode, StatementPartitioning partitioning) throws VoltCompiler.VoltCompilerException {
// Cleanup whitespace newlines for catalog compatibility
// and to make statement parsing easier.
stmt = stmt.replaceAll("\n", " ");
stmt = stmt.trim();
compiler.addInfo("Compiling Statement: " + stmt);
// put the data in the catalog that we have
if (!stmt.endsWith(";")) {
stmt += ";";
}
// if this key + sql is the same, then a cached stmt can be used
String keyPrefix = compiler.getKeyPrefix(partitioning, detMode, joinOrder);
// if the key is cache-able, look for a previous statement
if (keyPrefix != null) {
Statement previousStatement = compiler.getCachedStatement(keyPrefix, stmt);
// check if the stmt exists and if it's the same sql text
if (previousStatement != null) {
catalogStmt.setAnnotation(previousStatement.getAnnotation());
catalogStmt.setAttachment(previousStatement.getAttachment());
catalogStmt.setCachekeyprefix(previousStatement.getCachekeyprefix());
catalogStmt.setCost(previousStatement.getCost());
catalogStmt.setExplainplan(previousStatement.getExplainplan());
catalogStmt.setIscontentdeterministic(previousStatement.getIscontentdeterministic());
catalogStmt.setIsorderdeterministic(previousStatement.getIsorderdeterministic());
catalogStmt.setNondeterminismdetail(previousStatement.getNondeterminismdetail());
catalogStmt.setQuerytype(previousStatement.getQuerytype());
catalogStmt.setReadonly(previousStatement.getReadonly());
catalogStmt.setReplicatedtabledml(previousStatement.getReplicatedtabledml());
catalogStmt.setSeqscancount(previousStatement.getSeqscancount());
catalogStmt.setSinglepartition(previousStatement.getSinglepartition());
catalogStmt.setSqltext(previousStatement.getSqltext());
catalogStmt.setTablesread(previousStatement.getTablesread());
catalogStmt.setTablesupdated(previousStatement.getTablesupdated());
catalogStmt.setIndexesused(previousStatement.getIndexesused());
for (StmtParameter oldSp : previousStatement.getParameters()) {
StmtParameter newSp = catalogStmt.getParameters().add(oldSp.getTypeName());
newSp.setAnnotation(oldSp.getAnnotation());
newSp.setAttachment(oldSp.getAttachment());
newSp.setIndex(oldSp.getIndex());
newSp.setIsarray(oldSp.getIsarray());
newSp.setJavatype(oldSp.getJavatype());
newSp.setSqltype(oldSp.getSqltype());
}
for (PlanFragment oldFrag : previousStatement.getFragments()) {
PlanFragment newFrag = catalogStmt.getFragments().add(oldFrag.getTypeName());
newFrag.setAnnotation(oldFrag.getAnnotation());
newFrag.setAttachment(oldFrag.getAttachment());
newFrag.setHasdependencies(oldFrag.getHasdependencies());
newFrag.setMultipartition(oldFrag.getMultipartition());
newFrag.setNontransactional(oldFrag.getNontransactional());
newFrag.setPlanhash(oldFrag.getPlanhash());
newFrag.setPlannodetree(oldFrag.getPlannodetree());
}
return true;
}
}
// determine the type of the query
QueryType qtype = QueryType.getFromSQL(stmt);
catalogStmt.setReadonly(qtype.isReadOnly());
catalogStmt.setQuerytype(qtype.getValue());
// might be null if not cacheable
catalogStmt.setCachekeyprefix(keyPrefix);
catalogStmt.setSqltext(stmt);
catalogStmt.setSinglepartition(partitioning.wasSpecifiedAsSingle());
String name = catalogStmt.getParent().getTypeName() + "-" + catalogStmt.getTypeName();
String sql = catalogStmt.getSqltext();
String stmtName = catalogStmt.getTypeName();
String procName = catalogStmt.getParent().getTypeName();
TrivialCostModel costModel = new TrivialCostModel();
CompiledPlan plan = null;
QueryPlanner planner = new QueryPlanner(sql, stmtName, procName, db, partitioning, hsql, estimates, false, DEFAULT_MAX_JOIN_TABLES, costModel, null, joinOrder, detMode);
try {
try {
if (xml != null) {
planner.parseFromXml(xml);
} else {
planner.parse();
}
plan = planner.plan();
assert (plan != null);
} catch (PlanningErrorException e) {
// These are normal expectable errors -- don't normally need a stack-trace.
String msg = "Failed to plan for statement (" + catalogStmt.getTypeName() + ") \"" + catalogStmt.getSqltext() + "\".";
if (e.getMessage() != null) {
msg += " Error: \"" + e.getMessage() + "\"";
}
throw compiler.new VoltCompilerException(msg);
} catch (Exception e) {
e.printStackTrace();
throw compiler.new VoltCompilerException("Failed to plan for stmt: " + catalogStmt.getTypeName());
}
// There is a hard-coded limit to the number of parameters that can be passed to the EE.
if (plan.parameters.length > CompiledPlan.MAX_PARAM_COUNT) {
throw compiler.new VoltCompilerException("The statement's parameter count " + plan.parameters.length + " must not exceed the maximum " + CompiledPlan.MAX_PARAM_COUNT);
}
// Check order and content determinism before accessing the detail which
// it caches.
boolean orderDeterministic = plan.isOrderDeterministic();
catalogStmt.setIsorderdeterministic(orderDeterministic);
boolean contentDeterministic = plan.isContentDeterministic() && (orderDeterministic || !plan.hasLimitOrOffset());
catalogStmt.setIscontentdeterministic(contentDeterministic);
String nondeterminismDetail = plan.nondeterminismDetail();
catalogStmt.setNondeterminismdetail(nondeterminismDetail);
catalogStmt.setSeqscancount(plan.countSeqScans());
// We will need to update the system catalogs with this new information
for (int i = 0; i < plan.parameters.length; ++i) {
StmtParameter catalogParam = catalogStmt.getParameters().add(String.valueOf(i));
catalogParam.setJavatype(plan.parameters[i].getValueType().getValue());
catalogParam.setIsarray(plan.parameters[i].getParamIsVector());
catalogParam.setIndex(i);
}
catalogStmt.setReplicatedtabledml(plan.replicatedTableDML);
// output the explained plan to disk (or caller) for debugging
// Initial capacity estimate.
StringBuilder planDescription = new StringBuilder(1000);
planDescription.append("SQL: ").append(plan.sql);
// Cost seems to only confuse people who don't understand how this number is used/generated.
if (VoltCompiler.DEBUG_MODE) {
planDescription.append("\nCOST: ").append(plan.cost);
}
planDescription.append("\nPLAN:\n");
planDescription.append(plan.explainedPlan);
String planString = planDescription.toString();
// only write to disk if compiler is in standalone mode
if (compiler.standaloneCompiler) {
BuildDirectoryUtils.writeFile(null, name + ".txt", planString, false);
}
compiler.captureDiagnosticContext(planString);
// build usage links for report generation and put them in the catalog
CatalogUtil.updateUsageAnnotations(db, catalogStmt, plan.rootPlanGraph, plan.subPlanGraph);
// set the explain plan output into the catalog (in hex) for reporting
catalogStmt.setExplainplan(Encoder.hexEncode(plan.explainedPlan));
// compute a hash of the plan
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
assert (false);
// should never happen with healthy jvm
System.exit(-1);
}
// Now update our catalog information
PlanFragment planFragment = catalogStmt.getFragments().add("0");
planFragment.setHasdependencies(plan.subPlanGraph != null);
// mark a fragment as non-transactional if it never touches a persistent table
planFragment.setNontransactional(!fragmentReferencesPersistentTable(plan.rootPlanGraph));
planFragment.setMultipartition(plan.subPlanGraph != null);
byte[] planBytes = writePlanBytes(compiler, planFragment, plan.rootPlanGraph);
md.update(planBytes, 0, planBytes.length);
// compute the 40 bytes of hex from the 20 byte sha1 hash of the plans
md.reset();
md.update(planBytes);
planFragment.setPlanhash(Encoder.hexEncode(md.digest()));
if (plan.subPlanGraph != null) {
planFragment = catalogStmt.getFragments().add("1");
planFragment.setHasdependencies(false);
planFragment.setNontransactional(false);
planFragment.setMultipartition(true);
byte[] subBytes = writePlanBytes(compiler, planFragment, plan.subPlanGraph);
// compute the 40 bytes of hex from the 20 byte sha1 hash of the plans
md.reset();
md.update(subBytes);
planFragment.setPlanhash(Encoder.hexEncode(md.digest()));
}
// Planner should have rejected with an exception any statement with an unrecognized type.
int validType = catalogStmt.getQuerytype();
assert (validType != QueryType.INVALID.getValue());
return false;
} catch (StackOverflowError error) {
String msg = "Failed to plan for statement (" + catalogStmt.getTypeName() + ") \"" + catalogStmt.getSqltext() + "\". Error: \"Encountered stack overflow error. " + "Try reducing the number of predicate expressions in the query.\"";
throw compiler.new VoltCompilerException(msg);
}
}
Aggregations