All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.voltdb.exceptions.ConstraintFailureException Maven / Gradle / Ivy

/* This file is part of VoltDB.
 * Copyright (C) 2008-2020 VoltDB Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with VoltDB.  If not, see .
 */

package org.voltdb.exceptions;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.logging.Logger;

import org.voltdb.PrivateVoltTableFactory;
import org.voltdb.VoltDB;
import org.voltdb.VoltTable;
import org.voltdb.client.ClientResponse;
import org.voltdb.messaging.FastDeserializer;
import org.voltdb.types.ConstraintType;

/**
 * Exception generated when a constraint is violated. Contains more information then a SQLException.
 *
 */
public class ConstraintFailureException extends SQLException {

    protected static final Logger LOG = Logger.getLogger(ConstraintFailureException.class.getName());

    /**
     * Constructor for deserializing an exception returned from the EE.
     * @param exceptionBuffer
     */
    public ConstraintFailureException(ByteBuffer exceptionBuffer) {
        super(exceptionBuffer);
        type = ConstraintType.get(exceptionBuffer.getInt());
        try {
            tableName = FastDeserializer.readString(exceptionBuffer);
        }
        catch (IOException e) {
            // implies that the EE created an invalid constraint
            // failure, which would be a corruption/defect.
            VoltDB.crashLocalVoltDB(e.getMessage(), true, e);
        }
        if (exceptionBuffer.hasRemaining()) {
            int tableSize = exceptionBuffer.getInt();
            buffer = ByteBuffer.allocate(tableSize);
            //Copy the exception details.
            exceptionBuffer.get(buffer.array());
        } else {
            buffer = ByteBuffer.allocate(0);
        }
    }

    /**
     * Get the type of constraint violation that occurred
     * @return Type of constraint violation
     */
    public ConstraintType getType() {
        return type;
    }

    public String getTableName() {
        return tableName;
    }

    /**
     * Get the table containing the involved tuples (target and source) that caused the constraint violation.
     */
    public VoltTable getTuples() {
        if (table != null) {
            return table;
        }

        table = PrivateVoltTableFactory.createVoltTableFromSharedBuffer(buffer);

        return table;
    }

    /**
     * ByteBuffer containing a serialized copy of a table with the tuples involved in the constraint violation
     */
    private final ByteBuffer buffer;

    /**
     * Type of constraint violation that caused this exception to be thrown
     */
    private final ConstraintType type;

    /**
     * Name of the table that the constraint violation occurred in.
     */
    private String tableName = null;

    /**
     * Lazy deserialized copy of a table with the tuples involved in the constraint violation
     */
    private VoltTable table = null;

    @Override
    public String getMessage() {
        if (buffer.capacity() == 0) {
            return super.getMessage();
        } else {
            StringBuilder sb = new StringBuilder(super.getMessage());
            sb.append('\n');
            sb.append("Constraint Type ");
            sb.append(type);
            sb.append(", Table CatalogId ");
            sb.append(tableName);
            sb.append('\n');
            sb.append("Relevant Tuples:\n");
            sb.append(getTuples().toFormattedString());
            // remove trailing whitespace
            while (Character.isWhitespace(sb.charAt(sb.length() - 1))) {
                sb.setLength(sb.length() - 1);
            }
            return sb.toString();
        }
    }
    /**
     * Retrieve a string representation of the exception. If this is a rethrown HSQLDB exception it returns the enclosed exceptions
     * string. Otherwise a new string is generated with the details of the constraint violation.
     */
    @Override
    public String toString() {
        return getMessage();
    }

    @Override
    protected SerializableExceptions getExceptionType() {
        return SerializableExceptions.ConstraintFailureException;
    }

    @Override
    public byte getClientResponseStatus() {
        return ClientResponse.GRACEFUL_FAILURE;
    }

    @Override
    public String getShortStatusString() {
        return "CONSTRAINT VIOLATION";
    }

    @Override
    protected int p_getSerializedSize() {
        // ... + 8 + string prefix + string length + ...
        return super.p_getSerializedSize()
            + 4 // constraint type
            + 4 // table name string length
            + tableName.length()
            + 4 // buffer length
            + buffer.capacity();
    }

    @Override
    protected void p_serializeToBuffer(ByteBuffer b) {
        super.p_serializeToBuffer(b);
        b.putInt(type.getValue());
        b.putInt(tableName.length());
        b.put(tableName.getBytes());
        b.putInt(buffer.capacity());
        buffer.rewind();
        b.put(buffer);
    }

    /**
     *
     */
    private static final long serialVersionUID = 1L;

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy