Search in sources :

Example 21 with StatementContext

use of org.apache.derby.iapi.sql.conn.StatementContext in project derby by apache.

the class GenericLanguageConnectionContext method doRollback.

/**
 * When a rollback happens, the language connection context
 * will close all open activations and invalidate
 * their prepared statements. Then the language will abort the
 * Store transaction.
 * <p>
 * The invalidated statements can revalidate themselves without
 * a full recompile if they verify their dependencies' providers still
 * exist unchanged. REVISIT when invalidation types are created.
 * <p>
 * REVISIT: this may need additional alterations when
 * RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT show up.
 * <p>
 * Also, tell the data dictionary that the transaction is finished,
 * if necessary (that is, if the data dictionary was put into
 * DDL mode in this transaction.
 *
 * @param xa    true if this is an xa rollback
 * @param requestedByUser   true if requested by user
 *
 * @exception StandardException thrown on failure
 */
private void doRollback(boolean xa, boolean requestedByUser) throws StandardException {
    StatementContext statementContext = getStatementContext();
    if (requestedByUser && (statementContext != null) && statementContext.inUse() && statementContext.isAtomic()) {
        throw StandardException.newException(SQLState.LANG_NO_ROLLBACK_IN_NESTED_CONNECTION);
    }
    clearDeferreds();
    // Log rollback to error log, if appropriate
    if (logStatementText) {
        if (istream == null) {
            istream = Monitor.getStream();
        }
        String xactId = tran.getTransactionIdString();
        istream.printlnWithHeader(LanguageConnectionContext.xidStr + xactId + "), " + LanguageConnectionContext.lccStr + instanceNumber + "), " + LanguageConnectionContext.dbnameStr + dbname + "), " + LanguageConnectionContext.drdaStr + drdaID + "), Rolling back");
    }
    endTransactionActivationHandling(true);
    // reset the current savepoint level for the connection to 0 at the beginning of rollback work for temp tables
    currentSavepointLevel = 0;
    if (allDeclaredGlobalTempTables != null)
        tempTablesAndRollback();
    finishDDTransaction();
    // with the user transaction.
    if (readOnlyNestedTransaction != null) {
        readOnlyNestedTransaction.destroy();
        readOnlyNestedTransaction = null;
        queryNestingDepth = 0;
    }
    // now rollback the Store transaction
    TransactionController tc = getTransactionExecute();
    if (tc != null) {
        if (xa)
            ((XATransactionController) tc).xa_rollback();
        else
            tc.abort();
        // reset the savepoints to the new
        // location, since any outer nesting
        // levels expet there to be a savepoint
        resetSavepoints();
    }
}
Also used : TransactionController(org.apache.derby.iapi.store.access.TransactionController) XATransactionController(org.apache.derby.iapi.store.access.XATransactionController) StatementContext(org.apache.derby.iapi.sql.conn.StatementContext)

Example 22 with StatementContext

use of org.apache.derby.iapi.sql.conn.StatementContext in project derby by apache.

the class GenericLanguageConnectionContext method getCurrentSQLSessionContext.

/**
 * Return the current SQL session context based on statement context
 */
private SQLSessionContext getCurrentSQLSessionContext() {
    StatementContext ctx = getStatementContext();
    SQLSessionContext curr;
    if (ctx == null || !ctx.inUse()) {
        curr = getTopLevelSQLSessionContext();
    } else {
        // We are inside a nested connection in a procedure of
        // function.
        curr = ctx.getSQLSessionContext();
        if (SanityManager.DEBUG) {
            SanityManager.ASSERT(curr != null, "SQL session context should never be empty here");
        }
    }
    return curr;
}
Also used : SQLSessionContext(org.apache.derby.iapi.sql.conn.SQLSessionContext) StatementContext(org.apache.derby.iapi.sql.conn.StatementContext)

Example 23 with StatementContext

use of org.apache.derby.iapi.sql.conn.StatementContext in project derby by apache.

