Search in sources :

Example 6 with Statement

use of org.voltdb.catalog.Statement 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);
            }
        }
    }
}
Also used : Group(org.voltdb.catalog.Group) Statement(org.voltdb.catalog.Statement) VoltCompilerException(org.voltdb.compiler.VoltCompiler.VoltCompilerException) VoltTypeException(org.voltdb.VoltTypeException) StmtParameter(org.voltdb.catalog.StmtParameter) AbstractExpression(org.voltdb.expressions.AbstractExpression) ProcInfoData(org.voltdb.ProcInfoData) StatementPartitioning(org.voltdb.planner.StatementPartitioning) VoltProcedure(org.voltdb.VoltProcedure) VoltNonTransactionalProcedure(org.voltdb.VoltNonTransactionalProcedure) Procedure(org.voltdb.catalog.Procedure) VoltCompilerException(org.voltdb.compiler.VoltCompiler.VoltCompilerException) GroupRef(org.voltdb.catalog.GroupRef) ParameterValueExpression(org.voltdb.expressions.ParameterValueExpression) ProcParameter(org.voltdb.catalog.ProcParameter)

Example 7 with Statement

use of org.voltdb.catalog.Statement in project voltdb by VoltDB.

the class MaterializedViewProcessor method compileCreateQueryAndUpdateCatalog.

private void compileCreateQueryAndUpdateCatalog(Database db, String query, VoltXMLElement xmlquery, MaterializedViewHandlerInfo mvHandlerInfo) throws VoltCompilerException {
    DatabaseEstimates estimates = new DatabaseEstimates();
    // Here we are compiling the query twice:
    //   In the first round, we will use inferPartitioning.
    // The purpose is to use the planner to check if the join query is plannable.
    // Some multi-partition join queries are not plannable because they are not
    // joining tables on the partition columns.
    //   In the second round, we will use forceSP to get the single partition
    // version of the query plan.
    Statement createQueryInfer = mvHandlerInfo.getCreatequery().add("createQueryInfer");
    Statement createQuery = mvHandlerInfo.getCreatequery().add("createQuery");
    createQueryInfer.setSqltext(query);
    createQuery.setSqltext(query);
    StatementCompiler.compileStatementAndUpdateCatalog(m_compiler, m_hsql, db, estimates, createQueryInfer, xmlquery, createQueryInfer.getSqltext(), // no user-supplied join order
    null, DeterminismMode.FASTER, StatementPartitioning.inferPartitioning());
    mvHandlerInfo.getCreatequery().delete("createQueryInfer");
    StatementCompiler.compileStatementAndUpdateCatalog(m_compiler, m_hsql, db, estimates, createQuery, xmlquery, createQuery.getSqltext(), // no user-supplied join order
    null, DeterminismMode.FASTER, StatementPartitioning.forceSP());
}
Also used : Statement(org.voltdb.catalog.Statement)

Example 8 with Statement

use of org.voltdb.catalog.Statement in project voltdb by VoltDB.

the class TestFragmentProgressUpdate method testPeakLargerThanCurr.

@SuppressWarnings("deprecation")
public void testPeakLargerThanCurr() throws Exception {
    m_ee.loadCatalog(0, m_catalog.serialize());
    int tableSize = 20000;
    int longOpthreshold = 10000;
    m_warehousedata.clearRowData();
    for (int i = 0; i < tableSize; ++i) {
        m_warehousedata.addRow(i, "name" + i, "st1", "st2", "city", "ST", "zip", 0, 0);
    }
    m_ee.loadTable(WAREHOUSE_TABLEID, m_warehousedata, 0, 0, 0, 0, false, false, WRITE_TOKEN);
    assertEquals(tableSize, m_ee.serializeTable(WAREHOUSE_TABLEID).getRowCount());
    System.out.println("Rows loaded to table " + m_ee.serializeTable(WAREHOUSE_TABLEID).getRowCount());
    Statement selectStmt = m_testProc.getStatements().getIgnoreCase("warehouse_join");
    PlanFragment selectBottomFrag = null;
    // delete 5000 records
    // I have no idea what's going on here, and just copy code from the above methods
    int i = 0;
    // this kinda assumes the right order
    for (PlanFragment f : selectStmt.getFragments()) {
        if (i != 0)
            selectBottomFrag = f;
        i++;
    }
    // populate plan cache
    ActivePlanRepository.clear();
    ActivePlanRepository.addFragmentForTest(CatalogUtil.getUniqueIdForFragment(selectBottomFrag), Encoder.decodeBase64AndDecompressToBytes(selectBottomFrag.getPlannodetree()), selectStmt.getSqltext());
    ParameterSet params = ParameterSet.emptyParameterSet();
    m_ee.executePlanFragments(1, new long[] { CatalogUtil.getUniqueIdForFragment(selectBottomFrag) }, null, new ParameterSet[] { params }, null, new String[] { selectStmt.getSqltext() }, null, null, 3, 3, 2, 42, READ_ONLY_TOKEN, false);
    // If want to see the stats, please uncomment the following line.
    // It is '8 393216 262144' on my machine.
    //System.out.println(m_ee.m_callsFromEE +" " + m_ee.m_peakMemoryInBytes + " "+ m_ee.m_currMemoryInBytes);
    assertEquals(longOpthreshold * m_ee.m_callsFromEE, m_ee.m_lastTuplesAccessed);
    assertTrue(m_ee.m_peakMemoryInBytes > m_ee.m_currMemoryInBytes);
}
Also used : ParameterSet(org.voltdb.ParameterSet) Statement(org.voltdb.catalog.Statement) PlanFragment(org.voltdb.catalog.PlanFragment)

