Search in sources :

Example 1 with SpecifiedException

use of org.voltdb.exceptions.SpecifiedException in project voltdb by VoltDB.

the class SysprocFragmentTask method processFragmentTask.

// Extracted the sysproc portion of ExecutionSite processFragmentTask(), then
// modified to work in the new world
public FragmentResponseMessage processFragmentTask(SiteProcedureConnection siteConnection) {
    final FragmentResponseMessage currentFragResponse = new FragmentResponseMessage(m_fragmentMsg, m_initiator.getHSId());
    currentFragResponse.setStatus(FragmentResponseMessage.SUCCESS, null);
    for (int frag = 0; frag < m_fragmentMsg.getFragmentCount(); frag++) {
        final long fragmentId = VoltSystemProcedure.hashToFragId(m_fragmentMsg.getPlanHash(frag));
        // equivalent to dep.depId:
        // final int outputDepId = m_fragmentMsg.getOutputDepId(frag);
        final VoltTrace.TraceEventBatch traceLog = VoltTrace.log(VoltTrace.Category.SPSITE);
        if (traceLog != null) {
            traceLog.add(() -> VoltTrace.beginDuration("runfragmenttask", "txnId", TxnEgo.txnIdToString(getTxnId()), "partition", Integer.toString(siteConnection.getCorrespondingPartitionId()), "fragmentId", String.valueOf(fragmentId)));
        }
        ParameterSet params = m_fragmentMsg.getParameterSetForFragment(frag);
        try {
            // run the overloaded sysproc planfragment. pass an empty dependency
            // set since remote (non-aggregator) fragments don't receive dependencies.
            final DependencyPair dep = siteConnection.executeSysProcPlanFragment(m_txnState, m_inputDeps, fragmentId, params);
            // @Shutdown returns null, handle it here
            if (dep != null) {
                currentFragResponse.addDependency(dep);
            }
        } catch (final EEException e) {
            hostLog.l7dlog(Level.TRACE, LogKeys.host_ExecutionSite_ExceptionExecutingPF.name(), new Object[] { Encoder.hexEncode(m_fragmentMsg.getFragmentPlan(frag)) }, e);
            currentFragResponse.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, e);
            if (currentFragResponse.getTableCount() == 0) {
                // Make sure the response has at least 1 result with a valid DependencyId
                currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(m_fragmentMsg.getOutputDepId(0), m_rawDummyResult, 0, m_rawDummyResult.length));
            }
            break;
        } catch (final SQLException e) {
            hostLog.l7dlog(Level.TRACE, LogKeys.host_ExecutionSite_ExceptionExecutingPF.name(), new Object[] { Encoder.hexEncode(m_fragmentMsg.getFragmentPlan(frag)) }, e);
            currentFragResponse.setStatus(FragmentResponseMessage.UNEXPECTED_ERROR, e);
            if (currentFragResponse.getTableCount() == 0) {
                // Make sure the response has at least 1 result with a valid DependencyId
                currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(m_fragmentMsg.getOutputDepId(0), m_rawDummyResult, 0, m_rawDummyResult.length));
            }
            break;
        } catch (final SpecifiedException e) {
            // Note that with SpecifiedException, the error code here might get changed before
            // the client/user sees it. It really just needs to indicate failure.
            //
            // Key point here vs the next catch block for VAE is to not wrap the subclass of
            // SerializableException here to preserve it during the serialization.
            //
            currentFragResponse.setStatus(FragmentResponseMessage.USER_ERROR, e);
            if (currentFragResponse.getTableCount() == 0) {
                // Make sure the response has at least 1 result with a valid DependencyId
                currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(m_fragmentMsg.getOutputDepId(0), m_rawDummyResult, 0, m_rawDummyResult.length));
            }
        } catch (final VoltAbortException e) {
            currentFragResponse.setStatus(FragmentResponseMessage.USER_ERROR, new SerializableException(CoreUtils.throwableToString(e)));
            if (currentFragResponse.getTableCount() == 0) {
                // Make sure the response has at least 1 result with a valid DependencyId
                currentFragResponse.addDependency(new DependencyPair.BufferDependencyPair(m_fragmentMsg.getOutputDepId(0), m_rawDummyResult, 0, m_rawDummyResult.length));
            }
            break;
        }
        if (traceLog != null) {
            traceLog.add(VoltTrace::endDuration);
        }
    }
    return currentFragResponse;
}
Also used : ParameterSet(org.voltdb.ParameterSet) VoltTrace(org.voltdb.utils.VoltTrace) SQLException(org.voltdb.exceptions.SQLException) SpecifiedException(org.voltdb.exceptions.SpecifiedException) SerializableException(org.voltdb.exceptions.SerializableException) FragmentResponseMessage(org.voltdb.messaging.FragmentResponseMessage) EEException(org.voltdb.exceptions.EEException) DependencyPair(org.voltdb.DependencyPair) VoltAbortException(org.voltdb.VoltProcedure.VoltAbortException)

Example 2 with SpecifiedException

