use of org.voltdb.catalog.ProcParameter in project voltdb by VoltDB.
the class StatementCompiler method compileDefaultProcedure.
/**
* This procedure compiles a shim org.voltdb.catalog.Procedure representing a default proc.
* The shim has no plan and few details that are expensive to compute.
* The returned proc instance has a full plan and can be used to create a ProcedureRunner.
* Note that while there are two procedure objects here, none are rooted in a real catalog;
* they are entirely parallel to regular, catalog procs.
*
* This code could probably go a few different places. It duplicates a bit too much of the
* StatmentCompiler code for my taste, so I put it here. Next pass could reduce some of the
* duplication?
*/
public static Procedure compileDefaultProcedure(PlannerTool plannerTool, Procedure catProc, String sqlText) {
// fake db makes it easy to create procedures that aren't part of the main catalog
Database fakeDb = new Catalog().getClusters().add("cluster").getDatabases().add("database");
Table table = catProc.getPartitiontable();
// determine the type of the query
QueryType qtype = QueryType.getFromSQL(sqlText);
StatementPartitioning partitioning = catProc.getSinglepartition() ? StatementPartitioning.forceSP() : StatementPartitioning.forceMP();
CompiledPlan plan = plannerTool.planSqlCore(sqlText, partitioning);
Procedure newCatProc = fakeDb.getProcedures().add(catProc.getTypeName());
newCatProc.setClassname(catProc.getClassname());
newCatProc.setDefaultproc(true);
newCatProc.setEverysite(false);
newCatProc.setHasjava(false);
newCatProc.setPartitioncolumn(catProc.getPartitioncolumn());
newCatProc.setPartitionparameter(catProc.getPartitionparameter());
newCatProc.setPartitiontable(catProc.getPartitiontable());
newCatProc.setReadonly(catProc.getReadonly());
newCatProc.setSinglepartition(catProc.getSinglepartition());
newCatProc.setSystemproc(false);
if (catProc.getPartitionparameter() >= 0) {
newCatProc.setAttachment(new ProcedurePartitionInfo(VoltType.get((byte) catProc.getPartitioncolumn().getType()), catProc.getPartitionparameter()));
}
CatalogMap<Statement> statements = newCatProc.getStatements();
assert (statements != null);
Statement stmt = statements.add(VoltDB.ANON_STMT_NAME);
stmt.setSqltext(sqlText);
stmt.setReadonly(catProc.getReadonly());
stmt.setQuerytype(qtype.getValue());
stmt.setSinglepartition(catProc.getSinglepartition());
stmt.setIscontentdeterministic(true);
stmt.setIsorderdeterministic(true);
stmt.setNondeterminismdetail("NO CONTENT FOR DEFAULT PROCS");
stmt.setSeqscancount(plan.countSeqScans());
stmt.setReplicatedtabledml(!catProc.getReadonly() && table.getIsreplicated());
// We will need to update the system catalogs with this new information
for (int i = 0; i < plan.parameters.length; ++i) {
StmtParameter catalogParam = stmt.getParameters().add(String.valueOf(i));
catalogParam.setIndex(i);
ParameterValueExpression pve = plan.parameters[i];
catalogParam.setJavatype(pve.getValueType().getValue());
catalogParam.setIsarray(pve.getParamIsVector());
}
PlanFragment frag = stmt.getFragments().add("0");
// 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);
}
byte[] planBytes = writePlanBytes(frag, 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);
frag.setPlanhash(Encoder.hexEncode(md.digest()));
if (plan.subPlanGraph != null) {
frag.setHasdependencies(true);
frag.setNontransactional(true);
frag.setMultipartition(true);
frag = stmt.getFragments().add("1");
frag.setHasdependencies(false);
frag.setNontransactional(false);
frag.setMultipartition(true);
byte[] subBytes = writePlanBytes(frag, plan.subPlanGraph);
// compute the 40 bytes of hex from the 20 byte sha1 hash of the plans
md.reset();
md.update(subBytes);
frag.setPlanhash(Encoder.hexEncode(md.digest()));
} else {
frag.setHasdependencies(false);
frag.setNontransactional(false);
frag.setMultipartition(false);
}
// set the procedure parameter types from the statement parameter types
int paramCount = 0;
for (StmtParameter stmtParam : CatalogUtil.getSortedCatalogItems(stmt.getParameters(), "index")) {
// name each parameter "param1", "param2", etc...
ProcParameter procParam = newCatProc.getParameters().add("param" + String.valueOf(paramCount));
procParam.setIndex(stmtParam.getIndex());
procParam.setIsarray(stmtParam.getIsarray());
procParam.setType(stmtParam.getJavatype());
paramCount++;
}
return newCatProc;
}
use of org.voltdb.catalog.ProcParameter in project voltdb by VoltDB.
the class ProcedureRunner method reflect.
// Returns a list that contains the names of the statements which are defined in the stored procedure.
protected ArrayList<String> reflect() {
Map<String, SQLStmt> stmtMap = null;
// fill in the sql for single statement procs
if (m_catProc.getHasjava() == false) {
try {
stmtMap = ProcedureCompiler.getValidSQLStmts(null, m_procedureName, m_procedure.getClass(), m_procedure, true);
SQLStmt stmt = stmtMap.get(VoltDB.ANON_STMT_NAME);
assert (stmt != null);
Statement statement = m_catProc.getStatements().get(VoltDB.ANON_STMT_NAME);
String s = statement.getSqltext();
SQLStmtAdHocHelper.setSQLStr(stmt, s);
m_cachedSingleStmt.stmt = stmt;
int numParams = m_catProc.getParameters().size();
m_paramTypes = new Class<?>[numParams];
for (ProcParameter param : m_catProc.getParameters()) {
VoltType type = VoltType.get((byte) param.getType());
if (param.getIsarray()) {
m_paramTypes[param.getIndex()] = type.vectorClassFromType();
continue;
}
// (ParameterConverter.tryToMakeCompatible) before falling through to the EE?
if (type == VoltType.INTEGER) {
type = VoltType.BIGINT;
} else if (type == VoltType.SMALLINT) {
type = VoltType.BIGINT;
} else if (type == VoltType.TINYINT) {
type = VoltType.BIGINT;
} else if (type == VoltType.NUMERIC) {
type = VoltType.FLOAT;
}
m_paramTypes[param.getIndex()] = type.classFromType();
}
} catch (Exception e) {
// shouldn't throw anything outside of the compiler
e.printStackTrace();
}
// iterate through the fields and deal with sql statements
try {
stmtMap = ProcedureCompiler.getValidSQLStmts(null, m_procedureName, m_procedure.getClass(), m_procedure, true);
} catch (Exception e1) {
// shouldn't throw anything outside of the compiler
e1.printStackTrace();
return null;
}
} else {
// this is where, in the case of java procedures, m_procMethod is set
for (final Method m : m_procedure.getClass().getDeclaredMethods()) {
String name = m.getName();
if (name.equals("run")) {
if (Modifier.isPublic(m.getModifiers()) == false) {
continue;
}
m_procMethod = m;
m_paramTypes = m.getParameterTypes();
break;
}
}
if (m_procMethod == null) {
throw new RuntimeException("No \"run\" method found in: " + m_procedure.getClass().getName());
}
// iterate through the fields and deal with sql statements
try {
stmtMap = ProcedureCompiler.getValidSQLStmts(null, m_procedureName, m_procedure.getClass(), m_procedure, true);
} catch (Exception e) {
// shouldn't happen here because it passed the compiler
VoltDB.crashLocalVoltDB("getValidSQLStmts threw exception during ProcedureRunner loading", true, e);
}
}
ArrayList<String> stmtNames = new ArrayList<String>(stmtMap.entrySet().size());
for (final Entry<String, SQLStmt> entry : stmtMap.entrySet()) {
String name = entry.getKey();
stmtNames.add(name);
// Label the SQLStmts with its variable name.
// This is useful for multi-partition stored procedures.
// When a statement is sent to another site for execution,
// that SP site can use this name to find the correct place to
// update the statistics numbers.
entry.getValue().setStmtName(name);
Statement s = m_catProc.getStatements().get(name);
if (s != null) {
/*
* Cache all the information we need about the statements in this stored
* procedure locally instead of pulling them from the catalog on
* a regular basis.
*/
SQLStmt stmt = entry.getValue();
// done in a static method in an abstract class so users don't call it
initSQLStmt(stmt, s);
//LOG.fine("Found statement " + name);
}
}
return stmtNames;
}
use of org.voltdb.catalog.ProcParameter in project voltdb by VoltDB.
the class ReportMaker method generateProcedureRow.
static String generateProcedureRow(CatalogMap<Table> tables, Procedure procedure) {
StringBuilder sb = new StringBuilder();
sb.append("<tr class='primaryrow'>");
// column 1: procedure name
String anchor = procedure.getTypeName().toLowerCase();
sb.append("<td style='white-space: nowrap'><i id='p-" + anchor + "--icon' class='icon-chevron-right'></i> <a href='#p-");
sb.append(anchor).append("' id='p-").append(anchor).append("' class='togglex'>");
sb.append(procedure.getTypeName());
sb.append("</a></td>");
// column 2: parameter types
sb.append("<td>");
List<ProcParameter> params = CatalogUtil.getSortedCatalogItems(procedure.getParameters(), "index");
List<String> paramTypes = new ArrayList<String>();
for (ProcParameter param : params) {
String paramType = VoltType.get((byte) param.getType()).name();
if (param.getIsarray()) {
paramType += "[]";
}
paramTypes.add(paramType);
}
if (paramTypes.size() == 0) {
sb.append("<i>None</i>");
}
sb.append(StringUtils.join(paramTypes, ", "));
sb.append("</td>");
// column 3: partitioning
sb.append("<td>");
if (procedure.getSinglepartition()) {
tag(sb, "success", "Single");
} else {
tag(sb, "warning", "Multi");
}
sb.append("</td>");
// column 4: read/write
sb.append("<td>");
if (procedure.getReadonly()) {
tag(sb, "success", "Read");
} else {
tag(sb, "warning", "Write");
}
sb.append("</td>");
// column 5: access
sb.append("<td>");
List<String> groupNames = new ArrayList<String>();
for (GroupRef groupRef : procedure.getAuthgroups()) {
groupNames.add(groupRef.getGroup().getTypeName());
}
if (groupNames.size() == 0) {
sb.append("<i>None</i>");
}
sb.append(StringUtils.join(groupNames, ", "));
sb.append("</td>");
// column 6: attributes
sb.append("<td>");
if (procedure.getHasjava()) {
tag(sb, "info", "Java");
} else {
tag(sb, null, "Single-Stmt");
}
boolean isND = false;
int scanCount = 0;
for (Statement stmt : procedure.getStatements()) {
scanCount += stmt.getSeqscancount();
if (!stmt.getIscontentdeterministic() || !stmt.getIsorderdeterministic()) {
isND = false;
}
}
if (isND) {
tag(sb, "inverse", "Determinism");
}
if (scanCount > 0) {
tag(sb, "important", "Scans");
}
sb.append("</td>");
sb.append("</tr>\n");
// BUILD THE DROPDOWN FOR THE STATEMENT/DETAIL TABLE
sb.append("<tr class='tablesorter-childRow'><td class='invert' colspan='6' id='p-" + procedure.getTypeName().toLowerCase() + "--dropdown'>\n");
// output partitioning parameter info
if (procedure.getSinglepartition()) {
String pTable = procedure.getPartitioncolumn().getParent().getTypeName();
String pColumn = procedure.getPartitioncolumn().getTypeName();
int pIndex = procedure.getPartitionparameter();
sb.append(String.format("<p>Partitioned on parameter %d which maps to column %s" + " of table <a class='invert' href='#s-%s'>%s</a>.</p>", pIndex, pColumn, pTable, pTable));
}
// get the annotation or ensure it's there
ProcedureAnnotation annotation = (ProcedureAnnotation) procedure.getAnnotation();
if (annotation == null) {
annotation = new ProcedureAnnotation();
procedure.setAnnotation(annotation);
}
// this needs to be run before the ProcedureAnnotation is used below
// because it modifies it
String statementsTable = generateStatementsTable(tables, procedure);
// output what schema this interacts with
// make sure tables appear in only one category
annotation.tablesRead.removeAll(annotation.tablesUpdated);
if (annotation.tablesRead.size() > 0) {
sb.append("<p>Read-only access to tables: ");
List<String> tableList = new ArrayList<String>();
for (Table table : annotation.tablesRead) {
tableList.add("<a href='#s-" + table.getTypeName() + "'>" + table.getTypeName() + "</a>");
}
sb.append(StringUtils.join(tableList, ", "));
sb.append("</p>");
}
if (annotation.tablesUpdated.size() > 0) {
sb.append("<p>Read/Write access to tables: ");
List<String> tableList = new ArrayList<String>();
for (Table table : annotation.tablesUpdated) {
tableList.add("<a href='#s-" + table.getTypeName() + "'>" + table.getTypeName() + "</a>");
}
sb.append(StringUtils.join(tableList, ", "));
sb.append("</p>");
}
if (annotation.indexesUsed.size() > 0) {
sb.append("<p>Uses indexes: ");
List<String> indexes = new ArrayList<String>();
for (Index index : annotation.indexesUsed) {
Table table = (Table) index.getParent();
indexes.add("<a href='#s-" + table.getTypeName() + "-" + index.getTypeName() + "'>" + index.getTypeName() + "</a>");
}
sb.append(StringUtils.join(indexes, ", "));
sb.append("</p>");
}
sb.append(statementsTable);
sb.append("</td></tr>\n");
return sb.toString();
}
use of org.voltdb.catalog.ProcParameter in project voltdb by VoltDB.
the class DefaultProcedureManager method addShimProcedure.
private void addShimProcedure(String name, Table table, Constraint pkey, boolean tableCols, int partitionParamIndex, Column partitionColumn, boolean readOnly) {
Procedure proc = m_fakeDb.getProcedures().add(name);
proc.setClassname(name);
proc.setDefaultproc(true);
proc.setHasjava(false);
proc.setHasseqscans(false);
proc.setSinglepartition(partitionParamIndex >= 0);
proc.setPartitioncolumn(partitionColumn);
proc.setPartitionparameter(partitionParamIndex);
proc.setReadonly(readOnly);
proc.setEverysite(false);
proc.setSystemproc(false);
proc.setPartitiontable(table);
if (partitionParamIndex >= 0) {
proc.setAttachment(new ProcedurePartitionInfo(VoltType.get((byte) partitionColumn.getType()), partitionParamIndex));
}
int paramCount = 0;
if (tableCols) {
for (Column col : table.getColumns()) {
// name each parameter "param1", "param2", etc...
ProcParameter procParam = proc.getParameters().add("param" + String.valueOf(paramCount));
procParam.setIndex(col.getIndex());
procParam.setIsarray(false);
procParam.setType(col.getType());
paramCount++;
}
}
if (pkey != null) {
CatalogMap<ColumnRef> pkeycols = pkey.getIndex().getColumns();
int paramCount2 = paramCount;
for (ColumnRef cref : pkeycols) {
// name each parameter "param1", "param2", etc...
ProcParameter procParam = proc.getParameters().add("param" + String.valueOf(paramCount2));
procParam.setIndex(cref.getIndex() + paramCount);
procParam.setIsarray(false);
procParam.setType(cref.getColumn().getType());
paramCount2++;
}
}
m_defaultProcMap.put(name.toLowerCase(), proc);
}
Aggregations