Search in sources :

Example 6 with ProcParameter

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;
}
Also used : CompiledPlan(org.voltdb.planner.CompiledPlan) ProcedurePartitionInfo(org.voltdb.CatalogContext.ProcedurePartitionInfo) Table(org.voltdb.catalog.Table) Statement(org.voltdb.catalog.Statement) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) Catalog(org.voltdb.catalog.Catalog) PlanFragment(org.voltdb.catalog.PlanFragment) StmtParameter(org.voltdb.catalog.StmtParameter) Database(org.voltdb.catalog.Database) StatementPartitioning(org.voltdb.planner.StatementPartitioning) Procedure(org.voltdb.catalog.Procedure) ParameterValueExpression(org.voltdb.expressions.ParameterValueExpression) MessageDigest(java.security.MessageDigest) QueryType(org.voltdb.types.QueryType) ProcParameter(org.voltdb.catalog.ProcParameter)

Example 7 with ProcParameter

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;
}
Also used : Statement(org.voltdb.catalog.Statement) AdHocPlannedStatement(org.voltdb.compiler.AdHocPlannedStatement) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) SerializableException(org.voltdb.exceptions.SerializableException) InvocationTargetException(java.lang.reflect.InvocationTargetException) EEException(org.voltdb.exceptions.EEException) SpecifiedException(org.voltdb.exceptions.SpecifiedException) VoltAbortException(org.voltdb.VoltProcedure.VoltAbortException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) ProcParameter(org.voltdb.catalog.ProcParameter)

Example 8 with ProcParameter

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();
}
Also used : Table(org.voltdb.catalog.Table) Statement(org.voltdb.catalog.Statement) ArrayList(java.util.ArrayList) Index(org.voltdb.catalog.Index) Constraint(org.voltdb.catalog.Constraint) GroupRef(org.voltdb.catalog.GroupRef) ProcParameter(org.voltdb.catalog.ProcParameter)

Example 9 with ProcParameter

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);
}
Also used : ProcedurePartitionInfo(org.voltdb.CatalogContext.ProcedurePartitionInfo) Column(org.voltdb.catalog.Column) Procedure(org.voltdb.catalog.Procedure) ColumnRef(org.voltdb.catalog.ColumnRef) ProcParameter(org.voltdb.catalog.ProcParameter) Constraint(org.voltdb.catalog.Constraint)

Aggregations

ProcParameter (org.voltdb.catalog.ProcParameter)9 Procedure (org.voltdb.catalog.Procedure)5 Statement (org.voltdb.catalog.Statement)5 VoltCompilerException (org.voltdb.compiler.VoltCompiler.VoltCompilerException)4 Method (java.lang.reflect.Method)3 VoltTypeException (org.voltdb.VoltTypeException)3 GroupRef (org.voltdb.catalog.GroupRef)3 ParameterValueExpression (org.voltdb.expressions.ParameterValueExpression)3 StatementPartitioning (org.voltdb.planner.StatementPartitioning)3 ArrayList (java.util.ArrayList)2 ProcedurePartitionInfo (org.voltdb.CatalogContext.ProcedurePartitionInfo)2 ProcInfoData (org.voltdb.ProcInfoData)2 VoltNonTransactionalProcedure (org.voltdb.VoltNonTransactionalProcedure)2 VoltProcedure (org.voltdb.VoltProcedure)2 VoltType (org.voltdb.VoltType)2 Constraint (org.voltdb.catalog.Constraint)2 Group (org.voltdb.catalog.Group)2 StmtParameter (org.voltdb.catalog.StmtParameter)2 Table (org.voltdb.catalog.Table)2 QueryType (org.voltdb.types.QueryType)2