the class GenericLanguageConnectionContext method setupSessionContextMinion.

private void setupSessionContextMinion(Activation a, boolean push, boolean definersRights, String definer) throws StandardException {
    if (SanityManager.DEBUG) {
        if (definersRights) {
            SanityManager.ASSERT(push);
        }
    }
    SQLSessionContext sc = a.setupSQLSessionContextForChildren(push);
    if (definersRights) {
        sc.setUser(definer);
    } else {
        // A priori: invoker's rights: Current user
        sc.setUser(getCurrentUserId(a));
    }
    if (definersRights) {
        // No role a priori. Cf. SQL 2008, section 10.4 <routine
        // invocation>, GR 5 j) i) 1) B) "If the external security
        // characteristic of R is DEFINER, then the top cell of the
        // authorization stack of RSC is set to contain only the routine
        // authorization identifier of R.
        sc.setRole(null);
    } else {
        // Semantics for roles dictate (SQL 4.34.1.1 and 4.27.3.) that the
        // role is initially inherited from the current session context
        // when we run with INVOKER security characteristic.
        sc.setRole(getCurrentRoleId(a));
    }
    if (definersRights) {
        SchemaDescriptor sd = getDataDictionary().getSchemaDescriptor(definer, getTransactionExecute(), false);
        if (sd == null) {
            sd = new SchemaDescriptor(getDataDictionary(), definer, definer, (UUID) null, false);
        }
        sc.setDefaultSchema(sd);
    } else {
        // Inherit current default schema. The initial value of the
        // default schema is implementation defined. In Derby we
        // inherit it when we invoke stored procedures and functions.
        sc.setDefaultSchema(getDefaultSchema(a));
    }
    final SQLSessionContext ssc = getCurrentSQLSessionContext(a);
    sc.setDeferredAll(ssc.getDeferredAll());
    sc.setConstraintModes(ssc.getConstraintModes());
    StatementContext stmctx = getStatementContext();
    // Since the statement is an invocation (iff push=true), it will now be
    // associated with the pushed SQLSessionContext (and no longer just
    // share that of its caller (or top).  The statement contexts of nested
    // connection statements will inherit statement context so the SQL
    // session context is available through it when nested statements are
    // compiled (and executed, for the most part).  However, for dynamic
    // result sets, the relevant statement context (originating result set)
    // is no longer available for execution time references to the SQL
    // session context, so we rely on the activation of the caller for
    // accessing it, cf. e.g. overload variants of
    // getDefaultSchema/setDefaultSchema.  If such nested connections
    // themselves turn out to be invocations, they in turn get a new
    // SQLSessionContext associated with them etc.
    stmctx.setSQLSessionContext(sc);
}
Also used : SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) SQLSessionContext(org.apache.derby.iapi.sql.conn.SQLSessionContext) UUID(org.apache.derby.catalog.UUID) StatementContext(org.apache.derby.iapi.sql.conn.StatementContext)

Example 24 with StatementContext

use of org.apache.derby.iapi.sql.conn.StatementContext in project derby by apache.

the class GenericTriggerExecutor method executeSPS.

/**
 * Execute the given stored prepared statement.  We
 * just grab the prepared statement from the spsd,
 * get a new activation holder and let er rip.
 *
 * @param sps the SPS to execute
 * @param isWhen {@code true} if the SPS is for the WHEN clause,
 *               {@code false} otherwise
 * @return {@code true} if the SPS is for a WHEN clause and it evaluated
 *         to {@code TRUE}, {@code false} otherwise
 * @exception StandardException on error
 */
