alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

HSQLDB example source code file (CompiledStatementExecutor.java)

This example HSQLDB source code file (CompiledStatementExecutor.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - HSQLDB tags/keywords

compiledstatementexecutor, expression, expression, hashmappedlist, hsqlarraylist, hsqlexception, hsqlexception, object, object, result, result, select, table, tablefilter

The HSQLDB CompiledStatementExecutor.java source code

/* Copyright (c) 2001-2008, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


package org.hsqldb;

import org.hsqldb.jdbc.jdbcResultSet;
import org.hsqldb.lib.HashMappedList;
import org.hsqldb.lib.HsqlArrayList;
import org.hsqldb.lib.java.JavaSystem;

// boucherb@users 200404xx - fixed broken CALL statement result set unwrapping;
//                           fixed broken support for prepared SELECT...INTO

/**
 * Provides execution of CompiledStatement objects. <p>
 *
 * If multiple threads access a CompiledStatementExecutor.execute()
 * concurrently, they must be synchronized externally, relative to both
 * this object's Session and the Session's Database object. Internally, this
 * is accomplished in Session.execute() by synchronizing on the Session
 * object's Database object.
 *
 * @author  boucherb@users
 * @version 1.7.2
 * @since 1.7.2
 */
final class CompiledStatementExecutor {

    private Session session;
    private Result  updateResult;
    private static Result emptyZeroResult =
        new Result(ResultConstants.UPDATECOUNT);
    private static Result updateOneResult =
        new Result(ResultConstants.UPDATECOUNT);

    static {
        updateOneResult.updateCount = 1;
    }

    /**
     * Creates a new instance of CompiledStatementExecutor.
     *
     * @param session the context in which to perform the execution
     */
    CompiledStatementExecutor(Session session) {
        this.session = session;
        updateResult = new Result(ResultConstants.UPDATECOUNT);
    }

    /**
     * Executes a generic CompiledStatement. Execution includes first building
     * any subquery result dependencies and clearing them after the main result
     * is built.
     *
     * @return the result of executing the statement
     * @param cs any valid CompiledStatement
     */
    Result execute(CompiledStatement cs, Object[] paramValues) {

        Result result = null;

        JavaSystem.gc();

        for (int i = 0; i < cs.parameters.length; i++) {
            cs.parameters[i].bind(paramValues[i]);
        }

        try {
            cs.materializeSubQueries(session);

            result = executeImpl(cs);
        } catch (Throwable t) {
            result = new Result(t, cs.sql);
        }

        // clear redundant data
        cs.dematerializeSubQueries(session);

        if (result == null) {
            result = emptyZeroResult;
        }

        return result;
    }

    /**
     * Executes a generic CompiledStatement. Execution excludes building
     * subquery result dependencies and clearing them after the main result
     * is built.
     *
     * @param cs any valid CompiledStatement
     * @throws HsqlException if a database access error occurs
     * @return the result of executing the statement
     */
    private Result executeImpl(CompiledStatement cs) throws HsqlException {

        switch (cs.type) {

            case CompiledStatement.SELECT :
                return executeSelectStatement(cs);

            case CompiledStatement.INSERT_SELECT :
                return executeInsertSelectStatement(cs);

            case CompiledStatement.INSERT_VALUES :
                return executeInsertValuesStatement(cs);

            case CompiledStatement.UPDATE :
                return executeUpdateStatement(cs);

            case CompiledStatement.DELETE :
                return executeDeleteStatement(cs);

            case CompiledStatement.CALL :
                return executeCallStatement(cs);

            case CompiledStatement.DDL :
                return executeDDLStatement(cs);

            default :
                throw Trace.runtimeError(
                    Trace.UNSUPPORTED_INTERNAL_OPERATION,
                    "CompiledStatementExecutor.executeImpl()");
        }
    }

    /**
     * Executes a CALL statement.  It is assumed that the argument is
     * of the correct type.
     *
     * @param cs a CompiledStatement of type CompiledStatement.CALL
     * @throws HsqlException if a database access error occurs
     * @return the result of executing the statement
     */
    private Result executeCallStatement(CompiledStatement cs)
    throws HsqlException {

        Expression e = cs.expression;          // representing CALL
        Object     o = e.getValue(session);    // expression return value
        Result     r;

        if (o instanceof Result) {
            return (Result) o;
        } else if (o instanceof jdbcResultSet) {
            return ((jdbcResultSet) o).rResult;
        }

        r = Result.newSingleColumnResult(CompiledStatement.RETURN_COLUMN_NAME,
                                         e.getDataType());

        Object[] row = new Object[1];

        row[0]                   = o;
        r.metaData.classNames[0] = e.getValueClassName();

        r.add(row);

        return r;
    }

// fredt - currently deletes that fail due to referential constraints are caught prior to
// actual delete operation, so no nested transaction is required

    /**
     * Executes a DELETE statement.  It is assumed that the argument is
     * of the correct type.
     *
     * @param cs a CompiledStatement of type CompiledStatement.DELETE
     * @throws HsqlException if a database access error occurs
     * @return the result of executing the statement
     */
    private Result executeDeleteStatement(CompiledStatement cs)
    throws HsqlException {

        Table       table  = cs.targetTable;
        TableFilter filter = cs.targetFilter;
        int         count  = 0;

        if (filter.findFirst(session)) {
            Expression    c = cs.condition;
            HsqlArrayList del;

            del = new HsqlArrayList();

            do {
                if (c == null || c.testCondition(session)) {
                    del.add(filter.currentRow);
                }
            } while (filter.next(session));

            count = table.delete(session, del);
        }

        updateResult.updateCount = count;

        return updateResult;
    }

    /**
     * Executes an INSERT_SELECT statement.  It is assumed that the argument
     * is of the correct type.
     *
     * @param cs a CompiledStatement of type CompiledStatement.INSERT_SELECT
     * @throws HsqlException if a database access error occurs
     * @return the result of executing the statement
     */
    private Result executeInsertSelectStatement(CompiledStatement cs)
    throws HsqlException {

        Table     t   = cs.targetTable;
        Select    s   = cs.select;
        int[]     ct  = t.getColumnTypes();    // column types
        Result    r   = s.getResult(session, Integer.MAX_VALUE);
        Record    rc  = r.rRoot;
        int[]     cm  = cs.columnMap;          // column map
        boolean[] ccl = cs.checkColumns;       // column check list
        int       len = cm.length;
        Object[]  row;
        int       count;
        boolean   success = false;

        session.beginNestedTransaction();

        try {
            while (rc != null) {
                row = t.getNewRowData(session, ccl);

                for (int i = 0; i < len; i++) {
                    int j = cm[i];

                    if (ct[j] != r.metaData.colTypes[i]) {
                        row[j] = Column.convertObject(rc.data[i], ct[j]);
                    } else {
                        row[j] = rc.data[i];
                    }
                }

                rc.data = row;
                rc      = rc.next;
            }

            count   = t.insert(session, r);
            success = true;
        } finally {
            session.endNestedTransaction(!success);
        }

        updateResult.updateCount = count;

        return updateResult;
    }

    /**
     * Executes an INSERT_VALUES statement.  It is assumed that the argument
     * is of the correct type.
     *
     * @param cs a CompiledStatement of type CompiledStatement.INSERT_VALUES
     * @throws HsqlException if a database access error occurs
     * @return the result of executing the statement
     */
    private Result executeInsertValuesStatement(CompiledStatement cs)
    throws HsqlException {

        Table        t    = cs.targetTable;
        Object[]     row  = t.getNewRowData(session, cs.checkColumns);
        int[]        cm   = cs.columnMap;        // column map
        Expression[] acve = cs.columnValues;
        Expression   cve;
        int[]        ct = t.getColumnTypes();    // column types
        int          ci;                         // column index
        int          len = acve.length;

        for (int i = 0; i < len; i++) {
            cve     = acve[i];
            ci      = cm[i];
            row[ci] = cve.getValue(session, ct[ci]);
        }

        t.insert(session, row);

        return updateOneResult;
    }

    /**
     * Executes a SELECT statement.  It is assumed that the argument
     * is of the correct type.
     *
     * @param cs a CompiledStatement of type CompiledStatement.SELECT
     * @throws HsqlException if a database access error occurs
     * @return the result of executing the statement
     */
    private Result executeSelectStatement(CompiledStatement cs)
    throws HsqlException {

        Select select = cs.select;
        Result result;

        if (select.sIntoTable != null) {

            // session level user rights
            session.checkDDLWrite();

            boolean exists =
                session.database.schemaManager.findUserTable(
                    session, select.sIntoTable.name,
                    select.sIntoTable.schema.name) != null;

            if (exists) {
                throw Trace.error(Trace.TABLE_ALREADY_EXISTS,
                                  select.sIntoTable.name);
            }

            result = select.getResult(session, Integer.MAX_VALUE);
            result = session.dbCommandInterpreter.processSelectInto(result,
                    select.sIntoTable, select.intoType);

            session.getDatabase().setMetaDirty(false);
        } else {
            result = select.getResult(session, session.getMaxRows());
        }

        return result;
    }

    /**
     * Executes an UPDATE statement.  It is assumed that the argument
     * is of the correct type.
     *
     * @param cs a CompiledStatement of type CompiledStatement.UPDATE
     * @throws HsqlException if a database access error occurs
     * @return the result of executing the statement
     */
    private Result executeUpdateStatement(CompiledStatement cs)
    throws HsqlException {

        Table       table  = cs.targetTable;
        TableFilter filter = cs.targetFilter;
        int         count  = 0;

        if (filter.findFirst(session)) {
            int[]          colmap    = cs.columnMap;    // column map
            Expression[]   colvalues = cs.columnValues;
            Expression     condition = cs.condition;    // update condition
            int            len       = colvalues.length;
            HashMappedList rowset    = new HashMappedList();
            int            size      = table.getColumnCount();
            int[]          coltypes  = table.getColumnTypes();
            boolean        success   = false;

            do {
                if (condition == null || condition.testCondition(session)) {
                    try {
                        Row      row = filter.currentRow;
                        Object[] ni  = table.getEmptyRowData();

                        System.arraycopy(row.getData(), 0, ni, 0, size);

                        for (int i = 0; i < len; i++) {
                            int ci = colmap[i];

                            ni[ci] = colvalues[i].getValue(session,
                                                           coltypes[ci]);
                        }

                        rowset.add(row, ni);
                    } catch (HsqlInternalException e) {}
                }
            } while (filter.next(session));

            session.beginNestedTransaction();

            try {
                count   = table.update(session, rowset, colmap);
                success = true;
            } finally {

                // update failed (constraint violation) or succeeded
                session.endNestedTransaction(!success);
            }
        }

        updateResult.updateCount = count;

        return updateResult;
    }

    /**
     * Executes a DDL statement.  It is assumed that the argument
     * is of the correct type.
     *
     * @param cs a CompiledStatement of type CompiledStatement.DDL
     * @throws HsqlException if a database access error occurs
     * @return the result of executing the statement
     */
    private Result executeDDLStatement(CompiledStatement cs)
    throws HsqlException {
        return session.sqlExecuteDirectNoPreChecks(cs.sql);
    }
}

Other HSQLDB examples (source code examples)

Here is a short list of links related to this HSQLDB CompiledStatementExecutor.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.