|
Restrictions
The following major capabilities are currently not supported:
- Reconnection
- UNICODE character sets
- quoted identifiers
- New Teradata V2R5.1 features:
- New Teradata V2R6.0 features:
- External stored procedure creation
- large response messages
- bulk SQL data operations
- minor PM/API enhancements
Support for most of these is planned for future releases.
Multi-threaded applications
should avoid sharing Connection objects across multiple threads
(i.e., multiple threads shouldn't access the same ResultSet at the same time.), with the exception
of one thread issuing a cancel() on another thread. Each Connection object encapsulates
an I/O object which handles most protocol details between the client and DBMS, and is shared
by the other standard classes (Statement, PreparedStatement, CallableStatement, DatabaseMetaData,
ResultSet, etc.). While this I/O
object acts as a mutex to keep multiple threads from disrupting protocol sequences, it is
still possible for multiple threads to disturb each other's view of pending result sets.
Both USING clauses and placeholder ('?') parameters are supported; however, they cannot be mixed in
the same statement. The exceptions are
- Only USING clauses should be used with utility sessions (FASTLOAD, MLOAD, EXPORT, MONITOR)
- Only placeholders should be used with CallableStatements (CALL()'s)
Placeholders will be treated as VARCHAR(16) during prepareStatement() or prepareCall(),
but will be instantiated with whatever type is supplied when parameters are bound by either
the setXXX(), or the tdrdxBindXXXArray() methods.
Unimplemented Methods
The following JDBC 2.0 standard methods will throw a NotImplemented exception;
most of these methods are unimplmented due to:
- unsupported data types (BLOBs, CLOBs, SQL ARRAY, etc.)
- bidirectional cursors required
- unsupported database capability (e.g., refreshing cursor rows from source table/view)
- rarely (never?) used functionality; low/no priority
Class |
Method |
LOW PRIORITY ISSUES |
PreparedStatement |
setCharacterStream() |
ResultSet |
getCharacterStream() |
PreparedStatement |
addBatch() |
UNSUPPORTED SQL DATA TYPES |
PreparedStatement |
setRef() |
PreparedStatement |
setBlob() |
PreparedStatement |
setClob() |
PreparedStatement |
setArray() |
ResultSet |
getRef() |
ResultSet |
getBlob() |
ResultSet |
getClob() |
ResultSet |
getArray() |
UNSUPPORTED DBMS FEATURE |
DatabaseMetaData |
getVersionColumns() |
DatabaseMetaData |
getBestRowIdentifier() |
ResultSet |
rowUpdated() |
ResultSet |
rowInserted() |
ResultSet |
rowDeleted() |
ResultSet |
refreshRow() |
REQUIRES BIDRIECTIONAL CURSOR SUPPORT |
ResultSet |
prev() |
OO DBMS ONLY |
Connection |
setTypeMap() |
DatabaseMetaData |
getUDTs() |
ResultSet |
getObject() |
ResultSetMetaData |
getColumnClassName() |
Driver Specific Extensions
The following methods have been provided to
- support summarized results
- simplify input/output of Teradata import/export file format records
- optimize performance for bulk operations
- support other convenient functionality
Class |
Method |
Description |
SUMMARIZED RESULT METHODS |
ResultSet |
boolean tdrdxIsSummaryRow() |
indicates whether the current result row is a summary row |
ResultSet |
int tdrdxGetSummaryRowNumber() |
returns the current summary row number; zero indicates a non-summary row |
ResultSetMetaData |
boolean tdrdxHasSummaryRows() |
indicates if the ResultSet has summary columns |
ResultSetMetaData |
int tdrdxGetAlignmentColumn(int column) |
returns the index of the non-summary column to which the specified summary column should be aligned (for display purposes) |
ResultSetMetaData |
boolean tdrdxIsSummaryColumn(int column) |
indicates if the specified column is a summary column |
ResultSetMetaData |
boolean tdrdxIsSummaryColumn(String columnname) |
indicates if the named column is a summary column |
ResultSetMetaData |
int tdrdxGetFirstSummaryColumn(int rownum) |
returns the index of the first summary column for the specified summary row number |
ResultSetMetaData |
int tdrdxGetSummaryColumnCount(int rownum) |
returns the number of summary columns in the specified summary row |
ResultSetMetaData |
int tdrdxGetSummaryRowCount() |
returns the number of summary rows defined by the ResultSet |
BULK TRANSFER (ARRAY BINDING) METHODS |
PreparedStatement |
void tdrdxBindByteArray(int parameterIndex, byte[] x) |
binds a byte array to the specified parameter |
PreparedStatement |
void tdrdxBindByteArray(int parameterIndex, Byte[] x) |
binds a Byte object array to the specified parameter |
PreparedStatement |
void tdrdxBindShortArray(int parameterIndex, short[] x) |
binds a short array to the specified parameter |
PreparedStatement |
void tdrdxBindShortArray(int parameterIndex, Short[] x) |
binds a Short object array to the specified parameter |
PreparedStatement |
void tdrdxBindIntArray(int parameterIndex, int[] x) |
binds a int array to the specified parameter |
PreparedStatement |
void tdrdxBindIntArray(int parameterIndex, Integer[] x) |
binds a Integer object array to the specified parameter |
PreparedStatement |
void tdrdxBindDoubleArray(int parameterIndex, double[] x) |
binds a double array to the specified parameter |
PreparedStatement |
void tdrdxBindDoubleArray(int parameterIndex, Double[] x) |
binds a Double object array to the specified parameter |
PreparedStatement |
void tdrdxBindBigDecimalArray(int parameterIndex, BigDecimal[] X) |
binds a BigDecimal object array to the specified parameter |
PreparedStatement |
void tdrdxBindStringArray(int parameterIndex, String[] X) |
binds a String object array to the specified parameter |
PreparedStatement |
void tdrdxBindDateArray(int parameterIndex, java.sql.Date[] X) |
binds a Date object array to the specified parameter |
PreparedStatement |
void tdrdxBindTimeArray(int parameterIndex, java.sql.Time[] X) |
binds an array of java.sql.Time object to the specified parameter |
PreparedStatement |
void tdrdxBindTimestampArray(int parameterIndex, java.sql.Timestamp[] X) |
binds an array of java.sql.Timestamp object to the specified parameter |
PreparedStatement |
void tdrdxBindBinaryArray(int parameterIndex, byte[][] X) |
binds an array of byte arrays to the specified parameter (for BINARY and VARBINARY , as well as raw tuple, input) |
ResultSet |
void tdrdxBindByteArray(int columnIndex, Byte[] x) |
binds a Byte object array to the specified column;
when the next() method is called, the array will be filled to either its capacity or the number of rows remaining in the I/O buffer |
ResultSet |
void tdrdxBindShortArray(int columnIndex, Short[] x) |
binds a Short object array to the specified column |
ResultSet |
void tdrdxBindIntArray(int columnIndex, Integer[] x) |
binds a Integer object array to the specified column |
ResultSet |
void tdrdxBindDoubleArray(int columnIndex, Double[] x) |
binds a Double object array to the specified column |
ResultSet |
void tdrdxBindDateArray(int columnIndex, java.sql.Date[] x) |
binds a Date object array to the specified column |
ResultSet |
void tdrdxBindBigDecimalArray(int columnIndex, BigDecimal[] X) |
binds a BigDecimal object array to the specified column |
ResultSet |
void tdrdxBindStringArray(int columnIndex, String[] X) |
binds a String object array to the specified column |
ResultSet |
void tdrdxBindBinaryArray(int columnIndex, byte[][] X) |
binds an array of byte arrays to the specified column |
ResultSet |
int tdrdxGetRowsFetched() |
returns the number of rows fetched into the bound arrays when array binding has been used |
MISCELLANEOUS CONVENIENCE METHODS |
Connection |
String tdrdxGetURL() |
Returns the URL used to create the Connection |
Connection |
String tdrdxGetUser() |
Returns the logon user string |
Connection |
String tdrdxGetPassword() |
Returns the logon password string |
Connection |
String tdrdxGetAccount() |
Returns the logon account string |
Connection |
String tdrdxGetPartition() |
Returns the logon partition string |
Connection |
int tdrdxGetLSN() |
returns the session LSN |
Connection |
String tdrdxGetServerVersion() |
returns the DBMS version string |
Connection |
int tdrdxGetSessionNo() |
returns the Connection's session number |
Connection |
void tdrdxDisableLogging() |
disables input/output parcel stream logging |
Connection |
void tdrdxEnableLogging() |
enables input/output parcel stream logging |
Connection |
short tdrdxGetHostID() |
returns the host id for the connection |
Driver |
String tdrdxHost() |
returns the logon hostname |
Driver |
int tdrdxPort() |
returns the logon port number |
Driver |
String tdrdxDatabase() |
returns the logon databasename |
Driver |
String tdrdxProperty(String Name) |
returns the specified property as parsed from the Connection URL |
ResultSet |
byte[] tdrdxGetRawRow() |
returns the current row as a single array of bytes; the first 2 bytes are the length of the row, and the last byte is a newline character (raw mode) |
ResultSet |
void tdrdxCopyMetaData(com.presicient.tdredux.ResultSetMetaData rsmd) |
establishes a reference to the specified ResultSetMetaData with the called ResultSet object (used only for EXPORT sessions!) |
ResultSet |
void tdrdxSetBooleanMap(int trueValue) |
establishes an Integer value to be interpretted as 'true' for ResultSet.getBoolean() |
ResultSet |
void tdrdxSetBooleanMap(String trueValue) |
establishes a String value to be interpretted as 'true' for ResultSet.getBoolean() |
ResultSetMetaData |
String tdrdxGetFormat(int column) |
returns the format descriptor as returned by the DBMS |
ResultSetMetaData |
boolean tdrdxConsolePrompt() |
(for Remote Console only) reports whether DBMS requires input (i.e., included a PROMPT parcel) |
ResultSetMetaData |
long tdrdxGetRowCount() throws SQLException |
returns the number of rows in the ResultSet (as returned by the SUCCESS or OK parcel) |
ResultSetMetaData |
String tdrdxGetActivity() throws SQLException |
returns the name of the ResultSet's activity type (as returned by the SUCCESS or OK parcel) |
Statement |
void tdrdxSetKeepResp(boolean t) |
causes requests issued to the DBMS to use the KEEPRESP parcel;
used for the control session of a FASTEXPORT application, or to keep a read-only cursor open across transaction boundaries. |
Statement |
void tdrdxSetSPLPrint(boolean enable) |
enables/disables the PRINT statements in stored procedures created with the Statement object |
Statement |
boolean tdrdxGetSPLPrint() |
reports current enable/disable state of PRINT statements in stored procedures created with the Statement object |
Statement |
void tdrdxSetSPLSave(boolean enable) |
enables/disables saving stored procedure text for procedures created with the Statement object |
Statement |
boolean tdrdxGetSPLSave() |
reports current enable/disable state of stored procedure text saving for the Statement object |
Statement |
void tdrdxSetProperty(String prop, String val) throws SQLException |
sets a property on a Statement; currently only "Formatted" is supported (see Formatted Results) |
Statement |
void tdrdxRemoveProperty(String prop) |
remove a property on a Statement |
Statement |
String tdrdxGetProperty(String prop) |
returns the current value of a property on a Statement |
Statement |
boolean tdrdxTestProperty(String prop) |
tests the current value of a property on a Statement to be any of "TRUE", "YES", or "1" (case-insensitive) |
Array Binding
At present, the JDBC 2.0 standard does not provide optimizations for bulk data movement.
(Note: the Batch Execution interface provides some support, however, the code pathlength
required to individually bind each parameter for each statement nullifies much
of the benefit of such an interface).
This ommission may create a serious performance
impediment for purely standards-compliant JDBC applications in terabyte datawarehouse
environments. To remedy the situation, I've added some array binding methods as
outlined above.
For bulk export via either a regular SQL SELECT statement, or a
set of EXPORT sessions, the application can create arrays of any of the primitive
types (as specified above) and bind them to the ResultSet object returned by either
PreparedStatement.execute() or Statement.executeQuery(). Note the following rules:
- all bound arrays must be the same length, or an exception will be raised.
- mixing array bound processing and non-array bound processing on the same
ResultSet object is likely to return unexpected results
- when using tdrdxBindBinaryArray(), a special columnIndex value of zero indicates
the application wants entire rows returned in Teradata import/export file format, i.e., raw binary
prefixed by a 2 byte length, and with a newline appended.
- the degenerate case of binding single element arrays is equivalent to the
single variable binding common to other Database access APIs (e.g., ODBC, Perl DBI).
An example:
// // export a complete table in raw mode // try { com.presicient.tdredux.PreparedStatement pstmt = (com.presicient.tdredux.PreparedStatement)conn.prepareQuery("SELECT * FROM mytable"); com.presicient.tdredux.ResultSet rs = (com.presicient.tdredux.ResultSet)pstmt.executeQuery(); byte rows[][] = new byte[100]; rs.tdrdxBindBinaryArray(0, rows); int rows_rcvd = 0; while (rs.next()) { rows_rcvd = rs.tdrdxGetRowsFetched(); // // proceed to write out the rows // for (int i = 0; i < rows_rcvd; i++) exportfile.write(rows[i]); } } catch (SQLException SQLE) {...}
For bulk import to the DBMS, arrays may be bound to parameters using the PreparedStatement
methods described above. At present, only SQL and FASTLOAD sessions can exploit this interface,
though a future release will provide support for repeated execution. Note the following:
- all bound arrays must be the same length, or an exception will be raised.
- mixing array bound processing and non-array bound processing on the same
PreparedStatement object is likely to cause unexpected results
- Similar to the bulk export operations, a parameterIndex of zero indicates an entire
parameter tuple is being bound, in which case only the tdrdxBindBinaryArray() is allowed
- the degenerate case of binding single element arrays is equivalent to the
single variable parameter binding common to other Database access APIs (e.g., ODBC, Perl DBI).
- for FASTLOAD sessions,
PreparedStatement.execute() will cause the bound array data to be
bundled into a single request message and sent to the DBMS. If the array size(s) exceed the maximum message
length, an SQLException is thrown indicating the array sizes must be reduced, and the data is not sent.
- for SQL sessions, each PreparedStatement.execute() or executeUpdate() call will use a single tuple
of data from the bound arrays, and advance an internal "current tuple" index (Eventually, this
behavior may be modified to iteratively execute() internally until all the parameter tuples are consumed).
An example:
// // import a complete table in raw mode // try { com.presicient.tdredux.PreparedStatement pstmt = conn.prepareStatement("INSERT INTO mytable VALUES(?, ?, ?, ?, ?"); byte rows[][] = new byte[100][]; pstmt.tdrdxBindBinaryArray(0, rows); while (// data remains to load ) { for (int i = 0; i < 100; i++) { int len = importfile.readunsignedShort(); rows[i] = importfile.read(len); importfile.skipBytes(1); // skip newline } // ...load data into the rows array... for (int i = 0; i < 100; i++) pstmt.executeUpdate(); } } catch (SQLException SQLE) {...}
Summarized SELECT ResultSets
A set of methods has been provided to support the OLAP functions available via
the SELECT...WITH... statement. When a ResultSet contains summary information, additional columns
are defined, along with a set of "summary row" indexes, corresponding to each WITH clause in theSELECT statement; as a convenience, summary row 0 is used to indicate the non-summary row
to all the relevant ResultSet and ResultSetMetaData methods.ResultSetMetaData.tdrdxHasSummaryRows() can be called to determine if a ResultSet
includes summary data.
An application determines that the current ResultSet row is a summary row by callingResultSet.tdrdxIsSummaryRow() . Since a SELECT can have multiple WITH clauses, the application callsResultSet.tdrdxGetSummaryRowNumber()
to determine which summary row is currently available; if not on
a summary row, zero is returned.ResultSetMetaData.tdrdxIsSummaryColumn(int column) orResultSetMetaData.tdrdxIsSummaryColumn(String columnname)
can be called to determine if a specified column is part of a summarized row; this can be useful for determining
when to stop reading column values if the ResultSet currently holds a non-summary row. An application
manipulates the summary data by:
- calling
ResultSet.tdrdxGetSummaryRowNumber() to determine the current summary row;
a return value of 0
indicates the non-summary row, but summary and non-summary rows can be processed in nearly the same way.
- calling
ResultSetMetaData.tdrdxGetFirstSummaryColumn(summary_row_number) to
determine the starting column index of the current summary row.
- calling
ResultSetMetaData.tdrdxGetSummaryColumnCount(summary_row_number) to
determine the number of columns in the current summary row.
- iteratively calling
ResultSetMetaData.tdrdxGetAlignmentColumn(column_number) for each column in the current summary
row to determine the index of the non-summary row
column with which the specified summary row column should be aligned; -1 is returned if the specified column
is a non-summary row column.
Refer to the example in the EXAMPLES section below for better illustration of
using the summary data ResultSet and ResultSetMetaData methods.
Formatted Results
As of release 1.40, TdRedux supports returning results in Teradata formatted form (ala BTEQ report), using
the FMREQUEST parcel instead of the usual REQUEST/INDICREQUEST parcel, to send the SQL request to the
database.
To enable a formatted ResultSet:
- Before executing a Statement/PreparedStatement/CallableStatement, set the "Formatted" statement
property via
stmt.tdrdxSetProperty("Formatted", "True");
(these values are case-insensitive, and the value may be any of
"True", "Yes", or "1")
- after execution, all fields must be retrieved using the ResultSet.getString() method.
- To disable formatted ResultSets, either call Statement.tdrdxRemoveProperty("Formatted"),
or Statement.tdrdxSetProperty("Formatted", "False") ( or any other String other than
"True", "Yes", or "1").
- Note that, once a formatted Statement object has been execute()'d, disabling the "Formatted"
property will have no effect until the next Statement execute(). Likewise, setting the "Formatted"
property will have no effect on a current ResultSet until the next execute()
- Formatted ResultSets are only supported on DBC/SQL partitions.
- The current state of the formatted property can be tested by
calling the boolean method Statement.tdrdxTestProperty("Formatted"), or by retrieving the current String
value of the property via Statement.tdrdxGetProperty("Formatted").
Note that formatted ResultSets report all fields as TYPE_VARCHAR in the ResultSetMetaData;
any attempt to retrieve a field using other than getString() will cause a SQLExceptionto be thrown.
Installation
Currently there is no formal install packaging. For Windows
systems, simply unZIP the ZIP package to a directory of your
choosing; for UNIX systems, gunzip/untar to a directory of your choosing.
Then add the TdRedux.jar file - including the complete directory path - to your
CLASSPATH environment variable or the "-classpath" argument on your "java" commandline.
E.g.,
CLASSPATH=$CLASSPATH:/usr/local/jars/TdRedux.jar;export CLASSPATH [ for UNIX ]
set CLASSPATH=%CLASSPATH%;C:\TdRedux\TdRedux.jar [ for Windows ]
Testing the Installation
The release package includes a test application, TdRdxTest, which runs through a battery of
tests, including
- ANSI vs. Teradata mode
- stored procedures (if the DBMS supports them)
- multiple open requests, including updatable cursors
- multithreaded FASTLOAD
- multithreaded MLOAD
- multithreaded FASTEXPORT
- large SQL (V2R5 only)
- MONITOR
Both source and class files are included;
building the application from the source is recommended to test your installation:
javac TdRdxTest.java FastloadThread.java MultiloadThread.java ExportThread.java
To run TdRdxTest you'll need a Teradata user account capable of CREATE'ing and DROP'ing
tables and stored procedures, executing INSERTs, DELETEs and SELECTs against them,
referencing system data dictionary views, as well as running
FASTLOADs, MULTILOADs, and FASTEXPORTs. Only a small amount of database space is required, a max of
10,000 rows (about 100 bytes each) is loaded by a max of 2 FASTLOAD sessions. An additional
userid is used to test the MONITOR API; this user needs all the various privileges
required to SET SESSION RATE, SET RESOURCE RATE, and MONITOR xxx. If this additional user
is omitted, then the MONITOR tests will be bypassed.
The actual commandline is:
java TdRdxTest <hostname> <general-user-id> <general-user-password> [<monitor-user-id> <monitor-user-password>]
E.g.,
java TdRdxTest dbc darnold sde356yu dbc dbc
This test will spew a lot of information, you may want to redirect output to a file to capture it in case
things don't behave as expected. Note that several of the tests will return errors (they're actually testing error handling).
In addition, a simple remote console application "console.java" is included which can be used
to test the remote console interface. Be advised that remote console requires the following
to be setup on the DBMS:
- a database named CONSOLE
- NULL MACRO's with the same name as the console applications to be run must be created in the
CONSOLE database
- EXECUTE privilege on the NULL MACRO's must be granted to users to allow them to run the associated
applications.
To run the console.java:
java console <hostname> <user-id> <password> <console-app-name>
E.g.,
java console dbc darnold sde356yu DBSCONTROL
Connection URL
The format of the URL used during connection is
jdbc:tdredux:host[:port][;option[;...]]
where
- host is the hostname or IP address of the DBMS. NOTE: As of release 1.30,
TdRedux supports the xxxCOPn random selection translation (e.g., dbc => dbccop1, dbccop2, etc.).
The algorithm used to resolve the hostname is as follows:
- If the hostname as given can be resolved, it will be used as is.
- If the hostname does not exist in TdRedux's internal hostname cache,
TdRedux will sequentially attempt to resolve the hostname with COP numbers
starting from 1, until the hostname fails to be resolved. If no COP numbers
match, an exception is thrown; otherwise, the hostname and its
maximum resolved host number is saved in an internal cache for
quick lookup for subsequent connections. Note that this process can induce
significant delays during the first connection attempt.
- If the hostname exists in the internal hostname cache, TdRedux
will randomly choose a COP number between 1 and the maximum number
from the cache, and append the "COPn" to the supplied hostname.
- If a modified hostname is used, and the connection attempt fails,
TdRedux will cycle through the range of COP numbers, retrying
the connection up to 3 times.
For small, single connection applications, using the
full hostname (e.g., dbccop1), or DNS bind for round-robin
selection, will avoid the initial connection delay.
- port is the TCP port to connect to. If not specified the default is 1025.
- options may be any of
user=name[;password=string][;account=string]]
specifies logon username, password and optional account string; this information may also
be supplied directly by the DriverManager.getConnection(Url, User, Password) method.
partition={ DBC/SQL | SQL | FASTLOAD | EXPORT | MONITOR }
specifies the session partition; default is DBC/SQL.
lsn=value
the integer LSN to use for the connection. If set to zero, an LSN is allocated; otherwise the session
is associated with the specified LSN. The default is no LSN processing.
sessmode={ ANSI | Teradata | DEFAULT }
specifies the session mode; if not given, or specified as DEFAULT, the target DBMS default is used. Note
that only DBC/SQL partitions that neither allocate, nor associate with, an LSN are permitted to
use ANSI mode.
debug[=logfile]
causes parcel stream traffic for the connection to be logged to the DriverManager logwriter.
- If a logfile is specfied, the DriverManager logWriter will be set to the specified filename.
- If no logfile is specified and the DriverManager does not currently have a valid logWriter, the
DriverManager is set to the file "tdredux.log" in the current working directory.
- SecurityExceptions may be thrown if the application does not have appropriate permissions.
NOTE: logging can be enabled and disabled internally via the tdrdxEnableLogging() and tdrdxDisableLogging()
Connection methods.
buffersize=integer
sets the default response buffer size, in kilobytes. The default is the maximum, i.e., 64;
however, some environments may wish to limit resource usage (e.g., application servers
for large user communities). Must be between 1 and 64, inclusive.
database=name
sets the default database when the session logs on. Default is user's default database.
query_timeout=seconds
sets the default query timeout to some number of seconds. Default is no timeout. Note thatStatement.setQueryTimeout() overrides this value for the statement it is applied to.
E.g.,
jdbc:tdredux:dbc;user=dbitst;password=dbitst;partition=FASTLOAD;lsn=23564;sessmode=TERADATA;debug=fltest.log;buffersize=16;database=mydb
Connection Properties
The various connection options listed above may be set using the alternateDriverManager.getConnection(String url, Properties info) interface.
In that case, the following (case sensitive) properties are supported in the Properties parameter:
- PORT - the TCP/IP port to use for the database server connection
- DBNAME - the name of the database to be set as the default
- user - the connection username
- password - the connection password
- account - the connection account string
- QUERY_TIMEOUT - the default query timeout
- MLJOBS - the number of jobs to be processed during a Multiload operation
- Partition - the session partition for the connection (e.g., "DBC/SQL", "EXPORT", etc.)
- LSN - the LSN to be assigned to the session; if zero, then causes an LSN to be allocated
- SESSMODE - the session mode, any of "ANSI", "TERADATA", or "DEFAULT"
- DEBUG - enables the diagnostic logging
- BUFFERSIZE - sets the initial response buffersize, in kilobytes
- metaData - sets the scope of information returned by DatabaseMetaData objects;
can be either full or restricted (the default). full
uses the base data dictionary views, e.g., DBC.TABLES, whereas restricted
uses the user-visible version of those views, e.g., DBC.TABLESX.
The complete description can be queried at runtime using the
Driver.getPropertyInfo() method.
SQLSTATE Values
SQLExceptions may be thrown due to any of
- network connection failure
- DBMS reporting errors or failures
- invalid parameter usage or method calls
- query timeout, or thread interruption during query processing
- calling an unimplemented method.
For errors, failures, and warnings reported by the DBMS, TdRedux uses the SQLSTATE
code mapping described in Appendix D of Teradata RDBMS SQL Reference Volume 6:
Data Manipulation Statements (V2R4.0); any DBMS error codes
not listed in that table return a SQLSTATE starting with "T", followed by the actual
DBMS error code. Internal driver errors
return a vendor code of -1, and use one of the following SQLSTATE values:
- S1000 - generic error
- S1009 - the parameters or method call sequences were not valid.
- S1C00 - the method is not implemented, or the requested operation is not supported
- S1T00 - the query processing has either timed out, or was interrupted by another thread
- 08001 - unable to connect to the database
- 08S01 - the network connection has failed.
- 42000 - invalid method call sequences.
Prerequisite Software
TdRedux requires the following prerequisite software:
NOTE:As of release 1.39, TdRedux no longer requires the
Jakarta ORO package to be separately downloaded and installed. A modified
version of the package is now included in the TdRedux JAR, per the terms
of the Apache License (a copy of the license is included in the TdRedux
bundle). However, the package name has been modified
in order to overcome issues with various application servers
(most notably, IBM WebSphere) which use functionally-limited or
antiquated versions of the ORO package, and thus cause irreparable classpath
conflicts with any separately installed version. Also note that
this change requires a change in the WebSphere JDBC Provider
template (also included in this bundle).
The following examples are taken from the TdRdxTest application which accompanies
the release package.
Examples
Typical Usage Example
Review the various tests contained in TdRdxTest.java.
Summary Rows Usage Example
try { rs = (com.presicient.tdredux.ResultSet)stmt.executeQuery( "select col11, col2, col9 from alltypetst with avg(col2), avg(col9) by col11 with sum(col2)"); rsmd = (com.presicient.tdredux.ResultSetMetaData)rs.getMetaData(); while (rs.next()) { int sumrow = rs.tdrdxGetSummaryRowNumber(); if (sumrow == 0) continue; int i = rsmd.tdrdxGetFirstSummaryColumn(sumrow); int colcnt = rsmd.tdrdxGetSummaryColumnCount(sumrow); for (int j = 0; j < colcnt; i++, j++) { System.out.println(rsmd.getColumnName(i) + "(" + rsmd.getColumnLabel(i) + ") align to " + rsmd.tdrdxGetAlignmentColumn(i) + ":"); switch (rsmd.getColumnType(i)) { case Types.INTEGER: System.out.println(rs.getInt(i)); break;
case Types.SMALLINT: System.out.println(rs.getShort(i)); break;
case Types.TINYINT: System.out.println(rs.getByte(i)); break;
case Types.DOUBLE: System.out.println(rs.getDouble(i)); break;
case Types.CHAR: System.out.println(rs.getString(i)); break;
case Types.VARCHAR: System.out.println(rs.getString(i)); break;
case Types.DECIMAL: System.out.println(rs.getBigDecimal(i)); break;
case Types.DATE: System.out.println(rs.getDate(i)); break;
default: System.out.println("Unknown type"); } } } } catch (java.sql.SQLException SqlEx) { System.out.println("SQLException: " + SqlEx.getMessage()); }
FASTLOAD Usage Example
Detailed instructions for using Fastload via TdRedux.
MLOAD Usage Example
Detailed instructions for using Multiload via TdRedux.
FASTEXPORT Usage Example
Detailed instructions for using Fastexport via TdRedux.
MONITOR Usage Example
Review the montest() method in TdRdxTest.java.
NOTE:Teradata® V2R4.1 and V2R5.0 appear to have issues with MONITOR SESSION
for a specific username and/or session number.
Remote Console Usage Example
Review the console.java application.
FYI: Remote Console is the interface used for various administrative
utilities, e.g., DBSCONTROL, GTWGLOBAL, SHOWLOCKS, etc.
Implementation Notes
METADATA
|
|
The remaining fields return the following values for the respective types:
TYPE_NAME |
DATA_TYPE |
PRECISION |
LITERAL_PREFIX |
LITERAL_SUFFIX |
CREATE_PARAMS |
FIXED_PREC_SCALE |
MAXIMUM_SCALE |
<!-- TYPE_NAME DATA_TYPE PRECISION LITERAL_PREFIX LITERAL_SUFFIX CREATE_PARAMS FIXED_PREC_SCALE MAXIMUM_SCALE ---->
BYTE |
java.sql.Types.BINARY |
64000 |
NULL |
NULL |
"maxlength" |
false |
0 |
BYTEINT |
java.sql.Types.TINYINT |
4 |
NULL |
NULL |
null |
false |
0 |
CHAR |
java.sql.Types.CHAR |
64000 |
' |
' |
"maxlength" |
false |
0 |
CHARACTER |
java.sql.Types.CHAR |
64000 |
' |
' |
"maxlength" |
false |
0 |
CHAR VARYING |
java.sql.Types.VARCHAR |
64000 |
' |
' |
"maxlength" |
false |
0 |
CHARACTER VARYING |
java.sql.Types.VARCHAR |
64000 |
' |
' |
"maxlength" |
false |
0 |
DATE |
java.sql.Types.DATE |
19 |
NULL |
NULL |
null |
false |
0 |
DECIMAL |
java.sql.Types.DECIMAL |
18 |
NULL |
NULL |
"precision, scale" |
true |
18 |
DEC |
java.sql.Types.DECIMAL |
18 |
NULL |
NULL |
"precision, scale" |
true |
18 |
DOUBLE PRECISION |
java.sql.Types.DOUBLE |
18 |
NULL |
NULL |
null |
false |
0 |
FLOAT |
java.sql.Types.DOUBLE |
18 |
NULL |
NULL |
null |
false |
0 |
INTEGER |
java.sql.Types.INTEGER |
10 |
NULL |
NULL |
null |
false |
0 |
INT |
java.sql.Types.INTEGER |
10 |
NULL |
NULL |
null |
false |
0 |
INTERVAL YEAR |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision" |
false |
0 |
INTERVAL YEAR TO MONTH |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision" |
false |
0 |
INTERVAL MONTH |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision" |
false |
0 |
INTERVAL DAY |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision" |
false |
0 |
INTERVAL DAY TO HOUR |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision" |
false |
0 |
INTERVAL DAY TO MINUTE |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision" |
false |
0 |
INTERVAL DAY TO SECOND |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision, fractional_seconds_precision" |
false |
0 |
INTERVAL HOUR |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision" |
false |
0 |
INTERVAL HOUR TO MINUTE |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision" |
false |
0 |
INTERVAL HOUR TO SECOND |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision, fractional_seconds_precision" |
false |
0 |
INTERVAL MINUTE |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision" |
false |
0 |
INTERVAL MINUTE TO SECOND |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"precision, fractional_seconds_precision" |
false |
0 |
INTERVAL SECOND |
java.sql.Types.OTHER |
4 |
NULL |
NULL |
"fractional_seconds_precision" |
false |
0 |
LONGVARCHAR |
java.sql.Types.VARCHAR |
64000 |
' |
' |
null |
false |
0 |
NUMERIC |
java.sql.Types.DECIMAL |
18 |
NULL |
NULL |
"precision, scale" |
true |
18 |
REAL |
java.sql.Types.DOUBLE |
18 |
NULL |
NULL |
null |
false |
0 |
SMALLINT |
java.sql.Types.SMALLINT |
6 |
NULL |
NULL |
null |
false |
0 |
TIME |
java.sql.Types.TIME |
6 |
NULL |
NULL |
"fractional_seconds_precision" |
false |
0 |
TIME WITH TIMEZONE |
java.sql.Types.TIME |
6 |
NULL |
NULL |
"fractional_seconds_precision" |
false |
0 |
TIMESTAMP |
java.sql.Types.TIMESTAMP |
6 |
NULL |
NULL |
"fractional_seconds_precision" |
false |
0 |
TIMESTAMP WITH TIMEZONE |
java.sql.Types.TIMESTAMP |
6 |
NULL |
NULL |
"fractional_seconds_precision" |
false |
0 |
VARCHAR |
java.sql.Types.VARCHAR |
64000 |
NULL |
NULL |
"maxlength" |
false |
0 |
VARBYTE |
java.sql.Types.VARBINARY |
64000 |
NULL |
NULL |
"maxlength" |
false |
0 | |
|
Some of these values may seem odd, but e.g., PRECISION has different meanings for different types. I've tried
to base the values on the appropriate sections of the Teradata SQL Data Types Manual.
Additionally, CallableStatement objects use DatabaseMetaData objects internally
to map stored procedure IN, OUT, and INOUT parameter positions to the input and output field
positions reported when a CALL statement is prepared. Therefore, the user calling
the stored procedure needs access to the associated metadata.
ANSI vs. TERADATA MODE
- A session will be set to ANSI mode under the following conditions:
- The connection is for a DBC/SQL session that does NOT allocate or associate with an LSN AND
- The DBMS defines ANSI as the default mode and the connection URL omits the sessmode option OR
- The connection URL includes the
";sessmode=ANSI" option
The ";sessmode=ANSI" URL option will be ignored for non-SQL sessions, or sessions which use an LSN.
- Remember that a statement failure does NOT terminate a transaction in ANSI mode.
TdRedux will raise SQLExceptions whenever it receives a failure or error indication from the
DBMS; the application may choose to rollback() immediately, or may continue to process
ResultSets (possibly receiving further SQLExceptions).
STORED PROCEDURES
UPDATABLE CURSORS
- Note that updatable cursors are only supported in ANSI mode, and are subject
to the same restrictions listed in the Teradata SQL Reference Manuals.
- Positioned operations require that AUTOCOMMIT be disabled.
- Explicit cursor SQL syntax (e.g., "SELECT...FROM... FOR CURSOR",
"UPDATE ... SET... WHERE CURRENT OF...") is not supported; instead, applications should
use the relevant JDBC 2.0 cursor functions:
- To create an updatable cursor, the
create/prepareStatement() method should be
called with the resultSetConcurrency argument set to ResultSet.CONCUR_UPDATABLE .
- Calling the
executeQuery() method will open the cursor.
- To apply a positioned update, use the
ResultSet.updateXXX() methods to set the
various fields of the current row, then call ResultSet.updateRow() to apply the updates
(Note that the application does not supply any SQL statement for the update).
- To apply a positioned delete, call
ResultSet.deleteRow() . After deleteRow() is
called, the current cursor row will be invalid until ResultSet.next() called.
- Rows may be inserted by moving to the "insert" row (
ResultSet.moveToInsertRow() ),
calling the various ResultSet.updateXXX() methods to populate the row, and then
calling ResultSet.insertRow() to apply the insert. The application can then return
to the current cursor row by calling ResultSet.moveToCurrentRow() .
- Updates, deletes, and inserts applied in this fashion are only visible after the
current transaction is committed.
An example:
try { java.sql.Statement cursor = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_UPDATABLE); java.sql.ResultSet cursorrs = cursor.executeQuery("SELECT * FROM alltypetest"); while (cursorrs.next()) { int curcol1 = cursorrs.getInt(1); if (curcol1%3 == 0) { cursorrs.updateShort(2, (short)0); cursorrs.updateString("col5", "dsgsfglkjty kjhtyejhyrjhtylkjrhtykerjhtykrjhtyklerjmiyt"); cursorrs.updateRow(); continue; } if (curcol1%4 == 0) { cursorrs.deleteRow(); continue; } if (curcol1%5 == 0) { cursorrs.moveToInsertRow(); cursorrs.updateInt("col1", curcol1 + 124000); cursorrs.updateShort("col2", (short)23); cursorrs.updateByte("col3", (byte)1); cursorrs.updateString(4, "wqeryyy"); cursorrs.updateFloat(6, (float)1.2345); // leave everything else NULL cursorrs.insertRow(); cursorrs.moveToCurrentRow(); } } conn.commit(); } catch (java.sql.SQLException SqlEx) { System.out.println("SQLException: " + SqlEx.getMessage()); }
USING getBoolean()
Teradata does not have a native boolean column type. As a convenience,
a driver-specific ResultSet methods tdrdxSetBooleanMap(String trueValue)
and tdrdxSetBooleanMap(int trueValue) are provided to
allow an application to define any int or String value to be interpretted
as 'true' when the returned column value equals any of the registered trueValues.
NULL column values are always returned as 'false', and
string-typed columns must match the case of the specified trueValue object.
Note that the boolean map applies only to the ResultSet object
on which it is called.
E.g., to register the values 'TRUE', 'T', and 'YES' as true for a given ResultSet:
com.presicient.tdredux.ResultSet rs = (com.presicient.tdredux)pstmt.executeQuery(); rs.tdrdxSetBooleanMap("TRUE"); rs.tdrdxSetBooleanMap("T"); rs.tdrdxSetBooleanMap("YES");
Notes on Date and Timestamp Types
- Using PreparedStatement.setDate() for a placeholder (as opposed to a USING clause parameter)
will result in the provided value being converted to a VARCHAR string of the form 'YYYY-MM-DD'
for transfer to the DBMS.
- Teradata currently has an issue with using placeholders that are compared with TIME or TIMESTAMP types
within predicate clauses which causes an error to be generated when the statement is prepared. As of
release 1.20, TdRedux attempts to suppress this error by
- silently discarding the ANSI Date/time error during prepareStatement()
- when the statement is executed, constructing a modified version of the
statement to explicitly cast placeholders bound to TIME or TIMESTAMP values
to their respective type (unless the placeholder is already explicitly
cast), and re-preparing it.
- assuming the modified version is successfully prepared, the modified
statement is then executed.
Note that this process only works in ANSI mode, or in Teradata mode with autocommit
set to true. In Teradata mode with autocommit turned off, the initial
failure of the prepareStatement will cause transaction rollback, which must be
reported to the application. To minimize any impacts to your applications,
you should explicitly cast any TIME or TIMESTAMP placeholders, e.g.,WHERE timestamp_column < ?(timestamp(0))... . Also note that
write-only placeholders (i.e., placeholders in the VALUES clause of an INSERT
or the SET clause of an UPDATE) do not appear to have this issue, and so do not
require the explicit cast.
- As of release 1.20, TdRedux now supports the escaped version of date, time,
and timestamp literals (
{d 'YYYY-MM-DD'}, {t 'HH:MM:SS'},
{ts 'YYYY-MM-SS HH:MM:SS.SSS'} ).
- As of release 1.20, TdRedux now provides support for the Calendarized
version of get/setDate, get/setTime, and get/setTimestamp; however, these
implementations should be considered experimental, and users are advised
to fully analyze their use.
- As of release 1.24, TdRedux provides array binding interfaces for the TIME
and TIMESTAMP type (tdrdxBindTimeArray(),tdrdxBindTimestampArray())
- TdRedux assumes INTEGERDATE format if a DATE parameter is specified
via a USING clause. Be sure to force your session to INTEGERDATE via
"SET SESSION DATEFORM=INTEGERDATE" if you intend to specify DATE parameters
via USING clauses. Note that fastload sessions will inherit their
DATEFORM from the associated control SQL session, so set the
DATEFORM on the control session before attempting to fastload with
a DATE parameter in the USING clause.
Using PooledConnections
- TdRedux will attempt to "clean up" Connections returned to a
ConnectionPool by
- closing any open statements
- rolling back any open transaction
- restoring AutoCommit to true
However, applications should explicitly close their Statement objects,
and either commit or rollback any open transactions prior to closing
a pooled connection.
- Various Teradata session commands (SET SESSION DATEFORM, SET SESSION
ACCOUNT, SET TIME ZONE, DATABASE, etc.) can leave a pooled connection in
an unknown operational mode. Applications should either
- never use those commands
- always restore the session state to a known, predefined state
TdRedux may provide the ability to block such commands in a future
release.
- While TdRedux can detect database restarts, and other "soft" network
failures, the ability to detect "hard" network failures (e.g., network
switch or router failures, or a hard restart of the database platform)
is only available on platforms which are running JVM 1.3 or greater, as
Java did not provide the ability to enable TCP/IP's KEEPALIVE capability
until JVM 1.3. If your network is subject to frequent hard failures,
and you are still running on JVM 1.2, you may want to consider upgrading
to JVM 1.3.
In addition, since Java's setKeepAlive() interface uses the
simple BSD form (i.e., either enable or disable KEEPALIVE, rather than
specify the actual KEEPALIVE intervals), the length of time required
to detect a network failure is dependent on the hosting platform's
default KEEPALIVE settings. You may need to tune those settings in
order for network failures to be detected in an acceptable amount of
time.
- releases of TdRedux prior to 1.10 allowed applications to reuse Statement
(and PreparedStatement and CallableStatement) objects after they had
been explcitly close()'d. In support of PooledConnections, this
JDBC non-conformance has been corrected. Unfortunately, if your
application had inadvertantly been reusing Statements after they had
been closed, your application may break when using this release.
MISCELLANEOUS
- As of release 1.20, TdRedux has been formally tested as a Java application on
Windows 2000, Mac OS X, Red Hat Linux 7.3, and Solaris 8.0.
Other users have reported success on RS6000/AIX, and OS/390 platforms.
- TdRedux uses only Java-independent data types; this appears to Teradata as a
Sun/HP/IBM/iMac type workstation.
- When exporting data from a TdRedux application, be aware that the data is also
in Java platform-independent format.
- The array binding interfaces should be considered deprecated as of release 1.20.
and may be removed in a future release, to be superceded by the standard Batch
execution interface.
- Be aware that the Statement.cancel() method may have no impact if the
DBMS has completed processing the statement, and that result sets may continue
to return some rows after the cancel() is issued. In addition, the cancel() may take
a significant time to complete, in the event the DBMS must rollback a significant
amount of work for the overall transaction.
- FASTEXPORT support has only been tested on simple queries (e.g., SELECT * FROM table).
- When a query times out (i.e., the period defined by Statement.setQueryTimeout() is exceeded),
it is automatically
cancel() 'ed, which may
take a significant time to complete depending on query complexity. In addition, in Teradata session
mode, the timeout will result in implicit transaction rollback.
- Applications load the driver by either:
- "Batches" have not been thoroughly tested, and are only supported for non-parameterized
statements (i.e., only Statement objects).
- Remember to explicitly close() ResultSet, Statement, PreparedStatement, and CallableStatement
objects when finished with them. Failure to do so may lead to apparent memory leaks as internal buffers
and contexts accumulate. TdRedux attempts to clean up internal buffers in certain
circumstances to avoid such memory leaks, but the application must ultimately
determine when resources are no longer needed.
- If a response message from the DBMS exceeds the connection URL
buffersize , TdRedux
will expand the buffersize as needed. Note that the process of buffer expansion can
severely impact performance due to the additional message interchanges required between client
and server. Be sure to tune your buffersize appropriately, or use the default (maximum) size.
- As of release 1.20, TdRedux has been tested against both the Sun JDBC Conformance
Test Suite 1.2.1, and the IBM WebSphere Self Test Conformance test suite.
CHANGE HISTORY
- Release 8.01
- added support for V2R5.1.1,5.1.2,6.0 logon encryption
- improved logonsource information
- Release 1.42
- fix for CallableStatement activity peek
- Release 1.41
- added V2R5.1 encrypted logon support
- Release 1.40
- added ResultSetMetaData.tdrdxGetRowCount() to return the number of rows returned by a ResultSet
- added ResultSetMetaData.tdrdxGetActivity() to return the name of the activity associated with a ResultSet
- added support for Statement properties, via Statement.tdrdxSetProperty(), Statement.tdrdxGetProperty(),
Statement.tdrdxRemoveProperty(), Statement.tdrdxTestProperty()
- added support for formatted ResultSets
- Release 1.39
- Jakarta ORO is now included in TdRedux
package, with modified package name, in
order to avoid classpath conflicts with
various application servers (most notably,
IBM WebSphere). Please review APACHE-ORO-LICENSE
file for Apache license conditions.
- Release 1.38
- fixed IO.closeResultSet() when closing due to
exceeding maxRows (caused bad query timeout value)
- Release 1.37
- fixed Statement.setMaxFieldSize() to support a param value of zero
(which translates to "max" size)
- Release 1.36
- added metaData connection property
- Release 1.35
- fix for ResultSet.getDate() when returned
integer date value is negative
- Release 1.34
- fixed Account string append in DataSource.getUrl()
- fix for TIME/TIMESTAMP placeholder bindings that don't match
default format
- Release 1.33
- fixed for multiplexing requests on single Connection
- Release 1.32
- fixed DataSource to properly set account string property
- modified Connection.getTypeMap() to return null rather than throw exception
- Release 1.31
- fixed MONITOR SESSION input parameter order (due to bug
in Teradata PM API docs)
- Release 1.30
- added support for COPn hostname resolution
- corrected the removal of strings and comments
- corrected USING clause parse for names that
include NOT keyword
- converted string/comment removal from ORO to native java
- V2R5 metadata updates
- V2R5 PM API updates
- V2R5 large SQL support
- optimize I/O object partition testing
- added com.presicient.tdredux.Connection.tdrdxGetHostID() function
- fixed potential deadlock in diagnostic dump processing
- Release 1.29
- added support for ERRORLIMIT for FASTLOAD,MLOAD
- Release 1.28
- added support for MLOAD
- V2R5.0 compatibility testing
- Release 1.27
- fix for CallableStatement with only OUT parameters
- Release 1.26
- fixed USING w/ TIMESTAMP w/ subsec precision < 3
- fixed PREPARE optimization for CREATE/REPLACE (SET | MULTISET | VOLATILE | GLOBAL TEMPORARY) TABLE
- removed logtable updates for fastexport test
- forced session dateform to integerdate for fastload test
- Release 1.25
- fixed USING w/ TIME/TIMESTAMP values
- Release 1.24
- improved error reporting when exception thrown during logon
- fixed PreparedStatement.tdrdxBindDateArray()
- added PreparedStatement.tdrdxBindTimeArray(),
PreparedStatement.tdrdxBindTimestampArray()
- added Remote Console support, inlc. ResultSetMetaData.tdrdxConsolePrompt()
- Release 1.23
- added global query timeout parameter to Connection URL
- Release 1.22
- closed timing window which caused ineffective cancel()
against Statement objects from another thread
- improved exception info thrown from query timeout
- Release 1.21
- added TRIM() to all CHAR columns returned from
data dictionary queries in DatabaseMetaData class
to improve interoperability w/ some 3rd party tools
(e.g., Database Pilot in JBuilder 8)
- fixed ANSI mode issue w/ reusing PreparedStatement
objects which previously raised non-fatal errors (e.g., truncation)
and left the assoc. ResultSet object(s) in an indeterminate state,
cause subsequent uses of the PreparedStatement to return
wo/ fetching results
- fixed network socket issue to capture all exceptions
caused by connection failure
- fixed occasional spurious IndexOutOfBounds exception
due to invalid request activity code returned from DBMS
- Release 1.20
Numerous changes to improve JDBC 2.0 conformance via the JDBC CTS:
- fixed set/getBigDecimal() to use proper scale factor
- fixed Statement and PreparedStatement handling of
execute()/getUpdateCount()/getMoreResults() to conform to std.
- fixed numerous Statement.setXXX capability methods to throw
exceptions whne invalid values were supplied (setFetchSize,
setFetchDirection, setMaxFieldSize, setMaxRows, setQueryTimeout)
- fixed PreparedStatement constructor to throw exception on
ANSI Date/Time error when inside transaction in Teradata mode
(In Teradata mode, failure on PREPARE causes transaction rollback; hence,
the fix to ignore the ANSI date/time error and re-prepare after
parameters are bound will not work in that specific case)
- fix DatabaseMetaData.getCatalogs to throw NotImplemented
- fixed the SQL used for DatabaseMetaData.getColumns() to avoid
Database numeric overflow error.
- fixed getResultSetType() to return correct value
- fixed PreparedStatement.clearParameters() to function properly;
After first created, or after clearParameters() is called, any
attempt to execute a statement with placeholders will throw an
exception if all placeholders have not been explicitly set.
- fixed DatabaseMetaData.supportsBatchUpdates() to return false
- added support for the date, time and timestamp literals escape
syntax ({d 'YYYY-MM-DD'}, {t 'HH:MM:SS'}, {ts 'YYYY-MM-DD HH:MM:SS.SSSS'})
- fixed getTime() to properly trim subseconds before conversion
- fixed getDriverVersion(), getURL(), nullsAreSupported(), and
supportsStoredProcedures() in DatabaseMetaData to return
correct values
- improved error reporting when error is returned during attempt
to connect (esp. "All virtual circuits are in use")
- fixed CHAR/VARCHAR to number conversions (eg, getInt() on a
CHAR column) to trim whitespace before conversion
- fixed character set problem with diagnostic parcel stream logging
- suppress exception when commit() is called while autoCommit=true
(WebSphere self-test requirement)
- suppress exception to Failure 3514 when rollback in Teradata mode
- Changes in TdRedux 1.19
in support of WebSphere 4.0:
- add support for " FOR UPDATE" cursor syntax
- suppress exception for setTransactionIsolation()
because WebSphere doesn't check DatabaseMetaData
for supported isolations
- add setSessmode() methods because WebSphere cheats when using the
DataSourceFactory; instead of using an empty Reference to determine
which properties are supported, is requires each method to have
a matching setXxxxx() method
- modified close/cancel of updatable cursors to issue CANCEL when
assoc. resultset is closed.
- added description, networkProtocol, roleName DataSource properties
- fix for setNull() for Types.DATE types
- fix misparse of DATE from string when fetching or inserting
data in ANSI session mode
- Calendarized set/getTimestamp/Time/Date() (experimental)
- get/setBinary/Ascii/CharacterStream() (experimental)
- Changes in TdRedux 1.18:
- updated PreparedStatement.setTimestamp(), PreparedStatement.setTime()
to support placeholders which have not been explicitly cast
as TIMESTAMP or TIME type. Note that this capability does incur
some add'l overhead during statement execution to properly
update the SQL sent to the DBMS based on the type and precision
of the value bound to the placeholder, so explicitly casting the
placeholders in your SQL for such fields is more optimal.
- fixed event notification to properly generate SQLException
error msg and SQLSTATE (previously were swapped)
- improved/clarified error msg returned by Connection.setTransactionIsolation()
when other than TRANSACTION_SERIALIZABLE was specified; msg is now.
- modified TdRdxConnectionPoolWrapper to properly report instances
when the underlying physical connection was closed (eg, by
a loss of network connection)
- fixed "database=" URL property in ANSI mode to properly
commit() upon completion of DATABASE stmt
- changed source of database version and release information
- Release 1.14
- fix protocol error on commit() before ResultSet.close()
- Release 1.13
- fix PreparedStatement.clearParameters() when no params defined
- fix PreparedStatement.setXXX() parameter binding when no params defined
- Release 1.12
- fix diagnostic logging
- fix early ResultSet.close()
- Release 1.10
- Support for javax.sql extensions:
- DataSource
- ConnectionPoolDataSource
- PooledConnection
- ConnectionEvent, ConnectionEventListener
- fix PreparedStatement.setDate()
- fix setTransactionIsolation()
- fix BUFFERSIZE=64 overflow in connection URL
- fix explicit port specification in connection URL
- Release 1.05
- fix DatabaseMetadata.storesUpperCaseIdentifiers(), storesMixedCaseIdentifiers()
- fix null pattern arguments in various DatabaseMetadata methods
- Release 1.03
- corrected Statement regression introduced in 1.02
- Release 1.02
- fix for PreparedStatement reuse
- optimize Statement.executeUpdate() to skip prepare step
- PM API updates for V2R4.1
- metadata updates for V2R4.1
- Release 1.01
- fix for DATE type conversion
- Release 1.00
- First general availability release.
- removed explicit DriverManager logWriter dependency
- fixed large response buffer expansion
TO DO
The following list includes features under consideration for future releases.
- performance tuning
- javadocs
- UNICODE
- Reconnection
- quoted identifiers
- JDBC 3.0 updates
- JDK 1.4 updates
- full escape clause syntax support
- Teradata V2R5.1 LOBs, UDF creation
Teradata® is a registered trademark of Teradata Corporation.
WebSphere® is a registered trademark of IBM Corporation. | |