1 | /* |
2 | |
3 | Derby - Class org.apache.derby.client.net.NetStatementReply |
4 | |
5 | Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.client.net; |
22 | |
23 | import org.apache.derby.client.am.ColumnMetaData; |
24 | import org.apache.derby.client.am.DisconnectException; |
25 | import org.apache.derby.client.am.PreparedStatementCallbackInterface; |
26 | import org.apache.derby.client.am.ResultSetCallbackInterface; |
27 | import org.apache.derby.client.am.Section; |
28 | import org.apache.derby.client.am.SqlState; |
29 | import org.apache.derby.client.am.SqlException; |
30 | import org.apache.derby.client.am.Statement; |
31 | import org.apache.derby.client.am.StatementCallbackInterface; |
32 | import org.apache.derby.client.am.Types; |
33 | import org.apache.derby.client.am.Utils; |
34 | import org.apache.derby.jdbc.ClientDriver; |
35 | import org.apache.derby.client.am.ClientJDBCObjectFactory; |
36 | import org.apache.derby.shared.common.i18n.MessageUtil; |
37 | import org.apache.derby.shared.common.reference.JDBC30Translation; |
38 | import org.apache.derby.client.am.ClientMessageId; |
39 | import org.apache.derby.shared.common.reference.SQLState; |
40 | import org.apache.derby.shared.common.reference.MessageId; |
41 | |
42 | public class NetStatementReply extends NetPackageReply implements StatementReplyInterface { |
43 | NetStatementReply(NetAgent netAgent, int bufferSize) { |
44 | super(netAgent, bufferSize); |
45 | } |
46 | |
47 | //----------------------------- entry points --------------------------------- |
48 | |
49 | public void readPrepareDescribeOutput(StatementCallbackInterface statement) throws DisconnectException { |
50 | startSameIdChainParse(); |
51 | parsePRPSQLSTTreply(statement); |
52 | endOfSameIdChainData(); |
53 | } |
54 | |
55 | public void readExecuteImmediate(StatementCallbackInterface statement) throws DisconnectException { |
56 | startSameIdChainParse(); |
57 | parseEXCSQLIMMreply(statement); |
58 | endOfSameIdChainData(); |
59 | } |
60 | |
61 | public void readOpenQuery(StatementCallbackInterface statement) throws DisconnectException { |
62 | startSameIdChainParse(); |
63 | parseOPNQRYreply(statement); |
64 | endOfSameIdChainData(); |
65 | } |
66 | |
67 | public void readExecute(PreparedStatementCallbackInterface preparedStatement) throws DisconnectException { |
68 | startSameIdChainParse(); |
69 | parseEXCSQLSTTreply(preparedStatement); |
70 | endOfSameIdChainData(); |
71 | } |
72 | |
73 | public void readPrepare(StatementCallbackInterface statement) throws DisconnectException { |
74 | startSameIdChainParse(); |
75 | parsePRPSQLSTTreply(statement); |
76 | endOfSameIdChainData(); |
77 | } |
78 | |
79 | public void readDescribeInput(PreparedStatementCallbackInterface preparedStatement) throws DisconnectException { |
80 | if (longBufferForDecryption_ != null) { |
81 | buffer_ = longBufferForDecryption_; |
82 | pos_ = longPosForDecryption_; |
83 | count_ = longCountForDecryption_; |
84 | if (longBufferForDecryption_ != null && count_ > longBufferForDecryption_.length) { |
85 | count_ = longBufferForDecryption_.length; |
86 | } |
87 | dssLength_ = 0; |
88 | longBufferForDecryption_ = null; |
89 | } |
90 | |
91 | startSameIdChainParse(); |
92 | parseDSCSQLSTTreply(preparedStatement, 1); // anything other than 0 for input |
93 | endOfSameIdChainData(); |
94 | } |
95 | |
96 | public void readDescribeOutput(PreparedStatementCallbackInterface preparedStatement) throws DisconnectException { |
97 | startSameIdChainParse(); |
98 | parseDSCSQLSTTreply(preparedStatement, 0); // 0 for output |
99 | endOfSameIdChainData(); |
100 | } |
101 | |
102 | public void readExecuteCall(StatementCallbackInterface statement) throws DisconnectException { |
103 | startSameIdChainParse(); |
104 | parseEXCSQLSTTreply(statement); |
105 | endOfSameIdChainData(); |
106 | } |
107 | |
108 | |
109 | //----------------------helper methods---------------------------------------- |
110 | |
111 | //------------------parse reply for specific command-------------------------- |
112 | |
113 | // These methods are "private protected", which is not a recognized java privilege, |
114 | // but means that these methods are private to this class and to subclasses, |
115 | // and should not be used as package-wide friendly methods. |
116 | |
117 | private void parsePRPSQLSTTreply(StatementCallbackInterface statement) throws DisconnectException { |
118 | int peekCP = parseTypdefsOrMgrlvlovrs(); |
119 | |
120 | if (peekCP == CodePoint.SQLDARD) { |
121 | // the sqlcagrp is most likely null for insert/update/deletes. if it is null, then we can |
122 | // peek ahead for the column number which most likely will be 0. if it is 0, then we will |
123 | // not new up a ColumnMetaData, and we can skip the rest of the bytes in sqldard. |
124 | // if sqlcargrp is not null, (most likely for select's) then we will not peek ahead for the |
125 | // column number since it will never be 0 in a select case. |
126 | ColumnMetaData columnMetaData = null; |
127 | NetSqlca netSqlca = null; |
128 | boolean nullSqlca = peekForNullSqlcagrp(); |
129 | if (nullSqlca && peekNumOfColumns() == 0) { |
130 | netSqlca = parseSQLDARD(columnMetaData, true); // true means to skip the rest of SQLDARD bytes |
131 | } else { |
132 | columnMetaData = ClientDriver.getFactory().newColumnMetaData(netAgent_.logWriter_); |
133 | netSqlca = parseSQLDARD(columnMetaData, false); // false means do not skip SQLDARD bytes. |
134 | } |
135 | |
136 | statement.completePrepareDescribeOutput(columnMetaData, |
137 | netSqlca); |
138 | } else if (peekCP == CodePoint.SQLCARD) { |
139 | NetSqlca netSqlca = parseSQLCARD(null); |
140 | statement.completePrepare(netSqlca); |
141 | } else { |
142 | parsePrepareError(statement); |
143 | } |
144 | |
145 | } |
146 | |
147 | // Parse the reply for the Describe SQL Statement Command. |
148 | // This method handles the parsing of all command replies and reply data |
149 | // for the dscsqlstt command. |
150 | private void parseDSCSQLSTTreply(PreparedStatementCallbackInterface ps, |
151 | int metaDataType) // 0 is output, else input |
152 | throws DisconnectException { |
153 | int peekCP = parseTypdefsOrMgrlvlovrs(); |
154 | |
155 | if (peekCP == CodePoint.SQLDARD) { |
156 | ColumnMetaData columnMetaData = null; |
157 | |
158 | if (columnMetaData == null) { |
159 | columnMetaData = ClientDriver.getFactory().newColumnMetaData(netAgent_.logWriter_); |
160 | } |
161 | |
162 | NetSqlca netSqlca = parseSQLDARD(columnMetaData, false); // false means do not skip SQLDARD bytes |
163 | if (columnMetaData.columns_ == 0) { |
164 | columnMetaData = null; |
165 | } |
166 | |
167 | if (metaDataType == 0) // DESCRIBE OUTPUT |
168 | { |
169 | ps.completeDescribeOutput(columnMetaData, netSqlca); |
170 | } else { |
171 | ps.completeDescribeInput(columnMetaData, netSqlca); |
172 | } |
173 | } else if (peekCP == CodePoint.SQLCARD) { |
174 | NetSqlca netSqlca = parseSQLCARD(null); |
175 | if (metaDataType == 0) // DESCRIBE OUTPUT |
176 | { |
177 | ps.completeDescribeOutput(null, netSqlca); |
178 | } else { |
179 | ps.completeDescribeInput(null, netSqlca); |
180 | } |
181 | } else { |
182 | parseDescribeError(ps); |
183 | } |
184 | |
185 | } |
186 | |
187 | // Parse the reply for the Execute Immediate SQL Statement Command. |
188 | // This method handles the parsing of all command replies and reply data |
189 | // for the excsqlimm command. |
190 | private void parseEXCSQLIMMreply(StatementCallbackInterface statement) throws DisconnectException { |
191 | int peekCP = parseTypdefsOrMgrlvlovrs(); |
192 | |
193 | if (peekCP == CodePoint.RDBUPDRM) { |
194 | parseRDBUPDRM(); |
195 | peekCP = parseTypdefsOrMgrlvlovrs(); |
196 | } |
197 | |
198 | switch (peekCP) { |
199 | case CodePoint.ENDUOWRM: |
200 | parseENDUOWRM(statement.getConnectionCallbackInterface()); |
201 | parseTypdefsOrMgrlvlovrs(); |
202 | case CodePoint.SQLCARD: |
203 | NetSqlca netSqlca = parseSQLCARD(null); |
204 | |
205 | |
206 | statement.completeExecuteImmediate(netSqlca); |
207 | break; |
208 | default: |
209 | parseExecuteImmediateError(statement); |
210 | break; |
211 | } |
212 | |
213 | } |
214 | |
215 | // Parse the reply for the Open Query Command. |
216 | // This method handles the parsing of all command replies and reply data for the opnqry command. |
217 | // will be replaced by parseOPNQRYreply (see parseOPNQRYreplyProto) |
218 | private void parseOPNQRYreply(StatementCallbackInterface statementI) throws DisconnectException { |
219 | int peekCP = peekCodePoint(); |
220 | |
221 | if (peekCP == CodePoint.OPNQRYRM) { |
222 | parseOpenQuery(statementI); |
223 | peekCP = peekCodePoint(); |
224 | if (peekCP == CodePoint.RDBUPDRM) { |
225 | parseRDBUPDRM(); |
226 | peekCP = peekCodePoint(); |
227 | } |
228 | } else if (peekCP == CodePoint.RDBUPDRM) { |
229 | parseRDBUPDRM(); |
230 | parseOpenQuery(statementI); |
231 | peekCP = peekCodePoint(); |
232 | } else if (peekCP == CodePoint.OPNQFLRM) { |
233 | parseOpenQueryFailure(statementI); |
234 | peekCP = peekCodePoint(); |
235 | } else { |
236 | parseOpenQueryError(statementI); |
237 | peekCP = peekCodePoint(); |
238 | } |
239 | |
240 | } |
241 | |
242 | // Called by NETSetClientPiggybackCommand.read() |
243 | private void parseEXCSQLSETreply(StatementCallbackInterface statement) throws DisconnectException { |
244 | int peekCP = parseTypdefsOrMgrlvlovrs(); |
245 | |
246 | if (peekCP == CodePoint.RDBUPDRM) { |
247 | parseRDBUPDRM(); |
248 | parseTypdefsOrMgrlvlovrs(); |
249 | } else if (peekCP == CodePoint.ENDUOWRM) { |
250 | parseENDUOWRM(statement.getConnectionCallbackInterface()); |
251 | parseTypdefsOrMgrlvlovrs(); |
252 | } |
253 | |
254 | if (peekCP == CodePoint.SQLCARD) { |
255 | NetSqlca netSqlca = parseSQLCARD(null); |
256 | statement.completeExecuteSetStatement(netSqlca); |
257 | } else { |
258 | parseExecuteSetStatementError(statement); |
259 | } |
260 | |
261 | } |
262 | |
263 | // Parse the reply for the Execute SQL Statement Command. |
264 | // This method handles the parsing of all command replies and reply data |
265 | // for the excsqlstt command. |
266 | // Also called by CallableStatement.readExecuteCall() |
267 | private void parseEXCSQLSTTreply(StatementCallbackInterface statementI) throws DisconnectException { |
268 | // first handle the transaction component, which consists of one or more |
269 | // reply messages indicating the transaction state. |
270 | // These are ENDUOWRM, CMMRQSRM, or RDBUPDRM. If RDBUPDRM is returned, |
271 | // it may be followed by ENDUOWRM or CMMRQSRM |
272 | int peekCP = peekCodePoint(); |
273 | if (peekCP == CodePoint.RDBUPDRM) { |
274 | parseRDBUPDRM(); |
275 | peekCP = peekCodePoint(); |
276 | } |
277 | |
278 | if (peekCP == CodePoint.ENDUOWRM) { |
279 | parseENDUOWRM(statementI.getConnectionCallbackInterface()); |
280 | peekCP = peekCodePoint(); |
281 | } |
282 | |
283 | // Check for a RSLSETRM, this is first rm of the result set summary component |
284 | // which would be returned if a stored procedure was called which returned result sets. |
285 | if (peekCP == CodePoint.RSLSETRM) { |
286 | parseResultSetProcedure(statementI); |
287 | peekCP = peekCodePoint(); |
288 | if (peekCP == CodePoint.RDBUPDRM) { |
289 | parseRDBUPDRM(); |
290 | } |
291 | return; |
292 | } |
293 | |
294 | // check for a possible TYPDEFNAM or TYPDEFOVR which may be present |
295 | // before the SQLCARD or SQLDTARD. |
296 | peekCP = parseTypdefsOrMgrlvlovrs(); |
297 | |
298 | // an SQLCARD may be retunred if there was no output data, result sets or parameters, |
299 | // or in the case of an error. |
300 | if (peekCP == CodePoint.SQLCARD) { |
301 | NetSqlca netSqlca = parseSQLCARD(null); |
302 | |
303 | statementI.completeExecute(netSqlca); |
304 | } else if (peekCP == CodePoint.SQLDTARD) { |
305 | // in the case of singleton select or if a stored procedure was called which had |
306 | // parameters but no result sets, an SQLSTARD may be returned |
307 | // keep the PreparedStatementCallbackInterface, since only preparedstatement and callablestatement |
308 | // has parameters or singleton select which translates to sqldtard. |
309 | NetSqldta netSqldta = null; |
310 | boolean useCachedSingletonRowData = false; |
311 | if (((Statement) statementI).cachedSingletonRowData_ == null) { |
312 | netSqldta = new NetSqldta(netAgent_); |
313 | } else { |
314 | netSqldta = (NetSqldta) ((Statement) statementI).cachedSingletonRowData_; |
315 | netSqldta.resetDataBuffer(); |
316 | netSqldta.extdtaData_.clear(); |
317 | useCachedSingletonRowData = true; |
318 | } |
319 | NetSqlca netSqlca = |
320 | parseSQLDTARD(netSqldta); |
321 | |
322 | // there may be externalized LOB data which also gets returned. |
323 | peekCP = peekCodePoint(); |
324 | while (peekCP == CodePoint.EXTDTA) { |
325 | copyEXTDTA(netSqldta); |
326 | peekCP = peekCodePoint(); |
327 | } |
328 | statementI.completeExecuteCall(netSqlca, netSqldta); |
329 | } else { |
330 | // if here, then assume an error reply message was returned. |
331 | parseExecuteError(statementI); |
332 | } |
333 | |
334 | } |
335 | |
336 | protected void parseResultSetProcedure(StatementCallbackInterface statementI) throws DisconnectException { |
337 | // when a stored procedure is called which returns result sets, |
338 | // the next thing to be returned after the optional transaction component |
339 | // is the summary component. |
340 | // |
341 | // Parse the Result Set Summary Component which consists of a |
342 | // Result Set Reply Message, SQLCARD or SQLDTARD, and an SQL Result Set |
343 | // Reply data object. Also check for possible TYPDEF overrides before the |
344 | // OBJDSSs. |
345 | // This method returns an ArrayList of generated sections which contain the |
346 | // package and section information for the result sets which were opened on the |
347 | // server. |
348 | |
349 | // the result set summary component consists of a result set reply message. |
350 | java.util.ArrayList sectionAL = parseRSLSETRM(); |
351 | |
352 | // following the RSLSETRM is an SQLCARD or an SQLDTARD. check for a |
353 | // TYPDEFNAM or TYPDEFOVR before looking for these objects. |
354 | int peekCP = parseTypdefsOrMgrlvlovrs(); |
355 | |
356 | // The SQLCARD and the SQLDTARD are mutually exclusive. |
357 | // The SQLDTARD is returned if the stored procedure had parameters. |
358 | // (Note: the SQLDTARD contains an sqlca also. this is the sqlca for the |
359 | // stored procedure call. |
360 | NetSqldta netSqldta = null; |
361 | NetSqlca netSqlca = null; |
362 | if (peekCP == CodePoint.SQLCARD) { |
363 | netSqlca = parseSQLCARD(null); |
364 | } else { |
365 | // keep the PreparedStatementCallbackInterface, since only preparedstatement and callablestatement |
366 | // has parameters or singleton select which translates to sqldtard. |
367 | netSqldta = new NetSqldta(netAgent_); |
368 | netSqlca = parseSQLDTARD(netSqldta); |
369 | } |
370 | |
371 | // check for a possible TYPDEFNAM or TYPDEFOVR |
372 | // before the SQL Result Set Reply Data object |
373 | peekCP = parseTypdefsOrMgrlvlovrs(); |
374 | |
375 | int numberOfResultSets = parseSQLRSLRD(sectionAL); |
376 | |
377 | // The result set summary component parsed above indicated how many result sets were opened |
378 | // by the stored pocedure call. It contained section information for |
379 | // each of these result sets. Loop through the section array and |
380 | // parse the result set component for each of the retunred result sets. |
381 | NetResultSet[] resultSets = new NetResultSet[numberOfResultSets]; |
382 | for (int i = 0; i < numberOfResultSets; i++) { |
383 | // parse the result set component of the stored procedure reply. |
384 | NetResultSet netResultSet = parseResultSetCursor(statementI, (Section) sectionAL.get(i)); |
385 | resultSets[i] = netResultSet; |
386 | } |
387 | |
388 | // LOBs may have been returned for one of the stored procedure parameters so |
389 | // check for any externalized data. |
390 | peekCP = peekCodePoint(); |
391 | while (peekCP == CodePoint.EXTDTA) { |
392 | copyEXTDTA(netSqldta); |
393 | peekCP = peekCodePoint(); |
394 | } |
395 | statementI.completeExecuteCall(netSqlca, netSqldta, resultSets); |
396 | } |
397 | |
398 | // Parse the Result Set component of the reply for a stored procedure |
399 | // call which returns result sets. |
400 | // The Result Set component consists of an Open Query Reply Message |
401 | // followed by an optional SQLCARD, followed by an optional |
402 | // SQL Column Information Reply data object, followed by a Query Descriptor. |
403 | // There may also be Query Data or an End of Query Reply Message. |
404 | protected NetResultSet parseResultSetCursor(StatementCallbackInterface statementI, |
405 | Section section) throws DisconnectException { |
406 | // The first item returne is an OPNQRYRM. |
407 | NetResultSet netResultSet = parseOPNQRYRM(statementI, false); |
408 | |
409 | // The next to be returned is an OBJDSS so check for any TYPDEF overrides. |
410 | int peekCP = parseTypdefsOrMgrlvlovrs(); |
411 | |
412 | // An SQLCARD may be returned if there were any warnings on the OPEN. |
413 | NetSqlca netSqlca = null; |
414 | if (peekCP == CodePoint.SQLCARD) { |
415 | netSqlca = parseSQLCARD(null); |
416 | peekCP = parseTypdefsOrMgrlvlovrs(); |
417 | } |
418 | |
419 | // the SQLCINRD contains SQLDA like information for the result set. |
420 | ColumnMetaData resultSetMetaData = null; |
421 | if (peekCP == CodePoint.SQLCINRD) { |
422 | resultSetMetaData = parseSQLCINRD(); |
423 | peekCP = parseTypdefsOrMgrlvlovrs(); |
424 | } |
425 | |
426 | // A Query Descriptor must be present. |
427 | // We cannot cache the cursor if result set is returned from a stored procedure, so |
428 | // there is no cached cursor to use here. |
429 | parseQRYDSC(netResultSet.netCursor_); |
430 | peekCP = peekCodePoint(); |
431 | statementI.completeExecuteCallOpenQuery(netSqlca, netResultSet, resultSetMetaData, section); |
432 | |
433 | // Depending on the blocking rules, QRYDTA may have been returned on the open. |
434 | while (peekCP == CodePoint.QRYDTA) { |
435 | parseQRYDTA(netResultSet); |
436 | peekCP = peekCodePoint(); |
437 | } |
438 | |
439 | // Under some circumstances, the server may have closed the cursor. |
440 | // This will be indicated by an ENDQRYRM. |
441 | if (peekCP == CodePoint.ENDQRYRM) { |
442 | parseEndQuery((ResultSetCallbackInterface) netResultSet); |
443 | } |
444 | |
445 | return netResultSet; |
446 | } |
447 | |
448 | protected void parseOpenQuery(StatementCallbackInterface statementI) throws DisconnectException { |
449 | NetResultSet netResultSet = parseOPNQRYRM(statementI, true); |
450 | |
451 | NetSqlca sqlca = null; |
452 | int peekCP = peekCodePoint(); |
453 | if (peekCP != CodePoint.QRYDSC) { |
454 | |
455 | peekCP = parseTypdefsOrMgrlvlovrs(); |
456 | |
457 | if (peekCP == CodePoint.SQLDARD) { |
458 | ColumnMetaData columnMetaData = ClientDriver.getFactory().newColumnMetaData(netAgent_.logWriter_); |
459 | NetSqlca netSqlca = parseSQLDARD(columnMetaData, false); // false means do not skip SQLDARD bytes |
460 | |
461 | //For java stored procedure, we got the resultSetMetaData from server, |
462 | //Do we need to save the resultSetMetaData and propagate netSqlca? |
463 | //The following statement are doing the both, but it do more than |
464 | //we want. It also mark the completion of Prepare statement. |
465 | // |
466 | // this will override the same call made from parsePrepareDescribe |
467 | // this will not work, this is not the DA for the stored proc params |
468 | statementI.completePrepareDescribeOutput(columnMetaData, netSqlca); |
469 | peekCP = parseTypdefsOrMgrlvlovrs(); |
470 | } |
471 | // check if the DARD is mutually exclusive with CARD, if so, then the following if should be an elese |
472 | |
473 | if (peekCP == CodePoint.SQLCARD) { |
474 | sqlca = parseSQLCARD(null); |
475 | peekCP = parseTypdefsOrMgrlvlovrs(); |
476 | } |
477 | } |
478 | parseQRYDSC(netResultSet.netCursor_); |
479 | |
480 | peekCP = peekCodePoint(); |
481 | while (peekCP == CodePoint.QRYDTA) { |
482 | parseQRYDTA(netResultSet); |
483 | peekCP = peekCodePoint(); |
484 | } |
485 | |
486 | if (peekCP == CodePoint.SQLCARD) { |
487 | NetSqlca netSqlca = parseSQLCARD(null); |
488 | statementI.completeSqlca(netSqlca); |
489 | peekCP = peekCodePoint(); |
490 | } |
491 | |
492 | if (peekCP == CodePoint.ENDQRYRM) { |
493 | parseEndQuery(netResultSet); |
494 | } |
495 | |
496 | statementI.completeOpenQuery(sqlca, netResultSet); |
497 | } |
498 | |
499 | protected void parseEndQuery(ResultSetCallbackInterface resultSetI) throws DisconnectException { |
500 | parseENDQRYRM(resultSetI); |
501 | parseTypdefsOrMgrlvlovrs(); |
502 | NetSqlca netSqlca = parseSQLCARD(null); |
503 | resultSetI.earlyCloseComplete(netSqlca); |
504 | } |
505 | |
506 | void parseOpenQueryFailure(StatementCallbackInterface statementI) throws DisconnectException { |
507 | parseOPNQFLRM(statementI); |
508 | parseTypdefsOrMgrlvlovrs(); |
509 | NetSqlca netSqlca = parseSQLCARD(null); |
510 | statementI.completeOpenQuery(netSqlca, null); |
511 | } |
512 | |
513 | void parsePrepareError(StatementCallbackInterface statement) throws DisconnectException { |
514 | int peekCP = peekCodePoint(); |
515 | switch (peekCP) { |
516 | case CodePoint.ABNUOWRM: |
517 | { |
518 | NetSqlca sqlca = parseAbnormalEndUow(statement.getConnectionCallbackInterface()); |
519 | statement.completeSqlca(sqlca); |
520 | break; |
521 | } |
522 | case CodePoint.CMDCHKRM: |
523 | parseCMDCHKRM(); |
524 | break; |
525 | case CodePoint.DTAMCHRM: |
526 | parseDTAMCHRM(); |
527 | break; |
528 | case CodePoint.OBJNSPRM: |
529 | parseOBJNSPRM(); |
530 | break; |
531 | case CodePoint.RDBNACRM: |
532 | parseRDBNACRM(); |
533 | break; |
534 | case CodePoint.SQLERRRM: |
535 | { |
536 | NetSqlca sqlca = parseSqlErrorCondition(); |
537 | statement.completeSqlca(sqlca); |
538 | break; |
539 | } |
540 | default: |
541 | parseCommonError(peekCP); |
542 | } |
543 | } |
544 | |
545 | void parseExecuteImmediateError(StatementCallbackInterface statement) throws DisconnectException { |
546 | int peekCP = peekCodePoint(); |
547 | switch (peekCP) { |
548 | case CodePoint.ABNUOWRM: |
549 | { |
550 | NetSqlca sqlca = parseAbnormalEndUow(statement.getConnectionCallbackInterface()); |
551 | statement.completeSqlca(sqlca); |
552 | break; |
553 | } |
554 | case CodePoint.CMDCHKRM: |
555 | parseCMDCHKRM(); |
556 | break; |
557 | case CodePoint.DTAMCHRM: |
558 | parseDTAMCHRM(); |
559 | break; |
560 | case CodePoint.OBJNSPRM: |
561 | parseOBJNSPRM(); |
562 | break; |
563 | case CodePoint.RDBNACRM: |
564 | parseRDBNACRM(); |
565 | break; |
566 | case CodePoint.SQLERRRM: |
567 | { |
568 | NetSqlca sqlca = parseSqlErrorCondition(); |
569 | statement.completeSqlca(sqlca); |
570 | break; |
571 | } |
572 | default: |
573 | parseCommonError(peekCP); |
574 | break; |
575 | } |
576 | } |
577 | |
578 | |
579 | void parseDescribeError(StatementCallbackInterface statement) throws DisconnectException { |
580 | int peekCP = peekCodePoint(); |
581 | switch (peekCP) { |
582 | case CodePoint.ABNUOWRM: |
583 | { |
584 | NetSqlca sqlca = parseAbnormalEndUow(statement.getConnectionCallbackInterface()); |
585 | statement.completeSqlca(sqlca); |
586 | break; |
587 | } |
588 | case CodePoint.CMDCHKRM: |
589 | parseCMDCHKRM(); |
590 | break; |
591 | case CodePoint.RDBNACRM: |
592 | parseRDBNACRM(); |
593 | break; |
594 | case CodePoint.SQLERRRM: |
595 | { |
596 | NetSqlca sqlca = parseSqlErrorCondition(); |
597 | statement.completeSqlca(sqlca); |
598 | break; |
599 | } |
600 | default: |
601 | parseCommonError(peekCP); |
602 | } |
603 | } |
604 | |
605 | |
606 | void parseOpenQueryError(StatementCallbackInterface statementI) throws DisconnectException { |
607 | int peekCP = peekCodePoint(); |
608 | switch (peekCP) { |
609 | case CodePoint.ABNUOWRM: |
610 | { |
611 | NetSqlca sqlca = parseAbnormalEndUow(statementI.getConnectionCallbackInterface()); |
612 | statementI.completeSqlca(sqlca); |
613 | break; |
614 | } |
615 | case CodePoint.CMDCHKRM: |
616 | parseCMDCHKRM(); |
617 | break; |
618 | case CodePoint.DTAMCHRM: |
619 | parseDTAMCHRM(); |
620 | break; |
621 | case CodePoint.OBJNSPRM: |
622 | parseOBJNSPRM(); |
623 | break; |
624 | case CodePoint.QRYPOPRM: |
625 | parseQRYPOPRM(); |
626 | break; |
627 | case CodePoint.RDBNACRM: |
628 | parseRDBNACRM(); |
629 | break; |
630 | default: |
631 | parseCommonError(peekCP); |
632 | } |
633 | } |
634 | |
635 | void parseExecuteError(StatementCallbackInterface statementI) throws DisconnectException { |
636 | int peekCP = peekCodePoint(); |
637 | switch (peekCP) { |
638 | case CodePoint.ABNUOWRM: |
639 | { |
640 | NetSqlca sqlca = parseAbnormalEndUow(statementI.getConnectionCallbackInterface()); |
641 | statementI.completeSqlca(sqlca); |
642 | break; |
643 | } |
644 | case CodePoint.CMDCHKRM: |
645 | parseCMDCHKRM(); |
646 | break; |
647 | case CodePoint.DTAMCHRM: |
648 | parseDTAMCHRM(); |
649 | break; |
650 | case CodePoint.OBJNSPRM: |
651 | parseOBJNSPRM(); |
652 | break; |
653 | case CodePoint.RDBNACRM: |
654 | parseRDBNACRM(); |
655 | break; |
656 | case CodePoint.SQLERRRM: |
657 | { |
658 | NetSqlca sqlca = parseSqlErrorCondition(); |
659 | statementI.completeSqlca(sqlca); |
660 | break; |
661 | } |
662 | default: |
663 | parseCommonError(peekCP); |
664 | break; |
665 | } |
666 | } |
667 | |
668 | void parseExecuteSetStatementError(StatementCallbackInterface statement) throws DisconnectException { |
669 | int peekCP = peekCodePoint(); |
670 | switch (peekCP) { |
671 | case CodePoint.ABNUOWRM: |
672 | { |
673 | NetSqlca sqlca = parseAbnormalEndUow(statement.getConnectionCallbackInterface()); |
674 | statement.completeSqlca(sqlca); |
675 | break; |
676 | } |
677 | case CodePoint.CMDCHKRM: |
678 | parseCMDCHKRM(); |
679 | break; |
680 | case CodePoint.DTAMCHRM: |
681 | parseDTAMCHRM(); |
682 | break; |
683 | case CodePoint.OBJNSPRM: |
684 | parseOBJNSPRM(); |
685 | break; |
686 | case CodePoint.RDBNACRM: |
687 | parseRDBNACRM(); |
688 | break; |
689 | case CodePoint.SQLERRRM: |
690 | { |
691 | NetSqlca sqlca = parseSqlErrorCondition(); |
692 | statement.completeSqlca(sqlca); |
693 | break; |
694 | } |
695 | default: |
696 | parseCommonError(peekCP); |
697 | break; |
698 | } |
699 | } |
700 | |
701 | |
702 | //-----------------------------parse DDM Reply Messages----------------------- |
703 | |
704 | /** |
705 | * Open Query Complete Reply Message indicates to the requester |
706 | * that an OPNQRY or EXCSQLSTT command completed normally and that |
707 | * the query process has been initiated. It also indicates the |
708 | * type of query protocol and cursor used for the query. |
709 | * <p> |
710 | * When an EXCSQLSTT contains an SQL statement that invokes a |
711 | * stored procedure, and the procedure completes, an OPNQRYRM is |
712 | * returned for each answer set. |
713 | * |
714 | * @param statementI statement callback interface |
715 | * @param isOPNQRYreply If true, parse a reply to an OPNQRY |
716 | * command. Otherwise, parse a reply to an EXCSQLSTT command. |
717 | * @return a <code>NetResultSet</code> value |
718 | * @exception DisconnectException |
719 | */ |
720 | protected NetResultSet parseOPNQRYRM(StatementCallbackInterface statementI, |
721 | boolean isOPNQRYreply) |
722 | throws DisconnectException |
723 | { |
724 | // these need to be initialized to the correct default values. |
725 | int svrcod = CodePoint.SVRCOD_INFO; |
726 | boolean svrcodReceived = false; |
727 | int qryprctyp = 0; |
728 | boolean qryprctypReceived = false; |
729 | int sqlcsrhld = 0xF0; // 0xF0 is false (default), 0xF1 is true. |
730 | boolean sqlcsrhldReceived = false; |
731 | int qryattscr = 0xF0; // 0xF0 is false (default), 0xF1 is true. |
732 | boolean qryattscrReceived = false; |
733 | int qryattsns = CodePoint.QRYUNK; |
734 | boolean qryattsnsReceived = false; |
735 | int qryattupd = CodePoint.QRYUNK; |
736 | boolean qryattupdReceived = false; |
737 | long qryinsid = 0; |
738 | boolean qryinsidReceived = false; |
739 | |
740 | |
741 | int qryattset = 0xF0; // 0xF0 is false (default), 0xF1 is true. |
742 | boolean qryattsetReceived = false; |
743 | |
744 | parseLengthAndMatchCodePoint(CodePoint.OPNQRYRM); |
745 | //pushLengthOnCollectionStack(); |
746 | int ddmLength = getDdmLength(); |
747 | ensureBLayerDataInBuffer(ddmLength); |
748 | int peekCP = peekCodePoint(); |
749 | int length = 0; |
750 | |
751 | //while (peekCP != Reply.END_OF_COLLECTION) { |
752 | while (ddmLength > 0) { |
753 | |
754 | boolean foundInPass = false; |
755 | |
756 | if (peekCP == CodePoint.SVRCOD) { |
757 | foundInPass = true; |
758 | svrcodReceived = checkAndGetReceivedFlag(svrcodReceived); |
759 | length = peekedLength_; |
760 | svrcod = parseFastSVRCOD(CodePoint.SVRCOD_INFO, CodePoint.SVRCOD_SESDMG); |
761 | ddmLength = adjustDdmLength(ddmLength, length); |
762 | peekCP = peekCodePoint(); |
763 | } |
764 | |
765 | if (peekCP == CodePoint.QRYPRCTYP) { |
766 | foundInPass = true; |
767 | qryprctypReceived = checkAndGetReceivedFlag(qryprctypReceived); |
768 | length = peekedLength_; |
769 | qryprctyp = parseFastQRYPRCTYP(); |
770 | ddmLength = adjustDdmLength(ddmLength, length); |
771 | peekCP = peekCodePoint(); |
772 | } |
773 | |
774 | if (peekCP == CodePoint.SQLCSRHLD) { |
775 | // Indicates whether the requester specified the HOLD option. |
776 | // When specified, the cursor is not closed upon execution of a commit operation. |
777 | foundInPass = true; |
778 | sqlcsrhldReceived = checkAndGetReceivedFlag(sqlcsrhldReceived); |
779 | length = peekedLength_; |
780 | sqlcsrhld = parseFastSQLCSRHLD(); |
781 | ddmLength = adjustDdmLength(ddmLength, length); |
782 | peekCP = peekCodePoint(); |
783 | } |
784 | |
785 | if (peekCP == CodePoint.QRYATTSCR) { |
786 | foundInPass = true; |
787 | qryattscrReceived = checkAndGetReceivedFlag(qryattscrReceived); |
788 | length = peekedLength_; |
789 | qryattscr = parseFastQRYATTSCR(); |
790 | ddmLength = adjustDdmLength(ddmLength, length); |
791 | peekCP = peekCodePoint(); |
792 | } |
793 | |
794 | if (peekCP == CodePoint.QRYATTSNS) { |
795 | foundInPass = true; |
796 | qryattsnsReceived = checkAndGetReceivedFlag(qryattsnsReceived); |
797 | length = peekedLength_; |
798 | qryattsns = parseFastQRYATTSNS(); |
799 | ddmLength = adjustDdmLength(ddmLength, length); |
800 | peekCP = peekCodePoint(); |
801 | } |
802 | |
803 | if (peekCP == CodePoint.QRYATTUPD) { |
804 | foundInPass = true; |
805 | qryattupdReceived = checkAndGetReceivedFlag(qryattupdReceived); |
806 | length = peekedLength_; |
807 | qryattupd = parseFastQRYATTUPD(); |
808 | ddmLength = adjustDdmLength(ddmLength, length); |
809 | peekCP = peekCodePoint(); |
810 | } |
811 | |
812 | if (peekCP == CodePoint.QRYINSID) { |
813 | foundInPass = true; |
814 | qryinsidReceived = checkAndGetReceivedFlag(qryinsidReceived); |
815 | length = peekedLength_; |
816 | qryinsid = parseFastQRYINSID(); |
817 | ddmLength = adjustDdmLength(ddmLength, length); |
818 | peekCP = peekCodePoint(); |
819 | } |
820 | |
821 | if (peekCP == CodePoint.QRYATTSET) { |
822 | foundInPass = true; |
823 | qryattsetReceived = checkAndGetReceivedFlag(qryattsetReceived); |
824 | length = peekedLength_; |
825 | qryattset = parseFastQRYATTSET(); |
826 | ddmLength = adjustDdmLength(ddmLength, length); |
827 | peekCP = peekCodePoint(); |
828 | } |
829 | |
830 | |
831 | if (!foundInPass) { |
832 | doPrmnsprmSemantics(peekCP); |
833 | } |
834 | |
835 | } |
836 | checkRequiredObjects(svrcodReceived, qryprctypReceived, qryinsidReceived); |
837 | |
838 | netAgent_.setSvrcod(svrcod); |
839 | |
840 | // hack for now until event methods are used below |
841 | Statement statement = (Statement) statementI; |
842 | |
843 | // if there is a cached Cursor object, then use the cached cursor object. |
844 | NetResultSet rs = null; |
845 | if (statement.cachedCursor_ != null) { |
846 | statement.cachedCursor_.resetDataBuffer(); |
847 | ((NetCursor) statement.cachedCursor_).extdtaData_.clear(); |
848 | try { |
849 | rs = (NetResultSet)ClientDriver.getFactory().newNetResultSet |
850 | (netAgent_, |
851 | (NetStatement) statement.materialStatement_, |
852 | statement.cachedCursor_, |
853 | qryprctyp, //protocolType, CodePoint.FIXROWPRC | |
854 | // CodePoint.LMTBLKPRC |
855 | sqlcsrhld, //holdOption, 0xF0 for false (default) | 0xF1 for true. |
856 | qryattscr, //scrollOption, 0xF0 for false (default) | 0xF1 for true. |
857 | qryattsns, //sensitivity, CodePoint.QRYUNK | |
858 | // CodePoint.QRYINS | |
859 | // CodePoint.QRYSNSSTC |
860 | qryattset, |
861 | qryinsid, //instanceIdentifier, 0 (if not returned, check default) or number |
862 | calculateResultSetType(qryattscr, qryattsns, statement.resultSetType_), |
863 | calculateResultSetConcurrency(qryattupd, statement.resultSetConcurrency_), |
864 | calculateResultSetHoldability(sqlcsrhld)); |
865 | } catch(SqlException sqle) { |
866 | throw new DisconnectException(netAgent_,sqle); |
867 | } |
868 | } else { |
869 | try { |
870 | rs = (NetResultSet)ClientDriver.getFactory().newNetResultSet |
871 | (netAgent_, |
872 | (NetStatement) statement.materialStatement_, |
873 | new NetCursor(netAgent_, qryprctyp), |
874 | qryprctyp, //protocolType, CodePoint.FIXROWPRC | |
875 | // CodePoint.LMTBLKPRC |
876 | sqlcsrhld, //holdOption, 0xF0 for false (default) | 0xF1 for true. |
877 | qryattscr, //scrollOption, 0xF0 for false (default) | 0xF1 for true. |
878 | qryattsns, //sensitivity, CodePoint.QRYUNK | CodePoint.QRYINS |
879 | qryattset, |
880 | qryinsid, //instanceIdentifier, 0 (if not returned, check default) or number |
881 | calculateResultSetType(qryattscr, qryattsns, statement.resultSetType_), |
882 | calculateResultSetConcurrency(qryattupd, statement.resultSetConcurrency_), |
883 | calculateResultSetHoldability(sqlcsrhld)); |
884 | } catch(SqlException sqle) { |
885 | throw new DisconnectException(netAgent_,sqle); |
886 | } |
887 | |
888 | } |
889 | |
890 | // QRYCLSIMP only applies to OPNQRY, not EXCSQLSTT |
891 | final boolean qryclsimp = |
892 | isOPNQRYreply && |
893 | (rs.resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) && |
894 | netAgent_.netConnection_.serverSupportsQryclsimp(); |
895 | rs.netCursor_.setQryclsimpEnabled(qryclsimp); |
896 | |
897 | return rs; |
898 | } |
899 | |
900 | |
901 | // Also called by NetResultSetReply subclass. |
902 | // The End of Query Reply Message indicates that the query process has |
903 | // terminated in such a manner that the query or result set is now closed. |
904 | // It cannot be resumed with the CNTQRY command or closed with the CLSQRY command. |
905 | // The ENDQRYRM is always followed by an SQLCARD. |
906 | protected void parseENDQRYRM(ResultSetCallbackInterface resultSetI) throws DisconnectException { |
907 | boolean svrcodReceived = false; |
908 | int svrcod = CodePoint.SVRCOD_INFO; |
909 | boolean rdbnamReceived = false; |
910 | String rdbnam = null; |
911 | |
912 | parseLengthAndMatchCodePoint(CodePoint.ENDQRYRM); |
913 | pushLengthOnCollectionStack(); |
914 | int peekCP = peekCodePoint(); |
915 | |
916 | while (peekCP != Reply.END_OF_COLLECTION) { |
917 | |
918 | boolean foundInPass = false; |
919 | |
920 | if (peekCP == CodePoint.SVRCOD) { |
921 | foundInPass = true; |
922 | svrcodReceived = checkAndGetReceivedFlag(svrcodReceived); |
923 | svrcod = parseSVRCOD(CodePoint.SVRCOD_WARNING, CodePoint.SVRCOD_ERROR); |
924 | peekCP = peekCodePoint(); |
925 | } |
926 | |
927 | if (peekCP == CodePoint.RDBNAM) { |
928 | foundInPass = true; |
929 | rdbnamReceived = checkAndGetReceivedFlag(rdbnamReceived); |
930 | rdbnam = parseRDBNAM(true); |
931 | peekCP = peekCodePoint(); |
932 | } |
933 | if (!foundInPass) { |
934 | doPrmnsprmSemantics(peekCP); |
935 | } |
936 | |
937 | } |
938 | popCollectionStack(); |
939 | checkRequiredObjects(svrcodReceived); |
940 | |
941 | netAgent_.setSvrcod(svrcod); |
942 | |
943 | } |
944 | |
945 | |
946 | // Query Previously Opened Reply Message is issued when an |
947 | // OPNQRY command is issued for a query that is already open. |
948 | // A previous OPNQRY command might have opened the query |
949 | // which may not be closed. |
950 | // PROTOCOL Architects an SQLSTATE of 58008 or 58009. |
951 | // |
952 | // Messages |
953 | // SQLSTATE : 58009 |
954 | // Execution failed due to a distribution protocol error that caused deallocation of the conversation. |
955 | // SQLCODE : -30020 |
956 | // Execution failed because of a Distributed Protocol |
957 | // Error that will affect the successful execution of subsequent |
958 | // commands and SQL statements: Reason Code <reason-code>. |
959 | // Some possible reason codes include: |
960 | // 121C Indicates that the user is not authorized to perform the requested command. |
961 | // 1232 The command could not be completed because of a permanent error. |
962 | // In most cases, the server will be in the process of an abend. |
963 | // 220A The target server has received an invalid data description. |
964 | // If a user SQLDA is specified, ensure that the fields are |
965 | // initialized correctly. Also, ensure that the length does not |
966 | // exceed the maximum allowed length for the data type being used. |
967 | // |
968 | // The command or statement cannot be processed. The current |
969 | // transaction is rolled back and the application is disconnected |
970 | // from the remote database. |
971 | // |
972 | // |
973 | // Returned from Server: |
974 | // SVRCOD - required (8 - ERROR) |
975 | // RDBNAM - required |
976 | // PKGNAMCSN - required |
977 | // SRVDGN - optional |
978 | // |
979 | private void parseQRYPOPRM() throws DisconnectException { |
980 | boolean svrcodReceived = false; |
981 | int svrcod = CodePoint.SVRCOD_INFO; |
982 | boolean rdbnamReceived = false; |
983 | String rdbnam = null; |
984 | boolean pkgnamcsnReceived = false; |
985 | Object pkgnamcsn = null; |
986 | |
987 | parseLengthAndMatchCodePoint(CodePoint.QRYPOPRM); |
988 | pushLengthOnCollectionStack(); |
989 | int peekCP = peekCodePoint(); |
990 | |
991 | while (peekCP != Reply.END_OF_COLLECTION) { |
992 | |
993 | boolean foundInPass = false; |
994 | |
995 | if (peekCP == CodePoint.SVRCOD) { |
996 | foundInPass = true; |
997 | svrcodReceived = checkAndGetReceivedFlag(svrcodReceived); |
998 | svrcod = parseSVRCOD(CodePoint.SVRCOD_ERROR, CodePoint.SVRCOD_ERROR); |
999 | peekCP = peekCodePoint(); |
1000 | } |
1001 | |
1002 | if (peekCP == CodePoint.RDBNAM) { |
1003 | foundInPass = true; |
1004 | rdbnamReceived = checkAndGetReceivedFlag(rdbnamReceived); |
1005 | rdbnam = parseRDBNAM(true); |
1006 | peekCP = peekCodePoint(); |
1007 | } |
1008 | if (peekCP == CodePoint.PKGNAMCSN) { |
1009 | foundInPass = true; |
1010 | pkgnamcsnReceived = checkAndGetReceivedFlag(pkgnamcsnReceived); |
1011 | pkgnamcsn = parsePKGNAMCSN(true); |
1012 | peekCP = peekCodePoint(); |
1013 | } |
1014 | |
1015 | if (!foundInPass) { |
1016 | doPrmnsprmSemantics(peekCP); |
1017 | } |
1018 | |
1019 | } |
1020 | popCollectionStack(); |
1021 | checkRequiredObjects(svrcodReceived, |
1022 | rdbnamReceived, |
1023 | pkgnamcsnReceived); |
1024 | |
1025 | netAgent_.setSvrcod(svrcod); |
1026 | agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_, |
1027 | new ClientMessageId(SQLState.DRDA_CONNECTION_TERMINATED), |
1028 | MessageUtil.getCompleteMessage(MessageId.CONN_DRDA_QRYOPEN, |
1029 | SqlException.CLIENT_MESSAGE_RESOURCE_NAME, |
1030 | (Object [])null))); |
1031 | } |
1032 | |
1033 | // Open Query Failure (OPNQFLRM) Reply Message indicates that the |
1034 | // OPNQRY command failed to open the query. The reason that the |
1035 | // target relational database was unable to open the query is reported in an |
1036 | // SQLCARD reply data object. |
1037 | // Whenever an OPNQFLRM is returned, an SQLCARD object must also be returned |
1038 | // following the OPNQFLRM. |
1039 | // |
1040 | // Returned from Server: |
1041 | // SVRCOD - required (8 - ERROR) |
1042 | // RDBNAM - required |
1043 | // SRVDGN - optional |
1044 | private void parseOPNQFLRM(StatementCallbackInterface statement) throws DisconnectException { |
1045 | boolean svrcodReceived = false; |
1046 | int svrcod = CodePoint.SVRCOD_INFO; |
1047 | boolean rdbnamReceived = false; |
1048 | String rdbnam = null; |
1049 | |
1050 | parseLengthAndMatchCodePoint(CodePoint.OPNQFLRM); |
1051 | pushLengthOnCollectionStack(); |
1052 | int peekCP = peekCodePoint(); |
1053 | |
1054 | while (peekCP != Reply.END_OF_COLLECTION) { |
1055 | |
1056 | boolean foundInPass = false; |
1057 | |
1058 | if (peekCP == CodePoint.SVRCOD) { |
1059 | foundInPass = true; |
1060 | svrcodReceived = checkAndGetReceivedFlag(svrcodReceived); |
1061 | svrcod = parseSVRCOD(CodePoint.SVRCOD_ERROR, CodePoint.SVRCOD_ERROR); |
1062 | peekCP = peekCodePoint(); |
1063 | } |
1064 | |
1065 | if (peekCP == CodePoint.RDBNAM) { |
1066 | // skip the rdbnam since it doesn't tell us anything new. |
1067 | // there is no way to return it to the application anyway. |
1068 | // not having to convert this to a string is a time saver also. |
1069 | foundInPass = true; |
1070 | rdbnamReceived = checkAndGetReceivedFlag(rdbnamReceived); |
1071 | rdbnam = parseRDBNAM(true); |
1072 | peekCP = peekCodePoint(); |
1073 | } |
1074 | if (!foundInPass) { |
1075 | doPrmnsprmSemantics(peekCP); |
1076 | } |
1077 | |
1078 | } |
1079 | popCollectionStack(); |
1080 | checkRequiredObjects(svrcodReceived, rdbnamReceived); |
1081 | |
1082 | netAgent_.setSvrcod(svrcod); |
1083 | |
1084 | // get SQLSTATE from SQLCARD... |
1085 | } |
1086 | |
1087 | // RDB Result Set Reply Message (RSLSETRM) indicates that an |
1088 | // EXCSQLSTT command invoked a stored procedure, that the execution |
1089 | // of the stored procedure generated one or more result sets, and |
1090 | // additional information aobut these result sets follows the SQLCARD and |
1091 | // SQLDTARD in the reply data of the response |
1092 | // |
1093 | // Returned from Server: |
1094 | // SVRCOD - required (0 INFO) |
1095 | // PKGSNLST - required |
1096 | // SRVDGN - optional |
1097 | protected java.util.ArrayList parseRSLSETRM() throws DisconnectException { |
1098 | boolean svrcodReceived = false; |
1099 | int svrcod = CodePoint.SVRCOD_INFO; |
1100 | boolean pkgsnlstReceived = false; |
1101 | java.util.ArrayList pkgsnlst = null; |
1102 | |
1103 | parseLengthAndMatchCodePoint(CodePoint.RSLSETRM); |
1104 | pushLengthOnCollectionStack(); |
1105 | int peekCP = peekCodePoint(); |
1106 | |
1107 | while (peekCP != Reply.END_OF_COLLECTION) { |
1108 | |
1109 | boolean foundInPass = false; |
1110 | |
1111 | if (peekCP == CodePoint.SVRCOD) { |
1112 | foundInPass = true; |
1113 | svrcodReceived = checkAndGetReceivedFlag(svrcodReceived); |
1114 | svrcod = parseSVRCOD(CodePoint.SVRCOD_INFO, CodePoint.SVRCOD_INFO); |
1115 | peekCP = peekCodePoint(); |
1116 | } |
1117 | |
1118 | if (peekCP == CodePoint.PKGSNLST) { |
1119 | // contain repeatable PKGNAMCSN |
1120 | foundInPass = true; |
1121 | pkgsnlstReceived = checkAndGetReceivedFlag(pkgsnlstReceived); |
1122 | pkgsnlst = parsePKGSNLST(); |
1123 | peekCP = peekCodePoint(); |
1124 | } |
1125 | |
1126 | if (!foundInPass) { |
1127 | doPrmnsprmSemantics(peekCP); |
1128 | } |
1129 | |
1130 | } |
1131 | popCollectionStack(); |
1132 | checkRequiredObjects(svrcodReceived, pkgsnlstReceived); |
1133 | |
1134 | netAgent_.setSvrcod(svrcod); |
1135 | |
1136 | return pkgsnlst; |
1137 | } |
1138 | |
1139 | //--------------------- parse DDM Reply Data-------------------------------------- |
1140 | |
1141 | |
1142 | // SQL Data Reply Data consists of output data from the relational database (RDB) |
1143 | // processing of an SQL statement. It also includes a description of the data. |
1144 | // |
1145 | // Returned from Server: |
1146 | // FDODSC - required |
1147 | // FDODTA - required |
1148 | protected NetSqlca parseSQLDTARD(NetSqldta netSqldta) throws DisconnectException { |
1149 | boolean fdodscReceived = false; |
1150 | boolean fdodtaReceived = false; |
1151 | |
1152 | parseLengthAndMatchCodePoint(CodePoint.SQLDTARD); |
1153 | pushLengthOnCollectionStack(); |
1154 | |
1155 | NetSqlca netSqlca = null; |
1156 | int peekCP = peekCodePoint(); |
1157 | while (peekCP != Reply.END_OF_COLLECTION) { |
1158 | |
1159 | boolean foundInPass = false; |
1160 | |
1161 | if (peekCP == CodePoint.FDODSC) { |
1162 | foundInPass = true; |
1163 | fdodscReceived = checkAndGetReceivedFlag(fdodscReceived); |
1164 | parseFDODSC(netSqldta); |
1165 | peekCP = peekCodePoint(); |
1166 | } |
1167 | |
1168 | if (peekCP == CodePoint.FDODTA) { |
1169 | foundInPass = true; |
1170 | fdodtaReceived = checkAndGetReceivedFlag(fdodtaReceived); |
1171 | netSqlca = parseFDODTA(netSqldta); |
1172 | peekCP = peekCodePoint(); |
1173 | } |
1174 | |
1175 | if (!foundInPass) { |
1176 | doPrmnsprmSemantics(peekCP); |
1177 | } |
1178 | |
1179 | } |
1180 | popCollectionStack(); |
1181 | checkRequiredObjects(fdodscReceived, fdodtaReceived); |
1182 | netSqldta.calculateColumnOffsetsForRow(); |
1183 | return netSqlca; |
1184 | } |
1185 | |
1186 | protected void parseQRYDSC(NetCursor cursor) throws DisconnectException { |
1187 | parseLengthAndMatchCodePoint(CodePoint.QRYDSC); |
1188 | parseSQLDTARDarray(cursor, false); // false means don't just skip the bytes |
1189 | } |
1190 | |
1191 | private void parseFDODSC(NetCursor cursor) throws DisconnectException { |
1192 | parseLengthAndMatchCodePoint(CodePoint.FDODSC); |
1193 | parseSQLDTARDarray(cursor, false); // false means don't just skip the bytes |
1194 | } |
1195 | |
1196 | private void parseSQLDTARDarray(NetCursor cursor, boolean skipBytes) throws DisconnectException { |
1197 | if (skipBytes) { |
1198 | skipBytes(); |
1199 | } |
1200 | int previousTripletType = FdocaConstants.SQLDTARD_TRIPLET_TYPE_START; |
1201 | int previousTripletId = FdocaConstants.SQLDTARD_TRIPLET_ID_START; |
1202 | int mddProtocolType = 0; |
1203 | int columnCount = 0; |
1204 | netAgent_.targetTypdef_.clearMddOverrides(); |
1205 | |
1206 | int ddmLength = getDdmLength(); |
1207 | ensureBLayerDataInBuffer(ddmLength); |
1208 | |
1209 | while (ddmLength > 0) { |
1210 | |
1211 | int tripletLength = readFastUnsignedByte(); |
1212 | int tripletType = readFastUnsignedByte(); |
1213 | int tripletId = readFastUnsignedByte(); |
1214 | |
1215 | switch (tripletType) { |
1216 | |
1217 | case FdocaConstants.MDD_TRIPLET_TYPE: |
1218 | if ((tripletLength != FdocaConstants.MDD_TRIPLET_SIZE) || |
1219 | (tripletId != FdocaConstants.NULL_LID)) { |
1220 | descriptorErrorDetected(); |
1221 | } |
1222 | checkPreviousSQLDTARDtriplet(previousTripletType, |
1223 | FdocaConstants.SQLDTARD_TRIPLET_TYPE_MDD, |
1224 | previousTripletId, |
1225 | FdocaConstants.SQLDTARD_TRIPLET_ID_0); |
1226 | previousTripletType = FdocaConstants.SQLDTARD_TRIPLET_TYPE_MDD; |
1227 | previousTripletId = FdocaConstants.SQLDTARD_TRIPLET_ID_0; |
1228 | |
1229 | // read in remaining MDD bytes |
1230 | int mddClass = readFastUnsignedByte(); |
1231 | int mddType = readFastUnsignedByte(); |
1232 | int mddRefType = readFastUnsignedByte(); |
1233 | mddProtocolType = readFastUnsignedByte(); |
1234 | break; |
1235 | |
1236 | case FdocaConstants.NGDA_TRIPLET_TYPE: // rename to NGDA_TRIPLET_CODEPOINT |
1237 | if (tripletId != FdocaConstants.SQLDTAGRP_LID) { |
1238 | descriptorErrorDetected(); |
1239 | } |
1240 | checkPreviousSQLDTARDtriplet(previousTripletType, |
1241 | FdocaConstants.SQLDTARD_TRIPLET_TYPE_GDA, |
1242 | previousTripletId, |
1243 | FdocaConstants.SQLDTARD_TRIPLET_ID_D0); |
1244 | previousTripletType = FdocaConstants.SQLDTARD_TRIPLET_TYPE_GDA; |
1245 | previousTripletId = FdocaConstants.SQLDTARD_TRIPLET_ID_0; |
1246 | |
1247 | // add a quick check to see if the table is altered (columns are added or deleted) |
1248 | // before reusing the cached cursor. note: this check does not catch the case |
1249 | // where the number of columns stay the same, but the column type or length changes, |
1250 | // i.e. from integer to char. |
1251 | int columns = peekTotalColumnCount(tripletLength); |
1252 | // peek ahead to get the total number of columns. |
1253 | cursor.initializeColumnInfoArrays(netAgent_.targetTypdef_, columns, netAgent_.targetSqlam_); |
1254 | columnCount += parseSQLDTAGRPdataLabelsAndUpdateColumn(cursor, columnCount, tripletLength); |
1255 | break; |
1256 | |
1257 | |
1258 | case FdocaConstants.RLO_TRIPLET_TYPE: // rename to RLO_TRIPLET_CODEPOINT |
1259 | |
1260 | switch (tripletId) { |
1261 | case FdocaConstants.SQLCADTA_LID: |
1262 | if (tripletLength != FdocaConstants.SQLCADTA_RLO_SIZE) { |
1263 | descriptorErrorDetected(); // DSCERRCD_06 |
1264 | } |
1265 | checkPreviousSQLDTARDtriplet(previousTripletType, |
1266 | FdocaConstants.SQLDTARD_TRIPLET_TYPE_RLO, |
1267 | previousTripletId, |
1268 | FdocaConstants.SQLDTARD_TRIPLET_ID_E0); |
1269 | previousTripletType = FdocaConstants.SQLDTARD_TRIPLET_TYPE_RLO; |
1270 | previousTripletId = FdocaConstants.SQLDTARD_TRIPLET_ID_E0; |
1271 | checkFastRLO(FdocaConstants.RLO_SQLCADTA); |
1272 | break; |
1273 | |
1274 | case FdocaConstants.SQLDTARD_LID: |
1275 | if (tripletLength != FdocaConstants.SQLDTARD_RLO_SIZE) { |
1276 | descriptorErrorDetected(); // DSCERRCD_06 |
1277 | } |
1278 | checkPreviousSQLDTARDtriplet(previousTripletType, |
1279 | FdocaConstants.SQLDTARD_TRIPLET_TYPE_RLO, |
1280 | previousTripletId, |
1281 | FdocaConstants.SQLDTARD_TRIPLET_ID_F0); |
1282 | previousTripletType = FdocaConstants.SQLDTARD_TRIPLET_TYPE_RLO; |
1283 | previousTripletId = FdocaConstants.SQLDTARD_TRIPLET_ID_F0; |
1284 | checkFastRLO(FdocaConstants.RLO_SQLDTARD); |
1285 | break; |
1286 | default: |
1287 | descriptorErrorDetected(); // DSCERRCD_07 |
1288 | break; |
1289 | } |
1290 | break; |
1291 | |
1292 | case FdocaConstants.CPT_TRIPLET_TYPE: // rename to CPT_TRIPLET_CODEPOINT |
1293 | if (tripletId != FdocaConstants.NULL_LID) { |
1294 | descriptorErrorDetected(); |
1295 | } |
1296 | checkPreviousSQLDTARDtriplet(previousTripletType, |
1297 | FdocaConstants.SQLDTARD_TRIPLET_TYPE_CPT, |
1298 | previousTripletId, |
1299 | FdocaConstants.SQLDTARD_TRIPLET_ID_0); |
1300 | previousTripletType = FdocaConstants.SQLDTARD_TRIPLET_TYPE_CPT; |
1301 | previousTripletId = FdocaConstants.SQLDTARD_TRIPLET_ID_0; |
1302 | |
1303 | columnCount += parseSQLDTAGRPdataLabelsAndUpdateColumn(cursor, columnCount, tripletLength); |
1304 | break; |
1305 | |
1306 | |
1307 | case FdocaConstants.SDA_TRIPLET_TYPE: // rename to SDA_TRIPLET_CODEPOINT |
1308 | if (tripletLength != FdocaConstants.SDA_TRIPLET_SIZE) { |
1309 | descriptorErrorDetected(); // DSCERRCD_06 |
1310 | } |
1311 | checkPreviousSQLDTARDtriplet(previousTripletType, |
1312 | FdocaConstants.SQLDTARD_TRIPLET_TYPE_SDA, |
1313 | previousTripletId, |
1314 | FdocaConstants.SQLDTARD_TRIPLET_ID_SDA); |
1315 | previousTripletType = FdocaConstants.SQLDTARD_TRIPLET_TYPE_SDA; |
1316 | previousTripletId = FdocaConstants.SQLDTARD_TRIPLET_ID_SDA; |
1317 | netAgent_.targetTypdef_.setMddOverride(mddProtocolType, // mdd protocol type |
1318 | tripletId, // fdocaTripletLid |
1319 | readFastUnsignedByte(), // fdocaFieldType |
1320 | readFastInt(), // ccsid |
1321 | readFastUnsignedByte(), // characterSize |
1322 | readFastUnsignedByte(), // mode |
1323 | readFastShort()); |
1324 | break; |
1325 | |
1326 | default: |
1327 | descriptorErrorDetected(); //DSCERRCD_01 |
1328 | break; |
1329 | } |
1330 | |
1331 | ddmLength -= tripletLength; |
1332 | } |
1333 | |
1334 | adjustLengths(getDdmLength()); |
1335 | |
1336 | // Allocate a char buffer after all of the descriptors have been parsed out. |
1337 | cursor.allocateCharBuffer(); |
1338 | |
1339 | checkPreviousSQLDTARDtriplet(previousTripletType, |
1340 | FdocaConstants.SQLDTARD_TRIPLET_TYPE_END, |
1341 | previousTripletId, |
1342 | FdocaConstants.SQLDTARD_TRIPLET_ID_END); |
1343 | |
1344 | } |
1345 | |
1346 | private void checkPreviousSQLDTARDtriplet(int previousTripletType, |
1347 | int tripletType, |
1348 | int previousTripletId, |
1349 | int tripletId) throws DisconnectException { |
1350 | if (FdocaConstants.SQLDTARD_TRIPLET_TYPES[previousTripletType][tripletType] == false) { |
1351 | descriptorErrorDetected(); // DSCERRCD_02 move error identity into array |
1352 | } |
1353 | if (FdocaConstants.SQLDTARD_TRIPLET_IDS[previousTripletId][tripletId] == false) { |
1354 | descriptorErrorDetected(); // DSCERRCD_02 move error identity into array |
1355 | } |
1356 | } |
1357 | |
1358 | |
1359 | private void checkFastRLO(int[][] rlo) throws DisconnectException { |
1360 | for (int i = 0; i < rlo.length; i++) { |
1361 | int lid = readFastUnsignedByte(); |
1362 | if (lid != rlo[i][FdocaConstants.RLO_GROUP_LID]) { |
1363 | descriptorErrorDetected(); // DSCERRCD_42 |
1364 | } |
1365 | int elementTaken = readFastUnsignedByte(); |
1366 | if (elementTaken != rlo[i][FdocaConstants.RLO_ELEMENT_TAKEN]) { |
1367 | descriptorErrorDetected(); // DSCERRCD_07 |
1368 | } |
1369 | int repFactor = readFastUnsignedByte(); |
1370 | if (repFactor != rlo[i][FdocaConstants.RLO_REP_FACTOR]) { |
1371 | descriptorErrorDetected(); // DSCERRCD_07 |
1372 | } |
1373 | } |
1374 | } |
1375 | |
1376 | // Possible errors to detect include: |
1377 | // DSCERRCD_01 - FDOCA triplet is not used in PROTOCOL descriptors or type code is invalid |
1378 | // DSCERRCD_02 - FDOCA triplet sequence error |
1379 | // DSCERRCD_03 - An array description is required and this is not one |
1380 | // (too many or too few RLO triplets) |
1381 | // DSCERRCD_04 - A row description is required and this is not one |
1382 | // (too many or too few RLO triplets) |
1383 | // DSCERRCD_05 - Late Environmental Descriptor just received not supported |
1384 | // DSCERRCD_06 - Malformed triplet, required parameter is missing |
1385 | // DSCERRCD_07 - Parameter value is not acceptable |
1386 | // DSCERRCD_11 - MDD present is not recognized as an SQL descriptor |
1387 | // DSCERRCD_12 - MDD class is not recognized as a valid SQL class |
1388 | // DSCERRCD_13 - MDD type not recognized as a valid SQL type |
1389 | // DSCERRCD_21 - Representation is incompatible with SQL type (in prior MDD) |
1390 | // DSCERRCD_22 - CCSID is not supported |
1391 | // DSCERRCD_32 - GDA references a local identifier which is not an SDA or GDA |
1392 | // DSCERRCD_33 - GDA length override exceeds limits |
1393 | // DSCERRCD_34 - GDA precision exceeds limits |
1394 | // DSCERRCD_35 - GDA scale greater than precision or scale negative |
1395 | // DSCERRCD_36 - GDA length override missing or incompatible with data type |
1396 | // DSCERRCD_41 - RLO references a LID which is not an RLO or GDA. |
1397 | // DSCERRCD_42 - RLO fails to reference a required GDA or RLO. |
1398 | private void descriptorErrorDetected() throws DisconnectException { |
1399 | agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_, |
1400 | new ClientMessageId(SQLState.DRDA_CONNECTION_TERMINATED), |
1401 | MessageUtil.getCompleteMessage(MessageId.CONN_DRDA_INVALIDFDOCA, |
1402 | SqlException.CLIENT_MESSAGE_RESOURCE_NAME, |
1403 | (Object [])null))); |
1404 | } |
1405 | |
1406 | protected void parseQRYDTA(NetResultSet netResultSet) throws DisconnectException { |
1407 | parseLengthAndMatchCodePoint(CodePoint.QRYDTA); |
1408 | if (longValueForDecryption_ == null) { |
1409 | int ddmLength = getDdmLength(); |
1410 | ensureBLayerDataInBuffer(ddmLength); |
1411 | } |
1412 | parseSQLDTARDdata(netResultSet.netCursor_); |
1413 | if (longValueForDecryption_ == null) { |
1414 | adjustLengths(getDdmLength()); |
1415 | } else { |
1416 | longValueForDecryption_ = null; |
1417 | } |
1418 | if (longBufferForDecryption_ != null) { |
1419 | buffer_ = longBufferForDecryption_; |
1420 | pos_ = longPosForDecryption_; |
1421 | if (count_ > longBufferForDecryption_.length) { |
1422 | count_ = longBufferForDecryption_.length; |
1423 | } else if (longCountForDecryption_ != 0) { |
1424 | count_ = longCountForDecryption_; |
1425 | longCountForDecryption_ = 0; |
1426 | } |
1427 | dssLength_ = 0; |
1428 | longBufferForDecryption_ = null; |
1429 | } |
1430 | |
1431 | |
1432 | } |
1433 | |
1434 | NetSqlca parseFDODTA(NetCursor netCursor) throws DisconnectException { |
1435 | parseLengthAndMatchCodePoint(CodePoint.FDODTA); |
1436 | int ddmLength = getDdmLength(); |
1437 | ensureBLayerDataInBuffer(ddmLength); |
1438 | mark(); |
1439 | NetSqlca netSqlca = parseSQLCARDrow(null); |
1440 | int length = getFastSkipSQLCARDrowLength(); |
1441 | adjustLengths(length); |
1442 | parseFastSQLDTARDdata(netCursor); |
1443 | return netSqlca; |
1444 | } |
1445 | |
1446 | void parseFastSQLDTARDdata(NetCursor netCursor) throws DisconnectException { |
1447 | netCursor.dataBufferStream_ = getFastData(netCursor.dataBufferStream_); |
1448 | netCursor.dataBuffer_ = netCursor.dataBufferStream_.toByteArray(); |
1449 | netCursor.lastValidBytePosition_ = netCursor.dataBuffer_.length; |
1450 | } |
1451 | |
1452 | void parseSQLDTARDdata(NetCursor netCursor) throws DisconnectException { |
1453 | if (longValueForDecryption_ == null) { |
1454 | netCursor.dataBufferStream_ = getData(netCursor.dataBufferStream_); |
1455 | netCursor.dataBuffer_ = netCursor.dataBufferStream_.toByteArray(); |
1456 | } else { |
1457 | int size = netCursor.dataBufferStream_.size(); |
1458 | if (size == 0) { |
1459 | netCursor.dataBuffer_ = longValueForDecryption_; |
1460 | //longValue_ = null; |
1461 | } else { |
1462 | byte[] newArray = new byte[size + longValueForDecryption_.length]; |
1463 | System.arraycopy(netCursor.dataBuffer_, 0, newArray, 0, size); |
1464 | System.arraycopy(longValueForDecryption_, 0, newArray, size, longValueForDecryption_.length); |
1465 | netCursor.dataBuffer_ = newArray; |
1466 | //longValue_ = null; |
1467 | } |
1468 | } |
1469 | |
1470 | netCursor.lastValidBytePosition_ = netCursor.dataBuffer_.length; |
1471 | } |
1472 | |
1473 | protected void copyEXTDTA(NetCursor netCursor) throws DisconnectException { |
1474 | try { |
1475 | parseLengthAndMatchCodePoint(CodePoint.EXTDTA); |
1476 | byte[] data = null; |
1477 | if (longValueForDecryption_ == null) { |
1478 | data = (getData(null)).toByteArray(); |
1479 | } else { |
1480 | data = longValueForDecryption_; |
1481 | dssLength_ = 0; |
1482 | longValueForDecryption_ = null; |
1483 | } |
1484 | netCursor.extdtaData_.add(data); |
1485 | } catch (java.lang.OutOfMemoryError e) { |
1486 | agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_, |
1487 | new ClientMessageId(SQLState.NET_LOB_DATA_TOO_LARGE_FOR_JVM), |
1488 | e)); |
1489 | } |
1490 | } |
1491 | |
1492 | //------------------------parse DDM Scalars----------------------------- |
1493 | |
1494 | // RDB Package name, consistency token, and section number |
1495 | // specifies the fully qualified name of a relational |
1496 | // database package, its consistency token, and a specific |
1497 | // section within a package. |
1498 | // |
1499 | // Only called for generated secctions from a callable statement. |
1500 | // |
1501 | protected Object parsePKGNAMCSN(boolean skip) throws DisconnectException { |
1502 | parseLengthAndMatchCodePoint(CodePoint.PKGNAMCSN); |
1503 | if (skip) { |
1504 | skipBytes(); |
1505 | return null; |
1506 | } |
1507 | |
1508 | // Still need to populate the logical members in case of an "set current packageset" |
1509 | String rdbnam = null; |
1510 | String rdbcolid = null; |
1511 | String pkgid = null; |
1512 | byte[] pkgcnstkn = null; |
1513 | |
1514 | int pkgsn = 0; |
1515 | byte[] pkgnamcsnBytes = null; |
1516 | int pkgnamcsnLength = 0; |
1517 | |
1518 | int ddmLength = getDdmLength(); |
1519 | int offset = 0; |
1520 | |
1521 | ensureBLayerDataInBuffer(ddmLength); |
1522 | |
1523 | if (ddmLength == 64) { |
1524 | // read all the bytes except the section number into the byte[] for caching |
1525 | pkgnamcsnLength = ddmLength - 2; |
1526 | //pkgnamcsnBytes = readBytes (pkgnamcsnLength); |
1527 | pkgnamcsnBytes = new byte[pkgnamcsnLength]; |
1528 | // readFast() does a read without moving the read head. |
1529 | offset = peekFastBytes(pkgnamcsnBytes, offset, pkgnamcsnLength); |
1530 | |
1531 | // populate the logical members |
1532 | rdbnam = readFastString(18); // RDB name |
1533 | rdbcolid = readFastString(18); // RDB Collection ID |
1534 | pkgid = readFastString(18); // RDB Package ID |
1535 | pkgcnstkn = readFastBytes(8); // Package Consistency Token |
1536 | } else if ((ddmLength >= 71) && (ddmLength <= 781)) { |
1537 | // this is the new SCLDTA format. |
1538 | |
1539 | // new up a byte[] to cache all the bytes except the 2-byte section number |
1540 | pkgnamcsnBytes = new byte[ddmLength - 2]; |
1541 | |
1542 | // get rdbnam |
1543 | int scldtaLen = peekFastLength(); |
1544 | if (scldtaLen < 18 || scldtaLen > 255) { |
1545 | agent_.accumulateChainBreakingReadExceptionAndThrow( |
1546 | new DisconnectException(agent_, |
1547 | new ClientMessageId( |
1548 | SQLState.NET_SQLCDTA_INVALID_FOR_RDBNAM), |
1549 | new Integer(scldtaLen))); |
1550 | return null; |
1551 | } |
1552 | // read 2+scldtaLen number of bytes from the reply buffer into the pkgnamcsnBytes |
1553 | //offset = readBytes (pkgnamcsnBytes, offset, 2+scldtaLen); |
1554 | offset = peekFastBytes(pkgnamcsnBytes, offset, 2 + scldtaLen); |
1555 | skipFastBytes(2); |
1556 | rdbnam = readFastString(scldtaLen); |
1557 | |
1558 | // get rdbcolid |
1559 | scldtaLen = peekFastLength(); |
1560 | if (scldtaLen < 18 || scldtaLen > 255) { |
1561 | agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_, |
1562 | new ClientMessageId(SQLState.NET_SQLCDTA_INVALID_FOR_RDBCOLID), |
1563 | new Integer(scldtaLen))); |
1564 | return null; |
1565 | } |
1566 | // read 2+scldtaLen number of bytes from the reply buffer into the pkgnamcsnBytes |
1567 | offset = peekFastBytes(pkgnamcsnBytes, offset, 2 + scldtaLen); |
1568 | skipFastBytes(2); |
1569 | rdbcolid = readFastString(scldtaLen); |
1570 | |
1571 | // get pkgid |
1572 | scldtaLen = peekFastLength(); |
1573 | if (scldtaLen < 18 || scldtaLen > 255) { |
1574 | agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_, |
1575 | new ClientMessageId(SQLState.NET_SQLCDTA_INVALID_FOR_PKGID), |
1576 | new Integer(scldtaLen))); |
1577 | return null; // To make compiler happy. |
1578 | } |
1579 | // read 2+scldtaLen number of bytes from the reply buffer into the pkgnamcsnBytes |
1580 | offset = peekFastBytes(pkgnamcsnBytes, offset, 2 + scldtaLen); |
1581 | skipFastBytes(2); |
1582 | pkgid = readFastString(scldtaLen); |
1583 | |
1584 | // get consistency token |
1585 | offset = peekFastBytes(pkgnamcsnBytes, offset, 8); |
1586 | pkgcnstkn = readFastBytes(8); |
1587 | |
1588 | } else { |
1589 | agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_, |
1590 | new ClientMessageId(SQLState.NET_PGNAMCSN_INVALID_AT_SQLAM), |
1591 | new Integer(ddmLength), new Integer(netAgent_.targetSqlam_))); |
1592 | return null; // To make compiler happy. |
1593 | } |
1594 | |
1595 | pkgsn = readFastUnsignedShort(); // Package Section Number. |
1596 | adjustLengths(ddmLength); |
1597 | // this is a server generated section |
1598 | // the -1 is set for holdability and it is not used for generated sections |
1599 | Section section = new Section(this.agent_, pkgid, pkgsn, null, -1, true); |
1600 | section.setPKGNAMCBytes(pkgnamcsnBytes); |
1601 | return section; |
1602 | } |
1603 | |
1604 | // Query Protocol type specifies the type of query protocol |
1605 | // the target SQLAM uses. |
1606 | protected int parseQRYPRCTYP() throws DisconnectException { |
1607 | parseLengthAndMatchCodePoint(CodePoint.QRYPRCTYP); |
1608 | int qryprctyp = parseCODPNTDR(); |
1609 | if ((qryprctyp != CodePoint.FIXROWPRC) && (qryprctyp != CodePoint.LMTBLKPRC)) { |
1610 | doValnsprmSemantics(CodePoint.QRYPRCTYP, qryprctyp); |
1611 | } |
1612 | return qryprctyp; |
1613 | } |
1614 | |
1615 | protected int parseFastQRYPRCTYP() throws DisconnectException { |
1616 | matchCodePoint(CodePoint.QRYPRCTYP); |
1617 | int qryprctyp = readFastUnsignedShort(); |
1618 | if ((qryprctyp != CodePoint.FIXROWPRC) && (qryprctyp != CodePoint.LMTBLKPRC)) { |
1619 | doValnsprmSemantics(CodePoint.QRYPRCTYP, qryprctyp); |
1620 | } |
1621 | return qryprctyp; |
1622 | } |
1623 | |
1624 | // hold cursor position state indicates whether the requester specified |
1625 | // the HOLD option on the SQL DECLARE CURSOR statement. When the HOLD |
1626 | // option is specified, the cursor is not closed upon execution of a |
1627 | // commit operation. |
1628 | // The value TRUE indicates that the requester specifies the HOLD |
1629 | // operation. The value FALSSE indicates that the requeter is not |
1630 | // specifying the HOLD option. |
1631 | protected int parseSQLCSRHLD() throws DisconnectException { |
1632 | parseLengthAndMatchCodePoint(CodePoint.SQLCSRHLD); |
1633 | int sqlcsrhld = readUnsignedByte(); |
1634 | // 0xF0 is false (default), 0xF1 is true // use constants in if |
1635 | if ((sqlcsrhld != 0xF0) && (sqlcsrhld != 0xF1)) { |
1636 | doValnsprmSemantics(CodePoint.SQLCSRHLD, sqlcsrhld); |
1637 | } |
1638 | return sqlcsrhld; |
1639 | } |
1640 | |
1641 | protected int parseFastSQLCSRHLD() throws DisconnectException { |
1642 | matchCodePoint(CodePoint.SQLCSRHLD); |
1643 | int sqlcsrhld = readFastUnsignedByte(); |
1644 | // 0xF0 is false (default), 0xF1 is true // use constants in if |
1645 | if ((sqlcsrhld != 0xF0) && (sqlcsrhld != 0xF1)) { |
1646 | doValnsprmSemantics(CodePoint.SQLCSRHLD, sqlcsrhld); |
1647 | } |
1648 | return sqlcsrhld; |
1649 | } |
1650 | |
1651 | // Query Attribute for Scrollability indicates whether |
1652 | // a cursor is scrollable or non-scrollable |
1653 | protected int parseQRYATTSCR() throws DisconnectException { |
1654 | parseLengthAndMatchCodePoint(CodePoint.QRYATTSCR); |
1655 | int qryattscr = readUnsignedByte(); // use constants in if |
1656 | if ((qryattscr != 0xF0) && (qryattscr != 0xF1)) { |
1657 | doValnsprmSemantics(CodePoint.QRYATTSCR, qryattscr); |
1658 | } |
1659 | return qryattscr; |
1660 | } |
1661 | |
1662 | protected int parseFastQRYATTSCR() throws DisconnectException { |
1663 | matchCodePoint(CodePoint.QRYATTSCR); |
1664 | int qryattscr = readFastUnsignedByte(); // use constants in if |
1665 | if ((qryattscr != 0xF0) && (qryattscr != 0xF1)) { |
1666 | doValnsprmSemantics(CodePoint.QRYATTSCR, qryattscr); |
1667 | } |
1668 | return qryattscr; |
1669 | } |
1670 | |
1671 | // enabled for rowset positioning. |
1672 | protected int parseQRYATTSET() throws DisconnectException { |
1673 | parseLengthAndMatchCodePoint(CodePoint.QRYATTSET); |
1674 | int qryattset = readUnsignedByte(); // use constants in if |
1675 | if ((qryattset != 0xF0) && (qryattset != 0xF1)) { |
1676 | doValnsprmSemantics(CodePoint.QRYATTSET, qryattset); |
1677 | } |
1678 | return qryattset; |
1679 | } |
1680 | |
1681 | protected int parseFastQRYATTSET() throws DisconnectException { |
1682 | matchCodePoint(CodePoint.QRYATTSET); |
1683 | int qryattset = readFastUnsignedByte(); // use constants in if |
1684 | if ((qryattset != 0xF0) && (qryattset != 0xF1)) { |
1685 | doValnsprmSemantics(CodePoint.QRYATTSET, qryattset); |
1686 | } |
1687 | return qryattset; |
1688 | } |
1689 | |
1690 | // Query attribute for Sensitivity indicats the sensitivity |
1691 | // of an opened cursor to changes made to the underlying |
1692 | // base table. |
1693 | protected int parseQRYATTSNS() throws DisconnectException { |
1694 | parseLengthAndMatchCodePoint(CodePoint.QRYATTSNS); |
1695 | int qryattsns = readUnsignedByte(); |
1696 | switch (qryattsns) { |
1697 | case CodePoint.QRYUNK: |
1698 | case CodePoint.QRYINS: |
1699 | break; |
1700 | default: |
1701 | doValnsprmSemantics(CodePoint.QRYATTSNS, qryattsns); |
1702 | break; |
1703 | } |
1704 | return qryattsns; |
1705 | } |
1706 | |
1707 | protected int parseFastQRYATTSNS() throws DisconnectException { |
1708 | matchCodePoint(CodePoint.QRYATTSNS); |
1709 | int qryattsns = readFastUnsignedByte(); |
1710 | switch (qryattsns) { |
1711 | case CodePoint.QRYUNK: |
1712 | case CodePoint.QRYSNSSTC: |
1713 | case CodePoint.QRYINS: |
1714 | break; |
1715 | default: |
1716 | doValnsprmSemantics(CodePoint.QRYATTSNS, qryattsns); |
1717 | break; |
1718 | } |
1719 | return qryattsns; |
1720 | } |
1721 | |
1722 | // Query Attribute for Updatability indicates the updatability |
1723 | // of an opened cursor. |
1724 | protected int parseQRYATTUPD() throws DisconnectException { |
1725 | parseLengthAndMatchCodePoint(CodePoint.QRYATTUPD); |
1726 | int qryattupd = readUnsignedByte(); |
1727 | switch (qryattupd) { |
1728 | case CodePoint.QRYUNK: |
1729 | case CodePoint.QRYRDO: |
1730 | case CodePoint.QRYUPD: |
1731 | break; |
1732 | default: |
1733 | doValnsprmSemantics(CodePoint.QRYATTUPD, qryattupd); |
1734 | break; |
1735 | } |
1736 | return qryattupd; |
1737 | } |
1738 | |
1739 | protected int parseFastQRYATTUPD() throws DisconnectException { |
1740 | matchCodePoint(CodePoint.QRYATTUPD); |
1741 | int qryattupd = readFastUnsignedByte(); |
1742 | switch (qryattupd) { |
1743 | case CodePoint.QRYUNK: |
1744 | case CodePoint.QRYRDO: |
1745 | case CodePoint.QRYUPD: |
1746 | break; |
1747 | default: |
1748 | doValnsprmSemantics(CodePoint.QRYATTUPD, qryattupd); |
1749 | break; |
1750 | } |
1751 | return qryattupd; |
1752 | } |
1753 | |
1754 | |
1755 | private long parseFastQRYINSID() throws DisconnectException { |
1756 | matchCodePoint(CodePoint.QRYINSID); |
1757 | return readFastLong(); |
1758 | } |
1759 | |
1760 | |
1761 | // RDB Package Namce, Consistency Token, and Section Number List |
1762 | // specifies a list of fully qualified names of specific sections |
1763 | // within one or more packages. |
1764 | protected java.util.ArrayList parsePKGSNLST() throws DisconnectException { |
1765 | Object pkgnamcsn = null; |
1766 | java.util.ArrayList pkgsnlst = new java.util.ArrayList(); // what default size should we use |
1767 | |
1768 | parseLengthAndMatchCodePoint(CodePoint.PKGSNLST); |
1769 | pushLengthOnCollectionStack(); |
1770 | while (peekCodePoint() != Reply.END_OF_COLLECTION) { |
1771 | pkgnamcsn = parsePKGNAMCSN(false); |
1772 | pkgsnlst.add(pkgnamcsn); |
1773 | } |
1774 | popCollectionStack(); |
1775 | return pkgsnlst; |
1776 | } |
1777 | |
1778 | protected NetSqlca parseSQLDARD(ColumnMetaData columnMetaData, |
1779 | boolean skipBytes) throws DisconnectException { |
1780 | parseLengthAndMatchCodePoint(CodePoint.SQLDARD); |
1781 | return parseSQLDARDarray(columnMetaData, skipBytes); |
1782 | } |
1783 | |
1784 | protected int parseSQLRSLRD(java.util.ArrayList sectionAL) throws DisconnectException { |
1785 | parseLengthAndMatchCodePoint(CodePoint.SQLRSLRD); |
1786 | return parseSQLRSLRDarray(sectionAL); |
1787 | } |
1788 | |
1789 | protected ColumnMetaData parseSQLCINRD() throws DisconnectException { |
1790 | parseLengthAndMatchCodePoint(CodePoint.SQLCINRD); |
1791 | int ddmLength = getDdmLength(); |
1792 | ensureBLayerDataInBuffer(ddmLength); |
1793 | ColumnMetaData cm = parseSQLCINRDarray(); |
1794 | adjustLengths(getDdmLength()); |
1795 | return cm; |
1796 | } |
1797 | |
1798 | |
1799 | //--------------------------parse FDOCA objects------------------------ |
1800 | |
1801 | // SQLDARD : FDOCA EARLY ARRAY |
1802 | // SQL Descriptor Area Row Description with SQL Communications Area |
1803 | // |
1804 | // FORMAT FOR SQLAM <= 6 |
1805 | // SQLCARD; ROW LID 0x64; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1806 | // SQLNUMROW; ROW LID 0x68; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1807 | // SQLDAROW; ROW LID 0x60; ELEMENT TAKEN 0(all); REP FACTOR 0(all) |
1808 | // |
1809 | // FORMAT FOR SQLAM >= 7 |
1810 | // SQLCARD; ROW LID 0x64; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1811 | // SQLDHROW; ROW LID 0xE0; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1812 | // SQLNUMROW; ROW LID 0x68; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1813 | // SQLDAROW; ROW LID 0x60; ELEMENT TAKEN 0(all); REP FACTOR 0(all) |
1814 | NetSqlca parseSQLDARDarray(ColumnMetaData columnMetaData, |
1815 | boolean skipBytes) throws DisconnectException { |
1816 | int ddmLength = 0; |
1817 | if (!ensuredLengthForDecryption_ && longValueForDecryption_ == null) { //if ensuredLength = true, means we already ensured length in decryptData, so don't need to do it again |
1818 | ddmLength = getDdmLength(); |
1819 | ensureBLayerDataInBuffer(ddmLength); |
1820 | |
1821 | } |
1822 | if (longValueForDecryption_ != null) { |
1823 | buffer_ = longValueForDecryption_; |
1824 | pos_ = 0; |
1825 | count_ = longValueForDecryption_.length; |
1826 | //dssLength_ = 0; |
1827 | } |
1828 | |
1829 | |
1830 | NetSqlca netSqlca = null; |
1831 | if (skipBytes) { |
1832 | mark(); |
1833 | netSqlca = parseSQLCARDrow(null); |
1834 | skipFastBytes(ddmLength - getFastSkipSQLCARDrowLength()); |
1835 | adjustLengths(getDdmLength()); |
1836 | return netSqlca; |
1837 | } else { |
1838 | netSqlca = parseSQLCARDrow(null); |
1839 | } |
1840 | |
1841 | parseSQLDHROW(columnMetaData); |
1842 | |
1843 | int columns = parseSQLNUMROW(); |
1844 | if (columns > columnMetaData.columns_) // this will only be true when columnMetaData.columns_ = 0 under deferred prepare |
1845 | // under deferred prepare the CMD arrays are not allocated until now, no guesses were made |
1846 | { |
1847 | columnMetaData.initializeCache(columns); |
1848 | } else // column count was guessed, don't bother reallocating arrays, just truncate their lengths |
1849 | { |
1850 | columnMetaData.columns_ = columns; |
1851 | } |
1852 | |
1853 | // is this correct for 0 SQLNUMROW |
1854 | // does rest of code expect a null ColumnMetaData object |
1855 | // or does rest of code expect an non null object |
1856 | // with columns_ set to 0 |
1857 | |
1858 | for (int i = 0; i < columnMetaData.columns_; i++) { |
1859 | parseSQLDAROW(columnMetaData, i); |
1860 | } |
1861 | |
1862 | if (longValueForDecryption_ == null) { |
1863 | adjustLengths(getDdmLength()); |
1864 | } else { |
1865 | dssLength_ = 0; |
1866 | longValueForDecryption_ = null; |
1867 | } |
1868 | |
1869 | |
1870 | return netSqlca; |
1871 | } |
1872 | |
1873 | |
1874 | // SQLRSLRD : FDOCA EARLY ARRAY |
1875 | // Data Array of a Result Set |
1876 | // |
1877 | // FORMAT FOR ALL SQLAM LEVELS |
1878 | // SQLNUMROW; ROW LID 0x68; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1879 | // SQLRSROW; ROW LID 0x6F; ELEMENT TAKEN 0(all); REP FACTOR 0(all) |
1880 | // |
1881 | // SQL Result Set Reply Data (SQLRSLRD) is a byte string that specifies |
1882 | // information about result sets returned as reply data in the response to |
1883 | // an EXCSQLSTT command that invokes a stored procedure |
1884 | int parseSQLRSLRDarray(java.util.ArrayList sectionAL) throws DisconnectException { |
1885 | int numOfResultSets = parseSQLNUMROW(); |
1886 | for (int i = 0; i < numOfResultSets; i++) { |
1887 | parseSQLRSROW((Section) sectionAL.get(i)); |
1888 | } |
1889 | return numOfResultSets; |
1890 | } |
1891 | |
1892 | // SQLCINRD : FDOCA EARLY ARRAY |
1893 | // SQL Result Set Column Array Description |
1894 | // |
1895 | // FORMAT FOR SQLAM <= 6 |
1896 | // SQLNUMROW; ROW LID 0x68; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1897 | // SQLCIROW; ROW LID 0x6B; ELEMENT TAKEN 0(all); REP FACTOR 0(all) |
1898 | // |
1899 | // FORMAT FOR SQLAM >= 7 |
1900 | // SQLDHROW; ROW LID 0xE0; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1901 | // SQLNUMROW; ROW LID 0x68; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1902 | // SQLDAROW; ROW LID 0x60; ELEMENT TAKEN 0(all); REP FACTOR 0(all) |
1903 | // |
1904 | // SQL Result Set Column Information Reply Data (SQLCINRD) is a byte string |
1905 | // that specifies information about columns for a result set returned as |
1906 | // reply data in the response to an EXCSQLSTT command that invodes a stored |
1907 | // procedure |
1908 | ColumnMetaData parseSQLCINRDarray() throws DisconnectException { |
1909 | ColumnMetaData columnMetaData = ClientDriver.getFactory().newColumnMetaData(netAgent_.logWriter_); |
1910 | |
1911 | parseSQLDHROW(columnMetaData); |
1912 | |
1913 | // possibly change initializeCache to not new up arrays if |
1914 | // parseSQLNUMROW returns 0 |
1915 | columnMetaData.initializeCache(parseFastSQLNUMROW()); |
1916 | |
1917 | // is this correct for 0 SQLNUMROW, |
1918 | // does rest of code expect a null ColumnMetaData object |
1919 | // or does rest of code expect an non null object |
1920 | // with columns_ set to 0 |
1921 | for (int i = 0; i < columnMetaData.columns_; i++) { |
1922 | parseSQLDAROW(columnMetaData, i); |
1923 | } |
1924 | |
1925 | return columnMetaData; |
1926 | } |
1927 | |
1928 | // SQLDAROW : FDOCA EARLY ROW |
1929 | // SQL Data Area Row Description |
1930 | // |
1931 | // FORMAT FOR ALL SQLAM LEVELS |
1932 | // SQLDAGRP; GROUP LID 0x50; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1933 | private void parseSQLDAROW(ColumnMetaData columnMetaData, |
1934 | int columnNumber) throws DisconnectException { |
1935 | parseSQLDAGRP(columnMetaData, columnNumber); |
1936 | } |
1937 | |
1938 | // SQLDHROW : FDOCA EARLY ROW |
1939 | // SQL Descriptor Header Row Description |
1940 | // |
1941 | // FORMAT FOR SQLAM >= 7 |
1942 | // SQLDHGRP; GROUP LID 0xD0; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1943 | private void parseSQLDHROW(ColumnMetaData columnMetaData) throws DisconnectException { |
1944 | parseSQLDHGRP(columnMetaData); |
1945 | } |
1946 | |
1947 | // SQLRSROW : FDOCA EARLY ROW |
1948 | // SQL Row Description for One Result Set Row |
1949 | // |
1950 | // FORMAT FOR ALL SQLAM LEVELS |
1951 | // SQLRSGRP; GROUP LID 0x5F; ELEMENT TAKEN 0(all); REP FACTOR 1 |
1952 | private void parseSQLRSROW(Section section) throws DisconnectException { |
1953 | parseSQLRSGRP(section); |
1954 | } |
1955 | |
1956 | |
1957 | // These methods are "private protected", which is not a recognized java privilege, |
1958 | // but means that these methods are private to this class and to subclasses, |
1959 | // and should not be used as package-wide friendly methods. |
1960 | |
1961 | // SQLDAGRP : EARLY FDOCA GROUP |
1962 | // SQL Data Area Group Description |
1963 | // |
1964 | // FORMAT FOR SQLAM <= 6 |
1965 | // SQLPRECISION; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
1966 | // SQLSCALE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
1967 | // SQLLENGTH; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4 |
1968 | // SQLTYPE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
1969 | // SQLCCSID; PROTOCOL TYPE FB; ENVLID 0x26; Length Override 2 |
1970 | // SQLNAME_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 30 |
1971 | // SQLNAME_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 30 |
1972 | // SQLLABEL_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 30 |
1973 | // SQLLABEL_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 30 |
1974 | // SQLCOMMENTS_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 254 |
1975 | // SQLCOMMENTS_m; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 254 |
1976 | // |
1977 | // FORMAT FOR SQLAM == 6 |
1978 | // SQLPRECISION; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
1979 | // SQLSCALE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
1980 | // SQLLENGTH; PROTOCOL TYPE I8; ENVLID 0x16; Length Override 8 |
1981 | // SQLTYPE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
1982 | // SQLCCSID; PROTOCOL TYPE FB; ENVLID 0x26; Length Override 2 |
1983 | // SQLNAME_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 30 |
1984 | // SQLNAME_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 30 |
1985 | // SQLLABEL_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 30 |
1986 | // SQLLABEL_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 30 |
1987 | // SQLCOMMENTS_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 254 |
1988 | // SQLCOMMENTS_m; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 254 |
1989 | // SQLUDTGRP; PROTOCOL TYPE N-GDA; ENVLID 0x51; Length Override 0 |
1990 | // |
1991 | // FORMAT FOR SQLAM >= 7 |
1992 | // SQLPRECISION; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
1993 | // SQLSCALE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
1994 | // SQLLENGTH; PROTOCOL TYPE I8; ENVLID 0x16; Length Override 8 |
1995 | // SQLTYPE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
1996 | // SQLCCSID; PROTOCOL TYPE FB; ENVLID 0x26; Length Override 2 |
1997 | // SQLDOPTGRP; PROTOCOL TYPE N-GDA; ENVLID 0xD2; Length Override 0 |
1998 | private void parseSQLDAGRP(ColumnMetaData columnMetaData, |
1999 | int columnNumber) throws DisconnectException { |
2000 | long columnLength = 0; |
2001 | |
2002 | // 2-byte precision |
2003 | int precision = readFastShort(); |
2004 | |
2005 | // 2-byte scale |
2006 | int scale = readFastShort(); |
2007 | |
2008 | // 8 byte sqllength |
2009 | columnLength = readFastLong(); |
2010 | |
2011 | // create a set method after sqlType and ccsid is read |
2012 | // possibly have it set the nullable |
2013 | int sqlType = readFastShort(); |
2014 | |
2015 | // 2-byte sqlccsid |
2016 | // (NOTE: SQLCCSID is always flown as BIG ENDIAN, not as data!) |
2017 | // The C-Common Client also does the following: |
2018 | // 1. Determine which type of code page is to be used for this variable: |
2019 | // 2. Map the CCSID to the correct codepage: |
2020 | // 3. "Split" the CCSID to see whether it is for SBCS or MBCS: |
2021 | int ccsid = readFastUnsignedShort(); |
2022 | |
2023 | columnMetaData.sqlPrecision_[columnNumber] = precision; |
2024 | columnMetaData.sqlScale_[columnNumber] = scale; |
2025 | columnMetaData.sqlLength_[columnNumber] = columnLength; |
2026 | columnMetaData.sqlType_[columnNumber] = sqlType; |
2027 | // Set the nullables |
2028 | columnMetaData.nullable_[columnNumber] = Utils.isSqlTypeNullable(sqlType); |
2029 | columnMetaData.sqlCcsid_[columnNumber] = ccsid; |
2030 | columnMetaData.types_[columnNumber] = |
2031 | Types.mapDERBYTypeToDriverType(true, sqlType, columnLength, ccsid); // true means isDescribed |
2032 | parseSQLDOPTGRP(columnMetaData, columnNumber); |
2033 | } |
2034 | |
2035 | // SQLUDTGRP : EARLY FDOCA GROUP |
2036 | // SQL User-Defined Data Group Description |
2037 | // |
2038 | // FORMAT FOR SQLAM >= 7 |
2039 | // SQLUDTXTYPE; PROTOCOL TYPE I4; ENVLID 0X02; Length Override 4 |
2040 | // SQLUDTRDB; PROTOCOL TYPE VCS; ENVLID 0X32; Length Override 255 |
2041 | // SQLUDTSCHEMA_m; PROTOCOL TYPE VCM; ENVLID 0X3E; Length Override 255 |
2042 | // SQLUDTSCHEMA_s; PROTOCOL TYPE VCS; ENVLID 0X32; Length Override 255 |
2043 | // SQLUDTNAME_m; PROTOCOL TYPE VCM; ENVLID 0X3E; Length Override 255 |
2044 | // SQLUDTNAME_s; PROTOCOL TYPE VCS; ENVLID 0X32; Length Override 255 |
2045 | private void parseSQLUDTGRP(ColumnMetaData columnMetaData, |
2046 | int columnNumber) throws DisconnectException { |
2047 | if (readFastUnsignedByte() == CodePoint.NULLDATA) { |
2048 | return; |
2049 | } |
2050 | |
2051 | } |
2052 | |
2053 | // SQLDOPTGRP : EARLY FDOCA GROUP |
2054 | // SQL Descriptor Optional Group Description |
2055 | // |
2056 | // FORMAT FOR SQLAM >= 7 |
2057 | // SQLUNNAMED; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2058 | // SQLNAME_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2059 | // SQLNAME_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2060 | // SQLLABEL_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2061 | // SQLLABEL_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2062 | // SQLCOMMENTS_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2063 | // SQLCOMMENTS_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2064 | // SQLUDTGRP; PROTOCOL TYPE N-GDA; ENVLID 0x5B; Length Override 0 |
2065 | // SQLDXGRP; PROTOCOL TYPE N-GDA; ENVLID 0xD4; Length Override 0 |
2066 | private void parseSQLDOPTGRP(ColumnMetaData columnMetaData, |
2067 | int columnNumber) throws DisconnectException { |
2068 | if (readFastUnsignedByte() == CodePoint.NULLDATA) { |
2069 | return; |
2070 | } |
2071 | |
2072 | // SQLUNNAMED; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2073 | short sqlunnamed = readFastShort(); |
2074 | |
2075 | // SQLNAME_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2076 | // SQLNAME_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2077 | String name = parseFastVCMorVCS(); |
2078 | |
2079 | // SQLLABEL_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2080 | // SQLLABEL_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2081 | String label = parseFastVCMorVCS(); |
2082 | |
2083 | // SQLCOMMENTS_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2084 | // SQLCOMMENTS_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2085 | String colComments = parseFastVCMorVCS(); |
2086 | |
2087 | if (columnMetaData.sqlName_ == null) { |
2088 | columnMetaData.sqlName_ = new String[columnMetaData.columns_]; |
2089 | } |
2090 | if (columnMetaData.sqlLabel_ == null) { |
2091 | columnMetaData.sqlLabel_ = new String[columnMetaData.columns_]; |
2092 | } |
2093 | if (columnMetaData.sqlUnnamed_ == null) { |
2094 | columnMetaData.sqlUnnamed_ = new short[columnMetaData.columns_]; |
2095 | } |
2096 | if (columnMetaData.sqlComment_ == null) { |
2097 | columnMetaData.sqlComment_ = new String[columnMetaData.columns_]; |
2098 | } |
2099 | columnMetaData.sqlName_[columnNumber] = name; |
2100 | columnMetaData.sqlLabel_[columnNumber] = label; |
2101 | columnMetaData.sqlUnnamed_[columnNumber] = sqlunnamed; |
2102 | columnMetaData.sqlComment_[columnNumber] = colComments; |
2103 | |
2104 | // possibly move all the assignments into a single method on the columnMetaData object |
2105 | |
2106 | parseSQLUDTGRP(columnMetaData, columnNumber); |
2107 | parseSQLDXGRP(columnMetaData, columnNumber); |
2108 | } |
2109 | |
2110 | // SQLDXGRP : EARLY FDOCA GROUP |
2111 | // SQL Descriptor Extended Group Description |
2112 | // |
2113 | // FORMAT FOR SQLAM >=7 |
2114 | // SQLXKEYMEM; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2115 | // SQLXUPDATEABLE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2116 | // SQLXGENERATED; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2117 | // SQLXPARMMODE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2118 | // SQLXRDBNAM; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2119 | // SQLXCORNAME_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2120 | // SQLXCORNAME_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2121 | // SQLXBASENAME_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2122 | // SQLXBASENAME_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2123 | // SQLXSCHEMA_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2124 | // SQLXSCHEMA_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2125 | // SQLXNAME_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2126 | // SQLXNAME_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2127 | private void parseSQLDXGRP(ColumnMetaData columnMetaData, |
2128 | int column) throws DisconnectException { |
2129 | if (readFastUnsignedByte() == CodePoint.NULLDATA) { |
2130 | return; |
2131 | } |
2132 | |
2133 | |
2134 | // SQLXKEYMEM; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2135 | short sqlxkeymem = readFastShort(); |
2136 | |
2137 | // SQLXUPDATEABLE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2138 | short sqlxupdateable = readFastShort(); |
2139 | |
2140 | // SQLXGENERATED; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2141 | short sqlxgenerated = readFastShort(); |
2142 | |
2143 | // SQLXPARMMODE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2144 | short sqlxparmmode = readFastShort(); |
2145 | |
2146 | // SQLXRDBNAM; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2147 | String sqlxrdbnam = parseFastVCS(); |
2148 | |
2149 | // SQLXCORNAME_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2150 | // SQLXCORNAME_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2151 | String sqlxcorname = parseFastVCMorVCS(); |
2152 | |
2153 | // SQLXBASENAME_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2154 | // SQLXBASENAME_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2155 | String sqlxbasename = parseFastVCMorVCS(); |
2156 | |
2157 | // SQLXSCHEMA_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2158 | // SQLXSCHEMA_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2159 | String sqlxschema = parseFastVCMorVCS(); |
2160 | |
2161 | // SQLXNAME_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2162 | // SQLXNAME_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2163 | String sqlxname = parseFastVCMorVCS(); |
2164 | |
2165 | if (columnMetaData.sqlxKeymem_ == null) { |
2166 | columnMetaData.sqlxKeymem_ = new short[columnMetaData.columns_]; |
2167 | } |
2168 | if (columnMetaData.sqlxGenerated_ == null) { |
2169 | columnMetaData.sqlxGenerated_ = new short[columnMetaData.columns_]; |
2170 | } |
2171 | if (columnMetaData.sqlxParmmode_ == null) { |
2172 | columnMetaData.sqlxParmmode_ = new short[columnMetaData.columns_]; |
2173 | } |
2174 | if (columnMetaData.sqlxCorname_ == null) { |
2175 | columnMetaData.sqlxCorname_ = new String[columnMetaData.columns_]; |
2176 | } |
2177 | if (columnMetaData.sqlxName_ == null) { |
2178 | columnMetaData.sqlxName_ = new String[columnMetaData.columns_]; |
2179 | } |
2180 | if (columnMetaData.sqlxBasename_ == null) { |
2181 | columnMetaData.sqlxBasename_ = new String[columnMetaData.columns_]; |
2182 | } |
2183 | if (columnMetaData.sqlxUpdatable_ == null) { |
2184 | columnMetaData.sqlxUpdatable_ = new int[columnMetaData.columns_]; |
2185 | } |
2186 | if (columnMetaData.sqlxSchema_ == null) { |
2187 | columnMetaData.sqlxSchema_ = new String[columnMetaData.columns_]; |
2188 | } |
2189 | if (columnMetaData.sqlxRdbnam_ == null) { |
2190 | columnMetaData.sqlxRdbnam_ = new String[columnMetaData.columns_]; |
2191 | } |
2192 | |
2193 | columnMetaData.sqlxKeymem_[column] = sqlxkeymem; |
2194 | columnMetaData.sqlxGenerated_[column] = sqlxgenerated; |
2195 | columnMetaData.sqlxParmmode_[column] = sqlxparmmode; |
2196 | columnMetaData.sqlxCorname_[column] = sqlxcorname; |
2197 | columnMetaData.sqlxName_[column] = sqlxname; |
2198 | columnMetaData.sqlxBasename_[column] = sqlxbasename; |
2199 | columnMetaData.sqlxUpdatable_[column] = sqlxupdateable; |
2200 | columnMetaData.sqlxSchema_[column] = (sqlxschema == null) ? columnMetaData.sqldSchema_ : sqlxschema; |
2201 | columnMetaData.sqlxRdbnam_[column] = (sqlxrdbnam == null) ? columnMetaData.sqldRdbnam_ : sqlxrdbnam; |
2202 | } |
2203 | |
2204 | // SQLDHGRP : EARLY FDOCA GROUP |
2205 | // SQL Descriptor Header Group Description |
2206 | // |
2207 | // FORMAT FOR SQLAM >= 7 |
2208 | // SQLDHOLD; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2209 | // SQLDRETURN; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2210 | // SQLDSCROLL; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2211 | // SQLDSENSITIVE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2212 | // SQLDFCODE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2213 | // SQLDKEYTYPE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2214 | // SQLDRDBNAM; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2215 | // SQLDSCHEMA_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2216 | // SQLDSCHEMA_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2217 | private void parseSQLDHGRP(ColumnMetaData columnMetaData) throws DisconnectException { |
2218 | if (readFastUnsignedByte() == CodePoint.NULLDATA) { |
2219 | return; |
2220 | } |
2221 | |
2222 | |
2223 | // SQLDHOLD; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2224 | short sqldhold = readFastShort(); |
2225 | |
2226 | // SQLDRETURN; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2227 | short sqldreturn = readFastShort(); |
2228 | |
2229 | // SQLDSCROLL; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2230 | short sqldscroll = readFastShort(); |
2231 | |
2232 | // SQLDSENSITIVE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2233 | short sqldsensitive = readFastShort(); |
2234 | |
2235 | // SQLDFCODE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2236 | short sqldfcode = readFastShort(); |
2237 | |
2238 | // SQLDKEYTYPE; PROTOCOL TYPE I2; ENVLID 0x04; Length Override 2 |
2239 | short sqldkeytype = readFastShort(); |
2240 | |
2241 | // SQLDRDBNAM; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2242 | String sqldrdbnam = parseFastVCS(); |
2243 | |
2244 | // SQLDSCHEMA_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2245 | // SQLDSCHEMA_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2246 | String sqldschema = parseFastVCMorVCS(); |
2247 | |
2248 | columnMetaData.sqldHold_ = sqldhold; |
2249 | columnMetaData.sqldReturn_ = sqldreturn; |
2250 | columnMetaData.sqldScroll_ = sqldscroll; |
2251 | columnMetaData.sqldSensitive_ = sqldsensitive; |
2252 | columnMetaData.sqldFcode_ = sqldfcode; |
2253 | columnMetaData.sqldKeytype_ = sqldkeytype; |
2254 | columnMetaData.sqldRdbnam_ = sqldrdbnam; |
2255 | columnMetaData.sqldSchema_ = sqldschema; |
2256 | } |
2257 | |
2258 | // SQLRSGRP : EARLY FDOCA GROUP |
2259 | // SQL Result Set Group Description |
2260 | // |
2261 | // FORMAT FOR SQLAM >= 7 |
2262 | // SQLRSLOCATOR; PROTOCOL TYPE RSL; ENVLID 0x14; Length Override 4 |
2263 | // SQLRSNAME_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 255 |
2264 | // SQLRSNAME_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255 |
2265 | // SQLRSNUMROWS; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4 |
2266 | private void parseSQLRSGRP(Section section) throws DisconnectException { |
2267 | |
2268 | int rsLocator = readInt(); |
2269 | String rsName = parseVCMorVCS(); // ignore length change bt SQLAM 6 and 7 |
2270 | int rsNumRows = readInt(); |
2271 | // currently rsLocator and rsNumRows are not being used. |
2272 | section.setCursorName(rsName); |
2273 | } |
2274 | |
2275 | |
2276 | // this is duplicated in parseColumnMetaData, but different |
2277 | // DAGroup under NETColumnMetaData requires a lot more stuffs including |
2278 | // precsion, scale and other stuffs |
2279 | private String parseFastVCMorVCS() throws DisconnectException { |
2280 | String stringToBeSet = null; |
2281 | |
2282 | int vcm_length = readFastUnsignedShort(); |
2283 | if (vcm_length > 0) { |
2284 | stringToBeSet = readFastString(vcm_length, netAgent_.targetTypdef_.getCcsidMbcEncoding()); |
2285 | } |
2286 | int vcs_length = readFastUnsignedShort(); |
2287 | if (vcm_length > 0 && vcs_length > 0) { |
2288 | agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_, |
2289 | new ClientMessageId(SQLState.NET_VCM_VCS_LENGTHS_INVALID))); |
2290 | } else if (vcs_length > 0) { |
2291 | stringToBeSet = readFastString(vcs_length, netAgent_.targetTypdef_.getCcsidSbcEncoding()); |
2292 | } |
2293 | |
2294 | return stringToBeSet; |
2295 | } |
2296 | |
2297 | private String parseVCMorVCS() throws DisconnectException { |
2298 | String stringToBeSet = null; |
2299 | |
2300 | int vcm_length = readUnsignedShort(); |
2301 | if (vcm_length > 0) { |
2302 | stringToBeSet = readString(vcm_length, netAgent_.targetTypdef_.getCcsidMbcEncoding()); |
2303 | } |
2304 | int vcs_length = readUnsignedShort(); |
2305 | if (vcm_length > 0 && vcs_length > 0) { |
2306 | agent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(agent_, |
2307 | new ClientMessageId(SQLState.NET_VCM_VCS_LENGTHS_INVALID))); |
2308 | } else if (vcs_length > 0) { |
2309 | stringToBeSet = readString(vcs_length, netAgent_.targetTypdef_.getCcsidSbcEncoding()); |
2310 | } |
2311 | |
2312 | return stringToBeSet; |
2313 | } |
2314 | |
2315 | //----------------------non-parsing computational helper methods-------------- |
2316 | private int calculateResultSetType(int qryattscr, int qryattsns, int defaultType) { |
2317 | // We are passing in defaultType "FOWARD_ONLY", in case desired type |
2318 | // cannot be obtained,we don't want to set the type to Statement's type, |
2319 | // but we will set it to the default. |
2320 | |
2321 | if (qryattscr == 0xF0) { |
2322 | return java.sql.ResultSet.TYPE_FORWARD_ONLY; |
2323 | } |
2324 | |
2325 | switch (qryattsns) { |
2326 | case CodePoint.QRYINS: |
2327 | return java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE; |
2328 | default: |
2329 | return defaultType; |
2330 | } |
2331 | } |
2332 | |
2333 | private int calculateResultSetConcurrency(int qryattupd, int defaultConcurrency) { |
2334 | // QRYATTUPD does come back for forward-only cursors if the desired concurrency cannot be |
2335 | // obtained, in which case we don't want to set the concurrency to the default, but |
2336 | // we want to set it to the actual concurrency. |
2337 | switch (qryattupd) { |
2338 | case CodePoint.QRYRDO: |
2339 | return java.sql.ResultSet.CONCUR_READ_ONLY; |
2340 | case CodePoint.QRYUPD: |
2341 | return java.sql.ResultSet.CONCUR_UPDATABLE; |
2342 | default: |
2343 | return defaultConcurrency; |
2344 | } |
2345 | } |
2346 | |
2347 | private int calculateResultSetHoldability(int sqlcsrhld) { |
2348 | if (sqlcsrhld == 0xF0) { |
2349 | return JDBC30Translation.CLOSE_CURSORS_AT_COMMIT; |
2350 | } else { |
2351 | return JDBC30Translation.HOLD_CURSORS_OVER_COMMIT; |
2352 | } |
2353 | } |
2354 | |
2355 | private int parseSQLDTAGRPdataLabelsAndUpdateColumn(NetCursor cursor, int columnIndex, int tripletLength) |
2356 | throws DisconnectException { |
2357 | int numColumns = (tripletLength - 3) / 3; |
2358 | for (int i = columnIndex; i < columnIndex + numColumns; i++) { |
2359 | cursor.qrydscTypdef_.updateColumn(cursor, i, readFastUnsignedByte(), readFastUnsignedShort()); |
2360 | } |
2361 | return numColumns; |
2362 | } |
2363 | |
2364 | |
2365 | private String parseSQLSTT() throws DisconnectException { |
2366 | parseLengthAndMatchCodePoint(CodePoint.SQLSTT); |
2367 | return parseSQLSTTGRP(); |
2368 | } |
2369 | |
2370 | private String parseSQLSTTGRP() throws DisconnectException { |
2371 | int mixedNullInd = readUnsignedByte(); |
2372 | int singleNullInd = 0; |
2373 | String sqlsttString = null; |
2374 | int stringLength = 0; |
2375 | |
2376 | if (mixedNullInd == CodePoint.NULLDATA) { |
2377 | singleNullInd = readUnsignedByte(); |
2378 | if (singleNullInd == CodePoint.NULLDATA) { |
2379 | // throw DTAMCHRM |
2380 | doDtamchrmSemantics(); |
2381 | } |
2382 | // read 4-byte length |
2383 | stringLength = readInt(); |
2384 | // read sqlstt string |
2385 | sqlsttString = readString(stringLength, netAgent_.targetTypdef_.getCcsidSbcEncoding()); |
2386 | } else { |
2387 | // read 4-byte length |
2388 | stringLength = readInt(); |
2389 | // read sqlstt string |
2390 | sqlsttString = readString(stringLength, netAgent_.targetTypdef_.getCcsidMbcEncoding()); |
2391 | // read null indicator |
2392 | singleNullInd = readUnsignedByte(); |
2393 | } |
2394 | return sqlsttString; |
2395 | } |
2396 | |
2397 | public void readSetSpecialRegister(StatementCallbackInterface statement) throws DisconnectException { |
2398 | startSameIdChainParse(); |
2399 | parseEXCSQLSETreply(statement); |
2400 | endOfSameIdChainData(); |
2401 | } |
2402 | } |
2403 | |
2404 | |
2405 | |
2406 | |