Subject Re: [Firebird-Java] Re: Some bugs and patches
Author Blas Rodriguez Somoza
Hello

I hope you can do. I'll send two or three more patch groups before the weekend. Most of the changes are very simple ones.

Regards
Blas Rodriguez Somoza.

----- Original Message -----
From: "rrokytskyy" <rrokytskyy@...>
To: <Firebird-Java@yahoogroups.com>
Sent: Wednesday, May 15, 2002 10:03 PM
Subject: [Firebird-Java] Re: Some bugs and patches


> Hi,
>
> Thanks a lot! Unfortunatelly I will be able to patch sources only on
> weekend. After I do this, I will post a message here. Thanks again!
>
> Roman
>
> --- In Firebird-Java@y..., "Blas Rodriguez Somoza" <blas@p...> wrote:
> > Hello
> >
> > I spend some time testing the driver and I locate some bugs and
> it solutions. I send the methods affected in a text file with
> > the mail. I refresh my CVS repository on May-14 at 21:52 (Madrid
> Time) so I think I make the changes on the current version.
> >
> > With this patches, the driver passes all the tests for
> PreparedStatement. Otherwise, the bug about the statement closing have
> > some serious consecuences, between which it is that the driver
> locks a table and when after some other work, the program tries to
> > close the connection, the method fails with an exception.
> >
> > 1.- FBPreparedStatement.internalExecute.
> > BUG: a preparedStatement with the parameters cleared don't throw
> SQLexception when executed.
> > WHY: there is two internalExecute methods but only one is used.
> There are a parameters check in the wrong method
> > "internalExecute(String)". PATCH: copy the parameter check to the
> correct method "internalExecute(boolean)". I think it is better to
> > comment the unused method to avoid confusion.
> >
> > 2.- FBStatement.getResultSet()
> > BUG: When getResultSet is called after a execute
> (insert/update/delete) the driver throws an error "registerStatement
> called with no
> > transaction".
> > WHY: The driver try to return a new resultSet but it can't.
> > PATCH: Now there are some code to try to get more than one
> resultSet, but the driver does not implement getMoreResults and I
> don't
> > know if the driver and Firebird can return multiple results with
> one execute. The solution is to return null if there is no
> > cachedResultSet, this behavoir is the one the specification expects
> if there is no more resultSets.
> >
> > 3.- FBStatement.getMoreResults()
> > BUG: Not implemented
> > PATCH: return null.
> >
> > 4.- FBStatement.execute/executeQuery/executeUpdate
> > BUG: The execute methods does not verify if the Statement is closed.
> > PATCH: verify if the Statement is closed at the beggining of the
> three execute methods and return an SQLException if the statement
> > is closed.
> >
> > 5.- FBStatement.close
> > BUG: If an Statement is closed before it is used to execute a SQL
> command, the close method does not set closed=true because
> > fixedStmt is null.
> > PATCH: set closed=true in close() method if fixedStmt is false.
> >
> > 6.- FBConnection.setTransactionIsolation
> > BUG: If a transaction isolation level is not supported, the driver
> must upgrade the level to the next higher level, and if there is
> > no one then it must throw a SQLException.
> > PATCH: If READ_UNCOMMITTED isolation level is required then the
> driver set the level to READ_COMMITTED.
> >
> >
> > Regards
> > Blas Rodriguez Somoza.
> >
> >
> > Modified lines are marked with "MOD"
> >
> > FBConnection.setTransactionIsolation--------------------------------
> -----
> >
> > public void setTransactionIsolation(int level) throws
> SQLException {
> > switch (level) {
> > case TRANSACTION_SERIALIZABLE :
> > mc.setTransactionIsolation(GDS.isc_tpb_consistency);
> > break;
> > case TRANSACTION_REPEATABLE_READ :
> > mc.setTransactionIsolation(GDS.isc_tpb_concurrency);
> > break;
> > case TRANSACTION_READ_COMMITTED :
> > mc.setTransactionIsolation
> (GDS.isc_tpb_read_committed);
> > break;
> > MOD case TRANSACTION_READ_UNCOMMITTED :
> > MOD mc.setTransactionIsolation
> (GDS.isc_tpb_read_committed);
> > MOD break;
> > default: throw new SQLException("Unsupported
> transaction isolation level");
> > }
> > }
> >
> > FBStatement.executeQuery-------------------------------------
> >
> > public ResultSet executeQuery(String sql) throws SQLException {
> > MOD if (closed)
> > MOD throw new SQLException("Statement is closed");
> > try
> > {
> > c.ensureInTransaction();
> > if (!internalExecute(sql)) {
> > throw new SQLException("query did not return a
> result set: " + sql);
> > }
> > if (c.willEndTransaction())
> > {
> > ResultSet rs = getCachedResultSet(false);
> > //autocommits.
> > return rs;
> > } // end of if ()
> > else
> > {
> > return getResultSet();
> > } // end of else
> > }
> > catch (ResourceException re)
> > {
> > log.warn("resource exception", re);
> > throw new SQLException("ResourceException: " + re);
> > } // end of try-catch
> > catch (GDSException ge)
> > {
> > throw new SQLException("GDSException: " + ge);
> > } // end of try-catch
> > finally
> > {
> > c.checkEndTransaction();
> > } // end of finally
> >
> > }
> >
> > FBStatement.executeUpdate-------------------------------------
> >
> > public int executeUpdate(String sql) throws SQLException {
> > MOD if(closed)
> > MOD throw new SQLException("Statement is closed");
> > try
> > {
> > c.ensureInTransaction();
> > if (internalExecute(sql)) {
> > throw new SQLException("update statement returned
> results!");
> > }
> > return getUpdateCount();
> > }
> > catch (ResourceException re)
> > {
> > throw new SQLException("ResourceException: " + re);
> > } // end of try-catch
> > catch (GDSException ge)
> > {
> > throw new SQLException("GDSException: " + ge);
> > } // end of try-catch
> > finally
> > {
> > c.checkEndTransaction();
> > } // end of finally
> > }
> >
> > FBStatement.execute-------------------------------------
> >
> > public boolean execute(String sql) throws SQLException {
> > MOD if (closed)
> > MOD throw new SQLException("Statement is closed");
> > try {
> > c.ensureInTransaction();
> > boolean hasResultSet = internalExecute(sql);
> > if (hasResultSet && c.willEndTransaction())
> > {
> > getCachedResultSet(false);
> > } // end of if ()
> > return hasResultSet;
> > }
> > catch (ResourceException re)
> > {
> > throw new SQLException("ResourceException: " + re);
> > } // end of try-catch
> > catch (GDSException ge)
> > {
> > throw new SQLException("GDSException: " + ge);
> > } // end of try-catch
> > finally
> > {
> > c.checkEndTransaction();
> > } // end of finally
> > }
> >
> >
> > FBStatement.close-------------------------------------
> >
> > public void close() throws SQLException {
> > if (closed)
> > throw new SQLException("This statement is already
> closed.");
> >
> > if (fixedStmt != null) {
> > try {
> > //may need ensureTransaction?
> > mc.closeStatement(fixedStmt, true);
> > }
> > catch (GDSException ge) {
> > throw new SQLException("could not close
> statement: " + ge.toString());
> > }
> > finally {
> > fixedStmt = null;
> > currentRs = null;
> > currentCachedResultSet = null;
> > closed = true;
> > }
> > }
> > MOD else
> > MOD closed = true;
> > }
> >
> > FBStatement.getResultSet -------------------------------------------
> -------------
> >
> > public ResultSet getResultSet() throws SQLException {
> > if (currentRs != null) {
> > throw new SQLException("Only one resultset at a
> time/statement!");
> > }
> > if (fixedStmt == null) {
> > throw new SQLException("No statement just executed");
> > }
> > if (currentCachedResultSet != null)
> > {
> > ResultSet rs = currentCachedResultSet;
> > currentCachedResultSet = null;
> > return rs;
> > } // end of if ()
> > else
> > {
> > //currentRs = new FBResultSet(mc, this, fixedStmt);
> > MOD// currentRs = new FBResultSet(c, this, fixedStmt);
> > MOD// return currentRs;
> > MOD return null;
> > } // end of else
> > }
> >
> > FBStatement.getMoreResults -----------------------------------------
> ---------------
> >
> > public boolean getMoreResults() throws SQLException {
> > MOD// throw new SQLException("Not yet implemented");
> > MOD return false;
> > }
> >
> >
> > FBPreparedStatement ------------------------------------------------
> --------
> >
> > protected boolean internalExecute(boolean sendOutParams)
> throws SQLException
> > {
> > MOD boolean canExecute = true;
> > MOD for (int i = 0; i < isParamSet.length; i++){
> > MOD canExecute = canExecute && isParamSet[i];
> > MOD }
> >
> > MOD if (!canExecute)
> > MOD throw new SQLException("Not all parameters were set. " +
> > MOD "Cannot execute query.");
> >
> > XSQLVAR[] inVars = fixedStmt.getInSqlda().sqlvar;
> >
> > for(int i = 0; i < inVars.length; i++)
> > {
> > boolean isBlobField =
> > FBField.isType(inVars[i], Types.BLOB) ||
> > FBField.isType(inVars[i], Types.BINARY) ||
> > FBField.isType(inVars[i], Types.LONGVARCHAR);
> >
> > if (isBlobField)
> > {
> > FBBlobField blobField = (FBBlobField)getField(i +
> 1);
> > blobField.flushCachedData();
> > }
> > }
> > try {
> > closeResultSet();
> > mc.executeStatement(fixedStmt, sendOutParams);
> > return (fixedStmt.getOutSqlda().sqld > 0);
> > }
> > catch (GDSException ge) {
> > throw new SQLException("GDS exception: " + ge.toString
> ());
> > }
> > }
>
>
>
> To unsubscribe from this group, send an email to:
> Firebird-Java-unsubscribe@yahoogroups.com
>
>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>
>