use of org.voltdb.exceptions.SpecifiedException in project voltdb by VoltDB.

the class ProcedureRunner method getErrorResponse.

/**
    *
    * @param e
    * @return A ClientResponse containing error information
    */
public static ClientResponseImpl getErrorResponse(String procedureName, boolean readOnly, int individualTimeout, byte appStatus, String appStatusString, NonVoltDBBackend nonVoltDBBackend, Throwable eIn) {
    // use local var to avoid warnings about reassigning method argument
    Throwable e = eIn;
    boolean expected_failure = true;
    boolean hideStackTrace = false;
    StackTraceElement[] stack = e.getStackTrace();
    ArrayList<StackTraceElement> matches = new ArrayList<StackTraceElement>();
    for (StackTraceElement ste : stack) {
        if (isProcedureStackTraceElement(procedureName, ste)) {
            matches.add(ste);
        }
    }
    byte status = ClientResponse.UNEXPECTED_FAILURE;
    StringBuilder msg = new StringBuilder();
    if (e.getClass() == VoltAbortException.class) {
        status = ClientResponse.USER_ABORT;
        msg.append("USER ABORT\n");
    } else if (e.getClass() == org.voltdb.exceptions.ConstraintFailureException.class) {
        status = ClientResponse.GRACEFUL_FAILURE;
        msg.append("CONSTRAINT VIOLATION\n");
    } else if (e.getClass() == org.voltdb.exceptions.SQLException.class) {
        status = ClientResponse.GRACEFUL_FAILURE;
        msg.append("SQL ERROR\n");
    } else // or by a timeout in the middle of executing.
    if (e.getClass() == org.voltdb.exceptions.InterruptException.class) {
        status = ClientResponse.GRACEFUL_FAILURE;
        msg.append("Transaction Interrupted\n");
    } else if (e.getClass() == org.voltdb.ExpectedProcedureException.class) {
        String backendType = "HSQL";
        if (nonVoltDBBackend instanceof PostgreSQLBackend) {
            backendType = "PostgreSQL";
        }
        msg.append(backendType);
        msg.append("-BACKEND ERROR\n");
        if (e.getCause() != null) {
            e = e.getCause();
        }
    } else if (e.getClass() == org.voltdb.exceptions.TransactionRestartException.class) {
        status = ClientResponse.TXN_RESTART;
        msg.append("TRANSACTION RESTART\n");
    } else // SpecifiedException means the dev wants control over status and message
    if (e.getClass() == SpecifiedException.class) {
        SpecifiedException se = (SpecifiedException) e;
        status = se.getStatus();
        expected_failure = true;
        hideStackTrace = true;
    } else {
        msg.append("UNEXPECTED FAILURE:\n");
        expected_failure = false;
    }
    // ensure the message is returned if we're not going to hit the verbose condition below
    if (expected_failure || hideStackTrace) {
        msg.append("  ").append(e.getMessage());
        if (e instanceof org.voltdb.exceptions.InterruptException && readOnly) {
            int originalTimeout = VoltDB.instance().getConfig().getQueryTimeout();
            if (BatchTimeoutOverrideType.isUserSetTimeout(individualTimeout)) {
                msg.append(" query-specific timeout period.");
                msg.append(" The query-specific timeout is currently " + individualTimeout / 1000.0 + " seconds.");
            } else {
                msg.append(" default query timeout period.");
            }
            if (originalTimeout > 0) {
                msg.append(" The default query timeout is currently " + originalTimeout / 1000.0 + " seconds and can be changed in the systemsettings section of the deployment file.");
            } else if (originalTimeout == 0) {
                msg.append(" The default query timeout is currently set to no timeout and can be changed in the systemsettings section of the deployment file.");
            }
        }
    }
    // known and not helpful to the user.
    if (!hideStackTrace) {
        // Otherwise, generate more output for debuggability
        if (expected_failure) {
            for (StackTraceElement ste : matches) {
                msg.append("\n    at ");
                msg.append(ste.getClassName()).append(".").append(ste.getMethodName());
                msg.append("(").append(ste.getFileName()).append(":");
                msg.append(ste.getLineNumber()).append(")");
            }
        } else {
            Writer result = new StringWriter();
            PrintWriter pw = new PrintWriter(result);
            e.printStackTrace(pw);
            msg.append("  ").append(result.toString());
        }
    }
    return getErrorResponse(status, appStatus, appStatusString, msg.toString(), e instanceof SerializableException ? (SerializableException) e : null);
}
Also used : SpecifiedException(org.voltdb.exceptions.SpecifiedException) ArrayList(java.util.ArrayList) SerializableException(org.voltdb.exceptions.SerializableException) StringWriter(java.io.StringWriter) PrintWriter(java.io.PrintWriter) Writer(java.io.Writer) StringWriter(java.io.StringWriter) PrintWriter(java.io.PrintWriter)

Example 3 with SpecifiedException

use of org.voltdb.exceptions.SpecifiedException in project voltdb by VoltDB.

the class UpdateCore method checkForNonEmptyTables.

