private Result sqlExecuteBatchDirect(Result cmd) { Record record; Result in; Result out; Result err; int[] updateCounts; int count; String sql; count = 0; updateCounts = new int[cmd.getSize()]; record = cmd.rRoot; out = new Result(ResultConstants.SQLEXECUTE, updateCounts, 0); err = new Result(ResultConstants.ERROR); while (record != null) { sql = (String) record.data[0]; in = err; try { in = dbCommandInterpreter.execute(sql); } catch (Throwable t) { // if (t instanceof OutOfMemoryError) { // System.gc(); // } // "in" alread equals "err" // maybe test for OOME and do a gc() ? // t.printStackTrace(); } // On the client side, iterate over the colType vals and throw // a BatchUpdateException if a batch status value of // ResultConstants.EXECUTE_FAILED is encountered switch (in.iMode) { case ResultConstants.UPDATECOUNT: { updateCounts[count++] = in.iUpdateCount; break; } case ResultConstants.DATA: { // FIXME: we don't have what it takes yet // to differentiate between things like // stored procedure calls to methods with // void return type and select statements with // a single row/column containg null updateCounts[count++] = ResultConstants.SUCCESS_NO_INFO; break; } case ResultConstants.ERROR: default: { updateCounts[count++] = ResultConstants.EXECUTE_FAILED; break; } } record = record.next; } return out; }
/** * Executes the command encapsulated by the cmd argument. * * @param cmd the command to execute * @return the result of executing the command */ public Result execute(Result cmd) { try { if (Trace.DOASSERT) { Trace.doAssert(!isNestedTransaction); } Trace.check(!isClosed, Trace.ACCESS_IS_DENIED, "Session is closed"); } catch (Throwable t) { return new Result(t, null); } int type = cmd.iMode; synchronized (dDatabase) { if (sessionMaxRows == 0) { currentMaxRows = cmd.iUpdateCount; } DatabaseManager.gc(); switch (type) { case ResultConstants.SQLEXECUTE: { return cmd.getSize() > 1 ? sqlExecuteBatch(cmd) : sqlExecute(cmd); } case ResultConstants.SQLEXECDIRECT: { return cmd.getSize() > 0 ? sqlExecuteBatchDirect(cmd) : sqlExecuteDirectNoPreChecks(cmd.getMainString()); } case ResultConstants.SQLPREPARE: { return sqlPrepare(cmd.getMainString(), cmd.getStatementType()); } case ResultConstants.SQLFREESTMT: { return sqlFreeStatement(cmd.getStatementID()); } case ResultConstants.GETSESSIONATTR: { return getAttributes(); } case ResultConstants.SETSESSIONATTR: { return setAttributes(cmd); } case ResultConstants.SQLENDTRAN: { switch (cmd.getEndTranType()) { case ResultConstants.COMMIT: commit(); break; case ResultConstants.ROLLBACK: rollback(); break; case ResultConstants.SAVEPOINT_NAME_RELEASE: try { String name = cmd.getMainString(); releaseSavepoint(name); } catch (Throwable t) { return new Result(t, null); } break; case ResultConstants.SAVEPOINT_NAME_ROLLBACK: try { rollbackToSavepoint(cmd.getMainString()); } catch (Throwable t) { return new Result(t, null); } break; // not yet // case ResultConstants.COMMIT_AND_CHAIN : // case ResultConstants.ROLLBACK_AND_CHAIN : } return emptyUpdateCount; } case ResultConstants.SQLSETCONNECTATTR: { switch (cmd.getConnectionAttrType()) { case ResultConstants.SQL_ATTR_SAVEPOINT_NAME: try { savepoint(cmd.getMainString()); } catch (Throwable t) { return new Result(t, null); } // case ResultConstants.SQL_ATTR_AUTO_IPD // - always true // default: throw - case never happens } return emptyUpdateCount; } default: { String msg = "operation type:" + type; return new Result(msg, "s1000", Trace.OPERATION_NOT_SUPPORTED); } } } }
private Result sqlExecuteBatch(Result cmd) { int csid; Object[] pvals; Record record; Result in; Result out; Result err; CompiledStatement cs; Expression[] parameters; int[] updateCounts; int count; csid = cmd.getStatementID(); cs = compiledStatementManager.getStatement(csid); if (cs == null) { String msg = "Statement not prepared for csid: " + csid; return new Result(msg, "22019", Trace.INVALID_IDENTIFIER); } if (!compiledStatementManager.isValid(csid, iId)) { out = sqlPrepare(cs.sql, cs.type); if (out.iMode == ResultConstants.ERROR) { return out; } } parameters = cs.parameters; count = 0; updateCounts = new int[cmd.getSize()]; record = cmd.rRoot; out = new Result(ResultConstants.SQLEXECUTE, updateCounts, 0); err = new Result(ResultConstants.ERROR); while (record != null) { pvals = record.data; in = err; try { for (int i = 0; i < parameters.length; i++) { parameters[i].bind(pvals[i]); } in = compiledStatementExecutor.execute(cs); } catch (Throwable t) { // t.printStackTrace(); // System.out.println(t.toString()); // if (t instanceof OutOfMemoryError) { // System.gc(); // } // "in" alread equals "err" // maybe test for OOME and do a gc() ? // t.printStackTrace(); } // On the client side, iterate over the vals and throw // a BatchUpdateException if a batch status value of // esultConstants.EXECUTE_FAILED is encountered in the result switch (in.iMode) { case ResultConstants.UPDATECOUNT: { updateCounts[count++] = in.iUpdateCount; break; } case ResultConstants.DATA: { // FIXME: we don't have what it takes yet // to differentiate between things like // stored procedure calls to methods with // void return type and select statements with // a single row/column containg null updateCounts[count++] = ResultConstants.SUCCESS_NO_INFO; break; } case ResultConstants.ERROR: default: { updateCounts[count++] = ResultConstants.EXECUTE_FAILED; break; } } record = record.next; } return out; }