use of org.apache.derby.iapi.jdbc.EnginePreparedStatement in project derby by apache.
the class DRDAConnThread method parseSQLDTA_work.
/**
* Parse SQLDTA - SQL program variable data
* Instance Variables
* FDODSC - FD:OCA data descriptor - required
* FDODTA - FD:OCA data - optional
*
* @throws DRDAProtocolException
* @throws SQLException
*/
private void parseSQLDTA_work(DRDAStatement stmt) throws DRDAProtocolException, SQLException {
String strVal;
EnginePreparedStatement ps = stmt.getPreparedStatement();
int codePoint;
ParameterMetaData pmeta = null;
// Clear params without releasing storage
stmt.clearDrdaParams();
int numVars = 0;
boolean rtnParam = false;
reader.markCollection();
codePoint = reader.getCodePoint();
while (codePoint != -1) {
switch(codePoint) {
// required
case CodePoint.FDODSC:
while (// we get parameter info til last 6 byte
reader.getDdmLength() > 6) {
int dtaGrpLen = reader.readUnsignedByte();
int numVarsInGrp = (dtaGrpLen - 3) / 3;
if (SanityManager.DEBUG) {
trace("num of vars in this group is: " + numVarsInGrp);
}
// tripletType
reader.readByte();
// id
reader.readByte();
for (int j = 0; j < numVarsInGrp; j++) {
final byte t = reader.readByte();
if (SanityManager.DEBUG) {
trace("drdaType is: " + "0x" + Integer.toHexString(t));
}
int drdaLength = reader.readNetworkShort();
if (SanityManager.DEBUG) {
trace("drdaLength is: " + drdaLength);
}
stmt.addDrdaParam(t, drdaLength);
}
}
numVars = stmt.getDrdaParamCount();
if (SanityManager.DEBUG) {
trace("numVars = " + numVars);
}
if (// it is a CallableStatement under construction
ps == null) {
// construct parameter marks
StringBuilder marks = new StringBuilder();
marks.append("(?");
for (int i = 1; i < numVars; i++) {
marks.append(", ?");
}
String prepareString = "call " + stmt.procName + marks.toString() + ")";
if (SanityManager.DEBUG) {
trace("$$ prepareCall is: " + prepareString);
}
CallableStatement cs = null;
try {
cs = (CallableStatement) stmt.prepare(prepareString);
stmt.registerAllOutParams();
} catch (SQLException se) {
if (!stmt.outputExpected || (!se.getSQLState().equals(SQLState.LANG_NO_METHOD_FOUND))) {
throw se;
}
if (SanityManager.DEBUG) {
trace("****** second try with return parameter...");
}
// Save first SQLException most likely suspect
if (numVars == 1) {
prepareString = "? = call " + stmt.procName + "()";
} else {
prepareString = "? = call " + stmt.procName + "(" + marks.substring(3) + ")";
}
if (SanityManager.DEBUG) {
trace("$$ prepareCall is: " + prepareString);
}
try {
cs = (CallableStatement) stmt.prepare(prepareString);
} catch (SQLException se2) {
// The first exception is the most likely suspect
throw se;
}
rtnParam = true;
}
ps = (EnginePreparedStatement) cs;
stmt.ps = ps;
}
pmeta = stmt.getParameterMetaData();
// descriptor footer
reader.readBytes(6);
break;
// optional
case CodePoint.FDODTA:
// row indicator
reader.readByte();
for (int i = 0; i < numVars; i++) {
if (// nullable
(stmt.getParamDRDAType(i + 1) & 0x1) == 0x1) {
int nullData = reader.readUnsignedByte();
if ((nullData & 0xFF) == FdocaConstants.NULL_DATA) {
if (SanityManager.DEBUG) {
trace("******param null");
}
if (pmeta.getParameterMode(i + 1) != ParameterMetaData.parameterModeOut) {
ps.setNull(i + 1, pmeta.getParameterType(i + 1));
}
if (stmt.isOutputParam(i + 1)) {
stmt.registerOutParam(i + 1);
}
continue;
}
}
// not null, read and set it
readAndSetParams(i, stmt, pmeta);
}
break;
case CodePoint.EXTDTA:
readAndSetAllExtParams(stmt, false);
break;
default:
invalidCodePoint(codePoint);
}
codePoint = reader.getCodePoint();
}
}
use of org.apache.derby.iapi.jdbc.EnginePreparedStatement in project derby by apache.
the class DRDAConnThread method parseEXCSQLSTT.
/**
* Parse EXCSQLSTT - Execute non-cursor SQL Statement previously prepared
* Instance Variables
* RDBNAM - relational database name - optional
* PKGNAMCSN - RDB Package Name, Consistency Token and Section Number - required
* OUTEXP - Output expected
* NBRROW - Number of rows to be inserted if it's an insert
* PRCNAM - procedure name if specified by host variable, not needed for Derby
* QRYBLKSZ - query block size
* MAXRSLCNT - max resultset count
* MAXBLKEXT - Max number of extra blocks
* RSLSETFLG - resultset flag
* RDBCMTOK - RDB Commit Allowed - optional
* OUTOVROPT - output override option
* QRYROWSET - Query Rowset Size - Level 7
* MONITOR - Monitor events - optional.
*
* @throws DRDAProtocolException
* @throws SQLException
*/
private void parseEXCSQLSTT() throws DRDAProtocolException, SQLException {
int codePoint;
String strVal;
reader.markCollection();
codePoint = reader.getCodePoint();
boolean outputExpected = false;
Pkgnamcsn pkgnamcsn = null;
// default value
int numRows = 1;
int blkSize = 0;
// default value
int maxrslcnt = 0;
int maxblkext = CodePoint.MAXBLKEXT_DEFAULT;
int qryrowset = CodePoint.QRYROWSET_DEFAULT;
int outovropt = CodePoint.OUTOVRFRS;
byte[] rslsetflg = null;
String procName = null;
while (codePoint != -1) {
switch(codePoint) {
// optional
case CodePoint.RDBNAM:
setDatabase(CodePoint.EXCSQLSTT);
break;
// required
case CodePoint.PKGNAMCSN:
pkgnamcsn = parsePKGNAMCSN();
break;
// optional
case CodePoint.OUTEXP:
outputExpected = readBoolean(CodePoint.OUTEXP);
if (SanityManager.DEBUG) {
trace("outexp = " + outputExpected);
}
break;
// optional
case CodePoint.NBRROW:
checkLength(CodePoint.NBRROW, 4);
numRows = reader.readNetworkInt();
if (SanityManager.DEBUG) {
trace("# of rows: " + numRows);
}
break;
// optional
case CodePoint.PRCNAM:
procName = reader.readString();
if (SanityManager.DEBUG) {
trace("Procedure Name = " + procName);
}
break;
// optional
case CodePoint.QRYBLKSZ:
blkSize = parseQRYBLKSZ();
break;
// optional
case CodePoint.MAXRSLCNT:
// this is the maximum result set count
// values are 0 - requester is not capabable of receiving result
// sets as reply data in the response to EXCSQLSTT
// -1 - requester is able to receive all result sets
checkLength(CodePoint.MAXRSLCNT, 2);
maxrslcnt = reader.readNetworkShort();
if (SanityManager.DEBUG) {
trace("max rs count: " + maxrslcnt);
}
break;
// optional
case CodePoint.MAXBLKEXT:
// number of extra qury blocks of answer set data per result set
// 0 - no extra query blocks
// -1 - can receive entire result set
checkLength(CodePoint.MAXBLKEXT, 2);
maxblkext = reader.readNetworkShort();
if (SanityManager.DEBUG) {
trace("max extra blocks: " + maxblkext);
}
break;
// optional
case CodePoint.RSLSETFLG:
// Result set flags
rslsetflg = reader.readBytes();
if (SanityManager.DEBUG) {
for (byte b : rslsetflg) {
trace("rslsetflg: " + b);
}
}
break;
// optional
case CodePoint.RDBCMTOK:
parseRDBCMTOK();
break;
// optional
case CodePoint.OUTOVROPT:
outovropt = parseOUTOVROPT();
break;
// optional
case CodePoint.QRYROWSET:
// Note minimum for OPNQRY is 0, we'll assume it is the same
// for EXCSQLSTT though the standard doesn't say
qryrowset = parseQRYROWSET(0);
break;
// optional
case CodePoint.MONITOR:
parseMONITOR();
break;
default:
invalidCodePoint(codePoint);
}
codePoint = reader.getCodePoint();
}
if (pkgnamcsn == null) {
missingCodePoint(CodePoint.PKGNAMCSN);
}
DRDAStatement stmt;
boolean needPrepareCall = false;
stmt = database.getDRDAStatement(pkgnamcsn);
boolean isProcedure = (procName != null || (stmt != null && stmt.wasExplicitlyPrepared() && stmt.isCall));
if (// stored procedure call
isProcedure) {
if (stmt == null || !(stmt.wasExplicitlyPrepared())) {
stmt = database.newDRDAStatement(pkgnamcsn);
stmt.setQryprctyp(CodePoint.QRYBLKCTL_DEFAULT);
needPrepareCall = true;
}
stmt.procName = procName;
stmt.outputExpected = outputExpected;
} else {
// we can't find the statement
if (stmt == null) {
invalidValue(CodePoint.PKGNAMCSN);
}
stmt.setQryprctyp(CodePoint.QRYBLKCTL_DEFAULT);
}
stmt.nbrrow = numRows;
stmt.qryrowset = qryrowset;
stmt.blksize = blkSize;
stmt.maxblkext = maxblkext;
stmt.maxrslcnt = maxrslcnt;
stmt.outovropt = outovropt;
stmt.rslsetflg = rslsetflg;
if (pendingStatementTimeout >= 0) {
stmt.getPreparedStatement().setQueryTimeout(pendingStatementTimeout);
pendingStatementTimeout = -1;
}
// set the statement as the current statement
database.setCurrentStatement(stmt);
boolean hasResultSet;
if (reader.isChainedWithSameID()) {
hasResultSet = parseEXCSQLSTTobjects(stmt);
} else {
if (isProcedure && (needPrepareCall)) {
// if we had parameters the callable statement would
// be prepared with parseEXCQLSTTobjects, otherwise we
// have to do it here
String prepareString = "call " + stmt.procName + "()";
if (SanityManager.DEBUG) {
trace("$$$prepareCall is: " + prepareString);
}
database.getConnection().clearWarnings();
CallableStatement cs = (CallableStatement) stmt.prepare(prepareString);
}
stmt.ps.clearWarnings();
hasResultSet = stmt.execute();
}
ResultSet rs = null;
if (hasResultSet) {
rs = stmt.getResultSet();
}
// temp until ps.execute() return value fixed
hasResultSet = (rs != null);
int numResults = 0;
if (hasResultSet) {
numResults = stmt.getNumResultSets();
writeRSLSETRM(stmt);
}
// First of all, we send if there really are output params. Otherwise
// CLI (.Net driver) fails. DRDA spec (page 151,152) says send SQLDTARD
// if server has output param data to send.
boolean sendSQLDTARD = stmt.hasOutputParams() && outputExpected;
if (isProcedure) {
if (sendSQLDTARD) {
writer.createDssObject();
writer.startDdm(CodePoint.SQLDTARD);
writer.startDdm(CodePoint.FDODSC);
writeQRYDSC(stmt, true);
writer.endDdm();
writer.startDdm(CodePoint.FDODTA);
writeFDODTA(stmt);
writer.endDdm();
writer.endDdmAndDss();
if (stmt.getExtDtaObjects() != null) {
// writeScalarStream() ends the dss
writeEXTDTA(stmt);
}
} else if (hasResultSet) {
// DRDA spec says that we MUST return either an
// SQLDTARD or an SQLCARD--the former when we have
// output parameters, the latter when we don't.
// If we have a result set, then we have to write
// the SQLCARD _now_, since it is expected before
// we send the result set info below; if we don't
// have a result set and we don't send SQLDTARD,
// then we can wait until we reach the call to
// checkWarning() below, which will write an
// SQLCARD for us.
writeNullSQLCARDobject();
}
}
// We need to marke that params are finished so that we know we
// are ready to send resultset info.
stmt.finishParams();
EnginePreparedStatement ps = stmt.getPreparedStatement();
int rsNum = 0;
do {
if (hasResultSet) {
stmt.setCurrentDrdaResultSet(rsNum);
// indicate that we are going to return data
stmt.setQryrtndta(true);
if (!isProcedure) {
checkWarning(null, ps, null, -1, true, true);
}
if (rsNum == 0) {
writeSQLRSLRD(stmt);
}
writeOPNQRYRM(true, stmt);
writeSQLCINRD(stmt);
writeQRYDSC(stmt, false);
stmt.rsSuspend();
/* Currently, if LMTBLKPRC is used, a pre-condition is that no lob columns.
* But in the future, when we do support LOB in LMTBLKPRC, the drda spec still
* does not allow LOB to be sent with OPNQRYRM. So this "if" here will have
* to add "no lob columns".
*/
if (stmt.getQryprctyp() == CodePoint.LMTBLKPRC) {
writeQRYDTA(stmt);
}
} else if (!sendSQLDTARD) {
long updateCount = ps.getLargeUpdateCount();
// The protocol wants us to send RDBUPDRM here, but we don't do
// that because it used to cause protocol errors. DERBY-5847 has
// some discussion about this issue.
checkWarning(database.getConnection(), stmt.ps, null, updateCount, true, true);
}
} while (hasResultSet && (++rsNum < numResults));
}
use of org.apache.derby.iapi.jdbc.EnginePreparedStatement in project derby by apache.
the class DRDAConnThread method processCommands.
/**
* Process DRDA commands we can receive once server attributes have been
* exchanged.
*
* @exception DRDAProtocolException
*/
private void processCommands() throws DRDAProtocolException {
DRDAStatement stmt = null;
boolean PRPSQLSTTfailed = false;
boolean checkSecurityCodepoint = session.requiresSecurityCodepoint();
do {
correlationID = reader.readDssHeader();
int codePoint = reader.readLengthAndCodePoint(false);
int writerMark = writer.markDSSClearPoint();
if (checkSecurityCodepoint) {
verifyInOrderACCSEC_SECCHK(codePoint, session.getRequiredSecurityCodepoint());
}
switch(codePoint) {
case CodePoint.CNTQRY:
try {
stmt = parseCNTQRY();
if (stmt != null) {
writeQRYDTA(stmt);
if (stmt.rsIsClosed()) {
writeENDQRYRM(CodePoint.SVRCOD_WARNING);
writeNullSQLCARDobject();
}
// Send any warnings if JCC can handle them
checkWarning(null, null, stmt.getResultSet(), 0, false, sendWarningsOnCNTQRY);
writePBSD();
}
} catch (SQLException e) {
// if we got a SQLException we need to clean up and
// close the result set Beetle 4758
cleanUpAndCloseResultSet(stmt, e, writerMark);
}
break;
case CodePoint.EXCSQLIMM:
try {
long updateCount = parseEXCSQLIMM();
// does an update (that is the most conservative thing)
if (database.RDBUPDRM_sent == false) {
writeRDBUPDRM();
}
// we need to set update count in SQLCARD
checkWarning(null, database.getDefaultStatement().getStatement(), null, updateCount, true, true);
writePBSD();
} catch (SQLException e) {
writer.clearDSSesBackToMark(writerMark);
writeSQLCARDs(e, 0);
errorInChain(e);
}
break;
case CodePoint.EXCSQLSET:
try {
if (parseEXCSQLSET()) {
// all went well.
writeSQLCARDs(null, 0);
}
} catch (SQLWarning w) {
writeSQLCARD(w, 0, 0);
} catch (SQLException e) {
writer.clearDSSesBackToMark(writerMark);
writeSQLCARDs(e, 0);
errorInChain(e);
}
break;
case CodePoint.PRPSQLSTT:
int sqldaType;
PRPSQLSTTfailed = false;
try {
database.getConnection().clearWarnings();
sqldaType = parsePRPSQLSTT();
database.getCurrentStatement().sqldaType = sqldaType;
if (sqldaType > 0) {
// do write SQLDARD
writeSQLDARD(database.getCurrentStatement(), (sqldaType == CodePoint.TYPSQLDA_LIGHT_OUTPUT), database.getConnection().getWarnings());
} else {
checkWarning(database.getConnection(), null, null, 0, true, true);
}
} catch (SQLException e) {
writer.clearDSSesBackToMark(writerMark);
writeSQLCARDs(e, 0, true);
PRPSQLSTTfailed = true;
errorInChain(e);
}
break;
case CodePoint.OPNQRY:
try {
/*try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
System.out.println("interrupted exception: " + ie.getMessage());
ie.printStackTrace();
}*/
if (PRPSQLSTTfailed) {
// read the command objects
// for ps with parameter
// Skip objects/parameters
skipRemainder(true);
// If we failed to prepare, then we fail
// to open, which means OPNQFLRM.
writeOPNQFLRM(null);
break;
}
Pkgnamcsn pkgnamcsn = parseOPNQRY();
if (pkgnamcsn != null) {
stmt = database.getDRDAStatement(pkgnamcsn);
PreparedStatement ps = stmt.getPreparedStatement();
ps.clearWarnings();
if (pendingStatementTimeout >= 0) {
ps.setQueryTimeout(pendingStatementTimeout);
pendingStatementTimeout = -1;
}
stmt.execute();
writeOPNQRYRM(false, stmt);
checkWarning(null, ps, null, 0, false, true);
long sentVersion = stmt.versionCounter;
long currentVersion = ((EnginePreparedStatement) stmt.ps).getVersionCounter();
if (stmt.sqldaType == CodePoint.TYPSQLDA_LIGHT_OUTPUT && currentVersion != sentVersion) {
// DERBY-5459. The prepared statement has a
// result set and has changed on the server
// since we last informed the client about its
// shape, so re-send metadata.
//
// NOTE: This is an extension of the standard
// DRDA protocol since we send the SQLDARD
// even if it isn't requested in this case.
// This is OK because there is already code on the
// client to handle an unrequested SQLDARD at
// this point in the protocol.
writeSQLDARD(stmt, true, null);
}
writeQRYDSC(stmt, false);
stmt.rsSuspend();
if (stmt.getQryprctyp() == CodePoint.LMTBLKPRC && stmt.getQryrowset() != 0) {
// The DRDA spec allows us to send
// QRYDTA here if there are no LOB
// columns.
DRDAResultSet drdars = stmt.getCurrentDrdaResultSet();
try {
if (drdars != null && !drdars.hasLobColumns()) {
writeQRYDTA(stmt);
}
} catch (SQLException sqle) {
cleanUpAndCloseResultSet(stmt, sqle, writerMark);
}
}
}
writePBSD();
} catch (SQLException e) {
writer.clearDSSesBackToMark(writerMark);
// The fix for DERBY-1196 removed code
// here to close the prepared statement
// if OPNQRY failed.
writeOPNQFLRM(e);
}
break;
case CodePoint.RDBCMM:
try {
if (SanityManager.DEBUG) {
trace("Received commit");
}
if (!database.getConnection().getAutoCommit()) {
database.getConnection().clearWarnings();
database.commit();
writeENDUOWRM(COMMIT);
checkWarning(database.getConnection(), null, null, 0, true, true);
}
// we only want to write one of these per transaction
// so set to false in preparation for next command
database.RDBUPDRM_sent = false;
} catch (SQLException e) {
writer.clearDSSesBackToMark(writerMark);
// Even in case of error, we have to write the ENDUOWRM.
writeENDUOWRM(COMMIT);
writeSQLCARDs(e, 0);
errorInChain(e);
}
break;
case CodePoint.RDBRLLBCK:
try {
if (SanityManager.DEBUG) {
trace("Received rollback");
}
database.getConnection().clearWarnings();
database.rollback();
writeENDUOWRM(ROLLBACK);
checkWarning(database.getConnection(), null, null, 0, true, true);
// we only want to write one of these per transaction
// so set to false in preparation for next command
database.RDBUPDRM_sent = false;
} catch (SQLException e) {
writer.clearDSSesBackToMark(writerMark);
// Even in case of error, we have to write the ENDUOWRM.
writeENDUOWRM(ROLLBACK);
writeSQLCARDs(e, 0);
errorInChain(e);
}
break;
case CodePoint.CLSQRY:
try {
stmt = parseCLSQRY();
stmt.rsClose();
writeSQLCARDs(null, 0);
} catch (SQLException e) {
writer.clearDSSesBackToMark(writerMark);
writeSQLCARDs(e, 0);
errorInChain(e);
}
break;
case CodePoint.EXCSAT:
parseEXCSAT();
writeEXCSATRD();
break;
case CodePoint.ACCSEC:
int securityCheckCode = parseACCSEC();
writeACCSECRD(securityCheckCode);
/* ACCSECRD is the last reply that is mandatorily in EBCDIC */
if (appRequester.supportsUtf8Ccsid()) {
switchToUtf8();
} else {
/* This thread might serve several requests.
* Revert if not supported by current client. */
switchToEbcdic();
}
checkSecurityCodepoint = true;
break;
case CodePoint.SECCHK:
if (parseDRDAConnection()) {
// security all checked and connection ok
checkSecurityCodepoint = false;
}
break;
/* since we don't support sqlj, we won't get bind commands from jcc, we
* might get it from ccc; just skip them.
*/
case CodePoint.BGNBND:
reader.skipBytes();
writeSQLCARDs(null, 0);
break;
case CodePoint.BNDSQLSTT:
reader.skipBytes();
parseSQLSTTDss();
writeSQLCARDs(null, 0);
break;
case CodePoint.SQLSTTVRB:
// optional
reader.skipBytes();
break;
case CodePoint.ENDBND:
reader.skipBytes();
writeSQLCARDs(null, 0);
break;
case CodePoint.DSCSQLSTT:
if (PRPSQLSTTfailed) {
reader.skipBytes();
writeSQLCARDs(null, 0);
break;
}
try {
boolean rtnOutput = parseDSCSQLSTT();
writeSQLDARD(database.getCurrentStatement(), rtnOutput, null);
} catch (SQLException e) {
writer.clearDSSesBackToMark(writerMark);
server.consoleExceptionPrint(e);
try {
writeSQLDARD(database.getCurrentStatement(), true, e);
} catch (SQLException e2) {
// should not get here since doing nothing with ps
agentError("Why am I getting another SQLException?");
}
errorInChain(e);
}
break;
case CodePoint.EXCSQLSTT:
if (PRPSQLSTTfailed) {
// Skip parameters too if they are chained Beetle 4867
skipRemainder(true);
writeSQLCARDs(null, 0);
break;
}
try {
parseEXCSQLSTT();
DRDAStatement curStmt = database.getCurrentStatement();
if (curStmt != null) {
curStmt.rsSuspend();
}
writePBSD();
} catch (SQLException e) {
skipRemainder(true);
writer.clearDSSesBackToMark(writerMark);
if (SanityManager.DEBUG) {
server.consoleExceptionPrint(e);
}
writeSQLCARDs(e, 0);
errorInChain(e);
}
break;
case CodePoint.SYNCCTL:
if (xaProto == null) {
xaProto = new DRDAXAProtocol(this);
}
xaProto.parseSYNCCTL();
try {
writePBSD();
} catch (SQLException se) {
server.consoleExceptionPrint(se);
errorInChain(se);
}
break;
default:
codePointNotSupported(codePoint);
}
if (SanityManager.DEBUG) {
String cpStr = new CodePointNameTable().lookup(codePoint);
try {
PiggyBackedSessionData pbsd = database.getPiggyBackedSessionData(false);
// piggy-backing mechanism.
if (!this.deferredReset && pbsd != null) {
// Session data has already been piggy-backed. Refresh
// the data from the connection, to make sure it has
// not changed behind our back.
pbsd.refresh();
SanityManager.ASSERT(!pbsd.isModified(), "Unexpected PBSD modification: " + pbsd + " after codePoint " + cpStr);
}
// Not having a pbsd here is ok. No data has been
// piggy-backed and the client has no cached values.
// If needed it will send an explicit request to get
// session data
} catch (SQLException sqle) {
server.consoleExceptionPrint(sqle);
SanityManager.THROWASSERT("Unexpected exception after " + "codePoint " + cpStr, sqle);
}
}
// Set the correct chaining bits for whatever
// reply DSS(es) we just wrote. If we've reached
// the end of the chain, this method will send
// the DSS(es) across.
finalizeChain();
} while (reader.isChainedWithSameID() || reader.isChainedWithDiffID());
}
Aggregations