Search in sources :

Example 11 with Procedure

use of org.voltdb.catalog.Procedure 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 12 with Procedure

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

the class TestInvocationAcceptancePolicy method testUserPermission.

@Test
public void testUserPermission() {
    Procedure proc = new Procedure();
    proc.setDefaultproc(true);
    AuthSystem.AuthUser user = createUser(false, true, false, proc, true, false, false);
    StoredProcedureInvocation invocation = new StoredProcedureInvocation();
    invocation.setProcName("A.insert");
    invocation.setParams("test");
    InvocationPermissionPolicy policy = new InvocationDefaultProcPermissionPolicy();
    assertEquals(policy.shouldAccept(user, invocation, proc), PolicyResult.ALLOW);
    // A user that doesn't have crud permission
    user = createUser(false, false, false, null, true, false, false);
    assertEquals(policy.shouldAccept(user, invocation, proc), PolicyResult.DENY);
}
Also used : Procedure(org.voltdb.catalog.Procedure) Test(org.junit.Test)

Example 13 with Procedure

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

the class TestInvocationAcceptancePolicy method testAdHocUserPermission.

@Test
public void testAdHocUserPermission() {
    AuthSystem.AuthUser user = createUser(true, false, false, null, true, false, false);
    StoredProcedureInvocation invocation = new StoredProcedureInvocation();
    invocation.setProcName("@AdHoc_RW_MP");
    invocation.setParams("insert into T values (1);");
    Procedure proc = SystemProcedureCatalog.listing.get("@AdHoc_RW_MP").asCatalogProcedure();
    InvocationPermissionPolicy policy = new InvocationSqlPermissionPolicy();
    assertEquals(policy.shouldAccept(user, invocation, proc), PolicyResult.ALLOW);
    // A user that doesn't have adhoc permission
    user = createUser(false, false, false, null, true, true, true);
    assertEquals(policy.shouldAccept(user, invocation, proc), PolicyResult.DENY);
}
Also used : Procedure(org.voltdb.catalog.Procedure) Test(org.junit.Test)

Example 14 with Procedure

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

the class TestInvocationAcceptancePolicy method testUserDefinedProcPermission.

@Test
public void testUserDefinedProcPermission() {
    Procedure proc = new Procedure();
    StoredProcedureInvocation invocation = new StoredProcedureInvocation();
    invocation.setProcName("MyProc");
    invocation.setParams("test");
    InvocationPermissionPolicy policy = new InvocationUserDefinedProcedurePermissionPolicy();
    //WITH allproc access
    AuthSystem.AuthUser user2 = createUser(false, false, false, proc, true, true, true);
    assertEquals(policy.shouldAccept(user2, invocation, proc), PolicyResult.ALLOW);
    //Without allproc
    AuthSystem.AuthUser user3 = createUser(false, false, false, proc, false, false, false);
    assertEquals(policy.shouldAccept(user3, invocation, proc), PolicyResult.DENY);
//We cant test individual authorized proc here.
}
Also used : Procedure(org.voltdb.catalog.Procedure) Test(org.junit.Test)

Example 15 with Procedure

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

the class TestInvocationAcceptancePolicy method testSysprocUserPermission.

@Test
public void testSysprocUserPermission() {
    AuthSystem.AuthUser user = createUser(false, false, true, null, true, false, false);
    StoredProcedureInvocation invocation = new StoredProcedureInvocation();
    invocation.setProcName("@Pause");
    Procedure proc = SystemProcedureCatalog.listing.get("@Pause").asCatalogProcedure();
    InvocationPermissionPolicy policy = new InvocationSysprocPermissionPolicy();
    assertEquals(policy.shouldAccept(user, invocation, proc), PolicyResult.ALLOW);
    // A user that doesn't have admin permission
    user = createUser(false, false, false, null, true, false, false);
    assertEquals(policy.shouldAccept(user, invocation, proc), PolicyResult.DENY);
}
Also used : Procedure(org.voltdb.catalog.Procedure) Test(org.junit.Test)

Aggregations

Procedure (org.voltdb.catalog.Procedure)42 Statement (org.voltdb.catalog.Statement)12 Database (org.voltdb.catalog.Database)9 ArrayList (java.util.ArrayList)6 Test (org.junit.Test)6 Table (org.voltdb.catalog.Table)6 VoltTable (org.voltdb.VoltTable)5 Catalog (org.voltdb.catalog.Catalog)5 Constraint (org.voltdb.catalog.Constraint)5 ProcParameter (org.voltdb.catalog.ProcParameter)5 Config (org.voltdb.SystemProcedureCatalog.Config)4 ImmutableMap (com.google_voltpatches.common.collect.ImmutableMap)3 JSONException (org.json_voltpatches.JSONException)3 ProcInfoData (org.voltdb.ProcInfoData)3 SQLStmt (org.voltdb.SQLStmt)3 GroupRef (org.voltdb.catalog.GroupRef)3 PlanFragment (org.voltdb.catalog.PlanFragment)3 File (java.io.File)2 IOException (java.io.IOException)2 SimpleDateFormat (java.text.SimpleDateFormat)2