/**
     * Use EE stats to get the row counts for all tables in this partition.
     * Check the provided list of tables that need to be empty against actual
     * row counts. If any of them aren't empty, stop the catalog update and
     * return the pre-provided error message that corresponds to the non-empty
     * tables.
     *
     * Each of the tablesThatMustBeEmpty strings represents a set of tables.
     * This is is a sequence of names separated by plus signs (+).  For example,
     * "A+B+C" is the set {A, B, C}, and "A" is the singleton set {A}.  In
     * these sets, only one needs to be empty.
     *
     * @param tablesThatMustBeEmpty List of sets of table names that must include
     *                              an empty table.
     * @param reasonsForEmptyTables Error messages to return if that table isn't
     * empty.
     * @param context
     */
protected void checkForNonEmptyTables(String[] tablesThatMustBeEmpty, String[] reasonsForEmptyTables, SystemProcedureExecutionContext context) {
    assert (tablesThatMustBeEmpty != null);
    // no work to do if no tables need to be empty
    if (tablesThatMustBeEmpty.length == 0) {
        return;
    }
    assert (reasonsForEmptyTables != null);
    assert (reasonsForEmptyTables.length == tablesThatMustBeEmpty.length);
    // fetch the id of the tables that must be empty from the
    //  current catalog (not the new one).
    CatalogMap<Table> tables = context.getDatabase().getTables();
    List<List<String>> allTableSets = decodeTables(tablesThatMustBeEmpty);
    Map<String, Boolean> allTables = collapseSets(allTableSets);
    int[] tableIds = new int[allTables.size()];
    int i = 0;
    for (String tableName : allTables.keySet()) {
        Table table = tables.get(tableName);
        if (table == null) {
            String msg = String.format("@UpdateCore was checking to see if table %s was empty, " + "presumably as part of a schema change, and it failed to find the table " + "in the current catalog context.", tableName);
            throw new SpecifiedException(ClientResponse.UNEXPECTED_FAILURE, msg);
        }
        tableIds[i++] = table.getRelativeIndex();
    }
    // get the table stats for these tables from the EE
    final VoltTable[] s1 = context.getSiteProcedureConnection().getStats(StatsSelector.TABLE, tableIds, false, getTransactionTime().getTime());
    if ((s1 == null) || (s1.length == 0)) {
        String tableNames = StringUtils.join(tablesThatMustBeEmpty, ", ");
        String msg = String.format("@UpdateCore was checking to see if tables (%s) were empty ," + "presumably as part of a schema change, but failed to get the row counts " + "from the native storage engine.", tableNames);
        throw new SpecifiedException(ClientResponse.UNEXPECTED_FAILURE, msg);
    }
    VoltTable stats = s1[0];
    // find all empty tables and mark that they are empty.
    while (stats.advanceRow()) {
        long tupleCount = stats.getLong("TUPLE_COUNT");
        String tableName = stats.getString("TABLE_NAME");
        boolean isEmpty = true;
        if (tupleCount > 0 && !"StreamedTable".equals(stats.getString("TABLE_TYPE"))) {
            isEmpty = false;
        }
        allTables.put(tableName.toUpperCase(), isEmpty);
    }
    // Reexamine the sets of sets and see if any of them has
    // one empty element.  If not, then add the respective
    // error message to the output message
    String msg = "Unable to make requested schema change:\n";
    boolean allOk = true;
    for (int idx = 0; idx < allTableSets.size(); idx += 1) {
        List<String> tableNames = allTableSets.get(idx);
        boolean allNonEmpty = true;
        for (String tableName : tableNames) {
            Boolean oneEmpty = allTables.get(tableName);
            if (oneEmpty != null && oneEmpty) {
                allNonEmpty = false;
                break;
            }
        }
        if (allNonEmpty) {
            String errMsg = reasonsForEmptyTables[idx];
            msg += errMsg + "\n";
            allOk = false;
        }
    }
    if (!allOk) {
        throw new SpecifiedException(ClientResponse.GRACEFUL_FAILURE, msg);
    }
}
Also used : Table(org.voltdb.catalog.Table) VoltTable(org.voltdb.VoltTable) SpecifiedException(org.voltdb.exceptions.SpecifiedException) VoltTable(org.voltdb.VoltTable) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

SpecifiedException (org.voltdb.exceptions.SpecifiedException)3 ArrayList (java.util.ArrayList)2 SerializableException (org.voltdb.exceptions.SerializableException)2 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 Writer (java.io.Writer)1 List (java.util.List)1 DependencyPair (org.voltdb.DependencyPair)1 ParameterSet (org.voltdb.ParameterSet)1 VoltAbortException (org.voltdb.VoltProcedure.VoltAbortException)1 VoltTable (org.voltdb.VoltTable)1 Table (org.voltdb.catalog.Table)1 EEException (org.voltdb.exceptions.EEException)1 SQLException (org.voltdb.exceptions.SQLException)1 FragmentResponseMessage (org.voltdb.messaging.FragmentResponseMessage)1 VoltTrace (org.voltdb.utils.VoltTrace)1