You are viewing a plain text version of this content. The canonical link for it is here.
Posted to codereview@trafodion.apache.org by mashengchen <gi...@git.apache.org> on 2018/04/23 08:38:02 UTC

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

GitHub user mashengchen opened a pull request:

    https://github.com/apache/trafodion/pull/1535

    TRAFODION-2957 one stmt support multi-queries

    1. reconstitute the constructor of TrafT4Statement & TrafT4PreparedStatement
    2. add new property allowMultiQueries to support exec multi-queries in one statement
    3. new class extends from TrafT4Statement & TrafT4PreparedStatement to exec multi-queries

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/mashengchen/trafodion TRAFODION-2957

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/trafodion/pull/1535.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #1535
    
----
commit 414c71753ce2b6c260b6525ed46e1c1bb8aba865
Author: aven <sh...@...>
Date:   2018-04-23T08:30:20Z

    TRAFODION-2957 one stmt support multi-queries

----


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by selvaganesang <gi...@git.apache.org>.
Github user selvaganesang commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r184096949
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,393 @@
    +// @@@ START COPYRIGHT @@@
    +//
    +// Licensed to the Apache Software Foundation (ASF) under one
    +// or more contributor license agreements.  See the NOTICE file
    +// distributed with this work for additional information
    +// regarding copyright ownership.  The ASF licenses this file
    +// to you under the Apache License, Version 2.0 (the
    +// "License"); you may not use this file except in compliance
    +// with the License.  You may obtain a copy of the License at
    +//
    +//   http://www.apache.org/licenses/LICENSE-2.0
    +//
    +// Unless required by applicable law or agreed to in writing,
    +// software distributed under the License is distributed on an
    +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    +// KIND, either express or implied.  See the License for the
    +// specific language governing permissions and limitations
    +// under the License.
    +//
    +// @@@ END COPYRIGHT @@@
    +
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    +        pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
    +        paramDescs = new int[sqlArr.length][3];
    +        int total = 0;
    +        int currentParamsLen = 0;
    +        for (int i = 0; i < sqlArr.length; i++) {
    +            pstmtArr[i] = new TrafT4PreparedStatement(connection, sqlArr[i], resultSetType, resultSetConcurrency,
    +                    resultSetHoldability, stmtLabel);
    +            pstmtArr[i].prepare(sqlArr[i], queryTimeout_, resultSetHoldability_);
    +
    +            // this is to setup the paramDescs, each paramDesc has 3 column,
    +            // 1: index of preparedStatement
    +            // 2: num of params for current pstmt
    +            // 3: accumulated params for current index
    +            // this varible is used when there invoking setXXX api
    +            if (pstmtArr[i].inputDesc_ != null) {
    +                currentParamsLen = pstmtArr[i].inputDesc_.length;
    +                total += currentParamsLen;
    +            }
    +            int[] paramDesc = { i, currentParamsLen, total };
    +            paramDescs[i] = paramDesc;
    +
    +        }
    +    }
    +
    +    public boolean execute(String sql) throws SQLException {
    --- End diff --
    
    It could be valid from interface inheritance point of view. However, the JDBC specification  clearly says the following
    
    boolean execute(String sql)
                    throws SQLException
    Note:This method cannot be called on a PreparedStatement or CallableStatement.
    
    It is not a Trafodion restriction. It is against the intent of PreparedStatement functionality as per the specification, 
    
    All other flavors of execute call in Statement object can't be called in PreparedStatement or CallableStatement.


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by selvaganesang <gi...@git.apache.org>.
Github user selvaganesang commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r183744482
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,372 @@
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    --- End diff --
    
    You could search for the standalone ';' and ignore ';' when it is within a single quote.


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by selvaganesang <gi...@git.apache.org>.
Github user selvaganesang commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r184102393
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,372 @@
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    --- End diff --
    
    As per specification we should be allowing literals as part of the SQL.  I guess Trafodion SQL engine shouldn't be allowing the variables like $PARAM1 to be substituted on the fly in the query. If Trafodion did, it should be validated sufficiently not to allow the manipulation of the query via these variables


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by mashengchen <gi...@git.apache.org>.
Github user mashengchen commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r185398568
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,393 @@
    +// @@@ START COPYRIGHT @@@
    +//
    +// Licensed to the Apache Software Foundation (ASF) under one
    +// or more contributor license agreements.  See the NOTICE file
    +// distributed with this work for additional information
    +// regarding copyright ownership.  The ASF licenses this file
    +// to you under the Apache License, Version 2.0 (the
    +// "License"); you may not use this file except in compliance
    +// with the License.  You may obtain a copy of the License at
    +//
    +//   http://www.apache.org/licenses/LICENSE-2.0
    +//
    +// Unless required by applicable law or agreed to in writing,
    +// software distributed under the License is distributed on an
    +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    +// KIND, either express or implied.  See the License for the
    +// specific language governing permissions and limitations
    +// under the License.
    +//
    +// @@@ END COPYRIGHT @@@
    +
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    +        pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
    +        paramDescs = new int[sqlArr.length][3];
    +        int total = 0;
    +        int currentParamsLen = 0;
    +        for (int i = 0; i < sqlArr.length; i++) {
    +            pstmtArr[i] = new TrafT4PreparedStatement(connection, sqlArr[i], resultSetType, resultSetConcurrency,
    +                    resultSetHoldability, stmtLabel);
    +            pstmtArr[i].prepare(sqlArr[i], queryTimeout_, resultSetHoldability_);
    +
    +            // this is to setup the paramDescs, each paramDesc has 3 column,
    +            // 1: index of preparedStatement
    +            // 2: num of params for current pstmt
    +            // 3: accumulated params for current index
    +            // this varible is used when there invoking setXXX api
    +            if (pstmtArr[i].inputDesc_ != null) {
    +                currentParamsLen = pstmtArr[i].inputDesc_.length;
    +                total += currentParamsLen;
    +            }
    +            int[] paramDesc = { i, currentParamsLen, total };
    +            paramDescs[i] = paramDesc;
    +
    +        }
    +    }
    +
    +    public boolean execute(String sql) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "execute", "", p);
    +        }
    +        sqlArr = sql.split(";");
    +        pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
    +
    +        boolean result = false;
    +
    +        return result;
    +    }
    +
    +    // this method will return a 2 column array.
    +    // first column means the index of preparedStatement
    +    // second column means the real parameter index of the column one preparedStatement
    +    // eg:
    +    // insert into tbl values (?,?);insert into tbl values (?,?,?);insert into tbl values (?,?)
    +    // the paramDescs is {0,2,2},{1,3,5},{2,2,7} , when use setXXX(6, x);
    +    // there will return {2,1} , means set param for the 1st param of the 3rd sql.
    +    private int[] getCurrentParamIndex(int paramIndex) {
    +        if (paramIndex < 1 || paramIndex > paramDescs[paramDescs.length - 1][2]) {
    +            return new int[] { 0, paramIndex };
    +        }
    +        for (int i = 0; i < paramDescs.length; i++) {
    +            if (paramIndex > paramDescs[i][2]) {
    +                continue;
    +            } else {
    +                int index = paramIndex - (paramDescs[i][2] - paramDescs[i][1]);
    +                return new int[] { i, index };
    +            }
    +        }
    +
    +        return new int[] { 0, paramIndex };
    +
    +    }
    +
    +    public void setObject(int parameterIndex, Object x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setObject", "", p);
    +        }
    +        int[] paramIndex = getCurrentParamIndex(parameterIndex);
    +        pstmtArr[paramIndex[0]].setObject(paramIndex[1], x);
    +    }
    +
    +    public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setDate(int parameterIndex, Date x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setTime(int parameterIndex, Time x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    @Override
    +    public void setDouble(int parameterIndex, double x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    @Override
    +    public void setFloat(int parameterIndex, float x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    @Override
    +    public void setLong(int parameterIndex, long x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setInt(int parameterIndex, int x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setShort(int parameterIndex, short x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setByte(int parameterIndex, byte x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setBoolean(int parameterIndex, boolean x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setString(int parameterIndex, String x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setString", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setBytes(int parameterIndex, byte[] x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void addBatch() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "addBatch", "", p);
    +        }
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            pstmtArr[i].addBatch();
    +        }
    +    }
    +
    +    public int[] executeBatch() throws SQLException, BatchUpdateException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "executeBatch", "", p);
    +        }
    +        currentSqlIndex = 0;
    +
    +        int[] results = null;
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            int[] result = pstmtArr[i].executeBatch();
    +            if (results == null) {
    +                results = result;
    +            } else {
    +                int[] tmp = new int[results.length + result.length];
    +                System.arraycopy(results, 0, tmp, 0, results.length);
    +                System.arraycopy(result, 0, tmp, results.length, result.length);
    +                results = tmp;
    +            }
    +        }
    +
    +        return results;
    +    }
    +
    +    // TODO here may add some logic in TrafT4ResultSet
    +    public ResultSet executeQuery() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "executeQuery", "", p);
    +        }
    +        ResultSet[] results = new ResultSet[pstmtArr.length];
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            results[i] = pstmtArr[i].executeQuery();
    +        }
    +        return results[currentSqlIndex++];
    +    }
    +
    +    public boolean execute() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "execute", "", p);
    +        }
    +        boolean result = false;
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            result |= pstmtArr[i].execute();
    +        }
    +        return result;
    +    }
    +
    +    public int getUpdateCount() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "getUpdateCount", "",
    +                    p);
    +        }
    +        long result = 0;
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            result += pstmtArr[i].getUpdateCount();
    +        }
    +        return (int) result;
    +    }
    +
    +    public int executeUpdate() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_
    +                    .logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "executeUpdate", "", p);
    +        }
    +        long result = 0;
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            result += pstmtArr[i].executeUpdate();
    +        }
    +        return (int) result;
    +    }
    +
    +    public void close() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "close", "", p);
    +        }
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            pstmtArr[i].close();
    --- End diff --
    
    very good suggestions, thanks


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by mashengchen <gi...@git.apache.org>.
GitHub user mashengchen reopened a pull request:

    https://github.com/apache/trafodion/pull/1535

    TRAFODION-2957 one stmt support multi-queries

    1. reconstitute the constructor of TrafT4Statement & TrafT4PreparedStatement
    2. add new property allowMultiQueries to support exec multi-queries in one statement
    3. new class extends from TrafT4Statement & TrafT4PreparedStatement to exec multi-queries

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/mashengchen/trafodion TRAFODION-2957

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/trafodion/pull/1535.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #1535
    