private boolean executeSPS(SPSDescriptor sps, boolean isWhen) throws StandardException {
    boolean recompile = false;
    boolean whenClauseWasTrue = false;
    // The prepared statement and the activation may already be available
    // if the trigger has been fired before in the same statement. (Only
    // happens with row triggers that are triggered by a statement that
    // touched multiple rows.) The WHEN clause and the trigger action have
    // their own prepared statement and activation. Fetch the correct set.
    ExecPreparedStatement ps = isWhen ? whenPS : actionPS;
    Activation spsActivation = isWhen ? spsWhenActivation : spsActionActivation;
    while (true) {
        /*
			** Only grab the ps the 1st time through.  This
			** way a row trigger doesn't do any unnecessary
			** setup work.
			*/
        if (ps == null || recompile) {
            // The SPS activation will set its parent activation from
            // the statement context. Reset it to the original parent
            // activation first so that it doesn't use the activation of
            // the previously executed SPS as parent. DERBY-6348.
            lcc.getStatementContext().setActivation(activation);
            /*
				** We need to clone the prepared statement so we don't
				** wind up marking that ps that is tied to sps as finished
				** during the course of execution.
				*/
            ps = sps.getPreparedStatement();
            ps = ps.getClone();
            // it should be valid since we've just prepared for it
            ps.setValid();
            spsActivation = ps.getActivation(lcc, false);
            /*
				** Normally, we want getSource() for an sps invocation
				** to be EXEC STATEMENT xxx, but in this case, since
				** we are executing the SPS in our own fashion, we want
				** the text to be the trigger action.  So set it accordingly.
				*/
            ps.setSource(sps.getText());
            ps.setSPSAction();
            // trigger fires multiple times.
            if (isWhen) {
                whenPS = ps;
                spsWhenActivation = spsActivation;
            } else {
                actionPS = ps;
                spsActionActivation = spsActivation;
            }
        }
        // save the active statement context for exception handling purpose
        StatementContext active_sc = lcc.getStatementContext();
        /*
			** Execute the activation.  If we have an error, we
			** are going to go to some extra work to pop off
			** our statement context.  This is because we are
			** a nested statement (we have 2 activations), but
			** we aren't a nested connection, so we have to
			** pop off our statementcontext to get error handling	
			** to work correctly.  This is normally a no-no, but
			** we are an unusual case.
			*/
        try {
            // This is a substatement; for now, we do not set any timeout
            // for it. We might change this behaviour later, by linking
            // timeout to its parent statement's timeout settings.
            ResultSet rs = ps.executeSubStatement(activation, spsActivation, false, 0L);
            if (isWhen) {
                // This is a WHEN clause. Expect a single BOOLEAN value
                // to be returned.
                ExecRow row = rs.getNextRow();
                if (SanityManager.DEBUG && row.nColumns() != 1) {
                    SanityManager.THROWASSERT("Expected WHEN clause to have exactly " + "one column, found: " + row.nColumns());
                }
                DataValueDescriptor value = row.getColumn(1);
                if (SanityManager.DEBUG) {
                    SanityManager.ASSERT(value instanceof SQLBoolean);
                }
                whenClauseWasTrue = !value.isNull() && value.getBoolean();
                if (SanityManager.DEBUG) {
                    SanityManager.ASSERT(rs.getNextRow() == null, "WHEN clause returned more than one row");
                }
            } else if (rs.returnsRows()) {
                // The result set was opened in ps.execute()
                while (rs.getNextRow() != null) {
                }
            }
            rs.close();
        } catch (StandardException e) {
            /* 
				** When a trigger SPS action is executed and results in 
				** an exception, the system needs to clean up the active 
				** statement context(SC) and the trigger execution context
				** (TEC) in language connection context(LCC) properly (e.g.:  
				** "Maximum depth triggers exceeded" exception); otherwise, 
				** this will leave old TECs lingering and may result in 
				** subsequent statements within the same connection to throw 
				** the same exception again prematurely.  
				**    
				** A new statement context will be created for the SPS before
				** it is executed.  However, it is possible for some 
				** StandardException to be thrown before a new statement 
				** context is pushed down to the context stack; hence, the 
				** trigger executor needs to ensure that the current active SC 
				** is associated with the SPS, so that it is cleaning up the 
				** right statement context in LCC. 
                **
                ** It is also possible that the error has already been handled
                ** on a lower level, especially if the trigger re-enters the
                ** JDBC layer. In that case, the current SC will be null.
				**    
				** When the active SC is cleaned up, the TEC will be removed
				** from LCC and the SC object will be popped off from the LCC 
				** as part of cleanupOnError logic.  
				 */
            /* retrieve the current active SC */
            StatementContext sc = lcc.getStatementContext();
            /* make sure that the cleanup is on the new SC */
            if (sc != null && active_sc != sc) {
                sc.cleanupOnError(e);
            }
            /* Handle dynamic recompiles */
            if (e.getMessageId().equals(SQLState.LANG_STATEMENT_NEEDS_RECOMPILE)) {
                recompile = true;
                sps.revalidate(lcc);
                continue;
            }
            spsActivation.close();
            throw e;
        }
        /* Done with execution without any recompiles */
        return whenClauseWasTrue;
    }
}
Also used : StandardException(org.apache.derby.shared.common.error.StandardException) ExecPreparedStatement(org.apache.derby.iapi.sql.execute.ExecPreparedStatement) ResultSet(org.apache.derby.iapi.sql.ResultSet) CursorResultSet(org.apache.derby.iapi.sql.execute.CursorResultSet) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) Activation(org.apache.derby.iapi.sql.Activation) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) SQLBoolean(org.apache.derby.iapi.types.SQLBoolean) StatementContext(org.apache.derby.iapi.sql.conn.StatementContext)

