KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > client > net > NetStatementRequest


1 /*
2
3    Derby - Class org.apache.derby.client.net.NetStatementRequest
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20 */

21 package org.apache.derby.client.net;
22
23 import org.apache.derby.iapi.reference.DRDAConstants;
24 import org.apache.derby.client.am.Blob;
25 import org.apache.derby.client.am.Clob;
26 import org.apache.derby.client.am.ColumnMetaData;
27 import org.apache.derby.client.am.ResultSet;
28 import org.apache.derby.client.am.Section;
29 import org.apache.derby.client.am.SqlException;
30 import org.apache.derby.client.am.Types;
31 import org.apache.derby.client.am.ClientMessageId;
32 import org.apache.derby.shared.common.reference.SQLState;
33
34 // For performance, should we worry about the ordering of our DDM command parameters
35

36 public class NetStatementRequest extends NetPackageRequest implements StatementRequestInterface {
37     java.util.ArrayList JavaDoc extdtaPositions_ = null; // Integers: build EXTDTA for column i
38
int overrideLid_ = FdocaConstants.FIRST_OVERRIDE_LID;
39
40     // promototed parameters hold parameters that are promotoed to a different
41
// data type because they are too large to represent in PROTOCOL otherwise.
42
// This currently only applies for promotion of (VAR)CHAR -> CLOB and (VAR)BINARY -> BLOB
43
// The key for this structure is the parameter index. Note that having this
44
// collection does not eliminate the need for extdtaPositions_ because that
45
// is still needed for non-promototed LOBs
46
java.util.HashMap JavaDoc promototedParameters_ = new java.util.HashMap JavaDoc();
47
48     NetStatementRequest(NetAgent netAgent, CcsidManager ccsidManager, int bufferSize) {
49         super(netAgent, ccsidManager, bufferSize);
50     }
51
52     //----------------------------- entry points ---------------------------------
53

54     // Write the message to perform an execute immediate.
55
// The SQL statement sent as command data cannot contain references
56
// to either input variables or output variables.
57
//
58
// preconditions:
59
public void writeExecuteImmediate(NetStatement materialStatement,
60                                       String JavaDoc sql,
61                                       Section section) throws SqlException {
62         buildEXCSQLIMM(section,
63                 false, //sendQryinsid
64
0); //qryinsid
65
buildSQLSTTcommandData(sql); // statement follows in sqlstt command data object
66
}
67
68     // Write the message to preform a prepare into.
69
// Once the SQL statement has been prepared, it is executed until the unit of work, in
70
// which the PRPSQLSTT command was issued, ends. An exception to this is if
71
// Keep Dynamic is being used.
72
//
73
// preconditions:
74
public void writePrepareDescribeOutput(NetStatement materialStatement,
75                                            String JavaDoc sql,
76                                            Section section) throws SqlException {
77         buildPRPSQLSTT(section,
78                 sql,
79                 true, //sendRtnsqlda
80
true, //sendTypsqlda
81
CodePoint.TYPSQLDA_X_OUTPUT); //typsqlda
82

83         if (((NetStatement) materialStatement).statement_.cursorAttributesToSendOnPrepare_ != null) {
84             buildSQLATTRcommandData(((NetStatement) materialStatement).statement_.cursorAttributesToSendOnPrepare_);
85         }
86
87         buildSQLSTTcommandData(sql); // statement follows in sqlstt command data object
88
}
89
90     // Write the message to perform a reprepare.
91
//
92
// preconditions:
93
public void writePrepare(NetStatement materialStatement,
94                              String JavaDoc sql,
95                              Section section) throws SqlException {
96         buildPRPSQLSTT(section,
97                 sql,
98                 false, //sendRtnsqlda
99
false, //sendTypsqlda
100
0); //typsqlda
101

102         if (((NetStatement) materialStatement).statement_.cursorAttributesToSendOnPrepare_ != null) {
103             buildSQLATTRcommandData(((NetStatement) materialStatement).statement_.cursorAttributesToSendOnPrepare_);
104         }
105
106         buildSQLSTTcommandData(sql); // statement follows in sqlstt command data object
107
}
108
109     // Write the message to execute prepared sql statement.
110
//
111
// preconditions:
112
public void writeExecute(NetPreparedStatement materialPreparedStatement,
113                              Section section,
114                              ColumnMetaData parameterMetaData,
115                              Object JavaDoc[] inputs,
116                              int numInputColumns,
117                              boolean outputExpected,
118                              boolean chained) throws SqlException // chained flag for blobs only //dupqry
119
{
120         buildEXCSQLSTT(section,
121                 true, // sendOutexp
122
outputExpected, // outexp
123
false, // sendPrcnam
124
null, // prcnam
125
false, // sendQryblksz
126
false, // sendMaxrslcnt,
127
0, // maxrslcnt,
128
false, // sendMaxblkext
129
0, // maxblkext
130
false, // sendRslsetflg
131
0, // resultSetFlag
132
false, // sendQryrowset
133
0); // qryrowset
134

135         if (numInputColumns > 0) {
136             if ((extdtaPositions_ != null) && (!extdtaPositions_.isEmpty())) {
137                 extdtaPositions_.clear(); // reset extdta column position markers
138
}
139
140             boolean overrideExists = buildSQLDTAcommandData(numInputColumns,
141                     parameterMetaData,
142                     inputs);
143
144             // can we eleminate the chain argument needed for lobs
145
buildEXTDTA(parameterMetaData, inputs, chained);
146         }
147     }
148
149
150     // Write the message to open a bound or prepared query with input parameters.
151
// Check this -> For open query with input parameters
152
//
153
// preconditions:
154
public void writeOpenQuery(NetPreparedStatement materialPreparedStatement,
155                                Section section,
156                                int fetchSize,
157                                int resultSetType,
158                                int numInputColumns,
159                                org.apache.derby.client.am.ColumnMetaData parameterMetaData,
160                                Object JavaDoc[] inputs) throws SqlException {
161         boolean sendQryrowset = checkSendQryrowset(fetchSize, resultSetType);
162         fetchSize = checkFetchsize(fetchSize, resultSetType);
163         // think about if there is a way we can call build ddm just passing ddm parameters and not passing the material ps object
164
// maybe not, if sometimes we need to set the caches hanging off the ps object during the ddm build
165
// maybe we can extricate conditionals in the build ddm logic outside
166

167         buildOPNQRY(section,
168                 sendQryrowset,
169                 fetchSize);
170
171
172         // may be able to merge this with firstContinueQuery_ and push above conditional to common
173
((NetStatement) materialPreparedStatement).qryrowsetSentOnOpnqry_ = sendQryrowset;
174
175         if (numInputColumns > 0) {
176             if ((extdtaPositions_ != null) && (!extdtaPositions_.isEmpty())) {
177                 extdtaPositions_.clear(); // reset extdta column position markers
178
}
179             // is this the best place for this
180
// EXCSQSTT needs this too
181

182             // think about having this method return a boolean to
183
// indicate the extdta should be built
184
boolean overrideExists = buildSQLDTAcommandData(numInputColumns,
185                     parameterMetaData,
186                     inputs);
187
188             // can we eleminate the chain argument needed for lobs
189
// do we chain after Extdta's on open, verify this
190
buildEXTDTA(parameterMetaData,
191                     inputs,
192                     false); //chained, do we chain after Extdta's on open
193
}
194     }
195
196     // Write the message to open a bound or prepared query without input parameters.
197
// Check this-> For open query without input parameters
198
public void writeOpenQuery(NetStatement materialStatement,
199                                Section section,
200                                int fetchSize,
201                                int resultSetType) throws SqlException {
202         boolean sendQryrowset = checkSendQryrowset(fetchSize, resultSetType);
203         fetchSize = checkFetchsize(fetchSize, resultSetType);
204
205         // think about if there is a way we can call build ddm just passing ddm parameters and not passing the material ps object
206
// maybe not, if sometimes we need to set the caches hanging off the ps object during the ddm build
207
// maybe we can extricate conditionals in the build ddm logic outside
208
buildOPNQRY(section,
209                 sendQryrowset,
210                 fetchSize);
211
212
213         // may be able to merge this with firstContinueQuery_ and push above conditional to common
214
((NetStatement) materialStatement).qryrowsetSentOnOpnqry_ = sendQryrowset; // net-specific event
215

216
217     }
218
219     // Write the message to peform a describe input.
220
//
221

222     public void writeDescribeInput(NetPreparedStatement materialPreparedStatement,
223                                    Section section) throws SqlException {
224         int typsqlda = CodePoint.TYPSQLDA_X_INPUT;
225
226         buildDSCSQLSTT(section,
227                 true, //sendTypsqlda
228
typsqlda);
229     }
230
231     // Write the message to peform a describe output.
232
//
233
// preconditions:
234
public void writeDescribeOutput(NetPreparedStatement materialPreparedStatement,
235                                     Section section) throws SqlException {
236         // pick standard, light, extended sqlda. possibly push this up even more
237
// right now use SQLAM level as determining factor and go for the most data.
238
// if standard is the only suported option, don't send the typsqlda
239
// and let server default to standard. This prevents accidentally sending
240
// a typsqlda to a downlevel server. typsqlda is only supported at sqlam 6.
241
//KATHEY CHECK
242
buildDSCSQLSTT(section,
243                 true, //sendTypsqlda
244
CodePoint.TYPSQLDA_X_OUTPUT); //typsqlda
245
}
246
247     // Write the message to execute a stored procedure.
248
//
249
// preconditions:
250
public void writeExecuteCall(NetStatement materialStatement,
251                                  boolean outputExpected,
252                                  String JavaDoc procedureName,
253                                  Section section,
254                                  int fetchSize,
255                                  boolean suppressResultSets, // for batch updates == true
256
int resultSetType,
257                                  ColumnMetaData parameterMetaData,
258                                  Object JavaDoc[] inputs) throws SqlException // chain is for blobs
259
{
260         // always send QRYROWSET on EXCSQLSTT
261
boolean sendQryrowset = true;
262         fetchSize = (fetchSize == 0) ? org.apache.derby.client.am.Configuration.defaultFetchSize : fetchSize;
263
264         boolean sendPrcnam = (procedureName != null) ? true : false;
265         int numParameters = (parameterMetaData != null) ? parameterMetaData.columns_ : 0;
266         outputExpected = numParameters > 0;
267
268         // is it right here to send maxblkext (-1)
269
buildEXCSQLSTT(section,
270                 true, // sendOutexp
271
outputExpected, // outexp
272
sendPrcnam, // sendPrcnam
273
procedureName, // prcnam
274
true, // sendQryblksz
275
!suppressResultSets, // sendMaxrslcnt,
276
CodePoint.MAXRSLCNT_NOLIMIT, // maxrslcnt,
277
true, // sendMaxblkext
278
-1, // maxblkext (-1 for AR capable of receiving entire result set)
279
true, // sendRslsetflg
280
calculateResultSetFlags(), // resultSetFlag
281
sendQryrowset, // sendQryrowset
282
fetchSize); // qryrowset
283

284         if (numParameters > 0) {
285             if ((extdtaPositions_ != null) && (!extdtaPositions_.isEmpty())) {
286                 extdtaPositions_.clear(); // reset extdta column position markers
287
}
288             // is this the best place for this (OPNQRY needs this too)
289

290             // think about having this method return a boolean to
291
// indicate the extdta should be built
292
boolean overrideExists = buildSQLDTAcommandData(numParameters,
293                     parameterMetaData,
294                     inputs);
295
296             buildEXTDTA(parameterMetaData, inputs, false); // no chained autocommit for CALLs
297
}
298
299         ((NetStatement) materialStatement).qryrowsetSentOnOpnqry_ = sendQryrowset;
300     }
301
302     // Write the message to execute an SQL Set Statement.
303
/*
304   public void writeSetGenericSQLSetInfo (org.apache.derby.client.am.SetGenericSQLSetPiggybackCommand setGenericSQLSetPiggybackCommand,
305                                   org.apache.derby.client.am.JDBCSection section) throws SqlException
306   {
307     buildEXCSQLSET (section);
308
309     java.util.List sqlsttList = setGenericSQLSetPiggybackCommand.getList();
310     for (int i = 0; i < sqlsttList.size(); i++) {
311       String sql = (String)sqlsttList.get(i);
312       // Build SQLSTT only for the SET statement that coming from the server after RLSCONV
313       buildSQLSTTcommandData (sql);
314     }
315   }
316
317 */

318     //----------------------helper methods----------------------------------------
319
// These methods are "private protected", which is not a recognized java privilege,
320
// but means that these methods are private to this class and to subclasses,
321
// and should not be used as package-wide friendly methods.
322

323     // Build the Open Query Command to open a query to a relational database.
324
// At SQLAM >= 7 we can request the return of a DA, are there
325
// scenarios where this should currently be done (it is not supported now)
326
//
327
// preconditions:
328
// the sqlam and/or prdid must support command and parameters passed to this method,
329
// method will not validate against the connection's level of support
330
//
331
void buildOPNQRY(Section section,
332                      boolean sendQueryRowSet,
333                      int fetchSize) throws SqlException {
334         createCommand();
335         markLengthBytes(CodePoint.OPNQRY);
336
337         buildPKGNAMCSN(section);
338         buildQRYBLKSZ(); // specify a hard coded query block size
339

340         if (sendQueryRowSet) {
341             buildMAXBLKEXT(-1);
342             buildQRYROWSET(fetchSize);
343         }
344
345         // Tell the server to close forward-only result sets
346
// implicitly when they are exhausted. The server will ignore
347
// this parameter if the result set is scrollable.
348
if (netAgent_.netConnection_.serverSupportsQryclsimp()) {
349             buildQRYCLSIMP();
350         }
351
352         updateLengthBytes(); // opnqry is complete
353
}
354
355     // Build the Execute Immediate SQL Statement Command to
356
// execute a non-cursor SQL statement sent as command data.
357
//
358
// precondtions:
359
void buildEXCSQLIMM(Section section,
360                         boolean sendQryinsid,
361                         long qryinsid) throws SqlException {
362         createCommand();
363         markLengthBytes(CodePoint.EXCSQLIMM);
364
365         buildPKGNAMCSN(section);
366         buildRDBCMTOK();
367         if (sendQryinsid) {
368             buildQRYINSID(qryinsid);
369         }
370
371         updateLengthBytes();
372     }
373
374     // Build the Prepare SQL Statement Command to dynamically binds an
375
// SQL statement to a section in an existing relational database (RDB) package.
376
//
377
// preconditions:
378
// the sqlam and/or prdid must support command and parameters passed to this method,
379
// method will not validate against the connection's level of support
380
void buildPRPSQLSTT(Section section,
381                         String JavaDoc sql,
382                         boolean sendRtnsqlda,
383                         boolean sendTypsqlda,
384                         int typsqlda) throws SqlException {
385         createCommand();
386         markLengthBytes(CodePoint.PRPSQLSTT);
387
388         buildPKGNAMCSN(section);
389         if (sendRtnsqlda) {
390             buildRTNSQLDA();
391         }
392         if (sendTypsqlda) {
393             buildTYPSQLDA(typsqlda);
394         }
395
396         updateLengthBytes();
397     }
398
399     // Build the command to execute an SQL SET Statement.
400
// Called by NETSetClientPiggybackCommand.write()
401
//
402
// preconditions:
403
// the sqlam and/or prdid must support command and parameters passed to this method,
404
// method will not validate against the connection's level of support
405
void buildEXCSQLSET(Section section)
406             throws SqlException {
407         createCommand();
408         markLengthBytes(CodePoint.EXCSQLSET);
409         buildPKGNAMCSN(section); // is this PKGNAMCSN or PKGNAMCT
410
updateLengthBytes();
411     }
412
413     // Build the Execute SQL Statement (EXCSQLSTT) Command
414
// to execute a non-cursor SQL statement previously bound into a named package
415
// of a relational database (RDB). The SQL statement can optionally include
416
// references to input variables, output variables, or both.
417
//
418
// At SQLAM >= 7 we can get a DA back on this, are there times that we want to request it
419
// If so, we probably want to pass a parameter indicating the sqldaLevel requested.
420
//
421
// preconditions:
422
// the sqlam and/or prdid must support command and parameters passed to this method,
423
// method will not validate against the connection's level of support
424
// Here is the preferred codepoint ordering:
425
// PKGNAMCSN
426
// RDBCMTOK
427
// OUTEXP
428
// QRYBLKSZ
429
// MAXBLKEXT
430
// MAXRSLCNT
431
// RSLSETFLG
432
// QRYROWSET
433
// RTNSQLDA
434
// TYPSQLDA
435
// NBRROW
436
// ATMIND
437
// PRCNAM
438
// OUTOVROPT
439
// RDBNAM
440
void buildEXCSQLSTT(Section section,
441                         boolean sendOutexp,
442                         boolean outexp,
443                         boolean sendPrcnam,
444                         String JavaDoc prcnam,
445                         boolean sendQryblksz,
446                         boolean sendMaxrslcnt,
447                         int maxrslcnt,
448                         boolean sendMaxblkext,
449                         int maxblkext,
450                         boolean sendRslsetflg,
451                         int resultSetFlag,
452                         boolean sendQryrowset,
453                         int qryrowset) throws SqlException {
454         createCommand();
455         markLengthBytes(CodePoint.EXCSQLSTT);
456
457         buildPKGNAMCSN(section);
458         buildRDBCMTOK();
459         if (sendOutexp) {
460             buildOUTEXP(outexp);
461         }
462         if (sendQryblksz) {
463             buildQRYBLKSZ();
464         }
465         if (sendQryrowset && sendMaxblkext) {
466             buildMAXBLKEXT(maxblkext);
467         }
468         if (sendMaxrslcnt) {
469             buildMAXRSLCNT(maxrslcnt);
470         }
471         if (sendRslsetflg) {
472             buildRSLSETFLG(resultSetFlag);
473         }
474         if (sendQryrowset) {
475             buildQRYROWSET(qryrowset);
476         }
477         if (sendPrcnam) {
478             buildPRCNAM(prcnam);
479         }
480
481         updateLengthBytes(); // command is complete, update the length bytes
482
}
483
484     // Build the Describe SQL Statement command.
485
//
486
// preconditions:
487
// the sqlam and/or prdid must support command and parameters passed to this method,
488
// method will not validate against the connection's level of support
489
void buildDSCSQLSTT(Section section,
490                         boolean sendTypsqlda,
491                         int typsqlda) throws SqlException {
492         createCommand();
493         markLengthBytes(CodePoint.DSCSQLSTT);
494
495         buildPKGNAMCSN(section);
496         if (sendTypsqlda) {
497             buildTYPSQLDA(typsqlda);
498         }
499
500         updateLengthBytes();
501     }
502
503     // Build the SQL Program Variable Data Command Data Object.
504
// This object contains the input data to an SQL statement
505
// that an RDB is executing.
506
//
507
// preconditions:
508
boolean buildSQLDTAcommandData(int numInputColumns,
509                                    ColumnMetaData parameterMetaData,
510                                    Object JavaDoc[] inputRow) throws SqlException {
511         createEncryptedCommandData();
512
513         int loc = offset_;
514
515         markLengthBytes(CodePoint.SQLDTA);
516
517         int[][] protocolTypesAndLengths = allocateLidAndLengthsArray(parameterMetaData);
518
519         java.util.Hashtable JavaDoc protocolTypeToOverrideLidMapping = null;
520         java.util.ArrayList JavaDoc mddOverrideArray = null;
521         protocolTypeToOverrideLidMapping =
522                 computeProtocolTypesAndLengths(inputRow, parameterMetaData, protocolTypesAndLengths,
523                         protocolTypeToOverrideLidMapping);
524
525         boolean overrideExists = false;
526
527         buildFDODSC(numInputColumns,
528                 protocolTypesAndLengths,
529                 overrideExists,
530                 protocolTypeToOverrideLidMapping,
531                 mddOverrideArray);
532
533         buildFDODTA(numInputColumns,
534                 protocolTypesAndLengths,
535                 inputRow);
536
537         updateLengthBytes(); // for sqldta
538
if (netAgent_.netConnection_.getSecurityMechanism() ==
539                 NetConfiguration.SECMEC_EUSRIDDTA ||
540                 netAgent_.netConnection_.getSecurityMechanism() ==
541                 NetConfiguration.SECMEC_EUSRPWDDTA) {
542             encryptDataStream(loc);
543         }
544
545         return overrideExists;
546     }
547
548     // Build the FDOCA Data Descriptor Scalar whose value is a FDOCA
549
// Descriptor or a segment of an FDOCA Descriptor.
550
//
551
// preconditions:
552
private void buildFDODSC(int numColumns,
553                              int[][] protocolTypesAndLengths,
554                              boolean overrideExists,
555                              java.util.Hashtable JavaDoc overrideMap,
556                              java.util.ArrayList JavaDoc overrideArray) throws SqlException {
557         markLengthBytes(CodePoint.FDODSC);
558         buildSQLDTA(numColumns, protocolTypesAndLengths, overrideExists, overrideMap, overrideArray);
559         updateLengthBytes();
560     }
561
562     // Build the FDOCA SQLDTA Late Row Descriptor.
563
//
564
// preconditions:
565
protected void buildSQLDTA(int numColumns,
566                                int[][] lidAndLengthOverrides,
567                                boolean overrideExists,
568                                java.util.Hashtable JavaDoc overrideMap,
569                                java.util.ArrayList JavaDoc overrideArray) throws SqlException {
570         // mdd overrides need to be built first if any before the descriptors are built.
571
if (overrideExists) {
572             buildMddOverrides(overrideArray);
573             writeBytes(FdocaConstants.MDD_SQLDTAGRP_TOSEND);
574         }
575
576         buildSQLDTAGRP(numColumns, lidAndLengthOverrides, overrideExists, overrideMap);
577
578         if (overrideExists) {
579             writeBytes(FdocaConstants.MDD_SQLDTA_TOSEND);
580         }
581         writeBytes(FdocaConstants.SQLDTA_RLO_TOSEND);
582     }
583
584     // Build the FDOCA SQLDTAGRP Late Group Descriptor.
585
// preconditions:
586
protected void buildSQLDTAGRP(int numVars,
587                                   int[][] lidAndLengthOverrides,
588                                   boolean mddRequired,
589                                   java.util.Hashtable JavaDoc overrideMap) throws SqlException {
590         int n = 0;
591         int offset = 0;
592
593         n = calculateColumnsInSQLDTAGRPtriplet(numVars);
594         buildTripletHeader(((3 * n) + 3),
595                 FdocaConstants.NGDA_TRIPLET_TYPE,
596                 FdocaConstants.SQLDTAGRP_LID);
597
598         do {
599             writeLidAndLengths(lidAndLengthOverrides, n, offset, mddRequired, overrideMap);
600             numVars -= n;
601             if (numVars == 0) {
602                 break;
603             }
604
605             offset += n;
606             n = calculateColumnsInSQLDTAGRPtriplet(numVars);
607             buildTripletHeader(((3 * n) + 3),
608                     FdocaConstants.CPT_TRIPLET_TYPE,
609                     0x00);
610         } while (true);
611     }
612
613 /////////// perf end
614

615
616     protected void buildOUTOVR(ResultSet resultSet,
617                                ColumnMetaData resultSetMetaData) throws SqlException {
618         createCommandData();
619         markLengthBytes(CodePoint.OUTOVR);
620         int[][] outputOverrides =
621                 calculateOUTOVRLidAndLengthOverrides(resultSet, resultSetMetaData);
622         buildSQLDTARD(resultSetMetaData.columns_, outputOverrides);
623         updateLengthBytes();
624     }
625
626     private int[][] calculateOUTOVRLidAndLengthOverrides(ResultSet resultSet,
627                                                          ColumnMetaData resultSetMetaData) {
628         int numVars = resultSetMetaData.columns_;
629         int[][] lidAndLengths = new int[numVars][2]; //everything initialized to "default triplet"
630

631         return lidAndLengths;
632     }
633
634     protected void buildSQLDTARD(int numColumns, int[][] lidAndLengthOverrides) throws SqlException {
635         buildSQLCADTA(numColumns, lidAndLengthOverrides);
636         writeBytes(FdocaConstants.SQLDTARD_RLO_TOSEND);
637     }
638
639     protected void buildSQLCADTA(int numColumns, int[][] lidAndLengthOverrides) throws SqlException {
640         buildSQLDTAGRP(numColumns, lidAndLengthOverrides, false, null); // false means no mdd override
641
writeBytes(FdocaConstants.SQLCADTA_RLO_TOSEND);
642     }
643
644     private void buildFDODTA(int numVars,
645                              int[][] protocolTypesAndLengths,
646                              Object JavaDoc[] inputs) throws SqlException {
647         try
648         {
649             long dataLength = 0;
650             Object JavaDoc o = null;
651
652             markLengthBytes(CodePoint.FDODTA);
653             write1Byte(FdocaConstants.NULL_LID); // write the 1-byte row indicator
654

655             // write data for each input column
656
for (int i = 0; i < numVars; i++) {
657                 if (inputs[i] == null) {
658                     if ((protocolTypesAndLengths[i][0] % 2) == 1) {
659                         write1Byte(FdocaConstants.NULL_DATA);
660                     } else {
661                         //bug check
662
}
663                 } else {
664                     if ((protocolTypesAndLengths[i][0] % 2) == 1) {
665                         write1Byte(FdocaConstants.INDICATOR_NULLABLE);
666                     }
667
668                     switch (protocolTypesAndLengths[i][0] | 0x01) { // mask out null indicator
669
case DRDAConstants.DRDA_TYPE_NVARMIX:
670                     case DRDAConstants.DRDA_TYPE_NLONGMIX:
671                         // What to do for server that don't understand 1208 (UTF-8)
672
// check for a promototed type, and use that instead if it exists
673
o = retrievePromotedParameterIfExists(i);
674                         if (o == null) {
675                             writeSingleorMixedCcsidLDString((String JavaDoc) inputs[i], netAgent_.typdef_.getCcsidMbcEncoding());
676                         } else { // use the promototed object instead
677
Clob c = (Clob) o;
678                             dataLength = c.length();
679                             setFDODTALobLength(protocolTypesAndLengths, i, dataLength);
680                         }
681                         break;
682
683                     case DRDAConstants.DRDA_TYPE_NVARCHAR:
684                     case DRDAConstants.DRDA_TYPE_NLONG:
685                         o = retrievePromotedParameterIfExists(i);
686                         if (o == null) {
687
688                         } else { // use the promototed object instead
689
dataLength = ((Clob) o).length();
690                             setFDODTALobLength(protocolTypesAndLengths, i, dataLength);
691                         }
692                         break;
693
694                     case DRDAConstants.DRDA_TYPE_NINTEGER:
695                         writeIntFdocaData(((Integer JavaDoc) inputs[i]).intValue());
696                         break;
697                     case DRDAConstants.DRDA_TYPE_NSMALL:
698                         writeShortFdocaData(((Short JavaDoc) inputs[i]).shortValue());
699                         break;
700                     case DRDAConstants.DRDA_TYPE_NFLOAT4:
701                         writeFloat(((Float JavaDoc) inputs[i]).floatValue());
702                         break;
703                     case DRDAConstants.DRDA_TYPE_NFLOAT8:
704                         writeDouble(((Double JavaDoc) inputs[i]).doubleValue());
705                         break;
706                     case DRDAConstants.DRDA_TYPE_NDECIMAL:
707                         writeBigDecimal((java.math.BigDecimal JavaDoc) inputs[i],
708                                 (protocolTypesAndLengths[i][1] >> 8) & 0xff, // described precision not actual
709
protocolTypesAndLengths[i][1] & 0xff); // described scale, not actual
710
break;
711                     case DRDAConstants.DRDA_TYPE_NDATE:
712                         writeDate((java.sql.Date JavaDoc) inputs[i]);
713                         break;
714                     case DRDAConstants.DRDA_TYPE_NTIME:
715                         writeTime((java.sql.Time JavaDoc) inputs[i]);
716                         break;
717                     case DRDAConstants.DRDA_TYPE_NTIMESTAMP:
718                         writeTimestamp((java.sql.Timestamp JavaDoc) inputs[i]);
719                         break;
720                     case DRDAConstants.DRDA_TYPE_NINTEGER8:
721                         writeLongFdocaData(((Long JavaDoc) inputs[i]).longValue());
722                         break;
723                     case DRDAConstants.DRDA_TYPE_NVARBYTE:
724                     case DRDAConstants.DRDA_TYPE_NLONGVARBYTE:
725                         o = retrievePromotedParameterIfExists(i);
726                         if (o == null) {
727                             writeLDBytes((byte[]) inputs[i]);
728                         } else { // use the promototed object instead
729
Blob b = (Blob) o;
730                             dataLength = b.length();
731                             setFDODTALobLength(protocolTypesAndLengths, i, dataLength);
732                         }
733                         break;
734                     case DRDAConstants.DRDA_TYPE_NLOBCSBCS:
735                     case DRDAConstants.DRDA_TYPE_NLOBCDBCS:
736                         // check for a promoted Clob
737
o = retrievePromotedParameterIfExists(i);
738                         if (o == null) {
739                             try {
740                                 dataLength = ((java.sql.Clob JavaDoc) inputs[i]).length();
741                             } catch (java.sql.SQLException JavaDoc e) {
742                                 throw new SqlException(netAgent_.logWriter_,
743                                     new ClientMessageId(SQLState.NET_ERROR_GETTING_BLOB_LENGTH),
744                                     e);
745                             }
746                         } else {
747                             dataLength = ((Clob) o).length();
748                         }
749                         setFDODTALobLength(protocolTypesAndLengths, i, dataLength);
750                         break;
751                     case DRDAConstants.DRDA_TYPE_NLOBBYTES:
752                         // check for a promoted Clob
753
o = retrievePromotedParameterIfExists(i);
754                         if (o == null) {
755                             try {
756                                 dataLength = ((java.sql.Blob JavaDoc) inputs[i]).length();
757                             } catch (java.sql.SQLException JavaDoc e) {
758                                 throw new SqlException(netAgent_.logWriter_,
759                                     new ClientMessageId(SQLState.NET_ERROR_GETTING_BLOB_LENGTH),
760                                     e);
761                             }
762                         } else { // use promoted Blob
763
dataLength = ((Blob) o).length();
764                         }
765                         setFDODTALobLength(protocolTypesAndLengths, i, dataLength);
766                         break;
767                     case DRDAConstants.DRDA_TYPE_NLOBCMIXED:
768                         // check for a promoted Clob
769
o = retrievePromotedParameterIfExists(i);
770                         if (o == null) {
771                             if (((Clob) inputs[i]).isString()) {
772                                 dataLength = ((Clob) inputs[i]).getUTF8Length();
773                             } else // must be a Unicode stream
774
{
775                                 dataLength = ((Clob) inputs[i]).length();
776                             }
777                         } else { // use promoted Clob
778
dataLength = ((Clob) o).length();
779                         }
780                         setFDODTALobLength(protocolTypesAndLengths, i, dataLength);
781                         break;
782                     default:
783                         throw new SqlException(netAgent_.logWriter_,
784                             new ClientMessageId(SQLState.NET_UNRECOGNIZED_JDBC_TYPE),
785                                new Integer JavaDoc(protocolTypesAndLengths[i][0]),
786                                new Integer JavaDoc(numVars), new Integer JavaDoc(i));
787                     }
788                 }
789             }
790             updateLengthBytes(); // for fdodta
791
}
792         catch ( java.sql.SQLException JavaDoc se )
793         {
794             throw new SqlException(se);
795         }
796     }
797
798     // preconditions:
799
private void buildEXTDTA(ColumnMetaData parameterMetaData,
800                              Object JavaDoc[] inputRow,
801                              boolean chained) throws SqlException {
802         try
803         {
804             // build the EXTDTA data, if necessary
805
if (extdtaPositions_ != null) {
806                 boolean chainFlag, chainedWithSameCorrelator;
807
808                 for (int i = 0; i < extdtaPositions_.size(); i++) {
809                     int index = ((Integer JavaDoc) extdtaPositions_.get(i)).intValue();
810
811                     // is this the last EXTDTA to be built?
812
if (i != extdtaPositions_.size() - 1) { // no
813
chainFlag = true;
814                         chainedWithSameCorrelator = true;
815                     } else { // yes
816
chainFlag = chained;
817                         chainedWithSameCorrelator = false;
818                     }
819
820                     // do we have to write a null byte?
821
boolean writeNullByte = false;
822                     if (parameterMetaData.nullable_[index]) {
823                         writeNullByte = true;
824                     }
825                     // Use the type of the input parameter rather than the input
826
// column if possible.
827
int parameterType = parameterMetaData.clientParamtertype_[index];
828                     if (parameterType == 0) {
829                         parameterType = parameterMetaData.types_[index];
830                     }
831
832                     // the follow types are possible due to promotion to BLOB
833
if (parameterType == Types.BLOB
834                             || parameterType == Types.BINARY
835                             || parameterType == Types.VARBINARY
836                             || parameterType == Types.LONGVARBINARY) {
837                         Blob o = (Blob) retrievePromotedParameterIfExists(index);
838                         java.sql.Blob JavaDoc b = (o == null) ? (java.sql.Blob JavaDoc) inputRow[index] : o;
839                         boolean isExternalBlob = !(b instanceof org.apache.derby.client.am.Blob);
840                         if (isExternalBlob) {
841                             try {
842                                 writeScalarStream(chainFlag,
843                                         chainedWithSameCorrelator,
844                                         CodePoint.EXTDTA,
845                                         (int) b.length(),
846                                         b.getBinaryStream(),
847                                         writeNullByte,
848                                         index + 1);
849                             } catch (java.sql.SQLException JavaDoc e) {
850                                 throw new SqlException(netAgent_.logWriter_,
851                                     new ClientMessageId(SQLState.NET_ERROR_GETTING_BLOB_LENGTH),
852                                     e);
853                             }
854                         } else if (((Blob) b).isBinaryStream()) {
855                             writeScalarStream(chainFlag,
856                                     chainedWithSameCorrelator,
857                                     CodePoint.EXTDTA,
858                                     (int) ((Blob) b).length(),
859                                     ((Blob) b).getBinaryStream(),
860                                     writeNullByte,
861                                     index + 1);
862                         } else { // must be a binary string
863
// note: a possible optimization is to use writeScalarLobBytes
864
// when the input is small
865
// use this: if (b.length () < DssConstants.MAX_DSS_LEN - 6 - 4)
866
// writeScalarLobBytes (...)
867
// Yes, this would avoid having to new up a java.io.ByteArrayInputStream
868
writeScalarStream(chainFlag,
869                                     chainedWithSameCorrelator,
870                                     CodePoint.EXTDTA,
871                                     (int) ((Blob) b).length(),
872                                     ((Blob) b).getBinaryStream(),
873                                     writeNullByte,
874                                     index + 1);
875                         }
876                     }
877                     // the follow types are possible due to promotion to CLOB
878
else if (
879                             parameterType == Types.CLOB
880                             || parameterType == Types.CHAR
881                             || parameterType == Types.VARCHAR
882                             || parameterType == Types.LONGVARCHAR) {
883                         Clob o = (Clob) retrievePromotedParameterIfExists(index);
884                         java.sql.Clob JavaDoc c = (o == null) ? (java.sql.Clob JavaDoc) inputRow[index] : o;
885                         boolean isExternalClob = !(c instanceof org.apache.derby.client.am.Clob);
886
887                         if (isExternalClob) {
888                             try {
889                                 writeScalarStream(chainFlag,
890                                         chainedWithSameCorrelator,
891                                         CodePoint.EXTDTA,
892                                         (int) c.length(),
893                                         c.getCharacterStream(),
894                                         writeNullByte,
895                                         index + 1);
896                             } catch (java.sql.SQLException JavaDoc e) {
897                                 throw new SqlException(netAgent_.logWriter_,
898                                     new ClientMessageId(SQLState.NET_ERROR_GETTING_BLOB_LENGTH),
899                                     e);
900                             }
901                         } else if (((Clob) c).isCharacterStream()) {
902                             writeScalarStream(chainFlag,
903                                     chainedWithSameCorrelator,
904                                     CodePoint.EXTDTA,
905                                     (int) ((Clob) c).length(),
906                                     ((Clob) c).getCharacterStream(),
907                                     writeNullByte,
908                                     index + 1);
909                         } else if (((Clob) c).isAsciiStream()) {
910                             writeScalarStream(chainFlag,
911                                     chainedWithSameCorrelator,
912                                     CodePoint.EXTDTA,
913                                     (int) ((Clob) c).length(),
914                                     ((Clob) c).getAsciiStream(),
915                                     writeNullByte,
916                                     index + 1);
917                         } else if (((Clob) c).isUnicodeStream()) {
918                             writeScalarStream(chainFlag,
919                                     chainedWithSameCorrelator,
920                                     CodePoint.EXTDTA,
921                                     (int) ((Clob) c).length(),
922                                     ((Clob) c).getUnicodeStream(),
923                                     writeNullByte,
924                                     index + 1);
925                         } else { // must be a String
926
// note: a possible optimization is to use writeScalarLobBytes
927
// when the input is small.
928
// use this: if (c.length () < DssConstants.MAX_DSS_LEN - 6 - 4)
929
// writeScalarLobBytes (...)
930
writeScalarStream(chainFlag,
931                                     chainedWithSameCorrelator,
932                                     CodePoint.EXTDTA,
933                                     (int) ((Clob) c).getUTF8Length(),
934                                     new java.io.ByteArrayInputStream JavaDoc(((Clob) c).getUtf8String()),
935                                     writeNullByte,
936                                     index + 1);
937                         }
938                     }
939                 }
940             }
941         }
942         catch ( java.sql.SQLException JavaDoc se )
943         {
944             throw new SqlException(se);
945         }
946     }
947
948
949     //-------------------------helper methods-------------------------------------
950
// returns the a promototedParameter object for index or null if it does not exist
951
private Object JavaDoc retrievePromotedParameterIfExists(int index) {
952
953         // consider using a nonsynchronized container or array
954
if (promototedParameters_.isEmpty()) {
955             return null;
956         }
957         return promototedParameters_.get(new Integer JavaDoc(index));
958     }
959
960     private int calculateColumnsInSQLDTAGRPtriplet(int numVars) {
961         if (numVars > FdocaConstants.MAX_VARS_IN_NGDA) //rename to MAX_VARS_IN_SQLDTAGRP_TRIPLET
962
{
963             return FdocaConstants.MAX_VARS_IN_NGDA;
964         }
965         return numVars;
966     }
967
968
969     // Consider refacctor so that this does not even have to look
970
// at the actual object data, and only uses tags from the meta data
971
// only have to call this once, rather than calling this for every input row
972
// backburner: after refactoring this, later on, think about replacing case statements with table lookups
973
private java.util.Hashtable JavaDoc computeProtocolTypesAndLengths(Object JavaDoc[] inputRow,
974                                                                ColumnMetaData parameterMetaData,
975                                                                int[][] lidAndLengths,
976                                                                java.util.Hashtable JavaDoc overrideMap) throws SqlException {
977         try
978         {
979             int numVars = parameterMetaData.columns_;
980             String JavaDoc s = null;
981             if (!promototedParameters_.isEmpty()) {
982                 promototedParameters_.clear();
983             }
984
985             for (int i = 0; i < numVars; i++) {
986
987                 int jdbcType;
988                 // Send the input type unless it is not available.
989
// (e.g an output parameter)
990
jdbcType = parameterMetaData.clientParamtertype_[i];
991                 if (jdbcType == 0) {
992                     jdbcType = parameterMetaData.types_[i];
993                 }
994
995                 // jdbc semantics - This should happen outside of the build methods
996
// if describe input is not supported, we require the user to at least
997
// call setNull() and provide the type information. Otherwise, we won't
998
// be able to guess the right PROTOCOL type to send to the server, and an
999
// exception is thrown.
1000

1001                if (jdbcType == 0) {
1002                    throw new SqlException(netAgent_.logWriter_,
1003                        new ClientMessageId(SQLState.NET_INVALID_JDBC_TYPE_FOR_PARAM),
1004                        new Integer JavaDoc(i));
1005                }
1006
1007                switch (jdbcType) {
1008                case java.sql.Types.CHAR:
1009                case java.sql.Types.VARCHAR:
1010                    // lid: PROTOCOL_TYPE_NVARMIX, length override: 32767 (max)
1011
// dataFormat: String
1012
// this won't work if 1208 is not supported
1013
s = (String JavaDoc) inputRow[i];
1014                    // assumes UTF-8 characters at most 3 bytes long
1015
// Flow the String as a VARCHAR
1016
if (s == null || s.length() <= 32767 / 3) {
1017                        lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NVARMIX;
1018                        lidAndLengths[i][1] = 32767;
1019                    } else {
1020                        // Flow the data as CLOB data if the data too large to for LONGVARCHAR
1021
java.io.ByteArrayInputStream JavaDoc bais = null;
1022                        byte[] ba = null;
1023                        try {
1024                            ba = s.getBytes("UTF-8");
1025                            bais = new java.io.ByteArrayInputStream JavaDoc(ba);
1026                            Clob c = new Clob(netAgent_, bais, "UTF-8", ba.length);
1027                            // inputRow[i] = c;
1028
// Place the new Lob in the promototedParameter_ collection for
1029
// NetStatementRequest use
1030
promototedParameters_.put(new Integer JavaDoc(i), c);
1031
1032                            lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
1033                            lidAndLengths[i][1] = buildPlaceholderLength(c.length());
1034                        } catch (java.io.UnsupportedEncodingException JavaDoc e) {
1035                            throw new SqlException(netAgent_.logWriter_,
1036                                new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
1037                                "byte array", "Clob", e);
1038                        }
1039                    }
1040                    break;
1041                case java.sql.Types.INTEGER:
1042                    // lid: PROTOCOL_TYPE_NINTEGER, length override: 4
1043
// dataFormat: Integer
1044
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NINTEGER;
1045                    lidAndLengths[i][1] = 4;
1046                    break;
1047                case java.sql.Types.BOOLEAN:
1048                case java.sql.Types.SMALLINT:
1049                case java.sql.Types.TINYINT:
1050                case java.sql.Types.BIT:
1051                    // lid: PROTOCOL_TYPE_NSMALL, length override: 2
1052
// dataFormat: Short
1053
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NSMALL;
1054                    lidAndLengths[i][1] = 2;
1055                    break;
1056                case java.sql.Types.REAL:
1057                    // lid: PROTOCOL_TYPE_NFLOAT4, length override: 4
1058
// dataFormat: Float
1059
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NFLOAT4;
1060                    lidAndLengths[i][1] = 4;
1061                    break;
1062                case java.sql.Types.DOUBLE:
1063                case java.sql.Types.FLOAT:
1064                    // lid: PROTOCOL_TYPE_NFLOAT8, length override: 8
1065
// dataFormat: Double
1066
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NFLOAT8;
1067                    lidAndLengths[i][1] = 8;
1068                    break;
1069                case java.sql.Types.NUMERIC:
1070                case java.sql.Types.DECIMAL:
1071                    // lid: PROTOCOL_TYPE_NDECIMAL
1072
// dataFormat: java.math.BigDecimal
1073
// input only:
1074
// if null and describe input - use describe input precision and scale
1075
// if not null and describe input - calculate precision and actual scale from data
1076
// if null and no describe input - guess with precision 1 scale 0
1077
// if not null and no describe input - calculate precision and actual scale from data
1078
// output only:
1079
// use largest precision/scale based on registered scale from registerOutParameter
1080
// inout:
1081
// if null - use largest precision/scale based on scale from registerOutParameter
1082
// if not null - write bigDecimal () pass registered scale so it can pad, you don't even
1083
// have to look at the actual scale at this level.
1084
/*
1085                    if (parameterMetaData.isGuessed) {
1086                      java.math.BigDecimal bigDecimal = (java.math.BigDecimal) inputRow[i];
1087                      int precision = Utils.computeBigDecimalPrecision (bigDecimal);
1088                      lidAndLengths[i][1] = (precision << 8) + // use precision above
1089                                          (bigDecimal.scale() << 0);
1090                    }
1091                    */

1092                    // Split this entire method into two parts, the first method is called only once and the inputRow is not passed,!!
1093
// the second method is called for every inputRow and overrides inputDA lengths/scales based upon the acutal data!
1094
// for decimal and blob columns only
1095
int precision = parameterMetaData.sqlPrecision_[i];
1096                    int scale = parameterMetaData.sqlScale_[i];
1097                    lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NDECIMAL;
1098                    lidAndLengths[i][1] = (precision << 8) + (scale << 0);
1099                    break;
1100                case java.sql.Types.DATE:
1101                    // for input, output, and inout parameters
1102
// lid: PROTOCOL_TYPE_NDATE, length override: 8
1103
// dataFormat: java.sql.Date
1104
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NDATE;
1105                    lidAndLengths[i][1] = 10;
1106                    break;
1107                case java.sql.Types.TIME:
1108                    // for input, output, and inout parameters
1109
// lid: PROTOCOL_TYPE_NTIME, length override: 8
1110
// dataFormat: java.sql.Time
1111
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NTIME;
1112                    lidAndLengths[i][1] = 8;
1113                    break;
1114                case java.sql.Types.TIMESTAMP:
1115                    // for input, output, and inout parameters
1116
// lid: PROTOCOL_TYPE_NTIME, length overrid: 26
1117
// dataFormat: java.sql.Timestamp
1118
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NTIMESTAMP;
1119                    lidAndLengths[i][1] = 26;
1120                    break;
1121                case java.sql.Types.BIGINT:
1122                    // if SQLAM < 6 this should be mapped to decimal (19,0) in common layer
1123
// if SQLAM >=6, lid: PROTOCOL_TYPE_NINTEGER8, length override: 8
1124
// dataFormat: Long
1125
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NINTEGER8;
1126                    lidAndLengths[i][1] = 8;
1127                    break;
1128                case java.sql.Types.LONGVARCHAR:
1129                    // Is this the right thing to do // should this be 32700
1130
s = (String JavaDoc) inputRow[i];
1131                    if (s == null || s.length() <= 32767 / 3) {
1132                        lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLONGMIX;
1133                        lidAndLengths[i][1] = 32767;
1134                    } else {
1135                        // Flow the data as CLOB data if the data too large to for LONGVARCHAR
1136
java.io.ByteArrayInputStream JavaDoc bais = null;
1137                        byte[] ba = null;
1138                        try {
1139                            ba = s.getBytes("UTF-8");
1140                            bais = new java.io.ByteArrayInputStream JavaDoc(ba);
1141                            Clob c = new Clob(netAgent_, bais, "UTF-8", ba.length);
1142
1143                            // inputRow[i] = c;
1144
// Place the new Lob in the promototedParameter_ collection for
1145
// NetStatementRequest use
1146
promototedParameters_.put(new Integer JavaDoc(i), c);
1147
1148                            lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
1149                            lidAndLengths[i][1] = buildPlaceholderLength(c.length());
1150                        } catch (java.io.UnsupportedEncodingException JavaDoc e) {
1151                            throw new SqlException(netAgent_.logWriter_,
1152                                new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
1153                                "byte array", "Clob");
1154                        }
1155                    }
1156                    break;
1157                case java.sql.Types.BINARY:
1158                case java.sql.Types.VARBINARY:
1159                    byte[] ba = (byte[]) inputRow[i];
1160                    if (ba == null) {
1161                        lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NVARBYTE;
1162                        lidAndLengths[i][1] = 32767;
1163                    } else if (ba.length <= 32767) {
1164                        lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NVARBYTE;
1165                        lidAndLengths[i][1] = 32767;
1166                    } else {
1167                        // Promote to a BLOB. Only reach this path in the absence of describe information.
1168
Blob b = new Blob(ba, netAgent_, 0);
1169
1170                        // inputRow[i] = b;
1171
// Place the new Lob in the promototedParameter_ collection for
1172
// NetStatementRequest use
1173
promototedParameters_.put(new Integer JavaDoc(i), b);
1174
1175                        lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
1176                        lidAndLengths[i][1] = buildPlaceholderLength(ba.length);
1177                    }
1178                    break;
1179                case java.sql.Types.LONGVARBINARY:
1180                    ba = (byte[]) inputRow[i];
1181                    if (ba == null) {
1182                        lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLONGVARBYTE;
1183                        lidAndLengths[i][1] = 32767;
1184                    } else if (ba.length <= 32767) {
1185                        lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLONGVARBYTE;
1186                        lidAndLengths[i][1] = 32767;
1187                    } else {
1188                        // Promote to a BLOB. Only reach this path in the absensce of describe information.
1189
Blob b = new Blob(ba, netAgent_, 0);
1190
1191                        // inputRow[i] = b;
1192
// Place the new Lob in the promototedParameter_ collection for
1193
// NetStatementRequest use
1194
promototedParameters_.put(new Integer JavaDoc(i), b);
1195
1196                        lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
1197                        lidAndLengths[i][1] = buildPlaceholderLength(ba.length);
1198                    }
1199                    break;
1200                case java.sql.Types.BLOB:
1201                    java.sql.Blob JavaDoc b = (java.sql.Blob JavaDoc) inputRow[i];
1202                    if (b == null) {
1203                        lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
1204                        lidAndLengths[i][1] =
1205                                buildPlaceholderLength(parameterMetaData.sqlLength_[i]);
1206                    } else {
1207                        lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
1208                        try {
1209                            lidAndLengths[i][1] = buildPlaceholderLength(b.length());
1210                        } catch (java.sql.SQLException JavaDoc e) {
1211                            throw new SqlException(netAgent_.logWriter_,
1212                                new ClientMessageId(SQLState.NET_ERROR_GETTING_BLOB_LENGTH), e);
1213                        }
1214                    }
1215                    break;
1216                case java.sql.Types.CLOB:
1217                    {
1218                        // use columnMeta.singleMixedByteOrDouble_ to decide protocolType
1219
java.sql.Clob JavaDoc c = (java.sql.Clob JavaDoc) inputRow[i];
1220                        boolean isExternalClob = !(c instanceof org.apache.derby.client.am.Clob);
1221                        long lobLength = 0;
1222                        if (c == null) {
1223                            lobLength = parameterMetaData.sqlLength_[i];
1224                        } else if (isExternalClob) {
1225                            try {
1226                                lobLength = c.length();
1227                            } catch (java.sql.SQLException JavaDoc e) {
1228                                throw new SqlException(netAgent_.logWriter_,
1229                                    new ClientMessageId(SQLState.NET_ERROR_GETTING_BLOB_LENGTH),
1230                                    e);
1231                            }
1232                        } else {
1233                            lobLength = ((Clob) c).length();
1234                        }
1235                        if (c == null) {
1236                            lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
1237                            lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
1238                        } else if (isExternalClob) {
1239                            lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCDBCS;
1240                            lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
1241                        } else if (((Clob) c).isCharacterStream()) {
1242                            lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCDBCS;
1243                            lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
1244                        } else if (((Clob) c).isUnicodeStream()) {
1245                            lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
1246                            lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
1247                        } else if (((Clob) c).isAsciiStream()) {
1248                            lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCSBCS;
1249                            lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
1250                        } else if (((Clob) c).isString()) {
1251                            lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
1252                            lidAndLengths[i][1] = buildPlaceholderLength(((Clob) c).getUTF8Length());
1253                        }
1254                    }
1255                    break;
1256                default :
1257                    throw new SqlException(netAgent_.logWriter_,
1258                        new ClientMessageId(SQLState.UNRECOGNIZED_JAVA_SQL_TYPE),
1259                        new Integer JavaDoc(jdbcType));
1260                }
1261
1262                if (!parameterMetaData.nullable_[i]) {
1263                    lidAndLengths[i][0]--;
1264                }
1265            }
1266            return overrideMap;
1267        }
1268        catch ( java.sql.SQLException JavaDoc se )
1269        {
1270            throw new SqlException(se);
1271        }
1272    }
1273
1274    private int buildPlaceholderLength(long totalLength) {
1275        if (totalLength < 0x7fff) {
1276            return 0x8002; // need 2 bytes
1277
} else if (totalLength < 0x7fffffff) {
1278            return 0x8004; // need 4 bytes
1279
} else if (totalLength < 0x7fffffffffffL) {
1280            return 0x8006;
1281        } else {
1282            return 0x8008; // need 8 bytes
1283
}
1284    }
1285
1286    // Output Expected indicates wheterh the requester expects the target
1287
// SQLAM to return output with an SQLDTARD reply data object
1288
// as a result of the execution of the referenced SQL statement.
1289
// this is a single byte.
1290
// there are two possible enumerated values:
1291
// 0x'F1' (CodePoint.TRUE) - for true indicating the requester expects output
1292
// 0x'F0' (CodePoint.FALSE) - for false indicating the requeser does not expect output
1293
// 0x'F0' is the default.
1294
//
1295
// preconditions:
1296
// sqlam must support this parameter on the command, method will not check.
1297
private void buildOUTEXP(boolean outputExpected) throws SqlException {
1298        if (outputExpected) {
1299            writeScalar1Byte(CodePoint.OUTEXP, CodePoint.TRUE);
1300        }
1301    }
1302
1303    // Maximum Number of Extra Blocks specifies a limit on the number of extra
1304
// blocks of answer set data per result set that the requester is capable of
1305
// receiveing.
1306
// this value must be able to be contained in a two byte signed number.
1307
// there is a minimum value of 0.
1308
// a zero indicates that the requester is not capable of receiving extra
1309
// query blocks of answer set data.
1310
// there is a SPCVAL of -1.
1311
// a value of -1 indicates that the requester is capable of receiving
1312
// the entire result set.
1313
//
1314
// preconditions:
1315
// sqlam must support this parameter on the command, method will not check.
1316
void buildMAXBLKEXT(int maxNumOfExtraBlocks) throws SqlException {
1317        if (maxNumOfExtraBlocks != 0) {
1318            writeScalar2Bytes(CodePoint.MAXBLKEXT, maxNumOfExtraBlocks);
1319        }
1320    }
1321
1322    // preconditions:
1323
void buildQRYROWSET(int fetchSize) throws SqlException {
1324        writeScalar4Bytes(CodePoint.QRYROWSET, fetchSize);
1325    }
1326
1327    // The Procedure Name.
1328
// The default value of PRCNAM is the procedure name value contained
1329
// within the section identified by the pkgnamcsn parameter. If that
1330
// value is null, then the prcnam parameter must be specified.
1331
// it has a max length of 255.
1332
// the prcnam is required on commands if the procedure name is
1333
// specified by a host variable.
1334
// the default value is the procedure name contained in the section
1335
// specified by the pkgnamcsn parameter on the EXCSQLSTT command.
1336
//
1337
// preconditions:
1338
// sqlam must support this parameter for the command, method will not check.
1339
// prcnam can not be null, SQLException will be thrown
1340
// prcnam can not be 0 length or > 255 length, SQLException will be thrown.
1341
private void buildPRCNAM(String JavaDoc prcnam) throws SqlException {
1342        if (prcnam == null) {
1343            throw new SqlException(netAgent_.logWriter_,
1344                new ClientMessageId(SQLState.NET_NULL_PROCEDURE_NAME));
1345        }
1346
1347        int prcnamLength = prcnam.length();
1348        if ((prcnamLength == 0) || (prcnamLength > 255)) {
1349            throw new SqlException(netAgent_.logWriter_,
1350                new ClientMessageId(SQLState.NET_PROCEDURE_NAME_LENGTH_OUT_OF_RANGE),
1351                new Integer JavaDoc(prcnamLength), new Integer JavaDoc(255));
1352        }
1353
1354        writeScalarString(CodePoint.PRCNAM, prcnam);
1355    }
1356
1357
1358    // Query Block Size specifies the query block size for the reply
1359
// data objects and the reply messages being returned from this command.
1360
// this is a 4 byte unsigned binary number.
1361
// the sqlam 6 min value is 512 and max value is 32767.
1362
// this value was increased in later sqlam levels.
1363
// until the code is ready to support larger query block sizes,
1364
// it will always use DssConstants.MAX_DSS_LEN which is 32767.
1365
//
1366
// preconditions:
1367
// sqlam must support this parameter for the command, method will not check.
1368
void buildQRYBLKSZ() throws SqlException {
1369        writeScalar4Bytes(CodePoint.QRYBLKSZ, DssConstants.MAX_DSS_LEN);
1370    }
1371
1372    // Maximum Result Set Count specifies a limit on the number of result sets
1373
// the requester is capable of receiving as reply data in response to an ECSQLSTT
1374
// command that invokes a stored procedure. If the stored procedure generates
1375
// more than MAXRSLCNT result sets, then the target system returns at most, the first
1376
// MAXRSLCNT of these result sets. The stored procedure defines the order
1377
// in which the target system returns result sets.
1378
// this is s two byte signed binary number.
1379
// it has a min value of 0 which indicates the requester is not capable
1380
// of receiving result sets as reply data in response to the command.
1381
// a special value, -1 (CodePoint.MAXRSLCNT_NOLIMIT = 0xffff), indicates the
1382
// requester is capable of receiving all result sets in response the EXCSQLSTT.
1383
//
1384
// preconditions:
1385
// sqlam must support this parameter for the command, method will not check.
1386
// the value must be in correct range (-1 to 32767), method will not check.
1387
private void buildMAXRSLCNT(int maxResultSetCount) throws SqlException {
1388        if (maxResultSetCount == 0) {
1389            return;
1390        }
1391        writeScalar2Bytes(CodePoint.MAXRSLCNT, maxResultSetCount);
1392    }
1393
1394    // RDB Commit Allowed specifies whether an RDB should allow the processing of any
1395
// commit or rollback operations that occure during execution of a statement.
1396
// True allow the processing of commits and rollbacks
1397
private void buildRDBCMTOK() throws SqlException {
1398        writeScalar1Byte(CodePoint.RDBCMTOK, CodePoint.TRUE);
1399    }
1400
1401    // Result Set Flags is a single byte where each bit it a boolean flag.
1402
// It specifies wheter the requester desires the server to return name,
1403
// label and comment information for the columns of result sets generated by the command.
1404
// The default is b'00000000'.
1405
// columnNamesRequired
1406
// false means the requester does not desire column names returned.
1407
// true means the requester desires column names returned.
1408
// columnLabelsRequired
1409
// false means the requester does not desire column labels returned.
1410
// true means the requester desires column labels returned.
1411
// columnCommentsRequired
1412
// false means the requester does not desire column comments returned.
1413
// true means the requester desired column comments returned.
1414
// cantProcessAnswerSetData
1415
// false means that for each result set, the requester expects the command
1416
// to return an FDOCA description of the answer set data and to possibly
1417
// return answer set data. the block containing the end of the description
1418
// may be completed if room exists with answer set data. additional blocks
1419
// of answer set data may also be chained to the block containing the end of the
1420
// FDOCA description. up to the maximum number of extra blocks of answer set data
1421
// per result set specified in the MAXBLKEXT parameter.
1422
// true means that for each result set, the requester expects the command to return
1423
// an FDOCA description of the answer set data but does not expect the command to
1424
// return any answer set data.
1425
// at SQLAM 7, new flags are supported which can be used to return
1426
// standard, extended, and light sqlda
1427
//
1428
// preconditions:
1429
// sqlam must support this parameter, method will not check.
1430
private void buildRSLSETFLG(int resultSetFlag) throws SqlException {
1431        writeScalar1Byte(CodePoint.RSLSETFLG, resultSetFlag);
1432    }
1433
1434    void buildQRYINSID(long qryinsid) throws SqlException {
1435        markLengthBytes(CodePoint.QRYINSID);
1436        writeLong(qryinsid);
1437        updateLengthBytes();
1438    }
1439
1440
1441    // Return SQL Descriptor Area controls whether to return
1442
// an SQL descriptor area that applies to the SQL statement this command
1443
// identifies. The target SQLAM obtains the SQL descriptor area by performing
1444
// an SQL DESCRIBE function on the statement after the statement has been
1445
// prepared.
1446
// The value TRUE, X'F1' (CodePoint.TRUE), indicates an SQLDA is returned
1447
// The value FALSE, X'F0' (CodePoint.FALSE), default, indicates an SQLDA is not returned.
1448
//
1449
// preconditions:
1450
// sqlam must support this parameter for the command, method will not check.
1451
private void buildRTNSQLDA() throws SqlException {
1452        writeScalar1Byte(CodePoint.RTNSQLDA, CodePoint.TRUE);
1453    }
1454
1455    // Type of SQL Descriptor Area.
1456
// This is a single byte signed number that specifies the type of sqlda to
1457
// return for the command.
1458
// below sqlam 7 there were two possible enumerated values for this parameter.
1459
// 0 (CodePoint.TYPSQLDA_STD_OUTPUT)- the default, indicates return the output sqlda.
1460
// 1 (CodePoint.TYPSQLDA_STD_INPUT) - indicates return the input sqlda.
1461
// the typsqlda was enhanced at sqlam 7 to support extened describe.
1462
// at sqlam 7 the following enumerated values are supported.
1463
// 0 (CodePoint.TYPSQLDA_STD_OUTPUT) - the default, standard output sqlda.
1464
// 1 (CodePoint.TYPSQLDA_STD_INPUT) - standard input sqlda.
1465
// 2 (CodePoint.TYPSQLDA_LIGHT_OUTPUT) - light output sqlda.
1466
// 3 (CodePoint.TYPSQLDA_LIGHT_INPUT) - light input sqlda.
1467
// 4 (CodePoint.TYPSQLDA_X_OUTPUT) - extended output sqlda.
1468
// 5 (CodePoint.TYPSQLDA_X_INPUT) - extended input sqlda.
1469
//
1470
// preconditions:
1471
// sqlam or prdid must support this, method will not check.
1472
// valid enumerated type must be passed to method, method will not check.
1473
private void buildTYPSQLDA(int typeSqlda) throws SqlException {
1474        // possibly inspect typeSqlda value and verify against sqlam level
1475
if (typeSqlda != CodePoint.TYPSQLDA_STD_OUTPUT) {
1476            writeScalar1Byte(CodePoint.TYPSQLDA, typeSqlda);
1477        }
1478    }
1479
1480    /**
1481     * Build QRYCLSIMP (Query Close Implicit). Query Close Implicit
1482     * controls whether the target server implicitly closes a
1483     * non-scrollable query upon end of data (SQLSTATE 02000).
1484     */

1485    private void buildQRYCLSIMP() {
1486        writeScalar1Byte(CodePoint.QRYCLSIMP, CodePoint.QRYCLSIMP_YES);
1487    }
1488
1489    // helper method to buildFDODTA to build the actual data length
1490
private void setFDODTALobLength(int[][] protocolTypesAndLengths, int i, long dataLength) throws SqlException {
1491        if (protocolTypesAndLengths[i][1] == 0x8002) {
1492            writeShort((short) dataLength);
1493        } else if (protocolTypesAndLengths[i][1] == 0x8004) {
1494            writeInt((int) dataLength); // 4 bytes to encode the length
1495
} else if (protocolTypesAndLengths[i][1] == 0x8006)// 6 bytes to encode the length
1496
{
1497            writeLong(dataLength);
1498        }
1499        //throw new SqlException (netAgent_.logWriter_, "0x8006 lob place holders not yet supported");
1500
else if (protocolTypesAndLengths[i][1] == 0x8008)// 8 bytes to encode the length
1501
{
1502            writeLong(dataLength);
1503        }
1504
1505        if (dataLength != 0) {
1506            if (extdtaPositions_ == null) {
1507                extdtaPositions_ = new java.util.ArrayList JavaDoc();
1508            }
1509            extdtaPositions_.add(new Integer JavaDoc(i));
1510        }
1511    }
1512
1513    private boolean checkSendQryrowset(int fetchSize,
1514                                       int resultSetType) {
1515        // if the cursor is forward_only, ignore the fetchSize and let the server return
1516
// as many rows as fit in the query block.
1517
// if the cursor is scrollable, send qryrowset if it is supported by the server
1518
boolean sendQryrowset = false;
1519        if (resultSetType != java.sql.ResultSet.TYPE_FORWARD_ONLY) {
1520            sendQryrowset = true;
1521        }
1522        return sendQryrowset;
1523    }
1524
1525    private int checkFetchsize(int fetchSize, int resultSetType) {
1526        // if fetchSize is not set for scrollable cursors, set it to the default fetchSize
1527
if (resultSetType != java.sql.ResultSet.TYPE_FORWARD_ONLY && fetchSize == 0) {
1528            fetchSize = org.apache.derby.client.am.Configuration.defaultFetchSize;
1529        }
1530        return fetchSize;
1531    }
1532
1533    private int calculateResultSetFlags() {
1534        return CodePoint.RSLSETFLG_EXTENDED_SQLDA;
1535    }
1536
1537    public void writeSetSpecialRegister(java.util.ArrayList JavaDoc sqlsttList) throws SqlException {
1538        Section section =
1539                netAgent_.sectionManager_.getDynamicSection(java.sql.ResultSet.HOLD_CURSORS_OVER_COMMIT);
1540
1541        buildEXCSQLSET(section);
1542
1543        // SQLSTT:
1544
for (int i = 0; i < sqlsttList.size(); i++) {
1545            buildSQLSTTcommandData((String JavaDoc) sqlsttList.get(i));
1546        }
1547    }
1548
1549    private int[][] allocateLidAndLengthsArray(ColumnMetaData parameterMetaData) {
1550        int numVars = parameterMetaData.columns_;
1551        int[][] lidAndLengths = parameterMetaData.protocolTypesCache_;
1552        if ((lidAndLengths) == null || (lidAndLengths.length != numVars)) {
1553            lidAndLengths = new int[numVars][2];
1554            parameterMetaData.protocolTypesCache_ = lidAndLengths;
1555        }
1556        return lidAndLengths;
1557    }
1558
1559    private void buildMddOverrides(java.util.ArrayList JavaDoc sdaOverrides) throws SqlException {
1560        byte[] mddBytes;
1561        for (int i = 0; i < sdaOverrides.size(); i++) {
1562            mddBytes = (byte[]) (sdaOverrides.get(i));
1563            writeBytes(mddBytes);
1564        }
1565    }
1566
1567    private int getNextOverrideLid() {
1568        return overrideLid_++;
1569    }
1570}
1571
1572
1573
Popular Tags