----
commit f9d6cd532506aa56d48ed314f14da918a7cf2a35
Author: aven <sh...@...>
Date:   2018-05-03T08:09:41Z

    TRAFODION-2957 one stmt support multi-queries

----


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by mashengchen <gi...@git.apache.org>.
Github user mashengchen commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r185398464
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,393 @@
    +// @@@ START COPYRIGHT @@@
    +//
    +// Licensed to the Apache Software Foundation (ASF) under one
    +// or more contributor license agreements.  See the NOTICE file
    +// distributed with this work for additional information
    +// regarding copyright ownership.  The ASF licenses this file
    +// to you under the Apache License, Version 2.0 (the
    +// "License"); you may not use this file except in compliance
    +// with the License.  You may obtain a copy of the License at
    +//
    +//   http://www.apache.org/licenses/LICENSE-2.0
    +//
    +// Unless required by applicable law or agreed to in writing,
    +// software distributed under the License is distributed on an
    +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    +// KIND, either express or implied.  See the License for the
    +// specific language governing permissions and limitations
    +// under the License.
    +//
    +// @@@ END COPYRIGHT @@@
    +
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    +        pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
    +        paramDescs = new int[sqlArr.length][3];
    +        int total = 0;
    +        int currentParamsLen = 0;
    +        for (int i = 0; i < sqlArr.length; i++) {
    +            pstmtArr[i] = new TrafT4PreparedStatement(connection, sqlArr[i], resultSetType, resultSetConcurrency,
    +                    resultSetHoldability, stmtLabel);
    +            pstmtArr[i].prepare(sqlArr[i], queryTimeout_, resultSetHoldability_);
    +
    +            // this is to setup the paramDescs, each paramDesc has 3 column,
    +            // 1: index of preparedStatement
    +            // 2: num of params for current pstmt
    +            // 3: accumulated params for current index
    +            // this varible is used when there invoking setXXX api
    +            if (pstmtArr[i].inputDesc_ != null) {
    +                currentParamsLen = pstmtArr[i].inputDesc_.length;
    +                total += currentParamsLen;
    +            }
    +            int[] paramDesc = { i, currentParamsLen, total };
    +            paramDescs[i] = paramDesc;
    +
    +        }
    +    }
    +
    +    public boolean execute(String sql) throws SQLException {
    --- End diff --
    
    @selvaganesang so your suggestion is  to remove the method or  throw exception when user invoke the method?
    i see TrafT4PreparedStatement not mark the methods( execute(sql) ) as not support


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by mashengchen <gi...@git.apache.org>.
Github user mashengchen commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r183582930
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,372 @@
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    --- End diff --
    
    there will have syntax error.
    eg: insert into tbl values ('a;a'); insert into tbl2 values ('b')
    there will have 3 preparedStatments, each one do itself prepare, then there will throw exception when do insert into tbl values ('a
    Actually this is a problem, i don't have a good solution now, maybe you can give some suggestions, thanks.


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by selvaganesang <gi...@git.apache.org>.
Github user selvaganesang commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r183574234
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,372 @@
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    --- End diff --
    
    What happens if there is ';' in the character literal of the sql query?


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by venkat1m <gi...@git.apache.org>.
Github user venkat1m commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r184867241
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,393 @@
    +// @@@ START COPYRIGHT @@@
    +//
    +// Licensed to the Apache Software Foundation (ASF) under one
    +// or more contributor license agreements.  See the NOTICE file
    +// distributed with this work for additional information
    +// regarding copyright ownership.  The ASF licenses this file
    +// to you under the Apache License, Version 2.0 (the
    +// "License"); you may not use this file except in compliance
    +// with the License.  You may obtain a copy of the License at
    +//
    +//   http://www.apache.org/licenses/LICENSE-2.0
    +//
    +// Unless required by applicable law or agreed to in writing,
    +// software distributed under the License is distributed on an
    +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    +// KIND, either express or implied.  See the License for the
    +// specific language governing permissions and limitations
    +// under the License.
    +//
    +// @@@ END COPYRIGHT @@@
    +
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    +        pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
    +        paramDescs = new int[sqlArr.length][3];
    +        int total = 0;
    +        int currentParamsLen = 0;
    +        for (int i = 0; i < sqlArr.length; i++) {
    +            pstmtArr[i] = new TrafT4PreparedStatement(connection, sqlArr[i], resultSetType, resultSetConcurrency,
    +                    resultSetHoldability, stmtLabel);
    +            pstmtArr[i].prepare(sqlArr[i], queryTimeout_, resultSetHoldability_);
    +
    +            // this is to setup the paramDescs, each paramDesc has 3 column,
    +            // 1: index of preparedStatement
    +            // 2: num of params for current pstmt
    +            // 3: accumulated params for current index
    +            // this varible is used when there invoking setXXX api
    +            if (pstmtArr[i].inputDesc_ != null) {
    +                currentParamsLen = pstmtArr[i].inputDesc_.length;
    +                total += currentParamsLen;
    +            }
    +            int[] paramDesc = { i, currentParamsLen, total };
    +            paramDescs[i] = paramDesc;
    +
    +        }
    +    }
    +
    +    public boolean execute(String sql) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "execute", "", p);
    +        }
    +        sqlArr = sql.split(";");
    +        pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
    +
    +        boolean result = false;
    +
    +        return result;
    +    }
    +
    +    // this method will return a 2 column array.
    +    // first column means the index of preparedStatement
    +    // second column means the real parameter index of the column one preparedStatement
    +    // eg:
    +    // insert into tbl values (?,?);insert into tbl values (?,?,?);insert into tbl values (?,?)
    +    // the paramDescs is {0,2,2},{1,3,5},{2,2,7} , when use setXXX(6, x);
    +    // there will return {2,1} , means set param for the 1st param of the 3rd sql.
    +    private int[] getCurrentParamIndex(int paramIndex) {
    +        if (paramIndex < 1 || paramIndex > paramDescs[paramDescs.length - 1][2]) {
    +            return new int[] { 0, paramIndex };
    +        }
    +        for (int i = 0; i < paramDescs.length; i++) {
    +            if (paramIndex > paramDescs[i][2]) {
    +                continue;
    +            } else {
    +                int index = paramIndex - (paramDescs[i][2] - paramDescs[i][1]);
    +                return new int[] { i, index };
    +            }
    +        }
    +
    +        return new int[] { 0, paramIndex };
    +
    +    }
    +
    +    public void setObject(int parameterIndex, Object x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setObject", "", p);
    +        }
    +        int[] paramIndex = getCurrentParamIndex(parameterIndex);
    +        pstmtArr[paramIndex[0]].setObject(paramIndex[1], x);
    +    }
    +
    +    public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setDate(int parameterIndex, Date x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setTime(int parameterIndex, Time x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    @Override
    +    public void setDouble(int parameterIndex, double x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    @Override
    +    public void setFloat(int parameterIndex, float x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    @Override
    +    public void setLong(int parameterIndex, long x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setInt(int parameterIndex, int x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setShort(int parameterIndex, short x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setByte(int parameterIndex, byte x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setBoolean(int parameterIndex, boolean x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setString(int parameterIndex, String x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setString", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setBytes(int parameterIndex, byte[] x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void addBatch() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "addBatch", "", p);
    +        }
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            pstmtArr[i].addBatch();
    +        }
    +    }
    +
    +    public int[] executeBatch() throws SQLException, BatchUpdateException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "executeBatch", "", p);
    +        }
    +        currentSqlIndex = 0;
    +
    +        int[] results = null;
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            int[] result = pstmtArr[i].executeBatch();
    +            if (results == null) {
    +                results = result;
    +            } else {
    +                int[] tmp = new int[results.length + result.length];
    +                System.arraycopy(results, 0, tmp, 0, results.length);
    +                System.arraycopy(result, 0, tmp, results.length, result.length);
    +                results = tmp;
    +            }
    +        }
    +
    +        return results;
    +    }
    +
    +    // TODO here may add some logic in TrafT4ResultSet
    +    public ResultSet executeQuery() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "executeQuery", "", p);
    +        }
    +        ResultSet[] results = new ResultSet[pstmtArr.length];
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            results[i] = pstmtArr[i].executeQuery();
    +        }
    +        return results[currentSqlIndex++];
    +    }
    +
    +    public boolean execute() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "execute", "", p);
    +        }
    +        boolean result = false;
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            result |= pstmtArr[i].execute();
    +        }
    +        return result;
    +    }
    +
    +    public int getUpdateCount() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "getUpdateCount", "",
    +                    p);
    +        }
    +        long result = 0;
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            result += pstmtArr[i].getUpdateCount();
    +        }
    +        return (int) result;
    +    }
    +
    +    public int executeUpdate() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_
    +                    .logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "executeUpdate", "", p);
    +        }
    +        long result = 0;
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            result += pstmtArr[i].executeUpdate();
    +        }
    +        return (int) result;
    +    }
    +
    +    public void close() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "close", "", p);
    +        }
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            pstmtArr[i].close();
    +        }
    +    }
    +
    +    public void cancel() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "cancel", "", p);
    +        }
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            pstmtArr[i].cancel();
    --- End diff --
    
    Would it be helpful to add a try catch around here and cancel as many statements as possible and throw the first exception. For example I have 5 statements and cancel of 2nd stmt fails, the remaining 3 also will not get cancelled.


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by venkat1m <gi...@git.apache.org>.
Github user venkat1m commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r183821553
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,393 @@
    +// @@@ START COPYRIGHT @@@
    +//
    +// Licensed to the Apache Software Foundation (ASF) under one
    +// or more contributor license agreements.  See the NOTICE file
    +// distributed with this work for additional information
    +// regarding copyright ownership.  The ASF licenses this file
    +// to you under the Apache License, Version 2.0 (the
    +// "License"); you may not use this file except in compliance
    +// with the License.  You may obtain a copy of the License at
    +//
    +//   http://www.apache.org/licenses/LICENSE-2.0
    +//
    +// Unless required by applicable law or agreed to in writing,
    +// software distributed under the License is distributed on an
    +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    +// KIND, either express or implied.  See the License for the
    +// specific language governing permissions and limitations
    +// under the License.
    +//
    +// @@@ END COPYRIGHT @@@
    +
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    +        pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
    +        paramDescs = new int[sqlArr.length][3];
    +        int total = 0;
    +        int currentParamsLen = 0;
    +        for (int i = 0; i < sqlArr.length; i++) {
    +            pstmtArr[i] = new TrafT4PreparedStatement(connection, sqlArr[i], resultSetType, resultSetConcurrency,
    +                    resultSetHoldability, stmtLabel);
    +            pstmtArr[i].prepare(sqlArr[i], queryTimeout_, resultSetHoldability_);
    +
    +            // this is to setup the paramDescs, each paramDesc has 3 column,
    +            // 1: index of preparedStatement
    +            // 2: num of params for current pstmt
    +            // 3: accumulated params for current index
    +            // this varible is used when there invoking setXXX api
    +            if (pstmtArr[i].inputDesc_ != null) {
    +                currentParamsLen = pstmtArr[i].inputDesc_.length;
    +                total += currentParamsLen;
    +            }
    +            int[] paramDesc = { i, currentParamsLen, total };
    +            paramDescs[i] = paramDesc;
    +
    +        }
    +    }
    +
    +    public boolean execute(String sql) throws SQLException {
    --- End diff --
    
    The benefit of preparedstatements is to prepare the query once and to execute multiple times. By breaking each semicolon separated sql into its own preparestatement, are we losing out on this feature?
    
    Would it be more appropriate to implement this feature for dynamic statements "Statement" as opposed to "PreparedStatement" ?


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by selvaganesang <gi...@git.apache.org>.
Github user selvaganesang commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r183743639
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,393 @@
    +// @@@ START COPYRIGHT @@@
    +//
    +// Licensed to the Apache Software Foundation (ASF) under one
    +// or more contributor license agreements.  See the NOTICE file
    +// distributed with this work for additional information
    +// regarding copyright ownership.  The ASF licenses this file
    +// to you under the Apache License, Version 2.0 (the
    +// "License"); you may not use this file except in compliance
    +// with the License.  You may obtain a copy of the License at
    +//
    +//   http://www.apache.org/licenses/LICENSE-2.0
    +//
    +// Unless required by applicable law or agreed to in writing,
    +// software distributed under the License is distributed on an
    +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    +// KIND, either express or implied.  See the License for the
    +// specific language governing permissions and limitations
    +// under the License.
    +//
    +// @@@ END COPYRIGHT @@@
    +
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    +        pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
    +        paramDescs = new int[sqlArr.length][3];
    +        int total = 0;
    +        int currentParamsLen = 0;
    +        for (int i = 0; i < sqlArr.length; i++) {
    +            pstmtArr[i] = new TrafT4PreparedStatement(connection, sqlArr[i], resultSetType, resultSetConcurrency,
    +                    resultSetHoldability, stmtLabel);
    +            pstmtArr[i].prepare(sqlArr[i], queryTimeout_, resultSetHoldability_);
    +
    +            // this is to setup the paramDescs, each paramDesc has 3 column,
    +            // 1: index of preparedStatement
    +            // 2: num of params for current pstmt
    +            // 3: accumulated params for current index
    +            // this varible is used when there invoking setXXX api
    +            if (pstmtArr[i].inputDesc_ != null) {
    +                currentParamsLen = pstmtArr[i].inputDesc_.length;
    +                total += currentParamsLen;
    +            }
    +            int[] paramDesc = { i, currentParamsLen, total };
    +            paramDescs[i] = paramDesc;
    +
    +        }
    +    }
    +
    +    public boolean execute(String sql) throws SQLException {
    --- End diff --
    
    This method is invalid in PreparedStatement.  A preparedStatement can't execute different SQL.  


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by mashengchen <gi...@git.apache.org>.
Github user mashengchen commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r183933191
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,393 @@
    +// @@@ START COPYRIGHT @@@
    +//
    +// Licensed to the Apache Software Foundation (ASF) under one
    +// or more contributor license agreements.  See the NOTICE file
    +// distributed with this work for additional information
    +// regarding copyright ownership.  The ASF licenses this file
    +// to you under the Apache License, Version 2.0 (the
    +// "License"); you may not use this file except in compliance
    +// with the License.  You may obtain a copy of the License at
    +//
    +//   http://www.apache.org/licenses/LICENSE-2.0
    +//
    +// Unless required by applicable law or agreed to in writing,
    +// software distributed under the License is distributed on an
    +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    +// KIND, either express or implied.  See the License for the
    +// specific language governing permissions and limitations
    +// under the License.
    +//
    +// @@@ END COPYRIGHT @@@
    +
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    +        pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
    +        paramDescs = new int[sqlArr.length][3];
    +        int total = 0;
    +        int currentParamsLen = 0;
    +        for (int i = 0; i < sqlArr.length; i++) {
    +            pstmtArr[i] = new TrafT4PreparedStatement(connection, sqlArr[i], resultSetType, resultSetConcurrency,
    +                    resultSetHoldability, stmtLabel);
    +            pstmtArr[i].prepare(sqlArr[i], queryTimeout_, resultSetHoldability_);
    +
    +            // this is to setup the paramDescs, each paramDesc has 3 column,
    +            // 1: index of preparedStatement
    +            // 2: num of params for current pstmt
    +            // 3: accumulated params for current index
    +            // this varible is used when there invoking setXXX api
    +            if (pstmtArr[i].inputDesc_ != null) {
    +                currentParamsLen = pstmtArr[i].inputDesc_.length;
    +                total += currentParamsLen;
    +            }
    +            int[] paramDesc = { i, currentParamsLen, total };
    +            paramDescs[i] = paramDesc;
    +
    +        }
    +    }
    +
    +    public boolean execute(String sql) throws SQLException {
    --- End diff --
    
    @selvaganesang 
    i am not sure whether user will do execute(sql) in a preparedStmt. but this api is valid in JKD, it's inherted from java.sql.statement, if it's invalid in trafodion, i can remove it.
    
    @venkat1m there may have possible that user want to exec "insert into t values (?); insert into t2 values(?,?)" in one preparedstatement to avoid sql code insertion attacks, in this PR, it will separate to 2 preparedStmts, and each one can execute multi-times.  so the prepare is needed.


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by mashengchen <gi...@git.apache.org>.
Github user mashengchen commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r185394999
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,372 @@
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    --- End diff --
    
    @svarnau @selvaganesang actually, what TrafT4MultiQueriesPreparedStatement do is just TrafT4PreparedStatement do, so if TrafT4PreparedStatement can avoid insertion attacks or variables like $PARAM1, then TrafT4MultiQueriesPreparedStatement can


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by venkat1m <gi...@git.apache.org>.
Github user venkat1m commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r184867229
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,393 @@
    +// @@@ START COPYRIGHT @@@
    +//
    +// Licensed to the Apache Software Foundation (ASF) under one
    +// or more contributor license agreements.  See the NOTICE file
    +// distributed with this work for additional information
    +// regarding copyright ownership.  The ASF licenses this file
    +// to you under the Apache License, Version 2.0 (the
    +// "License"); you may not use this file except in compliance
    +// with the License.  You may obtain a copy of the License at
    +//
    +//   http://www.apache.org/licenses/LICENSE-2.0
    +//
    +// Unless required by applicable law or agreed to in writing,
    +// software distributed under the License is distributed on an
    +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    +// KIND, either express or implied.  See the License for the
    +// specific language governing permissions and limitations
    +// under the License.
    +//
    +// @@@ END COPYRIGHT @@@
    +
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    +        pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
    +        paramDescs = new int[sqlArr.length][3];
    +        int total = 0;
    +        int currentParamsLen = 0;
    +        for (int i = 0; i < sqlArr.length; i++) {
    +            pstmtArr[i] = new TrafT4PreparedStatement(connection, sqlArr[i], resultSetType, resultSetConcurrency,
    +                    resultSetHoldability, stmtLabel);
    +            pstmtArr[i].prepare(sqlArr[i], queryTimeout_, resultSetHoldability_);
    +
    +            // this is to setup the paramDescs, each paramDesc has 3 column,
    +            // 1: index of preparedStatement
    +            // 2: num of params for current pstmt
    +            // 3: accumulated params for current index
    +            // this varible is used when there invoking setXXX api
    +            if (pstmtArr[i].inputDesc_ != null) {
    +                currentParamsLen = pstmtArr[i].inputDesc_.length;
    +                total += currentParamsLen;
    +            }
    +            int[] paramDesc = { i, currentParamsLen, total };
    +            paramDescs[i] = paramDesc;
    +
    +        }
    +    }
    +
    +    public boolean execute(String sql) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "execute", "", p);
    +        }
    +        sqlArr = sql.split(";");
    +        pstmtArr = new TrafT4PreparedStatement[sqlArr.length];
    +
    +        boolean result = false;
    +
    +        return result;
    +    }
    +
    +    // this method will return a 2 column array.
    +    // first column means the index of preparedStatement
    +    // second column means the real parameter index of the column one preparedStatement
    +    // eg:
    +    // insert into tbl values (?,?);insert into tbl values (?,?,?);insert into tbl values (?,?)
    +    // the paramDescs is {0,2,2},{1,3,5},{2,2,7} , when use setXXX(6, x);
    +    // there will return {2,1} , means set param for the 1st param of the 3rd sql.
    +    private int[] getCurrentParamIndex(int paramIndex) {
    +        if (paramIndex < 1 || paramIndex > paramDescs[paramDescs.length - 1][2]) {
    +            return new int[] { 0, paramIndex };
    +        }
    +        for (int i = 0; i < paramDescs.length; i++) {
    +            if (paramIndex > paramDescs[i][2]) {
    +                continue;
    +            } else {
    +                int index = paramIndex - (paramDescs[i][2] - paramDescs[i][1]);
    +                return new int[] { i, index };
    +            }
    +        }
    +
    +        return new int[] { 0, paramIndex };
    +
    +    }
    +
    +    public void setObject(int parameterIndex, Object x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setObject", "", p);
    +        }
    +        int[] paramIndex = getCurrentParamIndex(parameterIndex);
    +        pstmtArr[paramIndex[0]].setObject(paramIndex[1], x);
    +    }
    +
    +    public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setDate(int parameterIndex, Date x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setTime(int parameterIndex, Time x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    @Override
    +    public void setDouble(int parameterIndex, double x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    @Override
    +    public void setFloat(int parameterIndex, float x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    @Override
    +    public void setLong(int parameterIndex, long x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setInt(int parameterIndex, int x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setShort(int parameterIndex, short x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setByte(int parameterIndex, byte x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setBoolean(int parameterIndex, boolean x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setString(int parameterIndex, String x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setString", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void setBytes(int parameterIndex, byte[] x) throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "setInt", "", p);
    +        }
    +        setObject(parameterIndex, x);
    +    }
    +
    +    public void addBatch() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "addBatch", "", p);
    +        }
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            pstmtArr[i].addBatch();
    +        }
    +    }
    +
    +    public int[] executeBatch() throws SQLException, BatchUpdateException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "executeBatch", "", p);
    +        }
    +        currentSqlIndex = 0;
    +
    +        int[] results = null;
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            int[] result = pstmtArr[i].executeBatch();
    +            if (results == null) {
    +                results = result;
    +            } else {
    +                int[] tmp = new int[results.length + result.length];
    +                System.arraycopy(results, 0, tmp, 0, results.length);
    +                System.arraycopy(result, 0, tmp, results.length, result.length);
    +                results = tmp;
    +            }
    +        }
    +
    +        return results;
    +    }
    +
    +    // TODO here may add some logic in TrafT4ResultSet
    +    public ResultSet executeQuery() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "executeQuery", "", p);
    +        }
    +        ResultSet[] results = new ResultSet[pstmtArr.length];
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            results[i] = pstmtArr[i].executeQuery();
    +        }
    +        return results[currentSqlIndex++];
    +    }
    +
    +    public boolean execute() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "execute", "", p);
    +        }
    +        boolean result = false;
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            result |= pstmtArr[i].execute();
    +        }
    +        return result;
    +    }
    +
    +    public int getUpdateCount() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "getUpdateCount", "",
    +                    p);
    +        }
    +        long result = 0;
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            result += pstmtArr[i].getUpdateCount();
    +        }
    +        return (int) result;
    +    }
    +
    +    public int executeUpdate() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_
    +                    .logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "executeUpdate", "", p);
    +        }
    +        long result = 0;
    +        currentSqlIndex = 0;
    +
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            result += pstmtArr[i].executeUpdate();
    +        }
    +        return (int) result;
    +    }
    +
    +    public void close() throws SQLException {
    +        if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
    +            connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "close", "", p);
    +        }
    +        for (int i = 0; i < pstmtArr.length; i++) {
    +            pstmtArr[i].close();
    --- End diff --
    
    Would it be helpful to add a try catch around here and close as many statements as possible and throw the first exception, so as to free resources. For example I have 5 statements and 2nd one fails, the remaining 3 also will not get closed.


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by selvaganesang <gi...@git.apache.org>.
Github user selvaganesang commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r185934375
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,372 @@
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    --- End diff --
    
    I agree with you @mashengchen. But my suggestion is to take care of ';' when it appears in the midst of string literal in the param.  Do you think if that suggestion would hold good? If so, do you think it is better to make that change


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by svarnau <gi...@git.apache.org>.
Github user svarnau commented on a diff in the pull request:

    https://github.com/apache/trafodion/pull/1535#discussion_r183804788
  
    --- Diff: core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4MultiQueriesPreparedStatement.java ---
    @@ -0,0 +1,372 @@
    +package org.trafodion.jdbc.t4;
    +
    +import java.math.BigDecimal;
    +import java.sql.BatchUpdateException;
    +import java.sql.Date;
    +import java.sql.ResultSet;
    +import java.sql.SQLException;
    +import java.sql.Time;
    +import java.sql.Timestamp;
    +import java.util.logging.Level;
    +
    +public class TrafT4MultiQueriesPreparedStatement extends TrafT4PreparedStatement {
    +
    +    private String[] sqlArr = null;
    +    private TrafT4PreparedStatement[] pstmtArr = null;
    +    private int[][] paramDescs = null;
    +
    +    private int currentSqlIndex;
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
    +        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
    +                TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    +        this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, null);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +    }
    +
    +    TrafT4MultiQueriesPreparedStatement(TrafT4Connection connection, String sql, int resultSetType,
    +            int resultSetConcurrency, int resultSetHoldability, String stmtLabel) throws SQLException {
    +        super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
    +        if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
    +            Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, sql, resultSetType,
    +                    resultSetConcurrency, resultSetHoldability, stmtLabel);
    +            connection.props_.t4Logger_.logp(Level.FINE, "TrafT4MultiQueriesPreparedStatement", "<init>", "", p);
    +        }
    +
    +        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
    +                && resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_type", null);
    +        }
    +        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
    +                    "invalid_resultset_concurrency", null);
    +        }
    +        if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
    +                && (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
    +            throw TrafT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
    +                    null);
    +        }
    +
    +        sqlArr = sql.split(";");
    --- End diff --
    
    This seems very prone to opening application to sql code insertion attacks. We have to be VERY careful not to allow any literal string to be executed as sql code.


---

[GitHub] trafodion pull request #1535: TRAFODION-2957 one stmt support multi-queries

Posted by mashengchen <gi...@git.apache.org>.
Github user mashengchen closed the pull request at:

    https://github.com/apache/trafodion/pull/1535


---