Example 25 with StatementContext

use of org.apache.derby.iapi.sql.conn.StatementContext in project derby by apache.

the class DropSchemaNode method bindStatement.

@Override
public void bindStatement() throws StandardException {
    /* 
		** Users are not permitted to drop
		** the SYS or APP schemas.
		*/
    if (getDataDictionary().isSystemSchemaName(schemaName)) {
        throw (StandardException.newException(SQLState.LANG_CANNOT_DROP_SYSTEM_SCHEMAS, this.schemaName));
    }
    /* 
        ** In SQL authorization mode, the current authorization identifier
        ** must be either the owner of the schema or the database owner 
        ** in order for the schema object to be dropped.
        */
    if (isPrivilegeCollectionRequired()) {
        LanguageConnectionContext lcc = getLanguageConnectionContext();
        StatementContext stx = lcc.getStatementContext();
        String currentUser = stx.getSQLSessionContext().getCurrentUser();
        getCompilerContext().addRequiredSchemaPriv(schemaName, currentUser, Authorizer.DROP_SCHEMA_PRIV);
    }
}
Also used : LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) StatementContext(org.apache.derby.iapi.sql.conn.StatementContext)

Aggregations

StatementContext (org.apache.derby.iapi.sql.conn.StatementContext)26 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)9 Activation (org.apache.derby.iapi.sql.Activation)5 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)5 ResultSet (org.apache.derby.iapi.sql.ResultSet)4 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)4 SQLWarning (java.sql.SQLWarning)3 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)3 SQLSessionContext (org.apache.derby.iapi.sql.conn.SQLSessionContext)3 CursorActivation (org.apache.derby.iapi.sql.execute.CursorActivation)3 TransactionController (org.apache.derby.iapi.store.access.TransactionController)3 XATransactionController (org.apache.derby.iapi.store.access.XATransactionController)3 StandardException (org.apache.derby.shared.common.error.StandardException)3 DataTruncation (java.sql.DataTruncation)2 GeneratedClass (org.apache.derby.iapi.services.loader.GeneratedClass)2 ResultDescription (org.apache.derby.iapi.sql.ResultDescription)2 ExecCursorTableReference (org.apache.derby.iapi.sql.execute.ExecCursorTableReference)2 Timestamp (java.sql.Timestamp)1 List (java.util.List)1 UUID (org.apache.derby.catalog.UUID)1