Example 9 with Statement

use of org.voltdb.catalog.Statement in project voltdb by VoltDB.

the class TestFragmentProgressUpdate method testFragmentProgressUpdate.

@SuppressWarnings("deprecation")
public void testFragmentProgressUpdate() throws Exception {
    m_ee.loadCatalog(0, m_catalog.serialize());
    int tableSize = 5001;
    int longOpthreshold = 10000;
    m_warehousedata.clearRowData();
    for (int i = 0; i < tableSize; ++i) {
        m_warehousedata.addRow(i, "name" + i, "st1", "st2", "city", "ST", "zip", 0, 0);
    }
    m_ee.loadTable(WAREHOUSE_TABLEID, m_warehousedata, 0, 0, 0, 0, false, false, WRITE_TOKEN);
    assertEquals(tableSize, m_ee.serializeTable(WAREHOUSE_TABLEID).getRowCount());
    System.out.println("Rows loaded to table " + m_ee.serializeTable(WAREHOUSE_TABLEID).getRowCount());
    Statement selectStmt = m_testProc.getStatements().getIgnoreCase("warehouse_select");
    PlanFragment selectBottomFrag = null;
    int i = 0;
    // this kinda assumes the right order
    for (PlanFragment f : selectStmt.getFragments()) {
        if (i != 0)
            selectBottomFrag = f;
        i++;
    }
    // populate plan cache
    ActivePlanRepository.clear();
    ActivePlanRepository.addFragmentForTest(CatalogUtil.getUniqueIdForFragment(selectBottomFrag), Encoder.decodeBase64AndDecompressToBytes(selectBottomFrag.getPlannodetree()), selectStmt.getSqltext());
    ParameterSet params = ParameterSet.emptyParameterSet();
    m_ee.executePlanFragments(1, new long[] { CatalogUtil.getUniqueIdForFragment(selectBottomFrag) }, null, new ParameterSet[] { params }, null, new String[] { selectStmt.getSqltext() }, null, null, 3, 3, 2, 42, Long.MAX_VALUE, false);
    // Like many fully successful operations, a single row fetch counts as 2 logical row operations,
    // one for locating the row and one for retrieving it.
    assertEquals(1, m_ee.m_callsFromEE);
    assertEquals(longOpthreshold, m_ee.m_lastTuplesAccessed);
    assertTrue(450000 < m_ee.m_currMemoryInBytes);
    assertTrue(550000 > m_ee.m_currMemoryInBytes);
    assertTrue(450000 < m_ee.m_peakMemoryInBytes);
    assertTrue(550000 > m_ee.m_peakMemoryInBytes);
    assertTrue(m_ee.m_peakMemoryInBytes >= m_ee.m_currMemoryInBytes);
}
Also used : ParameterSet(org.voltdb.ParameterSet) Statement(org.voltdb.catalog.Statement) PlanFragment(org.voltdb.catalog.PlanFragment)

Example 10 with Statement

use of org.voltdb.catalog.Statement 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;
}
Also used : ClientResponse(org.voltdb.client.ClientResponse) Statement(org.voltdb.catalog.Statement) ArrayList(java.util.ArrayList) VoltTable(org.voltdb.VoltTable) CompletableFuture(java.util.concurrent.CompletableFuture) Procedure(org.voltdb.catalog.Procedure) ClientResponseImpl(org.voltdb.ClientResponseImpl) CatalogContext(org.voltdb.CatalogContext)

Aggregations

Statement (org.voltdb.catalog.Statement)28 Procedure (org.voltdb.catalog.Procedure)12 ArrayList (java.util.ArrayList)8 Constraint (org.voltdb.catalog.Constraint)7 PlanFragment (org.voltdb.catalog.PlanFragment)7 ProcParameter (org.voltdb.catalog.ProcParameter)5 Table (org.voltdb.catalog.Table)5 VoltTable (org.voltdb.VoltTable)4 StmtParameter (org.voltdb.catalog.StmtParameter)4 VoltCompilerException (org.voltdb.compiler.VoltCompiler.VoltCompilerException)4 ParameterValueExpression (org.voltdb.expressions.ParameterValueExpression)4 QueryType (org.voltdb.types.QueryType)4 VoltXMLElement (org.hsqldb_voltpatches.VoltXMLElement)3 ParameterSet (org.voltdb.ParameterSet)3 SQLStmt (org.voltdb.SQLStmt)3 Database (org.voltdb.catalog.Database)3 GroupRef (org.voltdb.catalog.GroupRef)3 Index (org.voltdb.catalog.Index)3 StatementPartitioning (org.voltdb.planner.StatementPartitioning)3 Method (java.lang.reflect.Method)2