Subject: SQL Anywhere Bug Fix Readme for Version 9.0.2, build 3924
From: <Uloženo v aplikaci Windows Internet Explorer 8>
Date: Sun, 10 Jan 2010 14:47:41 +0100

SQL Anywhere Bug Fix Readme for Version 9.0.2, build 3924

Choose a range of build numbers for which to display descriptions.
For example if you want to see what was fixed since the last EBF you applied then change 2451 to the build number of that last EBF.
Click Update Readme to make those changes take effect.
to Update Readme

Contents

Description of download types

Express Bug Fixes
Maintenance Release

9.0.2 Behavior Changes and Critical Bug fixes

Adaptive Server Anywhere - JDBC Client Library (1)
Adaptive Server Anywhere - ODBC Client Library (1)
Adaptive Server Anywhere - Other (3)
Adaptive Server Anywhere - Server (10)
MobiLink - QAnywhere server (1)
MobiLink - Streams (1)
MobiLink - Synchronization Server (1)
MobiLink - iAS Branded ODBC Drivers (1)

9.0.2 New Features

Adaptive Server Anywhere - ADO.Net Managed Provider (2)
Adaptive Server Anywhere - JDBC Client Library (3)
Adaptive Server Anywhere - OLEDB Client Library (1)
Adaptive Server Anywhere - Server (26)
Adaptive Server Anywhere - Utilities (6)
MobiLink - QAnywhere client (3)
MobiLink - QAnywhere server (1)
MobiLink - SA Client (2)
MobiLink - Synchronization Server (3)
MobiLink - Utilities (3)
MobiLink - scripts (1)
UltraLite - HotSync Conduit (1)
UltraLite - Runtime Libraries (2)
UltraLite - UltraLite Engine (1)
UltraLite - UltraLite for M-Business Anywhere (3)
UltraLite - Utilities (2)

9.0.2 Bug fixes

Adaptive Server Anywhere - ADO.Net Managed Provider (65)
Adaptive Server Anywhere - DBLIB Client Library (25)
Adaptive Server Anywhere - JDBC Client Library (61)
Adaptive Server Anywhere - ODBC Client Library (42)
Adaptive Server Anywhere - OLEDB Client Library (72)
Adaptive Server Anywhere - Other (37)
Adaptive Server Anywhere - SNMP Extension Agent (2)
Adaptive Server Anywhere - Server (918)
Adaptive Server Anywhere - Sybase Central Plug-in (61)
Adaptive Server Anywhere - Utilities (173)
MobiLink - Charset Conversion (UNILIB) (1)
MobiLink - Java Plugin for Sybase Central (4)
MobiLink - Monitor (2)
MobiLink - QAnywhere client (82)
MobiLink - QAnywhere server (88)
MobiLink - SA Client (48)
MobiLink - Sample (1)
MobiLink - Streams (9)
MobiLink - Synchronization Server (43)
MobiLink - Utilities (31)
MobiLink - iAS Branded ODBC Drivers (11)
MobiLink - scripts (4)
SQL Remote for Adaptive Server Anywhere - Configuration Scripts (1)
SQL Remote for Adaptive Server Anywhere - Extraction Utility for Adaptive Server Anywhere (1)
SQL Remote for Adaptive Server Anywhere - File Messaging for Adaptive Server Anywhere (2)
SQL Remote for Adaptive Server Anywhere - Mapi Messaging for Adaptive Server Anywhere (1)
SQL Remote for Adaptive Server Anywhere - SQL Remote Message Agent (11)
SQL Remote for Adaptive Server Anywhere - Smtp Messaging for Adaptive Server Anywhere (1)
UltraLite - Analyser Java Classes (5)
UltraLite - Code Generator (1)
UltraLite - CodeWarrior plugin (1)
UltraLite - HotSync Conduit (1)
UltraLite - MobiLink Server (1)
UltraLite - MobileBuilder plugin (1)
UltraLite - Native UltraLite for Java (3)
UltraLite - Runtime Libraries (61)
UltraLite - SQL Preprocessor (1)
UltraLite - UltraLite Engine (12)
UltraLite - UltraLite Schema Painter (7)
UltraLite - UltraLite for AppForge MobileVB (4)
UltraLite - UltraLite for M-Business Anywhere (14)
UltraLite - UltraLite for eMbedded Visual Basic (3)
UltraLite - UltraLite.NET (17)
UltraLite - Utilities (26)

Some useful links

iAnywhere.com Support Page - http://www.ianywhere.com/support/support.html
EBF downloads page - http://downloads.sybase.com
SQL Anywhere newsgroups - http://www.ianywhere.com/support/newsgroups.html
SQL Anywhere Main Page (links to evaluation software, tech support, whitepapers, etc) - http://www.ianywhere.com/products/sql_anywhere.html
SQL Anywhere supported platform matrix - http://www.ianywhere.com/products/supported_platforms.html

Description of download types

Express Bug Fixes

A subset of the software with one or more bug fixes. The bug fixes are
listed below. A Bug Fix update may only be applied to installed software
with the same version number.
Moderate testing has been performed on the software, but full testing has not
been performed. Customers are encouraged to verify the suitability of the software
before releasing it into a production environment.

Maintenance Release

A complete set of software that upgrades installed software from an older
version with the same major version number (version number format is
major.minor.patch). Bug fixes and other changes are listed in the "readme"
file for the upgrade.

For answers to commonly asked questions please use the following URL:
Frequently asked Questions

9.0.2 Behavior Changes and Critical Bug fixes

If any of these bug fixes apply to your installation, iAnywhere strongly recommends
that you install this fix. Specific testing of behavior changes is recommended.

Adaptive Server Anywhere - JDBC Client Library

================(Build #3441 - Engineering Case #454449)================

When an application uses the iAnywhere JDBC driver, the URL that the application
passes to the driver begins with the header "jdbc:odbc:". Unfortunately,
this URL header conflicts with the URL header that the Sun JDBC-ODBC bridge
accepts. This problem is most noticible if the application uses JDK 1.6.
To avoid this conflict, the iAnywhere JDBC driver now accepts the header
"jdbc:ianywhere:" in addition to "jdbc:odbc:". Application developers are
encouraged to use the new "jdbc:ianywhere:" header instead of the old "jdbc:odbc:"
header when building the URL that will be passed in to the iAnywhere JDBC
driver.

Adaptive Server Anywhere - ODBC Client Library

================(Build #3786 - Engineering Case #558108)================

Calling the function SQLGetTypeInfo() would have returned an incorrect AUTO_UNIQUE_VALUE
column value in the result set for non-numeric types. The value return would
have been 0, but according to the ODBC specification a NULL should have been
returned.

ODBC specificatrion for AUTO_UNIQUE_VALUE :
Whether the data type is autoincrementing:
SQL_TRUE if the data type is autoincrementing.
SQL_FALSE if the data type is not autoincrementing.
NULL is returned if the attribute is not applicable to the data type or
the data type is not numeric.

The behaviour has been corrected to follow the ODBC specification.

Adaptive Server Anywhere - Other

================(Build #3582 - Engineering Case #485275)================

The changes for Engineering case 482379 had the potential to truncate the
.NET 2.0 machine.config file. This could have happened if the 9.0.2 EBFs
for builds 3575, 3576 or 3581 were applied. Without this file, problems running
.NET applications, or using Visual Studio 2005 may occur. The problem has
now been corrected, and the Setup will try to determine if the machine.config
file has been corrupted, and display an error dialog if corruption is found.
If the new Setup reports that the file may be corrupt, action must be taken
to restore the file to a working state.

The file machine.config is an XML-formatted file, and is usually found in
c:\Windows\Microsoft.NET\Framework\v2.0.50727\config. Data providers are
listed in the <DbProviderFactories> sub-section of the <system.data> section
of the file. A subset of the file is shown below:

<configuration>

(configuration for other providers)

<system.data>
<DbProviderFactories>
<add name="Odbc Data Provider" invariant="System.Data.Odbc" description=".Net
Framework Data Provider for Odbc" type="System.Data.Odbc.OdbcFactory, System.Data,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

(configuration for other providers)

<add name="SQL Anywhere Data Provider" invariant="iAnywhere.Data.AsaClient"
description=".Net Framework Data Provider for SQL Anywhere" type="iAnywhere.Data.AsaClient.AsaFactory,
iAnywhere.Data.AsaClient, Version=9.0.2.3585, Culture=neutral, PublicKeyToken=f222fc4333e0d400"
/>
</DbProviderFactories>
</system.data>

(configuration for other providers)

</configuration>

The bug was that the install truncated the file at the point where the "SQL
Anywhere Data Provider" entry should have been added. This left the XML file
in an inconsistent state, due to the <DbProviderFactories>, <system.data>
and <configuration> sections not being closed. As well, entries that occurred
after the <DbProviderFactories> section were missing entirely. Any data
providers from other database vendors that were listed in the file after
the SQL Anywhere provider would also have been deleted.

To fix the problem, the file needs to be restored manually. Ideally, if
there is a backup of this file, it can be restored from the backup.

If that is not the case, the file will need to be manually edited to add
the provider line above and close the <DbProviderFactories>, <system.data>
and <configuration> sections. There is a file called machine.config.default
in the same directory as the machine.config. This file contains the default
settings for the machine.config, and can be used to restore the missing sections.
Any installs for other products that modified the machine.config the file
will also need to be rerun.

================(Build #3451 - Engineering Case #456564)================

On Windows Vista, services are not allowed to interact with the desktop.
Even if "allow interaction with desktop" is enabled, the server will not
attempt to do so.

================(Build #3439 - Engineering Case #455977)================

License information for the Network Server (dbsrv9.exe), Personal Server
(dbeng9.exe), Runtime Server (rteng9.exe) and Mobilink server (dbmlsrv9.exe)
are now contained in a separate .LIC file, rather than inside the executable
file. The license file is stored in the same directory as the executable
file. When dblic.exe is run, specify the name of the .LIC file instead of
the .exe file that needs to be licensed.

Note, when deploying any of these executables, the .LIC file will need to
be deployed as well

Adaptive Server Anywhere - Server

================(Build #3881 - Engineering Case #587028)================

The fix for Engineering case 581991 could have inadvertently turned on the
feature for a new database architecture even if it was not requested. This
has now been fixed. This could only have affected a database that was created
using 9.0.2 build 3867-3880 or 10.0.1 build 3930-3948. The query:
select * from sa_db_properties() where propname = 'HasTornWriteFix';
can be used to determine if the setting is ON or OFF. Turning the setting
OFF requires a rebuild of the database using an engine with this fix.

================(Build #3867 - Engineering Case #581991)================

In some cases it was possible for a database to become corrupted if the last
write to disk was only partial completed, due to a power loss before the
write to disk finished. This would have been extremely rare on a desktop
machine or laptop using a conventional disk, but would have been much more
likely with flash memory on handheld devices. In either case, corruption
was more likely if the database file was encrypted. In order to prevent this
corruption it is necessary to change the physical format of the database
file. With this change in file format, the database should automatically
recover from a partial write.

WARNING: When choosing to use a database with the new file format described
below you give up the ability of being able to use older software that is
not aware of the file format change. Therefore, once you create this database
you will not be able to start an old server with such a database file. Any
attempt to start the server with a build prior to this fix will generate
an error "server must be upgraded to start 'database' ( capability 37 missing)".
Syntax has been added to dbinit and the create database statement to allow
for the creation of databases with this new file format. In order to create
a database with this new format, use either:
- dbinit -xw mydb.db // -xw (creates a database with the new file format)
- CREATE DATABASE mydb.db CAPABILITY 'TORNWRITEFIX' ...

Syntax has also been added to dbunload to rebuild databases so that the
new database will be created with the new file format. In order to rebuild
a database with the old format to one with the new format use:
- dbunload.exe -c 'your connection string to your old db' -xw -ar // this
will replace your old database with a new one
- dbunload.exe -c 'your connection string to your old db' -xw -an new.db
// this will create new.db in the new file format while maintaining your
old database in the old file format

NOTE: make sure to have a backup of your database file before attempting
this. Also if your database is strongly encrypted then you'll need to provide
the encryption key for both the old database and the new database file using
the -ek command line parameter.

In order to upgrade a database with this new file format from version 9
to version 10 or version 11 you'll need to use 10.0.1 3930 or greater or
11.0.1 2278 or greater.

================(Build #3612 - Engineering Case #489605)================

In case-sensitive databases, dbspace names were also case-sensitive. DDL
statements referring to the dbspace names were required to specify the dbspace
names exactly as they appeared in the catalog. This has been fixed.

Note, it is possible that a database could contain two dbspaces with the
same name in different cases. This change would prevent these dbspaces from
being differentiated. This would be a problem when migrating to versions
10 or later as well.

================(Build #3463 - Engineering Case #454858)================

The server could have crashed when performing a LOAD TABLE into a temporary
table. Certain requirements are now properly enforced when loading into temporary
tables. A commit is now performed prior to the load, and after a successful
load, for any table except a LOCAL TEMPORARY TABLE with ON COMMIT DELETE
ROWS. A partial LOAD TABLE into a temporary table due to a failure will
result in the entire contents of the table being removed, including rows
in the temporary table which were present prior to the load. Previously,
a partial load would have resulted in the rows loaded to that point being
left in the table, while others were missing. Since rows are removed from
a temporary table on error, it is now also required that there be no foreign
rows already referencing rows in the table being loaded. As a result, loading
into a temporary table already containing rows with foreign key references
from another table will result in an error. In version 10.0, the use of LOAD
TABLE into a global temporary table, that was created with the SHARE BY ALL
clause, will cause an exclusive lock on the table. This will prevent concurrent
loads into the table.

================(Build #3457 - Engineering Case #461144)================

The server will no longer start if a license file cannot be found. The error
message "License file could not be found" will now be displayed.

Rather than looking for fixed filenames "dbeng10.lic", "dbsrv10.lic", etc,
the server now looks for a ".lic" file that has the same base filename as
the executable that is being run. For example, if dbeng10.exe has been renamed
to be "mydb.exe", the server will now look for the file "mydb.lic".

================(Build #3450 - Engineering Case #452911)================

A database that had gone down dirty, could have become corrupted during recovery.
This would only have occurred if the database contained a very large checkpoint
log (greater than 32512 pages for a database with 4Kb pages), which means
that at least this many pages would have been altered in the database file
since the last checkpoint. The symptoms of the corruption could be many
different assertions including assertion 202101 - "Invalid bitmap links on
page {page_num}". Also, validation errors could have resulted due to this
corruption as well. This problem is now fixed.

It's possible that this corruption could be prevented by increasing the
server checkpoint urgency. The more often checkpoints occur the less likely
one is to get a database with a very large checkpoint log.

As always it is important to maintain a tested backup and recovery strategy.
Having a valid backup database in this case allows one to apply the current
transaction log to that backup to recover all transactions.

================(Build #3449 - Engineering Case #455926)================

An attempt to create a base table with the same name and owner as that of
an existing local temporary table is permitted by the server. However, the
newly created table could not have been accessed until the local temporary
table with the same name and owner was dropped from the current scope. The
server will now disallow the creation of a base table in this scenario.

================(Build #3319 - Engineering Case #432545)================

A problem was introduced with the changes for Engineering case 419782, such
that if a query contained two subselects S1 and S2, and subselect S2 referred
to S1 using an alias, and S1 does not appear in the select list returned
with S2, then S2 may have returned incorrect results. This has been corrected.
The most common failure mode would be to return the same value for multiple
rows (not re-evaluating as needed).

The following query demonstrates this problem:

SELECT row_num,
SS2
FROM
(
SELECT R.row_num,
( SELECT R.row_num FROM sys.dummy D1 ) AS SS1,
( SELECT SS1 + (100*row_num) from sys.dummy D2 ) AS SS2

FROM dbo.rowgenerator R
) DT

The problem can be worked around by including both subselects in the result
set of the query.

================(Build #3119 - Engineering Case #389039)================

The server could have failed with a "dynamic memory exhausted" error if AWE
was enabled (ie. -cw command line option). This problem has been corrected.
The only work around is to disable AWE.

================(Build #2529 - Engineering Case #370998)================

The problem addressed by changes for Engineering Case 323973, was reintroduced
by the changes for Case 369727.

A server crash at an inopportune moment could have resulted in a corrupt
database. This was more likely to have occurred with 9.x servers, and with
8.x servers running 8.x databases. It was unlikely to have occurred with
8.x and earlier servers when running against 7.x or earlier databases.

This has now been fixed.

MobiLink - QAnywhere server

================(Build #3420 - Engineering Case #452638)================

QAnywhere makes extensive use of the JRE, so the MobiLink server when run
with the QAnywhere messaging option (-- m), may have encountered instabilities
in the JRE under heavy load and low memory conditions. To address this the
JRE has now been updated. This update contains fixes that significantly improve
the stability of the JRE when running under these conditions.

MobiLink - Streams

================(Build #3390 - Engineering Case #444897)================

The changes for Engineering case 426484 would have caused the server to silently
ignore client requests if clients were upgraded to a version with the change,
but the server was not. This has been fixed so that newer clients with this
change can synchronize with servers that have not yet been upgraded to a
version with the change. Thus to solve this problem, the server must be upgraded
to build 3342 or later, or the client must be upgraded to build 3390 or later.

MobiLink - Synchronization Server

================(Build #3462 - Engineering Case #462471)================

The MobiLink server will no longer start if a license file cannot be found.
The error message "License file could not be found" will be displayed.

Rather than looking for fixed filenames, the MobiLink server now looks for
a ".lic" file that has the same base filename as the executable that is being
run.

MobiLink - iAS Branded ODBC Drivers

================(Build #3508 - Engineering Case #472239)================

Branded, third-party ODBC drivers are no longer shipped with MobiLink. Version
10.0.0 and up already do not ship with branded, third-party ODBC drivers.
The drivers that are no longer shipping are:
iAnywhere Solutions 9 - DB2 Wire Protocol
iAnywhere Solutions 9 - Oracle Wire Protocol
iAnywhere Solutions 9 - Sybase ASE

These drivers are now deprecated, although they will continue to be tested
to make sure MobiLink and other components still work with them. If a problem
is encountered with one of these drivers that cannot be worked around, a
fix cannot be made, the options are to directly use a recommended third-party
ODBC driver (see http://www.sybase.com/detail?id=1011880), or to move to
version 10.0.1 or higher. The aforementioned link will be updated, recommending:

- An IBM ODBC driver for DB2
- Our own (iAnywhere Solutions 9 - Oracle) ODBC driver for Oracle (now shipping
with 9.0.2 as of this change)
- A DataDirect ODBC driver for ASE

9.0.2 New Features

This section contains a description of new features added since the release
of version 9.0.2.

Adaptive Server Anywhere - ADO.Net Managed Provider

================(Build #3392 - Engineering Case #445710)================

The default value of SACommand.UpdateRowSource has been changed from UpdateRowSource.Both,
to UpdateRowSource.OutputParameters. This change can improve the performance
of SADataAdapter.Update. If the value of SACommand.UpdateRowSource is UpdateRowSource.OutputParameters,
the provider will call ExecuteNonQuery to update rows. If the value is UpdateRowSource.Both,
ExecuteDataReader is called to update rows.

================(Build #3221 - Engineering Case #410259)================

Microsoft has recently released Visual Studio 2005, which includes version
2.0 of the .NET Framework and the .NET Compact Framework. A new driver for
SQL Anywhere support of ADO.NET 2.0 is now available, which consists of the
following new files:

<install dir>\win32\VS8\iAnywhere.Data.AsaClient.dll
<install dir>\win32\VS8\iAnywhere.Data.AsaClient.dll.config
<install dir>\win32\VS8\policy.9.0.iAnywhere.Data.AsaClient.dll

<install dir>\ce\VS8\iAnywhere.Data.AsaClient.dll
<install dir>\ce\VS8\iAnywhere.Data.AsaClient.gac

The ADO.NET reference manual has also been updated to describe the new features
of ADO.NET 2.0. The new documentation files are:

<install dir>\docs\dbpaen9.chm
<install dir>\docs\pdf_en\dbpaen9.pdf

Compact Framework version 2.0 programs cannot be built with assemblies built
with version 1.0. The following new files are versions of the existing .NET
assemblies built with Compact Framework version 2.0.

<install dir>\ce\VS8\iAnywhere.QAnywhere.Client.dll
<install dir>\ce\VS8\iAnywhere.QAnywhere.Client.gac
<install dir>\ce\VS8\iAnywhere.QAnywhere.Client.xml

<install dir>\UltraLite\UltraLite.NET\ce\VS8\iAnywhere.Data.UltraLite.dll
<install dir>\UltraLite\UltraLite.NET\ce\VS8\iAnywhere.Data.UltraLite.xml
<install dir>\UltraLite\UltraLite.NET\ce\VS8\iAnywhere.UltraLite.dll
<install dir>\UltraLite\UltraLite.NET\ce\VS8\iAnywhere.UltraLite.xml

Adaptive Server Anywhere - JDBC Client Library

================(Build #3498 - Engineering Case #468630)================

The iAnywhere JDBC Driver currently supports the ResultSet.getBlob() method
even though this method is optional in the JDBC specification. However, the
ResultSet.getBlob().getBinaryStream() method (which is also optional in the
specification) was not supported. Some applications insist that Blob.getBinaryStream()
be supported if getBlob() is supported. As a result, the iAnywhere JDBC Driver
now supports ResultSet.getBlob().getBinaryStream().

================(Build #3190 - Engineering Case #403934)================

The iAnywhere JDBC driver has been enhanced so that it supports the Sun JDBCODBC
subprotocol for the URL definition in addition to the current definition.
As a result, applications can now use URLs of the form:

jdbc:odbc:<data-source-name>[;<attribute-name>=<attribute-value>]*

================(Build #3025 - Engineering Case #379662)================

The iAnywhere JDBC Driver has been enhanced to support the PreparedStatement.addBatch()
method. This method is useful for performing batched (or wide) inserts.

To use this method:
1) An INSERT statement should be prepared using one of the Connection.prepareStatement()
methods,
2) The parameters for the prepared insert statement should be set and batched
as follows:

for( ... ) // for loop to batch n sets of parameters
{
stmt.set?( 1, ? ); // where stmt is the prepared insert statement from
step 1
stmt.set?( 2, ? );
...
stmt.set?(m , ? ); // note that there are m parameters in the statement
stmt.addBatch(); // adds the set or parameters to the batch and moves
to the next row of parameters
}
3) The batch should then be executed using the PreparedStatement.executeUpdate()
method

It should be noted that only the PreparedStatement.addBatch() method is
supported and that the PreparedStatement.executeUpdate() method needs to
be called to execute the batch. None of batch methods for the Statement object
(i.e. Statement.addBatch(), Statement.clearBatch(), Statement.executeBatch()
) are supported since these methods are completely optional and not very
useful. For such static batches, it is best to call Statement.execute() or
Statement.executeQuery() on a single string with the batched statements wrapped
inside a BEGIN...END.

NOTE 1: BLOB parameters are not supported in batches

NOTE 2: String/Binary parameters are supported but the size of the string/binary
parameter is an issue. By default the string/binary parameter is restricted
to 255 characters or 510 bytes. The reason for the restriction is due to
the underlying ODBC protocol and will not be discussed here. For futher information,
it is best to view the documentation on passing arrays of parameters in ODBC.
If, however, an application needs to pass larger string or binary parameters
within a batch, then an additional method has been provided to increase the
size of the string/binary parameter. Note that this method must be called
PRIOR to the first addBatch() call. If the method is called after the first
addBatch() call, then the new size setting will be ignored. Hence, when calling
this extra method to change the size of a string/binary parameter, the application
needs to know ahead of time what the maximum string or binary value for that
parameter will be.

To use this extra method, you must modify the "code" above as follows:

// need to cast stmt to an IPreparedStatment object in order to change
the size of string/binary parameters
ianywhere.ml.jdbcodbc.IPreparedStatement _stmt = (ianywhere.ml.jdbcodbc.IPreparedStatement)stmt;

// now change the size of string parameter 4 from the default 255 characters
to 300 characters
_stmt.setBatchStringSize( 4, 300 ); // note string parameters are in "characters"

// change the size of binary parameter 6 from the default 510 bytes to
750 bytes
_stmt.setBatchStringSize( 6, 750 ); // note binary parameters are in bytes

for( ... ) // for loop to batch n sets of parameters where n should not
be too large
{
stmt.set?( 1, ? ); // where stmt is the prepared insert statement from
step 1
stmt.set?( 2, ? );
...
stmt.set?(m , ? ); // note that there are m parameters in the statement
stmt.addBatch(); // adds the set or parameters to the batch and moves
to the next row of parameters
}

The maximum string/binary size of a parameter should be modified with caution.
If the maximum is set too high, then the additional memory allocation cost
*will* probably override any performance gained from using the batch. Also,
there is a good chance the application will not know ahead of time what the
maximum string or binary value for a particular parameter is. The recommendation
then is to not change the maximum string or binary size of a parameter, but
rather to use the batch method until a string or binary value larger than
the current/default maximum is encountered. The application can at that point
call executeBatch() to execute the parameters that are currently batched,
then call the regular set and executeUpdate() method to execute until the
large string/binary parameters have been handled, then switch back into batch
mode when smaller string/binary parameters are encountered.

Adaptive Server Anywhere - OLEDB Client Library

================(Build #3730 - Engineering Case #543888)================

The SQL Anywhere OLE DB provider did not support multiple parameter sets
in the ICommand::Execute method. The number of parameter sets is specified
in the cParamSets field of the DBPARAMS structure, for example:

HRESULT Execute (
IUnknown     *pUnkOuter,
REFIID        riid,
DBPARAMS     *pParams,
DBROWCOUNT   *pcRowsAffected,
IUnknown    **ppRowset);

struct DBPARAMS {
void *pData;
DB_UPARAMS cParamSets;
HACCESSOR hAccessor;
};

This is now supported, so it is now possible to execute one INSERT statement
and specify several sets of parameters in order to insert several rows into
a table.

Note the following OLE DB specification restriction:
Sets of multiple parameters (cParamSets is greater than one) can be specified
only if DBPROP_MULTIPLEPARAMSETS is VARIANT_TRUE and the command does not
return any rowsets.

This means that multiple parameterized SELECT statements can not be executed
that would each return a result set. For the SQL Anywhere provider, DBPROP_MULTIPLEPARAMSETS
is VARIANT_TRUE (and always has been).

Adaptive Server Anywhere - Server

================(Build #3689 - Engineering Case #394857)================

Not all OLE DB schema rowsets are supported, however the most common and
useful rowsets are supported.  Two OLE DB schema rowsets that were not supported
have now been implemented.

CATALOGS: The CATALOGS rowset identifies the physical attributes associated
with catalogs accessible from the DBMS. SQL Anywhere does not support the
notion of catalogs as some other database systems do. With that in mind,
the SQL Anywhere OLE DB provider will return a result set for CATALOGS containing
all currently started databases. The following is an example.

CATALOG_NAME DESCRIPTION
AnotherSample c:\SQLAnywhere10\Samples\sample.db
demo c:\SQLAnywhere10\Samples\demo.db

The CATALOG_NAME column contains the database name.  The DESCRIPTION column
contains the physical location of the database on the database server computer.

SCHEMATA: The SCHEMATA rowset identifies the schemas that are owned by a
given user.  The following is an example of a SCHEMATA rowset  returned by
the SQL Anywhere OLE DB provider.

CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER DEFAULT_CHARACTER_SET_CATALOG DEFAULT_CHARACTER_SET_SCHEMA DEFAULT_CHARACTER_SET_NAME
demo dbo dbo demo SYS windows-1252
demo GROUPO GROUPO demo SYS windows-1252
demo ml_server ml_server demo SYS windows-1252
demo rs_systabgroup rs_systabgroup demo SYS windows-1252
demo SYS SYS demo SYS windows-1252

The CATALOG_NAME column contains the name of the database to which you are
currently connected. The SCHEMA_NAME and SCHEMA_OWNER columns contain identical
values  for SQL Anywhere databases. The DEFAULT_CHARACTER_SET_CATALOG column
always contains the name of the database to which you are currently connected
since character sets are associated with databases. The DEFAULT_CHARACTER_SET_SCHEMA
column is arbitrarily set to SYS since the character set in use for the database
is not owned by anyone. The DEFAULT_CHARACTER_SET_NAME column contains the
value of the "CharSet" database property

Note, to get this new functionality in existing databases, do the following:

9.0.2 - upgrade the databases by loading and running Scripts\oleschem.sql
using Interactive SQL.

10.0.1 - run dbupgrad on each database, or connect to each database and
run ALTER DATABASE UPGRADE. As an alternative, the databases can be upgraded
by running Scripts\oleschem.sql using Interactive SQL.

11.0.0 - run dbupgrad on each database, or connect to each database and
run ALTER DATABASE UPGRADE.

================(Build #3675 - Engineering Case #528793)================

A new connection and database property called "Authenticated" has now been
added. The use of these two new properties is as follows:
For OEM servers, once an application has executed the "SET TEMPORARY OPTION
CONNECTION_AUTHENTICATION=" statement, the application can then turn around
and execute a "SELECT connection_property( 'Authenticated' )" statement.
If the result is "YES", then the connection was properly authenticated and
all is well. If, however, the result is "NO", then the application can execute
a "SELECT db_property( 'Authenticated' )" statement. If the result of this
statement is "YES", then the database has been properly authenticated and
the connection authentication failed because the CONNECTION_AUTHENTICATION
string is incorrect. If, on the other hand, the result of querying the Authenticated
database property is "NO", then the connection authentication failed because
the database has not been properly authenticated. In this case, the customer
should examine the DATABASE_AUTHENTICATION string to determine what is wrong.

For non-OEM servers, the result of querying these new properties will always
be "YES".

================(Build #3594 - Engineering Case #486288)================

The best plan for a query block with a DISTINCT clause, and one or more joins,
may be to use semijoins instead of inner joins based on the expressions used
in the select list. Inner joins can be executed as semijoins for tables,
derived tables, or views whose expressions are not used in the select list.
The server will now make a cost-based decision to use inner joins or semijoins
during the optimization phase

================(Build #3586 - Engineering Case #485349)================

Predicates of the form "column IS NULL" are eliminated if the column is declared
NOT NULL earlier now in the optimization process. This increases the oportunity
for rewrite optimizations to be performed.

================(Build #3507 - Engineering Case #446914)================

With this change, it is now possible to restrict the permissions of temporary
files created by the server and/or client. Traditionally, these files were
unconditionally created with global read, write and execute permissions.
To use this feature, a directory must be specified using the SATMP environment
variable and this directory must not be one of the standard locations:
- /tmp
- /tmp/.SQLAnywhere
- the value of the TMP environment variable, if set
- the value of the TMPDIR environment variable, if set
- the value of the TEMP environment variable, if set
- a symbolic link pointing to any of the above
When SATMP is set to such a non-standard location, the server and client
will walk up the given directory path looking for directories owned by the
current user with permissions set to 707, 770 or 700. For each directory
found, the appropriate permissions (other, group, other+group respectively)
will be set from the permission mask used to create temporary files.

For example, if the SATMP environment variable is set to: /tmp/restricted_permissions/sqlany,
where restricted_permissions is a directory with permissions 700, then all
files created in this directory will have permissions 700.

================(Build #3498 - Engineering Case #468867)================

When run on Windows CE devices, 1MB per of address space was reserved by
the server for each thread, although only a portion was actually allocated,
or "committed". This has been changed for Windows CE PocketPC 2003 and newer
devices, as the server now implements the -gss command line option for these
devices. The -gss option sets the stack size per internal execution thread.
The default and minimum stack size is 64K and the maximum is 512K.

================(Build #3488 - Engineering Case #462899)================

When using the command line options -qw "do not display database server screen"
or -qi "do not display database server tray icon", a number of messages that
should have been logged to the -o output file were suppressed. This has now
been corrected.

================(Build #3461 - Engineering Case #463074)================

In build 3461, the ECC transport-layer security protocol has changed to allow
10.0.x clients to connect version 9 servers. If only the server is updated
to build 3461 or higher, 9.0.2 clients running older builds can continue
to connect using ECC transport-layer security. However, if 9.0.2 clients
are updated to build 3461 or higher, they can use ECC transport-layer security
to connect to a 9.0.2 server only if the server is also running build 3461
or higher. In other words, the 9.0.2 server must be updated first.

For a 10.0.0 client to use ECC transport-layer security to connect to a
9.0.2 server, the 10.0.0 client must be running build 2816 or higher, and
the 9.0.2 server must be running build 3461 or higher.

================(Build #3459 - Engineering Case #448493)================

There was really no way of forcing the server to quote identifiers when attempting
to execute a remote query that contained identifiers that needed to be quoted.
The quoting of idetifiers by the server is based on specific rules within
the Remote Data Access framework. This has now been enhanced to do a better
job of quoting identifiers for certain classes of remote servers. In particular,
the new more simplified, and more accurate rules, for quoting identifiers
are:

- For SA, ASE, and MS SQL Server, the quoted_identifier option is now turned
on by default at connect time and identifiers are always quoted.
- For Oracle, identifiers can always be quoted, so the server now always
quotes identifiers in SQL generated for Oracle.
- For DB2 and generic ODBC remote servers, the old rules for quoting identifiers
still apply. That is, quoting of identifiers is done based on whether or
not the identifier contains special characters that require quoting.

================(Build #3410 - Engineering Case #448759)================

The TDS DATE and TDS TIME datatypes were recently introduced into TDS clients.
As a result, applications that use Open Client 15 or newer versions/ebfs
of jConnect are now able to fetch date and time columns as TDS DATE or TDS
TIME values instead of TDS DATETIME. Unfortunately, Open Client and jConnect
applications wishing to fetch date and time columns as TDS DATE and TDS TIME
could not do so when connected to SA servers. The server has now been enhanced
so that TDS based applications can now fetch date and time data as TDS DATE
and TDS TIME values if they so wish. Applications that use an older version
of Open Client or jConnect will continue to fetch date and time data as TDS
DATETIME.

Note that non-TDS based applications (i.e. applications that use ESQL, ODBC
or the iAnywhere JDBC Driver) have always been able to fetch date and time
data as DATE and TIME values.

================(Build #3333 - Engineering Case #434602)================

A new server command line option has been added, -su <password>, in order
to specify the utility_db password, and deprecate the use of the util_db.ini
file. Also, the GRANT CONNECT statement now allows changing the utility_db
password, and the REVOKE CONNECT now allows disabling connections to the
utility_db

New option documentation:

-su server option

Function: Set the password for the DBA user of the utility database (utility_db),
or disables connections to the utility database.

Syntax: { dbsrv10 | dbeng 10 } -su password ...

Applies to: All operating systems and servers.

Description:
This options specifies the initial password for DBA user of the utility
database. By using a value of NONE for the password, all connections to
the utility database are disabled. You may wish to use dbfhide to obfuscate
the password, and reference the obfuscated file on the command line.
If this option is not specified, the personal server allows connections
with the DBA userid and any password. If this option is not specified, the
network server does not allow connections to the utility database unless
the util_db.ini file exists and the userid is DBA with a password which matches
the password in the util_db.ini file. On a network server, if both -su and
util_db.ini are used, util_db.ini is ignored.

Note util_db.ini is deprecated and will be removed a future version of SQL
Anywhere. While connected to utility_db, the GRANT CONNECT TO DBA [IDENTIFIED
BY 'new_password'] statement may be used to change the password for the DBA
user of the utility database, and the REVOKE CONNECT FROM DBA statement can
be used to disable connections to the utility_db.

Examples:
dbeng10 -su None demo.db
create util_db_pwd.cfg containing only the text "utilpwd"
dbfhide util_db_pwd.txt util_db_pwd_hide.txt
dbsrv10 -su @util_db_pwd_hide.txt -n my_server demo.db

See also:
- utility database
- util_db.ini

================(Build #3316 - Engineering Case #432227)================

When using Open Client, there was a requirement that the servername that
was specified as part of the Open Client login, was also the name of the
database that the user was attempting to connect to. The reason for this
requirement was due to the fact that the database name that is usually specified
as part of an Open Client connection actually does not get sent until after
the connection is establised. This model of sending the database name after
the connection is established works for ASE, since in ASE the connection
is to the master database first, and then switches to the specified database
once the database name is sent. However, in the case of SA, there is no master
database so SA needs to know at login time which database the user wants
to connect to.

A new feature has now been implemented so that the SA server will allow
connections to the default database, even though the Open Client login server
name does not match the name of the default database, provided that the connection
string does not involve starting a database (i.e. there is no DBF=), and
the server is only running one database. If both of these conditions are
met, then the Open Client connection will be allowed to the default database.

================(Build #3308 - Engineering Case #430899)================

When running on Solaris systems, the server will now use 'cp932' as the default
character set when it detects that the locale is set to ja_JP.PCK. Perviously,
it would have used 'iso_1' as the default character set.

================(Build #3308 - Engineering Case #429794)================

The SQL Anywhere Webservice Client has been modified such that when a defined
attribute resolves to NULL the behaviour is now equivalent to that of an
undefined attribute. For example, the following client procedure instances
behave as if the PROXY clause is not defined when their associated substitution
parameters are NULL:

create procedure f2c("temp" float, proxyurl long varchar )
url 'http://localhost/f2c' proxy '!proxyurl'; // where proxyurl = NULL

create procedure f2c("temp" float, schemehost long varchar, path long varchar
)
url 'http://localhost/f2c' proxy '!schemehost!path'; // where schemehost
= NULL and path = NULL

create procedure f2c("temp" float )
url 'http://localhost/f2c'; // proxy not defined

whereas:

create procedure f2c("temp" float, hostname long varchar, path long varchar
)
url 'http://localhost/f2c' proxy '!http://!hostname/!path'; // does not
resolve to NULL even if hostname = NULL and path = NULL

can never resolve to NULL due to the static text within the value of the
PROXY attribute.

An empty string '' is not treated the same as a NULL. If used within one
or more substitution parameters, the empty string will resolve to an empty
string - not NULL. In the case of the first two examples, if all substitution
parameters were empty strings, the proxy attribute would equal '' (empty
string). Conversely, in the fourth example proxy would resolve to 'http:///',
whether the substitution parameters were NULL or '' (empty string).

Default Behaviour of undefined (or resolve to NULL) Attributes
- ** type - 'SOAP:RPC'
- namespace - URI composed of scheme, hostname and port:
If type 'SOAP:DOC' Http SOAPAction header is composed of URI/operation,
where operation is the soap service endpoint. e.g.: if the operation at
localhost is login, then the namespace = 'http://localhost' and the SOAPAction
: "http://localhost/login"
If type 'SOAP:RPC' resulting Http SOAPAction header is SOAPAction : ""
- url - The URI 'NULL' is invalid. SQLCODE = -980
- proxy - no proxy.
- clientport - use any free port.
- certificate - no certificate.
- *header - no user defined HTTP headers.
- *soapheader - no soap headers.

Notes:
* header and soapheader clauses are a new features in 10.0.
** type substitution parameters are not supported prior to 10.0.

================(Build #3284 - Engineering Case #386434)================

Trying to create or start the database server on a Linux file system that
does not support Asynchronous I/O system calls, would have failed or caused
the server to hang. This has been fixed.

A work-around is to use the -ua server command line option, or remove the
library libdblaio(a|d){ver}.so from the installation directory, where {ver}
is the
SQLAnywhere major version number.

================(Build #3270 - Engineering Case #422513)================

The server now supports the READPAST table hint. An example:

Select *
From customer with( readpast )
Where state = 'NY'

READPAST is meaningful only at isolation level 1; it is ignored at all other
isolation levels. As with other hints, the READPAST hint is respected only
when the correlation name in the FROM clause refers to a base or global shared
temporary table. In other situations (views, proxy tables, table functions)
the READPAST hint is ignored. Queries within views may utilize READPAST as
long as the hint is specified for a correlation name that is a base table.

The READPAST hint directs the server to ignore locked rows (that is, rows
write-locked by other connections) rather than blocking. One way to think
about READPAST is to pretend that addtiional predicate has been added to
the query's WHERE clause; with the example above, akin to

Select *
From customer with( readpast )
Where state = 'NY' and (current row is not write locked by another transaction).

Consequently the READPAST hint is inconsistent with the behaviour of ANSI
SQL isolation level 1, as uncommitted changes (locked rows) have an impact
on the result set of a statement utilizing READPAST. As such, the use of
READPAST can lead to anomalies due to the interaction of locking and predicate
evaluation within the server. Subtle differences in this interaction from
release to release of SQL Anywhere may yield different behaviours. The precise
affect of READPAST may also depend on the optimization strategy determined
by the query optimizer, particularly if the hint is specified only on a subset
of the tables in the query. For example, consider the outer join query

SELECT * FROM R LEFT OUTER JOIN S (WITH READPAST) ON 1=0

In 9.0.2, a cursor stability lock is placed on the rows of R and S once
the join is performed (assume nested loop join, JNLO, in this example). Further,
assume that we find a single candidate S row to match the current R row,
but that it is dirty (the row is write-locked by another transaction). The
lock node will reject it, causing the server to fetch another row from the
JNLO. Since the JNLO thinks it has found a match, it will not generate a
null-supplied copy of the R row, and the server will fail to preserve the
R row in the result. Hence, in this case, the query's result will fail to
include all the rows of R, which it would if READPAST was not used.

READPAST can be used with all cursor types. However, KEYSET cursors must
be used with caution. When initially populating the keyset through forward
FETCH statements, READPAST will ignore locked rows as described above. However,
a subsequent refetch of a previously FETCH 'd row may block if that underlying
row was write-locked by another connection after the row was originally added
to the keyset. The blocking can be avoided through the use of the BLOCKING
option, but after receiving the ROW_LOCKED error (SQLCODE -210) the cursor
will be in an invalid state.

READPAST can be useful when implementing a queue with a table, and there
are multiple producers and consumers of the queue. Using READPAST can significantly
improve concurrency in this scenario.

================(Build #3207 - Engineering Case #409768)================

Support has now been added for 32-bit Itanium clients on HP-UX 11i v2 (HP-UX
11.23) IPF.

Note that starting with this build, HP-UX 11i IPF versions prior to HP-UX
11i v2 (HP-UX 11.23) are no longer supported.

For details on HP's HPUX 11i support, see:
http://www.hp.com/products1/unix/operating/oeurjuly05.html

================(Build #3204 - Engineering Case #406845)================

A new character set conversion mapping table has been added to provide Microsoft-compatible
conversion to and from CP932 (Japanese). In the existing mapping table, <install>\charsets\unicode\cp932ms.uct,
certain characters that appear more than once in CP932 map differently from
Microsoft conversion functions. By copying the new file, cp932ms3.uct, over
cp932ms.uct, mappings will be 100% compatible with the Microsoft mappings.
The affected characters in CP932 are 81CA, 8754-875D, 8782, 8784, 878A, EEF9,
FA4A-FA54, FA58-FA5A. As noted, for these characters, the same Japanese characters
occur as two different character codes in the character set.

It is important that this file be copied over cp932ms.uct before any use
of a database in the environment. In particular, it is recommended that this
file copy occur immediately after deploying Adaptive Server Anywhere and
a database and prior to running an application against the database. If the
file copy occurs after the database has been in use, the altered character
mappings may cause data values to change, even though the appearance of the
characters remains unchanged. In a synchronization environment, these data
changes may cause unexpected errors.

================(Build #3175 - Engineering Case #400908)================

Attempting to start a server with a non-existent configuration file, (i.e.
dbeng9 @does_not_exist), would have caused the Usage dialog to be displayed
without the name of the non-existent file. This has been changed so that
the Usage dialog will now display the missing file name.

================(Build #3113 - Engineering Case #386756)================

The server can now dump the SQL text or graphical plans of expensive queries
to the request-level log. A new server command line option, -zx <cost>, has
been added to turn on this feature and define the threshold above which queries
are considered expensive. Expensive queries can be handled in two ways:
when the -zp option is also specified, detailed graphical plans will be sent
to the request-level log. Otherwise, only the SQL text of the expensive
queries will be logged.

When both -zx (LogExpensiveQueries) and -zp (RememberLastPlan) are set:
-queries whose estimated cost is greater than <cost> milliseconds will be
built with full statistics gathering gear, and a graphical plan will be dumped
to the request-level log at build time
-queries whose estimated cost is less than <cost> milliseconds will be built
with low-detail statistics gathering gear
-queries whose actual run-time is greater than <cost> milliseconds will
have their graphical plan dumped to the request-level log when their cursor
is closed; plans will contain whatever level of statistical detail was determined
for them at optimization time (as described in the first point)

When only -zx is set:
-queries will be built with low-detail statistics gathering gear
-queries whose actual run-time is greater than <cost> milliseconds will
have their SQL text dumped to the request-level log when their cursor is
closed

The request-level log must be directed to a file for these lines to appear
(by using the -zo command line option or by setting the RequestLogFile property).
However, these lines will still appear even if the RequestLogging property
is 'None'.

Plans appear as a single PLAN line in the request-level log; SQL text appears
as a single INFO line. They are prefixed by a header which indicates whether
they were dumped at build time or cursor completion time, and what the associated
cost at that time was. Plans dumped at build time are prefixed by [XB <cost>],
plans dumped at cursor completion time are prefixed by [XC <cost>], and SQL
text dumped at completion time is prefixed by
[XS <cost>] (where all costs are given in seconds, the same as displayed
in graphical plans).

The LogExpensiveQueries property can be set by the -zx <cost> command line
option, or by setting the LogExpensiveQueries server option with sa_server_option().
Setting <cost> to 0 (zero) turns this logging off.

================(Build #3112 - Engineering Case #387852)================

The server will now dump cache information when it gets a 'dynamic memory
exhausted' assertion. The dump file will contain information about the cache
contents, and help engineering diagnose the cause of the out of memory condition.
The filename will be of the form asa_cache.dmp.<pid>, and will be placed
in one of the following directories:
- the directory specified by the environment variable ASA_DIAG_DIR
- the current directory of the server process
- the temp directory of the operating system

================(Build #3109 - Engineering Case #371941)================

The server command line options -c, -cl, and -ch allow cache sizes and limits
to be specified in terms of "percentage of total physical RAM installed in
the system". On systems where there was more physical RAM installed than
there was address space available to the server process, using percentage
notation could have caused the server to attempt to allocate a cache larger
than it could possibly allocate. For example, -c75p on a system with 8GB
of RAM installed would attempt to create a 6GB cache. Percentage notation
for these options are now defined as a percentage of available address space
or total physical RAM, which ever is less.

On all 32-bit systems other than Windows, available address space is defined
as 2GB less 256MB. On Windows, available address space is computed accurately
on startup. Note
that each process on 32-bit Windows is given a total of 2GB of address space
(that's an OS and 32-bit architecture limitation) except on Windows 32-bit
Advanced Server, Enterprise Server and Datacenter Server, where they are
given 3GB of address space in total provided "/3GB /PAE" is in the boot.ini
and there is no more than 16GB of RAM installed. Again, these are OS and
32-bit architecture limitations. 32-bit programs running on Windows x64 Edition
are given the full 4GB of address space. Available address space is then
defined as total address space less address space in use by the database
server at startup.

For AWE caches ('-cw' is on the command line), the definition of percentage
notation has not changed and remains as a percentage of total physical memory
on the system.

================(Build #3095 - Engineering Case #382935)================

CREATE LOCAL TEMPORARY TABLE can now be used to define a local temporary
table which will persist until the end of a connection, or until the table
is explicitly dropped. While DECLARE LOCAL TEMPORARY TABLE can be used to
do the same thing outside a procedure, there was previously no mechanism
for doing this within a procedure. In other words, if CREATE LOCAL TEMPORARY
TABLE is executed within a procedure, the table will continue to exist after
the procedure completes. Similarly, if this statement is executed within
an IF statement, the table will exist after the IF completes.

================(Build #3031 - Engineering Case #379686)================

A new database option has been added, UUID_has_hyphens, which will control
the formatting of uniqueidentifier values when they are converted to strings.
With the default setting of ON, the resulting strings contain 4 hyphens,
as in:
12345678-1234-1234-1234-1234567890ab
With the option set to OFF, the hyphens will be omitted from the string.

Also, when converting a string to a uniqueidentifier value, the server now
supports UUID strings both with and without hyphens.

================(Build #3028 - Engineering Case #379663)================

A new server command line option -ze, has been added to display the server
environment variables. The environment variables are displayed on the server
console window and will appear before the copyright notice. The output will
also go in the system log if configured properly. This option is not available
on Netware and Windows CE systems.

================(Build #2529 - Engineering Case #367568)================

Collation 1252NOR has been added to provide Norwegian ordering and comparisons
for Windows Code Page 1252. When creating a new database on Windows systems
using the cp1252 codepage, if no collation is specified, and the language
setting for the system is Norwegian (or the environment variable ASLANG is
set to "no"), then 1252NOR will be chosen. Previously, 1252LATIN1 would have
been chosen.

Adaptive Server Anywhere - Utilities

================(Build #3460 - Engineering Case #461282)================

The 32 bit version of the dbisqlc utility would not run on the PA-RISC version
of HP-UX
11i v3 (version 11.31) as it required the deprecated library libcur_colr.
This requirement for this library has been removed.

================(Build #3277 - Engineering Case #423859)================

The Service Creation utility can now create services for the Listener utility,
using the '-t dblsn' command line option.

================(Build #3266 - Engineering Case #420588)================

The Data Source utility now supports encrypting the password when creating
ODBC data sources. When the -pe command line option is specified, and a PWD
entry is provided, the password in the PWD entry is encrypted and replaced
by an ENP entry in the resulting data source.

================(Build #3239 - Engineering Case #416564)================

Two new commandline options have been added to the Data Source utility.

The ODBCINI and ODBCHOME environment variables are used to tell the ODBC
driver and Data Source utility where to find the .odbc.ini file. If these
environment variables were set to files that did not exist, a search for
the .odbc.ini file was done in the user's home directory, and if not found,
the path was searched. If a file was found, that file was used. If no file
is found, one was created in the user's home directory. The -ns option now
tells the Data Source utility not to search for the .odbc.ini file, but to
use the existing environment variables to determine where the file should
be. This is only useful when (a) the file specified by one or more of the
environment variables does not exist, AND (b) a DSN is being created.

The -f option tells the Data Source utility to display the name of the .odbc.ini
file that is being used. For example, "dbdsn -f -l" will display the name
of the .odbc.ini file being used, and then list the DSNs in that file.

================(Build #3221 - Engineering Case #410263)================

Microsoft's Visual Studio integration has been extended with the release
of the SQL Anywhere Explorer. The Explorer allows you to create connections
to SQL Anywhere databases and browse the contents of tables and columns within
the Visual Studio environment, in a manner similar to the Server Explorer.
The accompanying toolbar can be used to launch Sybase Central and Interactive
SQL from within Visual Studio. The Explorer supports browsing of the database
structure and allows drag-and-drop operations to populate forms with controls.
The SQL Anywhere Explorer supports both Visual Studio 2003 and Visual Studio
2005. The explorer is installed within Visual Studio by default when running
the setup program. Both the explorer and the toolbar can be started by selecting
them from the View menu in Visual Studio. There is no documentation yet for
the SQL Anywhere Explorer, but Visual Studio users who are already familiar
with the Server Explorer will find that it works in a very similar manner.

New files include

<install dir>\win32\iAnywhere.VSPackage.AsaClient.dll
<install dir>\win32\SetupVSPackage.exe
<install dir>\win32\1033\iAnywhere.VSPackage.AsaClientUI.dll

<install dir>\win32\VS8\iAnywhere.VSPackage.AsaClient.dll
<install dir>\win32\VS8\SetupVSPackage.exe
<install dir>\win32\VS8\1033\iAnywhere.VSPackage.AsaClientUI.dll

================(Build #2946 - Engineering Case #370744)================

In order to run a service under an account other than LocalSystem, that account
must have been granted the "Login as a service" privilege. Sybase Central
can detect when the account does not have this privilege, ask the user whether
to grant it, and grant it if so, but the Create Service utility dbsvc, did
not have this ability. Now, dbsvc will ask the whether to grant this privilege,
and grant it if so, if the -a (account name to use)command line option is
used rather than the -as option, and the account does not have this privilege
already.

Notes:
- if the user running dbsvc does not have Administrator privileges, then
granting the privilege will fail. However, users without Administrator privileges
cannot create services anyway
- if the -y option is used, then dbsvc will attempt to grant the "Login
as a
service" privilege without prompting the user

MobiLink - QAnywhere client

================(Build #3799 - Engineering Case #561122)================

The .NET QAManagerBase class now supports ExceptionListener delegates, which
allows for applications to be notified of QAExceptions that occur while receiving
messages on the background thread.

The following are the relevant APIs:
/// <summary>
/// ExceptionListener delegate definition.
/// </summary>
/// <param name="ex">The exception that occurred.</param>
/// <param name="msg">The message that was received, or null if the message
/// could not be constructed.</param>
public delegate void ExceptionListener( QAException ex, QAMessage msg );

/// <summary>
/// Sets an <see cref="ExceptionListener"/> delegate to receive QAExceptions
/// when processing QAnywhere messages asynchronously.
/// </summary>
/// <param name="address">The address of messages.</param>
/// <param name="listener">The exception listener to register.</param>
public void SetExceptionListener( string address, ExceptionListener listener
);

In 10.0.x and later, the .NET and Java QAManagerBase class now supports
exception listeners.

The .NET and Java QAManagerBase class now supports a property, RECEIVER_INTERVAL,
that represents the maximum wait interval (in milliseconds) in the background
receiver thread for receiving messages. The default is 60000 milliseconds.
As with other QAManager properties, this property must be set before calling
an Open() method.

The .NET and Java QAManagerBase class now supports a ReOpen() method that
can be called in an ExceptionListener or MessageListener to re-establish
connections to the message store database. Following is the API description.

/// <summary>
/// Reopens the QAManagerBase. This re-establishes connections to the message
/// store, without releasing any resources. This method may called in a
/// message or exception listener, and in that case it is not necessary
to
/// call Start() again. This method simply executes Close() then Open()
if
/// not called in a listener, and in that case Start() must be called to
/// restart receiving of messages.
/// </summary>
/// <exception cref="iAnywhere.QAnywhere.Client.QAException">
/// if there is a problem reopening the manager.
/// </exception>
public void ReOpen();

================(Build #3794 - Engineering Case #561067)================

The QAnywhere Agent (qaagent) now attempts to reconnect to the message store
database when the connection is dropped.
Notes:
- The initial database connection will be retried a given number of times
if the first connection fails
- Command line options for connection retries and retry delay:
-cr <n> (n is the number of retries to connect after a failure)
-cd <n> (n is delay, in seconds, between retries)
- The defaults are 3 retries with a 10 second delay between retries
- If all retries fail, the QAnywhere Agent displays an error and waits
to be shut down
- If a database connection fails during operation, the QAnywhere Agent
will go through termination steps, including finalizing connections, terminating
threads and external processes, and then re-starts.

================(Build #3483 - Engineering Case #466209)================

The QAnywhere Agent (qaagent) now has an option to control where the listener
tracking store is created. The option is -z <path> and corresponds to the
dblsn -z option documented in Engineering case 460718.

MobiLink - QAnywhere server

================(Build #3642 - Engineering Case #495514)================

The MobiLink system table ml_qa_status_history in a consolidated database
would have grown without limit. This happened with all QAnywhere supported
consolidated database types. This has been fixed so that when delete rules
cause messages to be deleted in the consolidated database, the corresponding
rows in the table ml_qa_status_history are now deleted. An existing ASA consolidated
database will be automatically upgraded with the fix for this problem. For
other consolidated databases, the MobiLink setup script for that database
must be executed.

MobiLink - SA Client

================(Build #3659 - Engineering Case #495705)================

When the MobiLink Client was launched using the Dbmlsync Integration Component,
it was possible to view the username and password in the dbmlsync command
line in plain text. This has been corrected so that the Dbmlsync Integration
Component will encrypt all the command line options and settings before passing
them to dbmlsync. Dbmlsync will then decrypt the options and settings.

Note, this fix does not apply to the Dbmlsync Integration Component running
on Windows CE systems.

================(Build #3556 - Engineering Case #480085)================

If transaction log files for multiple databases were stored in a single directory,
the MobiLink client dbmlsync might not have been able to synchronize any
of these databases, even if there were no offline transaction log files for
any of these databases. To resolve this, a new command line option has been
added to dbmlsync:
-do disable offline logscan (cannot use with -x)
When this new option is used, dbmlsync will not attempt to scan any offline
transaction logs. Therefore, dbmlsync with -do should be able to synchronize
a database that is stored with all the other databases in a single directory,
as long as this database does not have any offline transaction log files.
However, if actual offline transaction log files are requested (for instance,
if the minimum progress offset is located
in an offline transaction log or if an uncommitted transaction starts from
an offline transaction log), dbmlsync with -do will raise an error and refuse
to run the synchronization.

MobiLink - Synchronization Server

================(Build #3384 - Engineering Case #449309)================

Enhancements were made to the MobiLink Server to allow for future support
of currently non-supported consolidated databases.

================(Build #3342 - Engineering Case #426484)================

A new MobiLink server HTTP stream option, called session_key, has been added.
This option determines how the MobiLink server tracks non-persistent HTTP
sessions (i.e. when the MobiLink client specifies 'persistent=0'). The option
is used as follows:

dbmlsrv9 ... -x http(...session_key=[cookie|header];...) ...

When the session_key is 'cookie', which is the default, an HTTP cookie with
name JSESSIONID is used to track HTTP sessions. When the session key is 'header',
an HTTP header is used. The 'header' option is useful if the cookie name
of JSESSIONID conflicts with an existing cookie, in which case MobiLink will
track HTTP synchronizations using a custom header entry that will not conflict
with any other HTTP infrastructure. In order to implement this feature in
the MobiLink server, changes were also required to the MobiLink client. Thus
to get the new behaviour, clients need to be upgraded as well.

================(Build #3100 - Engineering Case #380750)================

MobiLink clients using HTTP and HTTPS can now set a liveness_timeout stream
option, as follows:

liveness_timeout=N

where N is the number of seconds for the timeout. The default is to have
no timeout (N=0). The synchronization will fail if the client waits N seconds
without any data from MobiLink server. Users must be careful when setting
this value. The value set should be short enough to timeout early enough
for an impatient user, but set long enough for the longest delay between
the MobiLink server receiving the upload and sending the download to the
client. Note, if a synchronization is aborted due to a timeout, subsequent
synchronizations should not be affected -- unless the MobiLink server is
still processing the previous synchronization, in which case a "user already
synchronizing" error will occur.

MobiLink - Utilities

================(Build #3483 - Engineering Case #466058)================

A new option has been added to the CE Deployement Installer, which allows
for excluding the default QAnywhere database in the .CAB file.

================(Build #3456 - Engineering Case #460718)================

The Listener used by MobiLink Server-Intitated Synchronization uses a tracking
database to store information. A new command line option -z has been added
to the Listener utility (dblsn) to allow specifying a non-default location
for the temporary tracking database. The -z option takes the location of
the tracking database as a parameter.

For example,
dblsn -z "c:\program files\tracker\"...

================(Build #3180 - Engineering Case #408937)================

The native Apache2 redirector now supports routing requests from Afaria clients
to an Afaria server.

MobiLink - scripts

================(Build #3236 - Engineering Case #416088)================

The MobiLink server's .Net scripting only supported version 1 .NET CLR. The
MobiLink server would have failed to start if it attempted to load version
2 .NET CLR. The error reported in the log was: " [-10192] Could not create
domain 'DefaultMobiLinkDNetScriptingDomain' ". The -clrVersion option could
have been used to force the loading of a version 1 .NET CLR, if the fix for
Engineering case 409377 had been included in the version of the software,
(i.e. -sl dnet(-clrVersion=v1.0.3705 ... ). Now support has been added for
.NET CLR version 2 as well.

UltraLite - HotSync Conduit

================(Build #2532 - Engineering Case #372644)================

When the UltraLite HotSync conduit is loaded by the HotSync Manager (on desktops),
it will now attempt to load the plug-in DLL, if the value "PluginDLL" is
specified in the following registry key:

Software\Sybase\Adaptive Server Anywhere\<version>\Conduit\<CRID>

where <CRID> is the creator ID that was used in an UltraLite Palm application
on the remote. The "PluginDLL" value should be set to the plug-in DLL location.

The conduit plug-in DLL should have the exported function ULCondGetExtraStreamParms
specified:

Prototype
bool ULCondGetExtraStreamParms( char * stream_parms, unsigned short buffer_len
)

Parameters
stream_parms: Pointer to a buffer in which to return the extra stream
parameters.
buffer_len: The length of *stream_parms in bytes.

Remarks
The function should return false on error; otherwise, return true on success.
The extra parameters returned will be appended to the existing stream parameters
in the UL database.

UltraLite - Runtime Libraries

================(Build #3256 - Engineering Case #419563)================

UltraLite now supports Windows Mobile 5.0 devices. If using Embedded Visual
C++ 3.0 or 4.0, the existing runtimes can continue to be useed. However,
new runtimes (installed under ultralite\ce\arm.50) are required when using
Visual Studio 2005 to build an application.

Visual Studio 2005 compilers define the wchar_t type as the internal __wchar_t
type, instead of unsigned short*, which is what was used in the previous
CE compilers. Because of this, apps compiled with Visual Studio 2005 would
trigger unresolved external errors when linked against the UltraLite runtime.
As a work-around, an application can cast all wchar_t, ul_wchar, and TCHAR
variables passed into the runtime to unsigned short* explicitly. Another
work-around is to use the -Zc:wchar_t- compiler option, which will cause
wchar_t to be defined as unsigned short *, though, this won't work if the
app links against other libraries such as the MFC library that are compiled
with Visual Studio 2005 without this option.

Note that the Visual Studio 2005 compatible runtimes do not support sync
encryption on 9.0.2.

================(Build #3031 - Engineering Case #379836)================

UltraLite can now be run on Palm NVFS devices, and supports both the record-based
and file-based data stores.

This is a summary of UltraLite clarifications for the Palm OS platform.

A. Database
An internal file volume may also be present on some NVFS devices, such as
Tungsten T5 handhelds, which can be accessed and used similar to an SD slot.
Therefore, ULEnableFileDB is called to store UltraLite databases on either
an internal drive (built-in storage card) or external slot (expansion card).
Furthermore, the existing connection parameter palm_db=CRID:n is used to
specify the data store on either an internal drive or external slot, where
n is the volume ordinal from enumerating the mounted volumes, and the default
value of n is 0. Tungsten T5, for example, has two volumes, the internal
file volume and the SD slot volume. If the device cannot locate a volume
with the user-specified volume ordinal, the SQLCODE -82 is reported when
opening the database. ULEnablePalmRecordDB is called to store record-based
UltraLite databases.

B. Synchronization Conduit
The conduit synchronizes the first UltraLite database which is found on
the device. The database lookup sequence is first the record storage, then
the file system including internal drive and external slot. The UltraLite
database which is intended to be synchronize should be made available as
the first one found in that sequence. The conduit has been designed to work
like this, since the file-based data store support was first added to the
Palm platform.

UltraLite - UltraLite Engine

================(Build #3398 - Engineering Case #439377)================

Two special values "default_internet" and "default_work", are now recognized
for the network_name client synchronization parameter on Windows CE These
values represent the default internet network and default work network, as
specified via the Start->Settings->Connections->Connections dialog. The network_name
parameter still accepts the name of a specific network profile as before.

UltraLite - UltraLite for M-Business Anywhere

================(Build #3272 - Engineering Case #405988)================

UltraLite for M-Business Anywhere now supports ECC (Elliptic curve cryptography)
for TLS (Transport Layer security). Both UltraLite for M-Business Anywhere
pod (ulpod9.dll) and One-Button-Sync (ulconnect.exe) now support ECC over
TCPIP or HTTP as synchronization stream types.

To use this new feature, users will need to have a valid Certicom ECC license,
as well as ECC client and server certificates. New properties and methods
have been added to the SyncParms pods object to support the new synchronization
stream types.

* PODS Constant: UInt32 STREAM_TYPE_ECC_TCPIP - select this value for the
SyncParms.setStream() method when synchronizing via TCPIP over ECC transport-layer
security.

* PODS Constant: UInt32 STREAM_TYPE_ECC_HTTP - select this value for the
SyncParms.setStream() method when synchronizing via HTTP over ECC transport-layer
security. Note, this is NOT the same as HTTPS.

* PODS Method: setSecurityParms( String v ) - Sets the options required
when using ECC transport-layer security. This method is relevant only when
the sync stream type is set to be ECC_TCPIP or ECC_HTTP. A detailed explanation
of this parm string can be found in the MobiLink documentation: MobiLink
Clients -> UltraLite Synchronization Parameters -> Synchronization parameters
-> Security Parameters synchronization parameter.

* PODS Method: String getSecurityParms() - Gets the option string for ECC
security.

The UltraLite for M-Business Anywhere samples, Simple and CustDB, have been
updated to demonstrate the use of these new methods and constants.

================(Build #3252 - Engineering Case #418909)================

A new method has been added to the SyncParms pods object:
setMBAServerWithMoreParms( String host, String port, String url_suffix,
String additional )

This new feature came from requests to specify a proxy server's host/port
with ULPod one-button-synch. This new method augments the existing SyncParms.setMBAServer()
method by adding the new string argument "additional".

The new "additional" argument gives user a chance to specify additional
stream parms, such as proxy host, proxy port, or other security-related parameters.

================(Build #3226 - Engineering Case #410109)================

The next M-Business Anywhere release, version 6.0, will begin supporting
UTF8-encoded webpages on Windows platforms (PocketPC and XP Desktop). This
will cause incompatibility problem with UltraLite for M-Business Anywhere
(ULPod) 9.0.2, as ULPod assumes the webpage is encoded with the local codepage
of the device (ISO encoding), when it converts strings passed from the PODS
engine into Unicode strings, and then pass it to the UltraLite runtime. If
the string is UTF8 encoded, the conversion will be wrong and the data will
be lost.

A new feature has been implemented which will allow ULPod to tell how the
string coming from the PODS engine is encoded, and use the correct conversion
parameters to convert it to, or from, Unicode. This new feature is only enabled
on Windows platforms, as M-Business Anywhere for Palm OS does not yet support
UTF8.

UltraLite - Utilities

================(Build #3385 - Engineering Case #442543)================

The UltraLIte Interactive SQL utility and the UltraLite schema painter were
not handling systems with multiple monitors correctly. If a window was closed
while on a secondary monitor and then the application was restarted when
only one monitor was connected, the window would have been positioned off
the visible desktop. This is now fixed.

A workaround for this situation is to do the following:
1. Right click on the application in the task bar.
2. Select Move
3. Use the keyboard cursor keys to bring the window back to the visible
desktop and hit Enter when it’s properly positioned.

================(Build #3099 - Engineering Case #383489)================

On NVFS devices with an internal file volume, the UltraLite Palm utility
now provides access to UltraLite databases which are stored on an internal
drive. This is an addition to the current access to UltraLite data stores
on both the external slot and in-memory.

9.0.2 Bug fixes
(see also Critical Bug Fixes) (see also New Features)
This section contains a description of bug fixes made since the release
of version 9.0.2.

Adaptive Server Anywhere - ADO.Net Managed Provider

================(Build #3893 - Engineering Case #588917)================

The policy file for .NET 2.0 was installed incorrectly. This has now been
corrected.

================(Build #3746 - Engineering Case #547504)================

A multithreading application using the ADO .Net provider, could have hung
due to incorrect thread synchronization. This has been corrected.

================(Build #3739 - Engineering Case #486086)================

Long exception message generated by the provider could have been truncated.
This problem has been fixed.

================(Build #3694 - Engineering Case #536563)================

The insert performance sample (instest) shipped with SQL Anywhere did not
correctly assign values to integer columns on 64-bit big-endian platforms.
Depending on the definition of the table being used, may have caused instest
to terminate prematurely. The instest sample has now been corrected. This
problem can be worked around by modifying the FillItem() function in instest.sqc
to use an "int", instead of a "long", in the cast performed for the DT_INT/DT_UNSINT
case.

================(Build #3674 - Engineering Case #531348)================

Table locks were not released by the SABulkCopy() method when SABulkCopyOptions.LockTable
is specified. This problem has been fixed.

================(Build #3671 - Engineering Case #530041)================

When an SACommand object's Connection property was null, and the methods
ExecuteNonQuery, ExecuteReader or ExecuteScalar were called, a wrong error
message would havew been given: "Unable to load DLL 'dbdata.dll' : The specified
module could not be found."

For example:
SACommand cmd = new SACommand();
cmd.CommandText = "UPDATE customers SET name='1' WHERE name='1'";
cmd.ExecuteNonQuery();

This problem has been fixed.

================(Build #3666 - Engineering Case #528430)================

Calling the methods ExecuteReader or ExecuteScalar with parameters, would
have resulted in a memory leak in the 2.0 provider. This problem has been
fixed.

===============(Build #36535 - Engineering Case #494184)===============

The SACommandBuilder class did not implement the QuoteIdentifier method.
The QuoteIdentifier method has now been added.

================(Build #3640 - Engineering Case #495375)================

The result set returned when SAConnection.GetSchema("ProcedureParameter")
was called, would have been in an unpredictable order. This has been fixed
by adding an ORDER BY clause to the query statement.

================(Build #3618 - Engineering Case #490564)================

A recordset update may have failed when one of more column values were null.
The OLEDB provider failed to correctly identify the primary key columns in
a table, and this resulted in an UPDATE statement containing a WHERE clause
that was overly complex. This problem has now been fixed.

================(Build #3590 - Engineering Case #486469)================

The Data adapter wizard would have shown errors when generating commands.
The errors were cause by exceptions when executing a command which still
had an open data reader. Fixed by using new commands.

================(Build #3589 - Engineering Case #486531)================

The SQL Anywhere Explorer now supports Visual Studio 2008. Registry settings
for Visual Studio 2008 are now created, and the integration dll has been
modified to support Visual Studio 2008. Note that assemblies built with Visual
Studio 2005 can be used in Visual Studio 2008 as well.

================(Build #3587 - Engineering Case #485568)================

Multi-threading applications could have failed with a number of symptoms.
These symptoms include 'Resource governor for prepared statements limit exceeded'
and 'Communication error' errors, as well as client application crashes.
This problem has been fixed.

================(Build #3587 - Engineering Case #483227)================

As well as the fixes to correct multi-threaded applications in Engineering
case 485568, changes have also been made to thread synchronization to prevent
hangs when running on multi-processor machines.

================(Build #3579 - Engineering Case #483261)================

The methods ClearAllPools and ClearPool could have caused an exception if
any of the connections in a pool were not opened. This problem has been fixed.

================(Build #3575 - Engineering Case #483316)================

The .NET provider could have gone into an endless loop, with very high CPU
usage, on termination of the application. This has been corrected.

================(Build #3556 - Engineering Case #480211)================

When one connection was blocking on a WAITFOR statement, all other connections
were also blocked until it finishes. This problem has been fixed.

================(Build #3555 - Engineering Case #479953)================

A call to SADataReader.Read() could have caused an exception after calling
SADataReader.NextResult(), if the resultset was empty. The SADataReader.Read()
method was failing to check the resultset before fetching data. This problem
has been fixed.

================(Build #3542 - Engineering Case #477150)================

Setting SAParameter.SADbType could have caused an IndexOutOfRangeException
in multi-threading code. This problem has been fixed.

================(Build #3537 - Engineering Case #476347)================

If a command resulted in an exception, calling the same command again would
have caused the exception "Attempted to read or write protected memory".

For example:

SACommand cmd = new SACommand("INSERT INTO t VALUES (1)", conn);
try
{
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine("Insert failed. " + ex.Message + "\n" + ex.StackTrace);
}

try
{
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine("Insert failed. " + ex.Message + "\n" + ex.StackTrace);
}

This problem has been fixed.

================(Build #3504 - Engineering Case #468033)================

Inout parameters were not returned by SADataAdapter.Update when using SADataAdapter
and stored procedures to update data. This problem has now been fixed.

================(Build #3492 - Engineering Case #467594)================

Calling SADataReader may have caused extra characters to have been returned
for string values. A miscalculation of the strings length has been fixed.

================(Build #3484 - Engineering Case #466513)================

Executing an SQL statement with input parameters could have caused a memory
leak. This problem has been fixed.

================(Build #3480 - Engineering Case #466560)================

Using 2.0 ADO .Net provider could have caused the exception TypeLoadException.
The 2.0 provider was built as an x86 specific assembly, but the assembly
binding policy file was not updated. This has now been fix by adding processorArchitecture="x86"
to the assembly binding policy file.

================(Build #3480 - Engineering Case #463466)================

The ADO.Net provider could have thrown the exception 'Resource governor limit
for prepared statements exceeded' if the application issued statements which
contained multi-select statement.

For example:

BEGIN
DECLARE @MyConnectionId INTEGER;
DECLARE @MaxCount INTEGER;
DECLARE @Prepared INTEGER;
SELECT CONNECTION_PROPERTY ( 'prepstmt' ) into @Prepared;
SELECT number INTO @MyConnectionId FROM sa_conn_list(-1);
SELECT Value INTO @MaxCount FROM sa_conn_properties(@MyConnectionId) WHERE
PropName='max_statement_count';
SELECT @MyConnectionId AS Id, @MaxCount AS MaxStatement, @Prepared as
Prepared;
END

This problem has been fixed.

================(Build #3469 - Engineering Case #463081)================

The property DataReader.HasRows would have always returned True, whether
there were actually rows in the dataReader or not. This problem has been
fixed.

================(Build #3468 - Engineering Case #463174)================

Using pooled connections could have caused exceptions when used in multi-thread
applications. This has been fixed.

================(Build #3460 - Engineering Case #461314)================

The size and position of some user interface controls have been adjusted,
as they were not displaying properly for applications run on Windows Vista.

================(Build #3455 - Engineering Case #456885)================

The Add Connection dialog did not close when the ESC key was pressed. This
has been fixed.

================(Build #3455 - Engineering Case #456875)================

The SQL Anywhere Explorer was not reading the correct Windows registry entry
for the language setting, as created by Language Selection utility (dblang).
This has been fixed.

================(Build #3443 - Engineering Case #454480)================

Calls to the method DataTable.Merge() would have failed after performing
an update, when using a data adapter with the property AcceptChangesDuringUpdate
set to false. This problem has been fixed.

================(Build #3433 - Engineering Case #442269)================

Calling the method DataReader.GetSchemaTable() would have thrown an exception
if the table name contained single quotes. This has been fixed by doubling
single quotes in the table name.

================(Build #3426 - Engineering Case #451730)================

The method SAConnection.BeginTransaction() could have failed with a "Resource
governor 'prepared statement' limit exceeded" exception, if there were many
undisposed commands.

Here's an example:

using ( SAConnection conn = new SAConnection( "DSN=SQL Anywhere 10 Demo;UID=dba;PWD=sql"
) )
{
conn.Open();

for ( int i = 0; i < 1000; i++ )
{
SATransaction trans = conn.BeginTransaction();
SACommand cmd = new SACommand( "", conn, trans );
cmd.CommandText = string.Format( "INSERT INTO MyTable( id )
VALUES( {0} )", i );
cmd.ExecuteNonQuery();
trans.Commit();
}
}

The SAConnection.BeginTransaction method executes a SQL command to begin
a new transaction, but it was not checking if the number of existing prepared
statements had already exceeded the limit before executing the SQL. This
has been fixed.

================(Build #3422 - Engineering Case #450259)================

When executing a statement that runs for a long time ( for example, "waitfor
delay '20:00:00'" ), the application could have crash if the server had gone
down. This problem has been fixed.

================(Build #3422 - Engineering Case #450195)================

A SQL Anywhere web client procedure connecting to a non HTTP endpoint, may
have caused the server to crash, or to have failed silently with no error
message. This has been corrected so that the client will now generate the
error: "Invalid response from the HTTP server"

================(Build #3412 - Engineering Case #448751)================

Updating a DataTable using DataAdapter and CommandBuilder could have caused
the exception DBConcurrencyException.

Example:

AsaDataAdapter adapter = new AsaDataAdapter( "SELECT * FROM mytable",
conn );
DataTable table = new DataTable();
adapter.Fill( table );
table.Rows[ 0 ][ 1 ] = "ABCDEFG";
AsaCommandBuilder cb = new AsaCommandBuilder( adapter );
adapter.Update( table );

This problem has been fixed.

================(Build #3409 - Engineering Case #448363)================

The method SACommandBuilder.UnquoteIdentifier was not supported. Support
for this method has now been added.

================(Build #3403 - Engineering Case #446556)================

The ADO.NET providers ( versions 1.x and 2.0 ) were not marked as CLS Compliant.
This could have caused CS3001 and CS3003 warnings from Visual Studio. This
problem has been fixed.

================(Build #3403 - Engineering Case #446220)================

Calling a stored procedure that did not return a result set, could have caused
a "cursor not open" error. This problem has been fixed.

================(Build #3393 - Engineering Case #445193)================

Calling the method SACommand.ExecuteNonQuery with invalid parameter values,
could have caused an NullReferenceException to be thrown. This problem has
been fixed.

A C# example:

SAConnection conn = new SAConnection("dsn=SQL Anywhere 10 Demo;uid=dba;pwd=sql");
conn.Open();

SACommand cmd = new SACommand( "DELETE FROM Departments WHERE DepartmentID
= ?", conn );
cmd.Parameters.Add( "p1", SADbType.Integer );
cmd.Parameters[0].Value = "xxx";

int rowsAffected = cmd.ExecuteNonQuery();

================(Build #3392 - Engineering Case #444896)================

The performance of unprepared commands was slower than prepared commands
when calling ExecuteNonQuery. This problem has been fixed.

================(Build #3382 - Engineering Case #441675)================

Runing an NUnit test case repeatedly when connection pooling was enabled,
could have caused a System.AccessViolationException unhandled exception.
This problem has been fixed.

================(Build #3376 - Engineering Case #442767)================

Applications calling a procedure with a blob output parameter could have
crashed if any parameters of the procedure were derived by calling the SACommandParameter.DeriveParameters()
method. The SACommandBuilder.DeriveParameters() method was setting the size
of output blob parameters to 2GB, which caused a memory access violation.
This has been fixed by changing the Size of blob parameters to the default
value (32767).

================(Build #3376 - Engineering Case #442307)================

Calling a stored procedure that returned empty date, datetime, smalldatetime
or timestamp values, would have caused an ArgumentOutOfRangeException. This
problem has been fixed.

================(Build #3372 - Engineering Case #443651)================

The default value of the PrefetchRows connection parameter has been changes
from 10 to 200 as a performance optimization. That is if the PrefetchRow
parameter is not specified, the ADO.NET Data Provider will set it to 200.
The default value of AsaConnectionStringBuilder.PrefetchRow (and SAConnectionStringBuilder.PrefetchRow
for SA 10) has also been changed to 200. Prefetching is disabled if the resultset
has any blob columns.

================(Build #3364 - Engineering Case #440344)================

The performance of the ADO .Net 2.0 provider has been improved.

================(Build #3352 - Engineering Case #438528)================

The name of the table's owner was not being added to automatically generated
INSERT, UPDATE and DELETE statements by ADO.NET 2.0 provider. This has now
been fixed by setting the BaseSchemaName to the table's owner.

================(Build #3352 - Engineering Case #437957)================

The error message: "Package 'SQL Anywhere Explorer' has failed to load propertly...
", would have been displayed when attempting to open SQL Anywhere Explorer
in Visual Studio 2005. This problem has been fixed.

================(Build #3341 - Engineering Case #437013)================

UPDATE and DELETE statements that were automatically generated by the provider
would have failed if table had nullable columns. This problem has been corrected.

================(Build #3333 - Engineering Case #434603)================

If the method AsaConnection.GetSchema was called while the connection already
had a transaction, an exception would have been thrown. This problem has
been fixed.

================(Build #3207 - Engineering Case #405965)================

When installed on non-English Windows systems, the managed provider components
(Adapter, Connection, Command) were not displayed in Visual Studio's toolbar
tab correctly, along with the rest of the Data Components. This has now been
fixed.

================(Build #3198 - Engineering Case #405060)================

When Connection Lifetime was specified in a connection, the connection duration
would have been incorrect. This has been fixed so that the behaviour is as
follows:
- If the time span exceeds the value specified by Connection Lifetime, the
connection will be destroyed when it is closed.
- If the time span does not exceed the value specified by Connection Lifetime,
the connect will be returned to the pool when it is closed.

================(Build #3189 - Engineering Case #403057)================

Calling the ChangeDatabase method would have resulted in the provider looking
for name of the DSN, instead of the database name. The ChangeDatabase method
has been corrected to now use the DatabaseName(DBN) connection parameter
to change the current database.

================(Build #3173 - Engineering Case #400563)================

It was not possible to call a stored procedure via ADO.Net and have it to
use the default values for the stored procedure parameters, unless the parameters
were at the end of the list. This has been resolved by adding a new class
ASADefault/SADefault to the .NET provider. If the value of a parameter is
set to AsaDefault/SADefault.Value, the server will use the default value
to execute the procedure.

For example:

create procedure DBA.myproc( in arg1 int default 1, in arg2 int default
2, in arg3 int default 3)
begin
select arg1 + arg2 + arg3 from dummy;
end

To use the default values, set the parameters' value to SADefault.Value:

SAConnection conn = new SAConnection( "DSN=SQL Anywhere 10 Demo" );
conn.Open();

SACommand cmd = new SACommand( "DBA.myproc", conn );
cmd.CommandType = CommandType.StoredProcedure;

cmd.Parameters.Add( new SAParameter( "arg1", SADefault.Value ) );
cmd.Parameters.Add( new SAParameter( "arg2", SADefault.Value ) );
cmd.Parameters.Add( new SAParameter( "arg3", SADefault.Value ) );

int val = ( int ) cmd.ExecuteScalar();

================(Build #3131 - Engineering Case #392294)================

If the server was already stopped, the AsaClient would have thrown an exception
when closing the connection. The AsaClient was checking the error code when
closing the connection and threw the exception if the error code is not -85
Communication error. The AsaClient now ignores error whem closing the connection.

================(Build #3129 - Engineering Case #391887)================

Calling the method AsaDataReader.GetSchema() could have generated the exception:
"ASA .NET Data Provider: Column 'table_name' not found (-143)", if the database
also had a user table named systable. This has now been fixed by qualifying
references to system tables with the SYS owner name.

================(Build #3114 - Engineering Case #387070)================

The the method AsaDataAdapter.Fill may have caused an InvalidCastException
if the query returned columns which had the same name and different data
types. This problem has been fixed, but it is not recommanded to use duplicate
column names when filling a DataSet.

================(Build #3111 - Engineering Case #386109)================

The AsaDataAdapter object was very slow when filling a DataSet or a DataTable
which had primary key. This problem has been fixed.

================(Build #3108 - Engineering Case #385349)================

When inserting Multi-byte Character Set strings, by passing them as parameters
to the AsaCommand method, the strings were not saved. This has ben fixed.

================(Build #3035 - Engineering Case #379532)================

The same command object could have been deleted twice when running in a multi-threaded
environment. This could potentially have caused a crash. The problem has
been fixed.

================(Build #3025 - Engineering Case #378360)================

The Data Adapter did not set IsKey property to true when filling a DataTable
if the source tables had unique indexes. This problem has been fixed.

================(Build #2542 - Engineering Case #374580)================

An InvalidCastException would have been thrown when filling a DataTable using
AsaDataAdapter, if a returned TIME column was mapped to a STRING column in
the DataTable.
This problem has been fixed.

================(Build #2529 - Engineering Case #371411)================

The isolation level for a transaction was being set to 1 when the connection
was opened. Now, the isolation level is no longer set to any specific value.
The server default is the value defined for the connection by the database
option Isolation_level.

Note, this problem was introduced in the following builds:
8.0.3 5128
8.0.2 4442
9.0.2 2528
9.0.0 1333
9.0.1 1887
The old behavior is now restored

================(Build #2529 - Engineering Case #370326)================

The method AsaDataReader.GetSchemaTable() may have caused an InvalidCastException
when the data reader had some unique columns and computed columns. This problem
has been fixed.

================(Build #2529 - Engineering Case #369704)================

When filling a DataSet using the ASADataAdapter object, the AutoIncrement
property of DataColumn was not set properly. This has now been fixed.

Adaptive Server Anywhere - DBLIB Client Library

================(Build #3891 - Engineering Case #590383)================

On UNIX systems, there were directories left in the temporary directory,
with names of the form __SQLAnyCli__X_Y, where X is a process number and
Y is an alphanumeric number. This usually happened when a SQL Anywhere client
application was terminated abnormally. An example of this was the PHP driver
running within the Apache web server. This has been fixed.

================(Build #3678 - Engineering Case #498395)================

In vary rare circumstances, a Solaris client application may have crashed
when attempting to connect to a server. This would have occurred if the communications
initialization code failed to allocate some memory. This has been fixed.
The client connect request will now receive a -86 "Client out of memory"
error in these instances.

================(Build #3661 - Engineering Case #500123)================

An embedded SQL application may have hung if all of the following conditions
were true:
- the applicaiton had registered a DB_CALLBACK_CONN_DROPPED callback using
db_register_a_callback()
- the application called db_fini to free the resources associated with a
sqlca.
- there was a least one active connection associated the sqlca (i.e. there
was a connection that had not been disconnected)
This was more likely to occur on a Unix system (including Linux and Mac
OSX), than on Windows systems. This has been fixed.

A work-around is to ensure that all connections are disconnected prior to
calling db_fini();

================(Build #3579 - Engineering Case #483533)================

If the LOGFILE connection parameter was specified, when connecting to either
a personal or network server without specifying a server name, the line "Connected
to the default personal server" was logged. This was inaccurate, and possibly
confusing. The text of this message has now been changed to "Connected to
the default SharedMemory server."

================(Build #3498 - Engineering Case #468897)================

If an embedded SQL application allocated a SQLCA, some of the contents of
the allocated SQLCA could have been left uninitialized after calling db_init.
It was also possible, although likely rare, that a call to sqlerror_message
using an allocated SQLCA could have caused the application to crash. Using
the sqlca pointer included in DBLib did not have this problem. This has been
fixed so that the allocated SQLCA is now properly initialized as part of
db_init, and calls to sqlerror_message will not cause a crash.

A workaround is to zero out the allocated SQLCA memory after allocating
it and before calling db_init. The allocated SQLCA (say app_sqlca) can be
zeroed out using:
memset( app_sqlca, 0, sizeof( SQLCA ) )

================(Build #3484 - Engineering Case #466442)================

The changes for Engineering case 449577 introduced a problem with the Developer
and Evaluation Editions. When run on Unix systems, the server could not be
autostarted, and therefore utilities that auto-start servers, such as dbinit
or dbunload, would have failed. On Linux systems, the server would have started
to the point where the GUI splash screen / license prompt was brought up.
This has been fixed.

================(Build #3472 - Engineering Case #463748)================

On Unix systems, attempting to connection without including a UserID in the
connection string would have failed with the error "User ID '???' does not
exist". This has been fixed to give the error "Invalid user ID or password".

================(Build #3462 - Engineering Case #461990)================

When unloading the DBLIB client library, or the ODBC or OLEDB drivers on
Windows Vista, could have caused the client application to crash. This problem
has been fixed.

================(Build #3419 - Engineering Case #449577)================

On Unix systems, an auto-started server that had shut down would have remained
a zombie until the parent process exited. This has been fixed by doing a
double fork when spawning the server, in order to ensure all parent-child
relationships are erased when it is shutdown.

================(Build #3409 - Engineering Case #448405)================

Auto-starting a database with a connection string that contained the CharSet
connection parameter, whose value differed from the OS charset, could have
failed. This would have ocurred when a value for the EngineName, DatabaseName,
or DatabaseFile parameters did not consist of ASCII characters. If it did
succeed, the name of the auto-started server would have been mangled, and
connections to it using a connection string that lacked the CharSet parameter,
or that had a different value for this parameter, would have subsequently
failed.

Note, this problem affected all connections using the iAnywhere JDBC driver,
regardless of whether or not the CharSet connection parameter was explicitly
specified. This also affected the Java Tools, and actions like, for instance,
creating a database from Sybase Central that had a non-ASCII, non-UTF-8 name.

This has been fixed.

================(Build #3371 - Engineering Case #441275)================

Attempting to make a connection to the database server at midnight, could
have resulted in the error "Connection error: Found server but communication
error occurred". The client software did not handle a date roll-over if a
timeout was specified. This has been fixed.

================(Build #3348 - Engineering Case #437815)================

A client application would have crashed when a connection attempt was made
using a connect string that used the hash char '#' in place of the equal
sign '=' for the CommLinks option VerifyServerName (e.g. "Verify#No"). This
has been fixed.

================(Build #3338 - Engineering Case #436194)================

Attempting to autostart a server and database would fail if the DatabaseFile
(DBF) parameter contained both apostrophes (single quotes) and spaces. This
has been fixed.

Note, that apostrophes in database file names are not supported by CREATE
DATABASE and other tools, so using apostrophes in database file names is
not recommended.

================(Build #3299 - Engineering Case #429262)================

If an ODBC application called SQLSetConnectAttr() to set the isolation level
while there were concurrent requests using the same connection on other threads,
the application could have hung, crashed, or the call could have failed with
an error. This problem does not occur on Windows systems when using the
Microsoft ODBC Driver Manager. This problem has been fixed.

Note, similar problems with SQLConnect, SQLBrowseConnect, SQLDriverConnect,
SQLAllocStmt/SQLAllocHandle and SQLFreeStmt/SQLFreeHandle have also been
corrected.

================(Build #3272 - Engineering Case #422996)================

Embedded SQL applications running on Unix or NetWare systems would not have
had the DB_CALLBACK_CONN_DROPPED callback function called when the server
was about to drop a connection. This has now been fixed.

================(Build #3255 - Engineering Case #419414)================

If a nested transaction was started with a BEGIN TRANSACTION statement, and
two or more COMMITs were done one after the other to commit the nested transaction,
the transaction may not have been committed. This has been fixed so that
the transaction is now committed.

================(Build #3189 - Engineering Case #403762)================

If an Embedded SQL application called the function sqlerror_message(), without
first calling the function db_init(), the application could have crashed.
Without first calling db_init(), sqlerror_message() would use a NULL cmdseq_env.langstring.
This has been fixed so that now the message "DBLib not initialized: error <SQLCODE>"
is returned.

================(Build #3143 - Engineering Case #395662)================

An Embedded SQL or ODBC application, which used wide fetches or ODBC multi-row
rowset fetches on a cursor which had prefetched enabled, could have returned
a row with invalid data or data from a previous row when an error should
have been returned instead. An example of a row error which could have caused
this type of behaviour is the "Subquery cannot return more than one row"
error. Also, for Embedded SQL applications, SQLCOUNT was not being set correctly
to the number of rows fetched on an error. These problems have been fixed
so that the error is correctly returned, and SQLCOUNT is set correctly on
errors.

================(Build #3128 - Engineering Case #391747)================

If a connection string contained the START= parameter with a value that ended
with "-x",
"-xs" or "-ec", and was immediately followed by the -x, -xs or -ec parameter
with at least two options, then the string would not have parsed properly
and the application would have failed with a SQLCODE -95 error. This is most
likely to happen with dbspawn, which converts the server command to a START=
parameter.

For example:
dbspawn dbeng9 -n myserver -o output-file-x -x tcpip(port=1234;timeout=3)

This has been fixed.

================(Build #3096 - Engineering Case #382507)================

When using TLS encryption, the client software would go through the list
of trusted root certificates provided and would fail with a handshake error
if any of the certificates had expired. This behaviour was incorrect. Now,
clients will ignore expired root certificates when reading them, and will
only report an error during the SSL/TLS handshake if no valid root certificates
were found to match the server.

================(Build #2551 - Engineering Case #375971)================

An application could have hung, received a communication error, or have possibly
seen other incorrect behaviour, when doing a fetch with prefetch enabled,
and then immediately doing a commit, rollback, or another fetch with an absolute
or negative offset. It was rare on multiprocessor machines, and would have
been even rarer on single processor machines. As well, there may have been
other timing dependent cases which could have failed. This has been fixed.

================(Build #2543 - Engineering Case #374874)================

When using a cursor for which prefetch could be enabled, the fetch performance
of many rows may have been slower than expected. In order for this problem
to have occurred, the bound size, or described size, of the columns would
have to have been fairly small (less than 50 bytes), and the number of rows
prefetched must have been reduced by the maximum memory used for buffering
prefetch data (see the PrefetchBuffer connection parameter). This has now
been fixed.

================(Build #2537 - Engineering Case #373482)================

If a connection string included the TCP parameter VerifyServerName=NO, and
contained an incorrect server name, the connection would have failed, essentially,
the VerifyServerName parameter was ignored. This has been fixed.

================(Build #2537 - Engineering Case #373480)================

If a server was started with a server name containing non-7-bit ASCII characters,
and the client machine's character set did not match the server machine's
character set, applications may not have been able to connect when specifying
the server name, (ie ENG parameter). This has been fixed.

================(Build #2533 - Engineering Case #372175)================

The server could have leaked memory, eventually resulting in an 'Out of Memory'
error. This could have occurred while executing INSERT or LOAD TABLE statements
for tables which the server maintains statistics. This has been fixed

Adaptive Server Anywhere - JDBC Client Library

================(Build #3863 - Engineering Case #580599)================

The SQL Anywhere JDBC driver getTimeDateFunctions() call did not return the
correct names for the CURRENT_DATE, CURRENT_TIME, and CURRENT_TIMESTAMP functions.
It returned "current date,current time,current timestamp" instead of "current_date,current_time,current_timestamp".
The same problem also existed in the iAnywhere JDBC driver. These problems
have now been fixed.

================(Build #3863 - Engineering Case #578990)================

If an application called DatabaseMetaData.getSystemFunctions(), the string
returned would have contained the functions named dbname and username. The
correct function names are database and user. This problem has now been fixed.

================(Build #3803 - Engineering Case #563736)================

If an ODBC DSN explicitly specified an isolation level, and that DSN was
then used within the Interactive SQL utility (dbisql), then the isolation
level specification would have been ignored. This problem has been fixed.

================(Build #3782 - Engineering Case #556757)================

If a JDBC application called ResultSetMetaData.getColumnTypeName() with an
invalid column index, then the application may have crashed. This problem
has been fixed.

================(Build #3766 - Engineering Case #552888)================

If an application called PreparedStatement.setBlob(), and if the underlying
java.sql.Blob implementation misbehaved, then there was a chance that the
iAnywhere JDBC driver would have failed when the PreparedStatement was executed.
Workarounds have now been implemented in the iAnywhere JDBC driver to attempt
to handle the Blob implementation misbehaviour.

================(Build #3764 - Engineering Case #552314)================

If an application called the ResultSet.getBlob() method, and if fetching
the blob should have thrown a valid SQLException, then quite often the exception
would not have been thrown and an empty blob would have instead been returned
to the client. This problem has now been fixed.

================(Build #3762 - Engineering Case #551978)================

If an application called ResultSet.getString() on a uniqueidentifier column,
the iAnywhere JDBC driver would have incorrectly returned a string of binary
bytes. This problem has now been fixed and the iAnywhere JDBC driver now
returns a properly formatted GUID string.

================(Build #3750 - Engineering Case #549218)================

If an application creates a scrollable statement and then scrolls through
the result set, calling ResultSet.getRow() will return the correct row number
for all rows. Calling ResultSet.getRow() will also return the correct row
number when the end of the result set is reached. However, if the application
called ResultSet.isLast() while positioned on the last row of the result
set and then called ResultSet.getRow(), the row number returned would have
been "invalid" or "unknown". This problem has now been fixed.

Note that calling ResultSet.getRow() after calling ResultSet.isLast() while
positioned on any row other than the last row would have returned the correct
row number.

================(Build #3747 - Engineering Case #548322)================

If an application calls PreparedStatement.executeBatch(), the iAnywhere JDBC
driver is supposed to return an integer array that contains a status for
each row in the batch. The iAnywhere JDBC driver was instead returning an
integer array containing only two elements. This problem has now been fixed.

================(Build #3710 - Engineering Case #536921)================

Applications using the iAnywhere JDBC driver, could have crashed or hung
if a process ran out of memory. This has been fixed so that it will now either
fail gracefully, or cause an assertion with an appropriate error message,
depending on the circumstances.

================(Build #3705 - Engineering Case #538904)================

If an application using the iAnywhere JDBC driver called the method ResultSet.isLast()
when the result set was positioned on the last row, the call would have correctly
returned a value of 'True', but the result set position would have been move
to be after the last row. The problem has now been fixed.
Note, this problem does not occur if the result set is not positioned on
the last row.

================(Build #3681 - Engineering Case #533604)================

If a multi-threaded JDBC application generated a ResultSet object on one
thread, at about the same time that the underlying Statement object was closed
on another thread, then the application may in very rare cases have crashed,
if that ResultSet object was subsequently closed. The same problem could
have occurred if the ResultSet object was generated at about the same time
that the underlying Connection object was closed. This problem has now been
fixed.

================(Build #3679 - Engineering Case #532802)================

Closing a ResultSet object may have, in very rare cases, crashed the iAnywhere
JDBC driver. This problem has now been fixed.

================(Build #3675 - Engineering Case #531962)================

If an application attempted to use a Statement, PreparedStatement or ResultSet
object at the same time that the underlying Connection object was closed
on a different thread, then there was a chance the application would have
crashed.The problem has now been fixed.
Note that finalizing Connection objects can cause the same crash.

================(Build #3675 - Engineering Case #531718)================

If an application using the iAnywhere JDBC driver attempted to perform a
batched insert (using addBatch()/executeBatch()) and the batch size was large
(greater than 500), then performance of the batch insert would have degraded
significantly when long string columns were involved in the batch. The driver
was allocating more memory than necessary, and making several small allocations
instead of a few large ones. This problem has now been corrected.

================(Build #3671 - Engineering Case #530594)================

Closing a ResultSet object may, in very rare cases, crash the iAnywhere JDBC
driver. This problem has now been fixed.

================(Build #3653 - Engineering Case #498183)================

In very rare circumstances, the iAnywhere JDBC driver may have crashed when
a connection was being closed. This problem has now been fixed.

================(Build #3647 - Engineering Case #496899)================

An application using the iAnywhere JDBC driver would have leaked memory when
executing statements that returned multiple result sets. Executing statements
that return a single result set will not be affected by this problem. The
driver was failing to implicitly close pending result sets for statements
that returned multiple result sets. This has now been fixed.

================(Build #3647 - Engineering Case #496897)================

An application using the iAnywhere JDBC driver would have leaked memory when
making multiple DatabaseMetaData calls. The driver was not releasing references
to Java strings. This problem has been fixed.

================(Build #3645 - Engineering Case #496438)================

An application using the iAnywhere JDBC driver, that had many threads that
were opening and closing connections or statements, may have crashed during
garbage collection. This problem has now been fixed.

================(Build #3640 - Engineering Case #482591)================

If an application using the iAnywhere JDBC driver had multiple threads trying
to create connections, or create statements/prepared statements/callable
statements at the same time, then there was a chance the JDBC driver could
have crashed. The crashes were actually in the Java VM, and work arounds
have now been implemented.

================(Build #3630 - Engineering Case #492533)================

In very rare, timing-related circumstances, calling a Java procedure, or
making a request than references a remote JDBC clase server, may have failed
with the error "No suitable driver", if a cancel had been received. When
this happened, all JVM's, or the database, would have had to have been restarted
to resolve the problem. This has been fixed.

================(Build #3564 - Engineering Case #481450)================

On Unix systems, if a client application left TCPip connections open when
dblib, or the ODBC driver, was unloaded (for instance, at application shutdown
time), the application may have crashed. There was a higher chance of seeing
this on multi-processor machines. This has been fixed.

================(Build #3561 - Engineering Case #481235)================

The iAnywhere JDBC driver could have incorrectly given conversion errors
when fetching numeric data. For the problem to have occurred, the numeric
column had to follow a long char or varchar, or a long binary or long varbinary
column in the result set. This problem was not likely to have occurred using
the SQL Anywhere ODBC driver or the DataDirect ODBC drivers, but could have
occurred using the iAywhere Oracle ODBC driver. The problem has now been
fixed.

================(Build #3559 - Engineering Case #480937)================

If an application using the iAnywhere JDBC Driver fetched an unsigned tinyint
value in the range of 128 to 255, then the JDBC driver would have incorrectly
thrown an overflow exception. This problem has been fixed by having the JDBC
driver promote unsigned tinyint values to smallint.

================(Build #3559 - Engineering Case #480204)================

If an application called the methods ResultSet.getTime(), ResultSet.getDate()
or ResultSet.getTimestamp() using a java.util.Calendar object, then the iAnywhere
JDBC driver would have returned the wrong result. This problem has now been
fixed.

================(Build #3544 - Engineering Case #477892)================

If an application was using the iAnywhere JDBC driver and called ResultSet.getBlob().getBytes()
on a char, varchar or binary column that had an empty value in it, then the
driver would have incorrectly returned null, instead of returning a 0-length
byte [] value. This problem did not occur for empty long varchar or long
binary columns. This problem has now been fixed.

================(Build #3513 - Engineering Case #471575)================

If an application used the iAnywhere JDBC Driver to connect to a DB2 server,
and attempted to use PreparedStatement.setBoolean(), the JDBC driver would
have thrown an exception. Calling PreparedStatement.setBoolean() resulted
in the driver binding a parameter of type SQL_BIT, even though DB2 does not
support SQL_BIT. This has been fixed so that a parameter of type SQL_TINYINT
is now used for DB2.

================(Build #3485 - Engineering Case #466700)================

When using the IBM DB2 ODBC driver with the iAnywhere JDBC driver to try
to fetch rows from a result set, the iAnywhere JDBC driver would have have
crashed if the result set had a CLOB column. This has now been fixed.

================(Build #3480 - Engineering Case #464442)================

The iAnywhere JDBC Driver could have leaked memory, and exhausted memory
heaps, if an application causes many SQLWarnings to be generated. This problem
has now been fixed.

================(Build #3457 - Engineering Case #461027)================

If an application, connected using the iAnywhere JDBC driver, started a request
and then attempted to close the connection on a separate thread, it was very
likely that the application would have crashed. This problem was most easily
reproduced in Sybase Central when a profiling session was cancelled, and
an attempts was made to go back to design mode. The problem has now been
fixed.

================(Build #3447 - Engineering Case #455814)================

If an application connected using the iAnywhere JDBC Driver, prepared a callable
statement, set the value of a parameter, registered the same parameter as
output, and executes the statement, the output value of the INOUT parameter
would not always have been correct. In some cases, the output value of the
parameter would have incorrectly been set to the input value of the same
parameter (i.e. the value would have remained unchanged after the callable
statement was executed). This problem has now been fixed.

================(Build #3443 - Engineering Case #454890)================

If an application using the iAnywhere JDBC driver attempted to cancel a long
running statement, it was possible that it could have crashed. This has now
been fixed.

================(Build #3428 - Engineering Case #452110)================

If an application used the iAnywhere JDBC driver to connect to an Oracle
database with a multi-byte charset using the DataDirect Oracle 5.1 ODBC driver,
and then attempted to fetch a long varchar column that had multi-byte data,
there was a chance that the fetch would have failed with a conversion or
translation error. This problem is actually a bug in the DataDirect Oracle
5.1 ODBC driver but a workaround has now been implemented in the iAnywhere
JDBC driver.

================(Build #3424 - Engineering Case #451486)================

If an application using the iAnywhere JDBC driver fetched a result set with
more than one column, and one of the columns was a blob column, then calling
ResultSet.wasNull() after calling ResultSet.getBlob() would not always have
indicated the correct 'nullness' of the the blob value that was just fetched.
The driver was not properly setting the null bit for blob columns, so calling
ResultSet.wasNull() after fetching a blob column would have actually returned
the null bit of the previous column fetched. This problem has been fixed.

================(Build #3404 - Engineering Case #447345)================

If an application using the iAnywhere JDBC driver executed a statement, or
prepared statement, that returned several tens of thousands of asynchronous
messages to the client (i.e. calling a stored procedure that executes many
MESSAGE ...TO CLIENT statements), then there it was very likely that the
Java VM would either run out of memory or crash. If however, the stored procedure
returned only a few messages per execution, calling the stored procedure
tens of thousands of times would not have been a problem. This is now fixed.

Note, that for this problem to occur, the application must install an asynchronous
message handler. the Interactive SQL utility is one such application.

This problem has now been fixed.

================(Build #3393 - Engineering Case #445062)================

Typically, ResultSet.getBlob() is used to retrieve columns of type long binary,
however, there is no reason an application cannot use the getBlob() method
to retrieve a column of type VARBINARY or BINARY. Unfortunately, getBlob()
did not work properly for columns of type VARBINARY or BINARY. This problem
has now been fixed.

================(Build #3360 - Engineering Case #439713)================

If an application called ResultSet.close(), and the underlying ODBC driver
threw an error when closing the result set, then the iAnywhere JDBC Driver
would have thrown a JNI exception complaining about making a JNI call with
a pending exception. This problem has now fixed by ignoring the error from
SQLFreeStmt.

================(Build #3349 - Engineering Case #438119)================

If a connection was made from Sybase Central to a SQL Anywhere server, using
the iAnywhere JDBC Driver, and then a subsequent connection attempt was made
to an ASE server within the same Sybase Central session using the ASE plug-in
and jConnect, the connection to ASE would have failed. This problem has been
fixed.

================(Build #3278 - Engineering Case #424091)================

It was possible for the iAnywhere JDBC Driver to have crashed, or to hang,
when creating or preparing a statement. While rare, this was more likely
when under a heavy load. This problem has been fixed.

================(Build #3278 - Engineering Case #424090)================

When DatabaseMetaData.getColumns() was called on a table that contained a
uniqueidentifier column, the datatype returned for the uniqueidentifier column
was -11 (i.e. SQL_GUID). If the application then useed -11 as the datatype
value in a setNull or setObject call, the iAnywhere JDBC Driver would have
returned an invalid datatype error. This problem has now been resolved and
-11 is now accepted for setNull and setObject.

================(Build #3255 - Engineering Case #419284)================

The iAnywhere JDBC Driver can be used to fetch blobs from a server, but if
the underlying ODBC driver returned an unexpected error code when fetching
the blob, then the JDBC driver may have crashed or run out of memory. Note
that this problem was more likely to occur with ODBC drivers for servers
other than SA. This has been fixed by having the JDBC driver throw a SQL
Exception when the ODBC driver returns an unexpected error.

================(Build #3245 - Engineering Case #417130)================

The fix for Engineering Case 416089 exposed a bug in the iAnywhere JDBC driver
which caused the Interactive SQL utility, and other applications, to crash
when fetching result sets. Note that this problem only happened with 64-bit
clients. This problem has been fixed.

================(Build #3211 - Engineering Case #407672)================

The changes for Engineering Case 404072 resolved a memory leak in the iAnywhere
JDBC driver, but revealed a problem with synchronizing the release of resources
within the native portion of the iAnywhere JDBC driver and the VM's garbage
collector. We had to ensure that resources were not being released while
the garbage collector was running. The issue with synchronizing the VM's
garbage collector has now been resolved.

================(Build #3190 - Engineering Case #404072)================

If an application relied on the garbage collector to clean up ResultSet and
(Prepared) Statement objects rather than explicitly closing these objects,
then the iAnywhere JDBC driver would have leaked memory. It should be noted
though that explicitly closing either the ResultSet object or the (Prepared)
Statement object was enough to avoid the memory leakage. This problem has
now been fixed.

================(Build #3190 - Engineering Case #401809)================

If an application prepared an INSERT statement to be used within a batch
and then switched datatypes when setting different row values of a particular
column, the iAnywhere JDBC driver could have inserted incorrect values. The
driver now throws a SQL exception when the datatype is switched.

An example of the incorrect JAVA code follows:

PreparedStatement stmt = con.prepareStatement( "INSERT INTO t VALUES(?,
?)" );
stmt.setInt(1, 100);
stmt.setString(2, "row 1");
stmt.addBatch();
BigDecimal bd = new BigDecimal(200);
stmt.setBigDecimal(1, bd); // notice the switch in datatype when setting
the variable value
stmt.setString(2, "row 2");
stmt.addBatch();
stmt.execute();

The above code would have inserted incorrect data for the second row in
the batch, but will now throw an execption when the application performs
the stmt.setBigDecimal() call.

Note that switching datatypes is perfectly acceptible during different executions
of a batch. So, the following code will not generate an exception and will
insert correct data:

PreparedStatement stmt = con.prepareStatement( "INSERT INTO t VALUES(?,
?)" );
stmt.setInt(1, 100);
stmt.setString(2, "row 1");
stmt.addBatch();
stmt.setInt(2, 200);
stmt.setString(2, "row 2");
stmt.addBatch();
stmt.execute(); // notice the execution of the first batch
BigDecimal bd = new BigDecimal(300);
stmt.setBigDecimal(1, bd); // notice the switch in datatype when setting
the variable value
stmt.setString(2, "row 3");
stmt.addBatch();
stmt.execute();

================(Build #3189 - Engineering Case #403518)================

If an application used the setString() method to set up a number of string
values for a batch insert, and the strings varied widely in size, then it
was possible that the call to addBatch() would have crashed the iAnywhere
JDBC driver. The driver was setting up the string array for the wide insert
incorrectly when a new string was larger than the standard element size.
The string array is now adjusted correctly.

================(Build #3185 - Engineering Case #403315)================

The changes for Engineering case 385659 accidentally removed the IPreparedStatement.setBatchStringSize
method. This method has now been added back.

================(Build #3157 - Engineering Case #398062)================

If an application used the PreparedStatement.addBatch() method to perform
a wide insert, and set some of the columns in the insert to NULL, the addBatch()
may have failed with a "Not Yet Implemented" error. The new addBatch code
was not properly checking the NULL indicator prior to attempting to setup
the next row in the batch. This has now been fixed.

================(Build #3157 - Engineering Case #396873)================

Changes for Engineering Case 392484 ensured that data exceptions that occurred
during a wide fetch were not lost, but the changes introducing an error such
that warnings were lost instead. This has been corrected so that both data
exceptions and warnings are properly reported to the client.

================(Build #3140 - Engineering Case #394722)================

If an application retrieved the ResultSetMetaData and then queried the datatype
of an unsigned smallint, unsigned int or unsigned bigint column, the datatype
returned would have been incorrect. This problem has now been fixed so that
an application can properly determine the unsigned column type using the
ResultSet.getColumnType() and ResultSet.isSigned() methods.

================(Build #3139 - Engineering Case #393604)================

If an application used ResultSet.relative(0) to attempt to refresh a row,
then the iAnywhere JDBC Driver would usually have given an "Invalid cursor
position" or a "Not on row" error. It should be noted that the "Invalid cursor
position" error is valid since that error is usually given by the underlying
ODBC driver when the Statement or PreparedStatement that generated the ResultSet
is of type TYPE_FORWARD_ONLY. However, when the Statement or PreparedStatment
is scrollable, then the iAnywhere JDBC Driver should refresh the row rather
than give the "Not on row" error. This problem has been fixed.

================(Build #3125 - Engineering Case #385659)================

If an application relied on the Java VM's garbage collector to close Statement,
PreparedStatement or CallableStatement objects, rather than explicitly closing
these objects, the server could have eventually failed with a "resource governor
exceeded" error. The garbage collector was being prevented from closing these
objects. This problem has been fixed and these objects now properly get garbage
collected.

================(Build #3119 - Engineering Case #388573)================

If a result set had a DECIMAL column with a value that has more than 10 digits,
but less than 19 digits, and was an integer, then calling ResultSet.getLong()
should have returned the entire value but did not. This problem has been
fixed.

================(Build #3119 - Engineering Case #387869)================

When executing a batch using the PreparedStatement object, it is proper practice
to use the PreparedStatement.executeUpdate() method to execute the batch
and retrieve the single update count associated with it. However, applications
sometimes (incorrectly) use the PreparedStatement.executeBatch() method instead.
The iAnywhere JDBC driver has now been modified to support the PreparedStatement.executeBatch()
method in this manner.

================(Build #3022 - Engineering Case #377885)================

If an application used the PreparedStatement.setTimestamp() method to set
a timestamp parameter, then the millisecond portion of the timestamp would
not have been set. This problem has been fixed.

================(Build #2543 - Engineering Case #374840)================

Calling the Connection.getCatalog() method, when using the iAnywhere JDBC
Driver, would have yielded a string with extra characters. Note that this
problem only existed if the JDBC Driver was used to connect to a server other
than an ASA server. The problem has been fixed.

================(Build #2543 - Engineering Case #374727)================

When using the iAnywhere JDBC Driver to connect to a DB2 database using the
IBM DB2 ODBC driver, and the method ResultSet.getObject() was used on a BLOB
column, the iAnywhere JDBC Driver would have failed with the error "Failed
to map result on column ? to a Java class" where ? is the column number.
This problem has been fixed.

================(Build #2543 - Engineering Case #374714)================

Executing a statement using Interactive SQL that sends messages back to the
client (ex. ALTER DATABASE UPGRADE, or CREATE DATABASE, or MESSAGE ... TO
CLIENT), could have caused Interactive SQL to crash, if the connection was
via the iAnywhere JDBC driver. This has now been fixed.

While the problem exists on all platforms, the crash has only been seen
on AIX systems.

================(Build #2541 - Engineering Case #374451)================

An application using the iAnywhere JDBC Driver would have leaked memory if
it called Connection.getMetaData() repeatedly. This problem has been fixed.

================(Build #2535 - Engineering Case #373086)================

If a JDBC cursor was positioned on a row with a LONG VARCHAR column, then
calling ResultSet.getString() on the column would have returned the proper
value for the first call, but each subsequent call would have returned NULL
if the cursor had not been repositioned. This problem has now been fixed.

Adaptive Server Anywhere - ODBC Client Library

================(Build #3884 - Engineering Case #587036)================

If a LONG VARCHAR column containing multi-byte data was fetched by the OLE
DB provider, the resulting string may have contained appended null characters.
As a result, the Length attribute of the string (e.g., strTxt.Length) may
have been larger than expected. This problem has been fixed.

================(Build #3865 - Engineering Case #581793)================

If a SQL_NUMERIC or SQL_DECIMAL value had a precision sufficiently greater
than the bound precision, then an internal buffer would have been overrun.
For example, if a bound column was defined as DECIMAL(10,2), and the precision
described by the input SQL_NUMERIC_STRUCT parameter value was 40, then an
internal buffer would have been overrun. This problem has been fixed.

================(Build #3857 - Engineering Case #579816)================

A new connection parameter has been added to the ODBC driver. This parameter
(ESCAPE) allows you to specify the escape character used in the LIKE clause
of SQL statements generated by the ODBC driver when returning a list of tables
or columns.

By default the ODBC driver uses the tilde character (~), but some applications
do not properly query the ODBC driver to see what escape character is used,
and assume that it is the backslash character (\). With this new connection
parameter, users can specify the escape character in the connection string
to make these applications work properly.

"DSN=My Datasource;UID=xxx;PWD=xxx;ESCAPE=\;ENG=myserver"

================(Build #3807 - Engineering Case #565110)================

When binding a column in ODBC, the column type, a buffer and a length are
specified. For static types (int, long, double, time, etc) the ODBC driver
ignores the length specified because the length is constant. The ODBC driver
should have been treating SQL_GUID columns as static as well, but was incorrectly
respecting the length specified, which sometimes resulted in truncated values.
This has been fixed.

================(Build #3803 - Engineering Case #563848)================

If an ODBC application called SQLColAttribute() on a long varchar, long nvarchar
or long binary column, with an attribute value of SQL_DESC_DISPLAY_SIZE,
then the ODBC driver would have incorrectly returned the value 65535. This
problem has been fixed and the driver now returns the value 2147483647.

================(Build #3789 - Engineering Case #551956)================

When the TargetType parameter to the ODBC function SQLGetData() is SQL_C_DEFAULT,
the driver selects the default C data type based on the SQL data type of
the source.

For NCHAR types, the Microsoft ODBC driver selects a SQL_C_CHAR binding.
Microsoft acknowledges in its knowledgebase article http://support.microsoft.com/default.aspx/kb/293659
that to do so is an error, but states that it does this to support older
legacy applications. The SQL Anywhere ODBC driver selected a SQL_C_WCHAR
binding. This caused problems with applications like Microsoft Access, that
expected the Microsoft ODBC behaviour. This problem in Access could have
been seen when setting up a linked table using the SQL Anywhere ODC driver
to a database table containing NCHAR, NVARCHAR, or LONG NVARCHAR column types.
The resulting table columns were displayed with "#deleted" values. To conform
to the Microsoft ODBC driver behaviour, the SQL Anywhere ODBC driver has
been changed. Now, the SQL Anywhere ODBC driver selects a SQL_C_CHAR binding
for NCHAR, NVARCHAR, and LONG NVARCHAR (including NTEXT) types when the "MS
Applications ( Keys In SQLStatistics)" checkbox is selected in the ODBC Administrator
configuration dialog for SQL Anywhere datasources. This option can also be
specified as the connection parameter "KeysInSQLStatistics=YES" in a SQL
Anywhere ODBC driver connection string. This change affects any ODBC function,
like SQLBindCol, SQLBindParameter, and SQLGetData, where SQL_C_DEFAULT can
be specified.

================(Build #3786 - Engineering Case #557955)================

Calls the function SQLGetInfo() would have incorrectly returned SQL_CB_NULL
for SQL_CONCAT_NULL_BEHAVIOR. As the result of the server concatenating a
string and NULL is the string, calls to SQLGetInfo() have now been corrected
to return SQL_CB_NON_NULL for SQL_CONCAT_NULL_BEHAVIOR.

================(Build #3785 - Engineering Case #555059)================

When using Microsoft's AppVerifier (a development/debugging tool), the tool
may have reported various errors, such as the use of an invalid handle in
client libraries (ODBC, dblib, etc) or in the database server. These problems
have been fixed and the database server and client libraries now run cleanly
under AppVerifier.

Note, without the use of AppVerifier it would have been extremely rare for
users to encounter these problems.

================(Build #3780 - Engineering Case #555963)================

If an NCHAR, NVARCHAR, or LONG NVARCHAR parameter was bound as SQL_C_DEFAULT,
the binding would have defaulted to SQL_C_CHAR, instead of SQL_C_WCHAR. This
has been corrected.

================(Build #3764 - Engineering Case #552210)================

After selecting the Network tab in the ODBC Administrator (ODBCAD32) for
ASA 9.0.2 data sources, it was not possible to configure RSA_TLS_FIPS. The
RSA_TLS option would have been selected and the suboptions string would have
been garbled. This problem has been fixed.

================(Build #3697 - Engineering Case #534949)================

The iAS ODBC driver for Oracle would have truncated the time portion of timestamp
values, when the application was trying to fetch the timestamp values using
SQLGetData. An internal buffer was too small for a timestamp column. This
has been fixed.

================(Build #3650 - Engineering Case #497256)================

When calling the ODBC function SQLGetInfo(), the driver will return an indication
that conversion from SQL_VARCHAR to SQL_WVARCHAR is possible using the ODBC
CONVERT function.
For example:
rc = SQLGetInfo(hdbc, SQL_CONVERT_VARCHAR, (SQLPOINTER)&bitmask, sizeof(bitmask),
NULL);
This will return with the SQL_CVT_WVARCHAR bit set in bitmask which indicates
that the conversion is possible. However, attempting to do the conversion
will return an error. This is illustrated by the preparing the following
statement for execution:
SELECT {fn CONVERT(Surname,SQL_WVARCHAR)} FROM Employees
The error is "[42000][Sybase][ODBC Driver]Syntax error or access violation".
This problem has been fixed. Support has been added for conversion to types
SQL_WCHAR, SQL_WLONGVARCHAR, SQL_WVARCHAR, and SQL_GUID.

================(Build #3643 - Engineering Case #492780)================

When an ODBC datasource was modified on Windows, the permission settings
on the registry key were modified. This has been corrected.

================(Build #3608 - Engineering Case #488520)================

On Unix systems, 64-bit ODBC applications required LONG_IS_64BITS to be defined
at compilation time. Failure to do this would most likely have resulted in
a crash in the application. This has been fixed

================(Build #3593 - Engineering Case #487008)================

The changes made for Engineering case 484553 incorrectly had the PWD value
replaced with all asterisks "*" in the OutConnectionString parameter of the
SQLDriverConnect() function. This has been corrected.

================(Build #3542 - Engineering Case #477526)================

Applications running on HP-UX and using the iAnywhere ODBC Driver Manager,
may have had connection attempts fail if the connection string contained
non-ASCII characters. This would have been true for the MobiLink server,
Remote Data Access connections and applications using the iAnywhere JDBC
driver. This has been fixed.

================(Build #3534 - Engineering Case #475624)================

When using a multi-threaded ODBC application with distributed transactions,
attempting to enlist a DTC transactions could have failed in some cases.
This problem has now been fixed.

================(Build #3527 - Engineering Case #473833)================

If an ODBC application bound a procedure's INOUT parameter as input-only,
a communication error may have occurred. Calling SQLBindParameter( ...,
SQL_PARAM_INPUT, SQL_C_WCHAR,... ) would bind an input-only parameter. This
has been fixed.

================(Build #3521 - Engineering Case #473206)================

On UNIX platforms, linking applications directly against the iAnywhere ODBC
driver without using a driver manager is supported. When an application was
linked in this way, the FileDSN connection parameter would have been ignored
by the ODBC driver. This has been fixed.

As a workaround, a driver manager such, as unixODBC, can be installed, or
the ODBCINI environment variable can be set to point to the DSN file in question.
The second work around would require the FileDSN parameter to be changed
to DSN.

================(Build #3509 - Engineering Case #469411)================

Calls to the ODBC function SQLNativeSql() could have caused a crash in the
ODBC driver. If the character set of the database was UTF8, a crash could
have occurred or incorrect results could have been returned. This problem
has been fixed.

================(Build #3468 - Engineering Case #462915)================

The ODBC PrefetchOnOpen optimization was disabled for queries which had input
parameters. The PrefetchOnOpen optimization is disabled by default, and
is enabled with the PrefetchOnOpen ODBC connection parameter. This has been
changed so that the optimization is now enabled for queries which have input
parameters if the ODBC PrefetchOnOpen connection parameter is used.

================(Build #3461 - Engineering Case #461574)================

If an application that was connected to the utility database via ODBC, executed
"select @@server" and bound the resulting string as a WCHAR, there was a
chance that the length of the string returned would have been incorrect.
This problem only appeared if the server was running on a mult-byte character
set system and the servername being fetched was a string of multi-byte characters.
The problem has now been fixed.

Note that the problem did not happen if the application connected to a real
database, instead of the utility database.

================(Build #3367 - Engineering Case #440704)================

If the ODBC function SQLBindParameter was called for a SQL_WCHAR with an
odd BufferLength and a NULL StrLen_or_IndPtr value, the driver would have
returned an errror with SQL state "HY090". The problem has been corrected.

================(Build #3366 - Engineering Case #440124)================

The ODBC function SQLBindParameter is used to specify a data buffer address
or offset, and a data length/indicator address or offset. As offsets, these
values are combined with the address specified by SQLSetStmtAttr(SQL_ATTR_PARAM_BIND_OFFSET_PTR)
to produce an actual memory addresses. A change to the SQL Anywhere ODBC
driver to check data buffer alignment failed to combine the offset and address
which when referemnced, resulted in a memory access violation. This problem
has been fixed.

================(Build #3350 - Engineering Case #438265)================

On Unix platforms, if the sum of the lengths of all the keys in the [ODBC
Data Sources] section of .odbc.ini, added to the number of the keys in the
section, equaled one less than some multiple of 100 (i.e., 99, 199, 299,
etc.), calling SQLDataSources may have caused memory corruption. This has
been fixed.

A workaround is to change data source names such that the above condition
is avoided.

================(Build #3348 - Engineering Case #433428)================

Using SQLBindCol to bind to a variable that was not naturally aligned would
have resulted in an error on AIX and Mac OS X (PowerPC) systems, even though
these platforms can handle this situation properly. The 2-byte, 4-byte, and
8-byte alignment requirement has been removed for AIX and Mac OS X platforms.

================(Build #3336 - Engineering Case #435328)================

The ODBC function SQLBindParameter could have incorrectly reported an "Invalid
String or Buffer Length" error if parameters were passed at execution time.
The check that would report this error to the SQLExecute call is now delayed,
ensuring that the error is only reported when it is valid.

================(Build #3331 - Engineering Case #435083)================

Changing the rowset size (SQL_ATTR_ROW_ARRAY_SIZE) from a smaller to a larger
value between calls to SQLFetchScroll, when using bookmarks on 64-bit platforms,
would have caused the application to crash. The driver was not freeing the
bookmark buffer, but was reusing the existing buffer without growing it.
This problem has been fixed.

Note, a similar problem with the SQL Anywhere OLE DB provider on 64-bit
platforms has also been fixed.

================(Build #3305 - Engineering Case #408806)================

When an input parameter was bound to a parameter in a stored procedure, and
the procedure parameter was actually an INOUT parameter, the ODBC driver
would have attempted to update the value after the procedure executed. This
could have lead to a 'data truncated' warning message if the resulting string
did not fit. This has been fixed so the the ODBC driver will no longer attempt
to update the values of INOUT parameters bound as input only.

================(Build #3248 - Engineering Case #416442)================

When running the 64 bit version of the driver, a call to SQLColAttributes
or SQLColAttributesW would have returned invalid datatypes for SQL_COLUMN_TYPE.
The results would have been either -1 or a large number such as 2147482128.
A 32 bit pointer was being returned instead of a 64 bit pointer. This has
been corrected.

================(Build #3246 - Engineering Case #417500)================

When an array of parameters was used as input to an ODBC execute (for example,
to insert more than one row with one SQLExecute), some of the parameter values
could have be sent to the server incorrectly. It was possible for this to
have occurred if CHARACTER or BINARY data was used, and the data size for
a particular column was slightly larger in subsequent rows than previous
rows within a single array of parameters (for example, if the first row in
the array had a value of length 1000, and the second row in the array had
a value of length 1050 for the same column). This has now been fixed so that
the data is correctly sent to the server in this situation.

================(Build #3241 - Engineering Case #416332)================

If a call was made to SQLColAttribute, SQLColAttributeW, SQLGetDescField
or SQLGetDescFieldW ( and the deprecated ODBC 2.0 functions SQLColAttributes
and SQLColAttributesW) with a NULL pointer value, no error would have been
reported and the function would have returned SQL_SUCCESS. This is illustrated
by the following code fragment:

SQLRETURN res = SQLColAttribute(hstmt, SQLUSMALLINT(i), SQL_DESC_COLUMN_TYPE,
0, 0, 0, 0);
switch ( res ) {
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
break;
default:
ODBC_error(henv,hdbc,hstmt);
break;
}

This problem has been fixed.

================(Build #3235 - Engineering Case #415897)================

On HP-UX, a non-threaded ODBC application using the ODBC driver could have
hung, or crashed at start-up, if the application was linked against a third
library that was in turn linked against the libpthread library. This has
been fixed by changing the method for detecting the threading model.

================(Build #3207 - Engineering Case #407012)================

The following ODBC driver problems have been fixed:

1) Fetching multiple rows into a bound WCHAR column, which was too small
for the column (thus truncating the data), could have copied the data into
the wrong user buffer location. Data was filled correctly on the first fetch,
but incorrectly on subsequent fetches, likely overrunning memory and possibly
crashing the application.

2) Using SQLGetData to put data into a WCHAR buffer, where the client or
database charset was multibyte, may have caused a subsequent SQLGetData on
the same column to contain incorrect data. Also, indicator values may have
been set incorrectly for SQLGetData or SQLFetch calls to fill WCHAR buffers
when using multibyte character sets.

3) Using SQLGetData to put data into a WCHAR buffer with more than 64K WCHARs
could have returned the wrong indicator, when there is no truncation.

4) Using SQLPutData to put more than 64K of data of ANY TYPE in one SQLPutData
call, may have put incorrect data.

5) Calling SQLPutData with CHAR (not WCHAR) data and SQL_NTS length, only
appended the first 256K of data. Appended data greater than 256K was lost.

6) Calling SQLPutData with WCHAR data and using odd lengths (i.e. partial
characters), may have put incorrect data if the client or database charset
was multibyte.

================(Build #3175 - Engineering Case #401244)================

Calling SQLBindCol() would have returned the error HY090 "Invalid string
or buffer length", when trying to bind a user supplied buffer pointer that
was not aligned to the data type requested on x86 platforms. Starting with
9.0.2, a check was added to the ODBC driver to return this error if a buffer
pointer that was not aligned to the data type was requested This check has
been removed for x86 platforms as x86 allows unaligned memory accesses.

================(Build #3170 - Engineering Case #400466)================

If an ODBC application described a signed bigint column, the precision would
have been returned as 20 when it should really have been 19. This problem
has been fixed.

Note that the precision of unsigned bigint columns is still returned as
20, which is the correct value.

================(Build #3143 - Engineering Case #392484)================

If an application using either the ASA ODBC driver, or the iAnywhere JDBC
driver, fetched a set of rows in which one of the rows encountered a data
exception, then it was likely that the error would not have been reported.
Note that Prefetch must have been on for the problem to occur. This problem
has now been fixed, but in addition to this change, the changes to the server
for Engineering Case 395662 are also required

================(Build #3136 - Engineering Case #393587)================

The ODBC driver was not returning some reserved words for SQLGetInfo( SQL_KEYWORDS
). The mssing reserved words were:

character
dec
options
proc
reference
subtrans

These words are synonyms for other reserved words, and have now been added
to the list returned by SQLGetInfo( SQL_KEYWORDS ).

================(Build #3128 - Engineering Case #390234)================

A call to SQLDriverConnect() can return the completed connection string.
In version 8, the ASA ODBC driver produced the connection string with the
"DSN=" connection parameter first in the string. In version 9, the ODBC driver
produced the connection string such that "DSN=" was not necessarily first.

For example, if the connection string passed to SQLDriverConnect() was "PWD=sql;Userid=dba;DSN=test9"
then in version 8 the connect string "DSN=test9;UID=dba;PWD=sql" was returned,
and in version 9 the connection string "UID=dba;PWD=sql;DSN=test9" was returned.
According to the ODBC specification, the order shouldn't matter, but Gupta
Team Developer 3.1 applications did not handle the version 9 order correctly.
This problem has been resolved by restoring the version 8 behavior where
"DSN=" is placed first in the connect string.

================(Build #2552 - Engineering Case #355595)================

Calling the ODBC function SQLGetData() with a length of 0 would have failed
for SQL_WCHAR.

SQLRETURN SQLGetData(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLINTEGER BufferLength,
SQLINTEGER * IndPtr);

SQLGetData can be used to obtain the amount of data available by passing
0 for the BufferLength argument. The amount of data available is returned
in the location pointed to by IndPtr. If the amount available cannot be determined,
SQL_NO_TOTAL is returned. When the TargetType was SQL_C_WCHAR, the amount
of available data was incorrect (a character count rather than byte count
was returned). This has been fixed.

There were also some problems returning correct indicator values for databases
using the UTF8 collation. This has also been fixed.

================(Build #2532 - Engineering Case #370604)================

In ODBC, changing the option for a cursor's scrollability, could have caused
the driver to change the cursor type as well. For instance if the cursor
type was forward-only, changing the scrollability to scrollable would have
changed the cursor type to dynamic. The problem was that the driver was
always changing the cursor type to dynamic regardless of the existing cursor
type. This has been corrected.

================(Build #2531 - Engineering Case #370905)================

An ODBC application that allocated both an ODBC 2.0 style environment handle
and an ODBC 3.0 style environment handle, could have have returned ODBC 3.0
result codes when functions were called in the ODBC 2,0 environment, or vice
versa. This could have lead to subsequent function calls failing with erroneous
error messages, including 'function sequence error'. Now, the driver will
always allocate a separate environment handle each time SQLAllocEnv or SQLAllocHandle
is called.

Adaptive Server Anywhere - OLEDB Client Library

================(Build #3924 - Engineering Case #611017)================

When the OLE DB provider's GetNextRows method was called, the next row would
not have been read if the previous row had NULL column values. This problem
was introduced by the changes for Engineering case 605058, and has now been
fixed.

================(Build #3916 - Engineering Case #606642)================

If a division by zero error occurred in a result set, the SQL Anywhere OLE
DB provider would have returned DB_S_ENDOFROWSET instead of 0x800a000b (divide
by zero). For example, the following SELECT statement will result in a division
by zero error if the column value for "num" is 3:
SELECT num/(num-3) FROM divisionby0

This problem has been fixed. ADO will now set the correct error number (11)
and description (Division by zero) from the error code returned by OLE DB.

================(Build #3915 - Engineering Case #606229)================

When using the SQL Anywhere OLE DB provider, a memory leak cpuld have occurred
when fetching data LONG VARCHAR or long VARBINARY columns. This problem has
been fixed.

================(Build #3914 - Engineering Case #605803)================

When uploading data into a SQL Anywhere database from Microsoft SQL Server
using the Linked Server mechanism, SQL Server could have reported that it
had received inconsistent metadata information and failed the upload. This
was due to the SQL Anywhere OLE DB provider returning inconsistent column
lengths for VARCHAR and NVARCHAR columns when using the UTF8 character set
collation. For example, an NVARCHAR(100) column length would have been reported
as 400, which is the octet length for this column using the UTF8 collation,
but the "ulColumnSize" field of the DBCOLUMNINFO structure should contain
the maximum length in characters for DBTYPE_STR and DBTYPE_WSTR columns,
not the maximum length in bytes. This problem has been corrected.

================(Build #3914 - Engineering Case #605058)================

If a client-side cursor UPDATE was performed using the SQL Anywhere OLE DB
provider, and the column was of type VARCHAR(n), where n was greater than
or equal to 256 and the column value was originally NULL, then an error message
similar to the following would have been issued by ADO:
Row cannot be located for updating. Some values may have been changed
since it was last read.

The OLE DB provider was failing to return DBSTATUS_S_ISNULL for the column
value and returned an empty string instead. This caused ADO to generate an
UPDATE statement with a WHERE clause expression of the form "column = ?"
and a bound value of '' (a zero-length string). This problem has been fixed.
ADO will now generate an UPDATE statement with a WHERE clause expression
of the form "column IS NULL".

A workaround is to use a server-side cursor.

================(Build #3891 - Engineering Case #590210)================

The SQL Anywhere OLE DB provider implementation of IMultipleResults::GetResult()
returned an incorrect 'rows affected' count for inserts, updates, and deletes.
In this situation, the result returned by OleDbCommand.ExecuteNonQuery(),
which called the GetResult() method, was -1. This problem has now been fixed
to return the correct 'rows affected' count.

================(Build #3843 - Engineering Case #574697)================

If a NUMERIC INOUT parameter was bound as SQL_PARAM_INPUT_OUTPUT, the result
that was returned to the caller was always 0.

For example:
CREATE PROCEDURE _TEST_PROC
(
@IN_VAL1 NUMERIC(7, 0),
@IN_VAL2 NUMERIC(7, 0),
@OUT_VAL NUMERIC(7, 0) OUTPUT
)
AS
BEGIN
SET @OUT_VAL = @IN_VAL1 + @IN_VAL2
END

If the statement "CALL PROCEDURE _TEST_PROC( 100, 200, ? )" was prepared,
and the third parameter was bound as SQL_PARAM_INPUT_OUTPUT, the result after
execution was 0. It should have been 300. If the parameter was bound as SQL_PARAM_OUTPUT,
the result returned was correct.This problem has been fixed.

Note that in the above Transact SQL procedure, OUT_VAL is an INOUT parameter,
since Transact SQL parameters are always INPUT and the addition of the OUTPUT
clause makes them INOUT.

================(Build #3804 - Engineering Case #564435)================

In an ADO/OLE DB application, when a UNIQUEIDENTIFIER (or GUID) was used
as a parameter in a query, an error message like "Cannot convert 0x to a
uniqueidentifier" may have resulted, or the query may simply have failed
to return any results. This problem has been fixed.

Sample schema:
create table uuidtable( pkey int, uuid uniqueidentifier, stringform uniqueidentifierstr
);

Sample query:
select * from uuidtable where uuid = ?

The following .NET/OLE DB example shows typical uniqueidentifier parameter
binding:

OleDbCommand cmd = new OleDbCommand(txtSQLStatement.Text.Trim(), _conn);
OleDbParameter param1 = new OleDbParameter();
param1.ParameterName = "@p1";
param1.DbType = System.Data.DbType.Guid;
cmd.Parameters.Add(param1);
cmd.Parameters[0].Value = new Guid("41dfe9f9-db91-11d2-8c43-006008d26a6f");

================(Build #3785 - Engineering Case #557924)================

If a connection string containing the "verify=no" TCP option was passed to
the Interactive SQL utility (dbisql) and the -jconnect option was used, the
dbisql would have crashed. This has now been fixed.

================(Build #3752 - Engineering Case #543695)================

Output parameters for stored procedure calls that were marked as indirect
(DBTYPE_BYREF) were not handled properly by the SQL Anywhere OLE DB provider.
This problem has been corrected.

================(Build #3710 - Engineering Case #540698)================

Calling the OleDbDataReader GetString() method may have failed if the source
string had a length of 0, or it may have returned a string that was missing
the trailing null termination character when the source string length was
greater than or equal to 1 (i.e., "abcde" comes back as "abcd"). This problem
has been fixed.

================(Build #3702 - Engineering Case #539056)================

For a statement of the form "EXEC <linked_server_name>..dba.myproc", Microsoft
SQL Server 2005 passes a statement of the form {?=call "dba"."myproc" }
to the SQL Anywhere OLE DB provider. It passes in a single integer parameter
for binding with a status of DB_E_UNAVAILABLE. The SQL Anywhere OLE DB provider
had always checked the status of parameters and accepted one of DBSTATUS_S_DEFAULT,
DBSTATUS_S_ISNULL, or DBSTATUS_S_OK. Any other status was flagged with an
error. As such, the above example would have failed with an error. Since
the parameter is OUTPUT-only, the status of the parameter can be ignored,
as the status for any OUTPUT parameters will be set after the statement has
been executed and any OUTPUT parameters will be filled in. The OLE DB provider
behaviour has been changed to ignore the incoming status of OUTPUT-only parameters.
This allows the EXEC statement to execute successfully.

================(Build #3697 - Engineering Case #537804)================

When the size of a long varchar or long binary column exceeded 32 KB on Windows,
or 1 KB on Windows Mobile, the column may not have been read correctly by
the OLE DB provider. This problem has been fixed.

================(Build #3694 - Engineering Case #536620)================

The OLE DB provider's ICommandWithParameters::SetParameterInfo() method may
have caused an access violation, depending on the order of parameter indexes
in rgParamOrdinals, which is one of the input parameters to the method. The
problem may have also occurred if SetParameterInfo() was called after ICommandPrepare::Prepare().
This problem has now been fixed.

================(Build #3691 - Engineering Case #530923)================

Occasionaly, a DB_E_BADACCESSORHANDLE error would have been returned by the
OLE DB IMultipleResults::GetResult method. This error could have occurred
if the DBPARAMS structure that was passed to the ICommand::Execute method
was disposed by the client before all the result rowsets from a stored procedure
call were returned by calls to the GetResult method. On the final call to
GetResult, output parameters may have become available. As a result, the
DBPARAMS structure was required to be intact for each call to GetResult.
This problem has been fixed. When Execute is called, if it is determined
that there are no output parameters, then the DBPARAMS structure will be
ignored on subsequent calls to GetResult.

================(Build #3670 - Engineering Case #530005)================

The provider's implementation of the GetParameterInfo() method did not indicate
whether parameters in a command were input (DBPARAMFLAGS_ISINPUT), output
(DBPARAMFLAGS_ISOUTPUT), or both.
Examples of such commands are:
INSERT INTO TestTable (ID,Name) VALUES(?,?)
?=CALL TestProcedure(?,?)
This problem has been fixed. The provider now returns the correct settings.
A work around is to use the SetParameterInfo() method to set the DBPARAMFLAGS_ISINPUT
or DBPARAMFLAGS_ISOUTPUT flags in the DBPARAMBINDINFO structure.

================(Build #3665 - Engineering Case #500661)================

When the database option "Blocking" was set to "Off", an attempt to read
rows using the SQL Anywhere OLEDB provider, from a table that has some or
all of its rows locked, would have resulted in the error DB_S_ENDOFROWSET
being returned, which means "no more rows". The error that should be returned
was DB_E_TABLEINUSE ("The specified table was in use"). This problem has
been fixed. Now, when ExecuteReader is called, the error "User 'DBA' has
the row in 'Customers' locked" is reported.

The following .NET example can be used to illustrate the problem. Suppose
another connection is inserting rows into the Customers table. Then the following
example should result in an error when "blocking" is "off".

OleDbConnection conn2 = new OleDbConnection("Provider=SAOLEDB;DSN=SQL Anywhere
10 Demo");
conn2.Open();
OleDbTransaction trans2 = conn2.BeginTransaction(IsolationLevel.ReadCommitted);
OleDbCommand cmd2 = new OleDbCommand("SELECT FIRST Surname FROM Customers",
conn2, trans2);
OleDbDataReader reader2 = cmd2.ExecuteReader();
while (reader2.Read())
{
String s = reader2.GetString(0);
MessageBox.Show(s);
}

================(Build #3651 - Engineering Case #497937)================

The following problems with the OLE DB provider have been corrected:
- conversion of multibyte strings to wide character strings (DBTYPE_WSTR)
was not being done correctly for non-UTF8 character sets.
- DBTYPE_BYREF parameters were not supported.
- the provider would have crashed in the OLE DB Execute method when prepared
statements did not have their parameter information set using the OLE DB
SetParameterInfo method.

================(Build #3637 - Engineering Case #494462)================

When attempting to call a stored procedure in an ADO application, the OLE
DB provider could have returned an "invalid parameter type" error. The order
of the parameters in the procedure was not determined correctly by the provider.
This has been corrected.

================(Build #3573 - Engineering Case #482839)================

When Microsoft's Business Intelligence Development Studio attempted to insert
string values into a row using the OLEDB InsertRow() method, it passed in
a pointer to the data to be inserted. For string values (DBTYPE_STR), it
sometimes did not pass in a length, which caused the SQL Anywhere provider
to insert a string of length zero into the corresponding column. This behavior
has been changed. Now, for types DBTYPE_STR and DBTYPE_WSTR, the provider
will attempt to determine the string's true length when no length is passed
in, with the assumption being that the string is null-terminated.

================(Build #3561 - Engineering Case #481000)================

Borland Delphi converts an empty string parameter to a VARIANT type wide
string with a NULL data pointer. When Borland Delphi was used with the SQL
Anywhere OLE DB provider, this would have resulted in the application crashing.
The following code fragment illustrates the situation.

ADOQuery1.SQL[0] := 'select * from Customers where GivenName = :fname';
ADOQuery1.Parameters.ParamByName('fname').Value := '';
ADOQuery1.ExecSQL;

This problem has been fixed. A null pointer passed to the provider for a
parameter will now be treated as an empty string when passed to the database
server.

================(Build #3542 - Engineering Case #476516)================

When using the SQL Anywhere OLE DB provider, preparing a statement that called
a user-defined function would have resulted in the function's result value
being truncated to 0 bytes. This problem has been corrected.

The following is an example:

CREATE FUNCTION foo( IN arg VARCHAR(3) )
RETURNS VARCHAR(10)
DETERMINISTIC
BEGIN
DECLARE retVal VARCHAR(10);
SET retVal = 'RETURNVALU';
RETURN retVal;
END

Dim cmd As New ADODB.Command
cmd.CommandText = "foo"
cmd.CommandType = ADODB.CommandTypeEnum.adCmdStoredProc
cmd.let_ActiveConnection(con)
cmd.Prepared = True
cmd.Parameters.Refresh()
cmd.Parameters(1).Value = "abc"
cmd.Execute()
MsgBox(cmd.Parameters(0).Value)

A work-around is to not prepare the command (ie. cmd.Prepared = False).

================(Build #3537 - Engineering Case #474282)================

When a DataGrid object was filled with columns that contained more than 32K
bytes, an error could have been returned by the SQL Anywhere OLE DB provider.
This problem has been fixed.

================(Build #3529 - Engineering Case #474606)================

When using the OLE DB provider, a crash could have occurred when disconnecting
from a datasource. This problem has been fixed.

================(Build #3493 - Engineering Case #467507)================

When using SQL Server Business Intelligence Development Studio, the Data
Flow Task "Preview" and column list functions would have failed when using
the SQL Anywhere OLEDB Provider to connect to a SQL Anywhere server. This
problem has been fixed.

================(Build #3488 - Engineering Case #467276)================

The SQL Anywhere OLE DB provider may have failed an assertion if called by
ADO with an incorrect set of parameters to Rowset::ReleaseRows. This problem
only exists in the 64-bit version of MSADO15.DLL for Windows Vista. It does
not exist in the 32-bit version of Vista, nor does it exist in the 64-bit
version of Windows 2003. It occurred when ADO calls the SQL Anywhere OLE
DB provider to release rows in a rowset that it has not previously fetched
rows from. The symptoms include a request to release a rowset with a single
row and a pointer to a row handle that is invalid.

A work around has been added to the SQL Anywhere OLE DB provider such that
a request to release a rowset when no rowset exists will be ignored. The
following VBScript sample will fail on 64-bit Windows Vista without the provider
workaround:

query = "SELECT * FROM Employees"
Set recordset = connection.Execute(query)
For Each field in recordset.Fields
WScript.Echo field.Name
propCount = 0
For Each prop in field.Properties 'crashes on 64-bit Vista
...
Next
Next

================(Build #3442 - Engineering Case #454481)================

The SQL Anywhere OLE DB provider was returning E_FAIL from IOpenRowset::OpenRowset
for database errors. Since E_FAIL was returned, the client would have reported
the message "Unspecified error". On a "table not found" error for example,
it should have returned DB_E_NOTABLE , "The specified table does not exist
in the data store". This problem has been fixed.

================(Build #3428 - Engineering Case #451941)================

When executing a stored procedure that used a string input parameter with
a length exceeding 30 bytes (15 wide characters), the OLE DB provider would
have overrun a buffer and a run-time error would have resulted. This problem
has been fixed.

================(Build #3423 - Engineering Case #451463)================

When running on Windows Vista, performing operations that require administrative
privileges will cause a Windows Vista Elevation Consent (or Credentials)
prompt to be displayed. The application name shown in the prompt will be
"dbelevate". In order for the operation to succeed, the user must provide
consent or provide administrative credentials.

Some self-registering DLLs require administrative privileges to register
or unregister themselves. During a normal installation, the installer runs
in an elevated state and a prompt for dbelevate will not be seen; however,
if regsvr32 is used directly, the prompt may be seen. The SQL Anywhere OLE
DBV provider, SAOLEDB, is Vista-aware and may request elevation when installed
or uninstalled.

================(Build #3419 - Engineering Case #449590)================

If a date parameter value (a value of type adDate) was inserted into a column,
only the year and month were inserted correctly. The day was always 1.

A Visual Basic example:
cmd.CommandText = "INSERT INTO DateTable(cDate) values (?)"
cmd.CommandType = ADODB.CommandTypeEnum.adCmdUnknown
parm = cmd.CreateParameter("inDate", ADODB.DataTypeEnum.adDate, ADODB.ParameterDirectionEnum.adParamInput)
cmd.Parameters.Append(parm)
parm.Value = "2006-12-15"
cmd.Execute()

The value inserted would have been "2006-12-01".

This problem has been corrected, so that the correct date is now inserted.

================(Build #3408 - Engineering Case #447585)================

When using Microsoft's Query Analyzer with Microsoft SQL Server, if a SELECT
statement that used the OPENDATASOURCE procedure and specified the SQL Anywhere
OLE DB provider was executed, it would have failed with the error: "Could
not perform a Windows NT authenticated login because delegation is not available.".

For example:
SELECT * FROM OPENDATASOURCE('ASAProv.90','Data Source=dba_sql_90;User
ID=dba;Password=sql')..dba.my_table

This has been fixed so that the OPENDATASOURCE procedure now works correctly.

================(Build #3385 - Engineering Case #443845)================

When using ADO and the SQL Anywhere OLE DB provider, a stored procedure reference
like "SProc" is correctly parsed in a CommandText string as a procedure name.
However, a stored procedure reference like "DBA.SProc" was incorrectly parsed
as a schema owner, followed by a catalog name, and no procedure name. The
following Visual Basic example fragment illustrates the problem:

objCmd.ActiveConnection = objConn
' Set CommandText equal to the stored procedure name.
objCmd.CommandText = "DBA.SProc"
objCmd.CommandType = adCmdStoredProc
' Automatically fill in parameter info for the stored procedure.
objCmd.Parameters.Refresh()
' Set the parameter values.
objCmd("@user_id") = "ianywhere"
objCmd("@password") = "test"
objCmd("@first") = "Iam"
objCmd("@last") = "Anywhere"
objCmd("@phone") = "5558836300"
objCmd("@extension") = "6300"

When ADO executeed the Refresh() method, the provider was asked to provide
parameter information on the "SProc" stored procedure. A catalog name ("SProc")
and schema owner name ("DBA") were passed in. Since catalog names are not
supported and ignored, information on all stored procedures owned by DBA
were returned to ADO.

This problem has been fixed. An incorrectly set property, DBPROP_CATALOGLOCATION,
resulted in the parsing error. The property value has been corrected.

================(Build #3385 - Engineering Case #443473)================

When a stored procedure call with a return value was prepared, the provider
would have generated a call with an incorrect number of parameters. The following
Visual Basic code demostrates the problem:

objCmd = CreateObject("ADODB.Command")
objCmd.CommandText = "Add_User"
objCmd.CommandType = adCmdStoredProc
objCmd.ActiveConnection = objConn
objCmd.Prepared = True
objCmd.Parameters.Append(objCmd.CreateParameter("Add_User", 3, 4))
objCmd.Parameters.Append(objCmd.CreateParameter("@userid", 200, 1, 25, "jbjones"))
objCmd.Parameters.Append(objCmd.CreateParameter("@first", 200, 1, 25, "John"))
objCmd.Parameters.Append(objCmd.CreateParameter("@last", 200, 1, 35, "Jones"))
objCmd.Parameters.Append(objCmd.CreateParameter("@phone", 200, 1, 18, "5558836300"))
objCmd.Parameters.Append(objCmd.CreateParameter("@extension", 200, 1, 6,
"6300"))

An erroneous SQL statement like the following is generated.

?=call Add_User(?,?,?,?)

If the objCmd.Prepared = True statement was not included , or the Prepared
property was set to False, then the problem did not appear. This has now
been fixed.

================(Build #3369 - Engineering Case #440709)================

When using the OLEDB provider to read values from a varchar( n ) column,
using the .NET DataReader, the last character was truncated if the column
contained exactly n characters. This problem has been fixed.

================(Build #3368 - Engineering Case #440215)================

The changes made for Engineering case 433717 caused the provider to return
'Object or provider is not capable of performing requested operation', when
executing a simple query. This has now been fixed.

================(Build #3363 - Engineering Case #439710)================

Trying to use the TableData adapter wizard with a Dataset, would have failed
with the message "Generated SELECT statement: 'ASAProv.90' failed with no
error message available, result code: DB_E_DELETEDROW(0x80040E23)". This
problem has been fixed.

================(Build #3325 - Engineering Case #433717)================

The Windows x64 version of the OLE DB provider did not align the data areas
for columns on memory boundaries. This was resulting in run-time errors.
This problem has been fixed.

================(Build #3325 - Engineering Case #432537)================

The OLE DB provider did not properly support 4-part queries when used with
the SQL Server 2005 Linked Server feature. For example, attempting the following
SQL statement in Microsoft SQL Server 2005 Management Studio:

SELECT * FROM ASASERVER..dba.customer

would have caused the error:

Msg 7320, Level 16, State 2, Line 1 Cannot execute the query

However, the OPENQUERY form of SELECT works fine:

SELECT * FROM OPENQUERY( ASASERVER, 'SELECT * FROM customer')

This problem has now been fixed. Note, this problem does not appear with
SQL Server 2000.

================(Build #3308 - Engineering Case #433726)================

The Windows CE version of the OLE DB Provider could have failed when attempting
conversions to and from Variant types. Also, some properties were not supported
properly under Windows CE and would have incorrectly returned errors. These
problems have now been fixed.

================(Build #3300 - Engineering Case #429527)================

The changes for Engineering case 404908, introduced a problem where obtaining
parameter information on a stored procedure that was owned by a different
user could have resulted in a crash.

The following Delphi code demostrates the problem:

procedure TForm1.Button1Click(Sender: TObject);
var
adoParams: Parameters;
nCnt: integer;
begin
mmoParams.Clear;
FAdoCommand.Set_ActiveConnection(ADOConnection1.ConnectionObject);
FAdoCommand.Set_CommandText("sp_test");
FAdoCommand.Set_CommandTimeout(30);
FAdoCommand.Set_CommandType(adCmdStoredProc);
adoParams := FAdoCommand.Get_Parameters();
adoParams.Refresh;
for nCnt := 0 to adoParams.Count - 1 do begin
mmoParams.Lines.Add(adoParams.Item[nCnt].Name);
end;
end;

This problem has been fixed.

================(Build #3286 - Engineering Case #426364)================

When scrolling backwards or forwards through a cursor, the OLEDB provider
would have refetched deleted rows. This problem has been fixed.

================(Build #3286 - Engineering Case #426361)================

The OLEDB provider was not converting columns of type BIT to DBTYPE_BOOL
correctly. A true value 1 should map to a 16-bit integer value equal to -1
rather than to the value 1, as it was. This problem has now been fixed.

================(Build #3286 - Engineering Case #424931)================

When the OLEDB provider was used with ADO, wide character strings (UTF16/OLECHAR)
were written correctly to a database that used the UTF8 collation. However,
when fetching the inserted values back from the database, the UTF8 strings
were not correctly converted back into UTF16. This has been fixed. The OLEDB
provider now does proper conversion from UTF8 strings to UTF16 strings.

================(Build #3279 - Engineering Case #424217)================

The iAnywhere OLEDB provider was not correctly executing multi-row fetches
as a result of calling the GetRowsAt() method. For example, when using GetRowsAt()
to fetch rows 1 through 50 of a result set and then fetching rows 26 through
75, the provider would have incorrectly returned rows 51 through 75 on the
second fetch. This problem has been fixed.

================(Build #3277 - Engineering Case #423911)================

Insertion of rows into a UTF8 database, using ADO and the OLEDB provider,
would sometimes have failed. The following Visual Basic script is an example
that reproduces the problem.

recordset.Open "Employees", connection, , , adCmdTable
recordset.AddNew
recordset.Fields.Item("EmployeeID") = 1000
recordset.Fields.Item("GivenName") = "Munroe"
recordset.Fields.Item("Surname") = "Marvin"
recordset.Fields.Item("DepartmentID") = 201
recordset.Fields.Item("Street") = "No fixed Street"
recordset.Fields.Item("City") = "No City"
recordset.Fields.Item("Salary") = 12000.00
recordset.Fields.Item("StartDate") = "2006-01-03"
recordset.Update

This has now been fixed.

================(Build #3277 - Engineering Case #423901)================

The OLEDB GetRowsByBookmark method, as implemented by the iAnywhere provider,
did not work correctly. It was possible to return invalid row handle values.
As well, incorrect row status array values were being returned. This has
now been fixed.

================(Build #3277 - Engineering Case #423508)================

The provider calls the ADO CreateParameter method using the adBSTR datatype.
Each time the Execute method was called, memory would have been leaked.
The following is a C++ example of the code.

std::wstring strParam1( 84, L'\x9F5F' );

// Create the parameters.
_ParameterPtr param1;
_variant_t val1( strParam1.c_str() );
param1 = cmd->CreateParameter( L"", adBSTR, adParamInput, (long)strParam1.length(),
val1 );
cmd->Parameters->Append( param1 );

// Run the command.
_variant_t vtEmpty1( DISP_E_PARAMNOTFOUND, VT_ERROR );
_variant_t vtEmpty2( DISP_E_PARAMNOTFOUND, VT_ERROR );
cmd->Execute( &vtEmpty1, &vtEmpty2, adCmdStoredProc | adExecuteNoRecords
);

When a variant BSTR object (val1) was converted to a BSTR object (the bound
parameter), a new object was created and the memory for that object was lost.
This problem has now been corrected.

================(Build #3250 - Engineering Case #417837)================

When the ADO methods AddNew() or Update() were called, a memory leak would
have occurred in the OLE DB provider. This problem has been fixed by appropriately
freeing the allocated memory.

================(Build #3246 - Engineering Case #417622)================

The OLE DB schema rowsets (e.g., INDEXES) are supported by stored procedures
like sa_oledb_indexes (and others). They return result sets that allow for
table names and other identifiers up to 128 characters in length. However,
the input parameters to these stored procedrues only allowed for identifiers
of up to 80 characters in length. This problem has been fixed so that parameters
can now be up to 128 characters in length.

================(Build #3221 - Engineering Case #409320)================

When retrieving long varchar fields using a client side ADO recordset, a
null character was appended to the end of the data by the OLEDB provider.
This problem has been fixed.

================(Build #3198 - Engineering Case #405321)================

An attempt to insert a value into a SQL TINYINT column declared as adTinyInt,
that was greater than 128, would have failed with the error "Count field
incorrect". Unfortunately, this message did not clearly indicate where the
problem occurred. The ADO adTinyInt type (DBTYPE_I1) includes numbers in
the range -128 to 127. A value like 255, which is outside of this range,
cannot be converted to an adTinyInt. The ASA TINYINT type corresponds to
an unsigned 1-byte integer, which matches the ADO adUnsignedTinyInt type
(DBTYPE_UI1). This type accepts values in the range 0 to 255. The conversion
error that results from trying to convert a value like 255 to an adTinyInt
type is now properly reported as "Cannot convert parameter X to a DBTYPE_I1"
where X is the index of the parameter to the INSERT statement.

================(Build #3196 - Engineering Case #404908)================

A memory leak in the OLE DB provider associated with calling stored procedures
has been fixed.

================(Build #3196 - Engineering Case #404290)================

A stored procedure call that included the owner name would have failed when
using ADO and the SQL Anywhere OLE DB provider. The following is an example
using Visual Basic:

' Set CommandText equal to the stored procedure name.
objCmd.CommandText = "fred.ShowSalesOrderDetail"
objCmd.CommandType = adCmdStoredProc
objCmd.ActiveConnection = objConnection

A couple of problems arose when using this form of the stored procedure
call. Internally, the OLE DB provider uses a SQL query to obtain information
on the number of parameters to the stored procedure. It asked for information
on a procedure name called "fred.ShowSalesOrderDetail" and there was no such
procedure name since the owner name had not been separated from the procedure
name. This problem has been fixed.

The second problem involved using the ADO parameter "Refresh" method as
shown below in a Visual Basic example:

' Automatically fill in parameter info from stored procedure.
' This avoids having to do CreateParameter calls.
objCmd.Parameters.Refresh

The problem is related to the way ADO interprets the components of the stored
procedure name. There are three basic forms recognized by ADO.

1. ProcedureName
2. Owner.Catalog
3. Owner.ProcedureName.Catalog

Here is how ADO interprets these forms.

The first form is what is most often used. When only a name appears (no
qualifiers), it is interpreted to be the procedure name. This form poses
no problems.

When the second form is used (two names separated by a period), the first
name is assumed to be the owner name and the second name is assumed to be
the catalog name. SQL Anywhere doesn't support the notion of catalogs.
When the Refresh method is called, the OLE DB provider is presented with
the following query by ADO.

EXECUTE sa_oledb_procedure_parameters inProcedureCatalog='Catalog',inProcedureSchema='Owner'

This query from ADO is meaningless to the SQL Anywhere OLE DB provider,
as the procedure name is missing. ADO has interpreted the two components
as a schema name (the owner) and a catalog name. The query returns information
on all procedures owned by "Owner" which is of no use.

When the third form is used, the first name is assumed to be the owner name,
the second name is assumed to be the procedure name. and the third name is
assumed to be the catalog name. When the Refresh method is called, the OLE
DB provider is presented with the following query by ADO.

EXECUTE sa_oledb_procedure_parameters inProcedureCatalog='Catalog',inProcedureSchema='Owner',inProcedureName='ProcedureName'

Since the procedure name and owner are present and since the catalog name
is ignored by the OLE DB provider, this query will return the correct information
about the procedure parameters. However, the actual procedure call will result
is a syntax error since "call Owner.ProcedureName.Catalog" is not an acceptable
form for a stored procedure call.

These problems can be avoided by not using the ADO "Refresh" method and,
also, by avoiding the use of the three-part syntax. The best solution is
to avoid the use of an owner qualification entirely since the "X.Y" form
is misinterpreted by ADO.

================(Build #3183 - Engineering Case #403026)================

For FORWARD-ONLY cursors, the iAnywhere OLEDB provider was returning the
error "HY109" when fetching rowsets with more than 1 row, and contained a
column with more than 200 bytes. This problem has been fixed.

================(Build #3183 - Engineering Case #403014)================

The iAnywhere OLEDB Provider's default ('PUBLIC') for the GRANTEE restriction
column for the COLUMN_PRIVILEGES and TABLE_PRIVILEGES rowsets was incorrect.
The default should be the empty string (''). Also, the Provider did not enforce
the GRANTOR and GRANTEE restriction columns for the COLUMN_PRIVILEGES rowset.
These problems have been fixed.

To install new versions of the OLEDB provider schema rowsets into a database,
load and rerun scripts\oleschem.sql.

================(Build #3183 - Engineering Case #403010)================

The iAnywhere OLEDB Provider could have reported a "Table not found" error
for any of the following rowsets:

COLUMN_PRIVILEGES
TABLE_PRIVILEGES
FOREIGN_KEYS

The SQL scripts that implement these schema rowsets did not qualify the
SYSGROUP or SYSTRIGGER tables with "SYS.". This has been corrected.

To install new versions of the OLEDB provider schema rowsets into a database,
load and rerun scripts\oleschem.sql.

================(Build #3180 - Engineering Case #402278)================

The Microsoft Query Analyzer uses the iAnywhere OLEDB provider to process
queries from (ASA) Linked Servers. The Query Analyzer can call ASA stored
procedures provided that Remote Procedure Calls have been enabled. The Linked
Server properties RPC and RPC Out must be selected; otherwise a message like
"Server 'asatest9' is not configured for RPC" will be issued.

The Query Analyzer forms a query that is syntactically incorrect for ASA
and this results in a syntax error message.

For example, the following query will result in the error messages shown
below.

asatest9..dba.sp_customer_list

Could not execute procedure 'sp_customer_list' on remote server 'asatest9'.
[OLE/DB provider returned message: Syntax error near '1' on line 1]

The Query Analyzer issues the SQL statement "{?=call "dba"."sp_customer_list";1}".
The ";1" results in a syntax error.

This has been fixed. The iAnywhere OLEDB provider will now remove the ";1"
from the statement as a work-around.

================(Build #3180 - Engineering Case #402276)================

The iAnywhere OLEDB Provider was reporting inconsistent type information
for NUMERIC/DECIMAL columns. In some cases it would have reported DBTYPE_DECIMAL
for NUMERIC/DECIMAL columns, in other cases it reported DBTYPE_NUMERIC. It
would also have inconsistently reported precision for NUMERIC/DECIMAL columns,
changing it between compile time and runtime. These problems have now been
fixed. The changes have been made to the provider, as well as the supporting
stored procedures. To install new versions of the OLEDB provider schema rowsets
into a database, scripts\oleschem.sql must be rerun against the database.

================(Build #3179 - Engineering Case #401990)================

When adding a new row into a table using the OLEDB provider, if the value
for a column was the empty string, Visual Basic would have reported reports
a run-time error. The conversion functions assumed that a result length of
0 indicated an error, which is true if the input length is non-zero, but
if the input length is 0 then a result length of 0 is expected. This problem
has been fixed.

================(Build #3179 - Engineering Case #401989)================

A Visual Basic application, using the OLEDB provider to add a new row to
a table that contained an unitiialized (NULL) column value , would have crashed
with a null pointer exception. This problem has been fixed.

================(Build #3179 - Engineering Case #401987)================

When adding a row to a table that contained a BIT column using the OLEDB
provider, the BIT column value was always recorded as FALSE. This problem
has been fixed.

================(Build #3168 - Engineering Case #400186)================

Insertion of multibyte strings (Chinese, Japanese, Korean, etc.) into a database
using the UTF8 collation would have failed. The following C# code illustrates
the problem.

System.Data.OleDb.OleDbDataAdapter Ada=new System.Data.OleDb.OleDbDataAdapter
("select * from test",conn);
System.Data.OleDb.OleDbCommandBuilder CommandBuilder=new System.Data.OleDb.OleDbCommandBuilder
(Ada);

System.Data.DataTable dt=new DataTable ();
Ada.FillSchema (dt,System.Data.SchemaType .Mapped );
System.Data.DataRow dr=dt.NewRow ();
dr["Col01"]=textBox1.Text ;
dt.Rows.Add (dr);
Ada.Update (dt);

If the text entered into "textBox1" was a multibyte character, it would
not have been inserted correctly into column "Col01" of the "test" table
when the database was using the UTF8 collation. This problem has now been
fixed.

================(Build #3165 - Engineering Case #399872)================

When using FoxPro to display a result set, the first record was missing.
The following code sample illustrates the problem.

conn = CREATEOBJECT( 'ADODB.Connection' )
conn.ConnectionString = [Provider=ASAProv.90;uid=dba;pwd=sql;]
conn.Open
rs = CREATEOBJECT( 'ADODB.RecordSet' )
rs.ActiveConnection = conn
curs = CREATEOBJECT( 'CursorAdapter' )
curs.datasourcetype = 'ADO'
curs.datasource = rs
curs.SelectCmd = 'SELECT * FROM SYS.SYSTABLE WHERE table_id = 2'
curs.alias = 'ADO Test'
curs.cursorfill
BROWSE

FoxPro obtained the first row in the result set and then issued a RestartPosition()
call to reposition to the first row in the result set. The cursor type for
the query in the above example was FORWARD ONLY. With this type of cursor,
the RestartPosition() procedure failed to reposition to the start of the
result set. This problem has been fixed. RestartPosition() will now re-execute
the query to position to the start of the result set when the cursor type
is FORWARD ONLY.

================(Build #3161 - Engineering Case #397798)================

If a Visual Basic application attempted to open a record set using a STATIC
cursor with a PESSIMISTIC locking mechanism, the OLEDB provider would have
selected a DYNAMIC cursor instead. This was done by the provider to ensure
that updating of the records was possible, usually by locking records at
the data source immediately before editing. Of course, this also meant that
the records were unavailable to other users once editing had begun, until
the lock was released by calling Update. This type of lock is used in a system
where you can't afford to have concurrent changes to data, such as in a reservation
system. If the application then tried to obtain the current bookmark value,
an error would have occurred. This made it appear that STATIC cursors didn't
support bookmarks, whereas the real problem was that DYNAMIC cursors do not
support bookmarks. If the application specifies a STATIC cursor with a READ-ONLY
locking mechanism, then a STATIC cursor will be used and bookmarks are supported.
The OLEDB provider has been changed so that a KEYSET cursor will be selected
instead of a DYNAMIC cursor when PESSIMISTIC locking is requested. This will
allow the use of bookmarks.

================(Build #3122 - Engineering Case #389502)================

The OLEDB PROVIDER_TYPES rowset did not implement the DATA_TYPE and BEST_MATCH
restrictions. It implemented a restriction on TYPE_NAME instead and ignored
BEST_MATCH. This problem has been fixed so that the PROVIDER_TYPES rowset
now implements the DATA_TYPE and BEST_MATCH restrictions. To install a new
version of the PROVIDER_TYPES rowset into your database, load and run scripts\oleschem.sql
against the database.

As well, not all type names are included in the rowset, and some data types
that could be included were not. This has also been corrected.

================(Build #3034 - Engineering Case #379901)================

The OLEDB provider was failing to close the result set cursor between prepared
command executions. Enigeering Case 351298 reintroduced this bug, which was
originally described by Case 271435. This fix addresses both issues, an open
cursor is now closed before a SQLExecute, when the command has been previously
prepared.

================(Build #3024 - Engineering Case #376453)================

An ADO .Net application that attempted to obtain the primary keys from a
query on a table using the OLEDB provider, may have been returned incorrect
results when the table had more than one primary key column and/or columns
with unique constraints or unique indexes.

A sample code fragment follows:

DataTable Table = new DataTable(textTableName.Text);
OleDbDataAdapter adapter;
OleDbConnection connection = new OleDbConnection(textConnectionString.Text);
using (connection)
{
try
{
connection.Open();

adapter = new OleDbDataAdapter("select * from dba." + textTableName.Text
+ " where 1=0", connection);
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
adapter.Fill(Table);

listBox1.Items.Clear();
foreach(DataColumn col in Table.PrimaryKey)
{
listBox1.Items.Add(col.ColumnName);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

The DataTable PrimaryKey property is an array of columns that function as
primary keys for the data table. This problem has been fixed.

One of the elements that ADO.Net uses in deciding whether a column belongs
in this set is the column metadata rowset.

IColumnsRowset::GetColumnsRowset - Returns a rowset containing metadata
about each column in the current rowset. This rowset is known as the column
metadata rowset and is read-only. The optional Metadata Column DBCOLUMN_KEYCOLUMN
is described to contain one of the values VARIANT_TRUE or VARIANT_FALSE or
NULL.

VARIANT_TRUE — The column is one of a set of columns in the rowset that,
taken together, uniquely identify the row. The set of columns with DBCOLUMN_KEYCOLUMN
set to VARIANT_TRUE must uniquely identify a row in the rowset. There is
no requirement that this set of columns is a minimal set of columns. This
set of columns may be generated from a base table primary key, a unique constraint
or a unique index.

VARIANT_FALSE — The column is not required to uniquely identify the row.

This column used to contain VARIANT_TRUE or VARIANT_FALSE. It now contains
NULL since OLEDB cannot correctly set the value. As a result, ADO.Net uses
other means for determining which columns belong in the PrimaryKey columns
property.

================(Build #2529 - Engineering Case #369521)================

If the GetCurrentCommand method of the ICommandPersist interface was called,
the memory heap could have been corrupted. This problem has been fixed.

================(Build #2529 - Engineering Case #369272)================

A call to IRowsetChange::InsertRow() in the OLEDB provider, ASAProv, results
in a crash. This call can be made from C++ using a simple table insert:

CTable<CAccessor<CSimpleAccessor> > dbSimple;
hr = dbSimple.Insert(1);

This problem has been fixed.

================(Build #2529 - Engineering Case #369072)================

When using the OLEDB provider ASAProv, String parameters may not have been
passed correctly to stored procedures. This problem has been fixed.

The following Visual Basic example calls a stored procedure with a String
parameter.

Dim sendParam1 As String
sendParam1 = "20040927120000"
Dim cmd As ADODB.Command
cmd = New ADODB.Command
With cmd
.CommandText = "testproc1"
.CommandType = ADODB.CommandTypeEnum.adCmdStoredProc
.ActiveConnection = myConn
.Prepared = True
.Parameters(0).Value = sendParam1

Call .Execute()
End With

An example of a stored procedure follows.

ALTER PROCEDURE "DBA"."testproc1" (in param1 varchar(30))
BEGIN
message 'in Parameter [' + param1 + ']';
END

================(Build #2529 - Engineering Case #369016)================

When an application using the OLEDB driver provided a DBTYPE_DECIMAL parameter
with over 15 digits, the most significant digits would have been lost. For
example, if the value 1234567890.123456 was provided as a DBTYPE_DECIMAL
parameter, this would have been incorrectly interpreted as 234567890.123456
(the leading 1 would be lost). In particular, this could affect Visual Basic
applications using an OleDbDataAdapter on a query with a numeric or decimal
typed column, and a generated DataSet. The problem has now been fixed.

================(Build #2529 - Engineering Case #368574)================

The execution of a SELECT statement containing JOINs of several tables by
applications using the OLEDB provider ASAProv, would have resulted in a memory
leak. This has been fixed.

Adaptive Server Anywhere - Other

================(Build #3759 - Engineering Case #551602)================

The file sbgse2.dll was a new file added in a 9.0.2 EBF for the support of
FIPS encryption. The EBF installer was incorrectly installing this file only
when MobiLink was installed. It was therefore possible to break FIPS encryption
by installing an EBF.
For example:
- 9.0.2.GA was installed with Mobilink deselected,
- FIPS is installed, again with Mobilink deselected,
- a 9,0,2 EBF is installed accepting all the defaults.
FIPS gets broken because sbgse2.dll does not get installed.

This has been fixed. The installer now checks if FIPS is installed before
copying sbgse2.dll.

================(Build #3705 - Engineering Case #540227)================

On Linux x86 and Solaris SPARC systems, the encryption libraries have been
updated to use Certicom 5.

================(Build #3677 - Engineering Case #529075)================

When trying to use the database tools library on HP-UX (PARISC 32 or 64)
to read a database created with a version prior to 10.0, the application
would have failed with the error "could find or load the physical store DLL".
This has been fixed.

================(Build #3672 - Engineering Case #531094)================

The installer may failed on some versions of Linux. Symptoms may have ncluded
incorrect reporting of available disk space, and messages such as:
tail: `-1' option is obsolete; use `-n 1'
Try `tail --help' for more information.
An error occurred while attempting to extract files in /opt/sybase/

The way in which the head and tail utilities were being invoked by the installer
was incompatible with some older versions of the Gnu head and tail utilities
included on Linux. This has been fixed by replacing the use of head and tail
in the setup script with appropriate sed commands.

================(Build #3632 - Engineering Case #492387)================

The install would have failed on Unix systems which contained a version of
coreutils 6.9 or newer (such as Ubuntu Linux 8.04). The failures would likely
have occurred while checking that the target system meets the minimum requirements
for SQL Anywhere, or while verifying the amount of free disk space available.
The "setup" install script can be modified to work around this issue as follows:
1. Find all lines containing the "cut" command that uses the "-f" argument
2. For all such lines if a comma immediately follows the "-f", remove this
comma
For example, the line:
OS_REL_1=`echo $OS_REL | cut -d. -f,1`
should become:
OS_REL_1=`echo $OS_REL | cut -d. -f1`

================(Build #3575 - Engineering Case #482379)================

After applying an EBF for SQL Anywhere Windows systems with Visual Studio
2005 installed, there could have been some garbled characters left at the
beginning of the machine.config file for .NET Framework 2.0. This would have
caused the SQL Anywhere Explorer for Visual Studio 2005 to not work properly.
This has been fixed.

================(Build #3534 - Engineering Case #474904)================

If two or more transactions concurrently attempted to lock a table t in exclusive
mode with "lock table t in exclusive mode", the transactions could have deadlocked.
This was much more likely to occur on multi-processor systems, and is not
likely to be reported by personal servers. This has been fixed.

================(Build #3513 - Engineering Case #470680)================

When running the Windows Performance Monitor in a Terminal Services session
other than session 0, it was not possible to monitor database services running
in session 0. On XP, system services and the primary desktop are all in session
0. On Vista, only the system services run in session zero. The behaviour
has been changed so that when the Windows Performance Monitor (perfmon) is
started (actually, when "add counters" is selected for the first time), perfmon
will monitor a database server in the local session if one exists and is
providing statistics. If there is no server running in the current session,
perfmon will monitor a database server in session 0 if one exists and is
providing statistics. If there is no database server providing statistics
in the local session or in session 0, perfmon will display statistics for
a database server if one is subsequently started in the local session ONLY.
To monitor a database server that runs in session 0 (eg, a system service)
from a session other than session 0, the database server must be started
before perfmon is started.

================(Build #3483 - Engineering Case #461712)================

On older versions of Windows NT the install could have failed to load a required
dll with a message like: "Unable to load install support DLL (dbinst.dll)...".
This has been fixed.

================(Build #3471 - Engineering Case #455330)================

The Unix install could have hung after reporting the following error:
"No valid values found for the -w flag". The installer makes a call to the
OS to get the size of the current window, which is then used to format the
display of the install text. If this call returns an error, the window size
is set to a default of 80x24. If however, the call does not return an error
but returned a window size of 0x0, the installer would have tried to use
this to format the text, leading to problem. This has been fixed by using
the default 80x24 size for this case as well.

================(Build #3451 - Engineering Case #456580)================

The sample programs provided have been changed so that they now correctly
handle SQL Anywhere installation pathnames that contain spaces. Previously,
the sample programs used the Windows "short" filename (8.3) format, which
avoided spaces.

================(Build #3450 - Engineering Case #461999)================

The United State has extended Daylight Saving Time (DST) by 4 weeks in the
U.S. time zones that recognize DST. Starting in 2007, Daylight Saving Time
will begin the second Sunday in March (2am, March 11, 3 weeks earlier than
previous years) and will end the first Sunday in November (November 14, 2am,
1 week later than previous years). SQL Anywhere software is not directly
vulnerable to issues related to this change, but users of Java logic may
need to update their run-time environments.

For more details, see:
http://www.ianywhere.com/developer/technotes/sa_daylight_savings_time_change.html

================(Build #3441 - Engineering Case #453846)================

Prior to HP-UX 11i v2 September 2004 Update, hostname length on HP-UX machines
was limited to 64 bytes. Starting with that version, system administrators
could enable support for 255-byte hostnames by setting a kernel parameter.
However, on SQL Anywhere servers on HP-UX machines with long hostname support
enabled, the MachineName property would only have returned at most 64 bytes
of the hostname. The same was true of the HOST key in the AppInfo string
for clients on such machines. This has now been fixed, and both MachineName
and AppInfo are now capable of containing 255-byte hostnames.

================(Build #3428 - Engineering Case #452414)================

When setting dynamic traps for the SNMP Extension agent, the modifiers 'K',
'M', 'G',
or 'T' can now be used to specify numeric values. For example, you can set
a
dynamic trap to fire if the current cache size exceeds 200 MB using:

Trap1=1.3.6.1.4.1.897.2.1.1.11.1 > 200M

Note, the modifiers are case insensitive.

================(Build #3412 - Engineering Case #448506)================

When SQL Remote for ASA/SA was the only feature selected for installation,
the installer was failing to include certain files (dbtools*.dll, dblib*.dll,
dblg*.dll) required for standalone operation. This has been fixed so that
these files are now installed.

================(Build #3404 - Engineering Case #447355)================

If the tracetime.pl Perl script (<asany>\Samples\ASA\PerformanceTraceTime\tracetime.pl)
was run using a request log containing host variable information, the script
would have hung. The script failed to increment a counter within a loop that
was resetting the hostvar info. This has been fixed.

================(Build #3395 - Engineering Case #445847)================

On Unix systems, if the environment variable ASTMP (9.0) or SATMP (10.0)
contained a path, where the final two or more component directories did not
exist, client utilities would have crashed on startup with the error message
"Failed to create directory '<path>': No such file or directory". This has
been fixed.

Note that the network server is not affected by this.

================(Build #3389 - Engineering Case #443642)================

If an application sent a timestamp structure host parameter which contained
an invalid year, the server would not have generated an error if the database
option Conversion_error was On. Timestamp structures are used for example,
with the embedded
SQL type DT_TIMESTAMP_STRUCT, and the ODBC type SQL_TIMESTAMP. If a stored
timestamp value with an invalid year was converted to a string, the year
component of the string would have contained asterisks (e.g. ****-02-28 ).
This has now been fixed so that the server correctly generates the error
SQLE_CONVERSION_ERROR (-157) for invalis timestamp structures, even when
the option Conversion_error is On.

================(Build #3382 - Engineering Case #442574)================

Applications which did not use ODBC (for example, dbisql and other utilities)
would not find a file DSN file if the file was in the default ODBC File DSN
directory. The FILEDSN connection parameter can be used to specify a file
DSN. The default ODBC File DSN directory is the directory where File DSNs
are created by default by the Microsoft ODBC Data Source Administrator. This
has been fixed.

================(Build #3354 - Engineering Case #438405)================

When using the Database Tools interface, calling DBToolsInit followed by
DBToolsFini, would have resulted in a few kilobytes of memory being left
unfreed. The amount would have been relatively constant.

Calling DBSynchronizeLog, would also have resulted in memory being left
unfreed. The amount of memory left unfreed was proportional to the number
of articles contained in all the publications involved in synchronization
subscriptions in the database being synchronized.

Both of these memory leaks have now been fixed.

================(Build #3299 - Engineering Case #429284)================

On Unix systems, when searching for the .odbc.ini file, or an ODBC File DSN,
one of the places searched is the user's home directory. Under normal circumstances,
the HOME environment variable points to the user's home directory, but it
can be changed. If the HOME environment variable was set to a location other
than the user's actual home directory, and the file being sought was not
found there, the file was not then searched for in the user's "real" home
directory (ie ~/.odbc.ini). This has been corrected so that the user's actual
home directory is search as well.

================(Build #3274 - Engineering Case #425280)================

Starting with build 9.0.2.3274, pre-generated .CAB files for Windows Mobile
5 will now be shipped which are security-signed by Verisign. These can be
installed only on Windows Mobile 5 devices, and will avoid the "unknown publisher"
warning displayed when installing un-signed .CAB files.

There is an additional feature: "Signed .CAB files for Windows Mobile 5"
in the desktop install.

In the CE deployment installer, there are now up to 5 platforms to choose
from:
Build or Deploy a .CAB file for Windows Mobile 5
Build a .CAB file for ARM
Build a .CAB file for ARMV4T
Build a .CAB file for MIPS
Build a .CAB file for Pocket PC 2002 emulator (X86)

Selecting the Windows Mobile 5 option, will also allow the choice of deploying
one of the two security-signed .CAB files -- one has support for Compact
Framework 1.1, the other for Compact Framework 2.0. Alternatively, a custom
.CAB file can still be built, but this will not be security-signed.

================(Build #3188 - Engineering Case #402170)================

Replaying a silent install on a machine running a firewall would have resulted
in the failure of the silent install when it attempted to load the Sybase
Central or Interactive SQL fast-launchers. This has been fixed by no longer
attempting to load the fast-launchers during either the recording or the
playback of a silent install.

================(Build #3165 - Engineering Case #397914)================

Error message for SQLSTATE 23506, SQL error code -209 (INVALID_COLUMN_VALUE)
contained a spelling error in Lithuanian. "eleistina" should be "neleistina".
This has been corrected.

================(Build #3141 - Engineering Case #384130)================

If the length of an indexed table column was increased on a big endian machine,
using the index may have caused the server to crash due to an unaligned memory
reference. This has been fixed.

================(Build #3140 - Engineering Case #383170)================

If an installation had been updated using the Maintenance Patch, or an EBF,
in a language other than that used during the original installation, the
uninstall would fail. The Patch or EBF would have overwritten the suport
files, which contained support for the original language, but would not have
changed the language option in the uninstall command line. This would have
resulted in the uninstall attempting to run in the original language and
failing to find the correct language support. This has now been fixed by
changing the uninstall command line to reflect the language of the last-run
Patch or EBF.

================(Build #3131 - Engineering Case #385383)================

The installer would have occasionally failed to determine the location of
the Shared folder. For example, if only Sybase Central had been installed,
the existing Shared folder would not have been found and the default location
would be used instead. If the default was chosen, plugins installed by other
products would have failed to load. This has been fixed.

================(Build #3123 - Engineering Case #389628)================

The Unix installer could have reported that there was enough disk space for
the installation, but later fail while copying files. This problem only occurred
when help files (HTML or PDF) were being installed. This has now been fixed.

================(Build #3091 - Engineering Case #380746)================

Playback of a silent install recording may have failed if the recording included
the ADO.NET feature, but the machine being installed to did not have the
.NET Framework installed. This has been fixed.

================(Build #3044 - Engineering Case #381563)================

There was a problem generating the cab file when deploying to a Windows CE
device after installing the 9.0.2 build 3040 EBF. Deselecting the sample
apps and database would have caused the cab file generation to fail with:

Error: Section [Shortcuts.All]shortcut "ADO.Net Sample.lnk" - there is no
matching target file "ado_net_sample.exe" for the current CPU type.

This has now been fixed.

================(Build #3040 - Engineering Case #379106)================

A multithreaded Embedded SQL application could, depending on timing, have
failed with the error "Invalid statement" (SQLCODE -130). For this to have
occurred, the application had to use the syntax "EXEC SQL DECLARE ... CURSOR
FOR SELECT ..." in code which could be run by multiple threads concurrently.
This has been fixed so that the SQL Preprocessor generates code for the syntax
"EXEC SQL DECLARE ... CURSOR FOR SELECT ..." that is thread safe.

Note the syntax "EXEC SQL DECLARE ... CURSOR FOR :stmt_num" is thread safe
(and is not affected by this problem), while the syntax "EXEC SQL DECLARE
... CURSOR FOR statement_name" is not thread safe (and cannot be made thread
safe).

================(Build #3023 - Engineering Case #376202)================

Installing an EBF may have abnormally terminated as it was about to copy
files to the target system. This has been fixed.

================(Build #2549 - Engineering Case #374870)================

The Palm HotSync Conduit Installation Utility (dbcond9.exe) may have crashed
when installing or uninstalling a conduit on Windows NT 4.0, if the HotSync
Manager was not available. This has been fixed.

================(Build #2531 - Engineering Case #366568)================

If MobiLink Server was the only component selected for installation, the
licensing utility dblic.exe was not installed and the MobiLink Server could
not have been re-licensed after installation. This has been fixed.

================(Build #2529 - Engineering Case #371843)================

When running an EBF install on Linux or Solaris systems, selecting the Japanese
license agreement would have caused the install to exit before applying the
EBF. The problem has now ben fixed.

================(Build #2529 - Engineering Case #370722)================

The QAnywhere Stop utility qastop, was added in an EBF after the GA release
of 9.0.1. The CE EBF installer was updated at the same time to expect qastop
to be present. If a subsequent EBF was applied, the installer would have
failed, with the following message:
Error: File 'c:\program files\sybase\asa9\ce\arm.30\qastop.exe' not
found.
This has been fixed.

================(Build #2529 - Engineering Case #369278)================

The stored procedure sp_jdbc_stored_procedures is used by jConnect to retrieve
stored proc metadata. Unfortunately the definition of the stored procedure
was incorrect and the PROCEDURE_TYPE column of the metadata result set was
returning whether or not the particular stored proc returned a result set.
In actuality, the PROCEDURE_TYPE column should return whether or not the
particular stored proc returns a return value. This procedure has now been
corrected.

Note, new databases will have the corrected procedure, but to update existing
databases, run the Upgrade utility dbupgrad.

Adaptive Server Anywhere - SNMP Extension Agent

================(Build #3429 - Engineering Case #452041)================

When setting a dynamic trap on the rdbmsDbLimitedResourceTable in the RDBMS
MIB, the trap would only have fired if a standard query for the same OID
was received after the condition was satisfied. If such a query was not received,
the dynamic trap would never be
sent. This has been fixed.

================(Build #3248 - Engineering Case #417847)================

The rdbmsSrvLimitedResourceTable.rdbmsSrvLimitedResourceID entry was returning
an OID that was either invalid or referred to an unrelated entry in the MIB.
This entry should return the OID of the limited resource in question (which
in ASA's case, is either licenses or processors), but the OID that was returned
referred to the asaSrvStat subtree rather than the asaSrvProp subtree. This
has been fixed.

Adaptive Server Anywhere - Server

================(Build #3918 - Engineering Case #607425)================

The number of nullable columns in a table is limited. This limitation is
based on the page size of the database. For 4K pages, the limit is approximately
32000 columns. Attempting to add too many nullable columns to a table using
ALTER TABLE would have resulted in a failed assertion, rather than an error
message. This has been fixed.

================(Build #3915 - Engineering Case #595276)================

Procedures containing XML generation functions (XMLAGG, XMLELEMENT, etc.)
that were simultaneously executed by large numbers of connections, could
have caused the server to crash. This has been fixed.

A workaround is to rewrite procedures that cause this behaviour to use the
XML generation functions as EXECUTE IMMEDIATEs with a trim. For example,
:
CREATE PROCEDURE FOO()
BEGIN
SELECT XMLELEMENT('foo');
END;

could be rewritten as:
CREATE PROCEDURE FOO()
BEGIN
EXECUTE IMMEDIATE trim('SELECT XMLELEMENT(''foo'')');
END;

Note that such rewritten procedures will no longer be able to take advantage
of plan caching.

================(Build #3912 - Engineering Case #596419)================

When autostarting a database, database-specific options (such as -ds) which
had values containing quotation marks were not handled correctly. For example,
the following would not have worked correctly:
dbisqlc -c "dbf=my.db;dbs=\"d:\tmp\spacey path\""

This problem has now been corrected.

Note that using quotation marks on the command line to start a database
server worked correctly:
dbeng11 my.db -ds "d:\tmp\spacey path"

A related problem was found and fixed in dbisqlc which handled the START
DATABASE statement itself, and constructed a connection string containing
a "dbs=-ds ..." parameter, rather than passing the START DATABASE statement
to the server. Dbisqlc was not putting quotes around a -ds parameter that
contained spaces.

================(Build #3909 - Engineering Case #532280)================

The server could have behaved erroneously when new procedures were created
from within event handlers, or after having executed the SETUSER statement.
Although rare, in the worst case a user could have been allowed to be dropped
while still connected. These problems have been corrected so that the server
now behaves correctly.

================(Build #3906 - Engineering Case #593472)================

If a subquery contained an equality predicate with an outer reference, and
the left and right expressions of the equality predicate had different domains,
then the computed result set may have been incorrect. The equality predicate
must have been of the form "local column = outer reference column". This
problem has now been fixed.

For example:

select * from R, S
where R.X NOT IN ( select T.X from T where T.N = S.I)

where the column T.N is of type numeric and the column S.I is of type integer.

================(Build #3906 - Engineering Case #593334)================

The error "Fatal error: Could not write to file" could have been returned
from the server when attempting to write to a file in a clustered environment.
While the clustering service was performing some tasks, it was possible that
the database server would be given an error ERROR_NOT_READY when attempting
to perform an operation on the file. The server now retries the operation
several times in this circumstance.

================(Build #3901 - Engineering Case #593428)================

If an application executed a query containing a large number of proxy tables
on a 64-bit server, and the query ended up being executed in NO PASSTHRU
mode, then there was a chance the server would have failed assertion 101508
instead of giving the "syntactic limit exceeded" error. This problem has
now been fixed, and the "syntactic limit exceeded" error is now properly
returned.

================(Build #3893 - Engineering Case #591001)================

In very rare circumstances, the server may have crashed when it should have
returned the sql error SQLSTATE_SYNTACTIC_LIMIT. This may have occurred when
loading very compley view definitions, or executing a SELECT INTO into table
statement. This has been fixed.

================(Build #3889 - Engineering Case #589762)================

The server would have crashed if the system functions db_property('LogFileFrangments')
or sa_db_properties() were executed against the utility database. This has
been fixed.

================(Build #3885 - Engineering Case #588740)================

We learned that in the interest of improved performance, Microsoft Windows
explicitly prevents certain documented methods of guaranteeing that data
has been written to the physical storage medium from working on IDE/SATA/ATAPI
drives (SCSI drives are unaffected). Recoverability after a power outage
could be compromised. The database server now performs additional operations
to flush data to disk to improve recoverability. In testing, there was no
measurable performance degradation by this change.

Relevant third-party articles:
http://perspectives.mvdirona.com/2008/04/17/DisksLiesAndDamnDisks.aspx
http://msdn.microsoft.com/en-us/library/dd979523%28VS.85%29.aspx
http://research.microsoft.com/apps/pubs/default.aspx?id=70554
http://groups.google.com/group/microsoft.public.win32.programmer.kernel/browse_frm/
thread/4590ed3a4133828f/406cfb3a9deae044

================(Build #3885 - Engineering Case #588499)================

The server would have stopped the TCP listener and printed the message "TCP
Listener shutting down (130)" to the console log, if it has accepted a new
client connection but the client side has already gone. This has been fixed.

================(Build #3884 - Engineering Case #588253)================

A database upgrade would not have added execute permissions to "public" on
the recreated procedure sp_password. This has been fixed.

================(Build #3882 - Engineering Case #583380)================

The server may have returned the error "-890: Statement size or complexity
exceeds server limits", or needed a very long time to complete, for very
complex statements that used proxy tables and alias names that depend on
many other alias names. During the Describe Output or Open of the statement,
the server may have consumed a large amount of cache space and blocked other
requests. This has been fixed.

================(Build #3878 - Engineering Case #585979)================

Using the BCP utility to insert data into a table could have failed with
a protocol error, if the version of Open Client that BCP used was older.
This problem has now been fixed.

================(Build #3861 - Engineering Case #580598)================

Tools such as the Data Source utility (dbdsn), which need to run as an elevate
process to perform privileged operations on Windows Server 2008 R2, failed
to do so and would have reported errors when run in an unelevated command
shell. This has been fixed.

================(Build #3860 - Engineering Case #580004)================

When describing arguments of a stored procedure called with non-positional
arguments, no information was returned from the server.

For example:
CREATE PROCEDURE foo ( IN a INTEGER, OUT b INTEGER )
BEGIN
SET b = a * 2
END

No information was returned when describing input arguments for the statement
"call foo( b=?, a=?)". This has been fixed.

================(Build #3857 - Engineering Case #579150)================

The server may have crashed if a statement that referenced a proxy table
was very complex and used alias names that depended on many other alias names.
This has been fixed.

================(Build #3856 - Engineering Case #578933)================

The FORWARD TO statement could have truncated the forwarded statements to
roughly a database page size in length. This has been fixed.

================(Build #3855 - Engineering Case #580168)================

When a NUMERIC or DECIMAL column with precision greater than 47 was fetched
using OLE DB, ODBC, or JDBC, a memory buffer overrun would have occurred.
This would have resulted in a corrupted heap. The client application may
then terminate unexpectedly due to the corrupted heap. This problem has been
fixed.

================(Build #3854 - Engineering Case #578191)================

If a server had request-level logging enabled (eg -zr sql command line option)
while the stored procedure debugger was being used (ie Sybase Central was
in "Debug mode"), the server could have crashed. This problem has been fixed.

================(Build #3852 - Engineering Case #578153)================

If a database created with a version 9 or earlier server was backed up via
the Backup utility (dbbackup), or the BACKUP DATABASE statement, the backup
copy could not have been unloaded using the Unload utility from version 10
or later. This has been fixed.

================(Build #3849 - Engineering Case #576913)================

If an application executed a remote query that must be handled in NO PASSTHRU
mode, and the query contained many tables, then it was possible for the server
to fail assertion 101508, instead of giving the "syntactic limit exceeded"
error. This problem has now been fixed, and the error is now properly returned.

================(Build #3847 - Engineering Case #576263)================

If the CREATE DATABASE statement was used to create a database with a filename
that contained a \n (for example CREATE DATABASE 'c:\\new.db'), the file_name
column in the SYSFILE system table could have been incorrect. An incorrect
file_name value would only have occurred if the CREATE DATABASE statement
was issued when connected to a database other than the utility_db. This has
been fixed.

Note, this problem did not affect the Initialization utility (dbinit), or
applications calling the dbtools library.

================(Build #3845 - Engineering Case #576009)================

The size of the stack used by some database server threads was not governed
by the -gs and -gss server command line options. Some of these threads used
stacks that were excessively large (1MB) for a CE environment, and could
have lead to problems loading DLL's on some CE systems. These stack sizes
have been reduced to 64K or less. The default stack size for request tasks
is unchanged at 96K. Some versions did not allow a -gss value of less than
96K, but now values as low as 64K are permitted.

================(Build #3842 - Engineering Case #574912)================

If a database contained a DISCONNECT event handler called E, and a transaction
log containing a DROP EVENT E statement was applied to the database, recovery
could have reported failed assertion 100904 ("Failed to redo a database operation
... Event E in use"). This has been fixed.

================(Build #3840 - Engineering Case #562236)================

In some cases, client applications running on Solaris systems may have hung
while communicating with the server through shared memory. Other symptoms
may also have included communication errors between the client and the server.
This was more likely
to happen on multi-processor machines. This has been fixed.

================(Build #3838 - Engineering Case #573636)================

After performing a database backup, a warning message of the form "Unable
to open backup log '...'" could have been sent to the client and console.
Note that this warning came as a "message" to the client, not as a warning
SQLCODE from the BACKUP statement. The problem was far more likely to have
occurred on Windows Vista or later when running as a non-elevated process,
as the server typically tried to write the log into the SQL Anywhere installation
directory which is not typically writable by non-elevated pocesses. This
problem was fixed by properly detecting which of the possible directories
for placement of backup.syb were writable, and adding the %ALLUSERSPROFILE%\SQL
Anywhere XX (XX=version number) directory to the list of possible directories.
On Vista and later, the %ALLUSERSPROFILE% directory is typically C:\ProgramData.
On earlier versions of Windows, it is typically C:\Documents and Settings\All
Users\Application Data.

================(Build #3837 - Engineering Case #573452)================

Fetching a result set may, on rare occasions, have caused an application
that connected using a newer version of Open Client 15 to hang or give a
protocol error. In addition, cancelling a request may also have caused the
application to hang or give a protocol error. These problems have now been
fixed.

Please note that if an application does use Open Client 15 to connect to
SQL Anywhere, then it will be necessary to update the version of Open Client
15 once this fix is installed.

================(Build #3836 - Engineering Case #564304)================

The server may have crashed when simple SELECT statements are executed against
the utility database. This has been fixed.

================(Build #3835 - Engineering Case #571957)================

The server could have generated a dynamic memory exhausted error when trying
to execute
a very complex statement. This has been fixed. The server will now return
the SQL error
SQLSTATE_SYNTACTIC_LIMIT.

================(Build #3833 - Engineering Case #571242)================

If a non-existent stored procedure was called with argument names in the
CALL statement, the server would have returned the misleading error message:
"Parameter '' not found in procedure '???'". This has been fixed so that
a prcedure not found error is returned.

================(Build #3833 - Engineering Case #570928)================

If a statement was executed with a hash group by operator, and there was
an aggregate function AGG( DISTINCT x ) for a blob value x, it was possible
in some situations for the server to have crashed. This has been fixed.

================(Build #3829 - Engineering Case #569931)================

If a user-defined function using the Transact-SQL dialect issued a RAISERROR
statement, and that function was called from another Transact-SQL function,
the calling application could have failed to receive the error. In some cases,
this would result in the application hanging. This has been fixed.

================(Build #3828 - Engineering Case #570094)================

The server would have crashed when parsing a procedure that contained a CASE
statement with a WHEN clause which had an unary search condition other than
ISNULL. When unparsing the WHEN clause the server was expected a binary search
condition and crashed when attempting to access the second operand. This
has been fixed.

================(Build #3827 - Engineering Case #570308)================

Attempting to return a result set from within a BEGIN ATOMIC block would
caused a memory leak in the server. This has been fixed.

Note that returning a result set from within an atomic block is not allowed,
and an error is issued in this case. This behaviour has not changed.

================(Build #3824 - Engineering Case #568991)================

Connecting to the server using Open Client and attempting to describe the
input parameters of a dynamic statement, would very likely have cause the
application to hang. This problem has now been fixed.

================(Build #3823 - Engineering Case #568455)================

If an application executed a statement of the form IF EXISTS( SELECT ...
FROM proc(), remote_tab ...) where proc() was a stored procedure that returned
a result set and remote_tab was a proxy table, then itwas likely that the
server would have crashed. This problem has now been fixed.

================(Build #3823 - Engineering Case #567543)================

If the WHERE clause of a query block contained many predicates using host
variables, it was possible that the PREPARE or OPEN times would have been
unnecessarily long. The server was not recognizing the two expressions with
host variables were the same. his has been fixed.

================(Build #3819 - Engineering Case #567570)================

It was possible for the server to enter a loop while processing some statements
that included an implicit or explicit use of the table SYS.DUMMY. This has
been fixed.

================(Build #3816 - Engineering Case #566693)================

On certain processors other than x86 and x86_64 (64 bit HP-UX for example),
the server may have crashed in extremely rare conditions when using a connection
number to get connection information. Examples of getting this type of connection
information include getting a connection property for another user, or calling
sa_conn_info. This has now been fixed.

================(Build #3812 - Engineering Case #566043)================

When working with .NET data sources and the OLEDB adapter using Visual Studio,
the Configure Dataset with Wizard dialog may have resulted in "Dynamic SQL
generation is not supported against a SelectCommand that does not return
any base table information." or theTableAdapter Query Configuration Wizard
dialog may have resulted in "Failed to get schema for this query". The SQL
Anywhere OLE DB provider has been corrected.

================(Build #3809 - Engineering Case #565835)================

The server may have crashed if the procedure debugger's connection, and the
debugged connection, stopped at the same time. This has been fixed.

================(Build #3807 - Engineering Case #563344)================

In certain situations, the server could have crashed while processing a hash
join. This has been fixed.

================(Build #3806 - Engineering Case #564677)================

A failed COMMENT ON PROCEDURE statement could have prevented the procedure
from being dropped. This has been fixed.

Note, a workaround is to stop and restart the database before attempting
to drop the procedure.

================(Build #3806 - Engineering Case #562957)================

The server may have crashed when executing a Group By Indexed strategy for
a SELECT
statement. This has been fixed.

================(Build #3804 - Engineering Case #564010)================

The server may have crashed if a floating point value was converted to a
string, and then subsequently cast to a string with a too small size. This
has been fixed.

================(Build #3803 - Engineering Case #562829)================

When querying a proxy table mapped to a remote ASE or Microsoft SQL Server
table, if the remote table had a varchar(255) column, then fetching data
from that column would have resulted in data truncation. This was due to
an off-by-one error, which has now been corrected.

================(Build #3802 - Engineering Case #536966)================

The server may have crashed if a rank function (see SQL Functions->Function
types->Rank functions in the SQL Usage guide) was used on constants. The
row_number() function in the example below:

select x from ( select V1.*, row_number() over ( order by b ) AS x
from ( select *, 7 as b from T1 order by 1 ) V1
) V2

is used on column "b" of the nested table expression "V1", and column "b"
is a constant there. This has been fixed.

================(Build #3801 - Engineering Case #562838)================

Applications using the Broadcast Repeater utility were not able to find servers
running on Linux machines on a different subnet using broadcasts. The server's
broadcast response was being malformed. This has now been corrected.

================(Build #3801 - Engineering Case #562534)================

Executing a query of the form "select ... into #temp ...", or a query with
a stored procedure in the FROM clause, may have caused the server to crash.
This would have occurred if the statement contained a CONVERT or CAST function
call to a user-defined type, or a WITH( column-name <user-defined type>,
...) clause. This has been fixed.

================(Build #3801 - Engineering Case #536347)================

Executing a LOAD TABLE statement with the clause CHECK CONSTRAINTS OFF, may
have failed if the table being loaded had publications. This has been fixed.

================(Build #3798 - Engineering Case #560935)================

Restoring a database from a backup archive using the RESTORE DATABASE command
with the RENAME option could have corrupted the transaction log associated
with the restored database. Translating the transaction log file using the
dbtran.exe utility would have resulted in an error indicating that the log
was missing a CONNECT operation. This has been fixed.

================(Build #3797 - Engineering Case #561553)================

When a query of the form "SELECT f(c) from t where t.c < 5", where f() was
a user-defined function and t was a proxy table, was executed the server
would have attempted to push the "where c < 5" to the remote server in order
to reduce the number of rows being returned. Unfortunately, due to the fix
for Engineering case 555959, this behaviour was changed such that the WHERE
clause was no longer getting pushed to the remote, resulting in more rows
being fetched from the remote than necessary. Note that the fix for case
555959 resulted in a performance degradation only, the resulting result set
was still correct. Nevertheless, this has now been resolved and the WHERE
clause will now properly be pushed to the remote server when it is safe to
do so.

================(Build #3795 - Engineering Case #557465)================

In exceptionally rare circumstances, the server may have crashed during the
rewrite phase of optimization, when attempting to execute a very large and
complex SELECT statement. This may have occurred when the server was close
to running ouf of stack space, or was low on cache. The problem was seen
with queries containing UNION, EXCEPT, INTERSECT, and deeply nested subselects.
This has been fixed. The server will now correctly return the error "-890:
Statement size or complexity exceeds server limits".

================(Build #3792 - Engineering Case #560080)================

If a user-defined function was created with the DETERMINISTIC keyword, the
parsed version of the CREATE FUNCTION sstatement that was placed in the catalog
did not contain this keyword. The function may not then have been treated
as deterministic, and if it was unloaded, the CREATE FUNCTION statement would
also not have contained the keyword. This has been fixed.

Note, to fix existing user-defined functions created with DETERMINISTIC,
the function will need to be recreated.

================(Build #3791 - Engineering Case #559898)================

If an application made use of one of the Remote Data Access JDBC classes,
and the application then disconnected abnormally, then the connection to
the remote server was never closed. The problem did not exist if the application
used one of the Remote Data Access ODBC classes instead. This problem has
now been fixed.

================(Build #3791 - Engineering Case #557812)================

If an UPDATE or DELETE statement used a keyset cursor and the statement executed
at isolation level 0 or 1, it was possible for the statement to update or
delete rows improperly. This could have occurred if another transaction deleted
a row identified by the UPDATE or DELETE statement and committed, and then
another transaction inserted a row and committed before the UPDATE or DELETE
statement had finished processing. In this case, the newly inserted row would
have been improperly processed by the UPDATE or DELETE statement. DELETE
and UPDATE statements use a keyset cursor if there is a possibility that
an updated row could be re-processed by the statement (for example if an
UPDATE modifies a column in the index scan, or if a join is present). This
has now been fixed.

A workaround would be to use a higher isolation level (2 or 3).

================(Build #3789 - Engineering Case #558446)================

Executing an insert statement of the form: 'INSERT INTO <remote table> ON
EXISTING UPDATE SELECT * FROM <table>', would have caused the server to correctly
return an error; but, if the application attempted to execute an insert statement
of the form: 'INSERT INTO <table> ON EXISTING UPDATE SELECT * FROM <remote
table>', the server would have crashed. The problem has now been fixed and
the server now correctly returns an error in both cases.

================(Build #3788 - Engineering Case #558756)================

Attempting to execute a query that referenced a view containing a remote
query, could have crashed the server. The crash would have occurred if the
remote query had both GROUP BY and HAVING clauses, and/or aliases. This problem
has now been fixed.

================(Build #3782 - Engineering Case #557679)================

When running a 64-bit version of perfmon, the Adaptive Server Anywhere or
SQL Anywhere counters would not have been displayed if the 64-bit version
of the counters library (dbctrsX.dll) was registered and the 32-bit version
was not. This has been corrected.

Note, both versions of the counters library are registered during a normal
product installation so it is unlikely that users would encounter this problem.

================(Build #3780 - Engineering Case #555959)================

If an application executed a remote query that involved a User Defined Function,
and the call to the function passed in column references as parameters, there
was a chance the server would have crashed when the server decided to run
the query in partial passthru mode. This problem has now been fixed.

================(Build #3770 - Engineering Case #553752)================

If a CREATE SYNCHRONIZATION SUBSCRIPTION statement was executed with an OPTION
clause that gets the option value from a variable (e.g. OPTION sv=@Var) and
the variable was set to null, then the server may have crashed, or inserted
a random option value into the catalogs. This has been fixed so that the
server now returns a sql error (SQLSTATE_BAD_SYNC_OPTION_VALUE) "Synchronization
option '%1' contains semi-colon, equal sign, curly brace, or is null".

================(Build #3770 - Engineering Case #543478)================

In very rare circumstances, an auto-shutdown of a database could have caused
the server to crash, if the server was in the process of shrinking the cache
at the same time. This problem has been fixed.

================(Build #3765 - Engineering Case #552591)================

If an Open Client or jConnect application executed a query that involved
the use of host variables within a batch, then the server would have crashed,
rather than giving the "Host variables may not be used within a batch" error
message. This problem has now been fixed.

================(Build #3765 - Engineering Case #552587)================

If an application created a remote server and then accessed that remote server
using a different case than the one specified on the CREATE SERVER statement,
the server would have incorrectly opened additional connections to the remote
server. For example, suppose the application executed the following CREATE
SERVER statement:

CREATE SERVER MyServer CLASS ...

and then created two proxy tables as follows:

CREATE EXISTING TABLE table1 AT 'myserver...'
CREATE EXISTING TABLE table2 AT 'MYserver...'

If the application now queried "table1", the remote data access layer would
have correctly established a connection to the remote and returned the requested
data. If the application then queried "table2", the data access layer should
reuse the connection previously established to the remote, but the server
instead would have created a new connection to the remote. This problem has
now been fixed.

================(Build #3764 - Engineering Case #552312)================

The changes made for Engineering case 541615 introduced a problem where attempting
to create a proxy table to a DB2 or Microsoft SQL Server table using Sybase
Central could have failed with a strange conversion error, instead of creating
the proxy table. This problem has now been corrected.

================(Build #3762 - Engineering Case #551944)================

The fix for Engineering case 549983 introduced a problem such that two simultaneous
remote data access requests from two separate connections could have caused
the server to crash. This problem has now been fixed.

================(Build #3762 - Engineering Case #551850)================

Attempting to execute a badly formed UPDATE statement of the form "update
test X set X..a = 2", where test is a proxy table, would very likely have
lead to a server crash. This problem has now been fixed.

================(Build #3762 - Engineering Case #548473)================

When a version 9 server was used to run a databases created with version
7 or older, the server could have choosen inefficient query access plans
due to errors in estimation of join selectivities. These database do not
contain column statistics in the form of domain distribution histograms stored
in the system table SYSCOLSTAT, as with later version. This has been corrected
so that the server will now do a much better job of estimating these selectivities.

================(Build #3761 - Engineering Case #551740)================

If a query contained an outer join and a predicate of that included the concatenation
operator (||), then the server could have returned the incorrect answer for
the query. In the incorrect case, the outer join was converted to an inner
join. This has been fixed.

For example, the following two queries should be equivalent, but the first
incorrectly returned no rows:

select R.row_num || 'z' x, string(R.row_num ,'z') y
from dummy D left outer join rowgenerator R on 1=0
where x = 'z'

select R.row_num || 'z' x, string(R.row_num ,'z') y
from dummy D left outer join rowgenerator R on 1=0
where y = 'z'

================(Build #3760 - Engineering Case #547496)================

A long-running HTTP connection to an OEM server would have resulted in an
authentication violation. This was corrected by making all HTTP connections
authenticated by default.

================(Build #3759 - Engineering Case #551690)================

If a request was made that was larger than the packet size, then, in rare
timing dependent cases, the connection could have hung until it was cancelled
or dropped. Examples of requests larger than the packet size include executing
a statement with long SQL text, or executing a statement with large host
parameters. This has now been fixed.

================(Build #3756 - Engineering Case #550676)================

Attempting to construct a string value longer than the server's maximum string
length (2^31-1) would have resulted in silent trucation of string data.
For example, the statement:
select length(repeat('a', 2000000000) || repeat('b', 2000000000))

returns 2147483647 (i.e., 2^31-1) characters, but does not raise a SQL error
to indicate the operation failed and truncated the string data. This has
been fixed so that SQL Error -1313 MAX_STRING_LENGTH_EXCEEDED will now be
generated whenever an operation attempts to construct a string value longer
than the server's internal maximum string length.

================(Build #3755 - Engineering Case #550095)================

If a query execution plan contained a Group-By Hash operator and one of the
aggregates computed was marked as DISTINCT, then the server could have crashed
while executing the statement. In order for the crash to occur, specific
characteristics needed to be present in the statement. Thishas now been fixed.

================(Build #3753 - Engineering Case #549940)================

If a transaction log was not completely written out to disk (e.g. during
a low disk space scenario), it was possible for the server to crash when
trying to apply a partial log operation during recovery. This has been fixed.

================(Build #3752 - Engineering Case #550116)================

In rare cases, a stored procedure call could have caused a server crash.
This has been fixed.

================(Build #3752 - Engineering Case #549983)================

If an application executed a query involving both proxy tables and local
tables, and the query had IN predicates that contained subqueries involving
proxy tables, then there was a chance executing the query would have caused
a server crash. This problem has now been fixed.

================(Build #3750 - Engineering Case #549453)================

When manually unregistering the SQL Anywhere ODBC driver from the command
line using "regsvr32 -u dbodbcXX.dll", the unregistration process may have
failed and reported error code 0x8000ffff. Note that the failure occurred
after the user successfully acknowledged the prompt to allow dbelevate (the
"SQL Anywhere elevated operations agent") to run as an administrator. This
problem has been fixed.

As a work-around, run "regsvr32 -u dbodbcXX.dll" from a command shell which
is already elevated.

================(Build #3750 - Engineering Case #549419)================

If an Open Client application that supports retrieving result sets with a
large number of columns attempts to perform an encrypted login, the login
would have failed with a protocol error. This problem has now been fixed.

================(Build #3750 - Engineering Case #496087)================

In rare instances, assertion failure 201822 "Checkpoint log: attempt to allocate
before recovery is complete" could have been reported during database recovery.
The problem has been fixed. If this problem is encountered, recovery with
a server containing this fix should complete normally.

================(Build #3741 - Engineering Case #547513)================

When running the server on Unix systems and using the -m command line option
("truncate transaction log after checkpoint"), the transaction log was not
being truncated on checkpoints. This has been fixed.

================(Build #3736 - Engineering Case #536805)================

Grouping queries containing a CUBE, ROLLUP or GROUPING SETS clause may have
returned incorrect results. The query must also have had a HAVING clause
with at least one null sensitive predicate (e.g., 'T.C IS NULL' , 'T.C IS
NOT NULL' ). This has been fixed.

An example:
select dim1, dim2, sum (val1), stddev (val2)
from tt
group by cube (dim1, dim2)
having dim1 is not null or dim2 is not null

================(Build #3733 - Engineering Case #546854)================

If a query contained DISTINCT, ORDER BY and GROUP BY clauses and an expression
in the ORDER BY clause appeared in the the GROUP BY clause, but not in the
SELECT list, then the wrong error was returned, namely "Function or column
reference to ... must also appear in a GROUP BY." This has been fixed so
that the correct error message: "Function or column reference to .. in the
ORDER BY clause is invalid."

For example, the query:
SELECT DISTINCT X
FROM T
GROUP BY E
ORDER BY E
Would have returned the error: "Could not execute statement. Function or
column reference to 'E' must also appear in a GROUP BY." SQLCODE=-149, ODBC
3 State="42000"

================(Build #3732 - Engineering Case #545374)================

When using the SQL Anywhere ODBC driver, if SQLBindCol was called immediately
after a SQLFetch and before calling SQLBulkOperations( SQL_UPDATE_BY_BOOKMARK
), then the SQLBulkOperations update would have failed. This problem has
been fixed.

================(Build #3732 - Engineering Case #544187)================

A server could have failed to start if another server was starting at the
same time. The server that failed to start would have displayed the error
"Database cannot be started -- No such file or directory". The error message
was also misleading since the database file did exist; the server actually
had a problem opening the database's temporary file. This has been fixed.

================(Build #3731 - Engineering Case #582756)================

The changes for Engineering case 544187 caused the server to have a limited
number of temporary files that it could create in the lifetime of the server
process (64K on non-UNIX systems, 4G on UNIX systems). The problem would
have shown up as an error writing to an invalid handle, and a fatal "disk
full" error would have been reported. On Windows, the message in the server
console would have looked like the following:

A write failed with error code: (6), The handle is invalid.
Fatal error: disk full when writing to "???"

This problem has been fixed.

A related problem was also fixed where failure to create a temporary file
for the utility_db would have cause the server to crash.

================(Build #3730 - Engineering Case #544791)================

In rare timing dependent cases, the server could have hung on shutdown, or
possibly failed in other ways, after executing a DROP CONNECTION statement.
This has now been fixed.

================(Build #3730 - Engineering Case #544669)================

If a column histogram incorrectly contained a selectivity estimate of 100%
for the NULL values, the best plan found by the optimizer could have been
very inefficient. This problem affected the computation of the selectivity
estimation of predicates of the form "T.X theta expression" (theta can be
=, <>, >, >=, < or <=) which would have incorrectly been computed as 0%.
A change has been made to the optimizer so that it no longer trusts a NULL
selectivity estimation of 100%, instead it uses the computed selectivity
estimation of (100% - epsilon).

To test the estimated selectivity of the NULL values for a column T.X use:
"select first estimate(X, null) from T".

A workaround is to recreate statistics on the column T.X by using: "create
statistics T (X)". However, if the column T.X has often only NULL values,
and then it is updated to some non-null values, it is recommended to upgrade
to a server containing this fix.

================(Build #3730 - Engineering Case #544191)================

In some circumstances, host variable references in batches could have caused
a server crash. This has been fixed so that the error "Host variables may
not be used within a batch" is now returned.

================(Build #3729 - Engineering Case #544496)================

If the server was started with the "-x none" command line option, and without
the -xs option, then calling an external web procedure would have caused
the server to crash. This has been fixed.

================(Build #3727 - Engineering Case #544486)================

If an application connected using Open Client attempted to fetch a result
set containing a large number of columns (more than 3000), then the application
would have failed with a TDS protocol error. This problem has now been fixed.

Note, that in order to fetch such a result set, the application must be
using Open Client 15.

================(Build #3727 - Engineering Case #543910)================

The version 10 and 11 servers were truncating 32-byte names to 31 bytes.
So when a version 10 or 11 client attempted a shared memory connection specifying
a 32-byte server name that had a common prefix of exactly 31 bytes with a
running version 10 or 11 server that also has a 31-byte name, the connection
attempt would have failed. As well, if a version 10 or 11 client attempted
a shared memory connection specifying a server name that had a common prefix
of exactly 31 bytes with a running version 9 or prior server that had a name
longer than 31 bytes, the connection attempt would have failed. This problem
has been fixed. Note that for version 10 and 11, the fix affects both client
and server. For version 9, the fix is just to the server. However, an unmodified
version 10 or 11 client will be able to establish such a connection against
an unmodified version 9
server.

================(Build #3726 - Engineering Case #543272)================

Second and subsequent connections from a single application may have used
TCP/SPX options specified by the first connection made by that application
using the same protocol. This could potentially have resulted in a connection
being made to the wrong server. This has been fixed.

================(Build #3725 - Engineering Case #544069)================

The server could have crashed if two or more connections were simultaneously
scanning a table for the first time after the server was started. This has
been fixed.

================(Build #3723 - Engineering Case #543562)================

If an application was connected using jConnect and attempted to fetch a result
set containing a large number of columns (more than 3000), then the application
would have failed with a TDS protocol error. This problem has now been fixed.
Note, that in order to fetch such a result set, the application must be
using jConnect 6.x.

================(Build #3723 - Engineering Case #543525)================

Issuing a REMOTE RESET, or granting REMOTE to a user, when the log offset
was larger than 4GB could have caused the server to crash. This has been
fixed.

================(Build #3721 - Engineering Case #530736)================

The changes for Engineering case 491180 (enable write through on CE) introduced
a dependency on the file note_prj.dll, which may not have been included on
non-standard Windows CE devices. On these devices, the server may have failed
to start with an error that it could not find the server or one of its components.
The Standard Windows Mobile devices were not affected. This has been corrected
and note_prj.dll is now loaded dynamically, and if it is not found, the server
will not enable write through on pre CE 5 devices.

================(Build #3720 - Engineering Case #543002)================

An HTTP server response returning an error status, such as "404 Not Found",
was returned in the server's language and the Content-Type header incorrectly
specifies charset=ISO-8859-1. This has been fixed so that HTTP status messages
are now always returned in the English language. Therefore the Content-Type
header charset=ISO-8859-1 will now be correct.

================(Build #3720 - Engineering Case #542840)================

If a Disconnect event was defined and a connection was dropped using DROP
CONNECTION, the value of event_parameter('DisconnectReason') would have been
incorrect when evaluated inside the event handler. This has been fixed.

================(Build #3716 - Engineering Case #542524)================

If an application on a Unix system used the iAnywhere JDBC driver to connect
to a DB2 server using a 64-bit DB2 ODBC driver, then calling the Connection.getTransactionIsolationLevel()
method may have crashed the client. This problem has been fixed.

================(Build #3716 - Engineering Case #542522)================

In rare cases, executing an invalid ALTER PROCEDURE statement could have
caused a server crash or an incorrect error message. This has been fixed.

================(Build #3716 - Engineering Case #542519)================

If an application made a large number of remote calls to fetch data from
a JDBC based Remote Data Access server, then there was a chance the server
would have crashed. For this problem to have occurred, the remote table and/or
column names must have been longer than 30 characters. This problem has now
been fixed.

================(Build #3716 - Engineering Case #542397)================

The DISH service does not set the HTTP Content-Type response header, which
has occasionally caused Internet Explorer 7 to fail to render the WSDL. This
has been fixed so that the response headers now include Content-Type: text/xml;
charset="utf-8".
Note, the charset qualifier is not included in 9.0.2 since its output is
in database character set. This change is in accordance with the WSDL 1.1
specification, see http://www.w3.org/TR/wsdl#_Toc492291097.

================(Build #3714 - Engineering Case #542342)================

If a conversion error occurred while constructing the string to be executed
by EXECUTE IMMEDIATE within a procedure, the error might not have been reported,
possibly leading to a server crash. This has been fixed.

================(Build #3713 - Engineering Case #541615)================

If an application made a remote procedure call to a procedure that returned
a result set with unsigned data types, there was a possibility that the call
would have failed with a conversion error. This problem has now been fixed.

================(Build #3713 - Engineering Case #540965)================

If a LOAD TABLE statement was executed on a table with an autoincrement column
and caused the range of values for the autoincrement column to be exhausted,
the server would have crashed. This has been fixed, and a "Column '<column-name>'
in table '<table-name>' cannot be null" error is now given.

================(Build #3710 - Engineering Case #540681)================

Running out of non-cache memory may have caused the server to hang. This
has been fixed.

================(Build #3708 - Engineering Case #540371)================

In rare circumstances, the server could have crashed while disconnecting,
if the connection had created temporary procedures. This has been fixed.

================(Build #3708 - Engineering Case #540220)================

The server could have hung, or even crashed, if an HTTP or HTTPS connection
was cancelled (i.e. the client application closed the socket) while a request
was being processed. This has been fixed.

================(Build #3708 - Engineering Case #540205)================

If a remote server was defined using one of the Remote Data Access JDBC classes,
then changing the value of the quoted_identifier option would not have resulted
in changing the value of the quoted_identifier option on the remote. This
problem has now been fixed.

================(Build #3702 - Engineering Case #538275)================

If a query execution plan contained a Group-by Ordered (GrByO) operator in
a particular stylized access plan pattern containing an outer joing, and
the group-by node had a string or NUMERIC value in the result, then it was
possible for the server to crash while processing the statement. The crash
would have depended on the order and values of rows processed by the plan.
This has been fixed.

================(Build #3701 - Engineering Case #538484)================

The server allows the use of host variables with the INSERT statement, to
insert multiple rows into the database in a single request. Under certain
circumstances, the server could have crashed when block inserts were executed
in the server. This has been fixed so that the server now generates an error
message instead in these circumstances.

================(Build #3701 - Engineering Case #538480)================

In rare circumstances, the server could have crashed while disconnecting
if -zl, -zp, sa_server_option( 'RememberLastStatement', 'YES' ) or sa_server_option(
'RememberLastPlan', 'YES' ) were used. This has been fixed.

================(Build #3697 - Engineering Case #537800)================

If an application executed a remote query with a malformed field or dotted
reference in the select list, then it was possible that the server could
have crashed. An example of such a query is:
select c1.ref(), max( c2 ), c2 from t1
where c1.ref() is a meaningless expression. This problem has now been fixed
and a proper error message will be returned to the application.

================(Build #3683 - Engineering Case #533724)================

The server would have crashed if the sa_locks() system procedure was executed
when it was running in bulk operation mode (-b server command line option).
This has been fixed.

================(Build #3682 - Engineering Case #532109)================

A query containing a derived table, or a subquery with a OUTER JOIN whose
ON condition references tables from outside the query block, may have returned
incorrect results. This has been fixed.

In the following example, the ON condition of the LEFT OUTER JOIN in the
EXISTS subquery references the table 't1', which is a table used in the FROM
clause of the main query block. This query may return incorrect result for
some instances of the database.

select * from t1
where exists(
select 1
from t4
left outer join t2 on ( t2.c1 = t4.c1 and t2.c1 = t1.c1 )
where t4.c1=1
)

================(Build #3681 - Engineering Case #533600)================

When using a derived table in a remote query, if one or more columns from
the derived table were referenced in the WHERE clause of the query, and the
query was going to be processed in full passthru, then the engine would have
returned with a "correlation name not found" error. This problem has now
been fixed.

================(Build #3678 - Engineering Case #532850)================

Executing a CREATE EXISTING TABLE statement to create a proxy table when
the remote table has an unsupported index on it, could have caused the statement
to fail. This problem has now been fixed.

================(Build #3678 - Engineering Case #532276)================

A large query containing a 'WITH' clause could have crashed the server. The
server was failing to recognize a SYNTACTIC_LIMIT error for such queries.
This has now been corrected.

================(Build #3676 - Engineering Case #532102)================

The changes made for Engineering case 483518 caused the server to crash if
a call to the graphical_plan() function was made within an event handler.
This has now been corrected.

================(Build #3675 - Engineering Case #531784)================

If an Open Client or jConnect application executed a query that involved
the use of host variables within a batch, then the server would have crashed.
This has been fixed so that the query now correctly fails with the error
message "Host variables may not be used within a batch".

================(Build #3674 - Engineering Case #531295)================

The server could have crashed while optimizing complex queries. This has
been fixed

================(Build #3674 - Engineering Case #531081)================

The changes for Engineering case 486744 introduced a problem where the server
could have crashed while executing a BEFORE UPDATE row level trigger. This
has been fixed.

================(Build #3671 - Engineering Case #530576)================

The http_encode() function was not encoding the 0x1f character. This has
been fixed. This character is now encoded to "%1F".

================(Build #3670 - Engineering Case #530339)================

If an application had a connection enlisted in Microsoft's Distributed Transaction
Coordinator (DTC), and it issued a commit on the distributed transaction,
then there was a chance the server would have hung when a request to enlist
in the DTC came in at the same time as the two phase commit. This problem
has now been fixed.

================(Build #3669 - Engineering Case #530054)================

When using CSCONVERT() to convert a string to UTF16, incorrect results could
have been produced. This has now been corrected.

===============(Build #36666 - Engineering Case #529203)===============

The changes made for Engineering case 495396 inadvertently caused database
names to be limited to a length of 40 bytes. This has been fixed so that
database names are now correctly limited to 250 bytes.

================(Build #3666 - Engineering Case #528627)================

Selectivity estimates could have been incorrectly updated if a query with
predicate of the form "T.x <op> expr( T.y ) or expr( T.y ) <op> T.x" was
executed. These
incorrect predicate selectivity estimates could have lead to lower quality
query access plans. When "expr" was an expression referencing one (or more)
columns of table with correlation name T, selectivity estimates could have
be updated with the assumption that "expr(T.y)" was constant for the duration
of the query. This has been fixed.

For example:
SELECT t.x, t.y, t.z
FROM tx AS t
WHERE t.x <= t.y + 1

================(Build #3665 - Engineering Case #500900)================

A validation check was missing when a SOAP request was made through a DISH
service endpoint. This has been fixed.

================(Build #3664 - Engineering Case #523745)================

The server automatically maintains columns statistics, in the form of histograms,
to capture the data distribution. Under some specific circumstances, the
server could have applied incorrect modifications to the automatically maintained
statistics, resulting in potentially poor query access plans. Symptoms of
this problem would often have been the presence of duplicate boundary values
in the result set of system procedure sa_get_histogram(). This has been corrected
by an update to the server's histogram maintenance algorithms.

================(Build #3662 - Engineering Case #500302)================

A SQL Anywhere SOAP SERVICE Soapfault was returned with the HTTP response
header "Content-Type: text/html" when the given service had encountered a
protocol or parse error. This has been fixed; a "Content-Type: text/xml"
is now returned.

================(Build #3661 - Engineering Case #499702)================

Queries using the set operators UNION, EXCEPT or INTERSECT, on tables with
publications, may have returned a "column/table 'x' not found" error. This
has been fixed.

================(Build #3660 - Engineering Case #499897)================

When a remote procedure call was made, if it contained a bigint parameter
then an incorrect value for the bigint parameter would have been sent to
the remote server. This problem has now been fixed.

================(Build #3658 - Engineering Case #499252)================

HTTP response headers were not set as expected if the SERVICE made a nested
call to an inner procedure from where the sa_set_http_header() system procedure
was called. Headers cannot be set by the inner procedure because the server
has already sent the headers prior to the call. This has been fixed so that
calling sa_set_http_header, when the HTTP headers have already been sent,
will now result in a SQL error: Invalid setting for HTTP header.

================(Build #3658 - Engineering Case #499250)================

When creating or altering a SERVICE that required a statement, a check was
missing to ensure that the service was properly configured with either a
SELECT or a CALL statement. A misconfigured service would have always returned
a '400 Bad Request' HTTP status for all requests. This has been fixed.

================(Build #3658 - Engineering Case #499233)================

The server may have got into an infinite loop trying to convert an invalid
date, time or timestamp value to an integer. This has been fixed.

================(Build #3658 - Engineering Case #499112)================

In certain cases where character set conversion was applied to character
data, the server could have gone into an infinite loop, consuming nearly
100% of CPU usage. For this problem to have occurred, the source string must
have either contained null bytes, or characters that were ill-formed or illegal
in the database character set. This has been fixed.

================(Build #3656 - Engineering Case #498583)================

The server would have rejected a SOAP request containing XML comments with
a '400 Bad Request' status. This has been fixed. Comments are now ignored
by the server.

================(Build #3656 - Engineering Case #498337)================

Queries with complex WHERE condition containing at least one element of the
form "( col1 > constant1 AND col1 < constant2 ) OR expression", with constant1 <
constant2, may have incorrectly returned more rows.

For example the following query will return rows with value 0 and 8 for
column "a":
SELECT a FROM T1
WHERE
( a > 0 AND a < 2 ) OR ( a > 1 AND a < 3 ) OR ( a > 2 AND a < 4 ) OR
( a > 3 AND a < 5 ) OR ( a > 4 AND a < 6 ) OR ( a > 5 AND a < 7 ) OR
( a > 6 AND a < 8 ) OR ( a > 8 AND a < 10 ) OR ( a > 9 AND a < 11 ) OR
( a > 10 AND a < 12 ) OR ( a > 11 AND a < 13 ) OR ( a > 12 AND a < 14 )

This has been fixed.

================(Build #3655 - Engineering Case #497646)================

If a database connection ended and the JVM stopped, the Java class finializers
were not called, which is correct Sun JDK behaviour. If Java classes had
opened network or JDBC connections to other servers or applications, then
these connections were not closed as well. In order to close these connections,
or to release other resources, the application can call the Java method System.runFinalizersOnExit(
true ), which force the JVM to run the finalizers of all not finalized classes.
Althrough the call is deprecated in JDK 1.2 and above, it will still work
in these versions. In version 10 and above applications can also use shutdown
hooks to release resources. A fix has been now made so that the finalizers
now run correctly at JVM stop, if the above method has been called. If no
class instance is created, and a resource assigned to a static member should
be released, the application may use an Uninit class as in the sample below:

public class SampleClass {
private static Uninit uniniter = null;
public static Connection conn = null;

static {
try {
uniniter = new Uninit();
System.runFinalizersOnExit( true );
conn = DriverManager.getConnection( "jdbc:sybase:TDS:RemoteServer:2638",
props );
}
catch ( Exception e ) {
System.out.println( "Error: " + e.getMessage() );
e.printStackTrace();
}
}
....
}

================(Build #3654 - Engineering Case #495700)================

As of Engineering case 408481, exists() subqueries were not flattened during
rewrite optimizations if the subquery contained more than two tables in the
FROM clause, and it was not known if the subquery returned at most one row.
Now, for a subquery to not be flattened, it must also contain other nested
subqueries.

================(Build #3650 - Engineering Case #497504)================

If an application that was using Remote Data Access support executed a remote
query that was very complex, then there was a possibility that the server
would have crashed. This problem has been fixed.

================(Build #3650 - Engineering Case #497467)================

The unparsing of an alias was incorrect in some cases. The alias was represented
as a '*' in an unparsed statement. This may have been observed in plans generated
when using the -zx server command line option to log expensive queries. This
has been fixed.

================(Build #3647 - Engineering Case #496906)================

The server, and client applications, would have leaked memory on Solaris
SPARC 64-bit and Solaris x64 when negotiating a shared memory connection.
This has been fixed.

================(Build #3647 - Engineering Case #496071)================

The server uses column statistics in order to estimate the number of rows
that satisfy a given predicate. The column statistics are maintained as histograms
that attempt to capture the data distribution of values in the database for
a given column. The server could have incorrectly estimated the selectivity
of BETWEEN predicates under certain circumstances. Note that a BETWEEN predicate
might be inferred by the server if the query contains appropriate conjunctive
predicates. As an example, "c1 >= 5 AND c1 <= 10" is semantically equivalent
to "c1 BETWEEN 5 AND 10". This estimation problem has been resolved.

================(Build #3645 - Engineering Case #495943)================

If the constant 0.0 (one decimal separator and all digits zero) was used
in the select list of a SELECT statement, it would have been described as
a numeric(0,0), and a SELECT statement with an INTO <permanent_table> clause
would have failed with a syntax error. This has been fixed so that the constant
0.0 is now correctly described as numeric(1,0).

================(Build #3644 - Engineering Case #495396)================

If a client connection went away (eg. the client application crashed), it
was possible for the server to have crashed. This was very rare and timing-dependent.
It has now been fixed.

================(Build #3642 - Engineering Case #489542)================

In very rare situations, the server could have hung while trying to drop
a Remote Data Access connection. This problem has now been fixed.

================(Build #3641 - Engineering Case #492783)================

If an application using the iAnywhere JDBC driver called ResultSet.getDouble()
to fetch a numeric value, then there was a chance the JDBC driver would have
thrown an "invalid numeric string" exception. This problem would only have
happened if the application was using the Java print service and the default
locale was a European one. Note that calling ResultSet.getBigDecimal() did
not have the same problem, hence calling ResultSet.getBigDecimal().doubleValue()
is a workaround for this problem. The original problem has now been fixed.

================(Build #3638 - Engineering Case #494708)================

It was possible for the server to fail assertions 201866 - "Checkpoint Log:
Page 0x%x is invalid" or 201864 - "Checkpoint log: Invalid page number on
page 0x%x", for a database containing a corrupted page in the checkpoint
log. This could have occurred in cases where it was safe for the server
to ignore the corruption and recover the database. This has been fixed.
The assertions never occurred in databases that didn't contain corruption.

================(Build #3637 - Engineering Case #494319)================

If the Unload utility was used to perform an internal unload (-ii or -ix
command line option) from a Windows client while connected to a Unix server,
unloaded data files would have been created with a backslash character in
the file name instead of being placed in a sub-directory of the server's
current working directory. Furthermore, the generated reload.sql script referenced
these data files using forward slashes, making it unusable without modification.
A work around is to append a forward slash to the end of the directory name
passed to the dbunload utility.

================(Build #3634 - Engineering Case #491885)================

If a value-sensitive cursor was opened with the 'WITH HOLD' clause, and it
referenced a table that was affected by a TRUNCATE statement, then the server
could have reported assertion failures when the cursor was used after the
truncate. This problem also occurred if the cursor referenced a temporary
table declared with the 'ON COMMIT DELETE ROWS' clause and if the cursor
was used after a commit. Assertions that could be reported in this situation
include the following, although this list is not exhaustive:
201417 "Invalid count or free space offset detected on a table page"
101412 "Page number on page does not match page requested"
Note that a value-sensitive cursor can be selected either explicitly, by
cursor flags (ODBC keyset-driven, ESQL/SP scroll), or implicitly if the cursor
type is changed by the query optimizer (for example, if a sort is used for
an updatable cursor). This problem has been fixed. In engines with the fix
for this problem, the affected cursor will return an error if it is used
after the TRUNCATE or COMMIT. The error returned is: CURSOR_INVALID_STATE
24000 -853 "Cursor not in a valid state"

================(Build #3632 - Engineering Case #493730)================

In rare, timing dependent cases, the server could have hung on multi-processor
systems with one processor at 100% usage when iterating through connection
handles (for example by using sa_conn_list or sa_conn_info). This was extremely
unlikely on single processor systems, or on a server that had a low rate
of connects and disconnects. This has been fixed.

================(Build #3632 - Engineering Case #493729)================

A problem introduced by changes for Engineering case 489871 made it possible
for database recovery to fail with databases using the -m switch to truncate
the transaction log at each checkpoint. This was not an issue if -m was
not being used. This has been fixed.

================(Build #3629 - Engineering Case #493049)================

If the very first request to a remote server was executed by an user event
at the time the server was shutting down, or during a server startup that
fails, then the server may have crashed. This has been fixed.

================(Build #3627 - Engineering Case #473559)================

The server could have failed to recover a database, with assertion failures
200502, 201417 or 201418 likely in this situation. This was most likely
to have occurred when the server was running on a Windows CE device, and
the device was reset while the server was active. Databases using checksums
or encryption may be more prone to seeing this problem. While this problem
has been fixed, it's still possible to get these assertions where there is
something wrong with the database.

================(Build #3626 - Engineering Case #492353)================

In rare cases, the server could have crashed on shutdown if the cache priming
page collection was enabled. Page collection is enabled by default, or if
-cc or -cc+ were provided on the command line. This has now been fixed. The
workaround is to use -cc- to disable cache priming page collection.

================(Build #3626 - Engineering Case #492302)================

A query that involved more than one "Remote Procedure Call" in the FROM clause,
could have caused the server to crash.

An example of such a query is:
SELECT col1
from remote_procedure_1()
where col2 = (select c1 from remote_procedure 2())

This problem has now been fixed.

================(Build #3624 - Engineering Case #490412)================

In very rare, timing-related circumstances, the server could have become
extremely slow when processing Java requests in the database, or disconnects
from connections with attached Java VMs. This may have happened if a large
number of connections were executing Java functions or if connections with
attached Java VMs received a cancel. This has now been fixed.

================(Build #3623 - Engineering Case #491910)================

In rare cases, concurrent execution of DML and DDL statements could have
crashed the server. This has now been fixed.

================(Build #3622 - Engineering Case #491180)================

On Windows CE devices, in rare cases it was possible for a database stored
on a flash storage memory to not recover after the device shutdown abnormally.
Flash storage memory includes flash memory cards and the standard storage
memory on Windows Mobile 5 and 6 devices. This has been fixed.

================(Build #3621 - Engineering Case #489871)================

There were several problems possible when the -m server command line option
was used to truncate database transaction log files at checkpoint. Some
of these problems were, but were not limited to, assertions indicating that
the log could not be deleted or restarted while a virus scanner or disk defragmenter
was accessing the log file; and occasionally having zero byte transaction
log file remaining after a system failure. These problems should no longer
occur as the transaction log file is no longer deleted and recreated at checkpoint
time when the -m option is being used. Instead the file gets truncated to
one page in size and then continues to be used. A side effect of this change
is that there will be a one page log file remaining after a successful shutdown
of a database, instead of no log file.

================(Build #3613 - Engineering Case #489889)================

When executing an UPDATE on a remote table with a cursor range, the cursor
range would have been ignored, and all rows would have instead been updated.

For example, executing the following:
UPDATE TOP 2 proxy_t
SET proxy_t.data = 'Hello'
ORDER BY proxy_t.pkey ASC;

would have updated all rows in the table. This problem has now been fixed.

================(Build #3612 - Engineering Case #489598)================

'Assertion 100904: Failed to redo a database operation' is generated when
the server fails to recover the database based on information stored in the
transaction log. This assertion never included the actual reason for the
recovery failure. The actual error message is now included in the assertion
message. In many cases the cause of the recovery failure was failure to find
a data file that was used in a LOAD TABLE statement. In cases where the data
file had been deleted recovery could not continue. The fact that the file
is missing is now incorporated into the assertion message.

================(Build #3611 - Engineering Case #489179)================

Load table could have failed when loading data into a table that contained
a self-referencing foreign key. As of Engineering Case 395054 the wait_for_commit
option was set to 'off' for LOAD TABLE so that errors could be detected immediately.
Now wait_for_commit for LOAD TABLE is set to 'on' if the table has a self-referencing
foreign key, otherwise it is sett 'off' as before.

================(Build #3609 - Engineering Case #488514)================

When running on Windows Server 2008 (which has not yet been released by Microsoft),
the server could have crashed while performing an integrated login when the
INTEGRATED_SERVER_NAME was blank. This has been corrected

================(Build #3606 - Engineering Case #486053)================

The server may have crashed if Java VMs from multiple connections attempted
to call the same Java interface method for the first time. Due to the very
small window where this could have occurred, it would have been exceptionally
rare. This has been fixed.

================(Build #3605 - Engineering Case #488410)================

A server running with AWE enabled may have performed poorly, or failed an
out of memory assertion. This has been fixed.

================(Build #3605 - Engineering Case #488404)================

The value returned for the Connection and Database property QueryCachePages
would have been incorrect. This has now been corrected.

================(Build #3601 - Engineering Case #488116)================

In very rare circumstances, the server may have crashed, or returned unexpected
JVM exceptions like "IllegalAccessException", if multiple connection JVMs
attempted to load the same class simultaneously. This has been fixed.

================(Build #3601 - Engineering Case #488115)================

If a Java class was loaded and initialized by the forName() method and an
exception was thrown during the class initialization, then the caller would
have seen the incorrect exception java.lang.NoClassDefFoundError for class
java/lang/VMAlreadyThrown. This has been fixed.

================(Build #3601 - Engineering Case #488097)================

The changes for Engineering case 485200, that forced the server to use the
local setting of the Quoted_identifier option when connecting to an ASE remote
server, was incomplete. Attemptiong to create a proxy table to an ASE remote
server would have failed if the location string included the catalog name.
This problem has now been fixed.

================(Build #3597 - Engineering Case #487950)================

The changes for Engineering case 484160 introduced a problem such that running
databases without the SYSEXTERNLOGINS system table (version 5.5.05 or earlier)
could have lead to a server crash when dropping users. This has been corrected.

================(Build #3597 - Engineering Case #486777)================

In rare cases, opening a cursor on a procedure call or batch statement could
have caused a server crash. This has been fixed.

================(Build #3596 - Engineering Case #487507)================

If a 32-bit server was used on a system that had more than 4GB of memory
available, then dynamic cache sizing could have selected cache sizes that
were inappropriately small. Inappropriately small cache selected in this
way would have affected query performance such that they could be very slow,
worse even then if that cache size had been set at startup time. This problem
has been fixed.

Note, this problem can be avoided by using the -ca 0 engine switch to disable
dynamic cache sizing.

================(Build #3596 - Engineering Case #487142)================

In some specific situations, an UPDATE statement could have failed to complete.
It would continue to execute until cancelled. This has been fixed.

================(Build #3595 - Engineering Case #487335)================

It was possible for an HTTP request to an SA DISH service to hang the server
while consecutively altering services. This has been fixed.

================(Build #3594 - Engineering Case #487141)================

If an HTTP connection was refused because of licensing restrictions, in rare
cases, the server could have crashed. This has been fixed.

================(Build #3594 - Engineering Case #486476)================

Due to a memory leak, calling the the system procedure xp_sendmail() many
times, could have caused the server to crash. The memory leak has been fixed,
and xp_sendmail will now fail with the error "Insufficient memory" (return
code 15), if memory does become exhusted.

================(Build #3592 - Engineering Case #486775)================

Executing a remote query that must be handled in no-passthrough mode, and
that involved many tables, then there was a chance the query would have caused
a server crash. Such crashes would have been more likely with databases that
had a smaller page size. This problem has been fixed and the server will
now properly give an error when a no-passthrough mode query with too many
table nodes is executed.

================(Build #3592 - Engineering Case #486561)================

In some situations, if a keyset-driven cursor was used for a query that contained
an IF or CASE expression in the select list, then the IF or CASE expression
could have returned an incorrect answer. The answer would have been the expression
evaluated for another row of the result set. This has been fixed.

================(Build #3592 - Engineering Case #485821)================

In very rare circumstances, and only on Unix platforms, queries on a given
table could have become very long running. The total query cost as reported
by a graphical or long text plan of such slow queries, would have been reported
as a negative number. This has been fixed.

A workaround is to drop and recreate statistics on the table in question.

================(Build #3592 - Engineering Case #485593)================

The server could have become deadlocked while running concurrent REORGANIZE
TABLE statements on the same table. There can now only be one REORGANIZE
TABLE statement executing on a table at a time. Attempts to execute a second
REORGANIZE TABLE on the same table will now result in the error SQLSTATE_REORG_ALREADY_IN_PROGRESS.

================(Build #3591 - Engineering Case #486393)================

A query with an outer join could have caused the server to hang with 100%
CPU usage. This has been fixed.

================(Build #3591 - Engineering Case #484487)================

On Solaris 10 systems, calling the system procedure xp_cmdshell() may have
failed if the server's cache was large. This has been fixed. This problem
still affects Solaris systems running version 8 and 9; as the problem arises
from the implementation of the fork system call and cannot be worked around
safely on Solaris versions 8 and 9. A more complete expalanation can be found
at: http://developers.sun.com/solaris/articles/subprocess/subprocess.html.

================(Build #3590 - Engineering Case #486440)================

The server could have crashed when attempting to recover a database with
a corrupted transaction log file. This has been fixed.

================(Build #3588 - Engineering Case #485576)================

If the encrypt() or decrypt() functions were called a combined total of about
4 billion times, they would fail with the error 'Unable to load encryption
dll ""'. This has been fixed.

================(Build #3587 - Engineering Case #485874)================

Calling the system procedure sa_send_udp() have could have caused the server
to crash. This has been fixed.

================(Build #3586 - Engineering Case #486554)================

The changes for Engineering case 485200 resulted in a bug where attempting
fetch data from Micrsoft SQL Server or ASE could have failed with an "invalid
object name" error. This problem has been fixed.

================(Build #3585 - Engineering Case #485425)================

When executing a query containing proxy tables that would normally have been
handled in 'full passthru' mode, but cannot be handled by the server because
it is too complex, would have crashed the server. This has been fixed so
that the server now properly returns the error "-890: Statement size or complexity
exceeds server limits".

================(Build #3585 - Engineering Case #485200)================

When connecting to ASE or Microsoft SQL Server, the Remote Data Access layer
was setting the quoted_identifier option to ON at connect time and then always
quoting identifiers when querying data from ASE or SQL Server. Unfortunately,
due to a restriction in the ASE server, always using quoted identifiers resulted
in problems if the column name was 29 or 30 characters in length. Now, when
connecting to ASE or SQL Server remote servers, the quoted_identifier option
on the remote is set to match the local setting.

================(Build #3585 - Engineering Case #483518)================

In some cases, requesting a graphical plan for a query could have caused
the server to fail with a fatal error: 'A read failed with error code: (38),
Reached the end of the file. Fatal error: Unknown device error.' This has
been fixed.

================(Build #3584 - Engineering Case #484981)================

If REORGANIZE TABLE was executed in one connection, while simultaneously
dropping the primary key or clustered index on the same table in another
connection, the server could have crashed. This has been fixed.

================(Build #3584 - Engineering Case #483065)================

The connection property 'CommLink' was not returning 'local' for local TCP/IP
connections on some patched Solaris 10 systems. These systems had to have
at least two active network interfaces for the problem to occur. This has
now been fixed.

A work around is to use the MyIP connection option on the client, and the
MyIP TCP/IP option on the server and to make sure that they match.

================(Build #3582 - Engineering Case #484679)================

The server could have crashed, or failed an assertion, when reloading a procedure.
This could only have happened if another connection was unloading the procedure
almost simultaneously. This has now been fixed.

================(Build #3582 - Engineering Case #472486)================

On Linux IA64 systems, the server may cause "floating-point assist" faults.
These warnings are as result of operations on denormal (quantities too small
to be represented in normalized form) floats and doubles in the server, and
can be considered harmless, especially if the number of warnings is low.
The Itanium CPU is incapable of operating on denormal numbers in hardware
and enters software emulation mode when such an operation is requested. The
Linux kernel detects this and displays a performance warning, as the software
emulation entails a performance penalty. The correctness of server operations
is not compromised. All the same, the server has been modified to minimize
internal use of denormal numbers. However, the warnings will still appear
if the server is explicitly requested to operate on denormals (for instance,
with the statement "SELECT 2.25e-309").

================(Build #3581 - Engineering Case #484605)================

Under heavy load, and while another connection was executing DDL statements,
calls to a user-defined function could have resulted in a server crash. This
has been fixed.

================(Build #3581 - Engineering Case #484543)================

If a connection used a ASAJDBC or ASEJDBC remote server, and only performed
CREATE TABLE AT statements against this remote server, then a small amount
of the server's cache would not have been freed during the disconnect for
this connection. This has been fixed.

================(Build #3581 - Engineering Case #484542)================

If a connection made DML requests against a JDBC class (ASAJDBC or ASEJDBC)
remote server, and the disconnect performed an implicit rollback, then a
small amount of the server's cache was not freed. This has been fixed.

================(Build #3581 - Engineering Case #481645)================

After loading a Java class, it is initialized. The class initialization is
performed by the connections's Java VM when the class is used for the first
time. If two VM's attempt to initialize the same class concurrently, one
needs to wait for the other to complete. If the waiting VM was cancelled,
then the class was marked as erroneous, with a status of NoClassDefFoundError,
and it did not get initialized. Later during this connection the VM may have
returned a NoClassDefFoundError exception or, if the connection attempted
to access the class, a server crash would have occurred. This has been fixed.

================(Build #3581 - Engineering Case #477194)================

Executing a REORGANIZE TABLE statement while other connections were also
performing DML on the table, could have caused the database server to fail
an assertion. Such assertions would have included 100701: "Unable to modify
indexes for row referenced in rollback log". The REORGANIZE TABLE statement
could have looped infinitely if another connection attempted to drop the
table. A failed REORGANIZE TABLE, due to a deadlock or perhaps some other
error, could have caused the server to crash. These problems have now been
fixed.

================(Build #3579 - Engineering Case #484256)================

Attempting to execute a query with an invalid dotted reference involving
proxy tables, would very likely have caused a server crash.
For example:
select prod_id.sum(sales) from sales group by prod_id order by prod_id
This query was intended to be "select prod_id, sum(sales) ..." but a typo
replaced a comma with a period. If the table prod_id was a remote table,
then the above mistyped query would have crashed the server. This problem
has now been fixed.

================(Build #3579 - Engineering Case #484194)================

When the server was run on HP-UX 11.00, HTTP connections may not have shut
down cleanly, and the server may have hung on shutdown. The cause was a bug
in the operating system.
While there is no fix to ASA software, customers are advised to apply the
HP-UX 11.00 patch PHNE_27886 or later (and all dependencies).

================(Build #3579 - Engineering Case #484160)================

Attempts to revoke connect permission from a user that still had an externlogin
mapped, would have failed with a strange foreign key error, after which,
logging in as the user that was being dropped would have resulted in the
user permissions being messed up. The server now properly gives an error
indicating the externlogins are still mapped for the user and leaves the
user permissions unchanged.

================(Build #3579 - Engineering Case #481834)================

Applying a transaction log to a database using the server command line option
-a, could have failed assertion 100902: "Unable to find table definition
for table referenced in transaction log -- transaction rolled back". This
would have occurred if one log (B) contained all of the operations of the
preceding log (A), plus additional operations, and a sequence of modifications
to a table T by one connection, which begin in log A and continued into log
B, were active when the backup that created log A was performed. This has
been fixed. The fix affects the contents of the transaction log at the time
a backup is performed; thus, a fixed server does not permit log backups created
prior to the fix to be applied.

Note that the problem does not affect backups where a log rename is performed
after each backup, since in that case the logs will not contain overlapping
sections. The problem can be avoided in version 10 by applying all of the
logs at one time using the -ar or -ad options, which will cause the server
to skip logs that are included by subsequent logs.

================(Build #3579 - Engineering Case #475448)================

In rare cases, the Extraction utility dbxtract could have generated a reload
script with a LOAD TABLE or INPUT statement referencing columns in an order
which did not match the order of the columns in the corresponding data file.
This has been fixed by adding a missing ORDER BY clause.

================(Build #3578 - Engineering Case #481099)================

If a server already had a database running, and that database was not the
utility database, then attempting to connect to the utility database would
have failed for a TDS based connection. This problem has been fixed.

================(Build #3578 - Engineering Case #480208)================

If a proxy table to a table on a Microsoft SQL Server remote server had a
long character column, attempting to insert a string longer than 254 characters
into that column would very likely have caused SQL Server to have returned
a "partial update/insert" warning. This problem has now been fixed.

================(Build #3577 - Engineering Case #483815)================

If a procedure that referenced proxy tables was used in the FROM clause of
a SELECT statement, and the first statement in the procedure is not a SELECT
statement, it was very likely that the server would have crashed. The problem
may also happen if such a SELECT was used as the subselect in a DML statement.
This has now been fixed.

================(Build #3575 - Engineering Case #483559)================

The server could have gone into an endless loop, with very high CPU usage,
instead of reporting an error when it ran out of free pages in the cache.
This has been fixed.

================(Build #3575 - Engineering Case #483129)================

Engineering Case 454858 introduced a problem where attempting to execute
concurrent LOAD TABLE statements which used the same global temporary table,
would have caused one of the statements to have been blocked. This has been
fixed so that the loads now run concurrently once again.

================(Build #3574 - Engineering Case #483558)================

The value of connection_property('TransactionStartTime') would have been
an empty string if the only statement executed since the last COMMIT/ROLLBACK
was an INSERT ... SELECT. This has been fixed.

================(Build #3574 - Engineering Case #481493)================

In rare timing dependent cases a Unix application could have hung if prefetch
was enabled and only part of a result set was fetched. This has been fixed.

================(Build #3571 - Engineering Case #482952)================

The server may have crashed when doing extensive console logging (e.g. when
-zr all was used). This was more likely to have occurred on multi-processor
machines, and has now been fixed.

================(Build #3571 - Engineering Case #482931)================

If corresponding items in two select lists of a INTERSECT or EXCEPT set operator
had different data types, the server would have chosen a data type for the
corresponding column in the result and automatically converted the columns
in each select list appropriately. If the conversion failed, and the server
was low on cache memory, then it may returned the assertion 102501 instead
of the correct conversion error. This has been fixed.

================(Build #3569 - Engineering Case #482612)================

Executing a very complex query could have caused the server to crash due
to a stack overflow. This has been fixed.

================(Build #3569 - Engineering Case #482493)================

The INTERSECT and EXCEPT set operators were using too much stack during optimization
process which may have resulted in very complex queries failing with a stack
overflow. The stack usage for these operations has now been significantly
reduced.

================(Build #3569 - Engineering Case #480103)================

The server may have failed assertion 101412, as well as oither assertion
errors, if the query contained a GROUP BY clause with a grouping expression
of type char or varchar. For this probel to have occurred, the query must
also have used an Indexed Group By, or the indexed grouping for a Hash Group
By, as a low memory strategy; and during the grouping the group rows had
to be updated (e.g. due to the LIST function). This has been fixed.

================(Build #3565 - Engineering Case #481964)================

The procedure dbo.sa_disk_free_space contained a redundant permissions check,
and has been removed. The procedure can now be called if any of the following
conditions hold:
- the caller has DBA authority
- the procedure is called from another procedure owned by a user having
DBA authority
- execute permission has been granted
To correct the problem in existing databases without rebuilding or upgrading,
the call to dbo.sp_checkperms in dbo.sa_disk_free_space can be removed.

================(Build #3565 - Engineering Case #481893)================

Referencing a stored procedure in the FROM clause of a query could have incorrectly
returned a "permission denied" error. This would have occurred when the following
conditions were true:
- the procedure was owned by a user with DBA authority
- the procedure contained a single SELECT statement and no other statements
- permission to execute the procedure was granted to a non-DBA user
- the procedure's SELECT referenced a table for which the procedure owner
had not been granted permissions
This has been fixed. A workaround is to add a statement such as "if 1 =
0 then return end if;" to the start of the procedure.

================(Build #3564 - Engineering Case #481970)================

The setting of the ASTMP_UMASK environment variable would have been ignored
on HP-UX systems. Also, the umask setting was ignored in the creation of
the lrm_socket on HP-UX and AIX. These problems have now been fixed.

================(Build #3564 - Engineering Case #481891)================

When similar requests are executed concurrently, there would have be large
variations in their response times. This problem would have shown up more
on single processor machines. This has been fixed

================(Build #3562 - Engineering Case #481644)================

Same machine connections were using communication compression if the COMPRESS
connection parameter or -pc server option was specified. This has been fixed
so that only remote connections will be compressed.

The sa_conn_compression_info procedure could have reported incorrect compression
rates or packet compression rates if more than about two million bytes had
been transferred since the server started. This has been fixed as wll.
In order to get the fixed sa_conn_compression_info procedure, the ALTER DATABASE
UPGRADE PROCEDURE ON statement must be executed (this will also upgrade the
database to the current version, if necessary).

================(Build #3561 - Engineering Case #474289)================

If an application maked use of external function calls, the server may have
crashed if the application disconnected while a call to an external function
was being executed; or if enough connections called external functions such
that the server's worker thread limit was exceeded and a deadlock condition
arose. This problem has been fixed. When a deadlock condition arises, the
error "All threads are blocked" will result for one or more connections executing
an external function call. To avoid this error, the server option -gn can
be used to increase the number of worker threads.

When a client disconnects during execution of an external function call,
the server will no longer crash.

================(Build #3560 - Engineering Case #481139)================

Renaming a table or view could have caused unpredictable behaviour if other
parsed objects, such stored procedures, user-defined functions, or views,
refered to the renamed object and parsed forms of these referencing procedures
or views were already in server memory. The potential unpredictable behaviour
would have included incorrect results, server faults, or server assertions.
The server was failing to invalidate in-memory copies of parsed objects on
a table or view rename. Now, parsed object definitions are unloaded and reloaded
after the RENAME.

================(Build #3559 - Engineering Case #480895)================

When registering the performance monitor counters DLL (dbctrs9.dll or dbctrs10.dll)
manually from a non-elevated process on Windows Vista (eg, regsvr32 dbctrs10.dll),
the performance counters may not have actually been registered correctly,
even though regsvr32 reported that the dll was successfully registered. This
problem has now been fixed.

Note that the SQLAnywhere installation is performed from an elevated process
and will not be affected by this bug.

================(Build #3557 - Engineering Case #480423)================

A query that involved more than one Remote Procedure Call in the FROM clause
could have caused the server to crash.

An example of such a query is:
SELECT col1
from remote_procedure_1()
where col2 = (select c1 from remote_procedure 2())

This problem has now been fixed.

================(Build #3557 - Engineering Case #480125)================

A database with a corrupt checkpoint log could have grown large during database
recovery instead of failing with an assertion error. In some cases the database
could have grown so large that a fatal error: disk full could have been caused.
This type of corruption in the checkpoint log is now detected and assertion
201864 is raised in such an instance. This type of corruption is likely
to be caused by a disk problem.

================(Build #3556 - Engineering Case #479816)================

Executing a REORGANIZE TABLE could have caused the server to fail assertion
100701 - "Unable to modify indexes for a row referenced in rollback log --
transaction rolled back". This has been fixed.

================(Build #3556 - Engineering Case #440029)================

Database corruption, and server crashes and assertions, could have occurred
if a database was modifed while in the process of being backed up. This could
only have happened on systems with multi-core processors. In 9.x and earlier
servers, this could also have happened if many thousands of locks had been
obtained.

Note that if a server was running multiple databases, databases other than
the one being backed up could have been affected.

================(Build #3555 - Engineering Case #408745)================

Image backups produced by a server when running on a multi-processor machine
could have been corrupt. This would have occurred if there was more than
one transaction concurrently modifying the database. This has now been corrected.

================(Build #3554 - Engineering Case #466790)================

If a query contained at least two predicates "T.col = (subselect1)" and "R.col
= (subselect2)" and both predicates could be used as fence posts for index
scans on the tables T and R respectively, then the optimizer would have under
estimated the cardinality of the joins which may have resulted, for complex
queries, in unoptimal plans. This has been fixed.

================(Build #3549 - Engineering Case #479061)================

Executing a DROP DATABASE statement could have caused a server crash or failed
assertion if the database being dropped needed recovery. This has been corrected.

================(Build #3549 - Engineering Case #479053)================

For some CPU bound queries, execution times could have been longer with Unix
servers than execution times compared to an equivalent Windows server. This
has been fixed.

================(Build #3548 - Engineering Case #468343)================

If an application attempted to connecting using the TCP parameter DoBroadcast=None
and specified an alternate server name, rather than the real server name,
in the ENG parameter, the connection would have failed. This has been fixed.

Note that the fix requires both an updated server and updated client library.

================(Build #3543 - Engineering Case #477370)================

When attempting to install an EBF on MacOS using the GUI installer, the installer
would have prompted for an installation key and subsequently rejected any
keys given. This has now been fixed. As a workaround, the command line installer
can be used to apply EBFs on MacOS.

================(Build #3541 - Engineering Case #476187)================

When opening a data reader, prepared statements were dropped and re-created
again. This has been fix so that a command can now only open one data reader
at any time.

================(Build #3540 - Engineering Case #475131)================

Under rare circumstances, applications running on Unix systems may have crashed
following a disconnect. This was more likely to have occurred on a multi-processor
machines. This has now been fixed.

================(Build #3536 - Engineering Case #476067)================

The CREATE INDEX statement was not respecting the setting of the Blocking
option, and would always have failed if another transaction had the table
locked (for shared or exclusive access). As of version 10.0, this is more
likely to be an issue as the cleaner locks tables temporarily as it does
its work. In particular, a reload could have failed with errors of the form
"User 'another user' has the table ... locked". This has now been fixed.

================(Build #3534 - Engineering Case #475650)================

Multiple connections using keyset cursors, and executing DELETE WHERE CURRENT
OF or UPDATE WHERE CURRENT OF statements on the same table at the same time,
could have caused the server to fail assertion 201501. This has been fixed.

================(Build #3534 - Engineering Case #475618)================

The changes made for Engineering case 468319 introduced a problem where if
many concurrent connections were made to the server, and then disconnected,
the server may have taken several additional seconds to shutdown after the
databases were shutdown. This has been fixed.

================(Build #3533 - Engineering Case #475278)================

If a table was defined with a char(255) or varchar(255) column, and then
BCP IN was used to insert a string of length 251 or greater bytes into the
char(255) column, then BCP would either have failed with a protocol error,
or, the value NULL would have been inserted into the column. This problem
has now been fixed.

================(Build #3533 - Engineering Case #474480)================

If a database contained a table with a table ID larger than 65535, calling
the system procedure sa_locks() may have caused the server to crash. This
crash would only have occurred if there was a lock held on a table with a
table ID larger than 65535. The contents of SYS.SYSTABLE can be examined
to determine if any such tables exist. This issue has been fixed.

================(Build #3532 - Engineering Case #472081)================

If a connection string contained LINKS=TCPIP(host=<hostname>...), where <hostname>
was an invalid host name, the client library may not have given an error
as expected. This would only have occurred with threaded clients on Linux.
This has been fixed.

================(Build #3529 - Engineering Case #474726)================

If a query contained INTERSECT ALL or EXCEPT ALL and one of the branches
of the query expression was optimized by un-nesting an EXISTS predicate,
then the wrong answer could have been given. The INTERSECT ALL would have
been incorrectly treated as INTERSECT, and the EXCEPT ALL as EXCEPT.

For example, the following query shows this problem:

select D0.type_id
from sys.sysdomain D0

intersect all

select D1.type_id
from sys.sysdomain D1
where exists ( select * from sys.sysdomain D2 where D2.type_id = D1.type_id
)

This has been fixed.

================(Build #3527 - Engineering Case #473990)================

If a statement contained a derived table or view that specified DISTINCT
and that derived table appeared on the NULL-supplying side of an outer join
and further the query optimizer selected the Ordered Distinct algorithm for
that derived table, then the statement could have failed with an assertion
failure:
Assertion failed: 106105 (...) Unexpected expression type dfe_PlaceHolder
while compiling

For example, the following statement could have this problem:
SELECT *
FROM
dbo.rowgenerator T1

LEFT JOIN
(
SELECT dummy_col c1
FROM sys.dummy T2

UNION ALL

SELECT 12345 c1
FROM ( select distinct id from sales_order_items order by id asc
) T3
) T4
ON 1=1
WHERE T1.row_num < 10

This has been fixed.

================(Build #3527 - Engineering Case #473827)================

The server could have failed during database recovery with assertion failures
202101 - "Invalid Bitmap Links on Page ..." or 202100 "Invalid bitmap page
at page ... -- transaction rolled back" under some circumstances where it
was not warranted. This has been fixed.

================(Build #3527 - Engineering Case #472400)================

In some cases, if a query contained an unflattened derived table on the null-supplying
side of an outer join and the derived table contained a constant, then the
statement could have failed with an assertion failure message:

Run time SQL error -- *** ERROR *** Assertion failed: 106105 (...)
Unexpected expression type dfe_PlaceHolder while compiling (SQLCODE: -300;
SQLSTATE: 40000)

For example, the following query demonstrates this problem:

SELECT *
FROM SYS.dummy D1
LEFT JOIN
( select c1
from ( select distinct D2.dummy_col, 31337 c1
from dbo.rowgenerator R1 , sys.dummy D2
) DT1
) DT2
ON (D1.dummy_col=DT2.c1-31337)

This has now been fixed.

================(Build #3526 - Engineering Case #473834)================

If a statement contained a user-defined function that had an argument that
was a subquery, and the statement contained a union view with a predicate
comparing a column of the union view to the user-defined function, then the
statement could have failed with an inappropriate error. For example, the
following sequence would generate this inappropriate error.

create view V_shubshub( x ) as
select dummy_col from sys.dummy D3
union all
select dummy_col from sys.dummy D4
go

create temporary function F_tt(in a1 smallint)
returns decimal(16,5)
begin
return 0.0
end
go

SELECT *
FROM
(
select F_tt( ( select dummy_col from sys.dummy D1 ) ) x
from sys.dummy D2
) AS T1
WHERE NOT EXISTS(
SELECT 1
FROM V_shubshub T2
WHERE T1.x=T2.x
)

In version 8.0, the following error was returned:
-266 42W27 "QOG_BUILDEXPR: could not build sub-select"
in version 9.0 and later, the following error was given:
"Run time SQL error -- *** ERROR *** Assertion failed: 102604 (...) Error
building sub-select"
In versions prior to 8.0, it was possible for an incorrect answer to be
returned without an error being returned.

This has been fixed.

================(Build #3524 - Engineering Case #474599)================

If the database option Ansi_close_cursors_on_rollback was set to 'on', and
a cursor was opened on a stored procedure containing a declared cursor, a
ROLLBACK could have put the connection into a state where attempting to open
additional cursors would have failed with the message: "Resource governor
for 'cursors' exceeded". The ROLLBACK caused the cursors to be closed in
an order that resulted in the server trying to close a cursor twice. This
has now been fixed.

================(Build #3517 - Engineering Case #472369)================

When running the Linux x86 (32-bit) server, the value of the NativeProcessorArchitecture
property would always have been "X86," even if the engine was running on
a system with an x86-64 CPU. This has been fixed.

================(Build #3515 - Engineering Case #471981)================

Attempting to create proxy tables to an Oracle server in an SA database with
a mult-byte character set, would likely have failed with a "table not found"
error if the table owner and name were not specified in uppercase in the
create existing table location string. This problem has now been fixed.

================(Build #3515 - Engineering Case #471948)================

If an HTTPS connection attempt failed because of licensing (i.e. too many
connections), the client would have received a plain-text error message,
instead of handshake data. HTTPS clients would have interpreted this as a
protocol error. This has been fixed.

================(Build #3513 - Engineering Case #471696)================

The 32-bit and 64-bit versions of the SQL Anywhere library that provides
support for the Windows Performance Monitor could not coexist. If the 64-bit
library was registered last, only the 64-bit version of the Performance Monitor
would have been able to monitor SQL Anywhere servers (both 32-bit and 64-bit
servers). If the 32-bit version was registered last, only the 32-bit version
of the Performance Monitor would have been able to monitor SQL Anywhere servers
(both 32-bit and 64-bit servers). The area of the registry that contains
performance monitoring information and, in particular the path to the support
library, is shared by both 32-bit and 64-bit applications, unlike other areas
of the registry which have been split into 32-bit and 64-bit versions. The
problem has been fixed by having the 32-bit and 64-bit support libraries
register using different service names.

================(Build #3511 - Engineering Case #470274)================

If a query used certain internal system procedures on the NULL-supplying
side of an outer join, the wrong results could have been returned. The following
procedures had this characteristic, and have been corrected:
- sa_rowgenerator
- sa_report_blocking
- sa_lockinfo
- sa_report_deadlocks
- sa_performance_diagnostics
- sa_performance_statistics

================(Build #3510 - Engineering Case #471006)================

EXECUTE permission was not granted to the group SA_DEBUG for the system procedures
sa_proc_debug_version and java_debug_version. If a user that was granted
membership in SA_DEBUG was not also a DBA, attempting to use the procedure
debugger would have failed and possibly caused Sybase Central to crash. This
has been corrected for newly initialized databases. For existing databases,
the permissions can be granted by executing the following:
grant execute on dbo.sa_proc_debug_version to sa_debug
go
grant execute on dbo.java_debug_version to sa_debug
go

================(Build #3509 - Engineering Case #470685)================

When attempting to fetch an unsigned integer from a table on a remote server,
the value returned would always have been 0 if the local server was running
on a 64-bit little endian machine. This problem has been fixed.

================(Build #3507 - Engineering Case #470173)================

After using Sybase Central to create a proxy table to a table in Paradox,
fetching from that table would have failed with a "could not find the object"
error message. The method Sybase Cenral used to qualify the table name with
the database name was not supported by Paradox. This problem has been fixed
by implementing a work around in the server to modify the qualified table
name so that it is supported by Paradox.

================(Build #3506 - Engineering Case #470195)================

If an event was fired using the TRIGGER EVENT statement with a list of event
parameter values, the server could have crashed when the event handler attempted
to access the parameters via the event_parameter() function. This has been
fixed.

================(Build #3506 - Engineering Case #468358)================

If the server returned the error "Dynamic memory exhausted", it will be followed
by diagnostic information about the cache usage that is printed to a file.
During this diagnostic printing the server may have crashed. This has been
fixed.

================(Build #3504 - Engineering Case #469523)================

If a view was updated with an UPDATE statement that contained a VERIFY clause,
the server may have crashed or incorrectly used the VERIFY clause. This would
only have happened if the view and the base table had a different column
ordering in the select list. This has been fixed.

================(Build #3499 - Engineering Case #463318)================

On Windows CE, when starting a second server on the device, the window of
the first server is normally displayed. This should not have been the case
though when the first server was started with the command line options -qw
and -qi to hide the window and the icon resectively. This has been corrected
so that the first server's command line is honored and the first server's
window is no longer displayed when attempting to start a second server on
the device. Starting the second server will now fail silently in this instance.

================(Build #3496 - Engineering Case #467737)================

When SQL Anywhere was installed in a directory path containing non-ASCII
characters, on a system for which the ANSI code page was different from the
OEM code page (such as a typical English Windows installation), the server
and client libraries may not have been able to access Unilib data files.
The problem could show up as an "invalid parameter" error from SORTKEY/COMPARE,
or failure to create certain character set converters. The path was erroneously
being converted from the OEM codepage to UTF16, rather than from the ANSI
codepage to UTF16. This has now been corrected.

================(Build #3494 - Engineering Case #468319)================

It was possible, although very unlikely and timing dependent, that the server
could have hung, or even less likely crashed, when a connection was disconnected.
This has been fixed.

================(Build #3494 - Engineering Case #465040)================

When the server was converting the WHERE, ON or HAVING clauses to Conjunctive
Normal Form, and discovered at least one simplified or implied condition,
then it was possible that the resulting query was not equivalent to the original
query and therefore did not return the same result set.

For example, the following should return 1 row, but did not return any rows:

create table T1 ( d int, e int, f char(5) ,g char(5) );
insert into T1 values ( 5, 2, '4E', 'N' );
select * from T1
where ( d is not null or d is NULL )
and ( e = 2 or e is NULL )
and ( g <> 'Y' or g is null )
and e = 2

This has been fixed.

================(Build #3493 - Engineering Case #467800)================

Attempting to create a proxy table to a table that has a computed index on
a remote Oracle server, would have failed with the error "column not found".
As part of creating a proxy table to an existing remote table, the server
will also attempt to create indexes on the proxy table to match the indexes
on the remote table. In this case, the name returned for the computed column
was not an actual column name, but an expression name. The server now verifies
that the column name truly is the name of a column in the proxy table when
automatically creating indexes on proxy tables.

================(Build #3491 - Engineering Case #467586)================

After a failed integrated login, calls to the system function EVENT_PARAMETER(
'User' ) in the ConnectFailed event, could have returned garbage characters.
This has been fixed so that calls to EVENT_PARAMETER( 'User' ) will now return
the empty string if the user is not known.

================(Build #3488 - Engineering Case #467437)================

Referencing a column as "IDENTIFIER" .. "IDENTIFIER" (note: two dots) could
have caused the server to hang. In cases where the server did not hang,
the first identifier would have been ignored. A similar problem existed for
columns referenced as "IDENTIFIER" . "IDENTIFIER" .. "IDENTIFIER".

For example, the following script would have caused a server hang:

CREATE TABLE T1 (
x char(4) NOT NULL,
y char(13) NOT NULL,
z char(5) NOT NULL,
);

CREATE TABLE T2 (
w char(5) NOT NULL,
);

SELECT a.x as x, a.y as y,
count(b.w)
FROM T1 a,
T2 b
WHERE a.z = b.w
Group by a.y, a..x ; -- Note extra '.'

Now, the server will generate an error if a query contains a column expression
of the form
"IDENTIFIER" .. "IDENTIFIER"
or
"IDENTIFIER" . "IDENTIFIER" .. "IDENTIFIER".

================(Build #3488 - Engineering Case #467122)================

The execution time of the CREATE TABLE statement did not scale very well
as the number of columns being created increased. The statement could have
taken a significant amount of time to create tables with thousands of columns.
The performance of the server has been improved so that the CREATE TABLE
statement behaves more gracefully as bigger tables are created.

Note, this also addresses the problem where deleting a column from a table
via the ALTER TABLE statement would have caused a syntax error for values
that already existed in other columns.

================(Build #3488 - Engineering Case #466044)================

If the server was started with the -qw ("do not display database server screen")
or -qi ("do not display database server tray icon or screen") command line
options, certain messages, such as checkpoint messages, would not have been
written to the output log or to the internal message list (which can be queried
with the property functions). Services on Windows Vista, as well as services
on XP which did not allow interaction with the desktop, may have behaved
as if -qi was specified. This has been fixed so that all messages now always
go to the server output log and internal message list.

On Windows, the -qw switch now completely suppresses the creation of the
server window. As before, a systray icon is created but that icon is now
created immediately upon startup. Previously, a minimized server window was
created momentarily before the systray icon was created. In 9.0.2, the menu
for the systray icon allowed the user to open the server window via the "Restore"
menu item but "Restore" has now been disabled (which is consistent with 10.x
& the fact that -qw is supposed to prevent the creation of a server window).

On UNIX, the -qw switch suppresses all messages from going to the console
after the 'press q to quit' message has been displayed.

================(Build #3487 - Engineering Case #466989)================

When running on HP-UX Itanium, the server did not search the LD_LIBRARY_PATH
when trying to locate shared libraries, instead the SHLIB_PATH is searched.
Now both locations are searched.

Note that in most cases the script sa_config.sh or sa_config.csh, that is
included in the install, is used to set the environment for SQL Anywhere.
When sa_config is used, both SHLIB_PATH and LD_LIBRARY_PATH are set, and
hence SQL Anywhere will be able to find any libraries it requires. If sa_config
is not used, users should work around this issue by
setting both SHLIB_PATH and LD_LIBRARY_PATH.

================(Build #3487 - Engineering Case #466873)================

If an application made a remote procedure call to a stored procedure in a
Microsoft SQL Server database, and one of the arguments to the stored procedure
was a string argument of type Input with the value of '' (empty string),
then the RPC would have failed with an 'invalid precision value' error. This
problem has now been fixed.

================(Build #3485 - Engineering Case #466491)================

The server could have failed with various assertion failure errors when rebuilding
a database with an invalid foreign key definition. For example, if the foreign
key trigger action had the column being set to NULL, based on some event
and the column definition did not allow NULLs, then this could have occurred.
A database could have gotten into this state if at the time the foreign key
was created the definition was valid but the column definition changed at
a later date. The proper error is now returned indicating the reason the
key is now invalid.

================(Build #3484 - Engineering Case #466203)================

If a trigger encountered an error due to a statement referencing a table
that was exclusively locked by another connection, a subsequent execution
of the trigger could report "Invalid statement". This has been fixed.

================(Build #3484 - Engineering Case #463733)================

The server may have hung on shutdown if it was running an HTTPS server. This
has been fixed.

================(Build #3483 - Engineering Case #466070)================

Connection attempts to the utility_db would have failed, throwing an exception
that setting options was not allowed in the utility_db. As the SET OPTION
statement is not valid in the utility_db, the AsaConection method now checks
if the database is the utility_db before issuing a SET TEMPORARY OPTION statement.

================(Build #3483 - Engineering Case #465003)================

If multiple connections using Remote Data Access attempted to read from the
same set of tables in a Microsoft SQL Server database, then the connections
would have been serialized. This was due to the fact that Remote Data Access
always used pessimistic locking when connecting to Microsoft SQL Server.
This has now been fixed so that connections to Microsoft SQL Server are no
longer serialized.

================(Build #3481 - Engineering Case #465814)================

Performing a LOAD TABLE into a temporary table that already contained rows
could have crashed, if the table had no primary key. This has been fixed.

================(Build #3480 - Engineering Case #465530)================

If the filename of a transaction log, including its full path, was exactly
70 bytes, and the Backup utility was used to do a backup, the server would
have failed to truncate the log when the -x option (delete and restart the
transaction log) was specified. This has been fixed.
A workaround would be to use the BACKUP DATABASE statement with the TRANSACTION
LOG TRUNCATE clause to truncate the log.

================(Build #3479 - Engineering Case #445626)================

Attempting to start a database with the wrong log file could have failed
with the error "Unable to start specified database: ??? belongs to a different
database". This has been fixed so that the log file name now correctly appears
in the error message.

================(Build #3478 - Engineering Case #465161)================

While rare, the server could have crashed on shutdown. This would only have
been seen if more than one external function had been called, and the calls
were either cancelled before the functions completed, or the database tasks
servicing the request had received a thread deadlock error before the functions
completed. This has been fixed.

================(Build #3477 - Engineering Case #462945)================

When run on NetWare systems, unloading the server using the NetWare console
(i.e. "UNLOAD DBSRV9") when there were still active connections to the server,
may have caused the server to abend or hang. This has been fixed.

================(Build #3476 - Engineering Case #464201)================

The runtime server does not support execution of procedures; however, it
still attempted to execute a login procedure if one was defined using the
PUBLIC.login_procedure option. That attempt would always have failed and
caused a message to be displayed in the server console window for each connection:
Login procedure 'sp_login_environment' caused SQLSTATE '0AW04'
Triggers and procedures not supported in runtime server
This has been corrected so that the runtime server will no longer attempt
to invoke the login procedure.

A workaround would be to execute:
set PUBLIC.login_procedure=''

================(Build #3475 - Engineering Case #464477)================

After the execution of an ALTER TABLE [ADD | DROP | MODIFY ] COLUMN statement,
the server would have failed to reload trigger and stored procedure definitions.
This reload should have caused a recompile of the trigger or procedure definitions,
which would have altered the semantics of their statements if they depended
upon the ALTERed column. As an example, if a query in a trigger definition
used the syntax "SELECT *" and referenced the modified table, an incorrect
number (or type) of columns would have been returned in the query's result.
This oversight has been corrected.

================(Build #3475 - Engineering Case #463882)================

If an application, connected via the iAnywhere JDBC Driver, fetched a timestamp
value using the ResultSet.getTimestamp() method, then the fractional portion
of the returned timestamp would have been incorrectly truncated to millisecond
precision. This problem has now been fixed and the fractional portion of
the timestamp is now the expected nanosecond precision.

================(Build #3472 - Engineering Case #463763)================

When using BCP IN to populate a table which had a nullable date or time column,
the BCP utility would have given a 'NULLs not allowed' error if the data
file inserted a NULL into the date or time column. The server was was incorrectly
describing all date and time columns to the BCP utility as non-nullable,
even if they were nullable. This problem has now been fixed.

================(Build #3472 - Engineering Case #463662)================

In general, the optimizer enumerates all valid plans which compute the correct
result set for a given query. For each such plan, the optimizer estimates
an execution cost measured in microseconds. The plan with the smallest estimated
cost is then chosen as the execution plan for a query (aka the 'best plan'
for a query). If the database option Optimization_goal is set to FIRST-ROW,
the estimated cost for a plan enumerated by the optimizer is the estimated
time to compute the first row of the result set of the query. If the optimization
goal is set to ALL-ROWS, the estimated cost for a plan enumerated by the
optimizer is the estimated time to compute all the rows in the result set
of the query. The optimizer was not enumerating plans with complete index
scans on the right hand side of a MERGE JOIN. This has now been fixed.

================(Build #3470 - Engineering Case #463734)================

A complex query (e.g. a join of many tables) may have taken a long time to
be optimized, and would have appeared to be hung. This has been fixed.

================(Build #3470 - Engineering Case #463170)================

If a query contained a left outer join with an index scan on the left hand
side, then the query could have returned incorrect results on a refetch operation.
This problem only occurred on refetch operations (e.g. fetch relative 0),
and only when the data from the current row on the left hand side of the
join had been modified or deleted since the original access.

For example:

create table R ( x integer primary key );
insert into R values (1);
insert into R values (2);
insert into R values (3);

create table T ( x integer primary key );
insert into T values (1);
insert into T values (3);

Connection A:
open crsr { select R.x, T.x from R ( with index( R ) ) left join T on R.x
- T.x = 0 }
fetch crsr into x1, x2
=> returns (x1, x2) = (1, 1)

Connection B:
update R set x = 99 where x = 1

Connection A:
fetch crsr relative 0 into x1, x2
=> returns (x1, x2) = (3, 3), should be (2, NULL)

This problem has been fixed.

================(Build #3467 - Engineering Case #462319)================

If an UPDATE statement specified a VERIFY clause that contained a string
or numeric (decimal) value, the server could have crashed under some conditions.
It was also possible that the wrong set of rows could have been updated,
or they could have been updated to incorrect values. This has now been corrected.

================(Build #3464 - Engineering Case #462322)================

Under very rare conditions the server could have crashed if it was unable
to start a database. This has been fixed.

================(Build #3463 - Engineering Case #453429)================

Database validation could have, in very rare cases, incorrectly reported
the error "Table (table_name) has an incorrect page count (x) in SYSTABLE
when (y) was expected. This has now been fixed.

================(Build #3462 - Engineering Case #455542)================

If the server was started with the -z option and an application connected
using either Open Client or jConnect, it was very likely that the server
would have crashed if the application subsequently fetched a large float
value. This problem has been fixed.

================(Build #3461 - Engineering Case #461591)================

Executing a query referencing proxy tables, that contains a subquery which
involved MANY unions, could have caused the server to have crashed. This
problem has been fixed.

================(Build #3461 - Engineering Case #461578)================

If a jConnect application connected to the utility database, then jConnect
always chose iso_1 as the character set, even if the server was using a multi-byte
character set. This problem has now been fixed and jConnect now uses the
same character set as the server.

================(Build #3461 - Engineering Case #461547)================

If a sargable IN list predicate can be used for a partial index scan of a
unique index, the optimizer was incorrectly choosing the unique index, without
costing other indexes or sequential scan alternatives. This exclusion of
other indexes may have resulted in an inefficient plan being used for the
query. This has been fixed so that the optimizer will cost all available
indexes and the sequential scan for cases where IN list predicates are present.

For example, the query below had always, before this fix, the plan T<c1>
which may be inefficient for some instances of the table T.
create table T (c1 int primary key );
.....

select count(*) from T where T.c1 IN (1,2,3,4,5,6,7,8,9);

================(Build #3460 - Engineering Case #456610)================

Executing a TRUNCATE TABLE statement on a very large global temporary or
permanent table may have blocked other database requests (including connect
requests) until its completion. This has been fixed.

================(Build #3458 - Engineering Case #461185)================

Executing a query with a dotted reference, with the dotted reference having
less than four fields, would likely have caused the server to crash, instead
of returning an error if one of the fields was empty. Note that for the query
to crash the server, the table being referenced in the dotted reference must
be a proxy table. This problem has now been fixed and a proper error message
is now returned.

================(Build #3457 - Engineering Case #461164)================

The SNMP agent could have crashed when dynamic traps were fired. This has
been fixed.

================(Build #3457 - Engineering Case #461036)================

When referencing a proxy table to a remote database with a multi-byte character
set, table or column names that had multi-byte characters could have been
passed to the remote server mangled. For identifiers in the multi-byte Character
set, the server may have incorrectly escaped certain characters and/or changed
the case. This problem has been fixed.

================(Build #3455 - Engineering Case #456231)================

If a statement contained one or more large IN list predicates that were processed
using the IN List algortihm, then the statement could have taken a long time
to respond to a cancel request. In some cases, a communication error would
have occurred when executing such statements. This has been fixed.

For more information on the IN List algorithm, see the documentation:
SQL Anywhere® Server - SQL Usage
Query Optimization and Execution
Query execution algorithms
Miscellaneous algorithms
IN List

================(Build #3454 - Engineering Case #455776)================

When a cursor was opened on a query with a "Nested Loops Semijoin Algorithm"
or a "Nested Loops Anti-Semijoin Algorithm" in the execution plan, the cursor
could have been repositioned inappropriately on a FETCH RELATIVE 0. Instead
of remaining on the current row, a different row or NOTFOUND could have been
returned. This has been fixed.

================(Build #3453 - Engineering Case #455148)================

Use of references to procedure in UPDATE statements could have caused the
server to crash. The server will now generate an appropriate error message.

================(Build #3451 - Engineering Case #456608)================

On Windows Vista, to use AWE (Address Windowing Extension) cache with the
database server, the server must be run as an administrator. If not run as
an administrator, the server will disable AWE and issue a warning message.

================(Build #3451 - Engineering Case #456473)================

When starting a database server on a file for which the server had no write
permissions, the server would have reported "Unable to start database server.
Unknown error (-29958)". A more appropriate error message is now displayed.
In the case of having no write permissions, the server will now display "Unable
to start database server. Permission denied"

================(Build #3451 - Engineering Case #456302)================

The server may have crashed if multiple connections ran the same stored procedure
concurrently the first time after the database was started, or an event caused
the procedure to be reloaded. For the crash to have occurred, the procedure
must have contained a control statement (e.g. IF) with a condition that used
a subselect referencing proxy tables. This has been fixed.

================(Build #3448 - Engineering Case #455973)================

A SQL Anywhere DISH service that was configured with a GROUP clause, but
no FORMAT clause, could have caused the server to crash on startup. This
problem affected Win64 and some Unix platforms, but did not occur on Win32
platforms. It has now been fixed.

================(Build #3447 - Engineering Case #455972)================

A plus character ('+') within a STRING type parameter (eg. var char) to a
SQL Anywhere web client configured as type HTTP:GET or HTTP:POST, was received
as a space ' ' by an HTTP server. The SQL Anywhere web client was not url-encoding
the plus character. This has been corrected.

================(Build #3447 - Engineering Case #428977)================

It was possible for a query to return the wrong answer, if the query contained
an IN list search condition that was used in an index scan to provide an
ordering property.

For example, the following query could give the wrong answer for some query
execution plans:

create table TOB( c1 int, c2 int);
create index TOBx on TOB(c1,c2);
insert into TOB
select row_num c1, 20-c1
from rowgenerator where row_num <= 20;
commit

select *
from TOB T1 with( index(TOBx) ), TOB T2 with( index(TOBx) )
where T1.c1 = T2.c1
and T1.c2 in (15,16,17,18,19) and T1.c1 in (1,2,3,4,5)
order by T1.c2

The wrong answer could have been returned in some cases if a Merge Join
was used for the above query. This problem has been fixed.

================(Build #3446 - Engineering Case #455659)================

A server crash was possible if concurrent connections were calling and dropping
a procedure. For the crash to have occurred, there must have been a specific
chain of events. A procedure was called on one connection, a checkpoint occurred,
another connection dropped the procedure, and the first connection rolled
back. This has been fixed.

================(Build #3446 - Engineering Case #454319)================

If the case of a variable in a procedure was used inconsistently (e.g. declared
in lower case but used in upper case), the server could have reported a "column
not found" error, or even have crashed, when the procedure was called. This
has been fixed.

================(Build #3446 - Engineering Case #421275)================

If a temporary table was declared as NOT TRANSACTIONAL, deleting rows in
the table using a DELETE statement did not release the space for re-use.
This has been fixed.

================(Build #3444 - Engineering Case #455140)================

Executing a query that involved a proxy table, and uses an invalid dotted
reference that contained empty fields within the query, would likely have
caused the server to crash. An example of an invalid dotted reference with
empty fields is:

select emp_profile..dependents..count(*) from emp_profile

This problem has now been fixed so that attempts to use an invalid dotted
reference of the above form will result in an "invalid field reference" error.

================(Build #3443 - Engineering Case #454868)================

On Windows CE, if a second server is started when one is already running,
the first server's console window is displayed, and the second server terminates
immediately. This is the correct behaviour, unless the command line coptions
-qw or -qi were used, in which case the server's console window should never
be displayed. This has been fixed so that the first server's console window
is not displayed if the second server's command line includes one of the
following options: -qw (do not display database server screen), -qi (do not
display database server tray icon or screen) or -qs (suppress startup error
dialogs).

================(Build #3443 - Engineering Case #454862)================

After receiving a TEMP_SPACE_LIMIT error, and then making more space available
to the temporary file partition by increasing the partition size or deleting
unnecessary files, an application may still have received a TEMP_SPACE_LIMIT
error. This could have happened even when enough space was added so that
all connections were below their quota, as the calculation of available temporary
space was being made when the temp file was extended. If the temp file was
not grown after more space becomes available, then the server would not have
applied newly available space to a connection's temp file quota. This has
been fixed. Now, after a small interval of time following a TEMP_SPACE_LIMIT
error, the engine will re-compute available temp space and temp file quotas.
The interval is currently set to 60 seconds. This recalculation is made
following every occurance of a TEMP_SPACE_LIMIT error.

================(Build #3443 - Engineering Case #386187)================

If a LIKE predicate was used on a LONG BINARY value that was longer than
would fit in a VARCHAR (32767), and the option String_rtruncation was set
to 'on', then a truncation error could inappropriately have been given. This
has been fixed.

The following example demostrates the error:
create table patterns( c1 long binary );
insert into patterns values( repeat('a', 50000);
select count(*) from patterns where c1 like '%aaa%'
The following error was returned: "Right truncation of string data" SQLCODE:
-638 SQLSTATE: 22001

================(Build #3442 - Engineering Case #454785)================

Attempting to create a proxy table to a remote table that had an underscore
in the table name, may have failed when using certain ODBC drivers. For this
problem to have occurred, the ODBC driver in question must have returned
the empty string as the "SQL_SEARCH_PATTERN_ESCAPE" string. At the moment,
the ASE ODBC driver seems to be the only one that is affected by this problem.
This has now been fixed.

================(Build #3442 - Engineering Case #454745)================

In some cases, an INSERT, UPDATE, or DELETE statement would have used a work
table that was not needed. This would have caused performance to be slower
than it could otherwise have been. This has been fixed.

================(Build #3440 - Engineering Case #453270)================

If a JDBC application connected using jConnect, and had the string_rtruncation
option set to ON, calls to the procedure DatabaseMetaData.getTables() to
get a list of tables would likely have resulted in an empty result set, even
though it should not have been. This problem would only have occurred if
one or more of the tables in the result set had a comment that was longer
than 128 characters in length. This problem has now been fixed.

================(Build #3439 - Engineering Case #451573)================

The changes for Engineering case 422775 may have caused the server to use
sequential scans when executing a SELECT statement over a large table, even
when a much more efficient access method using a clustered index scan was
available. The problem was more likely to be noticeable when the table was
fairly large, most of the table was not in cache, and the scan returned a
fairly large number of rows. The earlier fix caused the server to over estimate
the cost of partial index scans with a cold cache. This has now been corrected.

================(Build #3438 - Engineering Case #452761)================

The server may have crashed if a connection executed a Java procedure and
the connection received a cancel request while executing a createStatement()
call. This has been fixed.

================(Build #3437 - Engineering Case #453696)================

The changes made for Engineering case 372680 could have caused the server
to crash when executing a procedure with an outer-reference in a query block.
This has now been fixed.

For example, if the following query was in a procedure, the server may have
crashed executing the procedure:

select sum( R.z + ( select sum(DT.x + DT.y)
from (select T.x, R.y <<<<<-----R.x is an outerrefere
from T ) as DT(x, y) ))
from R

================(Build #3435 - Engineering Case #453399)================

The encrypt() or decrypt() function could have returned NULL if the algorithm
specified was AES_FIPS. This has been fixed.

================(Build #3434 - Engineering Case #453147)================

In some circumstances, the MobiLink plug-in would not have beeb able to display
the set of notifiers, gateways, carriers or versions in a database. This
has been fixed.

================(Build #3431 - Engineering Case #452515)================

Use of the "expr AS name" syntax in an argument to the functions XMLATTRIBUTES(),
XMLFOREST(), or XMLGEN(), inside a CALL statement argument, could have caused
the server to crash. This problem has now been fixed.

A workaround is to use "select * from proc()" rather than "call proc", or
to evaluate the expression into a variable before passing it as a call argument.

================(Build #3430 - Engineering Case #452329)================

The server may have crashed while processing a highly recursive query. This
has been fixed so that the error "syntactic limit reached" will now be returned
in such a situation.

================(Build #3429 - Engineering Case #452225)================

Attempting to execute a query that references a proxy table with an invalid
dotted reference (eg. select c1, p1.c2.foo() from proxy_t p1), would very
likely have caused the server to crash. The crash for an invalid dotted reference
has now been fixed.

Note that using a valid dotted reference like "select c1, u.f() from proxy_t",
where f was a user-defined function owned by user u, would have worked, and
will still work.

================(Build #3426 - Engineering Case #440246)================

ASA uses files for client-server shared memory communication. On Solaris
systems, when free disk space was exhausted, attempts to allocate more shared
memory was not being detected and raised as an error. Then, when either
the client or the server accessed the memory, a BUS error would have occurred.
This has been fixed, by added code to check free disk space whenever new
shared memory is created on Solaris.

================(Build #3423 - Engineering Case #450355)================

When a table or view is altered, the server finds all cursors (including
those created internally for DESCRIBE) that refer to the table or view being
altered and automatically closes them. Under some circumstances, the server
would have failed to close all such cursors, causing subsequent references
to these cursors to behave unpredictably. The results could have ranged
from no impact, to a server crash. This problem was likely to happen when
the table being altered had previously been used in a cursor, and the reference
was eliminated internally by the optimizer as being redundant. For views,
the problem could have arisen when the view was flattened by the optimizer,
and references to it were removed from the query that was optimized and executed.
This has been fixed so that the server now correctly finds and closes all
the cursors.

================(Build #3420 - Engineering Case #456317)================

When running in a Terminal Services (aka Remote Desktop or Fast User Switching)
session, clients were not be able to use the shared memory communications
port reliably. For example, database servers started as a Windows service
would only be visible to the primary local login session ("session 0"), and
they would be invisible to all other Terminal Services sessions. The behaviour
has now been corrected and improved as follows:

1. A database server started in session 0 (ie as a Windows service or on
the desktop of the primary login session) will be visible via shared memory
to all sessions.
2. A database server will not start if there is already a server running
by the same name in session 0 or in the current session. Note that the server
_will_ start if there is a database server running with the same name in
another session other than session 0.
3. When connecting via shared memory, clients will look for a server by
the specified name in the current session first and then in session 0.

Note that starting a database server on the desktop of session 0 can prevent
a server with the same name from starting as a service; however, this situation
is rare because services are normally started when the system starts.

================(Build #3419 - Engineering Case #449193)================

Duplicate variable declarations in Transact-SQL procedures were not detected
as syntax errors when the procedure was created. They would then have caused
spurious syntax errors during procedure execution. This has been fixed.

================(Build #3418 - Engineering Case #449506)================

Attempting to execute an INSERT ... SELECT, that did not fill columns defined
with default timestamp, may have caused the assertion failure "Attempting
to store invalid timestamp value in table ...". This occurred when the database
option Truncate_timestamp_values was set to ON, and the value for the database
option Default_timestamp_increment was greater then 1. This has been fixed.

================(Build #3418 - Engineering Case #407390)================

A query with an outerreference to unflattened derived table or view, that
was used twice in a subquery, could have failed with an unexpected expression
error, or could have caused theserver to crash. In the example below, the
outerreference T1.q is used twice in the subquery and it references a column
of a derived table with UNION:

SELECT T1.*
FROM
(select * from (select quantity from product UNION select quantity +10 from
product ) as V (q)
) T1 (q)
WHERE EXISTS(
SELECT 1 FROM
(select max(id) as i,
sum(quantity) as qty
from product
group by color) T2
WHERE T1.q >T2.i AND T1.q=T2.qty )

This has now been fixed.

================(Build #3416 - Engineering Case #449536)================

Calling the html_decode() function could have caused the server to crash.
This has been fixed.

================(Build #3413 - Engineering Case #448489)================

A DESCRIBE of a statement may have returned a syntax error if the SELECT
statement contained tables that had CHECK constraints, or articles with WHERE/SUBSCRIBE
BY clauses. For this to have occurred the very next operation after PREPARE
was an OPEN of a read-only cursor, and the statement described was executed
after opening the cursor. This has been fixed.

================(Build #3412 - Engineering Case #448828)================

If a non-DBA user created a view referencing a system table and granted SELECT
permission on the view to another user, then that other user could not have
selected from the view with a permission denied error. This was due to the
non-DBA user not having SELECT permission on the system table WITH GRANT
OPTION. The system table referenced could have been the SYS.DUMMY table referenced
implicitly. This has now been fixed. A workaround would be to explicitly
grant SELECT permission WITH GRANT OPTION on the system table to the view
creator.

================(Build #3412 - Engineering Case #448819)================

If an ORDER BY expression contained an IN predicate that matched an expression
in the SELECT list, it would have been treated as though there were no matching
expression in the SELECT list, resulting is an error.

For example, the following query (run on asademo.db):
select case when name in ('syscolumns') then name else 'OTHERS' end
from sysobjects
group by case when name in ('syscolumns') then name else 'OTHERS' end
order by case when name in ('syscolumns') then name else 'OTHERS' end
would have failed with the error "Function or column reference to 'name'
in the ORDER BY clause is invalid". This problem has been fixed.

================(Build #3412 - Engineering Case #385324)================

Attempting to execute a query with an ORDER BY clause that contained a subquery,
would have failed with the error -152: 'Invalid ORDER BY specification'.
For example:
select dept_id from department as D
group by dept_id
order by (select count(*) from employee as E where D.dept_id = E.dept_id)

This has been corrected so that subqueries are now allowed in the ORDER
BY clause, given that all outer references in the subquery are valid.

================(Build #3410 - Engineering Case #448501)================

The event viewer could have contained informational messages like "Service
not able to access Desktop" or "Service able to access Desktop". These messages
were the result of normal server startup. They are no longer generated by
the starting of a service for a server.

================(Build #3410 - Engineering Case #444898)================

The server may have crashed when using cached plans in nested procedures.
This crash would have been rare, and was likely to appear only when there
was heavy competition for cache memory. This has been fixed.

================(Build #3408 - Engineering Case #448223)================

A busy server with high CPU usage and hundreds, or thousands, of connections
could have occasionally dropped a connection due to a liveness timeout. If
this occurred, the liveness timeout would be detected by the client, and
a message like "Disconnecting Client - 120 seconds since last contact" would
have appeared in the client's logfile, if the logfile connection parameter
was used. A change has been made to the server's liveness code so that connections
should no longer be dropped in this case.

================(Build #3408 - Engineering Case #448115)================

When run on Windows CE, the server could have hung when attempting to display
a message if the PostMessage Windows function failed. This has been fixed
so that if PostMessage fails, the server will assert but not hang.

================(Build #3408 - Engineering Case #448083)================

A query that used both a keyset, and a complex expression involving a window
function in the select list, may have crashed or given incorrect results.
This is fixed.

================(Build #3408 - Engineering Case #448074)================

Repetition of a complex expression, inside and outside a window function
argument, could have caused incorrect results for the outside copy. The problem
has now been fixed.

Note, that this problem could also have occurred if an implicit cast of
a simple expression was repeated both inside and outside a window function.

================(Build #3406 - Engineering Case #447620)================

If a request log was generated using an application which dropped the statement
for a query before the cursor on that statement was closed, the tracetime.pl
Perl script would not have calculated the time for the statement correctly.
This has been fixedso that the script now keeps track of statements for which
a cursor is open, similar to the change made for sa_get_request_times in
Engineering case 445069.

================(Build #3406 - Engineering Case #440209)================

A WRITETEXT statement would have returned the incorrect SQL error "Subquery
cannot return more than one row" if the table had a publication with a "subscribe
by (subselect)" condition and the subselect returned more than one row. This
has been corrected.

================(Build #3405 - Engineering Case #447613)================

A performance warning "Server cache size is too small for database '<dbname>'"
could have been displayed in the server console even when the cache size
was adequate for the size of the database. The problem was that the server
was including the size of the transaction log in its space calculation. This
has been fixed.

================(Build #3403 - Engineering Case #446700)================

When calling a stored procedure with a string parameter, either inout or
out, the parameter value returned would have been an empty string, if the
size of the string parameter was not specified. Now, the provider will throw
an InvalidOperationException if the size of the parameter is invalid.

================(Build #3398 - Engineering Case #446425)================

The server could have leaked small amounts of memory when calling some of
the server or connection property functions, such as sa_conn_properties().
This has been fixed.

================(Build #3398 - Engineering Case #446233)================

It was possible that some components could have generated errors, or created
files with invalid names, when using files with names that had missing attributes.
For example, backing up a database and transaction log, where the log file
had no extension (ie. demo as opposed to demo.log), could have generated
an error that the log file could not be backed up and that the backup failed.
This has been fixed.

================(Build #3398 - Engineering Case #446066)================

The Backup utility would have given a poor error message when backing up
a database with one or more missing dbspaces. It would have reported the
following messages:

Database backup not started
Database backup failed

These messages were not very informative. This has been fixed so that the
following messages are now displayed:

Backup is unable to open database file '<file name>'
Database backup failed

================(Build #3396 - Engineering Case #440930)================

The database server could have crashed with a "memory exhausted" error. One
of the symptoms leading up to thecrash would have been increased disk read
activity by the server, although this is not always the case. This was due
to cache pages becoming unavailable for use. This could occur on machines
with 2 or more processors, but was more likely to happen on machines with
4 or more processors. This issue has been fixed.

================(Build #3395 - Engineering Case #445684)================

On NetWare, certain operations were slower than in previous ASA versions.
Particularly, operations which involved processing many rows for each row
returned in the result set were noticeably affected. This has been fixed
so that the performance of these operations has been improved.

================(Build #3395 - Engineering Case #445382)================

The server now makes use of direct I/O on Solaris, AIX, and Linux sytems
where possible. If direct I/O is not available the server will revert to
using synchronized I/O data integrity completion as before. Using direct
I/O will significantly improve some disk operations, such as extending a
databse or transaction log file.

================(Build #3394 - Engineering Case #445546)================

Calling an SA client SOAP procedure, from within the Interactive SQL utility,
may have returned unexpected HTML encoded data within the result set. Some
characters were being displayed in their html encoded form (i.e. an apostrophe
(') as '). This has been fixed.

================(Build #3393 - Engineering Case #446965)================

The fix for Engineering case 433730 introduced a problem which caused the
types for procedure parameters and function results defined using user-defined
types to be set incorrectly. As well. the problem could have affected procedures
which returned XML data. This has been fixed.

================(Build #3393 - Engineering Case #445543)================

When run on HP-UX systems, connection attemps using TCPIP would have failed
when using the single threaded 32-bit client libraries. This problem has
been corrected.

================(Build #3393 - Engineering Case #445369)================

If an INSERT ... SELECT query involved both remote and local tables, and
the table being inserted into was a view, then the query would have failed
with a "column not found" error. This problem has now been fixed.

================(Build #3393 - Engineering Case #445069)================

If a statement representing a query was dropped before the cursor using it
was closed, the system procedure sa_get_request_times() could have reported
a time for the statement which was too low. The sa_get_request_times() procedure
calculates statement duration using the enter and exit times for a subset
of the requests associated with that statement. Individual FETCH requests
are not considered, since request logs frequently do not contain that level
of detail. For queries, most of the time occurs between OPEN and CLOSE, so
sa_get_request_time() calculates the difference between the enter time for
the OPEN and the exit time for the CLOSE and adds that to the total for the
statement. While processing the log, it only keeps track of statements which
it considers "active". It discards its knowledge of a statement when it sees
a DROP for the statement. Many (if not most) applications perform queries
using the following sequence:
PREPARE
DESCRIBE
OPEN
FETCH ...
CLOSE
DROP

While the server can handle the statement being dropped before a cursor
using that statement is closed, sa_get_request_times() could not. This has
been fixed.

One possible workaround is to remove the lines representing the statement
DROP from the request log before calling sa_get_request_times(). Assuming
that statement handles are not re-used within the request log, this should
allow the correct times to be obtained.

================(Build #3393 - Engineering Case #445049)================

If an EXECUTE IMMEDIATE statement was used to execute a string representing
a compound statement having a single executable statement and an exception
handler, the exception handler would have been ignored. This has been fixed.
Adding a RETURN before the EXCEPTION would be a work around.

================(Build #3390 - Engineering Case #444758)================

When run on Windows CE, if the server executable was located on a filesystem
controlled by the Intel Persistent Storage Manager (IPSM), typically rooted
at the \IPSM directory, then the server and the Windows CE device could have
hung. The hang only occurred while writing data to a non-database file which
is also located on the IPSM, such as the server output log (-o command line
option), and was due to a problem with the IPSM driver. A work around to
this problem has been implemented. Moving non-database files to RAM is a
workaround.

The following is a copy of the IPSM bug description from Intel:

Note that other ASA components or 3rd party applications which might write
compiled-in strings to a file on IPSM will also be susceptible to this bug.
For 3rd party applications (or for ASA components prior to this fix), the
user can avoid the problem by copying the executables & DLLs into the RAM
disk or onto another flash device and running them from there instead of
from IPSM.

================(Build #3389 - Engineering Case #444627)================

Simple SELECT queries may have had a less than optimal query plan, which
may have resulted in poor performance. A bypass cursor has built for queries
that selected from a single table, even if the WHERE clause referenced only
some of the columns of the primary key with equality predicates. This has
been fixed.

================(Build #3389 - Engineering Case #444457)================

If the server displayed the message: "Cannot create stream controller thread"
on startup, it may not have been possible to connect to a server in this
state, and applications that were able to connect may have received communication
errors. This error only occurred if the server ran out of address space
(approximately 2GB of address space is available on 32bit Windows operating
systems). This has been fixed so that the server will now fail to start if
this error occurs. When this error occurs, the maximum cache size should
be reduced by at least 10MB.

================(Build #3389 - Engineering Case #444429)================

Web service SOAP client calls could have used temporary file pages without
releasing them, with at most one page would have been leaked per SOAP request.
The visible result of this leak was that the temporary file could slowly
grow in size over time when SOAP client calls were made. Since the leaked
pages were left in the cache, the effective size of the cache would also
have decreased over time. This has been fixed.

================(Build #3388 - Engineering Case #405626)================

The database server could have stopped writing to the console log file if
the file could not be opened after being renamed due to growing to its maximum
size. One cause for this would be a virus scanner which scans files immediately
after they are modified. This has been fixed so that logging to the file
will continue once the file can be opened again. There is a chance that
some messages may not be logged if this occurs.

================(Build #3385 - Engineering Case #444106)================

Complex disjunctive (OR) search conditions in a query's WHERE clause could
have been incorrectly transformed by rewrite optimizations in the server,
yielding a search condition not equivalent to the original, and hence yielding
incorrect results. It is difficult to completely characterize the types of
search conditions affected by this problem. However, for the problem to have
occurred, the search condition must have contained so many disjunctive conditions
that the condition exceeded a (generous) threshold of the maximal number
of potential predicates to generate.

The following example illustrates the complexity of a search condition necessary
for this problem to occur. However, the number of disjunctive clauses, and
the number of predicates in each clause, are not alone a guarantee of exhibiting
the problem:

select count(*)
from in_all
where
(d4=1 and d5=9 and d6=90 and d8=122)
and
(
(d7=4 and d8=122 and d9=138)
or (d8=122 and d9=112)
or (d3=57 and d7=4 and d8=122 and d10=4)
or (d8=122 and d9=65)
or (d3=76 and d7=1 and d8=122 and d9=62 and d10=2)
or (d3=62 and d4=1 and d7=1 and d10=2)
or (d3=76 and d4=1 and d5=9 and d7=3 and d10=1)
or (d3=55 and d4=1 and d5=9 and d6=90)
or (d3=124 and d7=4 and d8=122)
or (d4=1 and d7=2 and d8=122 and d9=37 and d10=1)
or (d3=22 and d7=1 and d8=122 and d10=2)
or (d3=76 and d4=1 and d5=9 and d8=122 and d9=37)
or (d3=31 and d7=1 and d8=122 and d9=59 and d10=2)
or (d3=57 and d4=1 and d7=1 and d8=122 and d9=59 and d10=2)
or (d3=110 and d4=1 and d5=9 and d10=4)
or (d3=76 and d7=1 and d8=122 and d9=23 and d10=3)
or (d3=150 and d7=1 and d8=122 and d9=23 and d10=2)
or (d3=36 and d7=1 and d10=2)
or (d3=30 and d4=1 and d7=2 and d8=122)
or (d4=1 and d7=5 and d8=122 and d9=136 and d10=1)
or (d3=76 and d4=1 and d5=9 and d6=90 and d7=2 and d10=4)
or (d3=110 and d8=122 and d9=59 and d10=1)
or (d4=1 and d5=9 and d7=3 and d8=122 and d9=37 and d10=4)
or (d3=61 and d4=1 and d5=9 and d8=122)
or (d3=91 and d7=3 and d10=4)
or (d3=216 and d7=1 and d10=2)
or (d4=1 and d5=9 and d7=4 and d8=122 and d9=37)
or (d3=30 and d4=1 and d8=122 and d9=23)
)
and date1 = 200406

This has been fixed.

================(Build #3385 - Engineering Case #443782)================

An HTTP request to a web service running in the server with an arbitrary
query string, would have been rejected with a 400 - 'Bad Request'. The SA
web server required the query component of the request URL to have one or
more name value pairs in the following format: 'name=value[&name2=value2...]'.
This restriction has been removed, so that now an arbitrary query string
will not be rejected.

For convenience, calling the http_header() function and specifying the pseudo-header
@HttpQueryString will return the query string component of the URL verbatim.
The function call next_http_variable() can be used to cycle through all the
keys, regardless of whether or not they contain a value.
A query string with no key and a value (e.g. http://localhost/x_service?=value)
can only be processed by parsing the query string as it is returned from
an http_header('@HttpQueryString') call.

Example:
http://localhost/a_service?h&0&name=value&=x
http_header('@HttpQueryString') returns: h&0&name=value&=x
An iteration of the next_http_variable function would return the following
keys: h, 0 and name (x is ignored). Using the http_variable function, the
value of h and 0 is '' (empty string) and the value of name is value.

================(Build #3385 - Engineering Case #443564)================

The server could have reported an assertion failure when processing an INSERT
statement for a table that had a particular form of publication. For example,
fhe following assertion failure could be reported: "Assertion failed: 102501
(9.0.2.xxx) Work table: NULL value inserted into not-NULL column" In this
case, the INSERT statement would fail, but the server would continue to run
and remain available for further requests. This has been fixed.

================(Build #3385 - Engineering Case #442641)================

If an UNLOAD statement includes ESCAPES OFF and QUOTES OFF and attempts to
unload a long string, the server could crash or generate garbage characters
in the output file. This has been fixed.

================(Build #3383 - Engineering Case #443285)================

The utilities dbunload, dbbackup and dbinfo, would not have operated correctly
when connected to a SQL Anywhere database that had the SQL_flagger_error_level
or SQL_flagger_warning_level options set to anything other than 'W'. Typical
behavior included getting the error message Disallowed language extension
detected..." when connecting. This has been fixed.

================(Build #3383 - Engineering Case #440903)================

If a table was defined with a trigger that fired for more than one type of
event (e.g. INSERT and UPDATE) ,while unlikely, a server crash could have
occurred if operations were being performed on the table while another connection
was performing a DDL statement. This has been fixed.

================(Build #3381 - Engineering Case #442928)================

If a server was run on a big endian machine, then attempting to retrieve
an unsigned integer value from a remote server could have returned a 0 instead
of the actual value. This problem has been fixed.

================(Build #3381 - Engineering Case #441260)================

If an INSERT ... FROM SELECT ... statement was used with the ON EXISTING
SKIP/ERROR clause, and the table being inserted into contained default columns,
then the server would have computed default values even for rows that already
existed. As a consequence, default values, such as autoincrement, were calculated
even for skipped rows resulting in skipped values in the autoincrement sequences.
The server now does not compute default values for rows being skipped.

The behaviour is not going to be changed in 10.x and newer versions, as
it is more consistent with what happens when the insert fails for a row that
already exists, and the ON EXISTING clause was not specified. As an example,
the following code will also cause autoincrement values to be skipped:

create table t1( c1 int primary key, c2 int default autoincrement );
insert into t1(c1) values(1);
insert into t1(c1) values(1);
insert into t1(c1) values(2);

The values inserted for the example above are:

1,1
1,3

================(Build #3379 - Engineering Case #442791)================

Creating a user defined domain with a long default value or CHECK condition
(greater than ~258 characters) would have caused a memory leak. This has
been fixed.

================(Build #3378 - Engineering Case #442761)================

The server could have failed with a 'Fatal error: disk full' error when writing
to the temporary file, even with TEMP_SPACE_LIMIT_CHECK turned on. This
has been fixed.

================(Build #3377 - Engineering Case #442268)================

A query containing an outer join, where the null-supplying side was a derived
table, may have failed with the error "The optimizer was unable to construct
a valid access plan". This occurred when the outer join was used in a correlated
subquery of an EXISTS, NOT EXISTS, ANY or ALL predicate, and the derived
table must have been uncorrelated, and not flattened (ie., it is a GROUPED
query, a UNION query, etc.) This has been fixed

For example:
select * from product p1
where EXISTS(select *
FROM product p2
left outer join (select p3.id, count(*) from product p3 group by p3.id )
as P(ID, c) ON P.id = p2.id
WHERE p2.id = p1.id )

================(Build #3375 - Engineering Case #441978)================

The changes for Engineering Case 440786 introduced a problem such that running
a large query that referenced proxy tables that were executed in FULL PASSTHRU
mode, could have failed with a memory allocation error. This problem has
been fixed.

================(Build #3375 - Engineering Case #441970)================

Attempting to perform an INSERT ... SELECT, where the select involved a derived
table that referenced both local and proxy tables, and the table being inserted
into was a local table, could have caused the server to crash. This problem
has been fixed.

================(Build #3375 - Engineering Case #441560)================

An application compiled to the DBTools API, which includes most the ASA database
tools including dbremote, dbmlsync and dbltm, could have reported an "Out
of memory" error, even though there appeared to be free memory on the system
where the error was reported. This has now been fixed.

================(Build #3374 - Engineering Case #441784)================

It was possible to call the system procedure sa_server_option with the option
'quitting_time' and set an invalid datetime parameter. This has been fixed.

================(Build #3373 - Engineering Case #441677)================

If a fatal error was encountered when starting a network listener thread,
and the server may have crashed as it was shutting down. This problem has
been fixed.

Note, this would only have occurred with servers running on Unix platforms.

================(Build #3371 - Engineering Case #405389)================

Calling a procedure using Transact-SQL EXECUTE syntax, and passing a subquery
as one of the parameters, could have caused a server crash. Attempt to pass
a subquery as a parameter will now result in a syntax error when using Transact-SQL
syntax for the call. This is the behaviour when using Watcom-SQL syntax..

================(Build #3369 - Engineering Case #441010)================

Executing a query that referenced a window function with a constant string
argument could have caused the server to crash. This has been fixed.

================(Build #3369 - Engineering Case #440041)================

The hash join algorithm has an optimization to scan the right input using
an index scan if the left side is small enough such that using the index
provides a cheaper strategy (shown as JHx in the plan). In some cases, the
use of this indexed strategy could have caused a server crash. One particular
way for this problem to occur was for the right hand table to contain a large
number of rows that had been deleted with the deletes not yet commited. This
problem has been fixed.

================(Build #3368 - Engineering Case #440783)================

It was possible for connections with communication compression enabled to
get communication errors. The problem was timing dependent, thus would have
been rare, and could have occurred if the data being transferred had poor
compression rates. This has been now been fixed.

================(Build #3368 - Engineering Case #439707)================

It was possible for the server to have crashed if the system procedure sa_server_option(
'RequestLogFile', ... ) was called while requests were running. This was
less likely on single processor machines. This has been fixed.

================(Build #3367 - Engineering Case #440689)================

Executing a remote query that contains a derived table which is a UNION,
would very likely have crashed the server. When analyzing the query and attempting
to determine the server id of the derived table, the server was assuming
that the derived table was always a simple select. The server now properly
handles the case where the derived table is a UNION, INTERSECT or EXCEPT.

================(Build #3366 - Engineering Case #440465)================

Attempting to upgrade a database created with software that is newer than
version 6.0.2, and older than version 8.0.0, where the public setting for
the Date_order option had been changed, would have failed with a conversion
error. This problem has now been fixed.

================(Build #3366 - Engineering Case #440462)================

When executing a query that involved a remote table, and an aggregate whose
argument was a concatenation with a user-defined function, the server would
have failed with the error "syntax error near unknown", rather than successfully
running the query. This has been fixed.

For example, the following would have generated the syntax error:
select min( cast( 'fred'||dba.NewID() as varchar(25) ) )
from remote_t
where remote_t is a proxy table and NewID() is a user-defined function.

================(Build #3366 - Engineering Case #439705)================

If a query contained a nested loops join with a subselect expression used
for the first time on the null-supplying side of the join, and also used
above the nested loops join, then the query could return the wrong answer
or possibly crash. This has been fixed.

================(Build #3366 - Engineering Case #437266)================

If a proxy table was created that referenced a table that had columns with
unsigned datatypes (i.e. unsigned smallint, unsigned bigint, and unsigned
int), then querying the data of the proxy table would have given incorrect
conversion errors. This problem has now been fixed.

================(Build #3366 - Engineering Case #434469)================

The server may have crashed if a trigger on a table that had multiple triggers
for the same event (ie. foreign keys with CASCADE referential actions), was
currently executing and another connection's operation (e.g. create publication,
alter table/view/publication, drop table/view/publication/domain, revoke)
marked all the triggers for reload. This has been fixed.

================(Build #3365 - Engineering Case #439597)================

The server may have crashed if a select list alias (e.g. "cols" in the example
below) was used in a LIKE predicate.

For example:
select table_name,
( select list(column_name) from syscolumn a where a.table_id = b.table_id
) cols
from systable b
where cols like 't%'

This has been fixed.

================(Build #3364 - Engineering Case #440231)================

When executing a FOR statement, where the CURSOR USING clause referenced
a variable, the server would have crashed with a SIGBUS on platforms that
enforce alignment, such as Solaris/SPARC. This problem has been fixed.

================(Build #3363 - Engineering Case #440146)================

Optimization of a query could have taken longer than necessary if it had
multiple window functions, each with a distinct window specification. In
practice, at least 10 windows functions would have been required for this
to have been noticeable. The problem has now been fixed.

================(Build #3363 - Engineering Case #439790)================

The selectivity estimation of a predicate of the form 'col IS NULL' is now
recomputed if the column 'col' is generated by the null-supplying side of
an outerjoin, and the predicate is evaluated after the outerjoin is computed.
Previously under these conditions, the selectivity estimation used (for example,
the histogram for the column 'col') was not accurate, as those estimates
did not take into account that the column 'col' may have been NULL supplied
by the outerjoin.

================(Build #3360 - Engineering Case #439687)================

SQL Anywhere web service client HTTPS connections may have truncated received
data. This has been fixed.

================(Build #3356 - Engineering Case #440007)================

The Interactive SQL utility now supports the new DIRECTORY clause added to
the START DATABASE statement by Engineeering case 438139.

================(Build #3354 - Engineering Case #453705)================

The server may have crashed after executing an xp_cmdshell() system procedure.
This problem has been fixed.

================(Build #3354 - Engineering Case #438857)================

The server could have incorrectly detected CPU characteristics, such as the
number of physical and logical cores, when run on some newer processor architectures.
This has been fixed.

================(Build #3350 - Engineering Case #438231)================

Attempting to execute a statement using the Open Client isql utility, that
failed with a conversion error, and which referenced to a proxy table, would
have leaked cache memory. If such statements were executed many, many times,
the server would have eventually failed with a "Fatal Error: Memory Exhausted".
This has now been fixed.

================(Build #3349 - Engineering Case #438075)================

If the server was started with the TCP/IP option ServerPort=0, no connection
through that link was possible, and the client error message did not help
in diagnosing the cause. This has been fixed so that the server can no longer
be started if one of the specified server ports is 0, and the error message
"Illegal value for option 'ServerPort'" will be displayed.

================(Build #3345 - Engineering Case #437700)================

When the database option Temp_space_limit_check was set to 'on', the temporary
file space used by user temporary tables, such as those created with DECLARE
LOCAL TEMPORARY TABLE, was not included in the temporary space limit checking.
This has now been fixed.

================(Build #3345 - Engineering Case #436457)================

The server could have leaked memory if user-defined datatypes containing
check constraints were used as column datatypes when creating tables. This
would have resulted in a server slowdown, and eventually a "memory exhausted"
error. This has been fixed.
In the course of fixing this problem a second memory leak was found that
affected columns that had check constraints, but were not user defined datatypes.
This has been fixed as well.

================(Build #3343 - Engineering Case #437306)================

It was possible, although extremely rare, for a database to get into an inconsistent
state, where some rolled back transactions would appeared to have been committed.
The chances of this happening were moret likely when performing several large
operations without doing any commits, and the operations also spanned checkpoints.
The connection doing the operations would have needed to be disconnected
before committing, and then the server must have gone down dirty at the appropriate
time. It also would have been more likely when 'savepoints' and 'rollback
to savepoint' were used. This has now been fixed.

================(Build #3343 - Engineering Case #437296)================

If an RPC call was made to an ASE remote server, the call may have failed
or hung. The problem was due to to the fact that RPC calls to ASE usually
need to be made with AUTOCOMMIT on. RPC calls are now always made with AUTOCOMMIT
on regardless of the back end, whereas previous calls were made within a
transaction with AUTOCOMMIT off.

================(Build #3340 - Engineering Case #436994)================

Illegal XML element names would have been generated within the WSDL output
of a SQLAnywhere DISH service whose name contained one or more forward slash
('/') characters. This caused some SOAP toolkit clients to fail, notably,
Visual Studio 2003 C# .NET will fail to 'Add WebReference' if the DISH service
name contained a '/'. This has been fixed so that DISH services may not
be created or altered if the service name contains a forward slash.

Note, any other service name may contain a forward slash.

================(Build #3340 - Engineering Case #435951)================

Expressions involving arithmetic operations with numeric data could have
yielded results with a precision that was greater than the maximum allowed
by the PRECISION database option. This has now been fixed.

================(Build #3339 - Engineering Case #437270)================

In rare situations, the server could have stopped processing requests for
a database when one user was attempting to CREATE, DROP or ALTER a procedure
while other users were calling procedures. This has been fixed.

================(Build #3337 - Engineering Case #436306)================

Attempting to make an encrypted connection using transport-layer security,
from a
non-threaded Unix clients, would have caused the application to hang. This
has now been fixed.

================(Build #3334 - Engineering Case #435243)================

The server could have crashed when running a stored procedure following the
execution of a DDL statemnt against the server. The server was failing to
detect that a cached plan for a procedure that has been reloaded (due to
a schema version change), was no longer valid. This has been fixed by not
allowing plans to be cached if the procedure is flagged as needing a reload.

A workaround is to set the option MAX_PLANS_CACHED to zero (although this
will hurt the performance of stored procedures).

================(Build #3333 - Engineering Case #435348)================

If an HTTPS connection was closed by the client while the initial connection
handshake was still in progress, the server could have crash. This has been
fixed.

================(Build #3333 - Engineering Case #422515)================

If there were active client or http requests when the server was shutting
down, there was a possibility, although small, that the server could have
crashed. If a crash occurred, it would have been after the databases were
stopped, so there was no chance of data loss. This has now been fixed.

================(Build #3332 - Engineering Case #433730)================

If a domain was dropped and re-created within a batch, and the batch also
included a subsequent reference to the domain in a CREATE TABLE or ALTER
TABLE statement, the server could have crashed. This has been fixed.

================(Build #3331 - Engineering Case #435053)================

If all other server threads were blocked, and the last server thread attempted
to execute a WAITFOR statement, the statement would have failed to wait and
server usage would have risen to 100%. The wait failed as a thread deadlock
would have occured on a wait. Executing WAITFOR on the last non-waiting
thread will now generate a thread deadlock error and will no longer result
in 100% CPU usage.

================(Build #3331 - Engineering Case #435039)================

When starting a database on a running server by passing the DatabaseFile
parameter (DBF), if the DatabaseKey parameter (DBKEY) is passed unnecessarily,
the server prints a warning message using the database file name. If the
database being connected to was the utility_db, for which there was no actual
file, the server would have crashed. This has now been fixed.

================(Build #3330 - Engineering Case #434601)================

If a procedure appeared in a select's FROM clause, and the procedure's select
list exceed the syntactic limit of the server, the server would have crashed
during execution of the CREATE PROCEDURE statement. This has been fixed.

================(Build #3329 - Engineering Case #434641)================

Use of an IF or CASE expression in an OLAP window function argument would
have given a wrong result, unless the leading edge of the window was always
the current row (e.g. when using "range between x preceding and current row").
This is fixed.

================(Build #3329 - Engineering Case #434510)================

Any variable name in an HTTP request that was HTTP encoded (e.g., "Test%20Name")
was not being HTTP decoded before being presented to the user. This has been
fixed.

================(Build #3329 - Engineering Case #433741)================

Although rare, the server may have crashed if at that moment a shared memory
connection was being established, the client process disappeared. For the
same reason a client application may have crashed if the server disappear
at the moment the application was about to establish a shared memory connection.
This has been fixed.

================(Build #3328 - Engineering Case #434364)================

If an external function DLL name contained a non-ASCII character, and the
OS and database character sets were different, then the external function
DLL would have failed to load with the following error:

Could not load dynamic library '<dll name>' [-620] ['WW006']

The external function DLL was being loaded using the name of the DLL encoded
in the database's character set. This has been fixed so that the external
function DLL is now loaded using the name of the DLL encoded in the native
character set.

================(Build #3327 - Engineering Case #433582)================

Engineering case 428075 introduced a problem where the server could hang
when starting a database read-only that was stored on a CD-ROM. This has
been fixed.

================(Build #3327 - Engineering Case #433047)================

The LOAD TABLE statement could have incorrectly loaded multi-byte character
data, due to incorrect accounting for a split character in a buffer. The
loaded data would appear to have characters or bytes within it that were
not part of the original data. This has been fixed.

================(Build #3327 - Engineering Case #431369)================

An INSERT statement with the ON EXISTING UPDATE clause could have failed
with an incorrect referential integrity error. This would only have occurred
if the table had a single column primary key, and there existed a row where
value of this column was the same as another column value in the VALUES clause.
This has been fixed, but a workaround would be to use an UPDATE statement
when the primary key value already exists.

================(Build #3326 - Engineering Case #433934)================

A memory leak may have occurred when web service client procedure parameters
were converted to Strings for XML or HTML representation. This has been fixed.

================(Build #3326 - Engineering Case #433829)================

It was not possible to interrupt or cancel execution of a CREATE STATISTICS
statement. As a consequence, if an exclusive operation such as a CHECKOINT
started in the middle of executing a CREATE STATISTICS statement, then all
other connections would have had to wait until both the CREATE STATISTICS
and the CHECKPOINT completed executing. This problem has been resolved by
having the CREATE STATISTICS operation context switch.

================(Build #3326 - Engineering Case #433484)================

The server may have crashed if an UPDATE statement contained a subquery with
a GROUP BY clause, and the subquery was merged into the main query block.
This has been fixed.

================(Build #3326 - Engineering Case #430576)================

It was possible, although rare, for the server to hang while doing an ALTER
TABLE. A deadlock problem updating histograms has been fixed.

================(Build #3324 - Engineering Case #432886)================

Attempting to reference a hexadecimal literal with an odd number of characters
between 9 and 15 characters long inclusive, would have caused a syntax error.
For example:
select cast( 0xF1234ABCD as bigint );
This has been fixed, as now an extra zero is added to the front of odd length
hexadecimal strings. Note, hexadecimal strings that are odd in length, and
too large to fit into a BIGINT, will still generate a syntax error.

================(Build #3323 - Engineering Case #433164)================

Engineering case 418264 introduced a problem such that if the server crashed
while executing a CREATE VIEW operation, there was a small window of opportunity
where the database could have become unrecoverable. The redo-log processing
would have failed trying to recreate the view. This has been fixed.

================(Build #3323 - Engineering Case #426186)================

If an embedded SQL application executed a PUT on a non-updateable cursor
with the option ANSI_UPDATE_CONSTRAINTS set to OFF, the server could have
crashed. This has been fixed.

================(Build #3322 - Engineering Case #433072)================

If a keyset-driven cursor (value sensitive cursor) was opened on a query
that contained a derived table used on the null-supplying side of an outer
join, and the derived table contained a subquery, then, depending on the
access plan selected, the server could have crashed, or in some cases, the
wrong answer could have been returned for the query.

The following is an example of the type of query that would be affected
by this problem if used in a keyset-driven cursor:
select ( if D1.y is null then 0 endif ) as z
from T1 left outer join
( select T2.b,
cast( sum( if T2.c = any( select T3.e from T3 WITH ( INDEX(T3)
)
where f in( 1001,1020,1040,1080,10100,10200,10400,10500,101000,102000))
then T2.d
endif) as numeric(12,4) ) as y
from T2
group by T2.b
) as D1
on T1.a = D1.b

The incorrect behaviour relies on the specific access plan selected. This
problem has been fixed.

================(Build #3320 - Engineering Case #432903)================

The server could crashed if an updatable keyset driven cursor was opened
for a query that had a predicate with an IF or CASE expression over a subquery.
This has been fixed. This is a similar issue to Engineering case 430465.

================(Build #3320 - Engineering Case #430465)================

If an updateable table in an updateable cursor was defined in a SQL Remote
or MobiLink article, retrieving the plan for the query could have caused
the server to crash.

================(Build #3319 - Engineering Case #432730)================

The server may have crashed, although occurences would have been rare, if
multiple connections ran the same stored procedure for the first time after
the database was started, and the procedure was used in a select statement.
This has been fixed

================(Build #3319 - Engineering Case #432246)================

If a query had a predicate of the form 'T.col1 = DT.col2', where DT was a
derived table or view, and T.col1 and DT.col2 had different domains, it was
possible for the server to return an incorrect result. This has been fixed.

For example:
create table T (x tinyint);
create table R (x smallint);
SELECT * FROM R, (SELECT T.x FROM T GROUP BY T.x ) dt
WHERE R.x = dt.x

================(Build #3316 - Engineering Case #432297)================

Graphical plans written to the server log had information missing 'Optimizer
statistics' sections. The following information is now displayed for these
plans:

CurrentCacheSize Current cache size in kilobytes
Isolation_level Controls the locking isolation level
Optimization_goal Optimize queries for first row or all rows
Optimization_level Reserved
Optimization_workload Controls whether optimizing for OLAP or mixed queries
ProductVersion Product version
User_estimates Controls whether to respect user estimates

Note, logging graphical plans to the server log is enabled by starting the
server with the -zx command line option, or by calling the system procedure
sa_server_option:

sa_server_option ( 'RequestLogging', 'NONE' );
sa_server_option ( 'RequestLogFile', {file_name} ); -- append to file
sa_server_option ( 'RememberLastPlan', 'ON' );
sa_server_option ( 'LogExpensiveQueries', {x} ); -- cost {x} threshold
in milliseconds

================(Build #3316 - Engineering Case #432113)================

The server could have crashed while generating a graphical UltraLite plan.
This has been fixed by adding a missing check for a NULL pointer.

================(Build #3315 - Engineering Case #432212)================

If a user had been granted select permissions on a view which referenced
a proxy table, but did not have select permissions on the underlying proxy
table, querying the view inside an IF or CASE expression would have failed
with a permission denied error. This problem has now been fixed.

Note that using the view outside of an expression would have worked fine.

================(Build #3314 - Engineering Case #432074)================

When run on Windows CE devices, the server could have crashed if the language
DLL could not be found or loaded. This has been fixed. A dialog stating the
language DLL could not be found will now be displayed.

================(Build #3312 - Engineering Case #431929)================

A SQLAnywhere SOAP webservice declared to return data in 'XML' would have
returned the XML data in unencoded form. This has been fixed so that the
XML data is now encoded and typed as an XMLSchema string type. A SOAP client
will unencode the XML data and assign it as a string, suitable for post processing
with an xml parser. The following SOAP response of a hello_svc webservice
demonstrates this behaviour:

<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope...>
<SOAP-ENV:Body>
<tns:hello_svcResponse>
<tns:hello_svcResult xsi:type='xsd:string'><tns:rowset><tns:row><tns:hello>Hello
World</tns:hello></tns:row></tns:rowset>
</tns:hello_svcResult>
<tns:sqlcode>0</tns:sqlcode>
</tns:hello_svcResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

A SOAP client will decode hello_svcResult element into a string as follows: <tns:rowset><tns:row><tns:hello>Hello
World</tns:hello></tns:row></tns:rowset>

================(Build #3311 - Engineering Case #431810)================

The server may have crashed, rather than return the error "OMNI cannot handle
expressions involving remote tables inside stored procedures" (SQLCODE -823
: SQLE_OMNI_REMOTE_ERROR).

For example (x is a remote table)

declare @x int
declare @y int
select @x =1
select @y =1
if (select x from x where y = @y) = @x + 1
print 'yes'
else
print 'no'

This has been fixed.

================(Build #3308 - Engineering Case #431023)================

If a SQL Anywhere Webservice Client was defined with a PROXY clause and the
proxy url, and/or the URL clause, contained a non-default port specification,
the web service request may have failed. This has been fixed.

The following example illustrates a relevant use case:

alter procedure f2c("temp" float )
url 'http://hostname:8081/f2c'
type 'SOAP:RPC'
proxy 'http://proxy-host:8080';

================(Build #3305 - Engineering Case #430564)================

If a connection executed a statement that caused the server's Java VM to
start, and another connection that was executing a Java statemet was canceled,
it was possible, although rare, that all connections could appear to hang
(ie. deadlock) in the presence of DDL statements, checkpoints, backups, and
possibly other operations, . This has been fixed.

================(Build #3305 - Engineering Case #430425)================

If a column was defined with DEFAULT GLOBAL AUTOINCREMENT before the value
of the Global_database_id option was set, and the new value for the option
was 0, the max_identity value of the column would not have been set based
on existing rows in the table. This has been fixed.

================(Build #3303 - Engineering Case #430229)================

If the LIST() function was used with a query over a large number of rows
and the result of the function was also large, the query would execute slowly
but would return the correct result. Changes have been made so that the same
query will now execute much faster.

================(Build #3302 - Engineering Case #429894)================

Executing an INSERT statement that used the ON EXISTING UPDATE clause, on
a table whose primary key contained column(s) with default values, but did
not provide a value for one of these default columns, could have caused the
INSERT to perform incorrect data changes. This problem has been resolved.

================(Build #3301 - Engineering Case #430554)================

Queries that contained predicates with subqueries that used a range clause
(i.e., FIRST, TOP N, TOP N START AT M) may have returned an incorrect result
set. The subquery had to have been correlated, and an ORDER BY clause was
not specified. This has been fixed.

The following examples demonstrate the problem:

select * from product p where p.id > any( select TOP 10 prod_id from sales_order_items
s where s.quantity > p.quantity )

select * from product p where exists( select TOP 10 START AT 2 * from
sales_order_items s where s.quantity > p.quantity )

================(Build #3301 - Engineering Case #429978)================

If a query contained window aggregate functions such as SUM(T.X) OVER (PARTITION
BY T.Y), and the query had a subquery appearing in an EXISTS, ANY, or ALL
predicate, then the query may have returned an incorrect result set. This
has been fixed.

For example:
select id,
sum( quantity) over (partition by size )
from product p
where exists( select 1 from sales_order_items s where s.quantity > p.quantity
)
and size = 'Large'
order by id

================(Build #3300 - Engineering Case #429026)================

When searching for the .odbc.ini file on Unix systems, the ODBC driver would
have first searched the current directory, and if one was found, would have
used it, incorrectly taking precedence over the search locations documented
in the SQL Anywhere Database Administration Guide. For example, a .odbc.ini
file found in the current directory would be used even if the ODBCINI environment
variable was set to reference a different file. This has been fixed so that
the search order is as documented.

Note, an application that is dependent upon finding the .odbc.ini file in
the current directory will need to explicitly include the current path or
full filename. The environment variables ODBCINI and ODBC_INI can be used
to specify the complete filename. The environment variables ODBCHOME, HOME
and PATH can be used to specify the directory containing .odbc.ini. Consult
the SQL Anywhere documentation for details.

================(Build #3299 - Engineering Case #429438)================

When the return value of a user-defined function was truncated, the server
created a temporary string that was not freed until the cursor was closed.
This problem only occurred with multibyte character set databases. This has
been corrected.

================(Build #3299 - Engineering Case #429267)================

The value returned for the ERRORMSG() function could have been incorrect
if the function was used within a procedure, and the statement referencing
it was executed repeatedly. The function was not defined as non-deterministic,
which as a result, may have caused plan caching to return a previous value.
This has been fixed.

================(Build #3298 - Engineering Case #429029)================

The changes for Engineering case 406765 could have caused a server crash.
The circumstances where this occurred were rare, and would have required
that the CONNECT or REMOTE permissions for a user be dropped, while dbremote
was actively replicating transactions for the user. This has been fixed.

================(Build #3295 - Engineering Case #428879)================

When using the Windows Service Manager to start and stop ASA services, the
option to pause
running services was available. This option has been removed for all services,
except for
dbltm.

================(Build #3295 - Engineering Case #428685)================

If the NUMBER(*) function was used in a subquery of an expression, and the
expression referenced a proxy table, the server may have crashed. This has
been fixed.

================(Build #3295 - Engineering Case #409734)================

It was possible for a call to an external function or procedure to have failed
without generating a SQL error. This was very unlikely and would only have
occurred when all other database request tasks (as set by the -gn server
switch) were internally blocked at the time the call was issued. In these
cases, the request that issued the call was terminated by the server to prevent
deadlock, but the SQLSTATE_THREAD_DEADLOCK error was not set for that connection.
This has been fixed by setting SQLSTATE_THREAD_DEADLOCK when this failure
arises. Additionally, under these circumstances, there was a very small window
of opportunity where an external function call failure could cause the server
to crash, most likely when being shutdown. This has also been fixed.

================(Build #3294 - Engineering Case #426330)================

Attempting to run two simultaneous archive backups, for different databases,
on the same server, could have caused the server to crash. The backup library
was being unloaded by the first operation to complete. This has been fixed.

This problem does not affect image backups created with BACKUP DATABASE
DIRECTORY or the DBBACKUP utility.

================(Build #3292 - Engineering Case #428075)================

It was possible for the server to hang while generating the plan for a query.
This has now been fixed.

================(Build #3289 - Engineering Case #427138)================

Server run on Unix systems with the -z command line option ("display debugging
information"), would have displayed a message indicating that a TCP/IP connection
has been received, when an HTTP or HTTPS request had been received. This
has been fixed. The message will now indicate that an HTTP (or HTTPS) connection
has been received (the same as on other platforms).

================(Build #3289 - Engineering Case #427121)================

Integrated login connections could have failed if INTEGRATED LOGIN was granted
to a Windows group, and the Windows group contained the particular user that
was connecting as domain\username. This has been fixed so that user 'username'
is now successfully logged in, even if they are in the Windows group as 'domain\username'.

================(Build #3289 - Engineering Case #426984)================

When upgrading a database, either by executing the ALTER DATABASE UPGRADE
statement, or running the Upgrade utility, the upgrade did not run the oleschem.sql.
This has now been corrected

================(Build #3287 - Engineering Case #426611)================

Calling connection_property( 'UnschReq' ) may have returned a value larger
than it should have been, particularly if multiple DROP CONNECTION statements
were issued against a single connection. This has been fixed.

================(Build #3286 - Engineering Case #426377)================

Attempting to execute an invalid recursive query (ie one that would have
failed with error "-921 - Invalid recursive query") could have caused the
server to crash, if it referenced remote tables. This has been fixed.

================(Build #3286 - Engineering Case #426279)================

The server may have crashed if an INSERT statement had subselects in the
VALUES clause that referenced remote tables, and the insert was executed
in no passthrough mode.

For example:
insert into T1 values ((select col1 from RemoteT1), (select col2 from RemoteT2))

This has been fixed so that now the server returns the error "Remote server
does not have the ability to support this statement", if SET items are subselects
in no passthrough mode.

To workaround this problem, the statement can be rewritten as an INSERT
... SELECT.

For example:
insert into T1 select (select col1 from RemoteT1), (select col2 from RemoteT2))

================(Build #3286 - Engineering Case #407422)================

It was possible for the server to fail with Assertion 200602: 'Incorrect
page count after deleting pages from table {table_name} in database {database_name}',
when dropping or truncating a table for which a LOAD TABLE had failed. It
was also possible for a failed LOAD TABLE to leak table pages, or temporary
file pages. A failed ALTER TABLE could have resulted in many other assertions
or strange behaviours. These problems would only have occurred if there where
other transactions actively committing and rolling back transactions at the
time of the LOAD TABLE or the ALTER TABLE. These problems have now been
fixed.

================(Build #3285 - Engineering Case #426167)================

The http_header() function returned an ASCII 0 control character when the
given header had no value. This has been fixed, the return value in this
case is now an empty string.

================(Build #3285 - Engineering Case #426165)================

If the SOAPAction URL was malformed an error of 400 'Bad Request' or 404
'Not Found' may have been returned. Now, a Malformed SOAPAction URL will
always return a 400 'Bad Request', whereas a correctly formed URL trying
to access a SOAP endpoint that does not exist will return a 404 'Not Found'.
This fix also simplifies the requirements for configuring an SA SOAP client
that accesses an SA SOAP service endpoint (client and server cannot be running
on the same database server).

The SOAPAction HTTP header is required by SA when a SOAP request is POSTed
to a DISH service endpoint. The SOAPAction URL is the 'address' of the SOAP
service endpoint for the request. Prior to this change an SA HTTP client
was required to provide a namespace clause that defined an appropriate URL
containing the database name for the endpoint service. Now it is now possible
to access an SA SOAP endpoint by assuming the use of its default database.
This only works in the simple case where the SA SOAP web service is not defined
within a 'group' of a DISH service. When a soap endpoint is defined within
a 'group', the SA SOAP client must specify the namespace to provide the appropriate
database and group mapping.

The simple case is described with two services as follows:

create SERVICE "wsdl"
TYPE 'DISH'
AUTHORIZATION OFF
format 'concrete'
USER DBA;

create SERVICE "soapecho"
TYPE 'SOAP'
AUTHORIZATION OFF
USER dba
AS call soapecho_proc( :s1 );

The following are valid SA SOAP client procedure definitions that access
the above soapecho service:

1) Access soapecho service directly (note, to stay consistent with the other
cases the format clause describes the desired output format):
create procedure soapecho( s1 long varchar )
url 'http://localhost/soapecho'
format 'concrete'
type 'soap:doc';

2) Access indirectly through the wsdl DISH service and specifying the namespace
(note, the server is expected to be running the sample.db):
create procedure soapecho( s1 long varchar )
url 'http://localhost/wsdl'
namespace 'http://localhost/sample'
type 'soap:doc';

3) With this change, namespace clause is no longer required:
create procedure soapecho( s1 long varchar )
url 'http://localhost/wsdl'
type 'soap:doc';

The above cases yield the following request characteristics:
CASE HTTP POST SOAPAction Namespace
1) POST /soapecho http://localhost/soapecho http://localhost
2) POST /wsdl http://localhost/sample/soapecho http://localhost/sample
3) POST/wsdl http://localhost/soapecho http://localhost

An example of a more complex case where the namespace clause for an SA SOAP
client is required (closely resembles case 2) above):

create SERVICE "wsdl"
TYPE 'DISH'
AUTHORIZATION OFF
format 'concrete'
group 'abc'
USER DBA;

create SERVICE "abc/soapecho"
TYPE 'SOAP'
AUTHORIZATION OFF
USER dba
AS call soapecho_proc( :s1 );

The namespace is required because it identifies both the database and the
group for the SA SOAP service endpoint:

create procedure soapecho( s1 long varchar )
url 'http://localhost/wsdl'
namespace 'http://localhost/sample/abc'
type 'soap:doc';

The resulting request is similar to case 2) with the exception that /abc
is appended to the SOAPAction URL and the soap envelope namespace URI.

================(Build #3285 - Engineering Case #426056)================

Attempting to execute a "SELECT INTO #temporary-table-name" statement, may
have caused a server crash in cases where it should have returned the error
"Statement size or complexity exceeds server limits". This has been fixed.

================(Build #3285 - Engineering Case #425955)================

The server would have reported an error when attempting to register with
LDAP, if the LDAP server was an Active Directory Server and the server was
listening on more than one IP address. This has been fixed.

Note, clients with this fix will not be able to connect through LDAP to
servers without the fix, and vice versa.

================(Build #3285 - Engineering Case #425925)================

It was possible for the server to crash if a user-defined datatype was dropped
while a CREATE TABLE statement, or an ALTER TABLE statement that added a
column of this type, was executing. This has been fixed.

================(Build #3284 - Engineering Case #425847)================

Queries containing expressions involving the GROUPING() function may have
returned incorrect results for those expressions. This has been fixed.

================(Build #3283 - Engineering Case #425513)================

Calling an HTTP client procedure with an unsupported data type, may have
caused the server to crash. This has been fixed.

================(Build #3283 - Engineering Case #425473)================

One of the server's recursive union execution strategies had inadvertently
become disabled. This could have caused poor performance for some recursive
queries and has been fixed.

================(Build #3282 - Engineering Case #425141)================

The AES_FIPS encryption type is not supported on 64-bit Windows, but attempting
to create a database of this type would have resulted in the error -976 "Could
not load the encryption DLL dbrsa9f.dll'". This has been fixed - the correct
error code -131 "Syntax error near 'encryption algorithm'" is now returned.

================(Build #3281 - Engineering Case #424923)================

Using an incorrect dot reference in a query that also references proxy tables,
would have failed with SQLCODE -660. The text of the error would be from
the remote server. This has now been fixed.

================(Build #3281 - Engineering Case #424920)================

Attempting to get the graphical plan for a batch, either using the GRAPHICAL_PLAN()
function or the Plan tab in Interactive SQL, or calling the REWRITE() for
a batch, could in some cases have caused the server to crash. This has been
fixed.

================(Build #3280 - Engineering Case #423730)================

A SOAP web service client procedure did not detect and encode string parameters
that contained XML special characters, such as '<', '>' or '&'. A string
parameter containing XML that was not well formed would have invalidated
the requesting SOAP envelope, causing an error at the web service endpoint.
This has been fixed so that Soap client parameters are now always encoded
(e.g. '<' becomes <).

================(Build #3280 - Engineering Case #423681)================

The server may have crashed during the second or subsequent executions of
a procedure,
if after its first execution, one of the referenced objects (table, view,
proxy table, etc) had been dropped and recreated with a changed type. For
example, a referenced table was dropped and a view with the same name was
recreated. This has been fixed

================(Build #3280 - Engineering Case #423578)================

Attempting to OPEN a cursor on a procedure call that returned the SQL warning
"Procedure has completed", would not have opened a cursor. The server still
created a cursor handle though, which was not freed until database shutdown.
This has been fixed so that the server will now return a NULL handle if the
cursor has not been opened.

================(Build #3279 - Engineering Case #424344)================

It was possible, although rare, for the server to crash if multiple requests
called the same stored procedure, and the procedure contained statements
of the form "select ... into #temp ...". This has been fixed.

================(Build #3277 - Engineering Case #423858)================

Applicatons connected via the CmdSeq protocol, could have crashed if a connection
request resulted in a warning. This has been fixed.

================(Build #3277 - Engineering Case #423828)================

SOAP v1.1 requires that the URI value of the HTTP SOAPAction header be enclosed
within double quotes. In the event that the quotes were missing the server
would have closed the HTTP connection without issuing an error response.
This has now been fixed so that the server will now respond with a "400 -
Bad Request".

================(Build #3274 - Engineering Case #423324)================

If a dynamic trap was set on a valid entry in the ASA MIB that was under
the agent or metadata subtrees, the SNMP agent would have crashed. This has
been fixed. Dynamic traps on these OIDs are not supported and they will be
ignored by the agent.

================(Build #3274 - Engineering Case #423139)================

In rare circumstances, the server may have crashed if a DROP PROCEDURE statement
failed because the procedure was currently in use. For this to happen there
must have been a disconnect in progress at the same time. This problem was
more likely to occur if the disconnect had to stop additional Java threads,
as would happen when using JDK 1.3. This has been fixed.

================(Build #3272 - Engineering Case #423129)================

It was possible, although very rare, for all connections to the server appear
to be hung (deadlocked) in the presence of DDL statements, checkpoints, backups,
or other operations, if a connection that was executing Java was cancelled.
This has now been fixed.

================(Build #3272 - Engineering Case #421142)================

On NetWare 6.5 with SP2 or later, the server may have abended if the database
server displayed a total of approximately 100kB worth of messages to the
console. This was due to a bug in the NetWare operating system relating to
the scrollable screen feature. To resolve this, the use of the scrollable
screen feature has been removed.

================(Build #3272 - Engineering Case #408903)================

Running the Validation utility would have cause the server's temporary file
to grow on each execution if validation with express check (-fx) was chosen.
This is the default mode in 9.0.2. The amount of growth would depend on the
number of tables in the database and the size of those tables. This has now
been fixed. A workaround is to validate using -fn rather than -fx. Validation
performance should improve with this fix as well.

================(Build #3270 - Engineering Case #422775)================

The optimizer would have underestimated the cost of using a clustered index
if the table pages were partially in the cache (for example, 40% of the table
pages were in the cache). This has been fixed.

================(Build #3270 - Engineering Case #422774)================

If the join predicates of a join involving a derived table, or a null-supplying
side of an outer join, contained equality predicates on the same column,
the estimated number of rows might have been incorrect. This has been fixed.

For example:

The derived table DT has two equality predicates on the column DT.X. The
estimated number of rows of the join of DT with (T join S) is underestimated
due to the fact that the selectivity estimations of the predicates 'T.X =
DT.X' and 'S.X = DT.X' are multiplied.

select *
from T, S, (select count(*), R.x, R.y from R group by R.X, R.Y ) as DT(
C, X, Y)
where T.X = DT.X and S.X = DT.X and T.X = R.X

================(Build #3270 - Engineering Case #422197)================

If a derived table was joined with the rest of the query using a Join Nested
Loops operator, the performance of the query may have suffered if the derived
table had to be computed many times due to many rows being generated by the
left hand side of the Join Nested Loops. The optimizer was choosing such
a plan if the estimated number of rows of the left hand side was very small.
If this estimation was wrong (e.g., the optimizer estimated one row for the
left hand side, but in reality the left hand side had 1,000 rows), the derived
table was computed many, many times during execution. This is now fixed by
having the optimizer only consider using the Join Hash or Join Sort Merge
operators for the derived table, if it is correct to do so.

================(Build #3268 - Engineering Case #422213)================

At isolation level 1, the last row visited by a keyset cursor scan before
finishing (ie a fetch returning 'row not found') would have been left locked
until the cursor was closed or moved. This has now been corrected.

================(Build #3268 - Engineering Case #422133)================

The changes for Engineering Case 421320 introduced a handle leak. As a result,
if many HTTP connections were received and serviced in a short time, the
server could have crashed. This has now been fixed.

================(Build #3268 - Engineering Case #421991)================

The server could have crashed while handling an HTTP request. The improper
handling of an HTTP header has been corrected.

================(Build #3266 - Engineering Case #420171)================

A failed UPDATE statement, for example due to a deadlock error, could have
resulted in a corrupted index. It is likely that only databases involved
in replication would have been affected by this problem. A database validation
with 'full check' would have detected that the index had missing values.
This has been fixed, but dropping and re-creating an index in such a state
will fix the corruption.

================(Build #3264 - Engineering Case #421320)================

If a partial HTTP request was received by the server, and the socket was
then closed, the server would have leaked three handles on Windows systems,
or one handle on Unix or NetWare systems. This has been fixed.

================(Build #3264 - Engineering Case #421161)================

If a user accidentally used a dot reference incorrectly, the syntax error
resulting from the incorrect use ws not reported properly by the server.
For example, if the following query was issued:

SELECT str(table_id).str(creator).length(table_name) from systable

the server would have reported "Syntax error near '' ???". The server will
now correctly report "Syntax error near 'length'".

================(Build #3264 - Engineering Case #420807)================

If the optimizer chose a query execution plan with a "Hash Table Scan" operator,
for a query that returned a string column, it was possible that a server
crash could have occurred. This has now been fixed.

================(Build #3263 - Engineering Case #421009)================

If a certificate was directly specified in a web procedure (i.e. using "certificate
'certificate=...'"), then it was possible that the connection would have
failed with the error "Error parsing certificate file". This has been fixed.
A workaround is to remove all whitespace in the certificate data.

================(Build #3263 - Engineering Case #420042)================

An INSERT, UPDATE or DELETE statement may have incorrectly returned the error
"Invalid statement", if the execution of the statement caused a trigger to
fire, or an RI action was executed, and a subsequent statement then failed
with a deadlock error. This has been fixed.

================(Build #3262 - Engineering Case #420864)================

While a database upgrade is in progress, event execution is not allowed.
If a scheduled
event did fire during a database upgrade it was correctly not executed,
but it was also incorrectly not scheduled for its next execution. This meant
that the event would not have been executed again until the database was
restarted. This has been fixed, so that now the event is rescheduled for
the next execution.

================(Build #3262 - Engineering Case #420749)================

On Linux and Solaris systems, the server command line option -ui ("automatically
choose UI") was not being accepted, and would have resulted in the usage
screen being displayed.
This has been fixed, and the switch now behaves as specified in the documentation.

================(Build #3262 - Engineering Case #420745)================

If a database that had been running on a network server with about 100 concurrent
connections or more, required recovery, attempting to recover the database
on a personal server would have failed assertion 104901 - "Allocating Stream
object for temporary connection failed". This has been fixed.

A workaround is to use the network server to recover the database.

================(Build #3261 - Engineering Case #419782)================

If a query contained an alias in the SELECT list, with the aliased expression
containing an IF or CASE expression, where the predicate in the IF or CASE
contained an EXISTS, ANY, or ALL predicate, and the aliased expression was
used as an outer reference in another subquery, and the execution plan contained
a materializing operator such as Hash Join, then incorrect results could
have been returned for the IF/CASE expression and the referencing subquery.

The following query demonstrates the problem using the demo database:

select T2.dept_id,
( if exists ( select 1 from sys.dummy T4 where T2.dept_head_id <>
-1 ) then 1 endif ) as S2,
( select 1 from sys.dummy T5 where S2 > 0 ) as S3
from
rowgenerator T0 with ( no index )
join department as T2 with ( no index )
on T0.row_num*100 = T2.dept_id

This has been fixed.

================(Build #3261 - Engineering Case #419708)================

Subqueries with an ANY or ALL condition, that also contained both a DISTINCT
and a TOP n clause (where n > 1), could have returned incorrect results.
The server was incorrectly eliminating the DISTINCT, which meant that some
rows could have been missed from the subquery. This has now been fixed.

================(Build #3259 - Engineering Case #420137)================

On Unix systems, if an application autostarted a server, used ASA's embedded
SQL function db_start_engine(), or used the Spawn utility to start a server,
and the application was terminated abnormally by SIGINT, SIGQUIT, SIGTERM
or some other unhandled signal (SEGV, etc), the server that had been started
would shutdown unexpectedly, although cleanly. This has been fixed.

A work-around is to specify -ud on the server command line, although this
has the side effect that the controlling application (e.g. dbspawn) will
return/continue immediately before the server has fully started all of its
databases, etc.

================(Build #3258 - Engineering Case #419897)================

When the server was running on NetWare, casting a string representing an
overly-large number to a double or float could have returned the value '1.#INF',
rather than setting error -158 (Value ... out of range for destination).
This has been corrected.

================(Build #3257 - Engineering Case #417335)================

The Lithuanian translation of error -100, Server not found, was improved.

================(Build #3256 - Engineering Case #419140)================

When the MESSAGE statement was called with the TO CLIENT clause, the registered
event handlers of AsaConnection.InfoMessage were not called. This problem
has been fixed so that registered event handlers are now correctly called.

================(Build #3252 - Engineering Case #418264)================

It was possible, although very unlikely, for the server to crash, or for
connections to deadlock and appear to hang, in the presence of concurrent
DDL statements. For one of these failures to have occurred, these concurrent
statements would generally have to refer to the same database object (i.e.,table,
column or stored procedure, etc), either directly or indirectly. A workaround
is to serialize all DDL requests that references the same object. This has
been fixed.

================(Build #3251 - Engineering Case #418346)================

If two or more users with DBA authority granted the same column update permission
to a user, these column permissions could then only have been revoked by
revoking the table update permission. Any attempt to revoke the column update
permission would have failed with the error "You do not have permission to
revoke permissions on <table>". This has been fixed.

================(Build #3251 - Engineering Case #417863)================

Calling a stored procedure that referenced a user-defined function in the
search-condition of an IF statement could have crashed the server if the
function called a procedure with OUTPUT or INOUT parameters defined as NUMERIC,
and then called another procedure. This has been fixed. A workaround is to
move the function call to an assignment statement preceding the IF.

================(Build #3249 - Engineering Case #404396)================

The server could have gone into an infinite loop while performing operations
on a database corrupted in a certain way. Validation of the database may
or may not have experienced the same behaviour. The server will now fail
with "Assertion 202101: Invalid bitmap links on page 0x%x" when such a condition
is encountered.

================(Build #3247 - Engineering Case #417598)================

If a web service procedure received an HTTP status of 300, 303, 405, or 406
from the remote web server, the error status would have been displayed as
"<status number> Unused". For example, if the error code 405 was returned
from the web server, the error displayed would have been "405 Unused" instead
of "405 Method Not Allowed". This has now been corrected by adding meaningful
strings for these errors.

================(Build #3247 - Engineering Case #407945)================

In some cases, secure web services (i.e. using HTTPS) may have failed to
connect, with the error "The connection was closed from the other side".
This has been fixed by upgrading to version 3.1.14 of the Certicom libraries.
Note that this problem did not occur on Mac OS X.

================(Build #3246 - Engineering Case #417512)================

An outer reference from a derived table to an alias should always give an
error. If the derived table was a UNION, INTERSECT or EXCEPT, the server
would have crashed instead. This has now been fixed.

================(Build #3246 - Engineering Case #417411)================

When using a moving window aggregate specified with a RANGE (not ROWS) clause,
an incorrect value of the aggregate was possible in rows following a row
where the RANGE specification resulted in an empty window. This has now
been fixed.

================(Build #3246 - Engineering Case #416729)================

When creating proxy tables using an ASAJDBC server class, some memory was
not released from the Java heap. This has been fixed.

================(Build #3245 - Engineering Case #417129)================

The Idle Timeout value was being ignored when the server was running on NetWare
or Unix systems, other than 32-bit Linux. This would have caused idle connections
to stay connected indefinitely. This has been fixed.

================(Build #3245 - Engineering Case #415862)================

It was possible for a small amount of cache memory to not have been freed
if the Java VM's garbage collector ran for a request that used the VM, and
that request has been cancelled. This has now been fixed.

================(Build #3243 - Engineering Case #415863)================

The server may have crashed while running the Java Virtual Machine's garbage
collector, if multiple connections run the garbage collector at the same
time. This problem was more likly to have occurred on Unix systems and multi-cpu
machines. This problem has been fixed.

================(Build #3241 - Engineering Case #416428)================

When using a secure (i.e. https) web services client function, if the https
connection to the remote host failed, the error message said simply "The
secure connection to the remote host failed". This same error message would
also have been returned if the certificate file could not be found or was
corrupt. The error message now contains more information as to why the connection
failed (eg. certificate file not found, certificate expired, server closed
connection, handshake failed, etc.) library to the error message.

================(Build #3239 - Engineering Case #409861)================

The server could have failed with the error - "Assertion failed : 101412
Page Number on page does not match the page requested" or possibly crashed.
This has been fixed.

================(Build #3236 - Engineering Case #415979)================

When the server was using a database file that was located on another machine
via Windows file sharing, or was located on the local machine but referenced
using a UNC name (such as \\mymachine\myshare\mydb.db), it could have failed
with one of the following errors (and possibly other assertion failures and
fatal errors, including OS error 58):
I/O Fatal error: Unknown device error
Assertion failed: 201125 Read Error with OS error code: 64

The problem only occurs on certain machines with certain patches and/or
hardware and/or drivers, the specifics of which have not been completely
identified. The problem is related to scattered reads (aka "group reads")
-- see the documentation to determine when the server may use scattered reads.
The server now works around this OS problem by disabling scattered reads
for files accessed by remote file sharing, or by UNC reference.

================(Build #3236 - Engineering Case #415756)================

If the server was running a database without a transaction log, and a request
was cancelled (or closed by the client) during a commit, the server could
have started running at 100% CPU usage. If this happened, the server would
also have hung on shutdown. This could also have happened when running with
a transaction log, if a CREATE DBSPACE, ALTER DBSPACE or DROP DBSPACE was
cancelled. This has now been fixed.

================(Build #3235 - Engineering Case #415893)================

On UNIX platforms, locale names ending with ".utf8", with the exception of
ko_KR.utf8, mk_MK.utf8, se_NO.utf8, tr_TR.utf8 and univ.utf8, were not being
correctly recognized as UTF-8 locales and were instead treated as ISO8859-1
locales. Locale names that instead ended with ".UTF-8" were recognized correctly.
This has been fixed.

================(Build #3235 - Engineering Case #415776)================

On UNIX platforms, if the locale (environment variables LC_ALL, LC_MESSAGES,
LC_TYPE, or LANG) was set to something invalid or unrecognized, the server,
or one of the client tools, may have crashed on startup. In particular, all
locale names ending with ".UTF-8" and all locale names ending with ".utf8"
except for ko_KR.utf8, mk_MK.utf8, se_NO.utf8, tr_TR.utf8 and univ.utf8 were
affected. This has now been fixed.

================(Build #3231 - Engineering Case #415161)================

Attempting to start the server on NetWare 6.5 with Service Pack 3 installed
would have caused the message "In LibC, NXSemaInit reports attempt to reinitialize
lock from DBSRV9.NLM" to be displayed, and then the server would have hung.
This has been fixed. Note that other versions of NetWare are not affected.
NetWare 6.5 with SP 4 installed does not experience the problem.

================(Build #3229 - Engineering Case #414939)================

It was possible, although very unlikely, for the server to crash if cache
warming was enabled. This has now been fixed.

================(Build #3229 - Engineering Case #409599)================

When starting a database with a writefile that required recovering, the server
could have crashed or failed with the error "Assertion failed: 102300 File
associated with given page id is invalid or not open". This has now been
fixed.
Note, the database is not corrupt and will recover correctly when started
with a server with this fix.

================(Build #3226 - Engineering Case #414454)================

Attempting to create and populate a table using SELECT ... INTO could have
failed if the table owner of the new table was different than the current
user. The table would have been created but not populated, and a "table not
found" error would habe been returned. This has been fixed.

================(Build #3226 - Engineering Case #407565)================

When run on some Windows CE devices, after the server had grown a file, the
OS would start to ignore the FILE_FLAG_WRITE_THROUGH flag, as well as the
FlushFileBuffers() call. On Windows CE, the server uses FlushFileBuffers()
to guarantee IO ordering for recoverability. In an attempt to work around
this problem, the server has been changed to close and reopen files after
the first call to FlushFileBuffers() after a file grows. It is not known
exactly which versions of Windows CE contain this problem.

================(Build #3225 - Engineering Case #415859)================

The server may have crashed while running the Java VM Garbage Collector.
The crash would have occurred if some time before a very long array or string
was allocated and during the allocation of pieces of that array or string
the Garbage Collect ran more than once. This has been fixed.

================(Build #3225 - Engineering Case #409772)================

The server may have crashed when executing a query with a subselect, if the
subselect caused an error when describing the result set. This has been fixed.

================(Build #3223 - Engineering Case #409773)================

If an error occurred while executing a subquery, then there is a chance that
the server would have left heap unfreed. This has now been fixed.

================(Build #3222 - Engineering Case #408655)================

Executing a very large query could have caused the server to crash. This
has been fixed.

================(Build #3220 - Engineering Case #409283)================

If an SMTP email was sent using the xp_sendmail procedure, and the engine
received a socket timeout error for a socket receive, the next xp_sendmail
or xp_stopsmtp call would have caused the server to crash. This has been
fixed.

================(Build #3219 - Engineering Case #409006)================

The server could have deadlocked at the end of an on-line backup if at least
two other concurrent transactions performed various unsafe actions. This
has been fixed.

================(Build #3219 - Engineering Case #408381)================

If an outstanding external procedure or function was cancelled, and a new
external call was issued shortly after the cancelled external call returned
back to the server, the newly issued call could potentially have returned
immediately, without executing. This has now been fixed.

================(Build #3219 - Engineering Case #402416)================

The performance of a Java stored procedure may have degraded the longer it
ran. This would occur if a JDBC Statement object that remained open for a
long time caused muliple warnings. Eventually, the buildup of SQLWarning
objects would have exhusted the Java heap, causing the Java garbage collector
to run continuously. These SQLWarning objects would have been garbage collected
when the JDBC Statement was closed, or when the clearWarnings function was
called by the Java procedure. This problem has been fixed by clearing the
Statement's SQLWarning objects whenever the Statement's associated ResultSet
is closed.

Note that the default heap size may be to small for some applications, but
can be increase with the Java_heap_size database option.

================(Build #3217 - Engineering Case #408512)================

It was possible, although very unlikely, for the server to crash if an undocumented
system procedure was called directly. This has been fixed.

================(Build #3217 - Engineering Case #402417)================

A memory leak in the Java VM would have caused poor performance of a Java
stored procedure if it was called hundreds of times. The cause of the performance
drop was exhaustion of the Java heap, forcing the Java garbage collector
to run continuously. This has been fixed.

Note that the default heap size may be to small for some applications, but
can be increase with the Java_heap_size database option.

================(Build #3216 - Engineering Case #408506)================

For CREATE VIEW and CREATE GLOBAL TEMPORARY TABLE statements, if the name
of the object being created included a server or database name, but no user
name, the statement recorded in the transaction log would have been invalid
and could prevent recovery using the log. This has been fixed.

================(Build #3216 - Engineering Case #408064)================

Starting the server on a database created by a previous version, (ie. versions
8.0.x and earlier) could have left the database in an unrecoverable state
for varying intervals of time between checkpoints. This time interval was
large on Windows 95, 98 or ME, and other Windows platforms where the server
was started using the undocumented command line option -hx. Otherwise the
interval of time was extremely short or non-existent.

================(Build #3214 - Engineering Case #408483)================

If a query had a predicate of the from "DT.X = expr", where "DT.X" was a
column in a derived table, the predicate "DT.X IS NOT NULL" is now generated
as a rewrite optimization. This generated predicate may then be used by other
rewrite optimization algorithms to eliminate OUTER JOINs, redundant or conflicting
predicates, etc. This could lead to vastly improved query performance.

================(Build #3214 - Engineering Case #408481)================

Subqueries with an EXISTS condition are no longer flattened if the subquery
contains more than two tables in the FROM clause, and it is not known if
the subquery returns at most one row. This can lead to improved performance,
as subquery optimization can now be done. The main issue with flattening
subqueries with more than one table in the FROM clause is that a Distinct
on rowids is always needed for the plan of the main query block. Previously,
when flattening was done as the query was parsed, the optimizer could not
choose any other plan but one with a Distinct.

================(Build #3214 - Engineering Case #408062)================

If a query referencing a proxy table was to be executed in "No passthru"
mode and the proxy table contained a varchar column, then any trailing blanks
in the varchar column would have been incorrectly stripped. This problem
has been fixed.

================(Build #3212 - Engineering Case #409230)================

A performance degradation may have been observed when executing queries with
proxy tables to an ASE Remote Server with the JDBC based server class 'asejdbc'.
This was due to a memory leak in the Java heap that could lead to heap exhaustion
and cause the Java garbage collector to run continuously. This problem has
been fixed.

================(Build #3212 - Engineering Case #408097)================

On Unix systems, calling the ODBC function SQLDataSources() would have caused
the server to crash with a SegFault, if no Driver Manager was being used.
This has been fixed.

================(Build #3211 - Engineering Case #400769)================

The server would have reported the following error to the server log when
attempting to register with LDAP if the LDAP server was an Active Directory
server:

Attempting to register server with LDAP
LDAP Error Referral (v2) received from ldap_search_s (LDAP server error:
Referral: <LDAP URL>
LDAP registration failed

This has been fixed with the addition of the following new asaldap.ini file
parameters:

read_authdn - the read-only authentication domain name. The domain name
must specify an existing user object in the LDAP directory that has read
access to the basedn. is only required if the LDAP server requires a non-anonymous
binding before searching can be done. For example, this field will normally
be required if Active Directory is used as the LDAP server. If this field
is missing, the bind will be anonymous.

read_password - the password for authdn. This is only required on the client
if read_authdn is used.

Note that this fix required changes to both the server and the client libraries.
Thus applications using ODBC, embedded SQL and JDBC with the iAnywhere JDBC
driver are affected. If a server containing this fix registers with an Active
Directory server, applications without this fix will not be able to find
it.

================(Build #3209 - Engineering Case #407815)================

A query that has many constant strings and duplicate constant strings in
the GROUP BY clause may have crashed the server.

For example:
select <many constant strings>, 'foo' 'foo'
from employee
group by 'foo', 'foo'

This has been fixed.

================(Build #3209 - Engineering Case #407181)================

If the following conditions were all true, the server could have crashed
when the calling connection was dropped:
- a user-defined function was called from a procedure
- the function in turn called a procedure with an inout or output parameter
- the argument corresponding to the output parameter had a different datatype,
requiring a conversion to be done
This has been fixed. A workaround is to ensure the argument datatype matches
the type of the output parameter, or declare the parameter explicitly as
IN if it was not intended to be INOUT.

================(Build #3207 - Engineering Case #407296)================

Logging deadlocks by setting the option PUBLIC.log_deadlocks to ON, could
have logged incorrect information. If the command line option -zl "remember
last statement text" was used, the "what" sa_report_deadlocks column may
have been blank and there was a chance the server could crash. These problems
were more likely when the 10K deadlock log buffer limit was reached, calling
sa_report_deadlocks would report the lowest snapshotId greater than 1. This
has been fixed.

================(Build #3207 - Engineering Case #406995)================

It was possible for the estimated number of rows returned by a plan operator
to be misreported. This problem was likely to only affect plans containing
derived tables. This problem only affected the graphical plan display; it
did not affect query optimization or execution. The incorrect estimate would
have been easily detectable, as it would either have been a number with an
extremely large (positive or negative) exponent, or it would have been a
string of characters like "IND#-1". This has been fixed.

================(Build #3207 - Engineering Case #403163)================

Any use of an aggregate function with DISTINCT in a query, could have potentially
lead to a 'dynamic memory exhausted' error. This has been fixed.

================(Build #3206 - Engineering Case #406765)================

Database recovery could have failed with assertion 201501 "Page for requested
record not a table page or record not present on page". The problem would
only have occurred in the event of the database server not shutting down
cleanly while dbremote replication was taking place. It would also have been
required that another connection revoked CONNECT or REMOTE from the remote
user for which the transactions were being replicated. This has been fixed
so that connections attempting to revoke permissions from the user for which
replication is currently occurring will now receive an error indicating that
the operation is "Not allowed while user 'user_name' is actively replicating
transactions". The connection attempting to REVOKE permissions will need
to wait until replication completes (commit/rollback) before being able to
revoke the permissions.

================(Build #3206 - Engineering Case #406753)================

If the server could not allocate the database cache, the server would likely
crash at startup. For example, starting a server with "-c 4800m" would have
caused the server to crash. This has been fixed.

================(Build #3205 - Engineering Case #406857)================

If a query like "SELECT TOP 5 * FROM T" was executed without an ORDER BY
clause, the server would normally return a warning stating that "the result
returned is non-deterministic." For Open Client applications, this warning
is now nonger returned.

================(Build #3204 - Engineering Case #406745)================

Executing DDL statements with incorrectly formed object names would have
made the transaction log unrecoverable.
For example, if a statement such as:
ALTER TABLE DBA..T ADD c2 INT
was executed, the resulting transaction log would contain an invalid statement
and recovery using the log would fail. This has been fixed so that when a
statement such as the one above is executed, it will now result in a valid
statement being recorded in the transaction log.

================(Build #3204 - Engineering Case #406488)================

The server was incorrectly assessing NULL selectivity when used with a descending
index. When examining an index to determine selectivity, the server assumed
that NULLs were at the start of the index. In a descending index, they are
at the end. This assumption has been corrected.

================(Build #3202 - Engineering Case #406567)================

The server could have crashed while executing a stored procedure that was
called from another stored procedure. This has been fixed.

================(Build #3202 - Engineering Case #406432)================

During periods of heavy server load, or substantial cache pressure, the server
could have appeared to stop processing active requests. This was more likely
to occur during very heavy disk I/O, and when issuing DDL statements alongside
connections that had created, and were dropping, string variables which contained
long string values. Although these active requests appeared to hang, they
would eventually complete, taking an arbitrarily long time. This has been
fixed.

================(Build #3202 - Engineering Case #406421)================

If a checkpoint was initiated while a backup was in progress, the changes
made for Engineering Case 400911 would have prevented subsequent commits
from completing until the backup had finished. The server now allows requests
attempting to suspend checkpoints to progress if there is a transaction already
suspending checkpoints as a result of a backup or other such operation.

================(Build #3200 - Engineering Case #406030)================

The server could have crashed when referencing a variable declared as a VARBINARY
of unspecified length. This has been fixed.

================(Build #3200 - Engineering Case #406017)================

Use of TOP n START AT m could have caused a server crash when used later
in a query plan, following certain operators. These operators include all
of the hash operators, the window operator, and the sortmerge operator.
This has been fixed.

================(Build #3200 - Engineering Case #405631)================

If a transaction spanned more than two transaction logs, and these logs were
applied to a copy of the original database, an error "<log_file> is an invalid
transaction log" could result. This has been fixed. The original transaction
logs and database are valid; however, the database produced by applying the
logs using a server without this fix may be missing transactions.

================(Build #3199 - Engineering Case #405887)================

The server could have generated inaccurate selectivity estimates for predicates
involving comparisons on a NUMERIC column when the value being used for comparison
had a different scale than that of the column. This problem has been resolved.

================(Build #3199 - Engineering Case #405516)================

The server could have crashed, or failed an assertion, when doing a REORGANIZE
TABLE on the tables rows. A work around is to lock the table exclusively
WITH HOLD before doing the reorganize.

================(Build #3199 - Engineering Case #405397)================

When run on Windows CE devices, the server was not have recognising the registry
setting to change the location of the temporary folder. This has been fixed,
so that temporary files may now be moved to a storage card.

================(Build #3196 - Engineering Case #404767)================

If an INSERT...SELECT was executed, such that the table being inserted into
was in a publication and the table being selected from was a proxy table,
then it was possible that the statement would have failed with unnexpected
errors. The most likely error was a "conversion error", but any number of
errors could have been returned. The problem has now been fixed.

================(Build #3194 - Engineering Case #393093)================

If executing an SQL Remote PASSTHROUGH statement caused a trigger to fire,
the statement would not have been send to the remote server. The problem
did not occur for PASSTHROUGH ONLY statements, since the statement did not
execute locally, no triggers were fired. This has been fixed.

================(Build #3192 - Engineering Case #404251)================

If the execution of a BACKUP statement failed, the next time the database
did a checkpoint the server would have failed with the following error:

Assertion failed: 108001 (9.0.2.3182) Attempting checkpoint while backup
active

A flag indicating that a backup was in progress was not being reset if the
backup failed. This has been corrected.

================(Build #3191 - Engineering Case #404188)================

Calling the function connection_property( 'UncommitOps', conn_num ) could
have returned a value greater than 4 billion if conn_num referred to an internal
connection of a database which was currently being started. This has been
fixed so that 0 is now reported in this case.

Note, the value greater than 4 billion could have caused an out of range
error if used with the procedure sa_conn_info.

================(Build #3191 - Engineering Case #404179)================

Cancelling a "Start Database" statement could have crashed the server. This
has been fixed.

================(Build #3191 - Engineering Case #404130)================

It was possible that the sa_get_request_times() procedure could not have
read request logs generated in certain locales. The satmp_request_time table
would have been empty. The request logs were generated with date/time values
that were in a locale-specific format, whereas the sa_get_request_times()
procedure was expecting a specific format. The date/time string will now
be output in the same format (mm/dd hh:nn:ss.iii) regardless of the locale
setting.

================(Build #3191 - Engineering Case #394297)================

Attempting to execute a statement like INSERT INTO v SELECT ..., where v
is a view on a proxy table, would have caused the server to crash. The problem
has now been fixed.

================(Build #3190 - Engineering Case #404151)================

Calling a procedure owned by another user with the result of a function owned
by a third user would have resulted in a 'permission denied' error. This
has now been fixed.

For example, the following this sequence would have generated the 'permission
denied' error:

create procedure userA.hello( in name char(10) )
begin
message 'Hello ' || name;
end;
grant execute on userA.hello to userC;

create function userB.world()
returns char(10)
begin
select 'world';
end;
grant execute on userB.world to userC;

create procedure userC.say_hello( )
begin
call userA.hello( userB.world() );
end;
call userC.say_hello();

================(Build #3190 - Engineering Case #403145)================

If a server was heavily loaded while the Index Consultant was doing a workload
capture, and was also checkpointing frequently, there was a small chance
that the srever could hang. Only threads working on the database being captured
would have been affected, other databases on the same server would remain
operational. This problem was more likely to occur on multi-processor systems.
This problem has now been fixed.

================(Build #3188 - Engineering Case #403624)================

If a user was granted SELECT permission on a view that referenced a proxy
table, but did not have SELECT permission on the proxy table, then using
the view in a subquery would have failed with a permission denied error.
This has been fixed.

================(Build #3188 - Engineering Case #403151)================

The database server could have crashed when connecting to the utility_db
from an ODBC application. This would only have occurred if the ODBC driver
was a newer version than the server. This has been fixed.

================(Build #3188 - Engineering Case #402431)================

The changes for Engineering Case 394506 introduced a bug that could have
caused a database file to become corrupted. The problem has been corrected

================(Build #3185 - Engineering Case #403353)================

If a system table was used in a procedure consisting of a single select statement,
and was not qualified with the owner, the server would have given an error
when the procedure was called in the FROM clause of a query. A workaround
is to qualify the table name. This has been fixed.

================(Build #3184 - Engineering Case #403355)================

Executing a REORGANIZE TABLE statement without the PRIMARY KEY, FOREIGN KEY
or INDEX clauses could have caused the server to become deadlocked and appear
to hang. This problem has now been fixed.

================(Build #3184 - Engineering Case #403199)================

Executing an ALTER VIEW statement with the SET HIDDEN clause, could have
caused the server to crash when given the name of an existing base table.
This has been corrected so the the server now generates an error.

================(Build #3183 - Engineering Case #402727)================

Issuing a START DATABASE request for a database with a mismatched transaction
log could have failed with the error message "Cannot open transaction log:
'???' belongs to a different database". The error message now correctly
specifies the transaction log file name in place of the string '???'.

================(Build #3181 - Engineering Case #402669)================

If a procedure call in the FROM clause returned fewer columns than indicated
in the result clause, or the catalog, and the last column returned was not
used by the query, the server would have crashed rather than give an error.
This has been fixed.

================(Build #3180 - Engineering Case #401614)================

The database file could have become corrupted when performing an ALTER TABLE
statement. The corruption may not have been immediately detected by database
validation. This has been fixed. A database corrupted in this manner can
perhaps be rebuilt by unloading the database with data 'ordered'.

================(Build #3180 - Engineering Case #400091)================

When a multi-byte character string was truncated in the middle of a character
by being but into a column that was not wide enough to for the whole string,
subseqent selects would have return a NULL at the end of the data. This could
have caused MobiLink synchronizations to fail, as the NULL was misinterpreted.
This has been fixed by truncating the string at the last full character.

================(Build #3178 - Engineering Case #402038)================

Executing an INSERT statement that specified a very long list of columns
(approx 1/4 of the database page size in bytes), could have caused a server
crash. This problem has been resolved. A temporary (inefficient) work around
would be to start the server with a larger cache page size.

================(Build #3178 - Engineering Case #401645)================

The server gathers and updates column statistics as part of the query execution
process. In the case of NOT predicates, the server could have incorrectly
changed the stored selectivity of these predicates to 100%. This problem
has been resolved.

================(Build #3175 - Engineering Case #401610)================

When a SOAP client toolkit requests a WSDL from the ASA server, the WSDL
targetNamespace would always have specified 'localhost', rather than the
machine name within the URL. This has been fixed so that the hostname is
now derived from the HOST header of the HTTP request. The HOST header field
is mandatory in HTTP 1.1.

================(Build #3175 - Engineering Case #401337)================

The base64_encode() function was embedding a linefeed character into the
result every 76 characters. This has been fixed.

================(Build #3174 - Engineering Case #401036)================

The system procedure sa_make_object() can now be called by any user having
RESOURCE authority. It no longer requires DBA authority.

================(Build #3174 - Engineering Case #400924)================

Setting the system clock back to an earlier time (either manually or by a
system daemon) on non Windows platforms (i.e. NetWare, Unix) could have caused
any of the following symtoms:
- timestamps reported in the request level log could jump ahead approximately
25 days
- client applications could be incorrectly disconnected

This has been fixed.

================(Build #3174 - Engineering Case #399488)================

Multiple errors were defined with SQLSTATE 28000. As a result, an incorrect
error message could have been returned. This has been corrected with the
following changes:

SQLSTATE_PARM_TOO_LONG changed from 28000 to 53W06
SQLSTATE_PASSWORD_TOO_SHORT changed from 28000 to 54W07
SQLSTATE_PASSWORD_TOO_LONG changed from 28000 to 54W08
SQLSTATE_INVALID_LOGON and SQLSTATE_INVALID_PASSWORD continue to return
28000

================(Build #3173 - Engineering Case #400165)================

Parameters for user-defined functions must be declared as IN. If a parameter
was declared as OUT or INOUT, the server would not have given an error until
the function was called. Now a syntax error will be given when the function
is created.

================(Build #3172 - Engineering Case #400799)================

Results from the Inttohex() function for bigint and numeric types were formatted
inconsistently.

The following are the results for bigint, integer and numeric values:

'00000001' '00000001' '00000001'
'ffffffffffffffff' 'ffffffff' 'ffffffffffffffff'
'00000002' '00000002' '00000002'
'fffffffffffffffe' 'fffffffe' 'fffffffffffffffe'
'7fffffff' '7fffffff' '7fffffff'
'ffffffff80000001' '80000001' 'ffffffff80000001'
'ffffffff80000000' '80000000' 'ffffffff80000000'
'80000000' '00008000' '80000000'
'7fffffffffffffff' '00007fff' '7fffffffffffffff'
'8000000000000001' 'ffff8000' '8000000000000001'
'8000000000000000' 'ffff7fff' '8000000000000000'

This problem has been fixed. The following shows typical results now returned
for bigint, integer and numeric values:

'0000000000000001' '00000001' '0000000000000001'
'ffffffffffffffff' 'ffffffff' 'ffffffffffffffff'
'0000000000000002' '00000002' '0000000000000002'
'fffffffffffffffe' 'fffffffe' 'fffffffffffffffe'

As well, with 9.0.2, passing a negative value to inttohex() would have resulted
result in a "value out of range" error. This to has been corrected

================(Build #3172 - Engineering Case #400670)================

When trying to create functions or procedures using Transact-SQL, use of
the "expr AS name" syntax in the arguments to the procedure or function call
would have failed with an error. This has been fixed.

A workaround is to write the function or procedure in using Watcom-SQL

================(Build #3172 - Engineering Case #398635)================

If a query referencing proxy tables that contained an ORDER BY clause within
the LIST() function was executed in Full Passthru mode, it would have failed
with the error "Feature 'olap extension' not implemented." This problem has
now been corrected.

================(Build #3170 - Engineering Case #400590)================

When an out-of-range hexadecimal value like 0xffffffff01000000 was passed
to the hextoint() function, no error was returned. Instead an incorrect integer
value was returned. This has been fixed so that out-of-range hexadecimal
values now return an error.

================(Build #3170 - Engineering Case #400467)================

Additional changes have been made to ensure that proper metadata is provided
for newer versions of jConnect. If a new version of jConnect is to be used,
then it is recommended that the new version of JCATALOG.SQL is run against
the database.

================(Build #3169 - Engineering Case #400911)================

A server experiencing a high rate of commits could have prevented checkpoints
from occurring. This has been fixed to provide fair access for checkpoints
in the presence of operations that suspend checkpoints, such as commits.

================(Build #3169 - Engineering Case #400331)================

The use of the ON EXISTING clause of the INSERT statement requires that the
referenced table have a primary key. The server would have generated a "syntax
error" in the event the table had no primary key defined. This has now been
changed so that the server will generate a "table has no primary key" (sqlcode:
SQLE_NO_PRIMARY_KEY) error instead.

================(Build #3167 - Engineering Case #400056)================

In rare circumstances, strongly encrypted connections to the database server
may have failed unexpectedly. Specifically, HTTPS connections may have returned
status 501 (Method not implemented), and ecc/rsa connections may have returned
handshake errors. This has been fixed.

================(Build #3165 - Engineering Case #399751)================

The character set names 'windows-936', 'gbk', 'cp936', and 'ms936' (all of
which refer to the same character set, gb18030), were ignored when requested
by an HTTP application. The mapping from character set name to Unicode ID
has been corrected.

================(Build #3162 - Engineering Case #399155)================

The server would have crashed under the following conditions:
- A BEGIN END block contained a nested BEGIN END block
- Inside the nesting block a local temporary table was declared (e.g. using
execute immediate)
- The outer block declared a cursor on the temporary table and was opened
inside the nested block but not closed in the nested block
- The cursor used an index on the temporary table
This has been fixed.

================(Build #3162 - Engineering Case #398122)================

While initializing the in-memory free list on start up, the server could
have run out of memory if the database was corrupt. The server will now generate
assertion 202100 - "Invalid bitmap page at page (page number)" when encountering
such corruption.

================(Build #3160 - Engineering Case #398964)================

On Linux Itanium, client applications could not connect to a server if the
server was restarted after a crash. This has been fixed. The work-around
is to shutdown the server and restart it again.

================(Build #3160 - Engineering Case #398604)================

It was possible for the server to loop infinitely while going through automatic
database recovery if the database file was corrupted. This could have occurred
when deleting an entry from a corrupted index. "Assertion 200901: Corrupted
page link found on page (0x%x) while deleting from index %s" will now be
generated for this situation.

================(Build #3158 - Engineering Case #397772)================

If a LOAD TABLE command failed, for example with a primary key violation,
then it was possible that the server would leak table pages and index pages
in the database. These leaked pages would not have belonged to any database
object and would also not have been marked as free. As a result, the database
file could have been larger than necessary. The only way to recover the
lost space is to rebuild the database.

================(Build #3157 - Engineering Case #398631)================

Queries with an ORDER BY clause and OUTER JOINs may have returned rows in
an incorrect order. This has been fixed.

The following conditions must have been met:
(1) there was at least one equality predicate between two expressions used
in the ORDER BY clause
(2) the equality predicate appears in an ON condition of an outer join
(3) the expressions were both from the preserved side of the outer join

Example:
select T.* from
T left outer join R on T.e1 = T.e2 and T.e2 = T.e3 and R.e1 = 10
where T.e1 = T.e2
order by T.e1, T.e3, T.e2

================(Build #3157 - Engineering Case #398294)================

Any user connected to the server was able to execute the REMOTE RESET statement.
This has been fixed, the user must now have DBA authority.

================(Build #3157 - Engineering Case #398293)================

When run on Unix, NetWare, or Windows CE systems, connection attempts could
have caused the server to crash if request-level logging was on. This has
been fixed.

================(Build #3157 - Engineering Case #398132)================

If a backup of the database was being performed and the transaction log was
either being renamed or truncated, if the database engine was unable to open
a new transaction log (or mirror log), an error would have been returned
to the backup process, but the server could have continued to apply operations
without logging them to the transaction log. The server will now faile an
assertion when it cannot open a new transaction log or mirror after the truncation
or rename, as this should be a fatal error.

================(Build #3157 - Engineering Case #397352)================

Executing a COMMENT TO PRESERVE FORMAT statement may have caused a server
hang. With a database page size is 2 KB this would have occurred if the
COMMENT statement was exactly 1960 characters in length. This problem would
have occurred for other pages sizes as well, if the exact length of the COMMENT
statement matched corresponding values. This problem has been fixed.

================(Build #3154 - Engineering Case #397635)================

The server could have crashed while executing a stored procedure, if it was
executed often enough to enable caching. This has been fixed.

================(Build #3153 - Engineering Case #396584)================

If a query referenced a proxy table and contained an ORDER BY clause, and
an ON condition in the FROM clause, it may have returned incorrect results
or an error. This has been fixed.

================(Build #3151 - Engineering Case #397134)================

A query that referenced proxy tables and contained a row limitation in the
SELECT clause (ie. FIRST n or TOP n) may have incorrectly returned the warning
"The result returned is n
non-deterministic.", even if the query had an ORDER BY clause. This has
been fixed.

Note, this will not have happened if the complete query was forwarded to
the remote
server, (ie. Full Pass-thru mode).

================(Build #3151 - Engineering Case #397058)================

If a DELETE statement involved a join, the server would have placed long-term
read locks on the unmodified tables, even if the DELETE statement was executing
as isolation level 0. This has been corrected, the server now locks rows
of the unmodified table according to the isolation level of the connection.

As an example, consider a local temporary table DELTEST that contains a
single column, X. The statement

DELETE
FROM DELTEST
FROM DELTEST JOIN PRODUCT ON (DELTEST.X = PRODUCT.ID)

would cause the server to place long-term read locks on the product rows
that successfully joined with the DELTEST table.

Note that this unnecessary locking occurs only with DELETE statements. INSERT
and UPDATE statements are unaffected by this error.

================(Build #3150 - Engineering Case #397047)================

Windows uses a two-character combination to indicate an end-of-line (\r\n).
In the request level log, these characters are replaced with spaces, so that
multi-line statements only take a single line of the file. Newlines at the
end of each line are preserved. As of build 3111, the extra newline character
used on Windows platforms was no longer preserved. This resulted in an extra
space appearing at the end of every line in most Windows editors. Very basic
text editors (such as Notepad) would have failed to detect the end-of-line
and would display the entire log as a single line. This has been fixed.

Note, his did not affect the processing of the Request-level log by the
builtin procedures (ie. sa_get_request_times, sa_get_request_profile, etc.).

================(Build #3148 - Engineering Case #396813)================

Changes for Engineering Case 395908 introduced a bug such that long binary
and long varchar columns were truncated for Open Client and jConnect applications.
This problem has been fixed.

================(Build #3147 - Engineering Case #396571)================

Calling the OPENXML() function with an xpath expression that was NULL, would
have caused the server to crash. This has been fixed. Note, this did not
happen to xpath expressions in the WITH clause.

================(Build #3146 - Engineering Case #396058)================

Inserting a string longer than 64K bytes into a column of a proxy table,
would have caused the local server to crash. This has been fixed.

================(Build #3145 - Engineering Case #397387)================

All ANY and ALL predicates are now rewritten to an EXISTS predicate, if it
is semantically correct to preform such a rewrite optimization. With this
rewrite optimization, a performance benefit may be observed for some queries.

================(Build #3145 - Engineering Case #396464)================

After having established an HTTPS connection, the server may have lost data
when receiving a large request. Data loss may have been experienced intermittently
when requests were in the range of 10K bytes or greater. Data loss may have
occurred either receiving POST or GET requests. This has been fixed.

================(Build #3145 - Engineering Case #395908)================

If an Open Client or jConnect application described a column that was of
type Varchar(n) or Varbinary(n), the size reported for the column would have
been 32768 instead of n, if n was greater than 255. This problem has now
been fixed.

================(Build #3144 - Engineering Case #395054)================

If the database option Wait_for_commit was set to ON while executing a LOAD
TABLE statement, and it failed with a referential integrity error, then the
database could have been left in an inconsistent or corrupt state. This has
been fixed.

Some of the errors that might be characteristic of this problem are:
- Assertion 200602 - Incorrect page count after deleting pages from table
'table_name' in database 'database_name' - could occur during TRUNCATE TABLE
or DROP TABLE.
- Database validation could report that an index has inaccurate leaf page
count statistics.
- Database validation could report that a foreign key is invalid and that
some primary key values are missing.
- Database validation could report that the rowcount in SYSTABLE is incorrect.
- Inconsistent row counts might be observed when querying the table sequentially
versus via an index.

================(Build #3142 - Engineering Case #393745)================

When running the reload.sql generated by the Unload utility, executing LOAD
STATISTICS statements may have failed. This would have occurred if the column
was of type binary or long binary, and the source database and the target
database had different collations
(e.g. one had a single byte collation and the other one a multi-byte
collation).
This has been fixed so that now the statistics of binary columns are only
loaded if both databases have the same collation.

================(Build #3142 - Engineering Case #381011)================

A selectivity estimates of 0% may have incorrectly been computed for non-equality
predicates on small tables (e.g., 1 or 2 rows). This has been fixed.

================(Build #3142 - Engineering Case #374308)================

Extremely complex queries with many equality predicates, for which the optimizer
underestimated the number of rows in the result set due to highly correlated
predicates, may have had inefficient query plans. This fix introduces a new
approach for dealing with such queries. Now, the optimizer evaluates for
very complex and cheap queries, some static qualities of the enumerated plans
that are not dependent on cost, or number of rows.

================(Build #3140 - Engineering Case #427299)================

The idle IO timer could have firing before the server was fully initialized,
which would have caused the server to crash. This has been fixed by checking
that the server has completed it's startup before dispatching the timer.

================(Build #3140 - Engineering Case #394668)================

The ON EXISTING UPDATE clause of the INSERT statement can be used to update
rows that already exist in the database. By default, columns with default
values in existing rows should be left unmodified unless their values are
explicitly changed by the INSERT statement. Under some circumstances, the
server could have modified these columns incorrectly. This problem has been
resolved.

As a simplified example consider the following:

drop table a;

CREATE TABLE a (
a1 INTEGER NOT NULL,
a2 INTEGER NOT NULL,
a3 INTEGER NOT NULL DEFAULT AUTOINCREMENT,
a4 INTEGER NOT NULL,
PRIMARY KEY ( a1, a2 ) );

INSERT INTO a VALUES( 1, 1, 1, 1);
INSERT INTO a VALUES( 2, 1, 2, 2);
commit;

INSERT a ON EXISTING UPDATE WITH AUTO NAME
SELECT 1 AS a1, 99 AS a2, 11 AS a4
union all
SELECT 2 AS a1, 1 AS a2, 88 AS a4;

The INSERT statement should

1. Insert a new rows into table a with PKEY <1,99>, and
2. Update the value of a.a4 to 88 in the row with PKEY <2,1>. The default
column a.a3 in this row should now remain unchanged.

================(Build #3139 - Engineering Case #442676)================

Processing large and complex queries may have caused the stack to overflow,
resulting in the server crashing. This has been fixed.

================(Build #3139 - Engineering Case #394558)================

A window function can not be referred to, either directly or indirectly,
in the WHERE clause of the block where the window is computed. However,
if a window function was used in a complex expression in the WHERE clause,
the server would have crashed rather than give error -964 as required. This
has been fixed.

================(Build #3139 - Engineering Case #393568)================

If the command line option -zl "remember last statement for each connection"
was used, and the database option Log_deadlocks was 'on', the server could
have crashed if a deadlock occurred. This has been fixed.

================(Build #3138 - Engineering Case #393746)================

If a space did not follow the method name in the EXTERNAL NAME clause of
the wrapper function to a Java method, calls to the function would have resulted
in a procedure not found error.

For example:
a wrapper function definition of
CREATE FUNCTION MyMeth (IN arg1 INT, IN arg2 varchar(255),IN arg3 INT )
RETURNS Int
EXTERNAL NAME 'TestClass.MyMethod(ILjava/lang/String;I)I'
LANGUAGE JAVA;

would have resulted in the error
Procedure 'TestClass.MyMethod(ILjava/lang/stringI)I' not found.

where as
EXTERNAL NAME 'TestClass.MyMethod (ILjava/lang/String;I)I'

would have worked. This has been fixed so that a space is no longer required
between the method name and the left parenthesis.

================(Build #3137 - Engineering Case #393923)================

If a procedure or function called a Java method, and the Java code used the
current connection to run a SQL statement that called a procedure or function
that also called a java method, the server would have crashed if the two
procedures or functions had a return statement.

================(Build #3135 - Engineering Case #393574)================

If a 'root' web service was created with URL ON or URL ELEMENTS, the service
would not have been selected to process a request when it should have been
selected. This has been fixed. The way that the server now determines which
service is to be used to process an HTTP[S] request is to do the following:
- if the request is for '/' then choose the 'root' service if it is defined
- first check for a service name for the entire URL
- interatively chop off one level from the URL at a time until a defined
service is found with URL ON|ELEMENTS setting.
- if no service is found using the above, then select the 'root' service
if it is defined with URL ON|ELEMENTS

For example:
If the request is for /a/b/c then the server will first look for a service
named 'a/b/c', then 'a/b', and finally 'a'. With this fix, the engine will
now also look for the 'root' service.
The latter three (a/b, a, and root) must all have been defined with URL
ON or URL elements in order to be chosen in this situation.

Note that by defining a root service with URL ON|ELEMENTS, this service
becomes a 'catch-all' service that will be used to process all requests (for
the selected database) that do not match any other defined service.

================(Build #3135 - Engineering Case #393434)================

On Windows platforms, when the Transaction Log, Log Translation or Backup
utilities are executed on a database with auditing enabled, a file called
"<db filename>.alg" is created or updated. A record is added containing the
date and time of execution, the Windows user name, and the name of the utility
executed. If this file already existed, but the new record could not be written
because the disk was full, the utility would have ignored the error and continued.
This has been fixed, now if the audit record cannot be created, the utility
fails. A message is also displayed to indicate that the audit record could
not be created.

================(Build #3135 - Engineering Case #393270)================

If a server was running with a ServerName longer than 32 bytes, attempts
to connect to it using SPX would have failed. This has now been fixed so
that only the first 32 bytes are relevant for SPX.

================(Build #3134 - Engineering Case #393022)================

If an expression contained a reference to a proxy table, the server would
have crashed if the expression was used:
- in a MESSAGE or PRINT statement
- in a RETURN statement of a function or procedure
- in a time/delay expression in a WAITFOR statement
- in an offset expression of a FETCH statement
This has been fixed so that the server now correctly returns the error "OMNI
cannot handle expressions involving remote tables inside stored procedures"

================(Build #3132 - Engineering Case #392668)================

If an application used the Remote Data Access feature to perform an INSERT
from SELECT in 'no passthru' mode, and the insert received an error, it was
possible for the server to have crashed. This problem has now been fixed.

================(Build #3132 - Engineering Case #392216)================

If a proxy table contained a column declared with DEFAULT AUTOINCREMENT,
and an insert into that table did not contain a value for that column, the
server may have crashed. For this to have happened, one of the column values
in the insert statement had to be an expression or function call that needed
to be evaluated. This has been fixed.

================(Build #3131 - Engineering Case #392502)================

If a Java application closed an SAConnection object, and then subsequently
called the 'isClosed' method on the same object, an exception would have
been thrown erroneously. This has been fixed.

================(Build #3131 - Engineering Case #392500)================

When the server was run on Unix systems, if the public.string_rtruncation
option was on when a database started and select length( property( 'CompactPlatformVer'
) ) was more than 40 characters, user options may not have been set correctly,
and other incorrect behaviour could have occurred. This has been corrected.

Windows platforms were not affected, since the length returned for 'CompactPlatformVer'
is much less than 40 characters.

================(Build #3129 - Engineering Case #392068)================

When backing up a database to multiple tapes, after the first tape had been
written, the request for the next tape would have failed. This problem has
been fixed.

================(Build #3129 - Engineering Case #392029)================

The server would have returned either -9 or a conversion error from the following
query, depending on the platform:

select hextoint('fffffffffffffff7');

This problem has been fixed. The server will now consistently return -9
for the result.

In furthering compatibility with Adaptive Server Enterprise, the following
examples now return errors, since they contain invalid hexadecimal characters.

select hextoint('ffffJackf7')

================(Build #3129 - Engineering Case #391751)================

Numerous changes have been made to the system procedures used by jConnect
when connected to ASA servers. Newly created databases will have these changes,
but to update existing databases run the script jcatalog.sql, which is in
the scripts directory.

================(Build #3127 - Engineering Case #391182)================

If the text of a stored procedure was made unreadable with the HIDDEN clause,
and it contained a call to itself with at least one parameter, then any call
to this procedure will have failed with the error "Wrong number of parameters
to function 'proc_name'". The error would have disappeared after restarting
the database or reloading the procedures due to the execution of a DDL statement.
This has now been fixed.

================(Build #3126 - Engineering Case #390765)================

If an Open Client dblib application attempted to fetch a tinyint value using
the dbdata() function, instead of dbbind(), then the application would always
get the value 0, instead of the actual tinyint value. Note that this problem
only occurred if the tinyint value was nullable. This problem has now been
fixed.

================(Build #3126 - Engineering Case #389570)================

Cardinality estimation for a partial index scan may have been incorrect if
selectivity estimations of the sargable predicates were set to 100%. This
has been fixed. The index must have been a foreign key, or an unique index.

================(Build #3124 - Engineering Case #390763)================

The number of rows returned as a result of a join of the form 'T1.primary
key = T2.primary key' may have been grossly underestimated during optimization.
Among the conditions that need to occur are the following:
1. The 'primary key' may have been a single column or a multi-column candidate
key
2. Table T1 must have been much smaller than table T2, and appeared before
T2 in the FROM clause.

This underestimate may have resulted in less than optimal plans being chosen
by the optimizer. This has now been fixed.

================(Build #3124 - Engineering Case #390761)================

The iAnywhere JDBC driver has now been enhanced to support the Organic ASE
ODBC driver. The JDBC driver now checks if the ODBC driver is the Organic
ASE ODBC driver and appropriately sets the default result set type and other
attributes.

================(Build #3124 - Engineering Case #390484)================

On the AIX, HP-UX, and Tru64 Unix platforms, if more than one database server
was run on a machine, the ServerPort TCPIP protocol option needed to be specified
on both the client and server in order to be able connect. This has been
fixed so that on these platforms the ServerPort option is no longer required
when multiple database servers are started on the same machine.

Note than on MacOS X, the ServerPort option must still be specified when
starting a network server, if a server is already running on the same machine.

================(Build #3124 - Engineering Case #390347)================

If a timestamp value is fetched using a TDS connection (ie. jConnect or Open
Client), the fractional seconds are only accurate to two digits of precision.
This is due to the TDS protocol representing fractional seconds as increments
of 1/300ths of a second. Since the server stores the fractional seconds as
microseconds, it is converted to a value which is a multiple of 1/300th of
a second. The converted value though was simply being truncated, rather than
rounded, which may have caused the value of a timestamp fetched via a TDS
connection to have been 1/300th of a second less than the value stored. This
has now been fixed, but it should be noted, that rounding does not work for
all values, but instead, will only work for timestamp values originally inserted
using a TDS connection. Since in these cases, the conversion to 1/300ths
of a second is first performed by jConnect or Open Client prior to sending
the value to the server.

================(Build #3124 - Engineering Case #390162)================

The server collects and maintains column statistics during UPDATE and DELETE
statements. In some situations, such as when a large DELETE statement was
rolled back, the column statistics could have progressively become incorrect.
In particular, the estimated selectivities could have kept increasing without
bound. The server now places an upper bound of 100% for each individual predicate
selectivity stored in the database in these situations.

================(Build #3124 - Engineering Case #390133)================

If only the second member of a UNION, INTERSECT, or EXCEPT query contained
multiple Transact-SQL variable assignments, then the server would have crashed.
This has been fixed. Now the engine will return a syntax error if any member
other than the first contains Transact-SQL variable assignments, or an "into <tablename>"
clause.

================(Build #3124 - Engineering Case #390063)================

Assert failures 200602 and 200603 indicate that when truncating a table,
a mismatch was detected between the number of pages in the table and the
counts recorded in the table's in-memory data structures. These assertions
would have brought down the server, even if the table concerned was a temporary
table. In the case of a temporary table, this likely does not warrant bringing
the server down. This behaviour has been changed so that now the assertion
text is written to the console log, and the server is allowed to continue
running. Also, the text of these assertions has been changed to indicate
the table in question.

================(Build #3124 - Engineering Case #390025)================

The server could have crashed while performing a string comparison using
the LIKE operator. This has been fixed

================(Build #3124 - Engineering Case #389970)================

On the AIX, HP-UX, and Tru64 Unix platforms, if more than one server was
run concurrently on the same machine, the ServerPort TCPIP protocol option
needed to be specified on both the client and server in order to be able
connect. This has been fixed so that on these platforms the ServerPort option
is no longer required when multiple database servers are started on one machine.

Note than on Mac OS X, the ServerPort option must still be specified when
starting a network server if a server is already running on the same machine.

================(Build #3124 - Engineering Case #389583)================

If a database with auditing enabled was loaded in read-only mode, the database
could have been used, but audit records would not have been created. This
has been fixed so that now databases with auditing enabled cannot be started
in read-only mode.

================(Build #3124 - Engineering Case #388906)================

When run on Linux platforms, the server could have crashed on shutdown if
a custom backup library was used to perform backups. This has been fixed.

================(Build #3124 - Engineering Case #387997)================

A database file may have grown, even when free pages existed in the dbspace,
if the free space was fragmented such that no 8-page cluster aligned on an
8-page boundary existed within the dbspace, and pages for a large table (one
with bitmaps) were being allocated. When growing a large table prior to this
change, the server always allocated table pages in clusters of eight pages
so that group-reads could be performed on a sequential scan. If no clusters
were found, the dbspace was grown to create one. Now, if no free cluster
is found, the server will attempt to allocate pages from a cluster that has
both free pages as well as pages allocated to the table that is being grown.
If no free pages are found by this method, the server will use any free page
in the dbspace. So now te dbspace will not grow until there are no free pages
left in the dbspace.

As a work-around, periodically running REORGANIZE TABLE on all tables will
generally avoid the problem

================(Build #3123 - Engineering Case #389796)================

When performing an UPDATE (or possibly a DELETE) using a keyset cursor, over
a table that was joined to itself (i.e. appears multiple times in the UPDATE
or FROM clause), the server could have failed to obtain write locks on rows
it modified. This could have resulted in lost updates, or a corrupted index,
if an update was made to an indexed column. This has been fixed.

================(Build #3123 - Engineering Case #389687)================

If the server was started with the -gn command line option (maximun number
of concurrent requests) set to a value greater than 255, the server may have
crashed when under a heavy I/O workload. This has now been fixed.

================(Build #3123 - Engineering Case #389590)================

If a server was started with the -o <file name> server command line option
(filename for copy of message window), then stopped and immediately started
again with the same -o <file name>, the server could fail to start with the
error "Invalid database server command line" or "Can't open Message window
log file: <file name>". This failure was rare and timing dependent. This
has been fixed so the second server will successfully start.

================(Build #3122 - Engineering Case #389598)================

If an Open Client application used unsigned datatypes in an Remote Procedure
Call, there was a good chance the application would hang. This problem has
now been fixed.

================(Build #3122 - Engineering Case #382839)================

When using the Microsoft SQL Server "Import and Export Data" tool to move
tables from a Microsoft SQL Server database to an ASA database, and the connection
to the ASA server used the OLEDB provider, column data was truncated to 200
bytes. This has now been fixed.

================(Build #3121 - Engineering Case #389447)================

If a database had a "Connect" event defined, attempting to rebuild the database
using the Unload utility with the Rebuild and Replace option (-ar) may have
failed with the error: "Too many connections to database being replaced".
Whether the error was reported or not depended on how long the event took
to execute. This has been fixed, this error will no longer be reported if
the only other connections are for event handlers.

================(Build #3120 - Engineering Case #390431)================

On all Unix platform except Solaris, the server may have incorrectly reported
the error "Unable to synchronize due to external event" in the event log,
and then crashed. This message indicates that a global System V semaphore
in use by the server was deleted by an external cause. In reality no such
cause existed and the real cause was due to an unrelated server crash. This
has been fixed and this error message will now only appear
if the semaphore was deleted.

================(Build #3120 - Engineering Case #389431)================

A query with an undefined column used inside a derived table or a view, may
have caused the server to crash. For this to have occurred, the derived table
or the view must have contained one of the UNION, EXCEPT, or INTERSECT operators.

For example:

CREATE VIEW VV1( X)
AS
SELECT A.id
FROM product A left outer join
(
SELECT ERROR FROM PRODUCT P1
UNION ALL
SELECT 1 FROM sales_order_items S1
) B
on 1=1;

The column 'ERROR" in the first query block of the derived table 'B' is
undefined, and the query 'select count(*) from VV1' will cause the server
to crash.

This is now fixed.

================(Build #3120 - Engineering Case #389230)================

While running multiple connections that fetched from different proxy tables,
and different remote servers using ASEJDBC, if one connection was killed
then the server's Java Virtual Machine can no longer be started. This has
now been fixed.

================(Build #3120 - Engineering Case #389224)================

The "ALTER DATABASE CALIBRATE" statement can be used to re-calibrate the
server's I/O cost model for a specific database and hardware configuration.
The recomputed cost model is stored in the catalog table SYS.SYSOPTSTAT.
In some cases, the server was improperly reading the cost model when the
server was restarted. This has been resolved, but it was not likely to have
caused any major and/or visible problems.

================(Build #3120 - Engineering Case #389195)================

Due to a race condition in the server, requests over HTTPS connections may
have been given an error status, usually 501 (Method Not Implemented). This
has been fixed.

================(Build #3120 - Engineering Case #388852)================

If Interactive SQL's "commit after each statement" option was on, calling
some system stored procedures (e.g. sa_table_fragmentation) would have produced
an empty result set. This was due to some local temporary tables not specifying
a disposition on COMMIT, and so assumed ON COMMIT DELETE ROWS. This has been
fixed. Databases with this problem must be rebuilt, or upgraded, to correct
the stored procedures affected by this change. A workaround is to uncheck
the "commit after each statement" option.

================(Build #3120 - Engineering Case #388838)================

If a proxy table was created with a column that contained a DEFAULT clause,
then an insert into that table would have failed if the insert explicitly
specify the column, but with a different case for the column name. The returned
error would have been "Duplicate insert column". For example:

create table T1 ( col1 int default 10, col2 int ) at '....';
insert into T1 ( COL1, col2 ) values ( 1, 1 );

This has been fixed.

================(Build #3120 - Engineering Case #388498)================

The server automatically gathers and maintains column statistics as queries
are executed. If multiple connections concurrently updated column statistics
as a result of query execution, there was a potential for some column statistics
to become inaccurate. This problem has been resolved.

================(Build #3119 - Engineering Case #389452)================

Growing dbspaces could be much slower than would normally be expected, particularly
on Windows platforms, after the applying the changes for Engineering Case
361509. Now, when ALTER DBSPACE ADD ... is executed on Windows platforms,
and more than 4MB of space is being added, the server will attempt to allocate
a large (4MB) buffer to initialize the newly allocated portion of the file.
The buffer will only be allocated if there is at least 16MB of physical memory
free, as well as at least 16MB of address space available. The buffer will
be freed after the file growth has completed. If the database server is running
on Windows XP or later, on an account with the volume management privilege
(which is on by default for an administrator), the server will also take
advantage of new OS APIs to make file growth even faster.

In a simple test on a system with a single SCSI drive, adding 1GB to a dbspace
took only 22 seconds with this change, compared to over 5 minutes previously.

================(Build #3119 - Engineering Case #388752)================

If a column's COMPUTE clause contained a string constant, or a string constant
expression, the server would have crashed each time the compute expression
was evaluated. This has been fixed.

================(Build #3119 - Engineering Case #388488)================

The server could have failed with "fatal error: unknown device error" when
performing a query over a temp table. The query had to return blob values,
and make use of the SortTopN data flow operator. SortTopN most frequently
appears in plans for queries with an ORDER BY clause and a row limit (ie.
TOP n or FIRST).

For Example:

create procedure test()
result( val char(256) )
begin
declare local temporary table val_table(
val char(256) null );

insert into val_table values( repeat('a',256));
select * from val_table;
end;

select first val from test() order by val;

This problem has now been fixed.

================(Build #3119 - Engineering Case #388383)================

The ASA server automatically collects column statistics during query execution,
DML update statements, LOAD TABLE statement and index creation. The default
behaviour was to collect and update statistics under all situations. A new
database option Collect_statistics_on_dml_updates has been added, allowed
values ON (default) or OFF, which can be used to enable or disable collection
of statistics during DML update statements.

================(Build #3119 - Engineering Case #388338)================

The number of rows returned from a Nested Block Join (JNB) could have been
underreported in a Graphical Plan with Statistics. This was a display problem
only, and did not affect the actual execution of the query. It was also not
a problem in a Graphical Plans with estimates only. This has been fixed.

================(Build #3119 - Engineering Case #388142)================

The system functions encrypt() and decrypt() did not respect the -fips server
switch. This has been fixed, if the -fips switch is specified, then the algorithm
used for encrypt() and decrypt() will be 'aes_fips', otherwise 'aes' (or
no algorithm) is specified.

================(Build #3119 - Engineering Case #388141)================

If the FIPS option was selected during installation, FIPS encryption will
be available, but calling the system function property('IsFipsAvailable')
would have returned 'NO'. The server was checking for the existence of the
dll libsb.dll only in %WINDIR%. This has been fixed, the server now checks
in the usual places and then checks %WINDIR% if it can't find it. A workaround
is to copy the libsb.dll from %ASANY9%\win32 to %WINDIR%.

================(Build #3119 - Engineering Case #388072)================

The INPUT...PROMPT statement would never have stopped prompting for column
values when Interactive SQL was run in console mode. This problem did not
occur when run in windowed mode. This bug has been fixed.

================(Build #3119 - Engineering Case #388068)================

If a connection that had the Wait_for_commit option set to 'On', issued a
request which violated referential integrity, and the next commit was done
as a result of a SET OPTION statement that set a permanent option for a
different user, the server could have failed assertion 104301 "Attempt to
free a user descriptor with non-zero reference count", when the server was
stopped (e.g. by autostop option), or a subsequent connection revoked CONNECT
permission from the user the option was set for. This has been fixed.

================(Build #3119 - Engineering Case #386705)================

The optimizer will occasionally recommend indexes that degrade query performance.
When the Index Consultant detects this siyiation, it discards the query from
its analysis. A check for whether a query had been discarded or not was missing
from the new analysis viewer, which could cause the Index Consultant to report
a NullPointerException, making unviewable the list of affected queries for
a recommended index. This has been fixed.

================(Build #3117 - Engineering Case #387625)================

In some cases compressing a database that was using checksums with the Compression
utility, could have corrupted it. This has been fixed.

================(Build #3115 - Engineering Case #384959)================

Changes made for Engineering Case #363767 could have caused the database
file to grow unnecessarily. A page that was in use as of the last checkpoint
is allowed to be reused before the next checkpoint, provided its preimage
has been saved in the checkpoint log. Prior to the changes for case 363767,
the preimage for a freed page was forced to disk and the page was allowed
to be reused immediately. After the changes for case 363767, the freed page
was not allowed to be reused until after the next checkpoint, because the
server no longer forced the preimage to disk for performance reasons. If
an application freed and reused pages frequently (for example, repeatedly
deleting all rows from a table then inserting rows back into the table),
the server would not have allowed many of the free pages to be used until
after the next checkpoint. The problem has been fixed by keeping track of
the set of free pages that would normally be allowed to be reused if only
the preimages were committed to disk.

Note that this growth was not unbounded and was not a 'leak', as the pages
are freed as of the next checkpoint. This problem only affected databases
created with 8.0.0 or later.

================(Build #3114 - Engineering Case #387530)================

When run on 32-bit x86 Linux systems, the server could have reported an incorrect
value for property( 'NativeProcessorArchitecture' ). The value could randomly
have been any of 'X86', 'X86_64' or 'IA64'. This has now been corrected.

================(Build #3114 - Engineering Case #387522)================

It was possible for the server to crash when starting up more than one database,
or when servicing the first few requests after startup, if a checkpoint was
also occurring. This problem was timing dependent and likely very rare, but
was more likely on multiprocessor machines. This has now been fixed.

================(Build #3113 - Engineering Case #387397)================

Closing an HTTP connection to the server could have caused the server to
crash, or other existing or subsequent HTTP connections to fail. While rare,
this problem was slightly more likely on multi-processor machines. This problem
has now been fixed.

================(Build #3113 - Engineering Case #387276)================

Predicates with constant arguments can be evaluated at optimization time,
which allows them to be simplified, potentially giving a better estimate
of selectivity. For example, the following predicate would give an estimate
of 15% when not simplified, but an estimate of 0% when it is: "1 IN (2, 3,
4)". Now with this change, LIKE and IN predicates are simplified in this
way. In addition, BETWEEN predicates where the first argument is a constant
NULL value, are now simplified to UNKNOWN.

In addition to improving selectivity estimates, these simplifications may
allow the optimizer to discover sargable predicates that permit a cheaper
access pattern. For example, the query:

select *
from rowgenerator
where 1 in (2,3,4) or row_num = 2

would have used a sequential scan before this change, but now would use
a scan on the primary key.

In the above discussions, host variables and procedure variables are also
considered as "constants" for the purposes of simplifying predicates.

================(Build #3112 - Engineering Case #387224)================

If a query involved the ROLLUP or CUBE operator over more than 255 columns,
memory would have been corrupted, which could have lead to unexpected behaviour.
This was very unlikely to occur in practice, and an error would have been
returned for ROLLUPs or CUBEs on 65 to 255 columns. An error is now returned
for ROLLUP or CUBE operations over 64 columns.

================(Build #3112 - Engineering Case #387180)================

The server may have stopped with an 'out of memory' fatal error when it did
not need to do so. For this to have occurred, there must be very few reusable
pages left in the cache.
While this specfic problem has been fixed, the server may still fail later
on with an 'out of memory' error.

================(Build #3112 - Engineering Case #387156)================

Attempting to grant a large number of column permissions, (the actual number
depended on the cache page size), for one table/grantor/grantee combination,
would have caused assertion failure 101506 - "Allocation size too large when
re-allocating memory". This has now been fixed.

================(Build #3112 - Engineering Case #387061)================

The locked_heap_pages and main_heap_pages statistics were being reported
incorrectly if the performance monitor was left running during server restarts.
Further, these counters were not being reported as accurately as they could
have been. These problems have been corrected.

================(Build #3111 - Engineering Case #386918)================

When an error occurred in a subselect that was part of a procedural statement
(for example, SET, MESSAGE, IF/WHILE conditions, etc.), the server would
have failed to release part of the cache that was used by that subselect.
Subselects that are part of queries that return results sets, explicitly
opened cursors, insert...select, or select...into statements, are not affected.
This would not cause any immediate problems, however if a large number of
calls were made to such procedures, an increasing portion of the database
server cache would have become unavailable to the server for normal use.
This would then have caused the cache to grow larger than necessary, and
eventually, given enough such calls, have failed with a 'Dynamic Memory Exhausted'
error. This may also have shown up as steadily decreasing server performance.
This problem was more likely to appear if stored procedures were written
with exception handlers or ON EXCEPTION RESUME. This has now been fixed.
A workaround is to restart the server whenever performance drops below an
acceptable level, or at shorter intervals than the memory exhaustion error
is reported.

================(Build #3111 - Engineering Case #385641)================

If a trigger or procedure executed a conditional statement (e.g. an IF statement)
that used a subselect on a procedure, and the procedure call in the subselect
took at least one parameter, a server crash would have resulted. This has
been fixed.

================(Build #3110 - Engineering Case #386569)================

The index corruption caused as a result of Engineering Case 383145 could
not have been detected by database validation. Validation of an index with
this type of corruption will now generate an assertion failure, (such as
100305, 102300, or 201601). Dropping and recreating the index will solve
the problem.

================(Build #3109 - Engineering Case #383970)================

The database server would have erroneously reported a licensing violation
on hyperthreaded or multicore CPUs. A message such as the following would
have been displayed:

"Warning: The server is limited to use xxx processor(s), but it is executing
on yyy processor(s)."

The server was using the number of CPUs reported by the operating system,
and was not accounting for the fact that they may be hyperthreads (or, soon,
just one of multiple cores in a single physical processor). Also, the server
would only create enough threads of execution to match the CPU license limit;
however, on a hyperthreaded or multicore processor, the server should create
enough threads of execution to run on all hyperthreads and cores on all of
the physical processors for which the server is licensed.

The problem has been corrected as follows:
1. The server adjusts its affinity mask to restrict the server to
run on only the licensed number of physical processors
2. The server creates enough OS threads to be able to execute on all
cores & hyperthreads of all processors for which the server is licensed.

To address #2 above, the default number of OS threads (changeable with the
'-gx' switch) is now 1 plus the number of hyperthreads and cores on all licensed
processors. The previous default number of OS threads was the minimun of
the licensed number of cpus, or 1 plus the number CPUs as reported by the
OS.

The server now also correctly adjusts its affinity mask to restrict the
server to the licensed number of physical processors. If the server is licensed
for 'n' processors, the server will by default run on all hyperthreads and
cores of 'n' physical processors.

A new server command line option has been added ('-gtc') to control the
aximum "processor concurrency" that the server will allow. For example, by
default on a single-processor hyperthreaded system, or on any hyperthreaded
system with a server licensed for just 1 CPU, the server will by default
allow two threads to run concurrently on one physical processor. Adding a
'-gtc 1' switch, for example, allows the user to force the engine to run
on just one core of one processor.

The following will help to clarify the interaction of the switches that
control licensing and concurrency. The following symbols will be used so
that the values can be easily related to the server options that control
them:

gt : the number of physical processors to use
gtc : the maximum processor-level concurrency
gn : the number of concurrent server requests
gx : the number OS threads to create

The default value for gt is the minimum of the number of physical processors
licensed and the number of physical processors in the machine. The user cannot
set gt to exceed the default value.

The default value for gtc is the minimum of the total number of cores and
hyperthreads on the licensed number of physical processors and the total
number of cores and hyperthreads in the physical machine. The user cannot
set gtc to exceed the default value.

The default value for gn is 20 for the network server. For the personal
server on platforms which support Java in the database, gn defaults to 2
times the connection limit (which is also 20 because the connection limit
is 10) and the user cannot specify a gn value less than 2 times the connection
limit or greater than 3 times the connection limit. For the personal server
on platforms that does not support Java in the database, gn defaults to connection
limit and the user cannot specify a gn value larger then connection limit.

Once the server has chosen the gt, gtc, and gn values based on command line
values, license restrictions, physical processors in the machine, and the
connection limit, the server will choose a gx value. The default value for
gx is the minimum of gtc plus 1 and gn. The user cannot specify a gx value
where gx > gn.

An example will also help to demonstrate how the server selects CPUs based
on gt and gtc. For the purposes of the examples below, assume we have a 4-processor
system with 2 cores on each processor. We label physical processors with
letters and the cores with numbers. This 4-processor system therefore has
processing units A0, A1, B0, B1, C0, C1, D0 and D1

Case 1: A 1-CPU license or "-gt 1" specified on the command line
The network server will use gt=1, gtc=2, gn=20, gx=21
Threads will be allowed to execute on A0 and A1

Case 2: An unlimited server with "-gtc 5" on the command line
The network server will use gt=4, gtc=5, gn=20, gx=21
Threads will be allowed to execute on A0, A1, B0, C0, and D0

Case 3: A server with a 3-CPU license and "-gtc 5" on the command line
The network server will use gt=3, gtc=5, gn=20, gx=21
Threads will be allowed to execute on A0, A1, B0, B1, and C0

================(Build #3108 - Engineering Case #386047)================

When using an AWE cache, the server could have failed with a "memory exhausted"
error (not to be confused with the "dynamic memory exhausted" fatal error),
other fatal errors or other operations problems, such as failures loading
DLL for Remote Data Access or external stored procedures could fail. The
problem was that the server would allocate space for use by the cache up
to the available address space less 64MB; effectively leaving only 64MB of
address space for other purposes, which was frequently insufficient. Note
that the amount of address space allocated never exceeded the amount of physical
memory allocated for the AWE cache. Now, the database server allocates up
to the available address space less 512MB

An undocumented command line option "-cm <size>" has always existed to control
the amount of address space allocated for an AWE cache. As a work-around,
this option can be added to the server's command line to leave more address
space for purposes other than the cache.

Each process on 32-bit Windows is given 2GB of address space in total (that's
an OS and 32-bit architecture limitation) except on Windows 32-bit Advanced
Server, Enterprise Server and Datacenter Server where they are given 3GB
of address space in total, provided "/3GB /PAE" is in the boot.ini and there
is no more than 16GB of RAM installed. Again, these are OS and 32-bit architecture
limitations. 32-bit programs running on Windows x64 Edition are given the
full 4GB of address space, although running native 64-bit programs on Windows
x64 Edition is preferable (they are not limited to 4GB of address space).

A description of "address space" is probably helpful at this point. Address
space essentially refers to the amount of memory that can referenced by a
program at any given time. You can think of this as the number of unique
1-byte memory addresses that can be referenced by a pointer value. On a 32-bit
architecture, pointers are limited to 32-bits, or 4GB, of addressability.
On Windows, the OS uses 1GB or 2GB of each process's address space for its
own purposes leaving 3GB or 2GB for the process to use. Usually, every piece
of memory allocated has address space associated with it. That includes memory
containing code (the database server code & all DLLs loaded) or data. On
Windows, "virtual memory" allows the actual physical contents of a page of
memory to be written to disk to allow the physical RAM to be used temporarily
for another purpose but the address space remains allocated. When the memory
is paged back in, the contents could be in a different physical piece of
memory but its address (pointer value) will be the same.

With an AWE cache, physical memory and address space are allocated separately.
The database server may use, for example, 1GB of address space and 7GB of
physical memory for the cache. Physical memory allocated for an AWE cache
is not virtualized -- it is never swapped out to disk. Because the database
server has only 1GB of address space for the cache, it can only access 1GB
worth of the cache at any given time. If a cached page exists in physical
memory but has not been assigned some address space, the server must pick
a piece of the address space (in 4K chunks) that was allocated for the AWE
cache and ask the OS to change the process's page table so that the given
address space now refers to a different piece of physical RAM. The old piece
of physical RAM is no longer visible to the database server.

Changing the AWE memory mappings is very fast and definitely much faster
than doing an IO; however, it is not absolutely free. For optimal performance,
you want your address space to be as large as possible to minimize the number
of AWE mapping changes that are performed but small enough that you don't
run out of address space.

Since some operations such as loading DLLs can occur after the database
server cache has been created and the database server cannot predict the
address space that will be needed by those operations, the minimum amount
of address space reserved for purposes other than the AWE cache has been
increased to 512MB instead of 64MB (which should be sufficient in most cases)
and can be controlled manually in exceptional cases with the "-cm <size>"
switch.

================(Build #3108 - Engineering Case #386033)================

Date formating strings containing the AM/PM indicators "aa" or "pp" could
have resulted in mangled characters in Chinese dates. This has been fixed.

================(Build #3107 - Engineering Case #385486)================

Attempting to create a proxy table to an existing table in another ASA database,
that had a defined with a UNIQUEIDENTIFIER datatype, would have failed with
the error "data type not supported". This problem has been fixed.

================(Build #3107 - Engineering Case #377749)================

A REMOVE JAVA CLASS ... statement would sometimes have failed to remove the
Java class, as an obsolete version of the class had a foreign key reference
to the current version. This problem was been fixed by deleting all obsolete
versions of a Java class first, and then deleting the current version.

================(Build #3106 - Engineering Case #385530)================

If an ALTER VIEW statement was executed by the creater of the view, but that
user no longer has RESOURCE authority, a "permission denied" error would
have been reported. The view definition in SYSTABLE.view_def would still
have been updated, but the preserved source for the view in SYSTABLE.source
would not have been updated. This has been fixed, now no error will be reported
in this situation, and the preserved source will be updated.

================(Build #3106 - Engineering Case #385494)================

The IsNumeric() function would have returned an error when the parameter
was too long. It now returns FALSE, since the parameter can't be numeric.

================(Build #3106 - Engineering Case #385315)================

The order of columns in an index as returned by the view SYS.SYSINDEXES,
in the column colnames, mayt be incorrect. This has been fixed by adding
an ORDER BY clause in the list() expression used to generate the column list.

================(Build #3105 - Engineering Case #385158)================

When the schema of a database object was modified by a DDL statement, any
existing views that refered to the modified object could potentially have
become invalid. However, the server did not detect any problems until the
view was subsequently referenced. In order to avoid such problems from happening,
it was necessary to recompile the affected views via the "ALTER VIEW ...
RECOMPILE" statement. If such recompilation was not done after dropping a
column that is referenced by a view for example, then the server could have
crashed in certain situations when the affected view was referenced. This
has been fixed, the server will now generate an error without crashing.

The server will now generate an error without crashing.

================(Build #3104 - Engineering Case #384795)================

Attempting to create a procedure or an event containing a LOAD TABLE statement,
which used a variable name to represent the filename, would have resulted
in a syntax error. This has been fixed.

================(Build #3104 - Engineering Case #381771)================

When performing a backup to a tape device on Windows systems, the server
would have asked for a tape switch after 1.5 GB of data had been backed up,
even if the tape capacity was larger. This problem has been fixed. The server
will now use the entire capacity remaining on the tape.

As a workaround, the desired capacity can be specified using the "capacity="
option in the device string.

For example:

BACKUP DATABASE TO '\\.\tape0;capacity=20064829' ATTENDED ON etc.

The value specified is in K and is calculated by dividing 20,546,384,896
(which is the capacity in bytes reported by Windows for a 20 GB tape) by
1024.

================(Build #3103 - Engineering Case #385645)================

When the server was run on big endian platforms, (such as Sun Solaris), the
global variable @@procid would always have returned zero. This has been fixed.

================(Build #3102 - Engineering Case #383345)================

An incorrect result may been returned for queries with EXISTS subqueries
with correlated HAVING clauses. For this problem to have occurred, the following
conditions must be met:
1. There must have been at least one correlated equality predicate in the
WHERE clause of an EXISTS subquery.
2. There must have been at least one correlated predicate in the HAVING
clause of the subquery which referenced an aggregate function.
3. The EXISTS subquery was used in the WHERE clause of the main query block.

This has been fixed.

Example:
select A.C from A
where exists (
select 1
from A H
where H.b=A.b
group by H.b
having MAX(H.c)=A.c )

================(Build #3102 - Engineering Case #382540)================

If a SELECT was used to obtain the value of SQLCODE or SQLSTATE within a
Transact-SQL procedure, and the procedure was called repeatedly, the plan
for the query may have been cached. If this happened, the values returned
for SQLCODE and SQLSTATE may be zero, even after an error had occurred. This
has been fixed.

The value of @@error will correctly return an indication of whether or not
an error occurred.

A workaround is to set the option Max_plans_cached to 0; however, this may
impact performance. Another workaround is to obtain the value for one of
@@error, SQLCODE or SQLSTATE using a SET (i.e. assignment) statement rather
than by using a SELECT.

================(Build #3101 - Engineering Case #390008)================

Attempting to unload the ASA server via the NetWare console (i.e. "unload
dbsrv9") would have caused the NetWare machine to hang. This has been fixed.

================(Build #3100 - Engineering Case #383786)================

A remote database connection back to the same ASA server, using the shared
memory link, would have hung on Solaris. A workaround is to use TCP/IP. This
has been fixed.

================(Build #3100 - Engineering Case #382022)================

A memory leak in the Java Heap would have caused poor performance for Java
stored procedures, that used internal JDBC to access the database, if it
was called repeatedly. When a procedure like this was called repeatedly without
disconnection, the Java Heap would slowly grow until it reached its maximum,
at which time the Java Garbage Collector would run every time a memory allocation
request was made, causing poor performance. The memory leak has been fixed.

================(Build #3099 - Engineering Case #383414)================

If an older database was upgraded, the system table SYSSQLSERVERTYPE was
not being repopulated with new values. This table is now rebuilt during an
upgrade.

================(Build #3099 - Engineering Case #383178)================

The server disables floating point exceptions by default. If an external
function DLL written in Delphi was used, floating point exceptions could
have been enabled. This could have lead to a subsequent server crash due
to a floating point exception. This has been fixed.

================(Build #3099 - Engineering Case #377911)================

Using AWE on Windows 2003 would very likely have caused some or all of the
following:
1) a blue screen error 76 with text "Process has locked pages",
2) event log messages indicating that a "driver is leaking locked pages",
3) ASA fatal errors indicating the reads or writes were failing with the
error code 1453 (ERROR_WORKING_SET_QUOTA), and/or
4) other generic fatal read/write errors

Microsoft has fixed this problem in Service Pack 1 of Windows 2003. It is
our understanding that no fix will be made by Microsoft prior to the release
of Service Pack 1.

In order to prevent these serious consequences the database server can no
longer be started on Windows 2003 pre-SP1 while using AWE. Any attempt to
do so will result in a startup error "Windows 2003 does not properly support
AWE caching before Service Pack 1"

At the time this description was written there was no existing Microsoft
Knowledge Base (KB) article describing this issue.

================(Build #3098 - Engineering Case #382951)================

When the server was reading a significant number of pages into cache, or
writing dirty pages from the cache, there could have been slightly poorer
performance than expected, especially on a multiprocessor machine. This has
been fixed by removing contention and slightly reducing CPU usage in this
case.

================(Build #3098 - Engineering Case #381486)================

If a large number of statements was being used concurrently by applications
connected to a database, a "SQL Statement error" could be issued. The maximum
number of concurrent statements that can be handled by the server per database,
was limited to 20 * (number of connections to the database) + 16384. This
limit has now been changed to be approximately 20 * (number of connections
to the database) + 65534. The exact number is dependent on the page size
of the database cache.

================(Build #3096 - Engineering Case #382499)================

If the server attempted to use an SSL certificate that had expired, the non-intuitive
error message "Error parsing certificate file, error code -6" would have
been displayed. The message has been improved, it is now "Certificate '<filename>'
has expired."

================(Build #3096 - Engineering Case #382345)================

Attempting to autostart a database with an invalid DatabaseSwitches connection
parameter could have caused the server to hang. If the server was also being
autostarted, the connection attempt could have hung. If the server was already
running, the connection attempt would not hang, but the server may have hung
when shutting down. These problems have now been fixed.

================(Build #3096 - Engineering Case #382026)================

An ALTER PROCEDURE executed via EXECUTE IMMEDIATE within another procedure,
would have failed to define the result set for the outer procedure correctly
if the outer procedure returned a result set without specifying an explicit
RESULT clause and it declared a variable by the same name as one declared
in the inner procedure. The result of executing an ALTER PROCEDURE within
anothert procedure would have been different than if the statement had been
executed by itself. This has been fixed. A workaround is to use unique variable
names in the procedure which executes the ALTER.

================(Build #3096 - Engineering Case #379077)================

When the LOAD TABLE statement is used with the CHECK CONSTRAINTS OFF clause,
it does not validate any check constraints on the table. However, the check
constraints were built and annotated as part of the LOAD TABLE and failure
to do so resulted in the statement being rejected. The server will now ignore
the check constraints completely, by not attempting to build them at all.

As an example the following returns a "table not found error" when the table
CT1 referenced in the check constraint is not visible to the user executing
the LOAD TABLE statement:

grant dba,resource to dbowner
CREATE TABLE dbowner.CT1 ( c1 integer NOT NULL )
CREATE TABLE dbowner.T2 ( c1 integer NOT NULL, check(not c1 = any(select
c1 from CT1) ) )
LOAD TABLE dbowner.T2 ... CHECK CONSTRAINTS OFF ...

================(Build #3095 - Engineering Case #382237)================

The sample program (samples\asa\externalprocedures\tests.sql), was using
the get_piece() function for all chunks rather than just for the 2nd and
subsequent chunks. If the code was modified such that the string in the 7th
argument was prefixed with '=abcd'

set rslt = xp_all_types( null, 127, -12345, null,
'abcdefghijkl', 12.34e15, '=abcd'+repeat('=',300) );

then xp_all_types would have reported that all characters in the 7th argument
match. This is not true since the are different. This has been fixed, the
code in tests.sql has been corrected.

================(Build #3095 - Engineering Case #382047)================

It was possible, although rare, for TLS or HTTPS connections to have been
dropped at any time because of decryption errors. For HTTPS connections,
the client could also have seen the error "501 Method Not Implemented". This
has been fixed.

================(Build #3095 - Engineering Case #381724)================

If more than the maximum number of licensed HTTP connections are attempting
to use the server, it will report '503 Service Temporarily Unavailable'.
It was possible that the server could have reported this error, even when
the client had not exceeded the maximum number of connections. This was more
likely to occur when the clients repeatedly made connections to the server,
and the server was heavily loaded. This has been fixed.

================(Build #3094 - Engineering Case #382018)================

Starting the server with the -fips command line option (strong encryption
done using FIPF approved algorithms), but without specifying the -ec option
(encryption types), would have failed with the message "Simple encryption
is not available in FIPS mode". This has been corrected by changing the default
for the -ec option to "none"

================(Build #3094 - Engineering Case #381748)================

If the server was started with the -fips flag, web procedures using HTTPS
will use the regular (non-FIPS) RSA library, rather than the FIPS one. This
has been fixed.

In addition, web procedures can be forced to use the FIPS library by specifying
the URL as 'https_fips://...'. If the procedure is created using the https_fips
protocol, and the database is subsequently run on a platform that doesn't
support FIPS, the procedure will be executed as using standard (non-FIPS)
HTTPS.

================(Build #3093 - Engineering Case #381736)================

Calling the system procedure sa_proc_debug_get_connection_name() could have
caused a server crash if given a connection id for a connection that was
attempting to access a database that was currently starting or shutting down.
This has been fixed.

================(Build #3092 - Engineering Case #381727)================

The server could have unexpectedly closed HTTP connections. This condition
was more likely to occur as other active HTTP connections were terminating,
or within a short period of time, (pprox. 5 to 10 seconds), of their terminating.
This has been fixed.

================(Build #3089 - Engineering Case #381465)================

The SKIP n clause of the LOAD TABLE statement did not skip the initial n
lines of the input file. The SKIP clause was effectively being ignored. This
has been fixed so that the SKIP n clause does skip the first n lines in the
input file.

================(Build #3089 - Engineering Case #381438)================

It was possible for column statistics to become incorrect, which could have
potentially resulted in poor access plans. The situaltion was rare, and was
likely to have no other visible symptoms. This problem has been fixed.

================(Build #3089 - Engineering Case #381217)================

If a BACKUP DATABASE statement specified a long directory name for the target
directory and also included TRANSACTION LOG RENAME MATCH, the server could
have subsequently crashed. This has been fixed. A workaround is to use a
shorter directory name in the BACKUP statement.

================(Build #3088 - Engineering Case #381112)================

The Datadd() and Datediff() functions would sometimes have produced incorrect
results when the time unit was Hours, Days, Weeks, Months or Years.

For example,
select dateadd(month, 119987, '0001/1/1'), dateadd(week,521722,'0001-01-01'),
datediff(month,'0001-01-01','9999-12-31')

produced the result:
****-04-01 00:00:00.000 1833-11-10 19:44:00.000 -11085

This has been fixed. Now, the result will be:
9999-12-01 00:00:00.000 9999-12-27 00:00:00.000 119987

================(Build #3088 - Engineering Case #379951)================

On some new versions of the Windows CE operating system, it was possible
to get a 'Fatal Error: No such file or directory' message from the server,
when bringing the device out of STANDBY mode. This has been fixed.

================(Build #3087 - Engineering Case #380970)================

A CREATE PROCEDURE statement that did not qualify the procedure name with
a userid, would have failed with the error "Item 'procedurename' already
exists", even if the user did not own a procedure with the same name, but
there existed a procedure with the same name in the user's namespace, (ie
owned by a group the user was a member). This has been corrected.

================(Build #3087 - Engineering Case #380491)================

When adding days to a date using the Dateadd() function, it may have overflowed
without an error, returning an incorrect date value.
For example:
select dateadd(day, 2250318 , '2005-02-16') would have returned 0000-01-00'

This has been fixed, an error message will now be returned.

================(Build #3087 - Engineering Case #380351)================

The server will no longer display command-line options in the console window
when any part of the command line is derived from an obfuscated file. It
will now display a command-line syntax error message with asterisks, instead
of the text that caused the syntax error when obfuscation is used, (ie Error
in command near "***" )

================(Build #3086 - Engineering Case #380744)================

It was possible to get a "Database page size too big" error when autostarting
a server, depending on timing, if the following events occurred:
- an autostarted database and server was stopped due to a disconnect, and
the database had a page size of 2K or greater
- then a new connection was made immediately, that autostarted a server
and the same database
- virus scanning software was being used
The server was ignoring errors when attempting to determine the page size
of databases during a server autostart, and using a 1k page size if there
were errors. Now the server correctly handles these errors and fails the
server autostart.

This has been fixed so that the autostart either succeeds or returns the
"Specified database file already in use" error.

================(Build #3085 - Engineering Case #379788)================

Windows Mobile 2003 Second edition (aka Pocket PC 2003 SE, running Windows
CE 4.21) is now supported. This Windows version supports both Portrait and
Landscape mode screens, square screens, and also VGA screens (640X480 instead
of 320X240). They can switch from portrait to landscape mode at the push
of a button.

Software installed on this platform would previously have failed to install
with the message: "The program you have installed may not display properly
because it was designed for a previous version of Windows Mobile Software".
The install has been updated to suppress this warning. Any software which
supports a version of Windows CE earlier than 4.21 will still issue this
error. The server was also updated to support screen resizing.

================(Build #3044 - Engineering Case #384742)================

The global variable @@procid would have always returned zero on big-endian
platforms, (ie Sun Solaris). This has been fixed.

================(Build #3042 - Engineering Case #380469)================

The server may have crashed while shutting down, if there was an outstanding
xp_cmdshell() request still executing, and the server was forced to shutdown.
This has been fixed.

================(Build #3035 - Engineering Case #380378)================

Malformed GRANT statements could have resulted in incorrect behaviour. This
has now been fixed.

================(Build #3034 - Engineering Case #380206)================

The server could have left connections hanging indefinitely, when receiving
multi-piece strings on a heavily loaded system. There was a chance that this
problem could also have occurred under other conditions, such as when the
network connection between client and server introduced long delays. This
was more likely to occur when the number of active requests was larger than
the number of tasks that were servicing requests (ie -gn). This has been
fixed.

================(Build #3034 - Engineering Case #380084)================

The Dateadd() function could have produced incorrect results when the time
unit was milliseconds, minutes, hours, days, or weeks.

For example:

select dateadd(hour,365*24*7923,'0001-01-01 21:45:37.027'),dateadd(hour,69399300,'0001-01-01
21:45:37.027')

would have resulted in:

'****-09-18 00:00:37.027' '9998-07-01 00:00:37.027'

This has been fixed. Now, the results are:

'7918-09-29 00:00:37.027' '7918-01-15 00:00:37.027'

Similarily, the Datediff() function produced incorrect results when the
time unit was milliseconds, minutes, hours, days, or weeks.

For example,

select datediff(minute,'2005-02-03 21:45:37.027','6088-02-26 23:52:37.027')

resulted in a range error. This has been fixed. Now, the result is

2147483647

================(Build #3034 - Engineering Case #379896)================

Dropping a column from a table could have caused any UPDATE OF {column} triggers
on that table to fire incorrectly. This has been fixed.

================(Build #3034 - Engineering Case #379892)================

If a variable was assigned a long string value (>254 character) from a table,
and the table was subsequently dropped or truncated, the server would likely
have crashed on the next use of the variable.

For example:

begin
declare local temporary table t(c varchar(32767));
declare rv varchar(32767);
insert into t values(repeat('*',5000));
select c into rv from t;
truncate table t;
select lcase(rv) from dummy;
end;

A work around is to concatenate a zero-length string to column value, i.e.
use "select c || '' into rv from t" in the example above.

================(Build #3033 - Engineering Case #380104)================

On 64 bit Windows systems, dynamic cache sizing did not work correctly. The
server was unable to query the OS to determine its own working set size,
so the cache growth algorithm reverted back to the old (version 6.0), very
conservative growth algorithm. This has been corrected.

================(Build #3033 - Engineering Case #380064)================

Attempting to use any of the bit-wise operators (&, |, ^, ~) with BIGINT
or UNSIGNED BIGINT arguments would have resulted in an error, if one of the
argument values was too large to be converted to an INTEGER or UNSIGNED INTEGER.
This has been fixed.

Also, the INTTOHEX function now permits UNSIGNED BIGINT arguments.

================(Build #3033 - Engineering Case #380056)================

It was possible, although extremely rare, for the server or client to crash,
or drop connections, when using the TCPIP link. This could also happen to
the server running on Windows for SPX connections. This has been fixed.

================(Build #3032 - Engineering Case #379963)================

Selectivity estimates for the predicates generated for the KEY JOINs may
have been set incorrectly when the User_estimates option was set to 'ENABLED'
or 'OVERRIDE-MAGIC'. The side effect of the wrong selectivity estimates may
have been bad performance for queries using KEY JOIN syntax. This has now
been fixed.

Workarounds:
1) set the option USER_ESTIMATES to DISABLED ( highly recommended ); OR
2) rewrite the KEY JOIN into a JOIN with an ON clause, which must contain
the predicates of the form 'primary key column = foreign key column' for
all primary key/foreign key columns.

================(Build #3032 - Engineering Case #379940)================

If an HTTP connection was cancelled by the client while the server was still
processing the request, the server may not have closed the socket or releasd
it back to the OS. On Unix systems, this could have caused the HTTP listener
thread to eventually run out of sockets and fail after a period of time.
Clients then attempting to connect to the HTTP server would hang. On Windows
systems, this problem was more likely to exhibit itself as a memory leak.
This has been fixed.

================(Build #3032 - Engineering Case #379916)================

Attempting to insert into a local table, selected rows from a proxy table
when the remote server was down or not available, would likely have caused
the server to crash. Note that the crash will only occur if this INSERT-SELECT
performs the first connection attempt to the remote server. This problem
is now fixed and a proper error message will now get displayed.

================(Build #3032 - Engineering Case #379740)================

A LIKE condition would have incorrectly evaluated to False, if the pattern
string started with an underscore "_" or percent sign "%", and ended with
at least two non-wildcard characters, (e.g. '%00'); or the string expression
ended with at least two occurences of a non-wildcard character sequence that
overlap, (e.g. '1000' LIKE '%00'). This has been fixed.

================(Build #3032 - Engineering Case #379371)================

If a CREATE TABLE statement was executed, and the table had a multi-column
primary key, the statistics of the first primary key column would not have
been used until the database had been restarted. This has been fixed

================(Build #3031 - Engineering Case #379688)================

If an application was using Java in the database, or was using Remote Data
Access with a JDBC class, then there was a possibility that the server may
have lost a SQL error. This was most likely to occur if the SQL error was
set, but the SQL error did not get reported to the client prior to the VM
Garbage Collector running. Due to the asynchronous nature of the VM Garbage
Collector, this problem is highly unreproducible. The problem has been fixed.

================(Build #3031 - Engineering Case #378516)================

Attempting to run an ODBC application with a third-party Driver Manager would
have resulted in a hang, or a crash, if the ASA ODBC driver stub (libdbodbc9.so)
was present, but the actual drivers (libdbodbc9_n.so and libdbodbc9_r.so)
were missing. This situation could occur if, when creating a custom ASA installation,
the driver libraries were deleted, or were not copied. THis has been fixed.

================(Build #3029 - Engineering Case #379414)================

The Dateadd() function would have produced incorrect results when the value
to be added was close to the maximum or minimum 32-bit signed integer values
and the time unit was milliseconds. For example:

select dateadd(ms,2147483647,'2005-02-03 21:45:37.027')

would have resulted in:

2005-01-10 01:15:**.***

This has been fixed, now, the result is:

2005-02-28 18:17:00.674

The Datediff() function also produced incorrect results when the difference
was close to the maximum or minimum 32-bit signed integer values and the
time unit was milliseconds. For example:

select datediff(ms,'2005-02-28 18:17:00.675','2005-02-03 21:45:37.027')

would have resulted in a range error. This has also been fixed, the result
is now:

-2147483648

================(Build #3029 - Engineering Case #379190)================

The Dateadd() function would have produced incorrect results when the value
to be added was close to the maximum or minimum 32-bit signed integer values
and the time unit was seconds. For example:

select dateadd(ss,2147483647,'2005-02-03 11:45:37.027')

would have resulted in:

1937-01-16 08:32:**.***

This has been fixed, now, the result is:

2073-02-21 14:59:44.027

The Datediff() function also produced incorrect results when the difference
was close to the maximum or minimum 32-bit signed integer values and the
time unit was second. For example:

select datediff(ss,'2073-02-21 14:59:45.027','2005-02-03 11:45:37.027')

would have resulted in a range error. This has also been fixed, the result
is now:

-2147483648

================(Build #3028 - Engineering Case #379071)================

If the server encountered unexpected file errors while starting, it could
have displayed the error: "Unknown error (xxxxx)" (where xxxxx was meaningless).

For example, if asatest.db existed, running:
dbeng9 asatest.db" (the trailing quote is intentional)

would generate the error: "Unknown error (xxxxx)".

This problem has now been fixed so that unexpected file errors now display
the error: "Could not open/read database file: <file name>"

================(Build #3028 - Engineering Case #378387)================

If membership in group SYS was revoked from PUBLIC, rebuilding a database
using "DBUNLOAD -an" would have failed with the error: "Table 'SYSOPTIONS'
not found"
This has been fixed.

A workaround is to unload without the -an option.

================(Build #3027 - Engineering Case #378835)================

The INSERT ... ON EXISTING UPDATE statement updates an existing row with
the new column values. If a column list had been specified, then in addition
to modifying the specified columns, the statement also modified columns with
their default values. Now, the server will no longer update default columns
unless explicitly asked to.

The following describes the new server behaviour:

1. When the row does not exist, the new row is inserted as per the
usual rules of the INSERT statement.
2. If the row exists, and ON EXISTING SKIP is specified, no changes
are made to the row.
3. If the row exists, and ON EXISTING UPDATE is specified, the row is
updated as par the following rules:
(a) All columns that have been explicitly specified in the
INSERT statement are updated with the specified values.
(b) Columns with defaults that are meant to be changed on an
UPDATE are modified accordingly. These special defaults include
"DEFAULT TIMESTAMP", "DEFAULT UTC TIMESTAMP", and
"DEFAULT LAST USER".
(c) Columns with other defaults are not modified unless some
of these are explicitly mentioned with a non default
value in the INSERT statement, in which case these columns
are modified as par rule 3(a) above.
(d) Computed columns are re-evaluated and modified using the new row.
(e) Any other columns are left unchanged.

================(Build #3027 - Engineering Case #378230)================

Queries containing predicates with subqueries may have crashed the server
during execution. This may hace occurred if one of the following conditions
was met:
1. There were at least two predicates with subqueries referencing the same
table T, and T was also referenced in the main query block. In the example
below, t3 is referenced in both subqueries and in the main query block.
2. There was an index on the outer reference columns used in the subquery.
In the example below, t3 has an index on the column t2_id which is the outer
reference column in both subqueries.

Example:
select * from t1 join t3 as t2 on t2.t2_id = t1.t1_id +1
where t1.t1_id between (select MIN(t3.t1_id) from t3 where t3.t2_id=t2.t2_id)
and (select MAX(t4.t1_id) from t3 as t4 where t4.t2_id=t2.t2_id)

================(Build #3024 - Engineering Case #378034)================

Executing a procedure that called a function in an external library could
have caused the server to crash if the called routine was using the old-style
API. The problem occurred when the function was declared in SQL with fewer
arguments than it was actually written to handle. Consider the following
example of a user-defined function accepting one output argument.

CREATE FUNCTION "DBA"."MachineName" (out @iMachine char(255))
returns integer external name
'Win32MachineName@C:\\path\\mytools.dll'

begin
declare @iMachine char(255);
call dba.MachineName(@iMachine);
select @iMachine
end

If the actual function was written to accept more than one argument (e.g.,
int Win32MachineName( char *p1, char *p2 ) ) and the function employed the
"callee pops the arguments" protocol, then the stack pointer will be improperly
aligned upon return to the caller (the server in this case). It will point
to a memory location 4 bytes higher than where it should.

After the user function was called. the server checked, and corrected, the
stack misalignment. There was, however, a small window of a few instructions
where the stack pointer was misaligned and the server makes some other function
calls. This resulted in the top of the stack being corrupted. In previous
versions of the server, this did not result in any permanent harm. In more
recent versions of the server, an important pointer is correpted, resulting
in a crash.

Now, the server pushes and pops extra guard words on the stack so that these
unused stack positions will be corrupted instead. The server also now checks
for a serious stack underflow and will issue an assertion (103701 "Function
parameter list mismatch") and stop rather than crash.

================(Build #3023 - Engineering Case #378243)================

Repeatedly calling a stored procedure that performed an INSERT, UPDATE or
DELETE into a proxy table, would likely have caused a server crash. This
problem has been fixed.

================(Build #3023 - Engineering Case #378242)================

If a batch containing a call to an external procedure was executed, and the
external procedure was subsequently canceled, the batch would have continued
execution, instead of being canceled as well. This problem has been fixed.

================(Build #3023 - Engineering Case #378225)================

If WAITFOR ... AFTER MESSAGE BREAK was used to wait for a message from another
connection and no message was received before the end of the specified waiting
period, querying the value of connection_property('MessageReceived') would
return the value of the previous message received. Now in this situation,
connection_property('MessageReceived') will return an empty string.

================(Build #3023 - Engineering Case #378101)================

If a column of type Double or Float had DEFAULT AUTOINCREMENT defined, and
the maximum value for the column had already been inserted into the the table,
then inserting the DEFAULT value will yield unexpected results instead of
inserting the expected NULL value. This problem has been fixed.

================(Build #3023 - Engineering Case #378026)================

Executing a query involving a column for which the server estimate for NULL
selectivity had become invalid (ie greater than 100%), could have caused
the server to crash. The server will now deal with this situation without
crashing. The problem can be rectified by recreating the affected column
statistics using the CREATE STATISTICS statement.

================(Build #3023 - Engineering Case #377433)================

If a jConnect or Open Client application made several requests to the server
using many host variables, but didn't open any cursors, and then attempted
to use a jConnect or Open Client cursor with host variables, then the server
would likely have crashed. This problem has been fixed.

================(Build #3021 - Engineering Case #377759)================

In Transact-SQL stored procedures, cursor names in DECLARE CURSOR statements
were required to be unique. It was not possible to conditionally declare
a cursor, then use a common set of statements to access the cursor. Now,
DECLARE CURSOR statements in Transact-SQL procedures are treated as executable
statements, and may appear anywhere in a procedure. The cursor declaration
takes effect when the statement is executed and remains in effect until a
DEALLOCATE CURSOR statement is executed or until the procedure completes.
In Watcom-SQL procedures, cursor names must still be unique and cursor declarations
must appear with variable declarations at the start of a BEGIN..END block.

================(Build #3021 - Engineering Case #377755)================

If a connection updated rows in a table and subsequently left a cursor open
past a commit or rollback, other connections would not have been able to
lock the entire table in share mode (ie LOCK TABLE ... IN SHARE MODE) until
the updating connection closed the cursors and executed either a commit or
rollback. If a cursor is left open past a commit or rollback, the schema
locks persist until the cursor is closed, but other locks are now released.

================(Build #3021 - Engineering Case #377566)================

Under rare circumstances, when executing an UPDATE statement, the server
could have created empty histograms, and/or corrupted the selectivity of
IS NULL predicates. This problem has now been resolved.

================(Build #3021 - Engineering Case #376210)================

The server could have crashed while performing Index Consultant analysis
on a complex query. This was only likely to happen in queries with numerous
equality predicates, and either an ORDER BY, GROUP BY, or SELECT DISTINCT
clause. This has been fixed.

================(Build #3021 - Engineering Case #373770)================

Attempts to use the builtin XML functions on proxy tables would have failed
with the error "No name for arguement". This problem has been fixed.

================(Build #3021 - Engineering Case #364372)================

Sargable predicates using subqueries were not used for partial index scans
in some cases. The sargable predicates having this problem were only the
ones referencing at least two different tables from the main query block.
An example of such predicate is "T1.col1 = (select max(R.col2) from R where
R.col3 = T2.col4)" where T1 and T2 are two tables of the main query block.
This has been fixed.

An example:

The sargable predicate " t1.t1_id = (select MIN(t3.t1_id) from t3 where
t3.t2_id=t2.t2_id)" can now be used to access the table t1 through a partial
index scan on the primary key index "t1". Hence, the query may have the
access plan
" t2<seq> JNL t1<t1> : GrByS[ t3<t3> ]" .

create table t1 ( t1_id int primary key);
create table t2 ( t2_id int );
create table t3 ( t1_id int, t2_id int primary key );

select * from t1, t2 on ( t2.t2_id = t1.t1_id +1 )
where t1.t1_id = (select MIN(t3.t1_id) from t3 where t3.t2_id=t2.t2_id)

================(Build #3020 - Engineering Case #377450)================

If one, or both, of the tables in a full outer join was a proxy table, executing
the query would have caused the server to either crash, or give a syntax
error. Remote data access did not support full outer joins, This has been
fixed, full outer join support has now been added.

================(Build #3018 - Engineering Case #377155)================

Creating an index on a function and then inserting, updating, or deleting
data into the table on which that index was created, could have created an
invalid transaction log entry. If the index was added before any other operations
are performed on the table or the server was shutdown after the index was
created, and before any other operations were performed on the table, the
log would have been valid. This has been fixed.

================(Build #3014 - Engineering Case #377021)================

A cursor for a query with a single group by expression, was incorrectly qualified
to be of type 'sensitive'.

For example:
"select sum(T.x) from T"

This has been fixed. Depending on the desired cursor type, the server may
change the cursor type accordingly, and return a warning. For example, under
ODBC, if the desired cursor type for a cursor of a single groupby query
is KEYSET-DRIVEN, the actual cursor type is determined to be STATIC.

For more information on cursor sensitivity please see:

ASA Programming Guide
Using SQL in Applications
Adaptive Server Anywhere
Cursor sensitivity overview

================(Build #3013 - Engineering Case #376977)================

If an application's operating system used a multibyte character set, which
was different from the character set of the database being unload by the
Unload utility dbunload, then dbunload could have generated an invalid reload.sql
script, and dbunload -an could have failed with a syntax error. Note that
dbunload -an turns off character set translation so the character set used
by dbunload in that case is the same as the database character set. For example,
running dbunload -an on a Chinese (cp936) machine to unload and recreate
a UTF8 database could have failed with a syntax error, or could have crashed.
This has been fixed.

================(Build #3013 - Engineering Case #376721)================

When running on NetWare 5.1 with Service Pack 8, the ASA server would have
hung on shutdown after displaying the message "Database server stopped at <date> <time>".
Some of the NLM unloading code changed in SP 8. This has been fixed, the
server now supports these changes..

================(Build #2964 - Engineering Case #373037)================

In rare circumstances, databases using a 1K page size, could have become
corrupted during database recovery. This could have resulted in the error
'Unknown device error', an assertion error, or some other error indicating
that the server was reading beyond the end of the file. This has now been
fixed.

================(Build #2960 - Engineering Case #372680)================

A query that used an outer join inside a lateral derived table may have failed
with the error -727 "The optimizer was unable to construct a valid access
plan".

Further, if the lateral derived table was flattenable and there was a reference
from the null-supplying side of the outer join to a table outside the lateral
derived table, then the target of the reference needed to be treated as part
of the preserved side. This was not happening, Therefore, the optimizer
could, in some cases, choose an incorrect plan with the table in question
appearing above the outer join rather than on its preserved side.

Both these issues have now been fixed.

================(Build #2960 - Engineering Case #372230)================

The reference to "DT2.*" in the following query:

SELECT 1 FROM ( SELECT DT2.* FROM ( select 1 c ) DT1 ) DT2

should have given an error, since it occurred inside the derived table DT2.
An error would only have been given if DT2 was specified with a column list.
Now, an error will always be reported for this situation.

================(Build #2959 - Engineering Case #372522)================

The server could have started processing requests while the HTTP and HTTPS
communications links were still being initialized. Now, requests received
by the server before it is fully initialized will wait until startup is complete.

================(Build #2925 - Engineering Case #391357)================

If the text of a stored procedure, view or trigger was made unreadable using
the HIDDEN keyword, and the definition string was invalid, the server may
have crashed. This has been fixed.

================(Build #2925 - Engineering Case #366752)================

If a CREATE UNIQUE INDEX statement was executed for a local temporary table,
a subsequent ROLLBACK could have caused the server to fail with assertion
100705. The CREATE INDEX statement was not performing an automatic COMMIT,
now it does. A workaround is to execute an explicit COMMIT prior to the CREATE
INDEX statement.

Note, If the temporary table was created without ON COMMIT PRESERVE ROWS
and the table was non-empty, execution of the CREATE INDEX statement will
now delete all of the rows in the table, because of the added commit. Due
to the addition of the commit, a CREATE INDEX on a local temporary table
can no longer be used in a trigger or within an atomic compound statement.
will release any locks held by the connection, and will close cursors not
opened WITH HOLD.

================(Build #2552 - Engineering Case #376742)================

If the sybase_sql_ASAUtils_retrieveClassDescription() function was called
with a very long class name, a server crash could have occurred. This has
been fixed.

================(Build #2552 - Engineering Case #376699)================

On Windows 95, 98 or ME, the build number of the operating system was displayed
incorrectly.

For example:

"Running on Win98 build 67766222"

The correct OS build number is now displayed.

================(Build #2551 - Engineering Case #376617)================

HTTP connections to a database initialized with the collation 874THAIBIN,
would have incorrectly returned a charset value of 'none', rather than the
correct value of 'TIS-620'. This has been fixed.

================(Build #2551 - Engineering Case #376608)================

If an Open Client application opened a cursor which cuased the warning: "cursor
options changed", the application would have failed to open the cursor. This
problem has now been fixed. There are situations where Open Client applications
are not expecting warnings, so certain warnings that are known to not be
handled are suppressed, while other warnings are sent as the client actually
expects them. The "cursor options changed" warning has been added to this
list of warnings not to be returned to an Open Client applications.

================(Build #2551 - Engineering Case #376606)================

Creating a COMMENT on a local temporary table would have caused the server
to fail with assertion 201501 - "Page for requested record not a table page
or record not present on page".

Example:
declare local temporary table temp1(c1 int);
comment on table temp1 is 'my comment';

Now an error is returned when attempting to add a comment to a local temporary
table.

================(Build #2551 - Engineering Case #376444)================

If a view V1 caused a warning to be given when referenced (e.g. the result
returned is non-deterministic), and another view V2 referenced V1, and the
definition of V2 was output into the reload.sql script by DBUNLOAD before
the definition of V1, then V2 may not have appeared in the database after
the reload.sql script has run. This has been fixed. ALTER VIEW ... RECOMPILE
did not handle a warning being set while building a cursor for the view.
The warning is now cleared before making catalog changes and then is restored.

================(Build #2551 - Engineering Case #376104)================

When processing an INSERT statement, the value of in inserted expression
could have had the wrong value if it was a complex expression involving NUMBER(*).
This has now been fixed.

For example, the following would have generated incorrect results:
BEGIN
DECLARE LOCAL TEMPORARY TABLE t ( row_number INTEGER );
INSERT t SELECT 2 + NUMBER(*) AS row_number ORDER BY dummy_col;
SELECT * FROM t;
END;

================(Build #2551 - Engineering Case #368540)================

When used in Java Stored Procedures, cursors and prepared statements were
left open until the connection disconnected. If called repeatedly, they could
accumulate until a "resource governor exceeded error" occured. This has been
fixed.

================(Build #2550 - Engineering Case #376229)================

Version 6.0.x clients were not able to connect to 9.0.2 servers over TCP/IP.
This has been fixed.

================(Build #2548 - Engineering Case #375757)================

If a BACKUP or RESTORE statement was executed from the Open Client Isql utility,
while the backup.syb file was marked as read-only, the server could have
crashed. This has been fixed.

================(Build #2546 - Engineering Case #374846)================

Issuing a CREATE VIRTUAL INDEX statement on a proxy table would have caused
the server to crash. A crash could also have occurred if the Index Consultant
was run against a workload containing queries over proxy tables. This has
been fixed. Note that although virtual index creation is allowed on proxy
tables, such indexes are not meaningful and are not considered by the optimizer.

================(Build #2545 - Engineering Case #375236)================

Under rare situations, calls to functions that took string parameters, could
have crashed the server. This was only a problem on Unix systems, and has
now been fixed.

================(Build #2545 - Engineering Case #375197)================

A problem with GROUPING SETS, that could have caused server crashes, has
been fixed.

================(Build #2545 - Engineering Case #372279)================

When opening a cursor for a statement that contained an outer join, it was
possible for the server enter an endless loop. For this to have occurred,
the table on the null-supplying side had to have a computed column that was
a complex expression of some other table columns, and the cursor must have
been opened 'for-update' (implying that Ansi_update_constraints was off),
and the computed column must have been nested within two outer joins. This
problem has been fixed.

For example, the following situation caused the problem:

set option public.ansi_update_constraints = 'off';
create table T1 ( a varchar(10), c varchar(10) compute ( a+'' ) );
create table T2 ( f int );
create table T3 ( z int );

select * from T3 left outer join
( T2 left outer join T1 on T2.f = T1.c )
on T3.z = T2.f
for update;

================(Build #2544 - Engineering Case #375102)================

In rare cases, the optimizer may have produced plans that omitted a sort.
For example, the following query requires 2 sorts to properly calculate the
3 window functions.

select
sum(emp_id) over (order by emp_fname, emp_lname),
sum(emp_id) over (partition by emp_lname),
sum(emp_id) over (partition by emp_lname, emp_fname)
from employee

Previously, it would only have used one. This has been fixed.

================(Build #2544 - Engineering Case #375088)================

If a client application was connected via jConnect or the Open Client interface,
and the application attempted to query a UNIQUEIDENTIFIER column, the query
would have failed with the error "Attempted conversion between an illegal
pair of types". This problem has now been fixed.

Note that in addition to getting a new server, a new version of jcatalog.sql
will have to be run against the database with the UNIQUEIDENTIFER column,
to fully implement this fix.

================(Build #2544 - Engineering Case #375084)================

If a request-level log contained host variable information for a TDS connection,
the system procedure sa_get_request_times would not have recorded the host
variable information in the satmp_request_hostvar table. This has been fixed.

================(Build #2544 - Engineering Case #374990)================

The server could have exhibited slower than expected insert performance on
a multiprocessor machine when multiple clients were repeatedly attempting
to insert into a table containing an index, primary key or unique constraint.
Specifically, this problem occured when the clients were doing repeated inserts
to the end of an index (such as is the case with an autoincrement primary
key column). In this case, the server running on multiprocessor machines
with more CPUs could exhibit relatively little performance improvement over
the server on machines with fewer CPUs. This has been fixed.

================(Build #2544 - Engineering Case #374988)================

An INSERT statement, using the ON EXISTING clause to insert the result set
of a query involving a remote table, into a local table, would have failed
with a syntax error. The server will now execute these statements correctly.

For example, instead of generating a syntax error, the following will cause
table 'bar' to contain one row:

CREATE SERVER asademo CLASS 'asaodbc' USING 'driver=Adaptive Server Anywhere
9.0;dbn=asademo';
CREATE TABLE foo(c1 int) AT 'asademo...';
create table bar( c1 int primary key );
insert into foo values(1);
insert into foo values(1);
insert into foo values(1);
commit;
insert into bar on existing skip select * from foo;
select * from bar

================(Build #2544 - Engineering Case #374976)================

The debugger would have shown all connections on the server, instead of only
showing those connections to the database that the debugger was connected
to. This has been fixed.

================(Build #2543 - Engineering Case #374895)================

Attempting to start a server on NetWare that supported both ecc_tls encryption
and https, would have failed with the error - 'Missing or invalid encryption
DLL "dbrsa9s.nlm"'. When starting a server with both ecc_tls and rsa_tls
encryption, the server would have started, but rsa_tls would not have been
supported. This has been fixed.

================(Build #2543 - Engineering Case #374822)================

Recovery of transactions requiring the Wait_for_commit option to be ON could
have failed assertion 100904 "Failed to redo a database operation". For this
to have occurred, the following must have been true:
- The WAIT_FOR_COMMIT option must have been on as a temporary option (not
a user-level option)
- A connection must have started a transaction
- A subsequent checkpoint must have occurred while the transaction started
was still active (ie. had not been committed or rolled back).
- Additional operations on the transaction must have been performed that
*required* the WAIT_FOR_COMMIT option and must have been written to disk
(likely due to a commit)
- The server must have gone down dirty before any other checkpoint occurred.

This has been fixed, the Wait_for_commit option is now always on during
recovery.

================(Build #2543 - Engineering Case #374752)================

If a server was listening on more than one HTTPS port, it was possible that
HTTP requests for services created with SECURE ON would have been redirected
to an HTTPS port that could not handle the request. This has been fixed.

For example, given a server started with the following command line options:

-xs http,https(port=443;dbn=db1),https(port=444;dbn=db2) db1.db db2.db

If "sec" was a secure service in db2, then HTTP requests for "/db2/sec"
would have been redirected (via the 301 status code) to port 443 rather than
444. In most cases, this would result in a "404 Not Found" status, but could
possibly have executed the wrong service. In this case, if db1 had a service
called "db2/sec".

================(Build #2543 - Engineering Case #374709)================

If the server was attempting to start the TCPIP link, but could not bind
to port 2638, possibly because it is already in use, it would not have chosen
a random port to listen on. This has been fixed.

Note, this problem only affected servers on Windows and Netware systems,
it did not affect servers running on Unix systems.

================(Build #2543 - Engineering Case #347314)================

If a query contained a LIKE predicate with a literal constant pattern, that
did not contain a wildcard, the query could have incorrectly returned rows
where the expression or column contained additional trailing blanks when
run against a database that does blank padding of strings. For example, given
the value 'abc' and the LIKE pattern 'abc ' (with a trailing blank), the
server would have incorrectly matched the value and caused its row to be
returned. This has been fixed.

================(Build #2541 - Engineering Case #374452)================

If a proxy table to a DB2 table with a CLOB column, was used in a query,
then selecting that CLOB column would have failed with an unsupported datatype
error. This problem has been fixed.

================(Build #2540 - Engineering Case #374162)================

In localized versions of ASA, the English string 'SubQ' (used as an abbreviation
for subquery) was inconsistently translated in the long query plan (i.e.
from the plan() function). It would appear translated in some contexts, and
not in others. This prevented users from easily scanning the query plan looking
for the same word to locate the subquery responsible for a given selectivity
This has been fixed so that 'SubQ' always appears in the localized language
of the plan.

================(Build #2540 - Engineering Case #374123)================

The function http_variable() would have returned a non-obvious ordering for
variables with multiple values.

For example, for the following request:
http://localhost/foo?id=1&id=2&id=3&id=4&id=5
http_variable() would return the values for id in the following order:
1, 5, 4, 3, 2

The function was adding variables (and their values), either after the first
occurrence of the variable, or at the end of the list. Now, variables and
their values are added after the last occurrence of the variable, or at the
end of the list.

================(Build #2538 - Engineering Case #373732)================

Statistics for the index on the SYSATTRIBUTE system table may have become
incorrect in rare cases. This would have been reported as a validation error.
The problem has been fixed.

================(Build #2538 - Engineering Case #373607)================

If the first executable statement of a stored procedure was a SELECT ...
INTO, then using this procedure in the FROM clause of a SELECT statement
would have caused the server to crash. This has been fixed

For example:
create procedure P1 ()
begin
declare var varchar(128);
select first table_name into var from systable;
end
then
select * from P1()
would have crashed the server.

================(Build #2538 - Engineering Case #373531)================

The fix for Engineering Case 367366 introduced a problem where attempting
to establish a connection to a remote ASA database with a long database name,
or a long engine name, could have crashed the server. This problem has been
fixed.

================(Build #2538 - Engineering Case #373531)================

The fix for Engineering Case 367366 introduced a problem where attempting
to establish a connection to a remote ASA database with a long database name,
or a long engine name, could have crashed the server. This problem has been
fixed.

================(Build #2537 - Engineering Case #373613)================

An obsolete Java class could have caused the error "-110 - 'Item ... already
exists'",
when attempting to install a new version of a Java class previously removed.
This has been fixed.

================(Build #2537 - Engineering Case #373483)================

If an INSERT statement used a SELECT query that required a work table at
the top of the query plan, then the value of NUMBER(*) in the result of the
insert could have been improperly set to 0 for all rows. This has been fixed.

For example, the following INSERT could have generated the incorrect values:

insert into R
select 0-row_num, number(*)
from rowgenerator
where row_num <= 3
order by 1

================(Build #2537 - Engineering Case #373462)================

If a CREATE TABLE statement failed, for example because of duplicate column
names, and no commit or rollback was executed so far, the next attempt to
execute a CREATE TABLE statement, on any connection, would have crashed the
server or cause an assertion failure 102801. This has now been fixed.

================(Build #2537 - Engineering Case #373382)================

If a query contained a join between a remote table and a lateral derived
table with an ON clause, the chances were very good that the server would
have crashed. This problem has been fixed.

================(Build #2537 - Engineering Case #373341)================

The plan for a static Ultralite query could have incorrectly contained references
to a base table's computed columns, causing a semantic error. This would
have occurred if the table being referenced contained a computed column,
even though the query did not refer to the computed column directly. This
has been fixed.

================(Build #2537 - Engineering Case #373299)================

Using the Unload utility dbunload, with the command line options -an (create
new database and reload) or -ar (rebuild and replace database), against a
server which was not running sharedmemory, would have failed attempting to
conmnect to the new database. The generated connection strings used to by
-an and -ar to connect to the new database did not include the LINKS parameters.
Now, it includes all the parameters specified for the connection to the source
database.

Note, the server used with dbunload -ar must be on the same machine where
dbunload is run, but dbunload -an can now be used against a remote server.

================(Build #2537 - Engineering Case #372736)================

If a stored procedure opened a cursor on a declared temporary table, but
did not close the cursor before exiting, the server could have crashed when
the procedure was called. Failure to close the cursor might have been caused
by the procedure exiting due to an error. This has been fixed.

================(Build #2536 - Engineering Case #373173)================

Using the index hints "CUSTERED INDEX" or "NO INDEX" in a query could have
caused the server to crash, if workload capturing for the Index Consultant
had been turned on while the query was executed. This problem has been resolved.

================(Build #2535 - Engineering Case #373157)================

The long plan text (i.e. from the plan() function) is currently English only.
However, the selectivity source names (e.g. Bounded, Index, etc.) were being
displayed in the client language, causing an inconsistent appearance to the
plans. This has been fixed so that English only is displayed.

================(Build #2535 - Engineering Case #373028)================

Stopping a server while a database was in the process of either starting
or stopping, could have caused incorrect behaviour, such as the database
requiring recovery the next time it is started, or the server asserting,
crashing or hanging. Now, server shutdown waits for databases which are not
active, to finish starting or stopping before shutting down, and ensures
that a database is not stopped twice.

================(Build #2535 - Engineering Case #373028)================

Stopping a server while a database was in the process of either starting
or stopping, could have caused incorrect behaviour, such as the database
requiring recovery the next time it is started, or the server asserting,
crashing or hanging. Now, server shutdown waits for databases which are not
active, to finish starting or stopping before shutting down, and ensures
that a database is not stopped twice.

================(Build #2535 - Engineering Case #372882)================

If a view was created with an owner like: "create view dba.V1 as select c1
from T1" the preserved source of this view (column SOURCE in SYSTABLE) would
have contained an space character following the owner; e.g "create view dba
.V1 as select c1 from T1".

As well, if a view was created with a "select * ...", the view definition
(column VIEW_DEF in SYSTABLE) was unparsed without the space between the
"select" and "*"; e.g. "select* ...".

Neither of these errors caused problems in ASA, but did cause problems for
Powerdesigner. Both issues have been fixed.

================(Build #2535 - Engineering Case #371549)================

If a query performed a join between a local table and a remote table with
an ON condition, then there was a very good chance that the query would have
been processed in 'partial passthru' mode and returned an incorrect result.
This problem has now been fixed.

================(Build #2534 - Engineering Case #373039)================

An attempt to create two user-defined types, whose names were the same except
for case, in a case sensitive database was permitted. This now results in
an error, since these names should always be case insensitive.

Also, dropping a user-defined type required the name to have matching case,
in a case sensitive database. This is no longer required.

================(Build #2534 - Engineering Case #372922)================

A cast from a domain to an equivalent user type could have been ignored.
For example, the following should skip quoting the result of the html_encode()

select xmlelement( name p, cast( html_encode('''') as xml ) )

However, the usertype "xml" is defined as long varchar which happens to
be the return type of html_encode(). Therefore, the cast is silently dropped
and the quoting happens anyway. This has been fixed.

================(Build #2533 - Engineering Case #372775)================

On Windows CE systems, an HTTP or web service procedure would have hung when
issuing the request to the web server. The procedure would have returned
when the web server issued a timeout for the request. This has been fixed.

================(Build #2533 - Engineering Case #370899)================

Several race conditions in the server while starting and stopping databases
have now been fixed:

- The server could have autostopped a database when it should not have,
or not autostopped a database when it should have.

- In rare timing dependent cases, the server could have deadlocked, asserted
or possibly crashed, when a database was starting up or shutting down.

Also in rare timing dependent cases, the server could have asserted or possibly
crashed if HTTP or HTTPS requests were made to a database that was starting
up or shutting down.

================(Build #2532 - Engineering Case #372605)================

If an application, connected to a server via jConnect, cancelled a request
or closed a JDBC statement, the cancel or close could have failed and/or
dropped the connection entirely. This problem has been fixed.

================(Build #2532 - Engineering Case #372469)================

If EXECUTE IMMEDIATE WITH RESULT SET ON was used to execute a string representing
a multi-statement batch, it would have failed with the error:
Result set not permitted in '<batch statement>'
The batch will now be executed correctly and its result set returned.

================(Build #2531 - Engineering Case #375325)================

On non-English platforms, db_property('PlatformVer') and db_property('CompactPlatformVer')
could have returned mangled strings. This problem also affected graphical
plans, which include these properties in their output. The problem could
have caused Interactive SQL to fail to display the results of a query containing
these functions. This has been fix. The descriptive string returned from
the OS was not being converted to the server's character set, now it is.

This was only likely to cause problems when connected to a database using
jConnect, but it may possibly have affected the ODBC and ESQL drivers as
well, and was most likely to affect servers running on Chinese and Japanese
non-Windows OS versions.

================(Build #2531 - Engineering Case #372481)================

The estimate of the rate at which pages are being dirtied has been made less
pessemistic (a smoothed version of the estimates used in 7.x). Also, on
32 bit Windows systems, the server now measures the random write times rather
than using the cost model estimates, as this caused the estimates to be off
by a factor of 50 in some cases.

This is a further performance improvement to the issue originally addressed
by Engineering Case 355123.

================(Build #2531 - Engineering Case #372239)================

An HTTP or web service procedure, or a function with a remote address given
in dotted quad notation (e.g., http://192.168.0.1/), may have sometimes
failed to resolve, or have resolved incorrectly. This has been fixed.

================(Build #2531 - Engineering Case #372231)================

The server could have deadlocked while running simultaneous queries containing
joins of the same tables.

For example, the following might have caused such a deadlock.
select * from a,b where a.a2 = b.b2; //connection 1
select * from a,b where b.b2 = a.a2; //connection 2

This would only have occurred if there was no index or key on the columns
a2 and b2. This would most likely have occurred on a multi-CPU machine. This
has now been fixed.

================(Build #2531 - Engineering Case #372122)================

Engineering Case 304975 added support for handling UUID/GUID columns in proxy
tables to remote servers. Unfortunately, that change had the side effect
of disallowing creation of existing proxy tables with smalldatetime columns.
The problem with the smalldatetime column has now been fixed.

================(Build #2531 - Engineering Case #372086)================

If a query referenced a procedure in the FROM clause, and the procedure in
turn had a query that referenced a remote server, but could not be executed
in full passthrough mode, and the query also referenced a procedure variable,
then a syntax error could have resulted. This has been corrected.

================(Build #2531 - Engineering Case #372074)================

If an INSERT .... ON EXISTING statement used DEFAULT in the VALUES clause
for any primary key column of the table, the server would have crashed. This
has been corrected.

================(Build #2531 - Engineering Case #371203)================

A warning message that the server was not licenced for the appropriate number
of CPUs on the machine, was being given at each checkpoint. The warning message
is now only given at startup.

================(Build #2531 - Engineering Case #355123)================

The server could have performed poorly relative to 7.x servers when doing
a long sequence of database inserts, updates or deletes. The server was spending
longer than necessary cleaning up the cache in preparation for a checkpoint.
This time has now been reduced. Also, current servers now estimate the recovery
time better. Thus the Recovery_time database option may need to be set to
a larger value in order to have the server more closely match the value the
7.x server would have used.

================(Build #2530 - Engineering Case #368168)================

Error messages returned to applications connected to the server via TDS (
e.g. connections using jConnect ), would have been mangled when the OS character
set and the client character set were different. The problem was caused by
the header of the TDS error message having been mistakenly created in the
OS character set, while the main body of the error message was in the client
character set. The header is now also created in the client character set.

================(Build #2529 - Engineering Case #374122)================

Any user with DBA authority could have connected to a web service, regardless
of the restrictions placed on that web service by the USER clause. Now the
USER clause restrictions are respected.

For example, if the following SQL was executed:

grant connect to hurz identified by 'sql';
create service test type 'html' user hurz as select * from systable;
grant connect to newdba identified by 'sql';
grant DBA to newdba;

then both hurz and newdba (as well as any other user with DBA authority)
could have connected to the service test.

================(Build #2529 - Engineering Case #371202)================

The system procedure sa_get_request_times, would have stored a conn_id of
0 in the table satmp_request_time for any connections established before
request-level logging was enabled, for the file being processed. If sa_get_request_times
was called with a conn_id parameter to limit the information collected from
the log, it would not have stored any information for a connection started
before logging was enabled. Now, the connection id will match the connection
handle value for this situation.

================(Build #2529 - Engineering Case #371180)================

The server could have failed with assertion 104000 when attempting to execute
a query with a large IN list. An IN list of size roughly (1/32)*(page-size)^2
could have generated the assertion failure on 32 bit platforms, and a value
half that size would on 64 bit platforms. This has now been fixed, and IN
lists are supported up to the available cache memory.

Now, for IN lists bigger than the above limit, the "IN list optimization"
is not used, and a virtual table is not introduced. This may result in a
sudden performance difference when the IN list size crosses this size threshold.
It is not recommended to use very large IN lists.

================(Build #2529 - Engineering Case #371032)================

If a query referenced both proxy and local tables, or proxy tables from different
servers, then it will have to be executed in 'no passthru' or 'partial passthru'
mode. If such a query also contained column references of the form 'user.table.column',
then the query would have failed with error -845 "Owner '<owner name>' used
in qualified column reference does not match correlation name '<table name>'".
This problem has now been fixed.

================(Build #2529 - Engineering Case #370861)================

If a request log file was generated using:

call sa_server_option('Request_level_logging','sql+plan+hostvars');

and a plan string in the request log exceeded approximately 325 bytes, then
calling sa_get_request_times to process the resulting file may have resulted
in the error:

Primary key for table 'satmp_request_time' is not unique

Whether or not the error was given depended on what other requests were
active at the time the statement with the long plan was executed. The request
log file will now be output correctly.

================(Build #2529 - Engineering Case #370585)================

If an HTTP or HTTPS response was more than a few kilobytes in size, and the
server was on Unix, NetWare or Windows 95, 98 or Me, the response could have
been truncated, contain unexpected data and/or include fatal error text.
This was more likely to occur if the server machine was lightly loaded and
was faster than the client machine, or the client and server machine were
separated by a slow network link. This has been fixed.

================(Build #2529 - Engineering Case #370456)================

Executing a VALIDATE TABLE statement, and using the WITH EXPRESS clause,
(or dbvalid -fx), would have failed with the error "Not enough memory to
start", if the currently available cache space was not large enough. If cache
resizing is possible, the server will now try to increase the cache size
to the amount required.

================(Build #2529 - Engineering Case #370421)================

If the ROUND() function rounded a numeric value, the resulting value may
not have fit into the original NUMERIC data types percision. For example:
The constant 9.995 is of type NUMERIC(4,3). The result of ROUND(9.995,1)
is 10.000 which does not fit into numeric(4,3). As a result the numeric value
generated by the ROUND() function could have been invalid and a conversion
of this numeric value to a string could have returned '?'.
This problem has been fixed. If the numeric value passed to ROUND() is a
constant, the resulting data types percision is increased by one, (numeric(5,3)
in the above example). If it is not a constant and the resulting value does
not fit, then a SQLE_OVERFLOW_ERROR is generated if the option Convertion_error
is set, otherwise NULL is returned.

================(Build #2529 - Engineering Case #370339)================

Correlated subqueries used in computed columns may have caused grouped queries
to fail with the error " Function or column reference to ... must also appear
in a GROUP BY". This has been fixed.

An example:

CREATE TABLE R (
X integer not null,
Z integer not null,
Y integer NULL COMPUTE ((select count(*) from R as old where old.X = R.X))
)

select R.Z from R group by R.Z

================(Build #2529 - Engineering Case #370312)================

A query in a procedure or batch, with an expression that involved remote
tables and a unary minus or simple cast operator, would have failed with
the error:

ASA Error -823: OMNI cannot handle expressions involving remote tables
inside stored procedures.

This problem has now been fixed so that these operators do now work in expressions
involving remote tables.

================(Build #2529 - Engineering Case #370301)================

The ISNUMERIC() function could have returned TRUE for values which used the
letter 'd' or 'D' as the exponent separator (eg. '1d2') on Windows platforms,
or for values such as 'NAN', '0x12', 'INF', or 'INFINITY' on UNIX platforms.
The function no longer returns TRUE for these values.

================(Build #2529 - Engineering Case #370071)================

When the BACKUP DATABASE TO statement failed and returned an error, (for
example if the location for the achive file was not writable), then subsequent
BACKUP DATABASE TO statements that failed would have caused the server to
fail with assertion 104400 (a stack overflow) on Solaris 8 or 9 systems.
This has been fixed.

================(Build #2529 - Engineering Case #370045)================

Insert performance on systems with three or more processors would have been
much poorer than on single processor systems. The drop in performance would
have been more noticable as the number of processors increased (and was likely
even more noticeable on Unix systems). This problem has now been corrected.

================(Build #2529 - Engineering Case #369957)================

On Windows 2000 or XP systems, if the keyboard was used to navigate to the
system tray icon and the context menu was activated, pressing Esc to cancel
the menu would not have caused focus to be restored to the system tray icon.
Pressing Tab to navigate would have resulted in a beep. Now, focus is restored
to the icon after the menu is canceled.

================(Build #2529 - Engineering Case #369956)================

If the system tray icon was left-clicked, and the mouse then quickly moved
far from the icon, the context menu would have appeared at the mouse location,
far from the icon. The menu will now appear next to the icon.

================(Build #2529 - Engineering Case #369811)================

A database server using SPX would have started up successfully even if another
server running SPX was already running with the same name. This has been
fixed so that the server will now correctly detect that an another SPX server
is already running with the same name and fail to start.

================(Build #2529 - Engineering Case #369692)================

Internally, the value of the server's name is stored in the OS's character
set. When the Transact-SQL variable @@servername was used in a query, it
was not converted to the database's character set and as a result, comparisons
could have been incorrect. If the value was returned to a client, the name
could have been mangled by going through an incorrect character set translation
(db charset to client charset for a string that was in server OS charset).
The property( 'name' ) function which returns the same value was already
correct. This bug affected the title bar of the dbisqlc window. The problem
has now been fixed.

================(Build #2529 - Engineering Case #369676)================

The server allowed system datatypes, such as MONEY and UNIQUEIDENTIFIERSTR,
to be dropped using the "DROP DATATYPE" statement. An attempt to drop these
datatypes will now be rejected with a "permission denied" error.

================(Build #2529 - Engineering Case #369536)================

When initializing a database, filenames were added to the SYSFILE system
table in the OS character set. The filenames are now added to the SYSFILE
system table using the database character set.

================(Build #2529 - Engineering Case #369410)================

If a stored procedure was dropped and then another stored procedure with
the same name was immediately created, users who had permission to access
the first procedure, and had already called it, will still have been able
to access the second procedure, even if they have not explicitly been given
permission, until the next time the database was stopped. This has been fixed.

================(Build #2529 - Engineering Case #369275)================

Executing a query that used two or more derived tables which each called
the OPENXML function, one of which contained an illegal XPATH expression,
could have caused the server to crash. This has been fixed.

================(Build #2529 - Engineering Case #369122)================

The server may have exhibited poor performance if many connections try to
concurrently truncate a global temporary table. This was due to each connection
attempting to acquire an exclusive lock on the global temporary table definition.
Since each connection
already has a pointer to the table definition, acquiring an exclusive lock
is no longer done.

================(Build #2529 - Engineering Case #369054)================

Under some conditions when the results of a sort did not fit entirely in
memory, the sort could have returned rows that were only partially ordered.
This has been fixed.

================(Build #2529 - Engineering Case #369013)================

The connection properties IndAdd and IndLookup were always returning the
value 0. This has been fixed. Note that the corresponding database properties
returned the correct values.

================(Build #2529 - Engineering Case #368995)================

If a procedure contained a query that call the OPENXML() function, and the
xpath expression was passed as a variable argument, the error "Feature 'OPENXML
with non-constant query' not implemented" would have been reported reported
on the 11th call. This has now been fixed.

================(Build #2529 - Engineering Case #368551)================

The server could have crashed when executing Java code. This has been fixed.

================(Build #2529 - Engineering Case #368459)================

A database used as the Replication Server stable queue database could not
have been upgraded or unloaded. The RepServer system procedures were no longer
executable by rs_systabgroup. This has been fixed.

================(Build #2529 - Engineering Case #368274)================

It was possible for the server to drop TLS connections, when under heavy
load. Although rare, it was more likely to occur on a multi-processor machine.
If the -z command line option, ("display debugging information"), was used
on the server, a message indicating that a bad packet was received would
have been displayed on the server console. This has been fixed.

================(Build #2529 - Engineering Case #368251)================

The server would have failed to return the result set under certain circumstances.
One such situation was when the option Row_counts was set to 'ON' and the
query access plan had an indexed sort node at the top. This problem has now
been fixed.

================(Build #2529 - Engineering Case #368249)================

In complex queries, if the optimizer found an expression (prefilter) that
evaluated to FALSE, the optimization time may have been long. This has been
fixed.

================(Build #2529 - Engineering Case #368236)================

In rare circumstances, if a database which required recovery was autostarted,
the server could hang with the server window still minimized. One situation
where this could have occurred was when the database had a "disconnect" event.
A workaround is to start the database manually first to allow the database
to recover, and then shutdown this engine.

This issue has been fixed.

================(Build #2529 - Engineering Case #368231)================

Executing an ALTER VIEW statement with a select statement that would have
returned the warning "The result returned is non-deterministic." would have
crashed the server. This has been fixed.

================(Build #2529 - Engineering Case #368167)================

When computing string functions that result in strings with lengths greater
than the maximum allowed size of 2GB, the server could have wasted resources.
As an example, the following code caused the server to compute a 24GB string
before discarding the extra 22GB.

begin
declare foo long varchar;
set foo = 'ABCDabcd';
set foo = repeat( foo, 49152);
set foo = repeat( foo, 65536);
end;

The server will now stop the computation after the maximum allowed size
of 2GB has been reached.

================(Build #2529 - Engineering Case #368127)================

If a remote server was created using one of the Remote Data Access ODBC classes,
opening a cursor on a proxy tables from that server would have leaked about
8 bytes of memory for each remote column. Memory allocated at cursor open
time, to hold the indicator for each column, is now freed when the cursor
is closed.

================(Build #2529 - Engineering Case #368116)================

If a stored procedure which returned a result set was called from within
an atomic compound statement (i.e. BEGIN ATOMIC ... END), an error was correctly
given, however, an assertion would result when the database was stopped,
(Assertion 104301 - Attempt to free a user descriptor with non-zero reference
count). This is fixed, the database will now shut down correctly.

================(Build #2529 - Engineering Case #368053)================

If a client application terminated while the last connection to the server
was in the process of being disconnected, the server may not have autostopped
when it should. In these cases, the server icon and window would still have
been active, and the database would have been stopped, but no connections
could have been made to the server. Pressing shutdown would have stopped
the server though. This problem has now been corrected.

Note, this scenario could have occurred in a multithreaded application if
all of the following conditions were true:
- the server was autostarted by a multithreaded application
- the main thread of the application signaled a child thread to shut down
- the child thread did a disconnect as part of shutting down
- the main thread did not wait for the child thread to complete before ending

This has been fixed so that the server will correctly autostop.

================(Build #2529 - Engineering Case #367935)================

When run on Unix systems, the server could have crashed when a non-DBA user
was connected, if auditing was enabled. This has been fixed.

================(Build #2529 - Engineering Case #367913)================

On systems rinning Windows 95, 98, or ME, with the LDAP feature in use, the
database server would have registered the invalid IP address "0.0.0.0" in
LDAP, as well as the real machine's address. The list of IP addresses from
these versions of Windows includes 0 (i.e. 0.0.0.0). This address is now
ignored when creating the list for LDAP.

================(Build #2529 - Engineering Case #367863)================

If the EXECUTE IMMEDIATE statement was used to perform a CALL containing
variables as procedure arguments, the parameter values would have failed
to be passed to the called procedure. If the procedure contained OUTPUT parameters,
the output variables would not be set when the procedure returned, or a "variable
not found" error would have been reported. This has been fixed.

================(Build #2529 - Engineering Case #367743)================

Attempting to use a view that referenced a proxy table, and contained a subselect
which used an aggregate function, would have failed with the error "invalid
use of an aggregate function". This has now been fixed.

================(Build #2529 - Engineering Case #367716)================

The userid 'dbo' was unable to use EXECUTE IMMEDIATE to execute a string
containing a multi-statement batch. This restriction has now been removed.

================(Build #2529 - Engineering Case #367688)================

Support for textual options to the Transact-SQL statement SET TRANSACTION
ISOLATION LEVEL, have been added for compatibility with Sybase ASE and Microsoft
SQL Server. Applications can now issue the following variants:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

which correspond to setting the isolation level of the connection to 0,
1, 2, or 3 respectively.

================(Build #2529 - Engineering Case #367533)================

The server could have crashed when requested to generate an access plan for
a remote query, either by the dbisql plan feature, or an explicit call to
the explanation() function, when that query would have been executed in full
passthrough mode. An example of such a query is 'INSERT INTO T VALUES(2)'
where T is a proxy table. The server will now return no plans for such queries.

================(Build #2529 - Engineering Case #367456)================

If a web client made an HTTP or HTTPS connection to a the database server,
it could have caused other connections to hang, until the HTTP or HTTPS connection
either completed, or was killed. This now has been fixed.

================(Build #2529 - Engineering Case #367451)================

If a Remote Data Access server was created in a database to connect back
to the same database, then creating proxy tables would have hung the server.
This is a followup to Engineering Case 367366, which resolved the problem
with circular ODBC connections. Now, the error "Unable to connect, server
definition is circular", (SQLCODE -657), will be generated for circular JDBC
connections as well.

================(Build #2529 - Engineering Case #367378)================

The server could have become hung in an endless loop while performing a sort.
When in this loop, the server would not have responded to the cancel request.
For the problem to have occurred, a sort must have been performed with a
small amount of memory available to the connection, followed by a decrease
in the amount of available memory. The problem could have occurred even with
large cache sizes, if a child of the sort consumed most, but not all, of
the connection's allotted memory. Extra checks have now been added for out-of-memory
situations when sorting.

================(Build #2529 - Engineering Case #367366)================

If a Remote Data Access server was created in a database to connect back
to the same database, then creating proxy tables would have hung the server.
This problem was originally addressed in ASA 7.0.0, but subsequent changes
necessitated a different fix. Now, the error "Unable to connect, server definition
is circular", (SQLCODE -657), will be generated, but only for ODBC connections.
JDBC connections will still have problems.

================(Build #2529 - Engineering Case #367342)================

If the first byte of the DELIMITED BY string for a LOAD TABLE statement was
greater than or equal to 0x80, the LOAD TABLE statement would not have recognized
any delimiters in the input file. This is now fixed.

================(Build #2529 - Engineering Case #367337)================

Attempting to get the application information of a jConnect or Open Client
application, using SELECT CONNECTION_PROPERTY( 'APPINFO', ... ), would have
always returned NULL for APPINFO. Now, the server will attempt to display
the application name, the application host and the application PID, if that
information has previously been provided by the application at connect time.
It should be noted that in some cases, the application information provided
by the client is not completely accurate; however, the server will still
display the inaccurate information.

================(Build #2529 - Engineering Case #367331)================

In rare circumstances, it is possible for database corruption to occur if
the machine running the database server was put into suspend or hibernate
mode, while the server was still running. This has now been fixed for the
majority of cases. It still possible on very heavily loaded servers, as the
OS may suspend the machine while the server is still preparing for it.

================(Build #2529 - Engineering Case #367252)================

If the get_identity() function was used to allocate an identity value for
a table, but the table itself was not modified by the current connection,
or any other connection, then the value of the SYSCOLUMN.max_identity column
was not updated at the next checkpoint. If the database was shutdown and
restarted, get_identity() would then have re-used values previously generated.
This has been fixed.

Note that the use of an empty table having an autoincrement column, together
with get_identity(), may still have resulted in values being re-used if the
database was not shut down cleanly and values were allocated since the last
checkpoint. Depending on how the values were used, it may have been possible
to correct the starting value in a DatabaseStart event by calling sa_reset_identity()
with the next value to use. For example:
declare maxval unsigned bigint;
set maxval = (select max(othercol) from othertab);
call sa_reset_identity('IDGenTab', 'DBA', maxval);

================(Build #2529 - Engineering Case #367221)================

When selecting from a single proxy table, the rowcount value returned by
the server was incorrectly always 1, instead of -1. As a result, applications
which rely on the rowcount information would have assumed that the query
only had a single row in the result set. Returning a rowcount of -1 tells
the application that the rowcount information is an estimate only and should
not be relied upon. Note that after this fix, the rowcount for remote queries
will always be -1 even if the ROW_COUNTS option is set.

================(Build #2529 - Engineering Case #366574)================

Queries specifying the "TOP n" clause, that were optimized with the Optimization_goal
set to "all-rows" may have had a less than optimal access plan. Such queries
are now costed based on the estimated cost to produce first n rows instead
of using the estimated total cost.

================(Build #2529 - Engineering Case #366510)================

The quality of access plans chosen for queries with joins to tables with
few rows, that can make use of indexes, has been improved.

================(Build #2529 - Engineering Case #366401)================

Rebuilding databases on Unix systems, using the Unload utility dbunload with
the -ar or -an command line options, would have failed during the rebuild
operation, if the source database had table or row constraints that specified
stored procedures. This has been fixed.

================(Build #2529 - Engineering Case #366267)================

When the database option Ansi_close_cursors_on_rollback was set to 'ON',
the Validation utility dbvalid would have failed to validate all the tables
in the database. The error 'cursor not open' would have been displayed. This
has been fixed.

================(Build #2529 - Engineering Case #365953)================

If a user-defined function contained a COMMIT, calling the function in a
SELECT statement within a batch or procedure would have caused the cursor
for the batch or procedure to be closed if the cursor was not declared WITH
HOLD. This may have resulted in unexpected error messages like "Column '@var'
not found". Now these cursors will not be closed.

================(Build #2529 - Engineering Case #363767)================

Deleting or updating a large number of rows could have taken longer than
a comparable operation done with a server from version 8.0.1 or earlier.
This would only have been observed when using a database created with version
8.0.0 or later. This has been corrected.

================(Build #2529 - Engineering Case #361210)================

A SELECT INTO #temp statement, using a recursive view, may have caused the
server to crash if used inside a stored procedure. This has been fixed.

For example:
create procedure P1( arg int )
begin
with recursive v( a, b ) as (
select T1.a,T1.b from T1 where T1.a = arg
union all
select T1.a,T1.b from T1 join v on(T1.a = v.b)
)
select * into #temptab from v;
end

================(Build #2529 - Engineering Case #360460)================

An UPDATE statement may have failed unexpectedly with the error "No primary
key value for foreign key". For this problem to have occurred, multiple rows
had to have been updated, the table had to have a trigger that contained
a SET TEMPORARY OPTION statement, and the table had to have at least on Foreign
Key with a referencial action defined. This problem has been fixed, there
is no longer an error in this situation. The workaround is to
remove the SET TEMPORARY OPTION statements.

================(Build #2529 - Engineering Case #360238)================

The system extended stored procedure xp_cmdshell will now accept command
lines up to 8000 bytes.

================(Build #2528 - Engineering Case #366233)================

If a stored procedure contained a statement that performed a sequential scan
of a global temporary table, executing the statement could have caused the
server to crash. This problem would have occurred if the following conditions
held:
- The statement plan was cached
- The table was declared as "ON COMMIT DELETE ROWS"
- The table had more than 100 pages when the plan was cached
- COMMIT was called before the statement was executed

This problem has been fixed. The crash could be avoided by setting the option
'Max_plans_cached' to 0.

================(Build #2453 - Engineering Case #379925)================

When run on Unix systems, the server could have hung or crashed, while processing
HTTP requests. This was more likely on slower machines, or when processing
large requests or responses, and has been fixed.

================(Build #2453 - Engineering Case #375348)================

Calls to web services client functions could have failed with error -981
("Unable to connect to the remote host specified by '<URL>'") when the server
was running on NetWare systems. This would only happen if more than one client
called web services client functions at the same time. This has now been
fixed.

================(Build #2453 - Engineering Case #375327)================

If the -o switch was used on the server to specify a message log output file,
and the file could not be opened, a message was displayed in the server console
window, and the server started anyway. This has been fixed, now if the output
file cannot be opened, the server will report an error and will not start.

================(Build #2453 - Engineering Case #375097)================

When running on NetWare 5.1 with service pack 8, the ASA server would not
start up if TCPIP or HTTP was used. When the -z (display debugging information)
command line option was used, the message "TCP/IP link, function bind, error
code 10038" was displayed on the
console. This has been fixed.

Note that at the time of this fix, NetWare 5.1 SP 8 was still in beta.

================(Build #2453 - Engineering Case #372196)================

When running on Unix systems, the server could have crashed while shutting
down with active TCP/IP connection. This would likely have been very rare,
and has now been fixed.

================(Build #2452 - Engineering Case #378936)================

After applying the 9.0.1 1965 EBF for Solaris, the server would no longer
have run on machines with pre-SparcV9 CPUs. A SparcV9 instruction (CAS) was
added to the server without properly detecting pre-SparcV9 chips. This has
been fixed, the server now reverts to an emulated version of CAS on SparcV8
and older CPUs.

Adaptive Server Anywhere - Sybase Central Plug-in

================(Build #3913 - Engineering Case #605253)================

Sybase Central would have throw an exception on startup on Windows 7 systems.
The Windows XP theme that Sybase Central used did not work poperly in JDK
1.4.2. That theme is no longer used on a Windows 7 system, the classic Windows
theme is used instead.

================(Build #3826 - Engineering Case #569797)================

When unloading or extracting a database into a new database that was created
with strong encryption, the Unload and Extract Database wizards would have
display the encryption key in plain text in the Unload or Extract Database
Messages Dialog. This has been corrected so that now the encryption key is
displayed as "***".

================(Build #3825 - Engineering Case #568426)================

When browsing permissions for tables and views, a user might have been listed
more than once on the Permissions page of the property sheet for a table
or view. Similarly, a table or view might have been listed more than once
on the Permissions page of a user's property sheet. When fetching permissions,
rows with the same grantee but different grantor, were not properly grouped.
This has been fixed.

================(Build #3746 - Engineering Case #492814)================

A user without administrator permission was unable to start, stop or delete
SQL Anywhere services on a Windows 2003 machine, even if that user had been
granted permission by an administrator to control those services. This has
been fixed.

================(Build #3704 - Engineering Case #538882)================

If the stored procedure debugger was used to trace execution of a procedure
containing a variable defined as UNIQUEIDENTIFIER, the value and datatype
for the variable would not have been displayed. This has been fixed.

================(Build #3604 - Engineering Case #483635)================

If a trigger was created using the Interactive SQL utility with the syntax:

CREATE TRIGGER owner.name ...

then Sybase Central would have displayed the trigger SQL with the trigger's
owner replaced by the trigger's name, such as:

ALTER TRIGGER name.name ...

This has been fixed. Now the SQL is displayed correctly as:

ALTER TRIGGER name ...

That is, the owner (which is syntactically valid, but is ignored by the
engine)
is removed from the source.

================(Build #3537 - Engineering Case #476533)================

The debugger state was not being updated correctly when debugging a connection
currently at a breakpoint and then a running connection was chosen from the
connections list. This has been fixed.

================(Build #3524 - Engineering Case #473831)================

A watch for the variable SQLCODE did not evaluate correctly. This has been
fixed.

================(Build #3497 - Engineering Case #468783)================

Clicking the Name column heading in the table editor, would not have sorted
the column names correctly. Specifically, all column names starting with
upper-case letters were sorted before all column names starting with lower-case
letters. This has been fixed. A similar fix has been made for the Data Type,
Value and Comment columns.

================(Build #3474 - Engineering Case #464155)================

Attempting to use the Create Procedure wizard to create a Transact-SQL procedure,
would have caused Sybase Central to crash. This has been fixed.

================(Build #3471 - Engineering Case #463613)================

Opening online help in Sybase Central may not have worked the first time
it was asked for, although subsequent requests would have succeeded. The
problem was timing and operating system dependent. It has been fixed.

================(Build #3471 - Engineering Case #463589)================

Clicking the "Help" button on the "Add Watch" dialog would not have done
anything. Now it correctly opens the online help for the dialog.

================(Build #3463 - Engineering Case #462154)================

On Windows XP or Vista, when launching Sybase Central while its Fast Launcher
was running, the application window may have failed to appear. This has been
fixed.

================(Build #3458 - Engineering Case #461161)================

Opening the Connected User property sheet for a connection that no longer
existed and clicking the Extended Information tab, would have caused Sybase
Central to crash. This has been fixed.

================(Build #3442 - Engineering Case #453834)================

Sybase Central was not respecting the language setting created by the Language
Select utility dblang. This has been corrected.

================(Build #3410 - Engineering Case #448832)================

Opening the Trigger wizard from the Triggers folder would have listed all
tables, including proxy tables. This has been corrected so that proxy tables
are now excluded, since a trigger on a proxy table will never execute.

================(Build #3404 - Engineering Case #447049)================

Executing a statement, or statements, which caused tens of thousands of messages
to be displayed in the "Messages" panel, could have caused Interactive SQL
to eventually report an out of memory error. This has been fixed so that
only the last 1000 messages are displayed when Interactive SQL is run as
a windowed application, in order to reduce the amount of memory required.
When run as a console application, all of the messages are displayed in the
console window.

================(Build #3378 - Engineering Case #442594)================

If a return variable name that contained spaces was specified in the Create
Function wizard, then Sybase Central could not have created the function.
The return variable name was not being quoted in the generated source. Now
it is if the dialect chosen is Watcom-SQL. If the dialect chosen is Transact-SQL,
then spaces are replaced with underscores, as Transact-SQL does not support
spaces in variable names.

================(Build #3374 - Engineering Case #441754)================

The keyword "REAL" was not supported in the Data Type column of the table
editor. The workaround was to use the keyword "FLOAT" instead. This has been
fixed.

================(Build #3336 - Engineering Case #435890)================

After pressing Finish in the Upgrade Database wizard, it was possible to
still cancel the upgrade operation by pressing the Escape key, even though
the Cancel button was disabled in the Upgrading Database dialog. This has
been fixed so that now Escape key presses are ignored while the database
is being upgraded and the Cancel button is disabled.

================(Build #3336 - Engineering Case #435885)================

If a database was upgraded using the Upgrade Database wizard, jConnect support
would always have be installed, regardless of whether the "Install jConnect
meta-information
support" check box was checked or not. This has been fixed.

================(Build #3298 - Engineering Case #429117)================

In the Details panel of a table's result set, if a row was selected and the
Delete key pressed, the row would have been successfully deleted. If the
Delete key was pressed again, an error would have been displayed. This has
been fixed.

================(Build #3295 - Engineering Case #428363)================

Both the SQL Anywhere and MobiLink plug-ins permitted pausing, and continuing
Windows services for dbsrv8 and dbsrv9, dbeng8 and dbeng9, dbremote, dbmlsync
and dbmlsrv8 and dbmlsrv9. This ability has been removed, as none of these
executables actually support pausing. Pause and continue operations are now
only permitted on dbltm Windows services.

================(Build #3262 - Engineering Case #420747)================

When the UltraLite statement property sheet was used to change an UltraLite
statement's SQL statement, its code segment setting would have been cleared.
This has been fixed so that the plug-in now re-applies the code segment setting
whenever the SQL statement changes.

================(Build #3260 - Engineering Case #420382)================

There are situations where passwords used in Sybase Central, running on Unix
systems, could be at risk of being discovered. Selecting the password field
text and pasting it into another field, would have allowed the clear text
password to be viewed. This has been fixed.

A full description of this problem is available at http://www.sybase.com/detail?id=1040117

================(Build #3258 - Engineering Case #419802)================

Attempting to use Sybase Central to create a proxy table for a Microsoft
Excel or Access database would have failed with the following error:

[Sybase][ODBC Driver][Adaptive Server Anywhere]Server '<server-name>': [Microsoft][ODBC
Driver Manager] Driver does not support this function (-660)

The Sybase Central plug-in was calling the ODBC function SQLPrimaryKeys()
to determine which columns in the table were part of the primary key. Some
ODBC drivers (such as Access and Excel) do not support this call. Now, if
the remote server is of type
"generic", any failures when this call is made are ignored, and no primary
key information is displayed.

================(Build #3249 - Engineering Case #417998)================

If the Interactive SQL utility, when launched from Sybase Central, was closed
by clicking its close button after the server to which it was connected had
already been stopped, Sybase Central could have crashed. This has now been
fixed.

================(Build #3199 - Engineering Case #405724)================

All of the menus in the menu bar could have become disabled on Mac OS X 10.4.2.
This did not happen in earlier OS X versions. This has now been fixed.

================(Build #3192 - Engineering Case #404280)================

If server was shutdown, or crashed while the debugger was in use, Sybase
Central may have become very slow. This has been fixed.

================(Build #3190 - Engineering Case #403932)================

When debugging a trigger, table columns referenced in the trigger were not
shown in the row variables table. This has been fixed.

================(Build #3190 - Engineering Case #403931)================

When editing a numeric trigger row variable value, a negative value could
not have been entered without first typing a digit. This has been fixed.

================(Build #3184 - Engineering Case #401979)================

The Index Consultant could have finished its analysis, but not displayed
the results, then failed with a dialog reporting a NullPointerException.
This was only likely to happen on databases used with jConnect connections.
This has been fixed.

================(Build #3160 - Engineering Case #399068)================

When Sybase Central - Tools - Connection Profiles... - New was used to successfully
create a new profile, and the user returned to the the Connection Profiles
dialog box, the list should have been scrolled to the new entry, and the
new entry should have been automatically selected. This is now fixed.

================(Build #3153 - Engineering Case #397046)================

The changes for Engineering Case 394722, to have the iAnywhere JDBC driver
correctly handle unsigned values without promoting them to the next largest
datatype, also required that code in the Index Consultant that was expecting
'Long' objects, be modified to accept the more general 'Number' objects.

================(Build #3148 - Engineering Case #396236)================

After shutting down Sybase Central or Interactive SQL, directories could
have been locked, making it impossible to delete or rename them. This problem
only occurred on Windows platforms, when the "Fast launcher" option was enabled,
and the file browser dialog was used to open or save a file. The native Windows
file dialog changes the current directory. A changes has been added to restore
the directory after the dialog is closed.

================(Build #3129 - Engineering Case #392017)================

If a shared connection profile was created, it was not saved if Sybase Central
terminated abnormally after the connection profile dialog is closed. Private
connection profiles were saved properly. This has now been fixed.

================(Build #3128 - Engineering Case #391584)================

If two tables or views were selected, and the "View data in Interactive SQL"
menu item was clicked, two Interactive SQL windows would have opened, but
data for only one of the tables or views was displayed in one of the Interactive
SQL windows. The other window would often have been empty. This has been
fixed.

A workaround for this problem is to open the Interactive SQL windows separately
-- select one table, click "View data in Interactive SQL", then select the
other table, and click the menu item again.

================(Build #3117 - Engineering Case #387676)================

After creating a procedure using the syntax

CREATE PROC [owner.]name ...

Sybase Central would have incorrectly displayed the procedure's SQL as

ALTER PROCEDURE [owner.]nameCREATE PROC [owner.]name ...

This has been fixed. Now the procedure is displayed as

ALTER PROCEDURE [owner.]name ...

================(Build #3092 - Engineering Case #381720)================

Connecting via a Connection profile would have failed unless the "Connect"
dialog was first opened. This has been corrected.

================(Build #3087 - Engineering Case #380793)================

The background color of explanatory text was being set incorrectly in wizards
when Sybase CEntral was run on Linux. This has been fixed so that the wizard
backgrounds are now transparent.

================(Build #3034 - Engineering Case #380163)================

If an Article of a Publication contained two columns such that one column's
name was an exact prefix of another column's name (for example, "id" and
"id2"), then only the shorter named column would have been marked as part
of the Article on the Columns tab of the Article property sheet. This has
been fixed.

================(Build #3024 - Engineering Case #378272)================

Attempting to view the SQL for a view, trigger, procedure or function, that
contained a -- comment anywhere in the "CREATE|ALTER <object-type> [<owner>].name"
prefix, may have caused Sybase Central to appear to hang, at 100% CPU usage.
It was in fact, just taking a very long time to parse the SQL. This has been
fixed.

================(Build #3023 - Engineering Case #378033)================

When creating a new breakpoint in the debugger, the procedure list was not
sorted. This has been fixed, now the list of procedures, events, and triggers
is sorted.

================(Build #2546 - Engineering Case #375369)================

When debugging a procedure or a Java class, if the editor was open when the
breakpoints dialog was closed, it scrolled back to line 1. This has been
fixed.

================(Build #2545 - Engineering Case #375256)================

In the Java class description and source details panels, the line and column
indicators were missing from the status bar. This has now been fixed.

================(Build #2544 - Engineering Case #375205)================

When adding or removing Java classes or JAR files in a database, a class
might have appeared in the All Java Classes folder, but not in the Java Packages
or JAR files folder. This has been fixed. Now, all sub-folders of the Java
Objects folder are kept synchronized.

================(Build #2539 - Engineering Case #373931)================

In some circumstances, attempting to unload the data from one or more tables
by selecting the tables, and then choosing "Unload Data..." from the File
menu, would have caused Sybase Central to crash. This has been fixed.

In addition, the "Unload Data..." menu item is now only available for base
tables. It was previously available to proxy tables and global temporary
tables as well, which was incorrect, as the Unload Data dialog can only be
used to unload data from a base table.

================(Build #2539 - Engineering Case #373919)================

If the Unload Database wizard was used to unload the data, but not the structure,
from a subset of a database's tables, then all types of tables were listed
in the wizard. This was misleading, since the wizard should only unload the
data from base tables; that is, the data from proxy and global temporary
tables should not be unloaded. Now, only base tables are listed in the wizard
when choosing to unload data only. When choosing to unload the tables' structure,
then all types of tables are listed as before.

================(Build #2538 - Engineering Case #373752)================

Attempting to duplicate a Group by copying it to the clipboard and then pasting
it into the Users & Groups folder, would not have copied any of the members.
As well, if a Group was copied and pasted into Interactive SQL, the SQL for
the group would not have ncluded the statements required to define its members.
Both of these problems are now fixed.

================(Build #2535 - Engineering Case #373206)================

In the Table wizard, when specifying a value other than the default for the
percentage of free space to be reserved on each page, the 'number of bytes'
value displayed was not updated as the percentage was changed. This has now
been fixed.

================(Build #2535 - Engineering Case #373172)================

In the Translate Log File wizard, selecting 'Include trigger generated transactions'
and 'Include as comments only', would have included the trigger generated
transactions as statements rather than as comments. This has been fixed.

================(Build #2534 - Engineering Case #372896)================

The optimizer occasionally recommends indexes that, if created, would degrade
query performance. If the Index Consultant detects this case, it discards
the query from its analysis. A check for whether a query had been discarded
or not was missing from the new Analysis Viewer, which could cause the Index
Consultant to fail with a NullPointer exception, making the analysis results
unviewable. This has been fixed.

================(Build #2533 - Engineering Case #372800)================

When clicking on the "..." button for a table column's data type, the mnemonics
would not work initially on the property dialog that appears. This has now
been fixed.

================(Build #2531 - Engineering Case #372181)================

Selecting a table in the tree and then clicking on the Data tab in the right
pane, would have caused any attempt to unload either the table's data or
the entire database to block, until the unload operation was cancelled and
another item was selected in the tree. Note that selecting another tab in
the right pane was not sufficient to remove the block. Now, the unload operation
will proceed regardless of which tab is selected in the right pane, and there
is no need to change the tree selection to proceed with the unload.

================(Build #2531 - Engineering Case #372069)================

In the MacOS version of Sybase Central, attempting to use the ENTER key in
a non-editable combo box, to commit the current selection in the drop down
list, would have caused the drop down list to be closed, but the current
item would not have been selected. This has now been fixed.

================(Build #2531 - Engineering Case #372065)================

When run on MacOS systems, after successfully running a utility wizard that
displayed a messages dialog, Sybase Central would needed to have been restarted
in order to use the menu bar items. Otherwise, selecting a menu item would
have provided no response. This has been fixed.

================(Build #2531 - Engineering Case #372064)================

When using the MacOS version of Sybase Central to edit a table and clicking
in the Data Type or Value column, by default most of the column's width would
have been taken up by the "..." button, leaving very little room to see the
current value. Now, the button is only as wide as required to show the "..."
text.

================(Build #2529 - Engineering Case #370840)================

Shutting down the server while debugging database objects, would have caused
Sybase Central to go to 100% CPU usage. This has been fixed.

================(Build #2529 - Engineering Case #367886)================

Attempting to use the Proxy Table wizard to create a proxy table for a remote
table that contained a column type not supported by Adaptive Server Anywhere,
would have caused Sybase Central to display an internal error. Now, if an
unsupported column type is encountered, the wizard restricts the selection
of only those columns that are supported.

================(Build #2529 - Engineering Case #367742)================

When Sybase Central was connected to a database using the iAnywhere JDBC
driver, and a database error occurred, it would have been treated internally
as a closed connection. The error would not have been reported though, as
there really were no closed connections. This has been fixed.

================(Build #2529 - Engineering Case #367470)================

In the "Backup Database" wizard, the "Browse" button on the third page allows
an existing file to be chosen, or to provide the name of a new file. If a
new file name was provided, but without an extension, the value of the file
name text field in the wizard would have ended in ".*" -- which was wrong.
Now, the name typed is copied to the text field verbatim.

Adaptive Server Anywhere - Utilities

================(Build #3849 - Engineering Case #574920)================

A client side backup of a database with a path and filename length greater
than 69 bytes in the client character set, could have failed or truncated
the filename. This has been fixed.

================(Build #3817 - Engineering Case #566970)================

When rebuilding a QAnywhere database, the reload of the ml_qa_status_history
table could have failed with the error: "No primary key value for foreign
key". This has been fixed.

================(Build #3817 - Engineering Case #566970)================

When rebuilding a QAnywhere database, the reload of the ml_qa_status_history
table could have failed with the error: "No primary key value for foreign
key". This has been fixed.

================(Build #3721 - Engineering Case #543231)================

The OK button on the "Connect" dialog could have failed to do anything if
all of the following were true:
1. The "Fast launcher" option was enabled
2. The "Connect" window was opened and left open in one DBISQL window
3. A "Connect" window was opened and closed from another DBISQL window
This has been fixed. To workaround the problem, close the "Connect" window
and reopen it.

================(Build #3701 - Engineering Case #534001)================

The Java Runtime Environments that are included in SQL Anywhere have been
updated to version 1.4.2_18 for 9.0.2 and 1.5.0_16 for 10.0.1. These updates
include a number of security fixes which do not directly impact SQL Anywhere
software, but were done to help those customers whose corporate policies
preclude the installation of older JRE updates which contain known security
defects.

In the future, customers will be able to update the JRE themselves by following
instructions which will be made available shortly.

================(Build #3699 - Engineering Case #538099)================

Attempting to copy a large number of values in the "Results" pane could have
caused Interactive SQL (dbisql) to crash. This has been foxed so that an
error message is now displayed and the copy is aborted.

================(Build #3672 - Engineering Case #530954)================

The Interactive SQL utility, (as well as other adinistration tools, such
as Sybase Central and the SQL Anywhere Console) may have failed to start
on newer Linux systems including Linux Red Hat Enterprise 5. These Administration
Tools rely on libXp.so.6 which may not have been installed by default. For
example, installing the following package solves the problem on RHE5:
libXp-1.0.0-8.1.el5.i386 "X Org X11 libXp runtime library"

================(Build #3653 - Engineering Case #496407)================

In exeptionally rare circumstances, the server may have crashed trying to
collect information about database pages to be loaded (cache warming) the
next time the database was started. This has been fixed.

================(Build #3640 - Engineering Case #495092)================

Messages displayed by many of the utilities (ie dbunload, dbvalid, etc) may
have been truncated. The message display buffer size has been increased to
correct this problem.

================(Build #3597 - Engineering Case #485979)================

A procedure that was used in the FROM clause of a SELECT statement, may have
returned the error "Derived table '<procname>' has no name for column 2".
This would have happened if the SELECT statement in the procedure referenced
a table without qualifying it with the owner, and only the procedure's owner
could select from the table without a qualifying owner (i.e. not the user
who executed the CREATE/ALTER PROCEDURE statement). This has
been fixed.

================(Build #3585 - Engineering Case #484964)================

The command line option that represents a memory value, used by all the database
tools including dbmlsync, dbremote, dbltm and the MobiLink Server, was not
recognizing "g" and "G" as valid characters for a gigabyte of memory. This
code is not used by the database server. This has been fixed, so that "1G"
or "1g" can now be specify as a valid memory value. As a workaround, "1024M"
can be used to represent a gigabyte of memory.

================(Build #3582 - Engineering Case #484368)================

When attempting to unload and then reload a database created with an older
build, using a more recent build, if the database had Remote Data Access
servers defined, then there was a chance the reload could have failed with
the error: "Server capability name 'encrypt' could not be found in the SYS.SYSCAPABILITYNAME
table". This problem has now been fixed.

================(Build #3569 - Engineering Case #482640)================

The Interactive SQL utility dbisql may not have displayed multiple result
sets when connected with the iAnywhere JDBC driver (which is the default).
This has been fixed.

================(Build #3563 - Engineering Case #474715)================

The server only supports compressed database files up to a size of 4GB. If
dbshrink
or the CREATE COMPRESSED DATABASE statement tried to create a compressed
db file larger
than 4GB then the resulting file would have been corrupted. This has been
fixed so that the server now returns the error "Database creation failed"
if the resulting file would be larger than 4GB.

================(Build #3558 - Engineering Case #480659)================

The Interactive SQL utility could have become unresponsive immediately after
loading a .SQL file. This problem would have been very rare and timing-dependent,
and would more likely have occurred on systems with fast processors. This
has been fixed.

================(Build #3549 - Engineering Case #479086)================

When importing data into an existing table, the "Preview" table in the Import
Wizard would have shown values in BINARY columns as "[B@" followed by up
to 8 numbers and letters. The value from the file is now correctly displayed.

================(Build #3546 - Engineering Case #476693)================

It was not possible touse the INPUT statement to populate a GLOBAL TEMPORARY
table that did not preserve rows on commit. The INPUT statement had the unintentional
side-effect of committing changes. This has been fixed, INPUT no longer does
a COMMIT.

================(Build #3544 - Engineering Case #477714)================

The ALTER TRIGGER SET HIDDEN statement incorrectly removed the table owner
from the
create trigger statement stored in the catalog. As a result, the reload
of a hidden trigger definition would have caused the SQL error: "Table ...
not found", if the DBA user couldnot access the trigger without table owner.
This has been fixed.

In order to unload an existing database with this problem, the trigger definition
will need to be recreated and then hidden first.

================(Build #3519 - Engineering Case #472617)================

The Interactive SQL window could have stopped repainting when executing a
long-running query. This has been fixed.

================(Build #3509 - Engineering Case #470660)================

Items in the "Edit" menu were not enabled and did not perform consistently:
1. The "Edit/Copy" menu item is now enabled if a results table has focus
and at least one row is selected.
2. If the Results panel is selected, the "Edit/Paste" menu item is no longer
enabled.
3. If a results table was focused, the "Edit/Delete" menu item could have
been clicked, but nothing would have happened. Now, the menu item will cause
the row to be deleted, the same as if the DELETE key had been pressed.
4. The "Cut", "Undo", "Redo", "Find/Replace", "Find Next", and "Go To" menu
items are now enabled only if the "SQL Statement" field has focus. Previously,
they were enabled even if the "Results" panel was selected.

================(Build #3501 - Engineering Case #469699)================

An attempt by a version 9.0.2 DLL to self-register itself on Windows Vista
would have resulted in the regsvr32 process going into an infinite loop waiting
for the self-registration to complete. This could have happened during any
of the EBF installs from 9.0.2 build 3476 on. The problem would also have
manifest itself after any of these EBFs have been installed by manually executing
a regsvr32 command on a DLL. Since any 9.0.2 DLL that requires registration
has already performed the registration step as part of the initial 9.0.2
install, the re-registration failure during an EBF install should not cause
any problem, and the regsvr32 process can be safely terminated. In a similar
fashion, any attempt to unregister a DLL (regsvr32 /u) once the EBF was applied
would also have failed. This problem has now been fixed.

================(Build #3498 - Engineering Case #468882)================

In certain situations, for example, when the database server was shutting
down, DBLauncher may not have displayed all of the messages it received
from the database server, making it look like the database server had hung.
This has been fixed.

================(Build #3498 - Engineering Case #461299)================

When using the Unload utility dbunload and doing an external unload of a
database to files (i.e., using -xx or -xi and specifying an unload directory)
on a system with a multi-byte OS charset, then the unloaded character data
could have been inconsistently encoded, or incorrectly unloaded. For this
problem to have occurred, a connection charset of something other than the
OS charset must have been specified. Fr data to be incorrectly unloaded,
t specified charset needed to be one of Windows-31j (sjis/cp932), GBK (cp936),
GB18030, cp950, big5-hkscs, or cp949, and the character data needed to contain
the value 0x5c (i.e. an ASCII backslash) as a follow-byte. Otherwise, the
unloaded data may just have been inconsistently encoded into hex (i.e., some
bytes encoded as '\xDD', and other bytes left as is) characters. While the
10.x fix addresses this problem for any unload connection charset, the fix
for earlier versions addresses this problem only when the specified connection
charset is either the OS or the database charset.

It is generally recommended that the database charset be used for unloading
as it avoids both the overhead of unnecessary charset conversion and potentially
lossy conversions.

================(Build #3497 - Engineering Case #468631)================

All of the GUI applications shipped with SQL Anywhere for Mac OS X, such
as the Interactive SQL utility and DBLauncher, would have stopped working
after applying
updates to Mac OS X, specifically Security Update 2007-004. The applications
would either have crashed, or displayed a message similar to the following:

The library dbput9_r could not be loaded. This may be because the provider
is being re-loaded (in which case you need to restart the viewer) or because
the library could not be found in the Adaptive Server Anywhere installation.
Service management will not be available.

or:

Link (dyld) error: Library not loaded: libdbserv9_r.dylib Referenced from:
/Applications/SQLAnywhere9/System/bin/dbsrv9 Reason: image not found

This has been corrected.

================(Build #3492 - Engineering Case #467789)================

Interrupting a SQL statement would not have also aborted any subsequent statements
which were pending execution. For example, if a number of statements were
entered in the "SQL Statements" field each separated by the command delimiterand
then executed, attempting to abort them by clicking the "interrupt" toolbar
button, would only have aborted the statement currently executing when the
button was aborted; the remaining statements would have continued to be executed.
This has been fixed so that the remaining statements are not executed.

================(Build #3492 - Engineering Case #467783)================

When executing a statement, the "Execution time" message displayed in the
"Messages" pane could have been displayed before all of the asynchronous
messages caused by a statement had been displayed. This has been corrected
to that the execution time message follows the asynchronous messages. Asynchronous
messages are those generated explicitly by the MESSAGE statement, or implicitly
by CREATE DATABASE.

================(Build #3488 - Engineering Case #467145)================

The keybaord accelerator for the "SQL/Stop" menu item was displayed as "Ctrl+Clear",
even though there is no "Clear" key on most keyboards. This text has been
changed to read "Ctrl+Break".

================(Build #3479 - Engineering Case #465405)================

The Edit/Select All menu item would only have operated on the contents of
the "SQL Statements" field. The intended behavior is that this operation
select the contents of the active pane. This has been fixed so that if a
result table has focus, the Edit/Select All menu item selects all of the
rows it contains.

================(Build #3463 - Engineering Case #462028)================

On Windows XP or Vista, when launching DBISQL while its Fast Launcher was
running, the application window may have failed to appear. This has been
fixed.

================(Build #3454 - Engineering Case #456675)================

If a result set row could not have been fetched, the full reason for the
failure might not have been reported. Typically, the message "Cursor not
in a valid state" was displayed without the underlying error indication.
Now, all of the available error information is displayed.

================(Build #3454 - Engineering Case #456232)================

The Interactive SQL utility, or any of the Java administration tools (ie
Sybase Central, DBConsole, and MobiLink Monitor) would not have started on
machines running German Windows Vista, if installed to "C:\Programme" rather
than "C:\Program Files". This problem has been fixed.

================(Build #3452 - Engineering Case #455668)================

It was possible for the database server to crash when attempting to run a
corrupted database file. Assertion 201418 'Row (page:index) has an invalid
offset' has now been added to detect this corruption.

================(Build #3445 - Engineering Case #455329)================

The Interactive SQL utility could have displayed BINARY, LONG BINARY, VARCHAR
or LONG VARBINARY values as empty if the "Show multiple result sets" option
was on and the truncation length was set to zero. This has been fixed.

Note, this problem only affected windowed operation, not console mode.

================(Build #3439 - Engineering Case #456445)================

It is not possible to use the Input Method Editor (IME) to enter passwords
in the Interactive SQL utility, or any of the Java administration tools,
due to a bug in the Java Runtime Environment.

================(Build #3420 - Engineering Case #449874)================

The dbisqlc utility may have terminated abnormally immediately on startup.
This problem occurs occasionally. A problem in the GUI initialization code
has been fixed.

================(Build #3419 - Engineering Case #449881)================

If the table names specified in the Unload utility's -t and -e command-line
options (or the equivalent Sybase Central settings) were provided in a character
set other than the database character set, the tables may not have been unloaded
(or excluded, in the case of -e). This problem would commonly have occurred
when the OS charset and database charset were different, and characters in
the table names required conversion. This has been fixed.

================(Build #3419 - Engineering Case #449783)================

Some of the utilities, dbunload, dbtran and dbmlsync were not always honouring
the SATMP (version 10.0.0), or the ASTMP (versions prior to 10.0.0) environment
variable, when determining a location to store temporary files. When that
happened, all the other steps in deciding the temporary directory location
were as documented. This has been fixed.

================(Build #3407 - Engineering Case #444436)================

The SQL preprocessor sqlpp could have generated incorrect code if the following
two statements were one after the other:
EXEC SQL SELECT ... INTO <hostvar list>
EXEC SQL DROP ...;

The DROP would have been missing from the generated. This has been fixed.

================(Build #3398 - Engineering Case #446269)================

Interactive SQL could have run out of memory when it executed a SQL file.
Running into this problem would have been more likely if the the SQL file
was large and run in batch mode from a command-line, the "-onerror continue"
command line option was used, or the script included an equivalent SET OPTION
statement in the SQL file itself, and executing the SQL file caused tens
or hundreds of thousands of errors to be reported. This is now fixed.

================(Build #3396 - Engineering Case #446003)================

Importing text files encoded with UTF-8, using the INPUT command, would have
failed if the file had a 3 byte endian header. This has been fixed.

Note that some text editors (e.g. Notepad) write the 3 byte header, but
others do not.

================(Build #3395 - Engineering Case #445836)================

In the dbisqlc Statistics window, messages such as "execution time xx.yyy
seconds..." could have had an incorrect number of seconds. This has been
fixed so that xx.y seconds is now reported (i.e. seconds including tenths),
and this time is accurate.

================(Build #3395 - Engineering Case #445707)================

The Interactive SQL utility could have crashed if it was closed while executing
a statement if all of the following were true:

- it was running as a windowed application
- a .SQL file had been opened,
- the file had been modified in the "SQL Statements" field,
- the file had not yet been saved,
- when prompted whether to save the file or not, the "Yes" button was
clicked.

This has been fixed.

================(Build #3395 - Engineering Case #445677)================

Interactive SQL could have reported an internal error if an accelerator key
(e.g. CTRL+N) was used while it was busy (e.g. saving a file). This has been
fixed.

================(Build #3393 - Engineering Case #444472)================

Using Interactive SQL with the -q command line option ("Suppress non-critical
messages"), would have caused all messages to be suppressed. This was not
correct, and has been fixed. Now, error messages are displayed regardless
of whether -q is used or not.

================(Build #3389 - Engineering Case #443671)================

If a statement was executed that returned a result set containing binary
column values that were longer than about 1MB, the Interactive SQL utility
could have become unresponsive for a length of time proportional to the width
of the column data. This has been fixed. This performance problem could often
be seen when selecting all columns from a proxy table to a directory access
server.

================(Build #3387 - Engineering Case #443758)================

The dbisqlc utility would have crashed if an OUTPUT command redirected a
non-deterministic result set. This has been fixed.

================(Build #3381 - Engineering Case #443027)================

The Interactive SQL utility, as well as Sybase Central and DBConsole, would
not have operated correctly when connected to a SQL Anywhere database that
had the SQL_flagger_error_level or SQL_flagger_warning_level options set
to anything other than 'W'. Typical behavior included getting the error message
Disallowed language extension detected..." when connecting. This has been
fixed.

================(Build #3378 - Engineering Case #442575)================

If a database had two or more tables with the same name and columns owned
by a different users, and one of those table owners had queried their table
with the Interactive SQL utility, opening the QueryEditor would have caused
an exception to be thrown. This problem has been fixed.

================(Build #3369 - Engineering Case #441110)================

Interactive SQL could have reported:

"There was an error reading the results of the SQL statement.
The displayed results may be incorrect or incomplete."

when attempting to display a result set which contained numeric data that
was undisplayable. This error message has been replaced with the the textual
representation of the value which is returned by the server. For example,
the following statements now display a result set with one value ("?"), whereas
previously, the result set column header and the error message above were
displayed, with no values at all.

set temporary option precision='1';
set temporary option scale='0';
create variable v1 decimal;
create variable v2 decimal;
set v1=9;
set v2=9;
select v1*v2;

================(Build #3366 - Engineering Case #440134)================

If the Datasource utility was executed with the -g option on a non-existent
DSN, or if -g or -gu was used on a system DSN on Windows; and the -cm option
was also used, then the output would have been an invalid dbdsn command.
This has been fixed.

================(Build #3364 - Engineering Case #440245)================

In the "Export" dialog, when the "Browse" button was clicked and an existing
file selected, the user was asked if they wanted to overwrite the file. This
prompt has been removed, as the user is asked this anyway when they click
the "Export" dialog's OK button.

================(Build #3364 - Engineering Case #440140)================

Calling the DBTools DBUnload function twice in an application would have
resulted in the second call hanging if the unload was attempting to load
into a new database. This problem did not affect dbunload.exe, but could
be seen using Sybase Central. This has been fixed.

================(Build #3364 - Engineering Case #438139)================

If a database having dbspaces with fully-qualified pathnames was backed up,
there was no way to start the backed-up copy of the database on the same
machine as the original database, while the original database was still running.
A new server command line option "-ds <dir>" has been added to tell the server
where to find all of the dbspaces and transaction log for the database. The
START DATABASE statement has a new clause as well to provide the same information:
START DATABASE 'db-file' ... DIRECTORY 'dbspace-directory'
When a dbspace directory is specified, the server will look only in that
directory for the files for that database. For example, if the server is
started in the same directory as all of the dbspaces, adding "-ds ." will
tell the server to find the log and all dbspaces in the current directory.

During startup, a message will be displayed in the server messages window,
e.g.:
Opening dbspace file 'path\sp1.db'
to indicate the location of the dbspace.

================(Build #3362 - Engineering Case #440037)================

The Input Wizard could have crashed when double-clicking the "Finish" button,
and was most likely to have occurred when the computer was busy. A similar
problem could have occurred with the "Next" button if the table which was
beaing imported into was locked, and the database option "Blocking" was "on".
This has been fixed by having the Wizard prevent any interaction with a control
while it is busy with a request to database.

================(Build #3360 - Engineering Case #439213)================

Global temporary tables were not listed in the "Lookup Table Name" window.
There were inadvertently excluded, and are now listed.

================(Build #3354 - Engineering Case #438976)================

Executing a STOP ENGINE statement would not have caused the Interactive SQL
title bar text to revert to "(Not Connected)". As a result, users may have
had the impression that they were still connected, even when they weren't.
The title text is now updated after execution of a STOP ENGINE statement
if the connection is closed.

================(Build #3349 - Engineering Case #438225)================

It is now possible to change the setting of the "Show multiple result sets"
checkbox (Tools->Options->results), using the SET statement. The name of
the option is "isql_show_multiple_result_sets". Allowable values are "on"
and "off" (case-insensitive).

For example:
SET TEMPORARY OPTION isql_show_multiple_result_sets = on;

This is not a new option per-se, but the ability to modify it from the SET
statement is new.

================(Build #3342 - Engineering Case #437122)================

When using Interactive SQL in console mode (ie with -nogui command line option),
result sets data could have been truncated unnecessarily if the column name
was shorter than any of the data in the column, and if the column data contained
leading and/or trailing blanks. This has been fixed.

================(Build #3338 - Engineering Case #436437)================

If the command history file could not be saved, the Interactive SQL utility
would have reported an internal exception (NullPointerException in PlainView.updateMetrics)
on shutdown. This has been fixed.

================(Build #3333 - Engineering Case #436293)================

When run on Unix systems, utilities such as Interactive SQL, when looking
for a file with a filename with no extension, might fail to find the file
even when present. The routine doing the search was appending the filename
with a dot ".", even when there was no extension to add. This has been fixed.

================(Build #3330 - Engineering Case #434740)================

When using ECC or TLS encryption to connect, a number of parameters about
the encryption certificate are specified, including the cerfificate company,
unit and name. When an ODBC datasource was created with these parameters,
it was necessary to specify all of the parameters. Omitting one of the parameters
would have left the value empty in the connection string, possibly preventingthe
connection from being made. This has been fixed so that empty parameters
are no longer added to the connection string.

================(Build #3329 - Engineering Case #434647)================

When upgrading a version 9.0.1 database to version 9.0.2, some views would
have been missing. This would not have occurred if the starting database
was older than version 9.0.1. This has been fixed.

================(Build #3326 - Engineering Case #430586)================

The Interactive SQL utility was failing to execute a ROLLBACK following a
failed statement if the Auto_commit option was ON. The behaviour has been
changed so that a ROLLBACK is now executed in this situation. Note, this
is now the same behavior as DBISQLC.

================(Build #3324 - Engineering Case #433460)================

The Interactive SQL utility was displaying messages that contained ampersands
incorrectly. Ampersands were removed from the text, and the characters following
the ampersands were underlined. This has been fixed.

================(Build #3324 - Engineering Case #431876)================

The Interactive SQL utility could have reported a spurious table missing
error if a connection executed a SELECT statement, disconnected, then connected
to a different database and executed an INSERT statement. The problem was
due to the "Auto_refetch" option being on. This option was not sensitive
to the connection being closed, which has now has been fixed.

================(Build #3318 - Engineering Case #431917)================

Engineering case 384238 changed the behaviour of the Ping utility, such that
when run with the -q command line option "quiet: do not print messages",
it would not have displayed a message if the server could not be found. According
to the
documentation, a message is always displayed when an error occurs. This
change has been reversed, so that error messages are now displayed.

================(Build #3318 - Engineering Case #431228)================

Specifying the connection parameter INT=NO (do not use integrated logins)
would actually have been interpreted as 'use integrated logins' if the database
was being autostarted, which would likely have prevented a connection from
being made. This has been fixed.

Note, this problem also affects the Console utility and the plug-ins for
Sybase Central.

================(Build #3314 - Engineering Case #421675)================

Interactive SQL would not have consistently reported errors raised from within
a stored procedure if connected via jConnect. This has been fixed.

================(Build #3313 - Engineering Case #432032)================

When run on Unix systems with the -q "silent mode" command line option, dbisqlc
would have crashed if a MESSAGE statement was executed with a TYPE ACTION
TO CLIENT or a TYPE WARNING TO CLIENT clause. This has been fixed.

================(Build #3310 - Engineering Case #431697)================

When the OUTPUT command was used with the FORMAT LOTUS clause, UNSIGNED SHORT
values greater than 32767 were exported as negative numbers. This has been
fixed by writing out UNSIGNED SHORTs as numeric records.

================(Build #3310 - Engineering Case #430742)================

Usually, the Interactive SQL utility sends statements to the database server
for execution one at a time. When dbisql saw an IF statement with an ELSEIF
clause, it would become confused as to where one statement ended and another
began, which would have caused multiple statements to be sent to the server
at the same time. This has now been fixed.

================(Build #3307 - Engineering Case #430442)================

When doing a restore from an archived backup image on UNIX platforms, the
disk activity would have been very high and the restore would have taken
a long time. This has been corrected.

================(Build #3301 - Engineering Case #429867)================

The Server Locate utility was truncating the server names in the list that
was displayed to 20 bytes. This has been fixed. The displayed server names
are no longer truncated.

================(Build #3301 - Engineering Case #429846)================

The Interactive SQL utility would have reported a syntax error when attempting
to execute a BACKUP DATABASE statement with the WAIT AFTER END clause from
within a BEGIN ... END block. The parser was interpreting the "END" in "WAIT
AFTER END" as the end of a BEGIN...END block, and then submitting only part
of the block to the server for execution. This has been fixed.

================(Build #3299 - Engineering Case #429607)================

The Unload utility could have generated calls to dbo.ml_add_property() in
the reload.sql file, even when they were not necessary. This has been fixed.

================(Build #3295 - Engineering Case #428508)================

The Interactive SQL utility could have reexecuted more than the last SELECT
statement if the "Auto_refetch" option was on. For this to have occurred,
DBISQL would also have to have been run in windowed mode, with multiple statements
executed at once, starting with a SELECT statement. e.g.
SELECT * FROM myTable;
OUTPUT TO 'c:\\test.txt';
Then an INSERT, UPDATE, or DELETE statement was executed, which would have
caused the statements following the SELECT statement (in this case, the OUTPUT
statement) to have been reexecuted. This has been fixed.

================(Build #3295 - Engineering Case #416755)================

A complex query in a recursive union could have caused predicate inference
problems in the optimizer. The reported symptom was an infinite loop. The
exact conditions are difficult to characterize, but the minimum complexity
that produces the problem involves a derived table in one of the branches
of the recursive union that itself contains a subquery and a join that uses
both an ON condition and a WHERE clause. The problem is now fixed.

================(Build #3294 - Engineering Case #428387)================

The option to print only the last result set when running in console mode
was ignored if the "Show multiple result sets" option was enabled. Instead
of printing only the last result set, all result sets were being printed.
This has been fixed.

The linkage between these two options is possibly not clear in the user
interface. To clarify the relationship, the "Results" panel in the "Options"
dialog has been updated to disable the option to show all result sets when
run in console mode when "Show multiple result sets" is turned off. Note
that in that case, "all" is the same as "last".

================(Build #3272 - Engineering Case #422845)================

Interactive SQL could have reported an internal error (NullPointerException)
when the Import Wizard was opened to import a file and a file was chosen,
but the file was deleted (or otherwise became unavailable) after entering
the wizard. This has been fixed.

================(Build #3267 - Engineering Case #421137)================

Database validation will now detect if the number of pages allocated to a
particular table matches what is stored in the system table SYSTABLE(table_page_count).
A message will be displayed if these values do not match. Incorrect table
page counts could potentially lead to assertion failures in the future.
Namely, assertion 200602 could be generated when dropping or truncating such
a table.

================(Build #3261 - Engineering Case #420462)================

If a zero-length file was opened, the status bar text would continue to read
"Loading <file name>", and a progress bar control would remain. This has
been fixed so that the status text is cleared, and the progress bar is not
present. Behavior for files with nonzero lengths is unchanged.

================(Build #3261 - Engineering Case #415245)================

On some systems running Windows XP, the graphical administration tools (i.e.
Sybase Central, Iteractive SQL, the MobiLink Monitor and the Console utility)
could have crashed on startup if the Windows desktop was configured to use
the "Windows XP style" for the "Windows and buttons" setting. While it is
still unclear as to the cause, a work-around for this problem is being provided.

After installing the EBF, create a file called "temp.reg", and paste the
following lines into it:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Sybase\Sybase Central\4.3\VMArgs]
"-Dswing.noxp"="1"
[HKEY_LOCAL_MACHINE\SOFTWARE\Sybase\Adaptive Server Anywhere\9.0\DBISQL\VMArgs]
"-Dswing.noxp"="1"
[HKEY_LOCAL_MACHINE\SOFTWARE\Sybase\Adaptive Server Anywhere\9.0\DBConsole\VMArgs]
"-Dswing.noxp"="1"
[HKEY_LOCAL_MACHINE\SOFTWARE\Sybase\Adaptive Server Anywhere\9.0\DBMLMon\VMArgs]
"-Dswing.noxp"="1"

and then run the file. If the "Fast Launcher" feature of Sybase Central
or DBISQL has been enabled, log out and then log back in again for the changes
to take effect.

While this procedure will prevent the programs from crashing, there will
be some visual anomalies, such as an incorrect background color for the menu
bar. These defects aside, the programs will function normally.

================(Build #3260 - Engineering Case #424219)================

A security problem on Unix sytems has been fixed

================(Build #3251 - Engineering Case #418500)================

If the Interactive SQL utility encountered an error while fetching the results
of a statement, it could have left the "Execute" toolbar button disabled
indefinitely, even after it reported the error to the user. This has been
fixed.

The workaround for this problem is to interrupt the statement by clicking
the "Stop" toolbar button.

================(Build #3247 - Engineering Case #416906)================

Starting the MobiLink server with an invalid connection parameters would
have caused the service to hang. The only way to remove the hung process
was to use the Task Manager. A semaphore which signaled that initialization
had completed was not being set in this particular error case. This has now
been corrected.

================(Build #3246 - Engineering Case #417496)================

Negative integer values exported to an Excel spreadsheet were exported incorrectly
(the values were incorrect). DOUBLE, FLOAT, NUMERIC, and REAL values were
not affected. The INTEGER record in the Excel BIF format is implicitly unsigned,
but signed numbers were being written. This has been fixed by writing negative
integers as NUMBER records instead.

================(Build #3239 - Engineering Case #415899)================

If there was an .odbc.ini file in the current directory, the Data Source
utility would always have used it, regardless of any environment variable
settings. This has been fixed.

================(Build #3232 - Engineering Case #415425)================

There were problems with the Java administration tools when they were run
on a secondary monitor. When the application window was run on the secondary
monitor, context menus would have appeared on the primary monitor. For dbisql
and dbconsole only, if the application window was last closed on a secondary
monitor, it would always have appeared on the primary monitor, rather than
on the secondary monitor, the next time they were run. These problems have
now been fixed.

================(Build #3212 - Engineering Case #407773)================

When connected to a server via jConnect, Interactive SQL could have displayed
the following warning after calling a stored procedure:

"010P4: An output parameter was received and ignored."

This warning has now been suppressed since there is nothing the user can,
or should, do about it.

================(Build #3209 - Engineering Case #407408)================

If the full path to the active transaction log was greater than 57 characters,
calling the Backup utility with command line option -xo "delete and restart
the transaction log without backup", would have failed to erase the renamed
transaction log. The renamed transaction log file is now properly deleted.

================(Build #3207 - Engineering Case #406904)================

If the Translation utility was used with the command line option -it "specify
table names to include in output", it would have crashed when the transaction
log file contained transactions that continue from the previous transaction
log file. This has now been
fixed.

================(Build #3206 - Engineering Case #406913)================

The Interactive SQL utility could have appeared to be hung when launched
from the context menu of a table in the ASA plug-in for Sybase Central. The
problem did not occur every time, nor on every machine. This has been fixed.

================(Build #3200 - Engineering Case #406093)================

Calling the Information utility with -u option "output page usage statistics",
could have caused a server crash if there was a table in the database with
a long name.

================(Build #3200 - Engineering Case #403665)================

The changes for Engineering Case 370421 caused the result from the Round()
function to be returned with an incorrect scale. This has been corrected.

This is illustrated by the following SQL code.

BEGIN
DECLARE @denominator numeric(16,12), @time_calc numeric(22,12)
select @denominator = 12
select @time_calc = round(1.0/@denominator,12)
select @time_calc
END

The correct result is .083333333333, prior to this fix, the result was .083333000000.

================(Build #3193 - Engineering Case #401948)================

The corruption caused by the problem fixed in Engineering Case 383145 could
have been undetectable by database validation. Engineering Case 386569 attempted
to address this, but the change may have caused validation of non-corrupted
indexes to fail. This has been fixed. Validation of a database affected by
the corruption in Engineering Case 383145 is now detected properly and results
in the error "Index 'index_name' on table 'table_name' has an invalid right
spine". This type of corruption should be fixed by rebuilding the index.

================(Build #3178 - Engineering Case #392640)================

When using a keyset-driven cursor over a query containing an unflattened
derived table that contains a subselect, the wrong answer could have been
returned for the subselect.

For example, the following query could cause the above problem:
select *
from (
select t1.a , (select t2.a from t2 where t2.b =t1.a) as x
from t1
order by t1.a
) v2

This error has been fixed. As a consequence, the results for unflattened
derived tables are now Insensitive in Keyset-driven cursors.

================(Build #3175 - Engineering Case #401494)================

The ESCAPE CHARACTER clause of the OUTPUT statement was being ignored so
that the escape character was always a backslash. This has been fixed.

================(Build #3175 - Engineering Case #401391)================

When run on Linux systems, the Interactive SQL utility was not able to run
a script file with if it did not have a ".sql" file extension. It would have
displayed an error message saying that the file did not exist. This has now
been fixed so that files can now be opened even if they do not have a ".sql"
file extension.

Note: This bug only affected opening a file by clicking on the "File/Run
Script" menu item. Behavior when running as a command line program was not
affected.

================(Build #3170 - Engineering Case #400332)================

Changes for Engineering Case 394722 to the iAnywhere JDBC Driver prevented
Interactive SQL from displaying, importing, or exporting unsigned numeric
types correctly. For example, when displaying unsigned values, an error dialog
could have been displayed saying that the value would not fit in an "n" byte
value, where "n" was a small whole number. This has now been fixed.

================(Build #3158 - Engineering Case #396681)================

When the Unload utility was run with the -ar command line option ("rebuild
and replace database"), it was possible that the transitional log file (or
mirror log file) that was used during the rebuild process would not have
been deleted. For example, if the transaction log name was asademo.log, then
an extra file called asademo.logR would have remained after the rebuild process.
The rebuild would have been successful, but subsequent attempts to run dbunload
-ar on the same database would have failed, if the file asademo.logR was
not removed. This has now been fixed.

================(Build #3146 - Engineering Case #396463)================

DBASE3 or FOXPRO files, created by saving a result set, could have appeared
empty when loaded by FoxPro. The problem was only seen when reading the file
with FoxPro, but not with Excel, and only when all of the following were
true:
- The result set contained fewer rows than the configured maximum number
of rows to fetch
- All column data was shorter than the configured truncation length.
- The "Show multiple result sets" option was OFF.

This has been fixed, which also solves the following related problems:

- Under the conditions listed above, DATE columns were written in character
fields in the .DBF file rather than using dBase/FoxPro "Date" fields.
- Warning messages about long column names being truncated would be displayed
twice. Now they are displayed only once.

================(Build #3143 - Engineering Case #395667)================

When attempting to export multiple result sets at the same time, Interactive
SQL could have failed with and internal error, or the resulting files could
have been empty. This has now been fixed.

This problem did not occur if the "Show multiple result sets" open was turned
OFF (which is the default), nor did the problem occur if there was only one
result set to export.

A crash was observed if the result sets were exported using the FIXED file
format. Using other file formats typically resulted in the first result set
being exported correctly, while the files for the subsequent result sets
would be empty.

================(Build #3141 - Engineering Case #395238)================

The changes for Engineering case 384294 had the side-effect of preventing
the "Continue" action from working properly after Interactive SQL failed
to execute a statement. This has now been corrected.

================(Build #3141 - Engineering Case #394136)================

If a table had been created with the PCTFREE clause (table page percent free),
the unload or reload of that table would not have used this PCTFREE in the
CREATE TABLE statement for the new database. This has been fixed.

================(Build #3135 - Engineering Case #390132)================

If the MobiLink ASA client, the MobiLink synchronization server, or SQL Remote
for ASA, was started as a Windows service, the service could not have been
stopped by Window's Service Manager or the Service Creation utility. This
has been fixed.

================(Build #3133 - Engineering Case #391900)================

Intreactive SQL could have reported an 'internal error' if the Import Wizard
was used to read data from an ASCII file into an existing table, and there
were fewer columns in the file than columns in the table. This has been fixed.

================(Build #3133 - Engineering Case #391888)================

If the "Show multiple result sets" option was turned on, result sets were
not editable. This has been corrected so that result sets are now editable
with this option on.

Note that editability is still subject to the requirements that:
- All of the columns are from the same table
- If the table has a primary key, all of the primary key columns must have
been selected
- There must not be any Java columns selected

================(Build #3128 - Engineering Case #391712)================

Upgrading a version 9.0.1 database, used as a QAnywhere consolidated message
store, to version 9.0.2 using the Upgrade utility may have failed if EBF
9.0.1 1991 had been applied to the 9.0.1 software. This EBF included an an
index on the column "destination" in the QAnywhere table ml_qa_repository,
in order to improve performance. This column is no longer used in 9.0.2,
and the upgrade script attempts to drop it, but the index makes this drop
fail. This has now been fixed by dropping the index if it exists.

A work around of the problem is to do the following:

- Start the consolidated database, ensuring that there is no MobiLink server
connected to the database
- Connect to the database as a user with DBA privilege using dbisql
- Drop the offending index by executing "drop index ml_qa_repository_destination"
- Disconnect and shut down the database
- Backup the database and log file (as should be done before any upgrade)
- Upgrade the database using the dbupgrad command.

Or rebuild the database as a 9.0.2 database using the Unload utility.

================(Build #3128 - Engineering Case #391598)================

Upgrading a version 9.0.1 database, used as a QAnywhere consolidated message
store, using Unload utility may have failed. The problem would occur if
any message contained an embedded single quote in any of the message's property
names, or any of the message's property values. The code to unload QAnywhere
data has now been fixed to properly escape single quotes.

A work-around is as follows:

- Start the consolidated database, ensuring that there is no MobiLink server
connected to the database
- Connect to the database as a user with DBA privilege using dbisql
- Delete the contents of the table ml_qa_repository_props by executing "delete
ml_qa_repository_props". Commit the operation by executing "commit". The
data in this table is strictly for caching purposes and deleting the data
will have no effect on server functionality.
- Upgrade the database using the dbunload command.

================(Build #3128 - Engineering Case #391577)================

The global variables @@fetch_status, @@sqlstate, @@error, and @@rowcount
may have been set with incorrect values if a cursor's select statement contained
a user-defined function that itself used a cursor. This has been fixed.

================(Build #3126 - Engineering Case #390773)================

If the output file specified for the File Hide utility already existed, and
was more than 6 bytes bigger than the input file, the utility would have
corrupted the output file. This has been fixed. A workaround is to delete
the output file before running the File Hide utility.

================(Build #3126 - Engineering Case #386025)================

When attempting to rebuild a strongly encrypted database with the Unload
utility with the 'rebuild and replace database'command line option (-ar),
if the database was involved in replication or synchronization, the current
transaction log offset of the newly rebuilt database would not have been
set correctly. When rebuilding databases of this type, the Unload utility
will now assume that the encryption key specified with the -ek or -ep switch
is the encryption key for both the database being rebuilt, and the newly
rebuilt database. In addition, using the -ar option will now return an error
in the following situations, where previously the database would have been
rebuilt but the log offset would not have been set correctly :

1) The database is involved in replication or synchronization, but the encryption
key provided with the -ek or -ep switch is not a valid encryption key of
the database being rebuilt.
2) The database is involved in replication or synchronization, the database
being rebuilt is strongly encrypted, but the -ek or -ep switch was not provided
on the dbunload command line.

================(Build #3125 - Engineering Case #388837)================

When building a remote database from a reload file generated by extracting
from a consolidated database there could have been a failure. This would
only have occurred if there existed a publication on a subset of columns
in a table and there were also statistics on some columns in the table that
were not part of the publication. This has been fixed.

A workaround would have been to drop the statistics on the table or column
before extracting the user database.

================(Build #3119 - Engineering Case #384294)================

Interactive SQL could have reported an OutOfMemory error during, or shortly
after, executing a statement which returned a large result set. This was
most likely to occur when the "Show multiple result sets" option was turned
on, and the "Maximum number of rows to display" option was set to "All rows".
This has been fixed so that now when Interactive SQL detects that it is running
out of memory, it will show only as many rows as it can, and will display
a warning that the result set is incomplete. As a side-effect of this change,
Interactive SQL's performance has been improved when executing sequences
of statements for which result sets are returned, but never displayed. For
example, the following sequence will execute considerably faster, especially
if all of the conditions listed above are met:

SELECT * FROM T1;
OUTPUT TO t1.txt;
SELECT * FROM T2;
OUTPUT TO t2.txt;

================(Build #3113 - Engineering Case #387212)================

Attempting to use the FileDSN connection parameter to connect to a database
would have caused Interactive SQL to fail to connect, if the file was not
in the current directory and the file name contained no path information.
The error message: "The ODBC data source file could not be found" would have
been displayed. This has been fixed.

Note, this problem would affect connecting in all of the graphical administration
tools.

A workaround would be to use a qualified name for the DSN file -- either
relative or absolute.

================(Build #3113 - Engineering Case #387038)================

When connecting using the "Connect" dialog, and specifying a DSN or FileDSN
that contained a LINKS connection parameter, the connection would have failed
if the "Search network for database servers" checkbox on the "Database page"
was checked. The problem was that the "Search network" checkbox causes "LINKS=ALL"
to be added to the end of the connection string, which overrides any LINKS
information contained in the DSN or FileDSN. This has been fixed so that
now when the "ODBC Data Source name" or the "ODBC Data Source file" radio
buttons are selected on the "Identification" page, the "Search network for
database servers" checkbox is automatically unchecked. The names of the server,
database, and database file are also reset. Users are free to modify these
fields if they need to override the contents of the data source.

================(Build #3110 - Engineering Case #383145)================

After deleting rows from the end of a large trie-based index, attempting
to insert or search for a value larger than any indexed value could have
resulted in fatal I/O errors (such as reading past the end of the file),
or assertions such as 102300, or 201601. For this to have occurred, the
index had to contain at least 3 levels (more than 50,000 rows with a 2k page
size), the value being deleted had to be the last value in the index, and
the leaf page containing the entry, (as well as the leaf's parent), must
have contained only a single entry. Rebuilding (or reorganizing) the index
would have fixed the problem.
Note, dbvalid would not have couaght this problem

================(Build #3108 - Engineering Case #384070)================

The INPUT statement was ignoring the setting of the "Default_isql_encoding"
option. This has now been fixed.

================(Build #3104 - Engineering Case #384773)================

The Import Wizard would have failed with an internal error (NullPointerException)
in the following situation:

1. the import file format was set to "fixed",
2. the wizard was told to import the data into an existing table,
3. "Next" was clicked until the end of the wizard was reached,
4. then "Back" was clicked until the first page in the wizard was reached,
5. the import file format was then changed to a delimited file
6. "Next" was again clicked until the end of the wizard was reached.

This has been fixed.

================(Build #3102 - Engineering Case #384238)================

The Ping utility would have displayed a message if the server could not be
found, even if the -q option ("quiet: do not print messages") had been used.
This has been fixed, no message will now be displayed if the -q option is
used.

================(Build #3102 - Engineering Case #383942)================

When using the Lithunian language resource library, the server usage failed
to show the command line options -cc, -cr, and -cv. This has been fixed.

================(Build #3096 - Engineering Case #382677)================

When run on SuSE 9.2, the main program windows for DBISQL and Sybase Central
would open behind the console window used to start them. This has been fixed.

================(Build #3088 - Engineering Case #381327)================

Some utilities, (ie dbltm.exe, ssremote.exe, dbremote.exe and ssqueue.exe)
would have crashed if they had been given a non-existent configuration file
on their command lines. The utilities now return the usage screen.

================(Build #3034 - Engineering Case #380191)================

Under some circumstances, the iAnywhere JDBC Driver could have return the
error "Database server not found (SQLCODE -100), as a result of executing
a "STOP ENGINE" statement. This error is now ignored by Interactive SQL and
is not reported to the user.

================(Build #3033 - Engineering Case #379862)================

The Unload utility option -ar ("rebuild and replace database"), would have
deleted the old online transaction log files when done, for databases that
were used as Replication Server stable queue databases. This problem has
been fixed.

================(Build #3029 - Engineering Case #379390)================

When starting Interactive SQL, if a "Connect" dialog is opened, the dialog
is now parented to the main window. This ensures that it never opens behind
the main window, and that if the main window is activated by clicking on
its task bar icon (Windows only), the "Connect" dialog will always come to
the front.

A similar bug was also fixed where error messages could have opened behind
the main window under some circumstances.

================(Build #3028 - Engineering Case #379245)================

Attempting to unload a version 5.5.x database, containing a table with a
BIT column having a default value, would have resulted in a syntax error
in the generated reload.sql script. This has been fixed.

================(Build #3025 - Engineering Case #378613)================

The following problems related to the Import Wizard have been fixed:

1. When importing ASCII or FIXED files into an existing table, the column
data types were always being displayed as "VARCHAR" on the last page. Now,
the actual column types are displayed.

2. When importing FIXED data in an existing table, if fewer column breaks
were placed so that fewer columns were defined than appeared in the actual
table, the preview would still have shown columns for all of the columns
in the database table. This was incorrect, and clicking on these extra columns
would have caused Interactive SQL to crash. These extra columns are now no
long displayed.

3. If the Import Wizard was closed by clicking the close box, it could
still attempt to import the data. Now, clicking the close box is synonymous
with clicking the "Cancel" button.

================(Build #3013 - Engineering Case #376990)================

Executing a "START JAVA" or "STOP JAVA" statement that did not end in a command
delimiter, would have caused Interactive SQL to hang. This has been fixed.

================(Build #2552 - Engineering Case #377116)================

The reload.sql file created by the Reload utility did not double-quote the
login name for CREATE EXTERNLOGIN statements. This may have caused a syntax
error during reload. This has been fixed, the login name is now double-quoted.

================(Build #2552 - Engineering Case #361115)================

If Interactive SQL was run in batch mode with the output redirected to a
file, executing a statement that caused a warning from the server would appear
to have hung. What was happening was that Interactive SQL was waiting for
a key to be pressed to continue execution after reporting the warning, the
prompt had been suppressed. Now, warnings are displayed without prompting
when run in batch mode. Operation in windowed mode has not been changed.

================(Build #2546 - Engineering Case #375341)================

The Index Consultant may have reported 'identifier ... too long' during analysis,
and failed to continue. This could have happened if the queries being analyzed
were over tables with long names and columns with long names. This has been
fixed.

================(Build #2546 - Engineering Case #375268)================

Interactive SQL (and the ASA plug-in for Sybase Central) were displaying
UNIQUEIDENTIFIER values as hexadecimal strings, of the form "0xaabbccddeeffgghhiijjkkllmmnnoopp".
Now it displays them using the usual GUID notation: "aabbccdd-eeff-gghh-iijj-kkllmmnnoopp".

================(Build #2546 - Engineering Case #374975)================

Under some circumstances, the Index Consultant could claim a benefit for
the query or workload, even though no indexes were recommended. This has
been fixed.

Note that the same problem could have occurred in the Sybase Central Index
Consultant as well, although it is less likely. It has been fixed there as
well.

================(Build #2543 - Engineering Case #374705)================

When the Unload utility dbunload, was run with the command line option -ar
(rebuild and replace database), the old transaction log file may not have
been deleted after the database was successfully rebuilt, even if there was
no replication/synchronization involved in the original database. This problem
has been fixed.

================(Build #2542 - Engineering Case #374630)================

On Mac OS X, script files, which did not have a file extension, were not
able to be selected by the "Run Script" menu item. . A ".sql" was always
added to the file name. This has now been changed so that a ".sql" file extention
is no longer required.

================(Build #2542 - Engineering Case #374602)================

Interactive SQL could have failed with an internal error (NullPointerException)
when one of its windows was closed, and all of the following were true:
- more than one window had been opened by clicking the "Window/New Window"
menu item
- more than one window was closed in quick succession

This was was more likely to have occurred on busy machines. It has now been
fixed.

================(Build #2541 - Engineering Case #374445)================

When running the Index Consultant from Interactive SQL, the 'Show Plan with
Virtual Indexes' button would have beeen disabled on non-English platforms,
regardless of whether any virtual indexes had been recommended. The same
problem could have appeared when using the Index Consultant from Sybase Central,
if a previously saved analysis was viewed. This has been fixed.

================(Build #2538 - Engineering Case #373740)================

The Interactive SQL utility dbisql, could have become unresponsive if a statement
which returned many large result sets was executed. Interactive SQL would
have attempted to display all the result sets, and could eventually run out
of memory .

Two changes were made to address this problem:
1. The "Show multiple result sets" setting was being ignored. Now the setting
is respected, so by default, only the first result set is displayed.
2. Even if the "Show multiple result sets" setting is on, only the first
10 result sets will be displayed.

================(Build #2537 - Engineering Case #373477)================

Running the Unload utility dbunload, with both the -ar (rebuild and replace
database) and -ek (specify encryption key for new database) command line
options, would have failed when attempting to connect to the new database
with the error "Unable to open database file "<file>" -- Missing database
encryption key." The last step of dbunload -ar is to rename the log file,
but the encryption key was not specified when it should have been. This is
now fixed, te encryption key is now specified correctly.

================(Build #2537 - Engineering Case #373472)================

The Unload utility dbunload, may not have properly reloaded the contents
of the sys.syssync table for databases that were involved in synchronization.
This would have caused dbmlsync to always have been checking the last sync
status with MobiLink synchronization server, in the first synchronization
after the remote database was rebuilt. This problem is noe fixed.

================(Build #2535 - Engineering Case #373255)================

It a column name ended in a blank space, the QueryEditor would have trimed
the blank space from the end of the name, causing errors. This has been fixed.

================(Build #2535 - Engineering Case #373254)================

When the QueryEditor was opened with a query with SELECT FIRST *, the query
would have been changed to SELECT *. This has been fixed.

================(Build #2535 - Engineering Case #373179)================

If two instances of the SQL preprocessor, sqlpp run at the same time, the
generated code may be invalid. The concurrently running preprocesor's could
attempt to use the other's temporary file, and silently generate invalid
code. This problem has been fixed by including the process pid in the temporary
file.

================(Build #2534 - Engineering Case #373253)================

When a table was removed from a query using the QueryEditor, the generated
query statement was not updated to reflect the change. This has been fixed.

Note, this same problem affected the QueryEditor in Sybase Central, and
is fixed as well

================(Build #2534 - Engineering Case #372897)================

If a database consisted of more dbspaces other than just the SYSTEM dbspace,
and an attempt was made to unload the data from this database to another
database with the same structure using the Unload utility dbunload:
DBUNLOAD -d -ac <connection-parameters-to-new-database>
The Unload utility would have attempted to create a dbspace for the new
database and would have reported an error if the dbspace already existed.
Now, dbunload will not attempt to create dbspaces when reloading into another
database if the -d command-line option is used.

================(Build #2532 - Engineering Case #372485)================

When run on Linux or Solaris systems, the Interactive SQL utilities Import
Wizard could have reported an internal error (NullPointerException) if a
file was imported in a file format other than ASCII, and the "File type"
field was not set to the appropriate type. This has been fixed.

================(Build #2531 - Engineering Case #371958)================

Running the Collation utility dbcollat with the -z command line option (specify
collation sequence label), can no longer be used to write a collation definition
to a file. To get a particular collation definition, a database must now
be built with the desired collation, and then dbcollat, without -z, can be
run to extract it. The -z option will be removed in a future version of SQL
Anywhere.

================(Build #2531 - Engineering Case #371930)================

It was possible, (although rare, it was more likely on 64 bit Unix systems),
that Interactive SQL dbisql, could have crashed when it was being shut down.
This has been fixed.

================(Build #2531 - Engineering Case #371849)================

Executing long statements, which contained the CASE keyword, could have caused
the Interactive SQL utility dbisql to appear to hang. The statement will
eventually execute, but the length of time required will be unreasonably
long. This problem does not affect all statements which contained a CASE
keyword. This has been corrected.

================(Build #2531 - Engineering Case #363428)================

When run on Unix systems, the dbisql command line option -onerror (Override
ON_ERROR option) was not being recognized. This has now been corrected.

================(Build #2529 - Engineering Case #370852)================

If an ASA database, created or upgraded to version 9.0.1, was used as a consolidated
server for MobiLink with QAnywhere messaging, then attempting to upgrade
the database to version 9.0.2 using dbunload would have failed with a conversion
error on the reload of the table dbo.ml_qa_repository.

For example, if the database was qanyserv.db, then the following command
would fail:

dbunload -c "dbf=qanyserv.db;uid=dba;pwd=sql" -ar .

This problem has been fixed, but there are a couple work-arounds. Rather
than using dbunload to upgrade a database from 9.0.1 to 9.0.2 one can use
the tool dbupgrad. For example:

dbupgrad -c "dbf=qanyserv.db;uid=dba;pwd=sql"

If unload and reload of the database is required, then another work-around
is to run dbunload, and then modify the reload.sql file to remove the reloading
of rows into the tables dbo.ml_qa_repository and dbo.ml_qa_repository_props.
These rows represent QAnywhere messages, so removing them will cause the
reloaded database to lose those messages.

================(Build #2529 - Engineering Case #370726)================

The Interactive SQl utility dbisql, would have failed to process statements
in a file read by the READ command if the file used UTF8 encoding and the
file started with an endian indicator (typically 0xef 0xbb 0xbf on Windows).
Now the endian indicator is handled appropriately.

================(Build #2529 - Engineering Case #370724)================

The Unload utility dbunload, would have silently placed old transaction log
files into the root directory, when the command line option -ar (rebuild
and replace database) was used and no log directory was specified, for databases
that were involved in synchronization/replication using RepAgent. Now, if
this situation occurs, the old transaction log file will be placed in the
log directory of the database.

================(Build #2529 - Engineering Case #370567)================

The Unload utility dbunload, may have crashed if the command line option
-ar (rebuild and replace database) was used with a database that had no online
transaction log. This problem has been fixed.

================(Build #2529 - Engineering Case #369977)================

The Interactive SQL utility dbisql, could have crashed if its window was
closed while an INPUT or OUTPUT statement was executing, and it had been
launched from Sybase Central. Now, clicking the "File/Exit" menu item when
a statement is executing will cause the same "Are you sure?" prompt as would
occur when clicking the window's close button.

================(Build #2529 - Engineering Case #369842)================

On Windows systems, the Data Source utility dbdsn, would not have listed
all of the data sources if the total length of all of the names exceeded
about 1024 bytes. This has been fixed.

================(Build #2529 - Engineering Case #369539)================

If the engine name in the OS charset (ie ENG= )was not identical to the engine
name in the database charset, then dbunload -an could have failed with an
error such as "SQL Error: Invalid database server command line". This has
now been fixed.

================(Build #2529 - Engineering Case #369516)================

The Interactive SQL utility dbisql, could have prompted for a seemingly unnecessary
second log in, if all of the following were true:
- DBISQL was running as a windowed application
- not all the connection parameters were supplied on the command line, or
in the SQLCONNECT environment variable, to complete the connection
- the "Connect" dialog was opened automatically when DBISQL started
- the connection was to a slow server

This has been fixed.

================(Build #2529 - Engineering Case #369491)================

When running on Unix systems, the Interactive SQL utility dbisql, would have
displayed the usage message when a full path to a SQL script file was given.
The leading '/' was was being interpreted as a command line switch on. This
has been fixed.

================(Build #2529 - Engineering Case #369170)================

When connected via jConnect, dbisql could have incorrectly reported that
the connection to the server was lost if a statement which caused a data
conversion error was executed, e.g. "select STRTOUUID ('12345678-1234-5678-9012-123456789012')".

Now, the data conversion error will be reported, but an error that the connection
has been closed will not.

================(Build #2529 - Engineering Case #369150)================

If the server command line passed to the Spawn utility dbspawn contained
the @filename option, dbspawn would have expanded the contents of the file
and then spawned the server. This meant that the server command line would
have included the contents of the file. If the file contained certificate
passwords or database encryption keys, they would then be visible through
the 'ps' command or equivalent. This has been changed, dbspawn will no longer
expand the @filename parameter.

================(Build #2529 - Engineering Case #369145)================

When launched from Sybase Central, dbisql would have connected to the wrong
database, if Sybase Central was connected to two (or more) databases and
a dbisql session had already been opened and was connected to one of the
databases. Subsequent attempts to launch dbisql from Sybase Central would
have always connected to whatever database the initial dbisql session was
connected. Now, dbisql will reliably connect to the appropriate database.

================(Build #2529 - Engineering Case #368825)================

If a datasource name was specified on the command line that contained an
encrypted password, dbisql would not have immediately connected to the database,
but would have first displayed the "Connect" dialog. Now an attempt is made
to connect immediately, without first displaying the "Connect" dialog.

================(Build #2529 - Engineering Case #368348)================

Starting dbisql with the "-f" command line option to load a graphical plan
file, could have caused it to hang on startup. The symptom was that the splash
screen would open, but not close, and the main window would not open. This
problem has now been fixed.

================(Build #2529 - Engineering Case #368170)================

When executing a READ statement with parameters, if the file being executed
did not contain a PARAMETERS statement, but contained an identifier within
braces, dbisql could have reported an internal error. This has been fixed.

================(Build #2529 - Engineering Case #368164)================

The Database Tools library has been reduced in size by approximately 272K.

================(Build #2529 - Engineering Case #368023)================

Attempting to run dbconsol.nlm and connect to a server would have caused
an abend. This has been fixed.

NOTE: 6.x versions of dbconsol on all platforms fail to connect to servers
after version 9.0.0 1223. This is still the case, and there is no workaround.

================(Build #2529 - Engineering Case #367549)================

The Interactive SQL utility dbisql, could have displayed the wrong table's
data when launched from Sybase Central. This would have happened if the "View
Data in Interactive SQL" menu item for a table had previously been clicked,
and the resulting Interactive SQL window was left open. When trying to view
the data for a different table, the new Interactive SQL window showed the
data for the previous table, not the one selected. This has now been fixed.

================(Build #2453 - Engineering Case #372220)================

When running on NetWare systems, the ASA server would have stopped executing
scheduled events and automatic checkpoints, about 66 hours after the ASA
server was started. This has been fixed.

================(Build #2452 - Engineering Case #370333)================

If a version 8.x database was being used as a MobiLink Consolidated database,
and at least one remote user had successfully synchronized multiple publications,
attempting to rebuild using dbunload would have failed when the reload.sql
file was run against an empty database. A primary key violation on the ml_subscription
table would have occurred. This has now been fixed. Note that the problem
did not occur when using the -an or -ar dbunload command line options.

================(Build #2452 - Engineering Case #370180)================

If a version 8.x database was being used as a MobiLink Consolidated database,
and at least one remote user had successfully synchronized multiple publications,
then dbupgrad would have failed to upgrade the database to version 9.x. The
Upgrade utility dbupgrad would have reported a primary key violation on the
ml_subscription table, or in some circumstances the server could fail an
assertion. This has been fixed.

================(Build #2452 - Engineering Case #367965)================

On Unix systems, the Data Source utility dbdsn uses the ODBCINI, ODBC_INI,
ODBCHOME, and HOME environment variables when trying to find the .odbc.ini
file, but if no such file was found, it was always created in the user's
home directory. This has been fixed - the environment variables listed above
will now be useed when creating the file.

MobiLink - Charset Conversion (UNILIB)

================(Build #2529 - Engineering Case #366503)================

When using the .NET scripting, Character fields moving to or from the database
may have been corrupted if they contained non-ascii characters. These fields
will now be bound as Unicode. Current user code can remain unchanged and
should continue to work.

MobiLink - Java Plugin for Sybase Central

================(Build #3289 - Engineering Case #427005)================

If the Gateway wizard or Property sheet was used to create or modify an SMTP
or UDP gateway, then an invalid "ack_timeout" property would have been set.
This has been fixed so that the correct property "confirm_timeout" is now
set.

This problem would also have prevented the MobiLink server from starting.
This has also been fixed by allowing the MobiLink server respect the "ack_timeout"
setting as an alias to the "confirm_timeout" property. If both property name
are used at the same time, the value associated with "confirm_timeout" will
take effect.

================(Build #3136 - Engineering Case #390955)================

Applying the 9.0.2 English Maintenance release to a 9.0.1 installation would
not have upgraded the MobiLink plug-in if Mobilink itself was not installed.
This would then have left the plug-in not matching the Sybase Central viewer
and ASA connection class.

The symptom of this failure is a stack trace when attempting to connect
from the MobiLink plug-in. The exception is due to this method not being
found, (the right function name, but the wrong parameter signature):

com.sybase.asa.logon.LogonDialogFactory.create( )

Subsequent applications of EBFs also did not update the plug-in and thus
failed to correct the problem. This has now been fixed, so that any EBF later
than build 3136 will upgrade mlplugin.jar.

================(Build #3123 - Engineering Case #389538)================

If an attempt to connect to a database with the MobiLink plug-in failed,
then Sybase Central would have crashed. The plug-in was assuming that if
a SQLException was thrown from JDBCDrivers.connect(), then the value returned
from SQLException.getMessage() was always non-null, which was not always
the case. This has been corrected.

================(Build #3032 - Engineering Case #375586)================

The following Connection events were missing from the combo box in the Connection
Script wizard: authenticate_parameters, begin_publication, end_publication,
and modify_error_message. This meant that it was not possible to use Sybase
Central to create scripts for these events. These events have now been added.

MobiLink - Monitor

================(Build #3380 - Engineering Case #435511)================

The MobiLink Monitor could have shown invalid counts for upload-only or download-only
synchronizations, or possibly have shut down unexpectedly. This has been
fixed.

================(Build #2529 - Engineering Case #370914)================

The MobiLink Monitor was not able to connect to the synchronization server
via HTTPS. This has been fixed.

MobiLink - QAnywhere client

================(Build #3913 - Engineering Case #605417)================

The QAManagerFactory.getInstance() method of the QAnywhere .NET client would
have thrown the exception System.DllNotFoundException when the native library
qany9.dll or qany10.dll was missing. This exception may have been unexpected
by a QAnywhere application, and has now been fixed. A QAException is now
thrown in this situation, with ErrorCode 1000 (QAException.COMMON_INIT_ERROR)
and Message containing the System.DllNotFoundException.

================(Build #3699 - Engineering Case #538346)================

When the QAnywhere Agent was started for the first time, and another the
qaagent to fail to start with an error similar to:
InternalError: User 'DBA' has the row in 'ml_qa_global_props_client' locked
Source statement: CREATE SYNCHRONIZATION SUBSCRIPTION TO ml_qa_user_group.ml_qa_repository_pub
FOR "sender-rules" OPTION sv='ml_qa_2'

This has been fixed by now having the QAnywhere Agent acquire exclusive
locks on tables involved in the publication, before creating the synchronization
subscription.

================(Build #3683 - Engineering Case #534005)================

If the QAnywhere client (qaagent) was started using a rules file for its
policy, then shut down and restarted with a syntax error on the command line,
in some situations an error such as
"SQL statement failed: (-265) Procedure 'ml_qa_sync_rule_0' not found"
would have occurred in the MobiLink client (dbmlsync). This has been fixed.

================(Build #3654 - Engineering Case #496969)================

When the QAnywhere Agent was running on a device that was not connected to
a network, each time a QAnywhere application queued a message the CPU usage
increased slightly. This has been fixed so that now, when the device is
not connected to a network, queueing a message uses about the same amount
of CPU regardless of whether or not the QAnywhere Agent is running. Moreover,
the required CPU usage stays constant as messages are queued.

================(Build #3638 - Engineering Case #494356)================

A QAnywhere .NET application could have hung if a QAManager API method was
interrupted by an exception in one thread and another thread subsequently
called a method on the QAManager that was interrupted. This has been fixed.

================(Build #3620 - Engineering Case #490862)================

A QAnywhere .NET application could have crashed with a memory access vio;ation
when terminating. This was due to a race condition, which has been fixed.

================(Build #3579 - Engineering Case #484272)================

The QATransactionalManager class would have failed to re-receive a message
with large content (exceeding MAX_IN_MEMORY_MESSAGE_SIZE in size) after it
was received once and a rollback was done. This problem applied to the C#,
Java and C++ QATransactionalManager classes. This has now been fixed.

================(Build #3569 - Engineering Case #480759)================

When making a call to a QAManager with the DBF and AutoStart connection parameters,
the database server would not have been autostarted. Instead, a -101 error
"not
connected" would have been logged by the QAManager, but was not reported
back to the application. It should be noted that a QAManager will autostart
the database server when the Open method is called. The issue was that when
the database server was shut down after Open had been called, then subsequent
QAManager operations would have failed because the database connection had
been terminated, but the error codes returned to the application do not indicate
that the connection to the database was bad, thus not allowing the application
to Close and Open the QAManager to recover from the error. This has been
fixed. If the ErrorCode of a QAException is greater than or equal to 2000,
then the error means the same as ErrorCode - 1000, and also that a database
connection failure has occurred (ie. SQL Anywhere native code -101). When
a database connection error is detected, it is possible to re-Open a QAManager
without recreating it and setting its properties and message listeners again.
This is done by calling Close() then Open() again. Note that the properties
of the QAManager cannot be changed after the first Open() and subsequent
Open() calls, and must supply the same acknowledgement mode.

================(Build #3499 - Engineering Case #469145)================

If the QAnywhere Agent is started on Windows CE with a spacey path in the
startline connection parameter, for example:
qaagent -c "...;startline=\Program Files\Sybase\ASA9\dbsrv9 -o dbsrv.txt
-c 20m -gd all -gp 4096 -n qanywhere -gk all -qw -gn 10"
then it would have failed to start the database server with the error "InternalError:
Unable to start database server". A problem with passing double quotes in
the connection string has been fixed.

================(Build #3498 - Engineering Case #469002)================

When run on Windows CE, the reserved stack sizes for all threads in the QAnywhere
agent, the Listener and the MobiLink client have been changed to be as follows:
qaagent.exe: 64 KB
dblsn.exe: 64 KB
dbmlsync.exe: 128 KB

Previously, 1MB per thread of address space was reserved, while only a portion
was actually allocated, or "committed".

================(Build #3498 - Engineering Case #468735)================

If a QAnywhere message in the server database with an expiration date, was
synchronized down to a client device before it had expired, the message would
not have transitioned to an expired state, and hence would not have been
deleted by the default server delete rule. This has been fixed.

Note that a QAnywhere message in the server database with an expiration
date, that is not delivered to the client device before it expires, will
also transition to an expired state and be deleted by the default server
delete rule. This was the case before this change.

================(Build #3494 - Engineering Case #467246)================

When there were a large number of messages in the message store that were
ready for transmission (eg. 200 12KB messages), and the QAnywhere Agent was
started on a Windows Mobile 5 device, the synchronization process would have
consumed 100% CPU for a significant period of time (eg. 1 minute). Further,
if the upload failed after it had started, for whatever reason, each subsequent
synchronization would have consumed CPU for a longer period each time. This
performance problem has now been significantly alleviated so that synchronizations
with QAnywhere will not get progressively longer after upload failures.

================(Build #3492 - Engineering Case #468031)================

Under some conditions, the qastop utility would have failed to shutdown the
QAnywhere Agent. When this occurred, qaagent would hang and the process
would have to be terminated. This has been fixed.

================(Build #3492 - Engineering Case #467712)================

A .NET application would have crashed when trying to send a text message,
if the QAManager is closed. Problems with detecting that message repository
objects were open have been corrected. Now, the message: "The QAManager
is not open." (error code 1021) will be returned.

================(Build #3492 - Engineering Case #466169)================

The method QAManagerBase.GetQueueDepth() could have returned a queue depth
of 0 when there were untransmitted outgoing messages in the message store.
This was due to a race condition between the GetQueueDepth method and the
message transmission process in the QAnywhere Agent. This has been fixed
by changing the behaviour of GetQueueDepth so that uncommitted outgoing messages
are included in the queue depth count.

================(Build #3471 - Engineering Case #462912)================

When a QAnywhere application had an open QATransactionalManager, delete rules
always failed in the QAnywhere Agent. The error from the database server
when executing delete rules would have been: ** ERROR conn: 5 code: -210
"User 'DBA' has the row in 'ml_qa_global_props_client' locked". This has
been fixed. Delete rules will now delete messages that satisfy the delete
rules, skipping over messages that are in an open transaction.

================(Build #3471 - Engineering Case #461846)================

It was possible for QAnywhere applications to get into a state where calls
to GetQueueDepth would have taken an usually long time to return, and eventually
have thrown a QAException "error getting queue depth". If a device crashed,
or was powered off while the QAnywhere Agent was marking messages to be uploaded,
a flag was left set that GetQueueDepth checked. This problem has been fixed
by adding code to reset the flag in appropriate circumstances.

================(Build #3454 - Engineering Case #455922)================

In some timing-sensitive circumstances the QAnywhere client could have returned
incorrect results. Calling QAManagerBase.GetMessageTimeout may have returned
NULL if the queue contained unread messages; and an incorrect queue depth
value may have been returned by calls to QAManagerBase.GetQueueDepth. These
problems have been fixed.

================(Build #3432 - Engineering Case #451555)================

The QAnywhere agent was not setting the store property ias_Network.Adapter
correctly when the device is on ActiveSync. This has been fixed so that
ias_Network.Adapter is now set to 'RndisFn1' when the device is on ActiveSync.

Note that the Remote-NDIS Host "IP address" and "Default gateway" properties
must be configured on the Windows CE device in order for name resolution
to work properly when connected on ActiveSync.

================(Build #3395 - Engineering Case #445042)================

On Windows CE systems, the MobiLink client could have crashed when the QAnywhere
agent was shut down. This has been fixed.

================(Build #3390 - Engineering Case #443798)================

When calling the GetQueueDepth() method, it could have returned inconsistent
values for the number of messages remaining in the queue. This has been fixed.

================(Build #3381 - Engineering Case #443455)================

When the QAnywhere agent was idle, that is not performing message transmissions,
there was a small spike in the CPU usage every 10 seconds. This has been
addressed by increasing the interval at which the message store is polled
to 15 minutes. A signaling mechanism is used to trigger a message transmission
when certain events happen in the message store, such as a message being
put on a queue, or a push notification being received.

================(Build #3381 - Engineering Case #439903)================

When the QAnywhere agent was running and the device was connected to a network
(e.g. wired, wireless, etc.), the device seemed to dramatically slow down.
For any other combination of QAnywhere agent running and network connectivity,
the device performance was fine. This has been addressed by a performance
optimization in the upload part of the QAnywhere data synchronization process.
The performance slowdown occurred when the QAnywhere agent was performing
repeated data synchronizations, such as when the device is connected, the
policy is automatic, and an application is adding messages to a queue at
a high frequency. This performance optimization should decrease the time
spent processing the upload by about 33%. An approach worth considering in
this scenario is to use transmission rules, or ondemand policy, to batch
several messages puts before triggering a message transmission to the server.

================(Build #3371 - Engineering Case #441267)================

There was no iAnywhere.QAnywhere.Client assembly for .NET Framework 2.0 in
SQL Anywhere 9.0.2. One has now been added.

================(Build #3353 - Engineering Case #438514)================

The MobiLink Listener (dblsn.exe) may have appeared to hang indefinitely,
resulting in the necessity to kill it, while shutting down the QAnywhere
Agent. The QAnywhere Agent hangs indefinitely waiting for the MobiLink Listener
to shutdown. This would have happened when the QAnywhere Agent was shut down
soon after starting, after dblsn had been launched and before dblsn was ready
to receive a shutdown command. This has now been fixed.

================(Build #3337 - Engineering Case #436098)================

Calling the QAManager Close() method could have taken up to 1 minute to return.
The background receiver thread could have been interrupted, resulting in
a cancel request which took a minute to timeout. Now the cancel request is
retried until it succeeds, so the Close() method will always complete in
a reasonable amount of time.

================(Build #3330 - Engineering Case #434808)================

A QAnywhere message listener could have been starved of messages waiting
to be delivered. If two or more listener were on a QAManager, and messages
were put in the queue of one of the listeners as fast as it could process
them, the other listeners would not have received any messages, even if there
were messages in its queue. This has been fixed so that messages are delivered
to listeners one at a time, with a round-robin algorithm.

================(Build #3329 - Engineering Case #434814)================

A QAnywhere application could get into the situation where an excessive amount
of CPU was being used. This would typically happen on Windows CE devices
when three or more QAManagers with message listeners were opened and started.
The problem can be avoided by increasing the database server's maximum number
of concurrent requests (using the -gn option). For a QAnywhere application,
the rule of thumb for the -gn value for the database server is: 3 * (number
of QAManager's ) + 2. The "+ 2" is for the qaagent and dbmlsync. This has
been corrected by adding a heuristic check to the QAManagerBase.Open method,
so that it will fail when it detects that the number of active requests in
the database server is too close to the maximum number of concurrent requests
for that server.

================(Build #3329 - Engineering Case #433696)================

On Windows CE, sending messages to a queue could have taken longer and longer
over time. This would have occurred when messages were not received by a
receiver, or transmitted from the message store. This has been fixed so
that the time taken to now send a message to a queue stays fairly constant,
even as messages build up in the queue.

================(Build #3298 - Engineering Case #429169)================

The message listeners in QAManagerBase were polling the message store for
messages. This unnecessarily consumed CPU resources. This has been changed
so that the background receiver thread now efficiently waits for a message
to be put on a queue before retrieving it and delivering it to the message
listener.

Note that the behaviour of the (foreground) blocking GetMessage methods
has not changed - these have always efficiently waited for a message to be
put on a queue.

================(Build #3297 - Engineering Case #429167)================

When a QATransactionalManager had an open transaction, another QAManager
would have blocked in the GetQueueDepth methods. This has been fixed so
that the GetQueueDepth methods do not block.

================(Build #3297 - Engineering Case #429149)================

The implementation of message listeners in QAManagerBase would have continued
to loop as long as it was receiving messages (which it would have continued
to do, as the same message would have continually been rolled back and subsequently
received) and did not intermittently check to see if a request had been issued
to stop or close the manager. This infinite loop would have occurred if
the message store property ias_MaxDeliveryAttempts was not set, or was set
to -1, and the processing of a message in a message listener caused an exception
to be thrown which was not caught. This has been fixed so that now a QAManager
in such a state can be stopped or closed.

================(Build #3291 - Engineering Case #427856)================

When the QAnywhere Agent was started by an application, and the application
then started sending and receiving messages immediately, it was possible
that the QAnywhere Agent would not complete its startup, and issue the following
error:

InternalError: User 'ml_qa_user' has the row in 'ml_qa_repository_content_client'
locked
Source statement: CREATE SYNCHRONIZATION SUBSCRIPTION TO ml_qa_user_group.ml_qa_repository_pub
FOR "02600601376" OPTION sv='ml_qa_2'

The problem was that messaging cannot begin until the synchronization subscription
is created in the message store, which cannot happen until the message store
ID is known. This has been fixed so that the message store property "ias_StoreID"
is set by the QAnywhere Agent when the message store ID has been initialized.
A QAnywhere application can query this message store property and begin sending
and receiving messages when the property value is defined.

================(Build #3291 - Engineering Case #427834)================

The QAnywhere Agent command line option -q (quiet) did not work well on Windows
CE. In particular, the database server was not started in quiet mode so the
server window would pop up briefly before being minimized. This has been
fixed so that when the the QAnywhere Agent is run with the -q option, the
database server is started with -qi on Windows CE, and with -qw on Windows,
as well..

================(Build #3291 - Engineering Case #425121)================

The call to MessageBox.Show() has been removed when there is an exception
thrown inside the QAnywhere Message Listener. Calling MessageBox.Show()was
not desired behaviour when in a transactional context environment. For the
.NET Compact Framework and the .NET Framework, exceptions that occur in a
message listener are now logged to the QAManager log file, rather than shown
in a MessageBox. The QAManager log file is set with the "LOG_FILE" QAManager
configuration property. It is recommended for all QAnywhere .NET applications
to catch ALL exceptions in the message listener delegate, and deal with them
appropriately.

================(Build #3286 - Engineering Case #425125)================

If an exception was thrown inside the message listener, the exception text
was displayed in the MessageBox.Show() dialog, (see Engineering case 425121
for a change in this behaviour), and the transaction was rolled back. However,
the message which caused the exception was then put back on the queue and
was then received by the message handler. If the message handler itself then
threw an exception, this could have resulted in an infinite loop. There was
no method of setting a maximum retry to interrupt this process. So a new
message store property "ias_MaxDeliveryAttempts" has been added. When this
property is set to a positive integer n by a QAnywhere application, eg. mgr.SetIntStoreProperty(
"ias_MaxDeliveryAttempts", 5 ), the QAnywhere client will attempt to receive
an unacknowledged message up to n times before setting the status of the
message to unreceivable. If the property "ias_MaxDeliveryAttempts" is not
set, or is negative, the QAnywhere client will attempt to receive messages
an unlimited number of times, which was the behaviour before this change.
Also, there is now an integer message property "ias_DeliveryCount" that is
set by the QAnywhere client in a message each time it is delivered to the
application by a get method. This property is the number of times that the
message has been delivered to the application, without being acknowledged.

================(Build #3269 - Engineering Case #421924)================

With the QAnywhere C# API, calling the Start() method on a QAManager that
had been previously Started and Stopped, could have caused the application
to hang, or fail to terminate cleanly. This has been fixed.

================(Build #3264 - Engineering Case #420924)================

After calling the C# API QAManager Close() method, future calls to the QAManager
did not throw exceptions as expected. This has been fixed. They now throw
an exception as documented.

================(Build #3262 - Engineering Case #420743)================

The QAnywhere Agent could have taken several minutes to shutdown after the
Shutdown button is clicked, if the MobiLink server was unreachable. This
has been fixed. Now, the QAnywhere Agent shuts down immediately when the
Shutdown button is clicked.

================(Build #3261 - Engineering Case #420752)================

When run on Microsoft CE devices, the QAnywhere Agent could have crashed
when invoked with command line parameters in a file, ie. qaagent @file.
This has been fixed.

================(Build #3253 - Engineering Case #418929)================

The QAnywhere .NET assembly for Compact Framework 2.0 was not strongly named.
This has been fixed. It is now strongly named with the same public key as
the QAnywhere .NET assembly for Compact Framework 1.0.

================(Build #3239 - Engineering Case #416223)================

The literals TRUE and FALSE can be used in client-side transmission rules,
however, the client-side rule processing code was treating these literals
no differently than a message property reference. Hence, unless the message
being evaluated happened to have a property TRUE or FALSE, TRUE or FALSE
was being evaluated to NULL. That is, if there was a rule "myboolprop = TRUE",
where myboolprop was a boolean typed message property, the rule would never
evaluate to TRUE. The work-around is to use the literal 1 in place of TRUE
and 0 in place of FALSE. This has now beeen fixed so that TRUE and FALSE
are correctly recognized as boolean literals.

================(Build #3225 - Engineering Case #410139)================

Attempting to send a message using QAnywhere Central while connected to a
client message store did not work. Right-clicking the client message store
tree icon, and selecting "Send Message", would have opened a dialog for authoring
a message, but nothing would have happened when clicking the "Send" button
to send the message. The dialog would not have gone away, and the message
would not have been sent. This has now been fixed so that messages can be
sent as normal.

================(Build #3224 - Engineering Case #410007)================

The QAManagerBase.GetQueueDepth methods could have returned incorrect values
for the QueueDepthFilter.ALL and QueueDepthFilter.OUTGOING arguments. These
methods may not have counted outgoing messages that were in the process of
being uploaded. If the upload then failed, the GetQueueDepth methods could
have indicated fewer outgoing messages in the queue than were actually there.
This has been fixed so that now outgoing messages are counted until they
have been successfully transferred to the server.

================(Build #3224 - Engineering Case #409857)================

The QAnywhere Agent incremental upload option (-iu) did not work well when
the network connection was lost during an upload. If there was a large amount
of message data to be uploaded, and the network connection was lost any time
before all of the data was committed on the server, all of the data would
have been re-uploaded in the next synchronization with the server. This has
been fixed so that now QAnywhere synchronizes approximately the amount of
data specified by the incremental upload option in the upload of each synchronization.
This means that if the network connection is broken, the messages that were
uploaded in successful synchronizations before the break do not have to be
re-uploaded in the next synchronization. This option may also be set by a
QAnywhere application using the message store property "ias_MaxUploadSize".

Note that at least 1 message will be in each upload (if there are messages
queued) and the QAnywhere Agent does not split messages. Therefore, the
incremental upload size is an approximation, and it will be a poor approximation
if there is a message to be uploaded that is many times larger than the incremental
upload size.

Example: The default incremental upload size is 256K, so if the average
message size is 256 bytes and the maximum message size is not too large,
then approximately 1000 messages will get transferred to the server per synchronization.
The synchronizations will continue until all queued messages are transferred
to the server, or until the connection is broken. The batches of messages
that were successfully transferred to the server will not be transferred
again.

================(Build #3221 - Engineering Case #408490)================

The MobiLink client would have leaked approximately 0.5 Kb, plus 0.5 Kb for
each user connection open to the database, for each synchronization. This
leak was small enough that it would only cause a problem if dbmlsync performed
many synchronizations between the time it was started and when it was shut
down (for example if a frequent schedule option was being used and dbmlsync
was left running for a long time). This has now been fixed.

================(Build #3218 - Engineering Case #409233)================

The QAnywhere Agent could have transferred unnecessary data during synchronizations,
causing message transfer to be slightly slower. This has been fixed.

================(Build #3202 - Engineering Case #406557)================

The QAnywhere client library's GetMessage methods could have returned inconsistent
data when there were at least two originating clients sending messages to
one receiver client,
and there was a high rate of messages being delivered to the receiver client,
resulting in several synchronizations per second. In this scenario it was
possible that message properties or content obtained from a given QAMessage
through the QAnywhere client API methods, may not have been correct, even
though the messages were stored correctly in the message store database.
This has been fixed.

================(Build #3199 - Engineering Case #405588)================

The QAnywhere Agent could have caused the MobiLink client to crash under
the following circumstances:
- a failover server was specified with a second -x option,
- the communication address of the failover server [as in -x tcpip(<communication
address>)] was longer than 255 characters, and
- communication with the primary server failed, causing an attempt to synchronize
with the failover server.

This has been fixed. The problem is related to Engineering Case 405360.

================(Build #3190 - Engineering Case #404331)================

The QAnywhere client library could crash in any of these methods: Commit()
or Rollback() of QATransactionalManager; Acknowledge(QAMessage msg) or AcknowledgeUntil(QAMessage
msg) or AcknowledgeAll() of QAManager. This has been fixed.

================(Build #3189 - Engineering Case #403958)================

Changes for Engineering Case 401757 caused the QAnywhere Agent to be very
slow during the upload phase of a message transmission if the message store
contained many messages. This has been fixed so that the time for the upload
phase is now similar to what it was before.

================(Build #3178 - Engineering Case #402084)================

The QAnywhere Agent could have used incorrect server information when it
was started on a fresh message store with option -x tcpip(host=serverA);
or when it was shut down and restarted on the same message store with option
-x tcpip(host=serverB). In the second case, the QAnywhere Agent would have
incorrectly transmited messages to serverA. This has been fixed. Now when
the QAnywhere Agent is restarted as in the second case, only serverB is used
for message transmissions.

================(Build #3167 - Engineering Case #401863)================

The QAnywhere Agent default delete rule did not completely clean up messages
from the message repository. This has been fixed.

================(Build #3167 - Engineering Case #401757)================

The QAnywhere Agent stopped transmission of all messages when a GetMessage
or PutMessage was called on a QATransactionalManager. Message transmission
was being suspended until a Commit or Rollback was done on that QATransactionalManager.
This has now been fixed so that the transmission of committed messages or
messages sent by a (non-transactional) QAManager will proceed, independent
of the status of uncommitted messages by any specific QATransactionalManager.

================(Build #3144 - Engineering Case #396173)================

If the QAnywhere Agent was started with a failover server defined (ie. there
was more than 1 "-x" option on the command line), and the device lost network
connectivity to all servers, and then the device recovered network connectivity
to at least one of the servers, queued messages would not have been transferred
to a sever. This has been fixed so that now, when network connectivity is
recovered, queued messages will be transferred to the primary server (if
it is reachable) or an alternate server, as appropriate.

================(Build #3141 - Engineering Case #394896)================

If the QAnywhere Agent was started with a window class name (using the -wc
option), that was the same as the message store ID (the -id option), it would
not have shutdown properly with either the Shutdown button on the UI, or
with qastop. This has been fixed.

================(Build #3138 - Engineering Case #394220)================

A message transmission rule with an equality expression that had the right-hand
operand missing (eg. a= ) would have caused the QAnywhere Agent to crash
when parsing the transmission rule file. This has been fixed so that a syntax
error is now flagged.

================(Build #3136 - Engineering Case #393817)================

If a QAnywhere application had received a message with a QATransactionalManager,
but had not committed or rolled back the transaction, and it then used another
QAManager to send a response to the message it had received, it was very
likely that the call to PutMessage would have blocked in a database deadlock
situation. This has been fixed so the PutMessage will now queue the message
without blocking.

================(Build #3136 - Engineering Case #393809)================

In a QAnywhere .NET application running on Windows CE, if a message listener
threw an exception, or a QAException was thrown by the QAnywhere library,
asynchronous message receiving would have stopped. This has been fixed.
Now a message box with the exception details is displayed and asynchronous
message receiving continues after clicking OK. To avoid the message box,
the application's message listener should handle any exceptions that occur
and return normally to the QAnywhere library.

================(Build #3135 - Engineering Case #393489)================

A message that should have expired would sometimes not expire on the client.
If the message was part of a previous failure to transmit messages to the
QAnywhere server (for example, network connectivity was lost) before the
message was scheduled to expire, then the message would not have expired.
Subsequently, when connectivity and message transmission with the QAnywhere
server was resumed, the message that was scheduled to expire would have been
transmitted to the server. Likely, the server would expire the message at
this stage, however, it was possible that the message would be transmitted
onwards to the target client before the server had a chance to expire it.

QAnywhere makes no guarantees that a message scheduled for expiration will
not be delivered, however, QAnywhere makes a best attempt to expire messages
as they are scheduled. In this case, QAnywhere missed an opportunity to expire
messages. This has been fixed so now, if a message was part of a previous
failure to transmit messages, that will not stop the subsequent expiring
of the message.

================(Build #3131 - Engineering Case #392323)================

If the QAnywhere Agent was run with the command line option -si to initialize
the message store database, and a message store ID was specified with the
option -id, the message store ID was not set until the QAnywhere Agent was
invoked without the -si option.

This problem would have been noticed in the following scenario:
When the QAnywhere Agent was starting up while messages were being put into
the message store, the QAnywhere Agent would have failed to start with the
error:

E. 05/27 09:12:50. InternalError: User 'QA_USER' has the row in 'ml_qa_repository_content_client'
locked

As well the problem would have occurred when the QAnywhere Agent was used
to initialize a message store with store ID 'xyz' (-si -id xyz), and then
the QAnywhere Agent was started with a different store ID (-id abc), the
following error should have been given, but was not:

E. 05/31 12:05:29. QAnywhere Agent cannot be started with a client message
store ID different than xyz with this message store.

This has been fixed so that now the message store ID is set, if it is specified,
when the message store is initialized.

================(Build #3114 - Engineering Case #387508)================

Message transmission rules are specified using the -policy <filename> command
line option of QAnywhere Agent. If the last rule in the rules file did not
end in a newline the rule was ignored. This is now fixed such that the last
rule no longer needs to be terminated by a newline.

================(Build #3106 - Engineering Case #386024)================

The method QATextMessage::readText() is used to read the text from a QATextMessage
in pieces. If readText() was called when there was no more text, it would
have returned an empty string. The next call to readText() would then have
returned -1, indicating no more text. This has been fixed, now readText()
returns -1 as soon as there is no more text, as documented.

================(Build #3106 - Engineering Case #386022)================

Calls to the method QABinaryMessage.ReadString() would have returned an empty
string when used to read a string of longer than 255 characters, if the string
was originally written with WriteString(). This has been fixed, now string
data types of length up to 32767 characters can be written and read from
a QABinaryMessage, as documented.

================(Build #3106 - Engineering Case #386004)================

The method QAManagerBase::getLastError() could have return an error code
indicating an error, even after the method call was successful. This would
happen after a previous method call that failed. This has now been fixed,
getLastError() returns an error indication, if and only if the prior method
call failed.

================(Build #3044 - Engineering Case #381729)================

In relatively rare circumstances, the QAnywhere .NET client could have thrown
the following exception:

System.NullReferenceException: Object reference not set to an instance of
an object.
at Microsoft.Win32.Win32Native.CopyMemoryAnsi(StringBuilder pdst, IntPtr
psrc, IntPtr sizetcb)
at System.Runtime.InteropServices.Marshal.PtrToStringAnsi(IntPtr ptr)
at iAnywhere.QAnywhere.Client.QATextMessage.get_Text()

when reading the Text property of QATextMessage. This has been fixed.

================(Build #3034 - Engineering Case #378245)================

The QAnywhere Agent would have needlessly directed the MobiLink client (dbmlsync)to
begin a synchronization process even though the MobiLink server was unreachable.
This would have resulted in dbmlsync scanning the transaction log, and then
failing the synchronization because it could not to connect to the server.
The problem was only noticeable in cases where the transaction log scanning
process was expensive and the server went offline and the transmission policy
was scheduled. In this case, dbmlsync would cause high CPU usage and then
fail to synchronize.

This problem has been fixed by doing a periodic check that the MobiLink
server is reachable. This check is done only after a connection failure has
occurred. Once the server is reachable again, the check is discontinued.
The QAnywhere Agent will not direct dbmlsync to begin the synchronization
process if it is known that the MobiLink server is unreachable.

================(Build #3028 - Engineering Case #379378)================

The QAManager.recover() method allows recovery of unacknowledged messages
so that they can be re-received. When a receiving QAManager called recover(),
re-received a message, then acknowledged the message, the 'received' status
of the message was not being synchronized back to the originator of the message.
The message repository used by QAManager keeps a list of unacknowledged message
IDs. This list was not being cleared by the recover() method, so the message
ID of a recovered message was added to this list twice. The fix was to have
the recover() method clear the list of unacknowledged message IDs.

================(Build #3028 - Engineering Case #379374)================

The QAnywhere Agent sends special system messages to a special "system" queue
that contains information about the network status of the client. These messages
were not getting deleted from the client message repository, even after they
expired. This has been fixed so that they are now deleted.

================(Build #3021 - Engineering Case #377586)================

An application thread using the QAnywhere client library for messaging, would
have blocked during message synchronization. Normally this was quite brief,
however, if synchronization was having difficulty establishing a connection
with the QAnywhere server, the blocking could have lasted several minutes.
This problem is fixed.

================(Build #2551 - Engineering Case #376620)================

The QAnywhere Agent was launching dbmlsync and dblsn with maximum verbosity
settings. Now, dbmlsync and dblsn are launched with minimum verbosity by
default, otherwise honouring the -v command line switch setting.

================(Build #2541 - Engineering Case #374353)================

The QAnywhere Agent, when run with "automatic" policy, could have performed
message synchronizations very slowly where the download portion of the synchronization
was interrupted and then restarted. This has been fixed, now synchronizations
will recover in a more timely manner when the downloads are interrupted and
restarted.

================(Build #2541 - Engineering Case #374061)================

The QAnywhere Agent could have sent or received messages with an "ondemand"
policy, without it calling QAManager.TriggerSendReceive. This has been fixed.
Now, when qaagent is started with "ondemand" policy, messages are sent and
received only when a client application calls QAManager.TriggerSendReceive,
as documented.

================(Build #2537 - Engineering Case #373543)================

The QAnywhere client library did not have APIs to provide information on
the number of messages queued for sending and receiving. This has been addressed
by adding methods to QAManagerBase to give this information.

For C#, the following enumeration type was added:

public enum QueueDepthFilter {
/// <summary>
/// Count both incoming and outgoing messages. System messages
/// and expired messages are not included in any queue depth
/// counts.
/// </summary>
ALL,
/// <summary>
/// Count only incoming messages. An incoming message is defined
/// as a message whose originator is different than the agent ID
/// of the message store.
/// </summary>
INCOMING,
/// <summary>
/// Count only outgoing messages. An outgoing message is defined
/// as a message whose originator is the agent ID
/// of the message store, and whose destination is not the
/// agent ID of the message store.
/// </summary>
OUTGOING
};

For C#, the following methods were added to QAManagerBase:

/// <summary>
/// Returns the total depth of all queues, based on a given filter.
/// <param name="filter">a filter indicating incoming messages,
/// outgoing messages, or all messages</param>
/// <exception cref="iAnywhere.QAnywhere.Client.QAException">
/// if there was an error
/// </exception>
/// <returns>the number of messages</returns>
/// </summary>
public int GetQueueDepth( QueueDepthFilter filter );

/// <summary>
/// Returns the depth of a queue, based on a given filter.
/// <param name="filter">a filter indicating incoming messages,
/// outgoing messages, or all messages</param>
/// <param name="address">the queue name</param>
/// <exception cref="iAnywhere.QAnywhere.Client.QAException">
/// if there was an error
/// </exception>
/// <returns>the number of messages</returns>
/// </summary>
public int GetQueueDepth( string address, QueueDepthFilter filter );

Similarly, for C++, the following methods were added to QAManagerBase:

/**
* Returns the total depth of all queues, based on a given filter.
* @param filter a filter indicating incoming messages, outgoing messages,
* or all messages
* @see QueueDepthFilter
* @return the number of messages, or -1 if there was an error
*/
virtual qa_int getAllQueueDepth(qa_short filter) = 0;

/**
* Returns the depth of a queue, based on a given filter.
* @param filter a filter indicating incoming messages, outgoing messages,
* or all messages
* @see QueueDepthFilter
* @param dest the queue name
* @return the number of messages in the queue, or -1 if there was an
error
*/
virtual qa_int getQueueDepth(qa_const_string dest, qa_short filter)
= 0;

================(Build #2533 - Engineering Case #373130)================

The QAnywhere Agent window did not have a way to be minimized on some Windows
CE operating systems. This has been fixed by adding a Hide button to the
dialog, similar to the Database Server window.

================(Build #2530 - Engineering Case #371558)================

When the QAnywhere library is used to receive a message using a transactional
manager, it is possible to roll back the receiving of messages. If the receive
of a message is rolled back, then the next time the message is received,
the Redelivered property of the message (getRedelivered() in C++) should
be true. In this situation though, the Redelivered property was always being
set to false. The Redelivered property of a message whose receive was rolled
back is now correctly set.

================(Build #2529 - Engineering Case #371389)================

When the QAnywhere Agent was set up to use a primary server and a secondary
server, and it was performing synchronizations frequently, a failover to
the secondary server may have occurred, even though the primary server was
reachable. This has been fixed. Two new command line options have now been
added: -fr <n>, which specifies the number of retries to connect to the primary
server after a connection failure (default 0), and -fd <n>, which is the
delay, in seconds, between retry attempts to the primary server (default
0). It is recommended that the retry delay be a relatively small value,
perhaps 10 seconds or less.

================(Build #2529 - Engineering Case #370335)================

On Windows CE, the method QAManagerBase::putMessage would have returned FALSE,
and getLastErrorMsg() would have returned the error message "The message
store is too large relative to the disk free space on the device", even though
there was sufficient space in the message store. This has been fixed.

================(Build #2529 - Engineering Case #370205)================

A call to the C++ methods QAManagerBase::getMessage and QAManagerBase::getMessageTimeout
may have returned a NULL value when there was, in fact, a message waiting.
A subsequent call to the method QAManagerBase::getLastErrorMsg would indicate
that a "Statement interrupted by user" error had occurred. Similarly, a call
to the C# methods QAManagerBase.GetMessage and QAManagerBase.GetMessageTimeout
would have caused a QAException to be thrown also indicating that a "Statement
interrupted by user" error had occurred. The problem has been fixed.

================(Build #2529 - Engineering Case #370185)================

If the QAnywhere Agent qaagent was stopped by pressing the shutdown button,
or using the QAnywhere Agent Stop utility qastop.exe, it could have taken
up to 60 seconds to shutdown. This has been fixed.

================(Build #2529 - Engineering Case #368388)================

When the QAnywhere Agent was run on Windows CE systems with "automatic" policy,
and was idle without any messages having been sent or received, subsequent
messages would sometimes appear to be blocked due to the QAnywhere Agent
not transmiting the message, even though the device was connected to a network.
The problem could usually be worked around by shutting down the QAnywhere
Agent, and restarting it while in network coverage. This has been fixed.
Now, messages are sent as needed, with automatic policy.

================(Build #2529 - Engineering Case #368382)================

The QAnywhere Agent Stop utility, qastop, would have returned before the
agent had terminated. This has been fixed, qastop now waits for the qaagent
process to finish before
returning. This allows more reliable control over starting and stopping
the QAnywhere
Agent under program control.

MobiLink - QAnywhere server

================(Build #3899 - Engineering Case #593120)================

The QAnywhere server could have stopped sending and receiving messages with
an Enterprise Messaging Server, through its JMS connector, when connectivity
to the EMS was interrupted and subsequently restored. This has been fixed.

================(Build #3882 - Engineering Case #585035)================

The QAnywhere server could have stopped sending/receiving messages with an
Enterprise Messaging Server, through its JMS connector, when a SQLException
was thrown by the JDBC driver. This has been fixed.

Where possible, the QAnywhere server should recover gracefully from exceptions
thrown by the JDBC driver and continue processing messages.

================(Build #3882 - Engineering Case #499959)================

With ASA databases the QAnywhere server caches prepared statements to avoid
re-preparing them on each statement execution. During periods of high activity
however, the server could have reported "Resource governor for 'prepared
statements' exceeded", followed by the failed execution of a SQL statement.
This problem has now been fixed.

================(Build #3846 - Engineering Case #577321)================

The MobiLink server with messaging (-m command line option) could have crash
when used with an ASE 12.5.3 consolidated database server and the ASE ODBC
driver version 15.0.0.140. This problem was introduced by the changes for
Engineering case 560045, and has now been fixed.

================(Build #3833 - Engineering Case #564639)================

When MobiLink servers with QAnywhere messaging were set up in a server farm,
push notifications could have stopped working in some circumstances. In particular,
if the MobiLink server(s) handling synchronization requests from QAnywhere
clients were different from the server that initiated the push notification
(as would have been the case if the notifications were the result of outbound
JMS messages in a server running a JMS connector), only the first push notification
would have been sent, and no further notifications would have been sent.
This has now been fixed.

It should be noted that, in a MobiLink server farm deployment, there could
be a latency of at most the automatic rules evaluation period to send a push
notification to a client as a result of an outbound message to that client.
This is due to scalabilty factors in a situation where there is a high volume
of outbound messages being processed by the MobiLink server.

================(Build #3797 - Engineering Case #560045)================

When the QAnywhere consolidated database contained a large number of messages
that satisfied a delete rule, and there were QAnywhere clients synchronizing
frequently, it was possible that delete rules would have always failed because
of database deadlock errors such as:

Error: [QA] Problem evaluating transmission rules for user ianywhere.server.deleteRules:
Problem updating object in repository using key "delete from ml_qa_repository
from ml_qa_repository mbr where msgid in (select msgid from ml_qa_messages
ml_qa_messages where status > 20 and (syncstatus = 1 or originator in ('ianywhere.connector.beajms','ianywhere.server')))":
java.sql.SQLException: [Sybase][ODBC Driver][Adaptive Server Anywhere]Deadlock
detected: [Sybase][ODBC Driver][Adaptive Server Anywhere]Dea
Error: dlock detected

This has been fixed. It is possible that some deadlock errors will still
occur, but the errors will not prevent delete rules from deleting old messages.

================(Build #3738 - Engineering Case #551406)================

A MobiLink server with messaging enabled, using an ASE consolidated database,
could have logged errors such as the following when a QAnywhere client synchronizes:

Stored procedure 'ml_qa_upsert_global_prop' not found. Specify owner.objectname
or use sp_help to check whether the object exists (sp_help may produce lots
of output).
(ODBC State = 42000, Native error code = 2812)
Error: Unable to insert into table 'ml_qa_global_props_client' using upload_insert

This problem may have been as a result of the fix made for Engineering case
546131. That fix involved MobiLink creating this stored procedure at startup
if it does not exist. In order for MobiLink to be able to create the stored
procedure, the database option "ddl in tran" needed to be true. Therefore,
there are two possible workarounds for this problem:

Workaround 1: Set "ddl in tran" to true in the database by executing the
following SQL statements on the database, where database_name is the name
of the database used as the QAnywhere server message store.

use master
go
sp_dboption database_name, "ddl in tran", true
go

Workaround 2: If workaround 1 is not desirable, execute the following SQL
statements on the database to make the changes described in case 546131:

drop trigger ml_qa_repository_trigger
go

create trigger ml_qa_repository_trigger on ml_qa_repository for delete
as
delete from ml_qa_repository_props from deleted d, ml_qa_repository_props
p
where d.msgid = p.msgid
delete from ml_qa_delivery from deleted d, ml_qa_delivery p
where d.msgid = p.msgid
delete from ml_qa_status_history from deleted d, ml_qa_status_history
p
where d.msgid = p.msgid
go

drop procedure ml_set_device_address
go

create procedure ml_set_device_address
@device varchar(255),
@medium varchar(255),
@address varchar(255),
@active char(1),
@ignore_tracking char(1),
@source varchar(255)
as
declare @d varchar( 255 )
if @active = 'y' begin
update ml_device_address
set active = 'n'
where address = @address
and medium = @medium
and active = 'y'
and device_name <> @device
end
select @d=device_name from ml_device_address
where device_name = @device and medium = @medium
if @d is null begin
insert into ml_device_address( device_name, medium, address, active,
ignore_tracking, source )
values( @device, @medium, @address, @active, @ignore_tracking, @source
)
end
else begin
if @source = 'tracking' begin
update ml_device_address
set address = @address,
active = @active,
ignore_tracking = @ignore_tracking,
source = @source
where device_name = @device and medium = @medium and ignore_tracking
= 'n'
end
else begin
update ml_device_address
set address = @address,
active = @active,
ignore_tracking = @ignore_tracking,
source = @source
where device_name = @device and medium = @medium
end
end
go

exec sp_procxmode 'ml_set_device_address', 'anymode'
go

create procedure ml_qa_upsert_global_prop
@client varchar(128),
@name varchar(128),
@modifiers integer,
@value varchar(16384)
as
begin
if exists( select 1 from ml_qa_global_props gp
where gp.client = @client and gp.name = @name )
update ml_qa_global_props
set modifiers = @modifiers, value = @value
where client = @client and name = @name
else
insert into ml_qa_global_props (client,name,modifiers,value)
values( @client, @name, @modifiers, @value )
end
go

exec sp_procxmode 'ml_qa_upsert_global_prop', 'anymode'
go

These SQL statements make the changes to the server message store that are
done automatically if database option "ddl in tran" is true.

Note, MobiLink system schema changes can only be made in a major release,
so these documented workarounds are provided. Later versions contain these
fixes.

================(Build #3738 - Engineering Case #548724)================

When using an ASE consolidated database, the MobiLink server with messaging
enabled will log deadlock errors, such as the following, when several QAnywhere
clients are synchronizing concurrently:

E. 10/07 09:14:13. Error: java.sql.SQLException: [DataDirect][ODBC Sybase
Wire Protocol driver][SQL Server]Your server command (family id #0, process
id #342) encountered a deadlock situation. Please re-run your command.

These errors happen because ASE uses page-level locking by default. This
locking level causes deadlocks with many of the SQL statements executed by
MobiLink with QAnywhere, especially as many clients are synchronizing concurrently.
This problem can be worked around by executing the following SQL statements
on the ASE consolidated database, when the database server is not handling
other requests:

alter table ml_qa_repository lock datarows
go
alter table ml_qa_delivery lock datarows
go
alter table ml_qa_notifications lock datarows
go
alter table ml_qa_global_props lock datarows
go
alter table ml_qa_status_history lock datarows
go
alter table ml_qa_repository_props lock datarows
go
alter table ml_qa_repository_staging lock datarows
go
alter table ml_qa_status_staging lock datarows
go

create index ml_qa_delivery_cli on ml_qa_delivery ( client )
go
create index ml_qa_delivery_dld on ml_qa_delivery ( client, syncstatus,
status )
go
create index ml_qa_mstage_user on ml_qa_repository_staging ( mluser )
go
create index ml_qa_sstage_user on ml_qa_status_staging ( mluser )
go

These SQL statements change the QAnywhere system tables to use row-level
locking, and add some indexes for increased performance.

================(Build #3738 - Engineering Case #546131)================

The following bug fixes, which were originally made only for ASA consolidated
databases, have now been implemented for ASE consolidated databases as well:
1 - primary key conflicts for table ml_qa_global_props in upload_insert
script (Engineering case 463062),
2 - table ml_qa_status_history unlimited growth problem (Engineering case
495514),
3 - UDP notifications to inactive devices problem (Engineering case 544613).

================(Build #3674 - Engineering Case #531525)================

MobiLink with QAnywhere messaging enabled used approximately 400 KB of heap
memory for each QAnywhere client that synchronizes with it. This occurred
until the prepared statement cache size (default 200 for SA consolidated
databases) was reached, and then each new QAnywhere client caused a cached
statement to be dropped and a new statement to be prepared. This behaviour
has been changed for SA consolidated databases only. Now the MobiLink server
will use a constant amount of heap memory for QAnywhere client synchronizations,
and will not overflow the prepared statement cache as many clients synchronize.

================(Build #3597 - Engineering Case #487581)================

Initializing a scheduled transmission rule containing an "EVERY" clause and
a "START DATE" clause set to a date that had already passed, in the QAnywhere
server or
in the QAnywhere Ultralight Agent, would have caused the rule to be immediately
and repeatedly executed many times on startup. This has been fixed.

================(Build #3576 - Engineering Case #478153)================

When the MobiLink server was running with QAnywhere messaging enabled and
a JMS connector was configured and there is a high volume of JMS traffic
between QAnywhere clients and a JMS system, the Java VM running in MobiLink
would have used a continuously increasing amount of heap memory and may eventually
have reached an out-of-memory condition. This has been fixed.

================(Build #3551 - Engineering Case #477156)================

When a large number of clients (more than 2500) had contacted the MobiLink
server, with all indicating they wished to receive push notifications, the
server would have consumed a large amount of CPU evaluating transmission
rules. This has been fixed.

NOTE (for 9.0.2 only): It is also important to run the MobiLink server
with the command line option
-sl java ( -Dianywhere.qa.db.upgradeDeliveryColumns=true )
in order to get the most out of this performance improvement. This option
causes the MobiLink server to reorganize the QAnywhere message store tables,
and add further indexes to these tables, to obtain optimal performance of
MobiLink with QAnywhere.

================(Build #3551 - Engineering Case #471045)================

The memory usage of the MobiLink server with QAnywhere messaging enabled
would have increased by a small amount at each client synchronization. The
amount of increase was reduced by about 90% by changes made for Engineering
case 471798. This increase has now been reduced by a further 5%. While not
completely resolved, the memory increase has been significantly reduced,
and it continues to be addressed.

================(Build #3519 - Engineering Case #472632)================

Messages with a NULL originator in the server message store, would have caused
message processing to halt. This has been fixed as follows: the QAnywhere
Agent has been changed so that messages with a NULL originator will not be
uploaded until the store ID is set on the client. The QAnywhere connector
has been changed so that if a message with NULL originator somehow gets into
the server message store, the message will be marked as unreceivable and
skipped, not halting further message processing.

================(Build #3479 - Engineering Case #463062)================

When a QAnywhere client that had previously synchronized with a MobiLink
server, and whose message store was subsequently re-created, synchronized
again with the MobiLink server, the error " -193 error Primary key for table
'ml_qa_global_props' is not unique" would have been reported in the MobiLink
log. This has been corrected so that the QAnywhere client's message store
properties are now upserted into the consolidated database. This fix is
only for ASA consolidated databases.

Note that this works correctly for all supported consolidated databases
in version 10.0.0 and later.

================(Build #3462 - Engineering Case #465712)================

When running the consolidated database on a server that uses snapshot isolation
(Oracle 10g for example), it was possible that MobiLink would have redelivered
messages to QAnywhere clients that were previously received and acknowledged.
This problem would have occurred when there was a long-running transaction
on the consolidated database, which caused the last_download_timestamp to
stay fixed at the time that the transaction began. It has now been fixed.

================(Build #3371 - Engineering Case #441562)================

It may have appeared that a lot of data was being sent from the server and
the client, even when the client was not receiving messages. The problem
occurred when using a consolidated database where the last_download and last_upload
time granularity was large, typically in the one second range. Because the
QAnywhere MobiLink server against an Oracle server only supports a one second
granularity, it would typically have happened only with an Oracle consolidated
database. The problem was that message synchronizations between the client
and the server, that took less than the timestamp granularity, would have
been interpreted as a failed sync by the next synchronization, resulting
in data being re-downloaded to the client. This has been fixed by correcting
for the timestamp granularity, so that re-downloading data to the client
will no longer occur.

================(Build #3360 - Engineering Case #439802)================

If the consolidated database had a message repository containing several
million messages, startup time of the MobiLink QAnywhere server may have
taken several minutes. This has been fixed so that the startup time should
now be the same, regardless of the number of messages in the repository.

================(Build #3358 - Engineering Case #440132)================

When not utilizing push notifications, the extra processing done on the MobiLink
server to process notifications was wasted. A new server configuration parameter
ianywhere.qa.server.disableNotifications has been added, that will allow
disabling server-side notification processing. The parameter, which defaults
to "false", should be set to "true" to disable server-side notification processing.
Disabling process notification should improve performance when not using
push notification.

================(Build #3356 - Engineering Case #439163)================

The error "Too many connections in use" may have appeared in the QAnywhere
MobiLink server log. It may have occurred if a JMS connector had been configured
and started, and the JMS connector was handling a large volume of incoming
messages from JMS to QAnywhere. The error would not have affected accurate
delivery of messages, but may have had an impact on performance. This has
been fixed.

================(Build #3332 - Engineering Case #436578)================

A message available for download to a client may not have been downloaded.
The message was not lost, and would likely have been downloaded on the next
synchronization of that client. The problem could only have occurrec if the
transmission rules used for the client included a reference to a custom message
property. This has been fixed.

================(Build #3332 - Engineering Case #436575)================

When using the QAnywhere JMS connector, a message may have appeared in the
server log indicating that a problem with anywhere.ml.jdbcodbc.IConnection.setAutoCommit
had occurred. The problem was with respect to resetting the autocommit status
of a database connection used by the QAnywhere JMS connector. The error had
no effect on the performance or accuracy of the connector, but the cause
of the error has now been removed and the message should no longer occur.

================(Build #3327 - Engineering Case #434318)================

The QAnywhere MobiLink server could have processed, and subsequently not
delivered, incoming JMS messages to its QAnywhere JMS connector if the QAnywhere
MobiLink server consolidated database was inaccessible, for example because
it had crashed. This has been fixed by allowing the default value of the
ianywhere.connector.incoming.retry.timeout property to be set to -1, and
making this the default. This means the connector will not give up trying
to send the message.

As a work around, the connector property ianywhere.connector.incoming.retry.timeout
can be set to a very large value, for example 1000000000. This property indicates
how many times the QAnywhere connector will retry transferring a JMS message
to QAnywhere before giving up. Unfortunately, the default value for this
property was set to 5, which was much too low. It was not documented, improperly
named, and had no support for specifying an infinite value. In recognition
that this property's name implies a duration rather than a number of retries,
a new property, ianywhere.connector.incoming.retry.max, has been added as
a replacement for ianywhere.connector.incoming.retry.timeout. The property
ianywhere.connector.incoming.retry.max indicates the maximum number of times
the connector will retry transferring a JMS message to QAnywhere before giving
up. The default is -1, which indicates that the connector will never give
up. Please now use this new property.

Also, the fact that the QAnywhere connector had given up trying to transfer
the message, was also not added to the dead message destination. Now, if
the connector reaches the maximum number of subsequent failed attempts to
transfer a JMS message to QAnywhere, the JMS message will be re-addressed
to the ianywhere.connector.jms.deadMessageDestination property value.

================(Build #3327 - Engineering Case #434305)================

The QAnywhere MobiLink server could have hung on shutdown if all the following
conditions occurred:
- There was a problem accessing the consolidated database, for example,
the consolidated database engine crashed,
- There were messages queued for delivery from QAnywhere to an external
JMS server via the QAnywhere JMS connector,
- An upload message transmission had just occurred, containing messages
meant for the QAnywhere JMS connector

If a shutdown was attempted at this point, it was possible that the QAnywhere
MobiLink server would not shutdown. As a work around, either the database
server would have to be brought back on line, or the QAnywhere MobiLink server
process would have to be killed. No message data would be lost. This has
now been fixed so that a shutdown should not hang under these circumstances.

================(Build #3327 - Engineering Case #434156)================

JBoss JMS message property names must begin with an alpha character, can
contain only alphanumeric and underscore characters, and must not be the
same name of any of the JMS Defined Properties (as listed in section 3.5.9
of the JMS 1.1 spec), that are defined as being set by the provider. These
include JMSXUserID, JMSXAppID, JMSXDeliveryCount, JMSXProducerTXID, JMSXConsumerTXID,
JMSXRcvTimestamp, or JMSXState. Using a property name that JBoss does not
support in a QAnywhere message, and then sending that to JBoss JMS via a
configured QAnywhere connector, would have caused problems. The connector
would have tried to deliver the message to JBoss continuously until the message
expired, was cancelled, or was deleted. This problem has been fixed so that
the problematic property name problem will be detected as message-specific,
the message will be marked as unreceivable, and the connector will no longer
try to deliver the message. If the property ianywhere.connector.outgoing.deadMessageAddress
is set to a non-empty value, then a copy of the message will be sent to that
address value.

================(Build #3324 - Engineering Case #433564)================

It was possible that the generation of notifications to the cliemt, for messages
that were available on the server for that particular client, might be delayed.
The problem was that the determination of whether notifications should be
generated was serialized. Hence, if the determination conditions were slow
for a particular client (because of complicated transmission rules), then
the determination for all other clients would have been held up. This has
been fixed so that slow determination of notifications for some clients will
not hold up the determination of notifications for other clients.

================(Build #3324 - Engineering Case #433341)================

If there was a transient connection problem with the consolidated database
server, it was possible that a message being transferred from QAnywhere to
JMS would have been duplicated. This problem would have occurred after a
message was transferred from QAnywhere to JMS. The transfer acknowledgement
is stored in the consolidated database, and if there was a temporary difficulty
accessing the database, the transfer would not have been acknowledged. At
a later time (not necessarily immediately), because the acknowledgement was
lost, the message may have been re-transferred from QAnywhere to JMS. This
problem has been fixed, although, if the connectivity with the consolidated
server is not resumed in a timely manner it is still possible the message
may be duplicated.

Note that we do not guarantee that duplicates will not be delivered from
QAnywhere to JMS, but duplicates should only occur in rare situations, for
example where the QAnywhere MobiLink server or the dbms or the JMS server
was to crash.

================(Build #3323 - Engineering Case #432929)================

Normally, QAnywhere works against any consolidated database that MobiLink
supports. However, MobiLink supports DB2 UDB 7.2 only with caveats. Those
caveats make it impossible for QAnywhere to work against a DB2 UDB 7.2 consolidated
database, and the documentation was not clear on this. In fact, there is
a small chance of message corruption if DB2 7.2 is used as a consolidated
database for QAnywhere. Now, attempting to to start a QAnywhere MobiLink
server against a DB2 UDB 7.2 database will result in an error. Similarly,
trying to administer such a database with QAnywhere Central will also result
in an error

================(Build #3312 - Engineering Case #429629)================

The QAnywhere Server could have performed poorly if the consolidated database
was IBM DB2. For the performance degradation to have been apparent, the
consolidated database must have contained more than 100,000 undelivered messages.
The performance issues included slow processing of messages by a JMS connector,
slow expiry of messages, and slow removal of old messages. This has been
fixed, but the fix requires the application of an upgrade to the DB2 consolidated
message store using a SQL script. The script, patchdb2.sql, is located in
the SQL Anywhere Studio 9.0.2 install directory under QAnywhere\sql. This
directory also includes a readme.txt that details how to apply the script.

================(Build #3298 - Engineering Case #429146)================

When there were hundreds of thousands of messages in the QAnywhere Server
consolidated message store, cleaning up (deleting) old messages could have
been very slow. Deleting this many messages would have locked down message
transmission for the duration of the operation. A work-around would be to
schedule message deletion to a time of low server activity, perhaps over
night. This has been fixed, but requires the application of an upgrade to
the QAnywhere Server consolidated message store. The fix, so far, is only
available for Adaptive Server Anywhere, Microsoft SQL Server, and Oracle
consolidated databases used by a Version 9.0.2 QAnywhere (MobiLink) server.
These scripts are located in the SQL Anywhere Studio 9.0.2 install directory
under QAnywhere\sql. This includes a readme.txt that details how to apply
the scripts. The scripts are:

patchasa2.sql
patchmss2.sql
patchora2.sql

for Adaptive Server Anywhere, Microsoft SQL Server and Oracle consolidated
databases respectively.

================(Build #3298 - Engineering Case #429136)================

Scripts are now available for applying QAnywhere performance upgrades to
consolidated databases used by a Version 9.0.2 QAnywhere (MobiLink) server.
These scripts are located in the SQL Anywhere Studio 9.0.2 install directory
under QAnywhere\sql. This includes a readme.txt that details how to apply
the scripts.

Engineering cases 409529, 415999, and 417415 described applying performance
upgrades by using additional command line parameters on the QAnywhere server:

-sl java ( -Dianywhere.qa.db.upgradeDeliveryColumns=true )

As there were situations where it was not possible to start the MobiLink
server with a database user having schema change permissions, the scripts:

patchasa1.sql
patchmss1.sql
patchora1.sql

were developed for applying the performance upgrades against Adaptive Server
Anywhere, Microsoft SQL Server and Oracle consolidated databases respectively.

================(Build #3274 - Engineering Case #420934)================

Opening a QATransactionalManager and putting a message onto a queue without
committing, creates an index lock on ml_qa_repository_client. This was preventing
any other application from sending or receiving messages until the transactional
manager executed a commit or rollback. This has been fixed by changing the
view used by the QAnywhere client to get messages, ml_qa_messages_client,
to use the WITH (READPAST) functionality recently added to the server, (see
Engineering case 422513). The order of insert statements in QAManagerBase.putMessage
was also changed to prevent another blocking issue.

================(Build #3261 - Engineering Case #419668)================

In the presence of many undelivered messages in the QAnywhere server, message
synchronization performance would have declined. This was largely due to
poor performance of a number of three SQL operations being executed against
the server message store. Two of these operations, that involved message
delivery confirmation and message download preparation, were re-structured
to dramatically improve performance. Applying the fix to the server is all
that is required to get these benefits. The final SQL operation requires
a schema change, and only is available for an Oracle consolidated database.
These schema changes can be made in two different ways. The first is to run
the QAnywhere server with the additional command arguments -sl java { -Dianywhere.qa.db.upgradeDeliveryColumns=true
} successfully at least once. The second is to execute the following SQL
against your Oracle database using SQL*Plus:

create global temporary table ml_qa_clients
( client varchar(255) not null ) on commit preserve rows
/
create index ml_qa_clients_index on ml_qa_clients( client )
/
drop index ml_qa_delivery_client
/
create index ml_qa_delivery_client on ml_qa_delivery(client,syncstatus,maxstatus,status)
/
create or replace trigger ml_qa_delivery_before_trigger
before insert on ml_qa_delivery
for each row
begin
insert into ml_qa_clients (client) values( :new.client );
select substr(:new.address,2,instr(:new.address,'\')-2) into :new.clientaddress
from dual;
select :new.status into :new.maxstatus from dual;
begin
select seqno, priority into :new.seqno, :new.priority
from ml_qa_repository where msgid = :new.msgid;
exception
when NO_DATA_FOUND then
select 0, 4 into :new.seqno, :new.priority from dual;
end;
end;
/

Note that this must be executed under the same database user initially used
to create the MobiLink QAnywhere schema.

================(Build #3255 - Engineering Case #419165)================

The documentation indicates that server-side transmission rule times could
be like '1:00am'. In fact, the default time format is hh:mm:ss, where hh
uses the 24 hour clock. Hence, using an AM or PM suffix is not valid, but
the error reporting and detection did not always report an error. If, for
example, the time '1:00:00 PM' was used, the PM portion of the time was ignored,
and the time was treated as 1:00:00 AM. This has been corrected so that
such a time is now reported as an error.

The documentation also did not indicate indicated how a user can change
the default time and date formats used by the QAnywhere server. To set the
time format, set the property ianywhere.qa.server.scheduleTimeFormat to a
value describing the time format. This property can be set in several different
ways. If the server uses a configuration file (using the -m <file-name> MobiLink
command line option), then a line can be added to the file as follows:

ianywhere.qa.server.scheduleTimeFormat = hh:mm:ss a

This property can also be set using the GUI tool QAnywhere Central, by clicking
on the server properties tab and adding the property. The time format values
are identical to those used in Java by the java.text.SimpleDateFormat class
(the default time format is HH:mm:ss):

Letter Time Component
a Am/pm marker (AM/PM)
H Hour in day (0-23)
k Hour in day (1-24)
K Hour in am/pm (0-11)
h Hour in am/pm (1-12)
m Minute in hour (0-59)
s Second in minute (0-59)

Time Format Example Time
HH:mm:ss z 12:08:56
h:mm a 12:08 PM
K:mm a 0:08 PM
hh:mm aaa 12:08 PM
HH:mm:ss 12:08:56
HHmmss 120856

To set the date format, set the property ianywhere.qa.server.scheduleDateFormat
to a value describing the date format. This property can be set in several
different ways. If the server uses a configuration file (using the -m <file-name>
MobiLink command line option), then a line can be added to the file as follows:

ianywhere.qa.server.scheduleDateFormat = yy:MM:dd

This property can also be set using the GUI tool QAnywhere Central, by clicking
on the server properties tab and adding the property. The date format values
are identical to those used in Java by the java.text.SimpleDateFormat

class (the default date format is yyyy-MM-dd):

Letter Date or Time Component
y Year
M Month in year (ie July, Jul or 07)
d Day in month

Date Format Example Date
yyyy.MM.dd 2001.07.04
yyyy.MMMMM.dd 02001.July.04
d MMM yyyy 4 Jul 2001
yyMMdd 010704

Note that the software does not need to be upgraded your to use the two
date and time formatting properties.

================(Build #3254 - Engineering Case #419399)================

There have been circumstances where the QAnywhere JMS connector would receive
a RuntimeException from either the JDBC driver or the 3rd party JMS driver.
The default behaviour of the JMS connector when it received this kind of
exception was to terminate execution. Such exceptions have often been found
to be transient or spurious, and that retrying the same operations often
results in the problem going away. Because of this experience, the behaviour
of the QAnywhere JMS connector has been changed to backoff and retry when
receiving this exception. The backoff is exponential, increasing in time
with each consecutive exception up to one minute (this default maximum can
be configured using the connector property ianywhere.connector.pollingFrequency
value in milliseconds).

Note that RuntimeExceptions are logged to the QAnywhere Server (MobiLink)
console and log file. Typically, RuntimeExceptions represent bugs, and probably
indicate that you need a fix for the component issuing the exception, for
example, the JDBC driver or JMS driver.

================(Build #3254 - Engineering Case #419146)================

If a QAnywhere server operating against an ASE consolidated database, was
terminated unexpectedly while a QAnywhere JMS connector was processing a
QAnywhere message destined for JMS, it was possible that when the QAnywhere
server was restarted the QAnywhere JMS connector would not be able to process
any subsequent messages. The problem was with the message that was being
processed during the crash. It can be worked around using the GUI administration
tool QAnywhere Central. Using QAnywhere Central, determine which message
is causing the problem (The address of the message will be the connector
address, and the state of the message will be "receiving"), select and export
the message, cancel the message, wait for the message to be deleted, then
use the exported message to create a new message containing the same content,
headers and address. There is a simpler work-around involving the use of
the tool dbisql. This work-around involves deleting the record indicating
the "receiving" state for the message, but this should only be attempted
with the assistance of Technical Support. This problem has now been fixed
so that neither of these the work-arounds are needed.

Note that this problem does affect QAnywhere server running against ASA,
Oracle, DB@ or Microsoft SQL Server.

================(Build #3245 - Engineering Case #417145)================

When tens of thousands of messages were directed to a QAnywhere JMS connector
(bridge), the connector would have processed the messages very slowly; for
example, depending on hardware, OS, and other software, the connector might
have handled only one message every few seconds. This has been fixed, resulting
in approximately a 10-fold improvement in QAnywhere JMS connector performance
in sending QAnywhere messages into JMS. This fix requires a schema change
to existing Microsoft SQL Server consolidated databases. To implement this
schema change, start the QAnywhere server dbmlsrv9 with the additional command
line parameters:

-sl java { -Dianywhere.qa.db.upgradeDeliveryColumns=true }

During start-up, the QAnywhere server will change the schema. Note that
the schema change should be considered irreversible. That is, it will not
be possible to go back to an earlier version of the software. Once the schema
change has completed, it is no longer necessary to start the QAnywhere server
with the additional command line parameters.

================(Build #3241 - Engineering Case #416461)================

The QAnywhere JMS connector was doing more processing of messaging incoming
from JMS than was necessarily. Although this problem did not affect correctness,
it could have affected performance. If an incoming message had many properties,
the performance impact of the problem may have been noticable, with the larger
the number of properties the larger the performance impact. This has now
been fixed so that there is no longer a performance impact with respect to
the number of properties in the incoming message.

================(Build #3241 - Engineering Case #415999)================

When there were tens of thousands of messages directed to a QAnywhere JMS
connector (bridge), the connector would have processed these messages very
slowly. For example, depending on your hardware, OS, and other software,
the connector may have handled only one message every three seconds. This
has been fixed, which should result in a roughly 10-fold improvement in QAnywhere
JMS connector performance in sending QAnywhere messages into JMS. A schema
change to the Oracle consolidated database is also required. To make this
schema change, start the QAnywhere server dbmlsrv9 with the following additional
command line parameters:

-sl java { -Dianywhere.qa.db.upgradeDeliveryColumns=true }

During start-up the QAnywhere server will change the schema. Note that
the schema change should be considered irreversible. That is, it will not
be possible to go back to an earlier version of the software. Once the schema
change has completed, it is no longer necessary to start the QAnywhere server
with the additional command line parameters.

================(Build #3239 - Engineering Case #416233)================

The literals TRUE and FALSE can be used in server-side transmission rules,
however, the server-side rule processing code was treating these literals
as invalid literals. Hence, an error would have occurred while processing
the rule indicating that TRUE or FALSE was not valid syntax. This has now
beeen fixed so that TRUE and FALSE are correctly recognized as boolean literals.

================(Build #3228 - Engineering Case #409529)================

When tens of thousands of messages were directed to a QAnywhere JMS connector
(bridge), the connector would have processed the messages very slowly; for
example, depending on hardware, OS, and other software, the connector might
have handled only one message every few seconds. This has been fixed, resulting
in approximately a 10-fold improvement in QAnywhere JMS connector performance
in sending QAnywhere messages into JMS. This fix requires a schema change
to existing ASA consolidated databases. To implement this schema change,
start the QAnywhere server dbmlsrv9 with the additional command line parameters:

-sl java { -Dianywhere.qa.db.upgradeDeliveryColumns=true }

During start-up, the QAnywhere server will change the schema. Note that
the schema change should be considered irreversible. That is, it will not
be possible to go back to an earlier version of the software. Once the schema
change has completed, it is no longer necessary to start the QAnywhere server
with the additional command line parameters.

================(Build #3207 - Engineering Case #406441)================

If two or more QAnywhere servers were started using the same consolidated
database, the JMS connectors in the multiple instances may have produced
duplicates messages. That is, if a QAnywhere message was sent to a JMS destination
via a JMS connector, it was possible that each instance of the JMS connector
would have read the QAnywhere message and produced a corresponding JMS message.
This has now been fixed so that the potential source of duplicate messages
has been removed.

================(Build #3195 - Engineering Case #404622)================

When 9.0.1 QAnywhere clients synchronized messages with 9.0.2 QAnywhere servers,
the performance may have been poor, especially under load situations. Checking
the QAnywhere server log would have likely shown multiple "Deadlock" errors.
Although these deadlock errors did not affect correct message delivery, the
deadlocks were forcing the clients to re-synchronize until there were nolonger
deadlock errors. This has been fixed, so that the deadlocks will no longer
occur, and performance under load situations will improve.

================(Build #3192 - Engineering Case #404321)================

If an Adaptive Server Enterprise database was used as a QAnywhere server's
consolidated database, and QAnywhere groups were created, any messages directed
at the groups would have queued up, but would never have been delivered.
This is now fixed, so that messages directed to groups will be delivered.
Any messages queued up before this fix will also be delivered.

================(Build #3176 - Engineering Case #401363)================

The QAnywhere JMS connector did not always ensure the preservation of the
order of delivery of messages from a JMS sender to a QAnywhere client receiver
when the QAnywhere server's consolidated database was non-ASA. This has
been fixed so that the order of new JMS messages to QAnywhere client receivers
will be preserved.

================(Build #3175 - Engineering Case #481898)================

If a Mobilink server with QAnywhere was running on a non-ASA consolidated
database and tried to process a message received from a JMS server, a SQL
statement could have failed resulting in the message not being properly received
by QAnywhere. This has been fixed.

================(Build #3170 - Engineering Case #400583)================

An empty value in the QAnywhere server's INI file for the transmission rule
file property ianywhere.qa.server.transmissionRulesFile, would have resulted
in the server failing on start-up. This has been fixed so that an empty value
is now treated as indicating the non-existence of ianywhere.qa.server.transmissionRulesFile.

A work-around is to delete the property from the INI file.

================(Build #3170 - Engineering Case #400572)================

If the QAnywhere server's consolidated database was Oracle, Microsoft SQL
Server or ASE, there would have been problems adding members to QAnywhere
message groups. The QAnywhere server would have failed the next time it was
started. A QAnywhere message group is a special QAnywhere client to which
other QAnywhere client's can become members. A message sent to the group
will then be forwarded to all the members in the group. This has now been
fixed.

================(Build #3170 - Engineering Case #400562)================

To set the same server-side transmission rule for many users, either each
user had to be added to the transmission rules file with the same rule, or
the same rule had to be added for each user using QAnywhere Central. This
was time-consuming and did not handle well situations where users were added
dynamically (MobiLink command line parameter -zu+).

With these changes, a default transmission rule can be set such that every
user that does not have an explicit transmission rule will use the default
rule as its transmission rule. There are two ways to set the default transmission
rule:

If you are using a transmission rule INI file, then create a section called
ianywhere.server.defaultRules and set the transmission rule. For example,
if the default transmission rule is to send only high-priority messages,
then the following should be added to the transmission rules file:

[ianywhere.server.defaultRules]
auto = ias_Priority > 6

You must restart the server for this rule to take effect

To set the default transmission rule using QAnywhere Central, follow these
steps:
Select Tools->Server store connect... and specify the necessary connection
parameters to connect to the server
Select the Properties item in the left-hand panel
Right-click "Properties" in the left-hand panel and select "Create property"
In the "New Property" dialog enter ianywhere.server.defaultRules for the
Client field, ianywhere.qa.server.rules for the Property field and the rule
(example "auto=ias_Priority > 6") for the Value field.

You must restart the server for this rule to take effect

To set the default transmission rule using a Server message

C# Example:

QAManager mgr = …; // Initialize the QAManager
QAMessage msg = mgr.CreateTextMessage();
msg.SetStringProperty( “ias_ServerPassword”, “QAnywhere” );

// Indenting and newlines are just for readability
msg.Text = “<?xml version="1.0" encoding="UTF-8"?>\n”
+ “<actions>\n”
+ “ <SetProperty>\n”
+ “ <prop>\n”
+ “ <client>ianywhere.server.defaultRules</client>\n”
+ “ <name>ianywhere.qa.server.rules</name>\n”
+ “ <value>auto = ias_Priority > 6</value>\n”
+ “ </prop>\n”
+ “ </SetProperty>\n”
+ “ <RestartRules>\n”
+ “ <client>ianywhere.server.defaultRules</client>\n”
+ “ </RestartRules>\n”
+ “</actions>\n”;

mgr.PutMessage( “ianywhere.server\system”, msg );

Note that this mechanism has the advantage that you do not have to restart
the server.

================(Build #3158 - Engineering Case #398459)================

The implementation of schedules for transmission rules on the server was
incorrect. Schedules with a 'start time' did not fire the rule evaluation
at the given start time. As well, schedules with serveral days of the week
or several days of the month scheduled at once (eg. every 10 seconds on ('Monday','Tuesday'))
did not work correctly. These problems have been corrected.

================(Build #3157 - Engineering Case #398456)================

If a delete rule was specified in the '[system:delete]' section of a transmission
rule file, it was ignored by the QAnywhere server. This has been fixed so
that now such a delete rule replaces the default delete rule used by the
server.

================(Build #3155 - Engineering Case #397668)================

Scheduling transmission rules that contained ON { days of the week } or ON
{ days of the month } clauses, but did not contain an EVERY {period} clause,
would have resulted in an "illegal argument" exception, causing the QAnywhere
server to fail. In scheduling these rules, the fact that the EVERY clause
was omitted was ignored and the rule was treated as though it had been included.
A check has now been added for these rules and they are now handled correctly.
Also, when calculating the next execution time for rules with the ON { days
of the week } clause, the scheduler mistakenly set the next day of execution
to the 7th of the month, rather than 7 days in the future. This has been
fixed as well.

================(Build #3141 - Engineering Case #394832)================

A QAnywhere client would not have been able to transmit messages to the server
if all the following apply

- The last time the client transmitted messages with the server it used
the "scheduled" policy (using the qaagent command line argument -policy scheduled)
- The client message store had subsequently been deleted and re-created
and then the client agent was started with the automatic policy (using the
qaagent command argument -policy automatic).

This has been fixed. To work-around the problem, start the client agent
with the "scheduled" policy. After a successful message transmission, the
client can then be re-started with whatever policy is desired. The key is
that after a client message store has been deleted and re-created, the first
time the client agent should be started with the last policy it previously
synchronized under.

================(Build #3140 - Engineering Case #394716)================

A message synchronization may not have completed, and appeared to be hung.
Disconnecting the client and re-attempting the synchronization would have
had no effect, as the server continued to try to complete the previous synchronization
and disallowed any new synchronizations from the client. Only re-starting
the QAnywhere server would have allowed subsequent synchronizations from
the client. This generally happened only when the server was under load.
The problem has been fixed.

================(Build #3138 - Engineering Case #393935)================

Attempting to register a schedule that contained the BETWEEN or ON { days
of the week } clauses would have failed, resulting in an "unexpected token"
exception to be thrown.

Also, attempting to register a schedule containing a time between 12:00:00
and 12:59:59, would have resulted in the 12 being interpreted as 00. For
example, START TIME '12:30:00' would have been interpreted as START TIME
'00:30:00'.

Both of these problems have now been corrected.

================(Build #3138 - Engineering Case #393813)================

A number of problems with the QAnywhere GUI admin tool have been fixed.

-Delete rules specified and "Save"'ed using the "Server Delete Rules" tab
now persist over a restart of the QAnywhere server.
-When creating a message using the "New Message" dialog, when specifying
a custom boolean typed property on the "Properties" tab, only the value "0"
could be entered to represent the false value. This was confusing, as the
value was displayed as "false". Now the value "0" or "false" can be entered
to represent the false value.
-When creating a message using the "New Message" dialog the "Content" tab
now allows the compression level that should be applied to the content to
be specified.
-When viewing a message in the right-hand panel using the "Content" tab,
if the message was compressed, then the content would have been displayed
rendering the compressed data as characters. Content is now displayed correctly
even if the data is compressed.
-If a QAnywhere connector took more than 30 seconds when started using the
"Start" menu item, the connector state would not have been updated on the
right-hand summary panel. The latency has been changed to 60 seconds, and
a new "Refresh" menu item has been added to allow refreshing of the current
connector state at any time.
-Messages created and sent using the "Send message..." menu item would not
trigger synchronization. Hence messages sent in this way would only be transmitted
to the server when another synchronization trigger occurred. Now, sending
such a message will act as a synchronization trigger. In fact, an additional
menu item "Trigger message transmission" has been added to trigger message
synchronization.
-The clients listed in the Clients tree view was only including clients
that had sync'ed sometime in the past. If the client had messages destined
for it, but had never sync'ed, it was not showing up in the tree view. The
tree view has been fixed to include clients that have messages destined for
it but have never sync'ed.
-The right-hand summary panel for a client displayed the client name on
the far right. This formatting problem has been fixed.

================(Build #3135 - Engineering Case #393429)================

If a remote QAnywhere client and a QAnywhere Connector shared the same name,
it was possible for both to receive the same message. While it is unlikely
that such a situation would set up purposefully, now with this fix, a remote
QAnywhere client and a QAnywhere Connector sharing the same name will nolonger
receive the same message.

================(Build #3130 - Engineering Case #392213)================

The QAnywhere JMS connector could have been slow in the presence of many
thousands of messages queued up destined for the connector. This has been
fixed so that any new ASA database created to be used as a consolidated database
for the QAnywhere server includes a new index that greatly improves the performance
of the JMS connector in this situation.

================(Build #3130 - Engineering Case #392209)================

QAnywhere 9.0.1 clients can synchronize messages with QAnywhere 9.0.2 servers,
but if there was a server-side transmission rule for a 9.0.1 client then
messages destined for the 9.0.1 client would never have been delivered. The
messages destined for the 9.0.1 client would have remained on the server
indefinitely. If the server-side transmission rule for the 9.0.1 client is
removed, the messages would then have been delivered normally. This has now
been fixed, there is no longer a problem delivering messages from a 9.0.2
server to a 9.0.1 client in the presence of server-side transmission rules.

================(Build #3129 - Engineering Case #392015)================

Server-side transmission rules, including references to more than one custom
message property, may under certain circumstances have evaluated as if one
or more of the custom property values was null. This may have occurred if
the transmission rule referred to two or more custom message properties in
the same rule and the server delete rules included a reference to one of
the same custom message properties. This problem has been fixed.

================(Build #3128 - Engineering Case #391785)================

Processing a message from QAnywhere to JMS through the QAnywhere JMS connector
could have taken up to 5 seconds. Previously, connectors were polled every
5 seconds for messages. Now a QAnywhere connector is notified as soon as
a message destined for the connector is uploaded.

================(Build #3128 - Engineering Case #391775)================

With the 9.0.2 build 3124 EBF a new message-based API was introduced for
configuring and closing a JMS connector on-the-fly. Using the API to close
and then opening a JMS connector on-the-fly had the side-effect of stopping
all QAnywhere output from being logged. Restarting the QAnywhere server would
have restored proper logging. This has been fixed, now closing a JMS connector
on-the-fly will not stop QAnywhere output from being logged.

================(Build #3128 - Engineering Case #391730)================

Server-side delete rules for deleting messages from an Oracle consolidated
message store did not work if the delete rule contained a reference to a
custom message property. This has been fixed so that such rules now work
correctly.

================(Build #3124 - Engineering Case #391889)================

If there were SQL errors reported in the server log by the JMS connector,
or the background notification threads (indicated by the prefix [QA]), then
a leak of database connections would have occurred. Every error that occurred
forced a new database connection to be created without closing the old connection.
One example of an error that can cause this problem is an invalid server-side
transmission or delete rule. The problem was due to the current connection
-- the one encountering the error -- not being returned to the connection
pool, so it was never closed. This has now been fixed so that the connection
encountering an error is closed.

================(Build #3114 - Engineering Case #387511)================

The QAnywhere JMS sample program for sending and receiving messages, used
a combination of API methods that was not always supported by JMS providers.
The QueueSender was being initialized with a specific Queue and then the
QueueSender method send() was being called with a specific (and identical)
Queue. Some providers would throw an UnsupportedOperationException. The sample
has been fixed to use the QueueSender send() method that does not specify
a Queue.

================(Build #3111 - Engineering Case #391202)================

JMS messages received by the QAnywhere JMS connector are forwarded on to
QAnywhere if they contain a property (ias_ToAddress) indicating the QAnywhere
address. If the property was missing, an error was logged, and the JMS message
was discarded. This did not provide an appropriate mechanism for handling
JMS messages missing the key property. To fix this, a new configurable JMS
connector property has been added: ianywhere.connector.jms.deadMessageDestination.
This property should be set to the value of a valid JMS Destination. All
messages received by the QAnywhere JMS connector that are missing the ias_ToAddress
property will be forwarded onwards to the JMS Destination specified by the
property ianywhere.connector.jms.deadMessageDestination. See the documentation
section "QAnywhere User's Guide->Setting Up QAnywhere Messaging->Using JMS
Connectors->Configuring the JMS connector properties file" for more information
on setting a connector property.

================(Build #3109 - Engineering Case #386422)================

If a MobiLink server was started with QAnywhere enabled using the -m command
line option and that QAnywhere server was using a connector to a JMS provider,
shutting down the MobiLink server using the GUI shutdown button, the text
console enter key, or dbmlstop, may not have shut down MobiLink cleanly.
That is, the MobiLink server output file may not have contained the line
"MobiLink server finished", as well dbmlstop may have terminated with an
error indicating that it could not shutdown MobiLink, when in fact, MobiLink
had shut down. This has now been fixed.

================(Build #3109 - Engineering Case #386385)================

While attempting to send a message to a JMS provider, if a QAnywhere connector
received certain varieties of Java exceptions from that provider, then the
connector would have stopped sending, and could only be restarted by restarting
the hosting MobiLink server. The variety of Java exceptions that would instigate
the problem were any that had a "null" return from the standard "getMessage"
Exception method. This type of exception is seen in certain situations where
a connection to the JMS provider is lost. This has now been fixed.

================(Build #3104 - Engineering Case #384758)================

A QAnywhere client could have continuously failed to synchronize messages
with a QAnywhere server when using a Microsoft SQL Server consolidated database.
This would have occurred if during the last message synchronization the server
committed the messages from the client, but the connection with the client
dropped before the client could receive the acknowledgement, and a new client
used the same message store id as a previous client message id that was abandoned.
The problem was with the QAnywhere system procedure for handling primary
key conflicts, ml_qa_handle_error. This has been fixed for any new QAnywhere
servers with a Microsoft SQL Server back-end. For existing QAnywhere servers
with a Microsoft SQL Server back-end, the QAnywhere server schema can be
patched by dropping and re-creating the procedure from the fixed syncmss.sql
script.

================(Build #3092 - Engineering Case #381750)================

It was possible, although likely rare, for the JMS connector to lose the
content of a BytesMessage, when the connector failed to send the message,
due to a JMS provider failure, immediately before or during the send operation.
This has been fixed.

================(Build #3035 - Engineering Case #380502)================

If the QAnywhere server contained several thousand undelivered messages (perhaps
because the target clients had not recently synchronized) then the database
server might appear to be using a large percentage of the CPU on its host
machine. The typical solution was to add some indices on the QAnywhere system
tables. Unfortunately, one of the queries being used by the QAnywhere server
was not very efficient, and may have prevented the database server from using
an index. The problem query has been fixed.

================(Build #3034 - Engineering Case #380632)================

The JMS connector would crash when its connection to the consolidated database
was broken. Now, whenever the consolidated database throws a SQLException,
all of the connections in the connection pool are discarded. When the database
is accessed again, new connections are opened which will autostart the database,
instead of using old, invalid connection objects.

================(Build #3028 - Engineering Case #379240)================

A client could have continuously failed to synchronize messages with a QAnywhere
server, using an ASE consolidated database, under the following circumstances:

1 - During the last message synchronization, the server committed the messages
from the client but the connection with the client dropped before the client
could receive the acknowledgement of that fact.

2 - A new client useed the same message store id as a previous client message
id that was abandoned.

The problem was with the QAnywhere system procedure for handling primary
key conflicts, ml_qa_handle_error. If QAnywhere is being using with an ASE
back-end, the QAnywhere server schema can be patched by dropping and re-creating
the procedure from the fixed syncase.sql, (or syncase125.sql), script.

Any new QAnywhere ASE server schemas created with the fixed scripts will
not have the problem.

================(Build #3025 - Engineering Case #378610)================

If the QAnywhere server crashed, it was possible that an incoming JMS message
could have been acknowledged as received without the JMS message being forwarded
onwards as a QAnywhere message. This has been fixed.

================(Build #3024 - Engineering Case #378482)================

Incoming JMS Messages marked as "redelivered", were not being processed correctly
by the QAnywhere JMS connector. This could have resulted in messages being
lost if the connection between the JMS connector and the JMS server was broken
while the connector was in the process of receiving a message. Now redelivered
messages are handled correctly.

================(Build #3024 - Engineering Case #377349)================

If a JMS server associated with a QAnywhere JMS connector went down, then
some QAnywhere messages directed towards JMS, via the connector, may have
been incorrectly routed to the dead message address instead. This has been
fixed such that QAnywhere messages directed to a JMS server that is down,
will be queued until it comes back up.

================(Build #3021 - Engineering Case #378305)================

Sending an empty BytesMessage through the JMS connector may have caused the
connector to crash due to an uncaught NullPointerException. This problem
has been fixed.

Also, the handling of reply-to addresses through the JMS connector was changed
to match the documentation.

================(Build #2551 - Engineering Case #376567)================

Message delivery would have been slow to QAnywhere clients using the "automatic"
policy, with push notifications enabled. Message delivery to the server was
fast, but the server was slow using push notifications to the message addressee
to indicate that a message for the addressee was available. By default, the
delay in the notification could be up to 60 seconds. This has been fixed.
As a work-around however, the server option "ianywhere.qa.server.autoRulesEvaluationPeriod"
can be set in the server configuration file to a lower number, for example
5000 (milliseconds), to speed-up notification check process.

================(Build #2537 - Engineering Case #373526)================

If a QAnywhere connector was configured to connect to WebSphere MQ, and a
QAnywhere message sent to the connector contained an InReplyToID,, (QAMessage::setInReplyToID()
in C++, QAMessage.InReplyToID property in .NET), then the message would not
have been sent onwards to WebSphere MQ. The MobiLink log would show an error
indicating an invalid "JMSCorrelationID". If the connector was configured
with a dead message address, then the message would be re-addressed to that
address. Now, this problem will no longer occur.

================(Build #2537 - Engineering Case #373519)================

If a QAnywhere connector was configured to connect to WebSphere MQ, and the
connector received a JMS BytesMessage with a zero length, the message would
have been ignored. The MobiLink log file would have included a error message
indicating "NullPointerException". With this fix, zero length BytesMessage
will be received correctly.

================(Build #2533 - Engineering Case #372743)================

The QAnywhere JMS connector places a message in the dead-letter queue when
it is determined the message is undeliverable. Binary content messages that
were placed in the dead-letter queue were losing their content. This has
been fixed, such that any new binary messages put in the dead-letter queue
will not lose content.

================(Build #2531 - Engineering Case #372374)================

The JMS connectror dead message address is an address to which messages are
forwarded if it is determined that the message is undeliverable (for example,
the address is not a valid JMS address). If the dead message address was
badly formed, (for example, missing an agentid), then the undeliverable message
would be queued but would be otherwise unreceivable. Now, if the dead message
address is badly formed, the connector will fail to start with an appropriate
connector initialization error message. This will ensure messages queued
against a dead message address will always be receivable.

================(Build #2531 - Engineering Case #372236)================

If the QAnywhere JMS connector received a JMS message having a non-null JMSCorrelationID,
then the QAnywhere server may have failed to receive the message indicating
a NullPointerException. The problem would have occurred even if the JMSCorrelationID
did not refer to a QAnywhere message id. This problem has been fixed.

================(Build #2529 - Engineering Case #370717)================

The setup script for Microsoft SQL Server was missing the last_modified column
in the ml_qa_messages view. While this column is not essential, it is useful
for debugging and manually tracking when messages change status on the server
side. The column has been added.

================(Build #2529 - Engineering Case #370699)================

Upgrading an ASE or Microsoft SQL Server QAnywhere consolidated database
from 9.0.1 to 9.0.2 would have caused all server-side queued messages to
have been lost if the server-side message store had at least one message
queued (ie. the ml_qa_repository table is non-empty). This has now been fixed.

================(Build #2529 - Engineering Case #370190)================

QAnywhere messages received by the JMS connector, that contain an invalid
JMS Destination, are normally placed in the dead-letter queue (specified
using the connector property ianywhere.connector.outgoing.deadMessageAddress).
If the dead-letter address referred to a QAnywhere client message store,
and that client subsequently received the message, then the copy of that
message would have remained in the server repository indefinitely. This problem
is now fixed.

================(Build #2529 - Engineering Case #369796)================

The ReplyToAddress and InReplyToID properties were not being mapped properly
when a message crossed between QAnywhere and JMS.

If a QAnywhere generated message was sent to a JMS client via the QAnywhere
JMS connector, any ReplyToAddress specified on the QAnywhere message (using
setReplyToAddress() in C++ or the ReplyToAddress property in C#) was mapped
over to the JMS property QAReplyToAddress. This differed from the documentation,
which indicated that the ReplyToAddress was mapped to the JMS property ias_ReplyToAddress.
Similarly, the InReplyToID specified on the QAnywhere message (using setInReplyToID()
in C++ or the InReplyToID property in C#) was mapped over to the JMS property
QAInReplyToID rather than the documented ias_InReplyToID.

If a JMS message was sent to a QAnywhere client via the QAnywhere JMS connector,
the JMSReplyTo specified on the JMS message (using setJMSReplyTo()) was mapped
over to the QAMessage property ias_ReplyToAddress rather than to the actual
ReplyToAddress of the message. Hence the ReplyToAddress could not be accessed
by calling getReplyToAddress() in C++ or the ReplyToAddress property in C#.
Similarly, the JMSCorrelationID specified on the JMS message (using setCorrelationID())
was mapped over to the QAMessage property ias_InReplyToID rather than to
the actual InReplyToID of the message. Hence the InReplyToID could not be
accessed by calling getInReplyToID() in C++ or the InReplyToID property in
C#.

This problem has been fixed to behave as documented.

MobiLink - SA Client

================(Build #3922 - Engineering Case #538936)================

The Dbmlsync Integration Component could have crashed during a call to the
Run method. As well, the OS would sometimes have detected a heap error. This
has been fixed.

================(Build #3836 - Engineering Case #572196)================

It was possible for the MobiLink client (dbmlsync) to have sent an incorrect
last download timestamp up to the MobiLink server, if dbmlsync had been running
on a schedule, and ALL of the following had occurred during the last synchronization
:

1) All of the data in the download stream had been applied, but had not
yet been committed to the remote database.
2) An SQL Error had been generated by dbmlsync before the download had been
committed. Examples of errors that could have occurred include an error occurring
in the sp_hook_dbmlsync_download_ri_violation or the sp_hook_dbmlsync_download_end
hooks, or an error occurring as dbmlsync had attempted to resolve referential
integrity issues.
3) Another hook had been defined in the remote database that would have
executed on another connection. For example, the sp_hook_dbmlsync_download_log_ri_violation
or the sp_hook_dbmlsync_all_error hooks would have executed on a separate
connection.

This problem has now been fixed, and the proper last download timestamp
is now sent up to the MobiLink server in the synchronization when this situation
occurs.

================(Build #3795 - Engineering Case #560943)================

The dbmlsync ActiveX component was not able to launch the dbmlsync application
properly on Windows if some or all of the dbmlsync options are given by a
file, and the dbmlsync command line contained the option @filename. This
problem has now been fixed.

================(Build #3714 - Engineering Case #542185)================

When the properties of the visual or non-visual version of the Dbmlsync ActiveX
Component were examined from a development environment, it would incorrectly
have been described as "iAnywhere Solutions Dbmlsync ActiveX Component 9.0.1".
The string has now been changed to properly reflect the true version of the
component.

================(Build #3598 - Engineering Case #486539)================

A synchronization could have failed with the error:
- Could not find subscription id for subscription of <ML user> to <publication>.
or
- SQL statement failed: (-101) Not connected to a database

if all the following were true:
1) the synchronization was scheduled and the time before the next scheduled
sync was more than a 2 minutes
2) for some row in the syssync table, "log_sent" was greater than "progress".
(This occurs when dbmlsync sends an upload to the MobiLink server, but does
not receive an ack/nack to indicate that the upload was applied to the consolidated
database or not)
3) hovering was enabled

This problem has now been fixed.

================(Build #3597 - Engineering Case #487690)================

Normally, the MobiLink client dbmlsync ignores the server side state on the
first synchronization of a subscription, although there was a problem where
dbmlsync might have respected the server side state on a first synchronization,
if an exchange was performed with the server to confirm the progress offsets
of other subscriptions that had previously synchronized. As a result of
this, data could have been lost and synchronizations could have failed with
the error "Progress offset mismatch, resending upload from consolidated database's
progress offset" being reported twice. This has been fixed.

================(Build #3597 - Engineering Case #487689)================

If the MobiLink client dbmlsync did not receive an ack/nack from the server
after sending an upload it has no way of knowing whether the upload was successfully
applied to the server. The best way to resolve this situation is to perform
an 'extra exchange' with the server before the next synchronization to request
the status of the upload, but dbmlsync did not perform this extra exchange
after an unacknowledged upload that occurred during the first synchronization
of a subscription. This would not have resulted in any data loss, but might
have increased the time required for the next synchronization as it might
cause two uploads to be built and sent to the MobiLink server. This has been
corrected so that an extra exchange is now performed in this case to eliminate
the possibility of sending two uploads.

================(Build #3597 - Engineering Case #487688)================

It was possible for the MobiLink client dbmlsync to upload operations for
a subscription that did not belong to that subscription, when all of the
following were true:
1) A subscription, S1, was created to some publication P1, and a second
subscription, S2, was also created for P1 (either by dropping S1 and recreating
it or by creating a new subscription to P1 with a different MobiLink User.)
2) During the first synchronization of S2, dbmlsync successfully sent an
upload but did not receive an ack/nack from the MobiLink server.
3) The upload was not successfully applied to the consolidated database
by the server.

When all these conditions were TRUE it was possible for operations that
occurred before subscription S2 was created to be uploaded when subscription
S2 was synchronized. This behavior has been corrected. Now, only operations
that occurred after subscription S2 was created will now be uploaded when
subscription S2 is synchronized.

================(Build #3597 - Engineering Case #487687)================

If the MobiLink client dbmlsync failed during the brief time between when
an upload was completed and when state information in the database was updated,
then the server would not have been queried at the start of the next sync
to determine if the upload was successfully applied to the consolidated database.
This problem would have occurred extremely rarely, and in most cases would
have been harmless. The result was simply that the next synchronization
took a little longer because an upload was built and uploaded, then rejected
by the server, and a new correct upload was built and uploaded. However
if the failure occurred on a subscription's first synchronization, it could
have resulted in operations being uploaded to the server twice, which would
usually have caused the synchronization to fail with server side errors.
This has been fixed so that the syssync table is updated prior to the end
of the upload. As a result an extra exchange may occur when the end of the
upload was not sent, but the client should never fail to do an extra exchange
when it is required.

================(Build #3597 - Engineering Case #487686)================

If the MobiLink client dbmlsync did not receive an ack/nack from the MobiLink
server after sending an upload, it has no way of knowing whether the upload
was successfully applied. The best way to resolve this situation is to perform
an 'extra exchange' with the server before the next synchronization to request
the status of the upload. Previously, this extra exchange was performed on
the first synchronization after dbmlsync started up. This has been changed
so that it will now perform the exchange any time there has been an un-acknowledged
upload.

================(Build #3548 - Engineering Case #475760)================

If multiple publications were being synchronized separately, and the MobiLink
client (dbmlsync) was running in hover mode, but the SendTriggers extended
option for the publications were not all the same, it was possible for dbmlsync
to not have synchronized trigger actions when they should have been, or to
have synchronized trigger actions when they should not have been. This problem
has now been fixed, but introduces a behaviour change. When multiple publications
are synchronized in hover mode, if the SendTriggers option changes from one
synchronization to the next, a complete rescan of the transaction log is
now executed to ensure that the proper SendTriggers option is used. This
could result in synchronizations taking longer than before, with the benefit
that the data in the synchronization is correct.

================(Build #3545 - Engineering Case #477367)================

When download acknowledgement was enabled, the MobiLink client would have
incorrectly failed to send a download ack for a synchronization if a previous
synchronization during the same run had encountered a server side download
error. As a result the server would report the following error:

Error: Unable to read from the 'tcpip' network connection. Unable to
read 2 bytes.
Error: [-10034] No download confirmation from remote database

This problem has been fixed

================(Build #3533 - Engineering Case #473724)================

When both the graphical and non-graphical Dbmlsync Integration Components
(ActiveX components) were unregistered, they left the following key in the
registry:

HKEY_CLASSES_ROOT\TypeLib\{A385EA65-7B23-4DC3-A444-2E759FF30B14}

This key is now removed when both components have been unregistered.

================(Build #3424 - Engineering Case #450353)================

The MobiLink client would gradually have consumed more and more memory when
synchronizing tables that contained foreign keys that refer to other tables
that were not being synchronized. This has been corrected.

================(Build #3408 - Engineering Case #446806)================

An application would not have shut down after it had NEW'ed a Dbmlsync object
(an object that represented the dbmlsync non-visual integration component
-- dbmlsynccom.dll). When the application closed the last of its windows
the process did not terminate, as the Application.Run() method did not return,
even though all application windows were closed. This problem has been resolved.
The application now shutdowns normally.

Note, this problem did not occur when the graphical version of the integration
component was used (dbmlsynccomg.dll).

================(Build #3379 - Engineering Case #442787)================

The registry entry for the two Dbmlsync Integration Components did not indicate
the threading model that were used. This prevented some containers from loading
the ActiveX components. Now, when these ActiveX components are registered,
it appropriate entries are created in the registry to indicate that it supports
the Apartment threading model.

================(Build #3320 - Engineering Case #433982)================

QAnywhere Java clients now support Windows CE running Windows Mobile 2003
and the J9 VM. The J9 VM is the core of WebSphere Everyplace Micro Environment
(WEME), an IBM(TM) implementation of the Java Virtual Machine Specification,
Version 1.3. The supported J9 runtime is J2ME Personal Profile 1.0 (JSR-62),
based on the CDC/Foundation Profile.

================(Build #3285 - Engineering Case #426153)================

If the MobiLink client was shutdown by clicking the shutdown button on the
window, using the stop method on the integrations component or sending a
WM_CLOSE message to the dbmlsync window, then it could have hung with 100%
CPU utilization. The behaviour would have occurred intermittently, and would
have been more likely on machines with multiple processors. This has now
been fixed

================(Build #3272 - Engineering Case #422828)================

If an sp_hook_dbmlsync_process_exit_code hook was defined and an invalid
dbmlsync extended option was specified, then the synchronization client would
have crashed. This has been fixed.

================(Build #3235 - Engineering Case #415767)================

If the MobiLink client was running on a schedule, and had successfully synchronized,
in very rare circumstances, it was possible for a failed synchronization
to result in the section of transaction log that was scanned during the failed
synchronization to not be scanned again in the next synchronization. This
has now been fixed.

================(Build #3230 - Engineering Case #415025)================

When the Dbmlsync Integration Component was used if a synchronization ended
because of an error, or because the stop method was called, the EndDownload
event may have been fired and the values passed to it for the number of rows
deleted and upserted by the download would have been incorrect. This problem
was transient and would usually not reproduce consistently. This has now
been fixed.

================(Build #3226 - Engineering Case #410251)================

If the MobiLink Client's DownloadReadSize extended option was specified,
it would report an error like the following:

Invalid option "<value>"

where <value> was the value the option was set to, (i.e. -e drs <value>).
The drs option was being treated as a boolean value, when in fact it is a
numeric value. This has been corrected, and the error will no longer be reported

================(Build #3225 - Engineering Case #409231)================

The the graphical version of the Dbmlsync Integration Component (ActiveX)
allowed no more than 30,000 characters to be added to the log window Further
output was ignored, however synchronization continued normally. This limit
is implosed by Windows on Edit controls. To fix this problem, once the Edit
control is full, lines will be deleted from the top of the output to make
room so that new lines can be added at the bottom

================(Build #3221 - Engineering Case #400188)================

If a MobiLink client connected to a database where SQL Remote was already
running, it was possible for the MobiLink client to report "Cannot convert
scanner to a unsigned int". When this error was reported, the current synchronization
would fail. This has been fixed so that the error is no longer reported.

================(Build #3199 - Engineering Case #405360)================

If a value longer than 255 bytes was passed to a MobiLink client hook procedure,
through the #hook_dict table, then the MobiLink client could have become
unstable. This may have occurred when a communications address longer than
255 bytes was specified, there was a failure connecting to the Mobilink server,
and there was an sp_hook_dbmlsync_ml_connect_failed hook defined. This has
now been fixed.

================(Build #3177 - Engineering Case #400604)================

At the end of each synchronization dbmlsync reports a line like the following:

End synchronizing 'template_P1' for MobiLink user 'template_U1'

If more than one publication was specified on the MobiLink Client commandline
(either together as -n P1,P2 or separately as -n P1 -n P2), then the publication
reported in this message may have been incorrect, although processing of
the synchronization would have continued correctly. Only the message was
wrong. The message now reports the correct publication name or names.

================(Build #3138 - Engineering Case #393970)================

Reloading state tracking information into an ASA database for MobiLink synchronization,
would have cause subsequent restartable downloads, or file-based downloads,
to fail. Five new columns were added to sys.syssync in version 9.0.0, but
only 2 columns were being unloaded. This has been fix to now unload the missed
columns.

================(Build #3138 - Engineering Case #393970)================

Reloading state tracking information into an ASA database for MobiLink synchronization,
would have cause subsequent restartable downloads, or file-based downloads,
to fail. Five new columns were added to sys.syssync in version 9.0.0, but
only 2 columns were being unloaded. This has been fix to now unload the missed
columns.

================(Build #3138 - Engineering Case #393633)================

On Windows CE devices, the MobiLink ASA client, (as well as SQL Remote for
ASA) may not have renamed the output file specified by the -o <filename>
option, even when the size of the output file exceeded the size specified
by the -os <size> option. This would have occurred if the output file already
existed before the application started. This has been corrected.

================(Build #3107 - Engineering Case #385179)================

The MobiLink client may not have detected that a table had been altered,
and would have sent an invalid upload stream to the consolidated database.
The following operations in a log file demonstrate the problem, when the
client scanned the log during a single synchronization :
1) Data on table t1 is changed.
2) Table t1 is removed from the only publication it belongs to.
3) Data on table t1 is changed again.
4) Table t1 is altered.
5) Table t1 is added back to the publication it was removed from.

Now, the MobiLink client will report the error "Table 't1' has been altered
outside of synchronization at log offset X" when this situation arises.

================(Build #3105 - Engineering Case #385174)================

The DBMLSync Integration Component would previously have created and written
debug information to a file named dbmlsyncActiveX.log. This file will no
longer be created in released versions of the DBMLSync Integration Component.

================(Build #3105 - Engineering Case #385171)================

If an sp_hook_dbmlsync_logscan_begin hook was defined that modified a table
being synchronized, and the extended option Locktables was set to 'off',
then actions performed by the hook would not have been uploaded during the
current synchronization. Actions would have been uploaded correctly though
during the next synchronization. This has been changed so that any changes
made to synchronization tables by the sp_hook_dbmlsync_logscan_begin hook
will now be uploaded during the current synchronization regardless of the
setting of the Locktables option.

================(Build #3103 - Engineering Case #372331)================

During synchronization it was possible for a Windows CE device to go into
sleep mode. Now the MobiLink client makes system calls to ensure that this
does not happen. It is still possible for a device to go into sleep mode
during a delay caused by the sp_hook_dbmlsync_delay hook or during the pause
between scheduled synchronizations.

================(Build #3102 - Engineering Case #384141)================

When using the Database Tools interface to run the MobiLink synchronization
client, if the a_sync_db version field was set to a value that was 8000 or
greater, and less than the version supported by the dbtools library, then
the upload_defs field would have been ignored. If the database had more than
one subscription, then this would have caused the synchronization to report
the following error message:

Multiple synchronization subscriptions found in the database. Please specify
a publication and/or MobiLink user on the command line.

This behaviour could also be seen if the MobiLink client was used with a
later version of the dbtools library. This has been corrected.

================(Build #3095 - Engineering Case #382167)================

If event hooks were defined, the MobiLink client would not have recognized
and executed them if their procedure name was not entered entirely in lower
case. The case of the procedure name is now ignored.

Note, a similar problem with the Extraction utility and SQL Remote has also
been fixed.

================(Build #3095 - Engineering Case #382166)================

When the MobiLink client extended option TableOrder was specified, the synchronization
would have failed if the tables, or their owners, were specified in a different
case from the one in which they were defined in the database. This problem
occurred whether the database was case sensitive or not. The tables and owners
specified by this option are now always treated as case insensitive.

================(Build #3032 - Engineering Case #377879)================

On Windows CE, when synchronizing a remote database with a double-byte character
set, the MobiLink client would issue the following warning if the database's
character set was not identical to the operating system's character set:

"Unable to convert the string ... from the system collation to the database
collation".

The MobiLink client will no longer issue this warning if the operating system
character set and the database character set are very similar (for example
cp932 and sjis).

================(Build #3025 - Engineering Case #378115)================

The MobiLink ASA client may not have shut down gracefully when it was running
as a Windows service. This may have caused resources such as temporary files,
not to have been cleaned up before shutting down. This problem has now been
fixed.

Note, this problem applied to the MobiLink synchronization server and SQL
Remote for ASA as well, and have also been fixed.

================(Build #3022 - Engineering Case #377878)================

The MobiLink client could have crashed, or behaved irratically, when when
the value of the 'charset' database property for the remote database was
longer than 29 bytes. In particular, this was the case for databases with
the EUC_JAPAN collation, although there may be other such collations. This
issue has been fixed.

================(Build #3020 - Engineering Case #377905)================

The documentation describes a MobiLink client hook called sp_hook_dbmlsync_process_return_code.
The documentation is incorrect in that the name of this hook is actually
sp_hook_dbmlsync_process_exit code. Otherwise the documentation on this hook
is correct.

================(Build #3018 - Engineering Case #377036)================

If the MobiLink client was run with the -vn option, ('show upload/download
row counts'), but not the -vr option, ('show upload/download row values'),
or the -v+ option, ('show all messages'), then the upload row counts reported
for each table would be cummulative, that is each rows count would include
not just the rows uploaded from that table, but also those uploaded for all
previous tables.

================(Build #2542 - Engineering Case #374595)================

After performing a large upload, there was a long pause at the end of synchronization.
This pause would have occurred after the message "Disconnnecting from Mobilink
server" was printed in the log, but before the message "Synchronization Completed".
This has been fixed, although the pause may still occur during a synchronization
when the MobiLink client expects to subsequently perform another synchronization
before it shuts down, (for example because a schedule option has been specified,
or more than one -n switch has been specified on the commandline, or the
restart option in the sp_hook_dbmlsync_end hook has been used). In these
cases the pause at the end of the earlier synchronization is offset by a
time savings in the following synchronization.,

================(Build #2541 - Engineering Case #374490)================

If the environment variables TMP or TEMP were not set, the MobiLink client
dbmlsync, would have given the error:
"Unable to open temporary file "MLSY\xxxx" -- No such file or directory"
and refused to start. This problem is now fixed.

================(Build #2540 - Engineering Case #374070)================

The ASA client dbmlsync, could have crashed, either while creating the upload,
or at the end of the synchronization. This was more likely to occur with
very large uploads. This behaviour has been corrected.

================(Build #2531 - Engineering Case #372085)================

When the Synchronization Client dbmlsync crashed it would have left behind
a temporary file, which would never have been deleted. Now, a check is made
at startup for any temporary files left from previous runs and deletes them
if they exist.

================(Build #2531 - Engineering Case #371856)================

When doing incremental uploads, dbmlsync was making several errors when estimating
the size of the upload. As a result the size of the upload increments were
sometimes very different from the size requested using the increment extended
option. The following sources of estimation error have been fixed:

1) Blobs were not being included in the estimate of the upload size.
2) When synchronizing a subscription for a user with more than one subscription,
some operations were being included in the estimate that were not being uploaded.

================(Build #2529 - Engineering Case #370609)================

The MobiLink Client dbmlsync, would have complained of an "invalid option
...", if it was started with a configuration file, @filename, and filename
contained any extended options specified as
-e opt1="val1";opt2=val2;...
even if all the extended options were valid. This problem is fixed now.

================(Build #2529 - Engineering Case #369238)================

If the schema of a table outside of a publication was altered (for example,
table "t1"), and a synchronizing table existed, whose name started with this
table's name (for example, table "t1_synch"), that had outstanding changes
to synchronize, then dbmlsync would incorrectly report that the schema of
the synchronizing table had been altered outside of synchronization. This
has now been fixed.

MobiLink - Sample

================(Build #3095 - Engineering Case #382174)================

The version information of the QAnywhere C++ TestMessage sample program was
incorrect or missing. This has been fixed.

MobiLink - Streams

================(Build #3606 - Engineering Case #488676)================

The HTTP option 'buffer_size' was limited to 64000 (64KB). On slow networks
and/or large uploads or downloads, the overhead due to HTTP could have been
significant. The 'buffer_size' option is now limited to 1000000000 (1GB).
When using slow networks to perform HTTP or HTTPS synchronizations, tests
could be done with larger values for 'buffer_size' to see if synchronization
times improve.

For versions 11.0.1 and up, this change only applies to the -xo option of
the MobiLink server. The -x option already allows larger values.

================(Build #3465 - Engineering Case #462449)================

Large, non-persistent HTTP synchronizations through a server or proxy, requiring
digest HTTP authentication, would have failed if the session timed-out and
a new session was initiated by the server or proxy. This has been fixed.

================(Build #3102 - Engineering Case #383977)================

The network protocol option network_leave_open is now supported on Palm devices.
Using the new option, a MobiLink client running on Palm can optionally specify
that the network connectivity should be left open after the synchronization
finishes.

The option syntax is as follows:

network_leave_open = { 0 | 1 }

On the Palm platform, the default is 1 where the network connectivity is
left open after the synchronization finishes.

================(Build #3094 - Engineering Case #381849)================

The MobiLink client would only have loaded the first certificate in the trusted
root certificates file specified by the "trusted_certificates" synchronization
parameter. This has been fixed.

Note, this problem did not exist for UltraLite.

================(Build #3094 - Engineering Case #381848)================

For secure TLS synchronization, the MobiLink client would have gone through
the list of trusted root certificates provided and failed with stream error
code STREAM_ERROR_SECURE_CERTIFICATE_EXPIRED if any of the certificates had
expired. This behaviour was incorrect. Now, the client will ignore expired
root certificates when reading them, and will only report an error during
the SSL/TLS handshake if no valid root certificates are found to match the
server.

================(Build #2533 - Engineering Case #372785)================

HTTP authentication would fail with Microsoft's Internet Security and Acceleration
Server 2004. When sending back an authentication challenge, ISA 2004 would
send back the HTTP header "Connection: Keep-Alive", even though the client
sent the header "Proxy-Connection: close", which caused the client to become
confused. This is fixed by having the client ignore connection keep-alive
requests.

================(Build #2529 - Engineering Case #370317)================

HTTP synchronizations would have failed if a proxy or web server used ASCII
characters that were not beteen 0x20 and 0x7e (except for CR and LF) in their
HTTP headers. now only characters less than 0x20 are rejected.

================(Build #2529 - Engineering Case #370166)================

When not going through a proxy server, MobiLink clients always used "localhost:80"
for the "Host:" HTTP header, instead of using the host and port passed via
the synchronization parameters. This has been corrected.

================(Build #2529 - Engineering Case #370165)================

MobiLink client's synchronizing through Microsoft's ISA Server 2000 proxy
server, via HTTP or HTTPS, would have caused the MobiLink server to hang.
This has been fixed for non-persisent HTTP connections (synchronization paramter
'persistent=0'), but not for persistent connections.

MobiLink - Synchronization Server

================(Build #3896 - Engineering Case #591002)================

The changes for Engineering case 582782 could have caused the MobiLink server
to be much slower for small sync than servers without the fix. This problem
would have occurred when a consolidated database was running on an Oracle
RAC. The slowness is in the Oracle server: fetching the minimum starting
time of the open transactions from gv$transaction can take as much as a couple
of seconds and it is much slower than from v$transaction. This has now been
corrected.

================(Build #3868 - Engineering Case #582782)================

When a consolidated database was running on an Oracle RAC, the MobiLink server
could have skipped rows being downloaded to remote databases in a time-based
download. In the following situations, rows modified in the Oracle database
could be missed from the download stream:
1) the MobiLink server connected to one node on an Oracle RAC;
2) another application, A connected to another node on the same Oracle RAC;
3) application A modifies rows in a synchronization table without commit;
4) a MobiLink client, R1 issues a synchronization request that contains
a time-based download from this table;
5) the MobiLink server completes the synchronization request successfully;
6) A commits its transaction;
Then the rows modified by application A would not be down loaded to remote
R1. This problem has now been fixed.

Note, as a result of this change, the Oracle account used by the MobiLink
server must now have permission for the GV_$TRANSACTION Oracle system view
instead of V_$TRANSACTION. Only SYS can grant this access. The Oracle syntax
for granting this access is:
grant select on SYS.GV_$TRANSACTION to <user-name>

================(Build #3769 - Engineering Case #553748)================

When using the iAS ODBC driver for Oracle, calling SQLColAttribute with an
attribute code of SQL_DESC_TYPE_NAME would not have returned the type names
of columns. This has now been fixed.

================(Build #3585 - Engineering Case #485242)================

When using the Dbmlsync Integration Component, an exception could have occurred,
or corrupt data could have been retrieved, if the UploadRow event or the
DownloadRow event was enabled. For this to have occurred, the handler for
the above event must have called the ColumnValue method on the IRowTransfer
object more than once with the same index, and the index used must have corresponded
to a column containing a string or BLOB value. This problem has now been
fixed.

A work around for this problem would be to ensure that the ColumnValue method
is not called more than once for a single index by storing the value retrieved
by the first call in a variable and working with that value.

================(Build #3484 - Engineering Case #466474)================

When synchronization tables on an ASE database server were created with the
'datarows' locking scheme, the MobiLink server could have silently skipped
rows that were inserted by other connections without a commit. The ASE server
doesn't block any other connections that are trying to query the rows from
a table that were created with 'datarows' locking scheme, even when there
are uncommitted inserts for this table. The MobiLink server now work around
this behaviour properly to ensure that no rows are skipped.

By default, the MobiLink server now queries the minimum transaction starting
time from master..systransactions and then sends this timestamp to the client
as the last download timestamp. In the next synchronization for this client,
the MobiLink server will use this timestamp as the last download time for
download. In order to get the starting time, the user ID the MobiLink server
uses to connect to an ASE server must have select permission and the master..systransactions
table. If the user does not have proper permissions, the MobiLink server
will present a
warning message and get the download time from the ASE function getdate(),
reverting to the old behaviour where rows could be missed in the download.
With this change, it's now possible that the MobiLink server may send duplicate
data to clients, if there are any open transactions that modified any tables
in the synchronization database or any databases on the ASE
database server when MobiLink server is doing a download. Although the
clients are able to handle duplicate data, this behavior may reduce MobiLink
server performance.

The MobiLink server now includes two new command line switches so you can
the behaviour of the MobiLink server with respect to tables with the 'datarows'
locking scheme. The -dr switch can be used to tell MobiLink that none of
the synchronizing tables use the 'datarows' locking scheme. The -dt switch
can be used to force MobiLink to detect transactions only within the current
database when determining the last download time that will be sent to the
remote database. The -dt switch should be used if all the synchronizing
tables are located in a single database, as this could reduce duplicate data
sent by the MobiLink server to the clients.

================(Build #3456 - Engineering Case #456829)================

When using Server-Initiated Synchronization, the server could have failed
with a java.lang.OutOfMemoryError exception due to Java heap memory exhaustion.
This would have occurred after many notifications. This is now fixed.

================(Build #3455 - Engineering Case #456868)================

When Mobilink was synchronizing data to a multi-byte Microsoft SQL Server
database, it was possible for the ODBC Driver to fail and return an "Unspecified
Error". The connection to the Microsoft SQL Server would have been dropped,
and the synchronization would have failed. The problem was in the Microsoft
SQL Server ODBC driver, and a workaround has been implemented in the Mobilink
Server to avoid it.

================(Build #3442 - Engineering Case #449676)================

It was possible for the MobiLink Server to have reported that a synchronization
had failed with no apparent error. The failure would happen after performing
the user authentication , even though the authentication had been successful.
The problem was a result of the size of the synchronization stream, so making
almost any change at the remote database would change the size of the synchronization
stream, causing the problem to disappear. This problem has now been fixed.

================(Build #3420 - Engineering Case #452650)================

Instabilities in the Java VM may have been encountered when the MobiLink
server was running under heavy load and low memory conditions, and executinging
Java synchronization scripts. To address this the JRE has now been updated.
This update to the JRE contains fixes that significantly improve the stability
of the JRE when running under these conditions.

================(Build #3392 - Engineering Case #444904)================

When the MobiLink server was listening for HTTP or HTTPS connections, it
would have silently ignored invalid connections/requests. It now displays
an error for each invalid request.

================(Build #3378 - Engineering Case #442684)================

The MobiLink server was not able to upload data from an ASA char/varchar
column to a Microsoft SQL Server nchar/nvarchar column, if the column width
defined in the remote database was greater than 2000 bytes. The Microsoft
ODBC driver would have given the error "Invalid precision value", when the
MobiLink client tried to upload data to a table that contained such columns.
This problem is fixed now.

================(Build #3377 - Engineering Case #442318)================

On Unix systems, an ODBC trace of the MobiLink server would have shown many
calls to SQLSetEnvAttr, as it was being called to set the ODBC version on
every connect. This problem could have caused a hang within the MobiLink
server when connected to a non-ASA consolidated. The hang could have eventually
tied up most, if not all, the server's worker threads, after which the MobiLink
server would have been completely unresponsive. This has been fixed so that
now SQLSetEnvAttr is only called when the environment is allocated.

================(Build #3353 - Engineering Case #438529)================

When a repeatable notification was sent, and the confirmation was not received
within the acknowledgement timeout of the delivering gateway, the notifier
would have deleted the request prematurely without respecting the repeatability
of the request. This problem was introduced by the changes for Engineering
case 437399, and hais now been fixed.

================(Build #3349 - Engineering Case #435217)================

If the upload_update synchronization event had been defined to accept both
the new and old row values being synchronized, the table contained blob columns,
and a new row value for one of the blob columns was of zero length, then
the MobiLink Server would have returned the error : "Error: INTERNAL ERROR:
occurred while retrieving a BLOB -- zero length". This problem has now been
fixed.

================(Build #3344 - Engineering Case #437399)================

If a repeatable notification was sent, and the confirmation was not received
within the acknowledgement timeout of the delivering gateway, the notifier
would have started polling the database once a second. This problem has been
fixed.

================(Build #3336 - Engineering Case #435045)================

If multiple blobs were synchronized from a remote to the consolidated, and
the -bn command line option was used on the MobiLink server, it was possible
for the MobiLink server to have hung while processing the download stream
for this synchronization. This problem has been fixed so that synchronization
of blobs will now complete as expected.

================(Build #3302 - Engineering Case #430086)================

After a deadlock occurred, the upload data for the tables prior the current
table that caused the deadlock may not have been applied to the consolidated
database by the MobiLink synchronization server if the following situations
applied:
1) the MobiLink synchronization was running with the rowset size greater
than 1: the command line option -s X (X > 1) was used or the command line
contained no -s option;
2) the deadlock occurred when the MobiLink synchronization server was applying
the upload operations in multi-row mode and there was no deadlock when the
server was retrying to apply the same operations for the current table in
single-row mode.
This problem is now fixed.

================(Build #3242 - Engineering Case #415985)================

The documented order of events in the prepare_for_download transaction has
been incorrect since the feature first appeared in 7.0.1. The correct order
is:

------------------------------------------------------
prepare_for_download
------------------------------------------------------

modify_last_download_timestamp
prepare_for_download
if( modify_last_download_timestamp script is defined
or prepare_for_download script is defined ) {
COMMIT
}

Previous documentation had the order of the scripts reversed. The above
order was chosen because the last-download timestamp (LDT) affects the content
of the download. If the LDT is being modified, it must be modified before
the download logic kicks in (ie. in the prepare_for_download script or in
the download scripts).

================(Build #3241 - Engineering Case #415877)================

If the authenticate_parameters method was being used as the only method of
authentication for the MobiLink server, and users were automatically being
added to the ml_user table during synchronization with the -zu+ command line
option, and an error occurred when authenticate_parameters was called, or
authenticate_parameters returned an authentication status indicating failure,
then the MobiLink user would still have been added to the ml_user table.
The MobiLink user is now removed from the ml_user table if the authenticate_parameters
fails to authenticate the user.

================(Build #3220 - Engineering Case #409377)================

If the -clrVersion or -clrFlavor .NET command line options were specified
when starting the MobiLink server, the MobiLink server would have reported
that the options were invalid, or not specified correctly. The MobiLink server
will now properly parse and accept these two .NET options.

================(Build #3199 - Engineering Case #405597)================

The MobiLink server would have failed to start if the Notifier properties
stored in the database contained empty SQL statements. This problem has been
fixed.

================(Build #3197 - Engineering Case #402359)================

The MobiLink Synchronization Server was not able to synchronize multi-byte
characters (e.g. Chinese characters) between ASA with the UTF8 collation
and Microsoft SQL server, if the columns were defined as CHAR (varchar, char,
or long varchar) in ASA and NVARCHAR in Microsoft SQL server. A new command
line option, -hwH+, has been added to the MobiLink server. By default, it
is on for Microsoft SQL server and off for all other consolidated databases.
When it is on, the MobiLink server will call SQLDescribeParam (this function
may not be supported by all ODBC drivers, but it is available in the driver
for the Microsoft SQL Server) to find out the data types of the parameters
in the consolidated database and binds the parameters with the consolidated
data types for all the columns with a CHAR datatype.

================(Build #3194 - Engineering Case #404448)================

When connected to an Adaptive Server Enterprise server whose version was
greater than or equal to 12.5.1, the MobiLink Synchronization Server could
have uploaded incorrect data from ASA TIME columns into ASE DATETIME columns
when a cursor-based upload was used. The date part of the uploaded rows
in the ASE database would have been the current date, instead of '1900-01-01'.
This problem is now fixed.

================(Build #3186 - Engineering Case #403187)================

When synchronizing against DB2, the synchronization could have been blocked.
MobiLink uses the table sysibm.systables to select current timestamp, thus
would have been blocked if another application was updating sysibm.systables
at the same time. To solve this problem, the table sysibm.sysdummy1, which
only has one row and is used for compatibility, is now used instead.

================(Build #3147 - Engineering Case #394331)================

When scanning the transaction log to determine which changes need to be uploaded,
if dbmlsync first found a DML statement on a table (for example, an insert),
and then later found a DDL statement on the same table (for example, an ALTER
TABLE), dbmlsync should have failed and reported an error similar to "Table
't1' has been altered outside of synchronization at log offset X". If the
table in question (or it's owner) had a name that required double quotes
around it in the log file (such as reserved words or numeric names such as
"42"), then dbmlsync would not have detected that the schema of the table
had changed and would not have reported the error. Also, if the ALTER TABLE
statement that was executed included a comment either before the ALTER TABLE
statement or between "ALTER TABLE" and the table name, dbmlsync would also
have failed to detect that the schema of the table had changed and would
not have reported the error. Dbmlsync will now report the error "Table 't1'
has been altered outside of synchronization at log offset X" when either
of these situations arise.

================(Build #3121 - Engineering Case #388904)================

The MobiLink server could have failed to gather the synchronization scripts
for a given table and reported the error "Error fetching table script t1.begin_synchronization",
even though table t1 did not have a begin_synchronization script. This problem
was more likely to have occured when using an Oracle consolidated database
and the "iAnywhere Solution 9 - Oracle Wire Protocol" ODBC driver. This
problem has now been fixed.

================(Build #3121 - Engineering Case #388858)================

When synchronizing an ASA MobiLink Client that had multiple publications,
MobiLink would have allocated new memory to store the publication information
on each synchronization. Now, the memory is freed after the synchronization
completes.

================(Build #3097 - Engineering Case #382704)================

The changes made for Engineering Case 377900, would have cause the MobiLink
server to issue a warning that it was unable to fetch the download transaction
time when running against an Oracle8i consolidated database. This has been
fixed. The version of Oracle running the consolidated database is detected
and appropriate statement is issued to fetch the transaction times.

================(Build #3095 - Engineering Case #381111)================

When used with a case-sensitive database, the MobiLink client could have
behaved incorrectly if MobiLink user and publication names were not specified
in the same case as they were defined in the database. These identifiers
might have been specified in any of the following places:
- the CREATE/ALTER SYNCHRONIZATION USER statement
- the CREATE/ALTER SYNCHRONIZATION SUBSCRIPTION statement
- the dbmlsync command line
- the CREATE/ALTER PUBLICATION statement

The incorrect behaviour could take one of the following forms:
- MobiLink client could have crashed
- synchronizations could have failed inappropriately
- if a MobiLink user was subscribed to more than one overlapping publication,
operations that belonged to both publications might have been uploaded more
than once, resulting in server side errors during synchronization.

MobiLink user and publication names are now treated case-insensitively

================(Build #3033 - Engineering Case #380086)================

The last_download_time (LDT) stored on the consolidated database, would have
been incorrectly set during an upload-only synchronization. Note, this wouldn't
affect the LDT stored at the remote, and sent up during synchronization,
only consolidated-side logic that directly inspected last_download_time in
the ml_user or ml_subscription tables would see an incorrect time. The LDT
is now set only when there is a download.

================(Build #3022 - Engineering Case #377471)================

Attemps to synchronize proxy tables would have failed with the error message
"Feature 'remote savepoints' not implemented". This has been fixed.

================(Build #3021 - Engineering Case #377900)================

When using timestamp-based downloads with MobiLink and an Oracle consolidated
database, special steps are required to ensure that all changes will be downloaded.
Otherwise uncommitted changes from before a download may be missed in downloads
that occur after the changes are committed, assuming that triggers are used
to record "last modified" timestamps for each row. In other RDBMSes, the
download will block until changes are committed, assuming MobiLink's default
isolation level, so changes are not missed.

To help download scripts avoid this problem, the MobiLink server now sets
the next "last download time" to the start time of the oldest open transaction.
This ensures that all changes will be picked up in the next synchronization
that occurs after they are committed. The Oracle account used the by the
MobiLink server must have permission for the V_$TRANSACTION Oracle system
view, otherwise the following warning message will be displayed:

Unable to access ORACLE table 'v_$transaction'. Access is needed in order
to ensure no data is missed if using timestamp-based downloads.

Note that only SYS can grant this access, and it must be granted for the
base V_$TRANSACTION view (V$TRANSACTION is a synonym for the V_$TRANSACTION
view, and hence cannot have permission granted on it directly). The syntax
is:

grant select on SYS.V_$TRANSACTION to <user_name>

Workaround:
For earlier versions of the MobiLink server, equivalent functionality can
be achieved with the following procedure:

The simplest way to make sure that all changes are downloaded, assuming
a trigger is used to maintain a last_modifed marker for each row, is to change
the next "last download time" to be the earliest start time of the open transactions.
MobiLink offers the modify_next_last_dowload_timestamp connection event for
modifying the next "last download time", but it is invoked at the end of
the download transaction, and the new value needs to be determined at the
beginning of the download transaction. So the value needs to be determined
in the begin_download connection event, and used in the modify_next_last_download_timestamp
event. In this example the value is stored in a package variable between
the events.

Here are detailed instructions:

1. Ensure that the MobiLink connection (i.e. Oracle user) has permission
to access the V$TRANSACTION Oracle system view. Only SYS can grant this access,
and it must be granted for the base V_$TRANSACTION view (V$TRANSACTION is
a synonym for the V_$TRANSACTION view, and hence cannot have permission granted
on it directly):

grant select on SYS.V_$TRANSACTION to <user_name>

It is essential for the user to have the permission directly, rather than
through a role, because a stored procedure does not have role privileges.

If GRANT access is not wanted on the whole view, instead define a view that
only allows access to the required start_time column, as in the following
example:

create view transaction_start_times
as
select start_time from v$transaction;

grant select on transaction_start_times to public;

2. Create a package with a variable to hold the timestamp value (use DATE
type instead of TIMESTAMP for Oracle 8), and procedures to set and get it
(from MobiLink events):

create or replace package SyncVars
as
procedure SetDownloadTimestamp;
function GetDownloadTimestamp return timestamp;
end SyncVars;

create or replace package body SyncVars
as
DownloadTimestamp timestamp;

procedure SetDownloadTimestamp
as
begin
select nvl( min( to_timestamp( start_time, 'mm/dd/rr hh24:mi:ss' ) ),
localtimestamp )
into DownloadTimestamp
from v$transaction;
end SetDownloadTimestamp;

function GetDownloadTimestamp return timestamp
as
begin
return DownloadTimestamp;
end GetDownloadTimestamp;

end SyncVars;

3. Add a begin_download connection script to determine the timestamp value:

exec ml_add_lang_connection_script( 'version?', 'begin_download', 'SQL','begin
SyncVars.SetDownloadTimestamp(); end;' );

4. Add a modify_next_last_download_timestamp connection script to replace
the timestamp that will be used by MobiLink:

exec ml_add_lang_connection_script( 'version?','modify_next_last_download_timestamp',
'SQL','begin ? := GetDownloadTimestamp(); end;' );

Then the table download_cursor scripts just need to use the usual 'WHERE
last_modified >= ?' clause, since the value that MobiLink passes in for the
question mark will be the timestamp value determined in the previous synchronization.

================(Build #2553 - Engineering Case #490209)================

An error would have been reported when some valid options were entered in
the dbmlsync option dialog on CE. The options affected included -q -Q -qc
-o -ot -os and -wc. This has been fixed.

================(Build #2551 - Engineering Case #376554)================

Upgrading an Oracle 8.1.7 database server, used as a consolidated database
by MobiLink, from ASA version 9.0.1 to version 9.0.2 would have failed if
the standard upgrade script MobiLink\upgrade\9.0.1\upgrade_ora.sql was used.
This script has beed fixed. The failure was as a result of trying to upgrade
the data in QAnywhere system tables, so if QAnywhere is not being used, or
the existing QAnywhere data does not matter, the failure can be ignored,
and the rest of the script executed. If any QAnywhere data is required to
be preserved, the fixed script is needed.

================(Build #2548 - Engineering Case #375421)================

The MobiLink server may have hung, with 100% CPU usage, when fetching user
scripts containing Japanese characters, if the consolidated database was
an Oracle database with Japanese character set JA16SJISTILDE, and the MobiLink
server was running on a Japanese OS and used the Data Direct native ODBC
driver 4.20.00.xx for Oracle. A work around for a problem in the Data Direct
driver has been implemented.

================(Build #2539 - Engineering Case #373623)================

When synchronizing a version 6 or version 7 MobiLink client to a version
9 MobiLink server, that was connected to a RDBMS other than ASA, it was possible
for the MobiLink server to report an "Invalid datetime format" error after
having sent the download stream to the remote. This has now been fixed.

================(Build #2537 - Engineering Case #373541)================

When run on Unix systems, the MobiLink server may have crashed when using
DataDirect's 5.0 Driver Manager. The crash would have occurred when trying
to retrieve an error message from the database server. This has been fixed.

================(Build #2537 - Engineering Case #367198)================

In some very rare cases, an UltraLite application may have marked a column
as a primary key, as well as an index column, thus causing the MobiLink server
to crash when the application synchronized. This problem has been fixed.
Now, the MobiLink server will give a protocol error when this situation is
detected. To avoid the protocol error, the table will need to be dropped
and recreated.

================(Build #2534 - Engineering Case #372262)================

Connecting to the MobiLink server immediately after a successful autodial
could have failed with error WSAEHOSTUNREACH (10065). The fix is to repeatedly
attempt to open the session until it is successful, or the network_connect_timeout
expires, default 2 minutes.

================(Build #2533 - Engineering Case #372205)================

When the Synchronization Server was run using the HTTP stream (ie -x http),
a synchronization failure could have caused the server to crash. This has
been fixed.

================(Build #2529 - Engineering Case #372098)================

In rare circumstances, an upload could have failed with the error "Unknown
Client Error n", where n was some random large number. This error was usually
followed by another error reporting that "A protocol error occurred when
attempting to retrieve the remote client's synchronization log". Although
there are circumstances where this is a valid error to report, an instance
where this error was incorrectly reported has now been fixed.

================(Build #2529 - Engineering Case #370712)================

Upgrading an Oracle consolidated database from 9.0.1 to 9.0.2 would have
left the stored procedure ml_qa_staged_msg_for_client, instead of dropping
it. The undropped procedure wouldn't have affected the behaviour after the
upgrade, it just would never have been used. It is now dropped.

================(Build #2529 - Engineering Case #367764)================

If the consolidated and remote databases had different collations, the MobiLink
Synchronization server may not have respected the column width defined in
the remote database for columns defined with char or varchar datatypes. This
may have caused the ASA client to crash. Now, the MobiLink server will display
an error, and abort the synchronization, if the length of the column value
is greater than the column width defined in the remote database.

MobiLink - Utilities

================(Build #3923 - Engineering Case #611877)================

The Listener utility (dblsn) was failing to recognize the operating system
when run on Windows 6.x systems, which may have resulted in crashes. This
has been fixed.

Note, the Listener utility now tracks the following new Windows 6.x versions:
Windows Server 2008
Windows Vista
Windows 7
Windows Server 2008R2
Future versions will be tracked as "Unrecognized Windows NT ?.?"

================(Build #3728 - Engineering Case #544613)================

In an SIS environment, if a MobiLink client device went offline (device a),
and then another client device (device B) came online with the same device
address (ie. IP address/port) as A, and an SIS UDP notification for client
A was sent by the notifier, then client B would have received and rejected
the notification with an error similar to the following:
Error: <Notifier(QAnyNotifier_client)>: Request 1604437321 is accepted by
invalid respondent 'ias_receiver_lsn'. Please check the message filters on
the listener

This error would have happened whenever a UDP notification for client A
was sent, resulting in wasteful SIS notifications. This has now been fixed.
For 9.0.2, the fix was made only for MobiLink with messaging (QAnywhere)
for ASA consolidated databases. In later versions, the fix applies to all
MobiLink Notifiers in all supported consolidated databases.

================(Build #3594 - Engineering Case #487169)================

The Listener may have displayed an error dialog shortly after startup when
handling notifications. This problem was timing sensitive, subsequent errors
would have gone into the log file and to the console only. This has been
fixed so that errors in handling notification will no longer cause an error
dialog to be displayed. A workaround is to add the -oq switch to the dblsn
command line.

================(Build #3574 - Engineering Case #481845)================

The following fixes have been made to the Listener utility
1) IP tracking was sometimes not firing BEST_IP_CHANGE event when the Listener
was run on Windows CE.
2) Engineering case 466446 introduced a problem in the Listener where options
following the options -ga or -gi may have been misinterpreted.
3) Asynchronous IP tracking (-ga) was not working on Windows CE devices.

Note, the Listener command line option -ga has been deprecated and asynchronous
IP tracking is now implicit. The default of -gi has been changed from 10
seconds to 60 seconds. The polling mechanism now serves only as a backup.
Users should not need to use -gi except for trouble shooting.

================(Build #3542 - Engineering Case #476819)================

When User Account Control (UAC) is enabled, applications cannot have been
registered with the provider for Windows Mobile Device Center (WMDC), either
from dbasinst or from the provider itself. The reason for this was that applications
are registered in the registry under HKEY_LOCAL_MACHINE, which requires administrator
privileges when UAC is enabled. Although dbasinst has been elevated, and
can set these registry entries, the provider was not. This has been corrected
so that applications are now registered under HKEY_CURRENT_USER instead.
However, this means that applications will now only be registered with a
specific user, instead of automatically being registered with all users of
a particular machine. The first time dbasinst is invoked after the patch
has been applied, it will automatically move all registry entries from HKEY_LOCAL_MACHINE
to HKEY_CURRENT_USER.

================(Build #3541 - Engineering Case #477203)================

When using the Dbmlsync Integration Component (ActiveX) and the Message
event was called, the msgID value was set to 0 for some messages that should
have had unique identifiers. In particular this was reported for the message
"Unable to find log offset ....", although other messages were likely affected
as well. The msgID value for these messages would not have been filled in
correctly with a unique value. This has now been corrected.

================(Build #3513 - Engineering Case #471692)================

Multi-byte characters in push notifications may have been lost. This problem
has been fixed.
Note, multi-byte characters are supported in UDP notifications, but SMS
notifications are restricted to 7-bit ascii.

================(Build #3484 - Engineering Case #466446)================

Two command line options have been added to the MobiLink listener (dnlsn)
for controlling ip tracking behavior.

1. The -gi option controls the ip tracker polling interval. The default
is 10 seconds.
example: dblsn.exe -gi 30

2. The -ga option is for asynchronous ip tracking. The -gi option is ignored
when -ga is used.
example: dblsn.exe -ga

================(Build #3428 - Engineering Case #452126)================

The Certificate Generation utility (gencert) cannot handle certificates with
an expiry date beyond January 2038. However, if a validity interval was
specified that put the expiry date beyond this, gencert would have created
an invalid certificate without reporting an error. This has been fixed so
that an interval is specified beyond January 1, 2038, gencert will now reduce
the expiry to this date.

================(Build #3380 - Engineering Case #442898)================

If a server-initiated synchronization property was set to the empty string
or blanks, the property was treated as not set. Blank padded strings were
trimed. This has been fixed so that string properties are accepted as is.

================(Build #3370 - Engineering Case #441243)================

Some carriers are injecting control characters in their SMS message. When
this is done at the end of the message, the MobiLink Listener that received
the message may have reported protocol mismatch errors, and discarded the
message. This has been fixed by removing all control characters in SMS messages.

================(Build #3342 - Engineering Case #437104)================

The Listener utility for Windows, when shutdown on CE devices under heavy
load may have taken a long time. Changes have been made to improve shutdown
times when the device is under load.

================(Build #3340 - Engineering Case #436988)================

The Listener utility for Windows, now logs the command line options when
verbosity is 1 or higher.

================(Build #3327 - Engineering Case #433281)================

If a transaction log was renamed and a new one started, and there were transactions
that spanned the old and new transaction logs, then it was possible for any
of the log scanning tools (dbmlsync, dbremote, dbltm or dbtran) to crash
while processing the two transaction logs in sequence. This problem has now
beem fixed.

================(Build #3305 - Engineering Case #430606)================

MobiLink synchronizations through an IIS redirector could have failed if
the http header sizes added up to an integer multiple of 2k, The problem
has been fixed.

================(Build #3277 - Engineering Case #423803)================

The Service Create utility can be used to create and start the Listen utility
as a service, much like other ASA servers or agents. However, the status
of the service would have remained as "STARTING", even when the listener
was up and running properly. Shutting down the listener service was also
problematic. These problems are now fixed.

================(Build #3246 - Engineering Case #416772)================

The Unload utility may not have properly unloaded a remote database that
was involved in synchronization, causing the reload file generated to contain
syntax errors. This would have occurred if any of the options for synchronization
users or synchronization subscriptions in the remote database had been completely
dropped with:
ALTER SYNCHRONIZATION USER ml_username DELETE ALL OPTION
or
ALTER SYNCHRONIZATION SUBSCRIPTION
TO publication-name
[ FOR ml_username, ... ]
DELETE ALL OPTION
This problem has now been fixed.

================(Build #3231 - Engineering Case #415787)================

The QAnywhere Agent Stop utility was missing a usage message. This has been
fixed. The usage is displayed with the command "qastop -?".

================(Build #3194 - Engineering Case #404437)================

The QAnywhere Central utility was not displaying the clients tree display
in sorted order, so finding a particular client in a list of any size was
difficult. With this fix, the clients are sorted by name.

================(Build #3190 - Engineering Case #408239)================

Changes to the Java redirector have been made so as to better support the
Java Servlet container behaviour in Tomcat 5.5.9.

================(Build #3190 - Engineering Case #403988)================

When using a stored procedure in the request_cursor property, the Notifier
may have failed to start, and in turn caused the MobiLink server to fail
to start. This could have happened when the database source did not support
the use of SQLColAttribute before a statement was executed. For example,
this limitation occurs on Oracle 9.2 with DataDirect's wire protocol driver
4.2, but not with ASA and ASA's ODBC driver. This failure would have caused
a SQLException with the following fragment of stack trace in the MobiLink
log during startup:
...
E. 09/02 11:21:58. Error: at ianywhere.ml.jdbcodbc.IResultSetMetaData.getColumnCount(IResultSetMetaData.java:213)
E. 09/02 11:21:58. Error: at ianywhere.ml.notifier.Notifier.connectDB(Notifier.java:348)
E. 09/02 11:21:58. Error: at ianywhere.ml.notifier.Notifier.init(Notifier.java:299
...

This problem has been fixed, the call to getColumnCount is now delayed until
after the request_cursor is executed.

================(Build #3180 - Engineering Case #408216)================

The native Apache2 redirector now supports initiating HTTPS connections to
Mobilink server. Prior to this new feature, the redirector could only communicate
to Mobilink through HTTP.

PLEASE NOTE THE FOLLOWING REDIRECTOR CONFIG FILE CHANGES:

THe MobiLink directive now supports the following formats for the directive
value.
(This is the old format - which is still supported) - Existing application
can continue to use this format. It's a simple and short format if applications
are not interested in HTTPS
ML=my-pc:82
(This is the new format - which allows for more security options to be specified)
ML="host=my-pc;port=82;trusted_certificates=rsaroot.crt;https=true"

Please note the following with the new format:
1- There is quotation marks that bounds the value of the options list. It
is mandatory that those quotes exist.
2- All Mobilink stream options are valid for the option list (since they
simply get passed along to Mobilink), Only the 'https=' option though is
specific to the redirector only.
2- The option, trusted_certificates (Plural), is where you specify the server
root certificate. This certificate has to be PEM encoded x509 type, which
is simply the supported Mobilink certificate format.
3- The option https=true has to be specified in order for the redirector
to enable SSL at the lower communication layer. Any value other than true
or if the option is omitted, the default is used, which is false.

================(Build #3130 - Engineering Case #392421)================

The IP tracker for the Listener utility may have produced repeated error
messages every second. They are now reported with an exponential increasing
delay with this change.

================(Build #3128 - Engineering Case #391582)================

The Listener utility may have hung on shutdown. This has now been fixed.

================(Build #3045 - Engineering Case #381331)================

The Listener utility may have crashed, if it was shutdown while it was attempting
a long running tracking synchronization. Tracking synchronizations are small
and typically complete or fail quickly. In some rare circumstances, synchronizing
again with a known host, where no MobiLink server was running on the agreed
port, seems to cause the delayed failure. A crash can also happen when a
shutdown was requested during such a delay. This has been fixed.

================(Build #3037 - Engineering Case #380738)================

The MobiLink Palm Listener now supports running on Treo 650 Smartphones.
The implementation has also been added to the MobiLink Listener SDK.

================(Build #3032 - Engineering Case #379909)================

If an IIS web server was setup behind a proxy (see diagram below), when a
client initiated an HTTPS request, the redirector may have failed to route
the request with the error message: "user requesting redirection to unknown
server:xxx". This has been fixed.

Diagram:

CLIENT <----HTTPS----> PROXY <----HTTPS----> IIS <-----> Redirector <----->
MobiLink

================(Build #2921 - Engineering Case #366155)================

When the Listener utility was started with the -t command line option, (enable
or disable remote tracking for a remote database), without using a -x option
for device tracking, the -t option would have been silently ignored. This
behavior has been changed so that the listener will no longer start up,
but will instead fail with an error.

================(Build #2540 - Engineering Case #374085)================

The MobiLink listener's -x option (MobiLink stream parameters) did not accept
stream parameters enclosed in braces. Braces are now allowed after this change.

For example, both of the following are now allowed:
dblsn.exe -x tcpip(host=localhost)
dblsn.exe -x tcpip{host=localhost}

================(Build #2531 - Engineering Case #371870)================

When using Server-Initiated Synchronization, the Listener could have hung
on shutdown, leaving an unresponsive console. A race condition has been fixed.

================(Build #2529 - Engineering Case #370070)================

The SIS Listener did not accept security options over TCPIP connections if
they were specified as part of the MobiLink stream parameters, (ie -x command
line option), when communicating tracking information and confirmations with
the MobiLink Server. This is now fixed so that rsa_tls and certicom_tls can
be used on top of TCPIP.

MobiLink - iAS Branded ODBC Drivers

================(Build #3860 - Engineering Case #573625)================

If an application asked for the connection status through the following ODBC
API
SQLGetConnectAttr( hdbc, SQL_ATTR_CONNECTION_DEAD, ... )
after an error occurred, the iAnywhere Solutions ODBC driver for Oracle
could told the application that the connection was still alive, even though
the connection had actually been killed, or had timed out. If this problem
occurred for the MobiLink server main connection, in most cases, the server
would have displayed the following messages:
[10009] MobiLink table 'ml_scripts_modified' is damaged
[-10020] Unable to flush scripts
and refused any synchronization requests. This MobiLink server would then
have needed to be be restarted in order to carry on any synchronization.
This problem is fixed now.

================(Build #3840 - Engineering Case #574354)================

The iAS ODBC driver for Oracle could have crash in a stored procedure call,
if the stored procedure contained char or varchar type INOUT parameters,
and the data length of these parameters was greater than 2000 bytes (1000
bytes for driver versions, 9.0.2 and 10.0.1). This has now been fixed.

================(Build #3836 - Engineering Case #570915)================

When the iAS ODBC driver for Oracle was used by the MobiLink server to upload
multiple CHAR type columns to a consolidated database running on an Oracle
9.2.0.8 server, it could have failed with the error;
"ORA-01461: can bind a LONG value only for insert into a LONG column"
This problem has now been fixed.

================(Build #3781 - Engineering Case #556326)================

Applications running on Unix systems, and using the iAS ODBC driver for Oracle,
could have received an "Out of memory" error when calling SQLTables, SQLColumns,
SQLPrimaryKeys, SQLForeignKeys, SQLProcedureColumns, SQLProcedures, or SQLStatistics.
This problem has now been fixed.

================(Build #3740 - Engineering Case #547049)================

After calling SQLGetTypeInfo, the application would not have been able to
get the column names through problem could have prvented exporting MobiLink
Monitor data to an Oracle database. This has now been fixed.

================(Build #3735 - Engineering Case #546072)================

The iAS ODBC driver for Oracle could have crashed when the application tried
to create multiple connections concurrently. This problem was more likely
to have occurred on Unix systems. This problem has now been fixed.

================(Build #3681 - Engineering Case #534135)================

The iAS ODBC driver for Oracle could have given mangled error and warning
messages to the application when it was running on a operating system that
used a multi-byte character set, such as a Japanese or Chinese. This problem
is now fixed.

Note, the iAS ODBC driver for Oracle in version 9.0.2 is actually the driver
from version 10.0.1. Versions of the driver with this fix are 10.0.1 3715
or later.

================(Build #3680 - Engineering Case #533958)================

When the event of a download_cursor, or a download_delete_cursor, in a MobiLink
server synchronization logic was written as:
{call procedure_name( ?, ? )}
for consolidated databases running on an Oracle server, the iAS ODBC driver
for Oracle may have given the error:
ORA-06553: PLS-306: wrong number or types of arguments in call to 'procedure_name'
if the stored procedure returned a result set and the word, "call" was not
all in lower-case. This has now been fixed.

Note, the iAS ODBC driver for Oracle in version 9.0.2 is actually the driver
from version 10.0.1. Versions of the driver with this fix are 10.0.1 3686
or later.

================(Build #3174 - Engineering Case #400047)================

When selecting Oracle timestamp values from a table using bound parameters,
the decimal digits from a previous bind and execute are returned instead
of the correct digits for the current bind and execute. The iAnywhere Solutions
Oracle WP driver has been updated to version 4.20.0114

================(Build #3173 - Engineering Case #400050)================

When using the iAnywhere Solutions driver for ASE ODBC driver and executing
a procedure using the native ASE syntax:

begin exec my_proc ? out end

would have returned the correct results for the first time it was called,
but second and subsequent calls would have return incorrect results. Updating
the driver to version 4.20.0106 resolves the problem.

A workaround is to execute the procedure using standard syntax:

{ CALL my_proc(?) }

================(Build #3044 - Engineering Case #376713)================

Inserting BLOBs or CLOBs bigger than 32k, via the iAnywhere Solution 9 DB2
WP driver 4.20.00.25( 9.0.1GA) or 4.20.00.92(B0072,U0065)( 9.0.2GA), would
have failed with the error:

"[ODBC DB2 Wire Protocol driver]Unexpected Server Reply (Conversational
Protocol error code: 146C (PRCCNVCD)). [-1217] ['HY000']"

This problem has been fixed in version 4.20.00.115(B0080,U0069). To upgrade
this driver, the following files should be changed:

wqdb219.dll
wqdb219r.dll

This fix is for Windows systems only.

MobiLink - scripts

================(Build #3019 - Engineering Case #377276)================

Setting up or upgrading an ASE 12.0 database server, used as a consolidated
database by MobiLink, would have failed. The problem was as a result of trying
to setup the QAnywhere system tables, so the errors can be ignored if QAnywhere
is not being used. The setup and upgrade scripts have been fixed.

================(Build #2541 - Engineering Case #365502)================

When upgrading Mobilink from version 6.0.x, 7.0.x or 8.0.x, if the consolidated
database was Oracle version 8i, the upgrade script would have failedwith
the following error:

ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00905: object FPSADMIN.ML_SCRIPT_UPGRADE is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

execute ml_script_upgrade -- failed

The problem is that Oracle 8i does not support the conversion from LONG
to CLOB. This has been fixed by using an Oracle provided function TO_LOB()
instead.

================(Build #2529 - Engineering Case #370835)================

Scripts for upgrading DB2 from 8.0.x and 9.0.0 short schema to 9.0.2, were
missing the MobiLink system triggers. This would have resulted in MobiLink
not working correctly after an upgrade. There are no scripts for upgrading
from 7.0.x and 8.0.0 long schema to 9.0.2, so upgrading from 7.0.x and 8.0.0
long schema to 9.0.2 is not possible. The 9.0.1 upgrade script would not
have dropped the old ml_qa_repository_content table. The 8.0.0 upgrade script
would not have dropped the old ml_add_lang_connec stored procedure. These
have been corrected.

================(Build #2452 - Engineering Case #370074)================

The MobiLink\upgrade subdirectory contains one subdirectory for upgrading
non-ASA consolidated databases from each previous version with different
MobiLink system tables. In each of these directories is a readme.txt file.
Some of these readme.txt files had headings that were misleading, leaving
users to believe that upgrading was a multi-step process, involving a partial
upgrade to a previous, but newer, version, then one or more additional upgrades
to the current version. This is NOT correct, and the readme.txt files have
been corrected.

The proper way to upgrade a non-ASA MobiLink consolidated database of version
6.0.x is to run the appropriate setup script from the MobiLink\setup directory,
followed by the SQL script from the appropriate MobiLink\upgrade\6.0.x subdirectory.

The proper way to upgrade a non-ASA MobiLink consolidated database of version
7.0.x or greater is to run one SQL script from the appropriate MobiLink\upgrade\_version_
subdirectory for the version that is being upgraded from.

There are a few special rules for DB2. Consult the documentation for details,
under:

What's New in SQL Anywhere Studio
Upgrading Software and Databases
Upgrading MobiLink
Upgrading your consolidated database

SQL Remote for Adaptive Server Anywhere - Configuration Scripts

================(Build #3666 - Engineering Case #528978)================

The SQL Remote Message Agent (dbremote) could have displayed the error, "SQL
statement failed: (-260) Variable 'n?' not found", where ? was an integer
greater than or equal to 10, if a replication table contained more than 9
columns (they could have beeb CHAR, BINARY or BIT type columns) with a data
length greater than 256 bytes. This problem has now been fixed.

SQL Remote for Adaptive Server Anywhere - Extraction Utility for Adaptive Server Anywhere

================(Build #3484 - Engineering Case #462482)================

It was possible for stored procedures to be unloaded in the wrong order when
using the Unload or Extraction utilities. In situation where an outer procedure
called an inner procedure, and the inner procedure returned a result set,
if the outer procedure was created first, then calling the outer procedure
would have resulted in the error 'Result set not permitted in InnerProcedure'.
The problem has now been fixed. It's important to note that this fix only
addresses situations where calling the outer procedure does not result in
an error on the original database, but an error is returned when called on
the newly rebuilt or extracted database. If the error is occurring on the
original database, then dropping and recreating the outer procedure should
fix the problem.

SQL Remote for Adaptive Server Anywhere - File Messaging for Adaptive Server Anywhere

================(Build #3272 - Engineering Case #421399)================

It was possible for dbremote to fail to send or receive messages, but no
line was written to the SQL Remote log that started with "E", indicating
that an error had occurred. This has been corrected so that an error line
is now always written to the log after the send or receive of a message fails.

================(Build #3217 - Engineering Case #397776)================

When using the FILE based messaging system for SQL Remote, there is a maximum
of 47,988 possible file names that SQL Remote will use to generate messages.
If all of these file names were already in use, then SQL Remote would have
looped forever trying to find a file name to generate a message. SQL Remote
will now detect that it has tried every single file name and break out of
the loop, reporting that "The maximum number of messages in the messaging
system has been reached". Note that although SQL Remote will now no longer
loop infinitely in this situation, to allow for the creation of new messages
for this remote user, all the files in the user's inbox may need to be manually
deleted, and possibly, the maximum message size increased using the -l switch
on the SQL Remote command line.

SQL Remote for Adaptive Server Anywhere - Mapi Messaging for Adaptive Server Anywhere

================(Build #3430 - Engineering Case #447602)================

It was possible for SQL Remote to have generated MAPI messages which were
visible in the account's inbox, even if the SQL Remote message link option
for IPM_Send had been properly set to FALSE. The IPM_Send variable was not
being properly initialized. This has now been fixed.

SQL Remote for Adaptive Server Anywhere - SQL Remote Message Agent

================(Build #3919 - Engineering Case #467100)================

When very rare, a client application using a shared memory connection could
have hung forever while executing a statement. This has been fixed.

================(Build #3911 - Engineering Case #596641)================

If all of the following conditions were met, then SQL Remote would have continued
to hold locks in the database until the next time that it needed to send
the results of a SYNCHRONIZE SUBSCRIPTION to a remote database:
1) SQL Remote was running in send-only mode (-s)
2) SQL Remote was running in continuous mode
3) SQL Remote was satisfying a resend request for user "X", and was forced
to re-scan the transaction logs
4) While scanning the transaction log, a SYNCHRONIZE SUBSCRIPTION operation
was scanned for a user "Y"
5) User "Y" had already been sent the results of the SYNCHRONIZE SUBSCRIPTION
operation in a previous run of SQL Remote.

This has been fixed by releasing the locks when the send phase of dbremote
reaches the end of the transaction log and determines that the SYNCHRONIZE
SUBSCRIPTION operation does not need to be sent to the remote user.

The problem can be worked around by stopping and starting the dbremote process
that was running in send-only mode.

================(Build #3665 - Engineering Case #528650)================

If the precision for a DECIMAL or NUMERIC column was greater than 30, then
SQL Remote and RepAgent would only have replicated up to 30 digits in accuracy
to a remote or secondary database, and the Log Translation utility (dbtran)
might only have written 30 digits in accuracy to a SQL file. The rest of
the digits would have been replaced by zero. This problem has been fixed.
The accuracy of the replicated/translated data should now be as high as it
was stored in the original database.

================(Build #3307 - Engineering Case #430594)================

If a passthrough session contained "create variable" or "drop variable" statements,
it was possible for SQL Remote to crash when applying the passthrough session
at the remote database. A case sensitive string comparison for "VARIABLE"
was being done, but if a create or drop variable command was executed in
lower case during a passthrough session, the receiving side would fail to
find the name of the variable, leading to the crash. The string is now converted
to upper case before doing the comparison.

================(Build #3209 - Engineering Case #407546)================

The Message Agent could have failed with the error "No log operation at offset
n in the current transaction log", if:
- the database used checksums;
- transactions spanned transaction logs;
- the last replication finished at a commit that was at the end of an offline
transaction log.
This problem has been fixed.

================(Build #3206 - Engineering Case #404450)================

If dbremote were forced to retry an operation that involved a long varchar
or long binary, then dbremote would have reported an error in the dbremote
log similar to "There is already a variable named 'n1'". Dbremote will no
longer report this error.

================(Build #3200 - Engineering Case #406125)================

If the sending and receiving phases of dbremote were being run in separate
dbremote processes, and the sending phase was processing a SYNCHRONIZE SUBSCRIPTION
request, it was possible for the two phases of dbremote to deadlock, resulting
in the sending phase being rolled back. The sending phase of dbremote will
now lock all the tables that are about to be synchronized if it detects that
the receiving phase of dbremote is also active. If the sending phase fails
to acquire the table locks, it will attempt to get the locks 5 times, with
a increasing delay between each attempt ( 100ms, 200ms, 400ms, 800ms). If
all five attempts to acquire the locks fail, the sending phase will attempt
to process the SYNCHRONIZE SUBSCRIPTION without acquiring the locks, which
could still result in a deadlock. To further reduce the possibility of deadlock,
the receiving phase of dbremote should run with "-g 1" to prevent the grouping
of transactions.

================(Build #3199 - Engineering Case #405375)================

If the sending phase of the SQL Remote Message Agent was the victim of a
deadlock, it could have crashed. Note that in order for the sending phase
of dbremote to have been the victim of deadlock, it would have to have been
in the process of satisfying multiple SYNCHRONIZE SUBSCRIPTION commands,
and the send and receive phases of would have had to be running on separate
dbremote processes. The Message Agent will no longer crash in this situation,
but will now report that the sending of messages has failed and will shut
down as expected.

================(Build #3173 - Engineering Case #399512)================

The SQL Remote Message Agent could have failed with the error "No log operation
at offset x in the current transaction log" if the database made use of checksums.
This has now been fixed.

================(Build #3018 - Engineering Case #376895)================

When the database option "Delete_old_logs" was set to "on", SQL Remote, (as
well as MobiLink, and the ASA RepAgent), may reported "missing transaction
log(s)...". This would have occurred in the following situation:
1) the online transaction that contains the last replication/synchronization
offset, had been renamed, say to X;
2) the offline log X contained transactions that started from an early log,
say Y; and
3) the log Y contained transactions started from an earlier log, say Z.
Transaction log Z may have already been deleted. This problem is fixed now.

================(Build #2529 - Engineering Case #354147)================

When the log scanning tools were looking for the log file with the desired
starting log offset, if that log file had a transaction in it which began
in an earlier log file, but the log file that contained the start of the
transaction could not be found, an error would have been reported similar
to "Missing transaction log(s) in between file AC.log (ending at offset X)
and file AD.log (starting at offset Y)". The offsets reported would have
been incorrect, and upon inspection, the ending log offset of AC.log would
have likely been the same as the starting log offset of AD.log. The correct
error is now reported, "Missing transaction log(s) before file AA.log".

SQL Remote for Adaptive Server Anywhere - Smtp Messaging for Adaptive Server Anywhere

================(Build #2529 - Engineering Case #367312)================

When run on Unix platforms, the SMTP message link for the ASA Message Agent
dbremote, would have started and then reported "Execution Complete", with
no errors. This was due to dbremote attempting to load the library libdbencode9_r.so,
rather than the correct library libdbencod9_r.so. Now dbremote loads the
correct library. A work around is to create the following symbolic in the
$ASANY9/lib directory: "ln -s libdbencod9_r.so libdbencode9_r.so".

Note, this problem also affected the SMTP message link for the ASE Message
Agent ssremote, on Unix platforms.

UltraLite - Analyser Java Classes

================(Build #3444 - Engineering Case #455003)================

The UltraLite generator ulgen could, if there was an unreferenced column
and that column was the referencing column of a foreign key, generate an
UltraLite database containing that column. This has been corrected.

================(Build #3349 - Engineering Case #437964)================

Compilation errors could have been produced if an application contained a
TRUNCATE TABLE statement on a table that was not referenced in other statements,
and there existed a foreign key which referenced a table that was referenced
in other statements. This has now been corrected.

================(Build #3263 - Engineering Case #420633)================

The Java code generated by the UltraLite Generator, could have contained
a compilation error when a query contained both DISTINCT and ORDER BY clauses,
and where a temporary table was required to satisfy the query. A extra semicolon
was being generated following a RETURN statement. This \was then detected
as a compilation error by some Java compilers. This has been fixed by eliminating
the extra semicolon.

================(Build #3131 - Engineering Case #392227)================

Certain CASE expressions would have caused a 'feature-not-implemented' error
to be generated by UltraLite Dynamic SQL. IF expressions were mistakenly
omitted from the expression-matching code. This has been corrected.

================(Build #2529 - Engineering Case #370126)================

When using CodeWarrior and Static SQL UltraLite, a statement such as:
SELECT DISTINCT x1, x2, ..., xm FROM <table-expression>
could have resulted in the UltraLite analyzer generating more code than
was necessary. In cases where the number of columns in the select-list was
large (for instance 20), the generated function could have been too large
for the CodeWarrior compiler to handle. This has now been fixed.

UltraLite - Code Generator

================(Build #2543 - Engineering Case #365342)================

The UltraLite Generator ulgen, could have crashed when generating code that
included an index with the same column specified more than once. In some
cases, it would run correctly, but then the application that used the generated
code would have crashed when executing the query that used an index with
the same column specified more than once.

Having a column specified multiple times in an index is not supported by
UltraLite (and would not provide any performance benefits anyway). An error
message is now displayed and the application exits.

The workaround to this problem is to remove the extra column definitions
from the index definition.

UltraLite - CodeWarrior plugin

================(Build #3207 - Engineering Case #403525)================

When large databases were synchronized, UltraLite on Palm with the file-based
data store, could have become very slow and would eventually time out on
conduit synchronization. This has been fixed by allowing users to specify
a larger default cache size, which significantly improves the synchronization
time by cutting down file I/Os.

Now, when the UltraLite conduit is loaded by the HotSync Manager (on the
desktop), it attempts to set the cache size using the value "CacheSize" if
it is specified in the following registry key:

Software\Sybase\Adaptive Server Anywhere\<version>\Conduit\<CRID>

where <CRID> is the creator ID used in an UltraLite Palm application on
remote. The size of "CacheSize" is in bytes, or the suffix k or K to indicate
kilobytes or m or M to indicate megabytes, can be used. If this value is
invalid, it is ignored and the old default cache size of 128KB is used. If
the "CacheSize" value is not set, the UltraLite conduit will use the new
default cache size of 4MB.

UltraLite - HotSync Conduit

================(Build #3150 - Engineering Case #396861)================

When a warning occurs during Palm HotSync synchronizations, HotSync raises
a dialog indicating a problem in the log. The log would have stated 'FAIL',
along with the positive SQLCODE value and message. Now, the log will state
'WARNING' for positive SQLCODE values, and will not cause HotSync to raise
a dialog.

UltraLite - MobiLink Server

================(Build #3642 - Engineering Case #495381)================

If ulview.exe was used to build a USM file and a column was added to the
primary key of a table after adding the same column to an index, would have
resulted in protocol error when
attempting to synchronize. This has now been fixed.

UltraLite - MobileBuilder plugin

================(Build #3142 - Engineering Case #395299)================

When using UltraLite Dynamic SQL it was possible to create incorrect foreign
keys when there were more than two unnamed foreign keys in a table. This
has been fixed.

UltraLite - Native UltraLite for Java

================(Build #3346 - Engineering Case #437586)================

Attempting to use IBM's J9 VM with Native UltraLite for Java would have caused
exceptions regarding deprecated methods in DatabaseManager. IBM's J9, based
on CDC 1.1/Foundation 1.1/Personal Profile 1.1, is now supported.

================(Build #3302 - Engineering Case #430149)================

When an existing entry was deleted from an index in a Java UltraLite database,
the subsequent coalescing of index pages could have left the index corrupt.
This has been corrected.

================(Build #3204 - Engineering Case #406885)================

The Synchronization observer ( ianywhere.ultralite.SyncProgressListener.syncProgressed()
) was invoked for every row during a synchronization. This caused increased
overhead and slowed the synchronization, particularly when using higher-level
components such as Native UltraLite for Java. The observer behaviour has
been changed to issue a maximum of 2 callbacks per second while in the sending
data or receiving data states.

UltraLite - Runtime Libraries

================(Build #3904 - Engineering Case #594288)================

The message for SQLE_INDEX_NOT_UNIQUE errors did not contain the index or
table names. This has been fixed so that the error is now set with the appropriate
parameters.

================(Build #3860 - Engineering Case #576120)================

The MobiLink server would have reported [-10001] 'Protocol error' during
synchronizations, if a DROP INDEX had been issued against the UltraLite remote
database. This has been fixed.

================(Build #3789 - Engineering Case #557837)================

Incorrect results were possible when there was both an equality condition
and another redundant conjunctive expression such as:
x >= 2 AND x = 3
with only a column name on one side of the comparison. That column name
must also have been the first column in an index. This has now been fixed.

================(Build #3680 - Engineering Case #533459)================

In some cases indexes could be left in a bad state after a large number of
rows are deleted. Depending on the subsequent operations the problem could
either have corrected itself, or lead to index corruption. Any table which
ever had a row count that was 256 or more, less than its maximum row count
could potentially have encountered this bug. The most common symptom was
queries that returned less rows than expected. This has now been corrected.
Databases that are suspected of having index corruption should be rebuilt
(eg. ulunload/ulload or start with a new db and synchronize it)

================(Build #3644 - Engineering Case #496110)================

Incorrect results may have been obtained for queries involving GROUP BY,
ORDER BY and HAVING clauses, where no indexes exist to implement the grouping
and the ordering, and where the grouping was such that the ordering could
not have been implied Plans of this situation would have shown two temporary
tables being present. This has now been corrected.

================(Build #3508 - Engineering Case #469674)================

The number of rows being sent by MobiLink to an UltraLite client could have
been more than the number of rows the UltraLite client actually inserted.
Rows could have been lost by UltraLite during synchronization when the primary
key for a table was not the first index in the table. This situation could
have occurred when changing the primary key via the UltraLite Schema Painter
application. This problem has now been fixed. Newly created schemas (or
altered schemas) will ensure the primary key is the first index for every
table. For existing databases, UltraLite will check after loading the schema,
that the primary key is the first index in every table and it will make it
so if necessary.

A workaround to this issue would be to unload and reload the schema and/or
the database.

================(Build #3498 - Engineering Case #469020)================

The internal data structure for a cursor cannot exceed 64K. When a cursor
would be larger than 64K, a diagnostic was not always generated. This was
corrected.

================(Build #3471 - Engineering Case #463517)================

On Windows CE devices, database corruption could have occurred due to a bug
in Windows CE related to growing the database file. A change to the runtime
to close and reopen the file after growing it has been implemented in an
attempt to work around the problem.

================(Build #3464 - Engineering Case #455533)================

When connecting to an UltraLite database with a connection string that did
not contain a password, the application (such as ULISQL) could have crashed.
This has been fixed so that specifying no password is now treated as an empty
string password.

This fix resolves another potential problem: attempting to add a user with
a null password. Calling the C++ method UltraLite_Connection::GrantConnectTo()
with NULL as the second parameter could also have crashed the application.
This has been resolved as well.

================(Build #3457 - Engineering Case #461054)================

The ASCII function would have returned an incorrect value when passed a zero-length
string as an argument. This has been corrected.

================(Build #3454 - Engineering Case #445898)================

When inserting a negative value into a column with an autoincrement default,
the error callback function is called if one was registered with the runtime.
The error passed to the callback was SQLE_OVERFLOW_ERROR however, no error
would have been signaled when checking immediately after the Insert call.
This has been fixed so that no error is now raised at all.

================(Build #3451 - Engineering Case #456324)================

In UltraLite, the dateformat() function was not properly using mixed case
when specified by the format string.
For example:
Select dateformat( ‘2007-02-15’, ‘DDDdddddd, Mmmmmmmm’ ) from dummy

This function would have incorrectly returned “thursday, february” instead
of “Thursday, February”. This has been corrected.

================(Build #3416 - Engineering Case #449439)================

Depending on the device and the mechanisms used, UUIDs are guaranteed or
are extremely likely to be unique. In the case where there was no host address
available, duplicate UUIDs were possible, because the node id was generated
randomly. The quality of the random number used for the node id has now been
improved for Windows CE, thus making duplicates far less likely.

================(Build #3412 - Engineering Case #448760)================

Several improvements have been made for Palm HotSync reliability and VFS
performance as follows:

- Devices with a sufficiently large heap (RAM) now use a RAM-based cache
for VFS file access instead of a storage heap-based cache.

- A fix has been made to prevent a progress mismatch with MobiLink, if a
reset was done at the right moment during a HotSync.

- A fix has also been made to resolve the problem where the HotSync conduit
could have referenced freed memory (likely causing a crash), if the record
database on the device was corrupt (missing pages), but caused no I/O errors.

================(Build #3404 - Engineering Case #446916)================

After doing a schema upgrade (ApplyFile) the values for the last_download_timestamp
of each publication would have been overwritten by the values of last_upload_timestamp.
This has been corrected.

================(Build #3399 - Engineering Case #446667)================

Casting a double with a large positive or negative exponent, into a string
with a large buffer, would have crashed the UltaLite runtime. An intermediary
buffer was too small. This has been fixed.

================(Build #3388 - Engineering Case #444284)================

When preparing statements with non-ASCII characters, Dynamic SQL could have
misinterpreted these characters causing unpredictable results. This has been
fixed. A work around is to enclose strings containing these characters with
double quotes.

================(Build #3336 - Engineering Case #435960)================

When an update was done to a row, any other cursors that were pointing to
that row could have lost the results of previous UltraLite_Table::Set calls.
This has been fixed.

================(Build #3336 - Engineering Case #435957)================

Calling the method UltraLite_Table::UpdateBegin, while on a row that had
been deleted by another cursor, would have caused the next row in the index
to be updated instead. This has been fixed. Now the UpdateBegin call will
fail with SQLE_NOTFOUND.

================(Build #3334 - Engineering Case #434597)================

Opening a table in extremely low memory conditions may have caused an UltraLite
application to crash. The Open() method on the generated class for a table
calls ULTable::init() (in ulapi.c). This method then calls ULOpenBegin(),
which could fail to allocate memory for the cursor if enough memory was not
available. When this happens, an error is set, UL_RUNTIME_EXIT() is called,
and NULL is return. The implementation of init() was checking for the NULL
return, but also calling UL_RUNTIME_EXIT() again. This would have put the
runtime into a state where the next call to the runtime would cause a crash.
This is now fixed.

Since ulapi.c is a distributed source file, a work around for this problem
is to remove the first call to UL_EXIT_RUNTIME() in ULTable::init().

================(Build #3282 - Engineering Case #425515)================

An Ultralite application may have crashed when operations were done on tables
that were near the 64K row limit. This has been fixed.

================(Build #3279 - Engineering Case #424465)================

Indexes in Java UltraLite databases could have become corrupted in some cases,
when a new entry was inserted in to the index page. This has been fixed.

================(Build #3268 - Engineering Case #422131)================

UltraLite Dynamic SQL would have handled a column reference incorrectly if
an alias name was the same as a column name and that name was used in an
IF or CASE statement within the SELECT expression to which the alias was
assigned. This has now been corrected.

================(Build #3268 - Engineering Case #422013)================

Comparisons involving NULL constants (such as column-name > NULL) may have
produced incorrect results or diagnostics. This has been corrected.

================(Build #3265 - Engineering Case #420496)================

On Palm T|X devices running the latest Palm OS v5.4.9, the OS can leave the
record busy bit turned on when the device is reset. This could have caused
UltraLite applications to fail on startup in the call ULAppLaunch(). A work
around has now been implemented.

================(Build #3255 - Engineering Case #419347)================

Using Dynamic SQL could have caused an exception during the execution of
a SQL query. For this to occur, the SELECT statement must have contained
an ORDER BY clause, and no index could be used to achieve the ordering. The
statement must also have contained a GROUP BY clause whose items all occur
in at the start of the ORDER BY clause, in some order, and must also contains
a HAVING clause. This problem has now been fixed.

================(Build #3249 - Engineering Case #418255)================

Using Dynamic SQL with the Palm OS Emulator (POSE), could have caused an
exception during the execution of a CREATE INDEX statement. This was been
corrected.

================(Build #3218 - Engineering Case #408974)================

On Windows CE and Windows Mobile devices, if the host synchronization parameter
was not supplied, applications would have tried to connect to a MobiLink
server running on the machine they had an ActiveSync partnership with. Unfortunately,
on Windows Mobile 5.0 devices, this operation could have failed. This has
now been fixed.

================(Build #3218 - Engineering Case #408613)================

When using Dynamic SQL, incorrect results could have been generated when
a SELECT DISTINCT query was executed, and a temporary table with more than
one column was required to create the result set. The temporary table was
being created with an incorrect primary key. This was been corrected.

================(Build #3216 - Engineering Case #407421)================

When executing a Dynamic SQL query containing a CASE statement, incorrect
errors could have been produced. This has been corrected.

================(Build #3207 - Engineering Case #407032)================

Write access to an UltaLite database was denied (with error code -89) during
synchronizations, even if the application was only pinging the MobiLink server.
This has been fixed so that now write access is permitted during synchronization
when doing a ping or a download-only synchronization. Write access is still
denied if when sending an upload to MobiLink.

Also, the runtime now permits a ping synchronization if there are uncommitted
transactions.

================(Build #3201 - Engineering Case #406890)================

A call to the ULSynchronize() could have caused stack corruption if an error
occurred and synch_info.stream_error.error_string was not NULL but synch_info.stream_error.error_string_length
was 0. This has been fixed.

================(Build #3199 - Engineering Case #405913)================

When using Dynamic SQL, erroneous results could have been produced if the
SUBSTRING() function was called with negative lengths. This has been corrected.

================(Build #3190 - Engineering Case #403970)================

The reserve_size connection parameter was being applied to the temporary
file as well as the main database file. This essentially doubled the space
allocated by reserve_size unnecessarily. Now, the reserve_size parameter
applies only to the main database file, and the temporary file is created
initially to contain a very small number of pages.

================(Build #3189 - Engineering Case #403811)================

Dynamic SQL did not properly handle aliases in metadata. For example, it
did not recognize an alias for a result set column that was a column in a
derived table. This has corrected.

================(Build #3177 - Engineering Case #401216)================

When using Dynamic SQL, executing a CREATE TABLE statement that involved
LONGVARCHAR or LONGBINARY columns could have caused a corrupt database. This
was corrected.

================(Build #3150 - Engineering Case #396917)================

UltraLite Dynamic SQL could have produced erroneous metadata for columns
in derived tables. The algorithm for matching user-supplied names with metadata
was flawed for some cases in derived tables. This has been corrected.

================(Build #3142 - Engineering Case #395313)================

When using UltraLite Dynamic SQL the result of the UPPER() function was erroneously
being treated as 256 characters long. This has been corrected.

================(Build #3130 - Engineering Case #392205)================

The SPACE() function in UltraLitre Dynamic SQL would have accepted a negative
value. This has now been corrected.

================(Build #3103 - Engineering Case #397223)================

Java UltraLite could have generated code which had compilation errors when
queries with an EXISTS was used. This was corrected.

================(Build #3103 - Engineering Case #384317)================

UltraLite could have generated incorrect results for queries that required
a temporary table, when DISTINCT and ORDER BY clauses were both present.
For example :
SELECT DISTINCT quantity, quantity + 1 FROM table ORDER BY quantity
where there was no index starting with the column named quantity. This has
been fixed.

================(Build #3100 - Engineering Case #383497)================

The ResultSet classes's GetState() method could return the incorrect state
when the query contains a LEFT OUTER JOIN. Specifically, if the last row
in the result set supplied NULL values for the right hand expressions, calling
GetState() after fetching all rows would return UL_RS_STATE_ON_ROW instead
of UL_RS_STATE_AFTER_LAST or UL_RS_STATE_BEFORE_FIRST.

Some applications might use GetState to determine whether a result set has
been completely fetched (for example, the UltraLite Interactive SQL utility
does this). These applications would not have behaved properly when executing
a query like the one described
above.

This has been fixed.

================(Build #3098 - Engineering Case #382317)================

The UltraLite runtime could have caused a crash when a subquery contained
outer references to more than one table

For example,
select * from T1, T2
where T1. x in ( select x from T3 where T1.z = T3.z and T2.y = T3.y
)

This has been corrected.

================(Build #3096 - Engineering Case #382443)================

UltraLite applications could have produced incorrect results with a query
that had both a left outer join and an order-by cluse which referenced columns
only from tables on the left side of the left outer join.
For example:
select * from t1 left out join l2 on t1.a = t2.b order by t2.x

This has ben fixed.

================(Build #3033 - Engineering Case #380189)================

When a unique constraint violation error occurred, the UltraLite run-time
would have only generated a PRIMARY_KEY_NOT_UNIQUE error (SQLCODE -193),
with no context information about which table caused the violation. Now if
a download unique constraint violation error occurs, the conflicting table's
name is added as part of the error parameters.

================(Build #3031 - Engineering Case #401161)================

UltraLite can now be run on Palm NVFS devices, and it supports both the record-based
and file-based data stores.

The following is a summary of UltraLite clarifications for the Palm OS platform.

A. Database
An internal file volume may also be present on some NVFS devices, such as
Tungsten T5 handhelds, which you can access and use similar to an SD slot.
Therefore, call ULEnableFileDB to store UltraLite databases on either an
internal drive (built-in storage card) or external slot (expansion card).
Furthermore, use the existing connection parameter palm_db=CRID:n to specify
the data store on either an internal drive or external slot. n is the volume
ordinal from enumerating the mounted volumes, and the default value of n
is 0. Tungsten T5, for example, has two volumes, the internal file volume
and the SD slot volume. If the device cannot locate a volume with the user-specified
volume ordinal, the SQLCODE -82 is reported when opening the database.

B. Synchronization Conduit
The conduit synchronizes the UltraLite database which is first found on
the device. The database lookup sequence is first the record storage, then
the file system including internal drive and external slot. Make the UltraLite
database which you intend to synchronize available as the first one found
in that sequence.

================(Build #3021 - Engineering Case #374301)================

Attempting to synchronize via HTTPS through an Internet Information Services
web server, with a VeriSign certificate, would have failed. This has been
corrected.

================(Build #3014 - Engineering Case #377011)================

UltraLite could have produced incorrect results when an index was used in
reverse order, and the indexed column contained NULLs. This has now been
fixed.

================(Build #2551 - Engineering Case #375851)================

When using UltraLite Dynamic SQL, a LIKE condition could have produced incorrect
results, if the left operand was a column which occurred first in an index,
and that column was larger than 126 characters. This has now been fixed.

================(Build #2546 - Engineering Case #375368)================

UltraLite UNICODE ODBC did not handle DECL_DECIMAL properly. The conversion
to string, required by the ODBC definition, did not append a null delimiter
character to the converted string with UNICODE. This has been fixed.

================(Build #2542 - Engineering Case #374620)================

When calling UltraLite_TableSchema::GetIndexSchema( ordinal ), if the ordinal
was greater then the number of indexes in that table schema, an error would
have been generated, and an illegal UltraLite_IndexSchema object would have
been returned. Using a method on that object would have then caused a crash
(illegal memory access). This is now fixed.

================(Build #2541 - Engineering Case #374535)================

The Ultralite Dynamic SQL parser did not support the Datetime() function
and incorrectly generated a syntax error. This has been fixed.

================(Build #2538 - Engineering Case #373705)================

Ultralite Dynamic SQL could have produced incorrect results with an ANY condition
in the WHERE clause, if there was a subquery that contained a reference to
a column in the original query. This has been fixed.

================(Build #2536 - Engineering Case #373215)================

Ultralite Dynamic SQL could have produced incorrect results when the left
table expression of a LEFT OUTER JOIN contained multiple INNER JOIN expressions.
This has been fixed.

================(Build #2535 - Engineering Case #373035)================

Performing a synchronization that downloaded rows to a table on which a cursor
had been opened, could have resulted in the cursor being positioned on an
incorrect row following an ABSOLUTE fetch.

UltraLite tries to optimize ABSOLUTE fetches by replacing them with RELATIVE
ones (if it thinks it will be more efficient). The algorithm first verifies
that no tables in the cursor have been modified, otherwise it does not attempt
the optimization. The problem occurred due to the synchronization code not
marking the tables as modified. Now they are.

================(Build #2529 - Engineering Case #371423)================

Ultralite Dynamic SQL would have failed to create a foreign key which referenced
the same table as was being created by the CREATE TABLE statement. This has
been fixed.

================(Build #2529 - Engineering Case #370247)================

If Ultralite Dynamic SQL attempting to execute a query that used an alias
name in the GROUP BY clause, it would have failed with a syntax error.

For example,

SELECT length( city ) AS city_length, count(*) FROM invoices GROUP BY city_length

was diagnosed as erroneous. This has been corrected so that alias names
in the GROUP BY clause are now accepted.

================(Build #2529 - Engineering Case #367932)================

Ultralite Dynamic SQL would have failed to prepare a CREATE TABLE statement
when one of the columns contained a partition size with a global autoincrement
default.

For example:

CREATE TABLE tab (
rowid int not null primary key,
col_a int default global autoincrement( 10000 )
)

This has now been fixed.

================(Build #2529 - Engineering Case #367695)================

If queries that required temporary tables were used, and then a schema upgrade
was done, it was possible that a crash could have occurred when these queries
were then run after the upgrade. A crash would not have occurred if the database
was restarted after the schema upgrade. Temporary table structures were not
being preserved across a schema upgrade. They are now restored at the end
of the schema upgrade.

================(Build #2529 - Engineering Case #367396)================

Ultralite Dynamic SQL would have failed with a conversion error, when attempting
to convert character strings to and from LONGVARCHAR columns, and binary
values to and from LONGBINARY columns. This problem has been corrected

================(Build #2529 - Engineering Case #367160)================

Ultralite Dynamic SQL would have erroneously reported an overflow error for
integers larger than 2147483647. A problem computing the precision correctly
has been fixed.

UltraLite - SQL Preprocessor

================(Build #3510 - Engineering Case #470582)================

The error 'Function or Column name reference "Unknown" must also appear in
GROUP BY', may have been erroneously raised when an IF expression involved
an aggregate function.
For example:
IF count(n) > 50 THEN 'good' ELSE 'bad' ENDIF
This has been corrected.

UltraLite - UltraLite Engine

================(Build #3321 - Engineering Case #432184)================

In PocketPC 2003 Applications, calling the MIN() function would have returned
the MAX-Value, and the MAX() function would have returned the Min-Value.
This has been fixed.

================(Build #3292 - Engineering Case #427456)================

When the UltraLite generator was run against a schema that included UUID
column types, and it was configured to generate the C++ API, it would have
generated code that referenced SQL_UUID. This symbol was not defined, causing
a compiler error when the code was compiled. This has been fixed by defining
the symbol SQL_UUID.

A work around is to add SQL_UUID to the enum listed in ulapi.h just before
SQL_MAX_INDEX.

================(Build #3268 - Engineering Case #421957)================

When UltraLite Dynamic SQL executed a query with both an ORDER BY clause
and a GROUP BY clause, an incorrect ordering could have occurred when there
existed an index to satisfy the ORDER BY, but no index existed for the GROUP-BY.
This has been corrected.

================(Build #3226 - Engineering Case #414410)================

Executing CREATE INDEX and DROP INDEX statements with Dynamic SQL could have
caused databases to become corrupt. This has been fixed.

================(Build #3207 - Engineering Case #406574)================

Dynamic SQL applications could have crashed when a nullable column participates
in an index optimization, and the predicate involved a host variable.

For example,
SELECT name from Table where name < ? (name starts an ascending index)
SELECT name from Table where name > ? (name starts a descending index)

This has been corrected.

================(Build #2544 - Engineering Case #374053)================

When using UltraLite Dynamic SQL, it would have taken a long time (approx
30 minutes) to create tables, when there were more than 200 tables already.
This has been fixed.

================(Build #2541 - Engineering Case #374459)================

If a client connection to an UltraLite engine crashed, or terminated without
properly calling DatabaseManager::Shutdown, and had autostarted the engine,
the engine would not automatically shutdown. This has been fixed.

================(Build #2541 - Engineering Case #374441)================

When using the UltraLite Engine, connections to a database could have failed
with error SQLE_UNRECOGNIZED_OPTION, if the StartLine connection parameter
was provided for autostarting the engine. This has been fixed.

================(Build #2535 - Engineering Case #372635)================

Ultralite Dynamic SQL was failing to respect an ORDER BY clause when there
was an index that could have been used to satisfy the ordering and there
existed another index that could have been used to optimize the search conditions.
This has now been corrected.

================(Build #2529 - Engineering Case #369273)================

When used in Ultralite Dynamic SQL the SWITCH-CASE expression could have
caused memory to be over-written. This has now been fixed.

================(Build #2529 - Engineering Case #367267)================

When using CREATE INDEX, Ultralite Dynamic SQL could have created an invalid
index, if one or more of the columns being indexed were already used in another
index. This problem has been corrected.

================(Build #2529 - Engineering Case #365929)================

An UltraLite application would have crashed on the final step of the following
sequence:
- Execute a query that contains a temp table
- Suspend and close the connection
- Re-connect to the database
- Apply a new schema file
This has been fixed.

UltraLite - UltraLite Schema Painter

================(Build #3751 - Engineering Case #543216)================

The Schema Painter would have failed to save schema if it contained multibyte
characters. This has been fixed.

================(Build #3246 - Engineering Case #417414)================

Changing the MobiLink Script Version field in the "Generate Consolidated
Database and MobiLink Scripts" dialog did not update the actual script version
in the generated MobiLink scripts. This has been corrected.
Workaround: After generating scripts with a new MobiLink script version,
use File|Save to save the schema. This will update the underlying meta information
file. Then generate the scripts again, the new MobiLink script version field
will now be used.

================(Build #3196 - Engineering Case #404915)================

When using the UltraLite Schema Painter, it was not possible to define a
Numeric column as autoincrement. An error dialog would have been displayed,
stating that the default was not compatible with the type of the column.
The Schema Painter was missing Numeric from its list of valid autoincrement
column datatypes. This has been corrected.

================(Build #2535 - Engineering Case #373248)================

When creating a foreign key with the UltraLite Schema Painter, the table
for which the foreign key is being created (the table doing the referencing)
was not listed as a table that could be referenced. This has been fixed,
self-referencing foreign keys can now be created.

================(Build #2532 - Engineering Case #372513)================

The UltraLite Schema painter could have crashed when creating a foreign key.
This has been fixed.

================(Build #2529 - Engineering Case #370134)================

With a new schema that had spaces in its pathname:

1. creating an UltraLite database would have failed with the error:
"UltraLite database creation failed. Error: cannot specify additional arguments"
2. generating MobiLink scripts, or ASA SQL, for that database would have
failed with the error:
"Script generation failed. Possible installation or path issue. Error:
only one XML file/sync block can be specified"

This problem has been corrected.

================(Build #2529 - Engineering Case #366930)================

It was possible to get a schema file into a state where creating a foreign
key was not possible. In the Schema Painter, attempting to create a foreign
key would have resulted in the error: SQLCODE -113 Column in foreign key
has a different definition than primary key, even though the domains of the
columns appeared to be the same. This problem occurred when the domain for
the column did not have a size, or precision and scale, thus making the domain_info
irrelevant when checking for column compatibility in foreign key creation.
Now, if the column type does not take a size, or precision and scale, the
domain_info is not compared.

A work around is to convert the database schema definition from USM to XML,
and back again:

ulxml.exe -toxml schema.usm schema.xml
rename schema.usm schema_old.usm
ulxml.exe -tousm schema.xml schema.usm

The new schema.usm will then allow creating a foreign key.

UltraLite - UltraLite for AppForge MobileVB

================(Build #3318 - Engineering Case #432645)================

After setting stream parameters, a Synchronize with callbacks would have
lost the stream parameters, preventing the connection/sync from happening.
This has been fixed. The only workaround is to not use callbacks for the
Synchronize operation.

================(Build #3265 - Engineering Case #421397)================

The ApplyFile() method's enumeration constants for state changes had incorrect
values, the Error and Done states were reversed. This has been coreected.
The correct values for ulUpgradeStateError and ulUpgradeStateDone are 3 an
4 respectively. A successful ApplyFile() call will generate the states 0,
1 or 4. States 2 and 3 are only produced when an error occurs.

================(Build #3203 - Engineering Case #406894)================

When the Synchronize() method was called with an observer function, a callback
was invoked for every row during a synchronization. This caused increased
overhead and slowed the synchronization, particularly when using higher-level
components such as UltraLite for MobileVB. The observer behaviour has been
changed to issue a maximum of 2 callbacks per second while in the sending
data or receiving data states.

================(Build #3097 - Engineering Case #382670)================

When running an AppForge Crossfire application in hosted mode (ie, in the
development environment) calling ULConnection.Close() might not actually
close the connection. If an application called Close() and then tried to
open the database again, it could cause SQL code -955 SQLE_CONNECTION_ALREADY_EXISTS.

One case that could lead to this was when ULColumn variables were assigned
and the garbage collector had not disposed of them before the call to ULConnection.Close().
An internal reference from the column objects to the connection prevented
the connection from closing. This will not happen when running on actual
devices, as garbage collection in the AppForge client is more predictable
on devices.

This has been fixed so that calling ULConnection.Close() will close the
connection and subsequent calls on the ULColumn object will return SQLE_CURSOR_NOT_DELCARED.

UltraLite - UltraLite for M-Business Anywhere

================(Build #3472 - Engineering Case #462642)================

Queries involving 'long varchar' or 'long binary' columns, containing both
null and non-null values, and a temp table, could have caused a crashed in
UltraLite, signaled an error, or produced incorrect results for the 'long'
columns. This has now been fixed.

================(Build #3434 - Engineering Case #453026)================

Calling the method ResultSet.Close() before the method PreparedStatement.Close()
would have resulted in a memory leak. This has been fixed.

================(Build #3393 - Engineering Case #445219)================

When the ULPod method ResultSetSchema.close() was called, the UltraLite runtime
object ResultSetSchema was released twice. This may have caused rare crashes
to have occurred. This has been fixed.

================(Build #3389 - Engineering Case #444498)================

The UltraLite stream objects, reader and writer, were not being released
correctly when ResultSet pods object is closed. This memory leak has now
been fix.

================(Build #3377 - Engineering Case #443495)================

Previously, ULPod only allowed one database connection per database manager.
Opening a new connection meant that the existing connection had to be closed
first. Now a DatabaseManager pods can open up to 10 different connections
at the same time. Opening more than 10 connections will result a SQLE_TOO_MANY_CONNECTIONS
error being returned. At this point, existing connections will need to be
closed in order to open new ones. To maintain the behavior compatibility
with the prvious ULPod, this new feature is
achieved through new methods on the DatabaseManager object.

New API methods:

For SA 10
ULPodConnection DatabaseManager.openConnectionEx(string conString)
ULPodConnection DatabaseManager.reOpenConnectionEx(string conName)

For ASA 9
ULPodConnection DatabaseManager.createDatabaseEx(string conString)
ULPodConnection DatabaseManager.createDatabaseWithParmsEx(ConnectionParms
parm)
ULPodConnection DatabaseManager.openConnectionEx(string conString)
ULPodConnection DatabaseManager.openConnectionWithParmsEx(ConnectionParms
parm )
ULPodConnection DatabaseManager.reOpenConnectionEx(string conName)

The difference between the Ex() and non-Ex() functions is that the Ex()
version
supports multiple connections, while the non-Ex functions do not.

================(Build #3369 - Engineering Case #440234)================

UltraLite Dynamic SQL could have generated incorrect results, and could have
possibly raised an exception, when there were host variables in the select
list for a query and temporary tables were required. This has been fixed.

================(Build #3298 - Engineering Case #429129)================

Two cases of memory leaks have been fixed in the ULPod component.

Case 1: If a PrepStmt pods object was not explicitly closed, the SQL string
stored in the object was not freed when an AvantGo client exited.

case 2: In SyncParms.getAuthenticationParms(), pods array elements used
to construct the output array were not freed properly afterwards.

================(Build #3298 - Engineering Case #428862)================

When host input variables were used in binary operations (such as comparisons
using LIKE) and the other operand of the operation had a string type, Ultralite
Dynamic SQL would have used the size of the other operand as the size for
the host input variable as well. This could have lead to incorrect results
when the string value was larger than the size designated for the host input
variable. This has been fixed by increasing the sizes used to handle most
reasonable cases, without using the maximum size which could impact the performance
of existing applications.

For example, a query of the form
SELECT * FROM table WHERE col-a LIKE ?
where col-a is a 5-character column with a value '12345', would have generated
a row in the result set for a host input value of '1234567%' (because that
value would be truncated to '12345').

Similar problems existed with other comparisons.

================(Build #3285 - Engineering Case #425943)================

The SQLError object was missing two error constants: SQLE_INVALID_OPTION_SETTING
and SQLE_METHOD_CANNOT_BE_CALLED. This has been corrected.

================(Build #3262 - Engineering Case #421349)================

The One-button synchronization feature of UltraLite for M-Business Anywhere
did not work correctly if the synchronization stream was HTTPS. The Certicom
libraries required were not being linked into ulconnect.exe. This has now
been corrected.

================(Build #3249 - Engineering Case #416625)================

The M-Business client would have crashed on File | Sync. If ulpod9.dll was
removed from the client machine, the crash no longer occurred. When the client
performs a sync, it sends a PODS_NOTIFY_PRESYNC event to the ULPod component.
ULPod uses this chance to close the current UltraLite database connection,
so that the same database can be opened later by ulconnect.exe for one-button-sync.
The connection was closed by calling the Close() method on the Connection
pods object, which in effect destroyed the Connection pods object. The has
been fixed by adding an internal method to the Connection object that does
the same thing as Close(), except it does not destroy the Connection object
itself. The PODS_NOTIFY_PRESYNC event handler now calls this function instead
of Close().

================(Build #3133 - Engineering Case #392504)================

If the method PreparedStatement.executeStatement(), as well as several others,
returned a non-zero SQLCode, an exception would have been thrown. This was
incorrect behaviour as positive SQLCode values are warnings. The problem
has been fixed to only throw exception when the SQLCode is less than zero.

================(Build #3033 - Engineering Case #380178)================

When ULPod threw an exception from Connection.Synchronize(), the message
field of the exception only contained the string "SQLE_xxx", giving the type
of the error, with no reference to the error context parameters. This information
was not enough to help diagnose the problem. For example, a UNIQUE constraint
violation during download would have caused the error from MobiLink: "download
failed with a client error -196", and the UltraLite client side would only
received a generic "SQLE_xxx" error string. It would have been very difficult
to identify on which table the violation occured.

Now, extra information has been added to the message field of the exception
thrown from Connection.Synchronize(). If a download UNIQUE constraint occurred
inside UltraLite runtime, the conflicting table's name is added to the error
parameters. ULPod will append the first three error parameters to the end
of the SQLE_xxx" string, separated by ":". For example, the following message
field of a synchronization exception "SQLE_SERVER_SYNCHRONIZATION_ERROR:-10013"
tells that the MobiLink server error code is -10013.

================(Build #2531 - Engineering Case #372289)================

On PalmOS devices, if a user entered the M-Business Client, and then exited
to the home screen without doing anything, it would have crashed. This has
now been corrected.

UltraLite - UltraLite for eMbedded Visual Basic

================(Build #3510 - Engineering Case #470562)================

When synchronizing with stream parameters pointing to a MobiLink server on
a different machine, carrying out several synchronization operations in a
row could have produced errors such as SQLE_COMMUNICATIONS_ERROR or SQLE_SYNC_INFO_INVALID.
This would not have occurred if the stream parameters string was empty and
the defaults were used. This has been fixed.

================(Build #3204 - Engineering Case #406895)================

When the Synchronize() method was called with an observer function, a callback
was invoked for every row during a synchronization. This caused increased
overhead and slowed the synchronization, particularly when using higher-level
components such as UltraLite ActiveX. The observer behaviour has been changed
to issue a maximum of 2 callbacks per second while in the sending data or
receiving data states.

================(Build #3186 - Engineering Case #403181)================

The ULSyncParms property that is documented as "StreamParms" was actually
coded as "StreamParams". This method has been corrected to be "StreamParms"
as documented, and an alias of "StreamParams" added for backwards compatibility.
The code samples have also been updated to use "StreamParms" instead of "StreamParams".

UltraLite - UltraLite.NET

================(Build #3443 - Engineering Case #454871)================

The method ULConnection.Synchronize(ULSyncProgressListener) could have thrown
an exception that application code could not catch, typically a unrecoverable
error like SQLE_DEVICE_ERROR. Worker threads were not trapping errors from
connection.Close(), as this exception was thrown from a worker thread, the
application could not catch it. This has been fixed.

================(Build #3437 - Engineering Case #453438)================

If UltraLite encountered a permanent error (ie SQLE_DEVICE_IO_FAILED), due
to the removal of an SD card, a subsequent attempts to close a connection
would have caused a crash with a native error. This has been fixed.

================(Build #3418 - Engineering Case #449459)================

If ULTransaction.Commit() failed (for example due to a referencial integraty
error), and the then ULTransaction.Rollback() was called, Rollback() would
have failed to report that the transaction had already completed. This has
now been corrected so that Commit() will only mark the transaction as completed
if there were no errors. A work-around is to close the connection and then
re-open it. A side-effect of this will be that all prepared statements will
be invalidated.

================(Build #3385 - Engineering Case #443856)================

If the non-security version of UltraLite.NET was installed and an attempt
was made to use the HTTPS synchronization stream, no error would have been
displayed and the SyncParms.Stream would have been set to UNKNOWN. A SQLException
SQLE_COULD_NOT_LOAD_LIBRARY is now thrown. This is the same error that occurs
when trying to set the HTTPS stream with the security version of UltraLite.NET
and the native ulrsaw9.dll is missing.

================(Build #3349 - Engineering Case #420898)================

In certain cases, with download acknowledgements turned off synchronization
through ActiveSync 4.x could have failed, even though the same sync would
have worked through ActiveSync 3.x. The reason for the failure is that with
ActiveSync 4.x, the internal proxy will time out the connection 15 seconds
after the server has finished sending the data and closed its side of the
connection, while with ActiveSync 3.x, the proxy would wait indefinitely
for the client to finish reading all the data before closing the connection.
Microsoft has indicated that this change was intentional, in order to avoid
resource leaks. A change has been made to improve download performance which
will increase the likelyhood that the client will finish reading the download
before the time out expires.

================(Build #3235 - Engineering Case #415894)================

The DLLs in <install dir>\ultralite\UltraLite.NET\ce\x86 were version 9.0.2.3211
in all EBFs from build 3212 on, and hence were unusable. UltraLite.NET would
have reported an error like "Unable to load dll ulnet9.0.2.3221" (where 3221
was the build of the EBF). Other CE platforms were not affected. These DLLs
are now properly updated.

================(Build #3235 - Engineering Case #415537)================

Changes have been made to UltraLite.NET to allow it to integrate with Visual
Studio 2005 (VS2005).
- In Smart Device and Windows projects, a reference to the iAnywhere.Data.UltraLite.dll
is available in the "Add References" dialog box.
- The SyncProgressDialog can be added to a project by selecting Project,
Add New Item.
- The ULConnectionParms controls are available, but must be added manually
as described below due to a problem in Visual Studio 2005. If a Compact Framework
DLL is added to the GAC before one of its controls is added to the VS2005
toolbox, the control will be permanently greyed out.

In the instructions below, <VS2005InstallDir> refers to the installation
directory of Visual Studio 2005. For example, "C:\Program Files\Visual Studio
2005\"

To add the ULConnectionParms controls to the toolbox, do the following after
the install:
1. Open the Visual Studio 2005 program.
2. Go to Tools, Choose Toolbox Items.
3. Note that there is already an iAnywhere.Data.UltraLite DLL with "Global
Assembly Cache" as its Directory.
4. Add the following DLL by clicking Browse:
<VS2005InstallDir>\SmartDevices\SDK\CompactFramework\2.0\v2.0\WindowsCE\iAnywhere.Data.UltraLite.dll
5. Check ULConnectionParms for the two iAnywhere.Data.UltraLite DLLs from
steps 3 and 4. Press OK.
6. Finally, in a command prompt (or the <Start>, Run dialog) , run
<VS2005InstallDir>\SDK\v2.0\Bin\gacutil.exe -i <VS2005InstallDir>\SmartDevices\SDK\CompactFramework\2.0\v2.0\WindowsCE\iAnywhere.Data.UltraLite.dll

================(Build #3213 - Engineering Case #408074)================

UltraLite.NET did not work with the .NET Compact Framework v2.0. New compatible
assemblies can now be found in <install dir>\ultralite\UltraLite.NET\ce\VS2005\.
These assemblies are based on the ADO.NET 1.0 API but have been recompiled
to work with v2.0.

Please note the following behaviour change:

The ULConnectionParms control does not work with Visual Studio 2005. Instead,
use the ULConnectionParms class programatically which functions exactly the
same as the control. Make a ULConnectionParms object and set its properties.
Finally, to get the connection string, call the ToString() method, as with
the control.

The SyncProgressDialog wizards are not available for Visual Studio 2005.
Users should visit codeXchange web-site for samples of the SyncProgressDialog.

Also note the the following behaviour changes have been observed in the
.NET Compact Framework 2.0:

1. Decimal object scale preserved

In Decimal objects, scale (i.e. number of digits after decimal place) is
preserved when converted to string even if the digits are zero.

As an example, the following piece of code will behave differently between
.NET Compact Framework 1.x and 2.0. In this example, a decimal value of
5 is assumed to have been placed in a Decimal column that has a precision
of 4 and a scale of 2.

ULDataReader dr = cmd.ExecuteReader();
dr.MoveFirst();
Decimal d = (Decimal) dr.GetValue( 1 );
Console.WriteLine( d );

Console Output under .NETF v1.x:
5

Console Output under .NETF v2.0:
5.00

2. ULRowUpdatedEventArgs and ULRowUpdatingEventArgs

In the ULRowUpdatedEventHandler method, getting the TableMapping property
of the given ULRowUpdatedEventArgs object behaves differently when run with
.NET v1.x and .NET v2.0. With .NET v1.x, null is returned when no TableMapping
is associated with the event. With .NET v2.0, an empty TableMapping object
is returned.

3. Deployment of resources on devices

iAnywhere.UltraLite.resources.dll and iAnywhere.Data.UltraLite.resources.dll

Consider the following directory structures:
Directory Structure #1
<curdir>\iAnywhere.Data.UltraLite.dll
<curdir>\iAnywhere.Data.UltraLite.resources.dll
Directory Structure #2
<curdir>\iAnywhere.Data.UltraLite.dll
<curdir>\en\iAnywhere.Data.UltraLite.resources.dll

With .NET v1.x, the resources dll could have been placed in the same directory
as the executing assembly or in a directory with the name of its culture.
That is, Directory Structure #1 and #2 are both acceptable.

With .NET v2.0, the resources dll must be placed in a directory with the
name of its culture. That is, using Directory Structure #1, the Compact
Framework will not be able to find the resources dll. Using #2 on the other
hand, the Compact Framework will find the resources dll.

================(Build #3207 - Engineering Case #406942)================

An UltraLite application could have taken a long time to time-out when attempting
to establish a connection over GPRS if the MobiLink server was not running.
If the client_port synchronization parameter was supplied with a large range
of ports, the client could take an extremely long time to time out, as each
port was tried in succession. This has been fixed so that the connection
attempt will now time out after the number of seconds specified in the "network_connect_timeout"
parameter has passed.

================(Build #3204 - Engineering Case #406730)================

The Synchronization observer ( iAnywhere.Data.UltraLite.ULSyncProgressListener.syncProgressed()
) was invoked for every row during a synchronization. This caused increased
overhead and slowed the synchronization, particularly when using higher-level
components such as UltraLite.NET. The observer behaviour has been changed
to issue a maximum of 2 callbacks per second while in the sending data or
receiving data states.

================(Build #3191 - Engineering Case #404134)================

The utility installULNet.exe, which removes and reinstalls Visual Studio
integration for UltraLite.NET, was failing to re-install the Sync Progress
Dialog wizards. This has been fixed.

================(Build #3103 - Engineering Case #384281)================

UltraLite could have incorrectly generated null results for expressions referencing
NOT NULL columns in tables to the right of a LEFT OUTER JOIN. This would
have happened for result set rows fetched after NULLs had been supplied for
the right hand side. This has been fixed.

================(Build #3087 - Engineering Case #380814)================

In locales where the decimal place separator is a comma, (ie French, Greek,
etc.) the methods DataReader.GetDecimal() and ULTable.SetDecimal(), or a
ULParameter with Decimal value, would have failed with the exception:
SQLE_CONVERSION_ERROR: Cannot convert System.Decimal to a Decimal

This has now been fixed.

================(Build #3035 - Engineering Case #380454)================

Calling the method ULDatabaseSchema.ApplyFile() would not have ignored extra
parameters in ULConnectionParms which it didn't need. This has been fixed.

================(Build #2533 - Engineering Case #372770)================

String transfers to UltraLite, on Windows CE devices, was slower than neccessary.
This has been fixed in the iAnywhere.Data.UltraLite namespace only.

================(Build #2529 - Engineering Case #370197)================

If a SELECT statement resulted in unnamed columns, the ULDataAdapter object
would have named the first unnamed column as "Column1", but then named subsequent
unnamed columns as "1", "2", "3", etc. Subsequent fills would not have equated
the first unnamed column as mapping to DataTable "Column1" and thus created
"Column2", growing the DataTable by one column each time Fill() or FillSchema()
was called.

Now, unnamed columns are named "Column1", "Column2", etc.. As a workaround,
columns may be named using aliasing in the SELECT statement.

Example (C#):
ULDataAdapter da = new ULDataAdapter( "SELECT MIN(SomeCol), MAX(SomeCol),
SUM(SomeCol), AVG(SomeCol) AS Average FROM SomeTable", conn );
DataTableMapping dtm = da.TableMapping( "Table", "MyTable" );
dtm.ColumnMappings.Add( "Column1", "Min" );
dtm.ColumnMappings.Add( "Column2", "Max" );
DataSet ds = new DataSet();
da.Fill( dataSet );

// dataSet now has DataTable "MyTable" with columns "Min", "Max", "Column3",
and "Average"

================(Build #2529 - Engineering Case #370046)================

The following issues have been corrected when filling a DataSet or DataTable
with the ULDataAdapter, and the ULDataAdapter.SelectCommand was of type TableDirect.
Dynamic SQL SELECT statements were not affected.

Only the name and type was specified for new columns when using Fill() with
MissingSchemaAction.Add. AllowDBNull, AutoIncrement, ReadOnly, Unique were
set only when Fill() with MissingSchemaAction.AddWithKey was used. Column
properties are now set for all new columns.

When FillSchema() or Fill() with AddWithKey was used with a non-empty DataTable
and the columns did not match the source properties with respect to AllowDBNull,
AutoIncrement, and Unique, DataException, ArgumentException, and InvalidConstraintException
might have occurred. Existing columns are now left as the user specified
them.

If a data source column was flagged as autoincrementing, the DataColumn
might have had its type corrupted, possibly resulting in a loss of data during
Fill(). If the DataTable contained data, an ArgumentException was thrown,
otherwise, an OverflowException might have been thrown during Fill(). Now
exisiting columns do not have their properties modified by Fill() or FillSchema().
New autoincrementing columns of data source type SmallInt, Integer, BigInt,
Decimal are flagged as AutoIncrement and may have their type sized up to
prevent Fill() errors. Other new autoincrementing columns (in particular
UnsignedBigInt) are not marked in the DataTable as AutoIncrement since .NET
does not support AutoIncrement with non-signed integer types.

UltraLite - Utilities

================(Build #3851 - Engineering Case #573843)================

In an UPDATE statement, no diagnostic error message was issued when a SET
clause was not followed by a name. Thisn has been fixed so that an eroor
message is now issue for this situation.

================(Build #3751 - Engineering Case #549518)================

The Schema Painter Create UltraLite Database Browse dialog was not filtering
for database files, but incorrectly filtered by SQL files (*.sql). This has
been fixed.

================(Build #3545 - Engineering Case #478022)================

Applying Microsoft's XML security patch KB 936181 (MSXML 4.0 dll version
4.20.9848.0) to Windows Vista systems, would have caused the UltraLite Load
utility to crash. This problem does not show up on Windows XP. A work around
has been implemented to prevent the crash.

================(Build #3501 - Engineering Case #469570)================

If the default command file for the Listener utility (dblsn,txt) was used
implicitly, then having the -q option in the command file would have had
no effect on the gui, instead of minimizing it. The desired behavior was
achieved if the same command file was used explicitly (i.e. dblsn.exe @dblsn.txt).
This problem has been fixed.

================(Build #3349 - Engineering Case #438141)================

If the ulload utility was used (without using the -i option) to load data
into a _nosync table, then any future deletes to those loaded rows would
have been leaked. This may eventually have caused UltaLite to hit its 64K
row limit (SQLE_DBSPACE_FULL error will be raised in this case). There was
no way to clean up the leaked rows, so the table could no longer have been
updated once the 64K limit was reached.

The workaround is to use ulload -i. This has been fixed by effectively
invoking the -i functionality, but only for _no_sync tables. So now rows
populated through ulload can be deleted, and they will be physically removed
from the database on a commit.

================(Build #3289 - Engineering Case #426786)================

Some aggregate expressions were not handled correctly by Dynamic SQL when
there was no GROUP BY clause.
For example, when table is empty:
SELECT ifnull( sum(x), 0 ) FROM table
This has been corrected.

================(Build #3262 - Engineering Case #420179)================

Dynamic SQL could have produced incorrect results for comparisons, when the
following conditions were true:
- a nullable column was being compared
- the nullable column occurred first in an index or foreign key
- the expression being compared was of a different type than the collumn
and could be casted to the type of the column
- the index or foreign key could have been used as part of the plan to execute
the query
This has now been corrected.

================(Build #3259 - Engineering Case #419848)================

The UltraLite Interactive SQL utility should be able to connect to databases
created on the desktop, Windows CE (i.e. Unicode databases) and Palm OS (either
in the record store or on the VFS). However, it was failing to open an UltraLite
database created by a Palm application on the VFS, returning a database not
found error (sqlcode -954). This has been fixed.

Note, when attempting to connect to an UltraLite database created by a Palm
OS application, and stored on the VFS, remember to include "palm_fs=vfs"
in the connection string. This tells UltraLite that this Palm database uses
the file store instead of the record store.

================(Build #3177 - Engineering Case #401758)================

Previously, all UltraLite database types, except Palm VFS files, could be
created by the UltraLite command line tools (ulload and ulcreate). Now, a
.udb file suitable for deployment to a Palm VFS card can be created by adding
"palm_fs=vfs" to the connection string on the command line.

For example,(Note the -p switch is still required):
ulload -p CRID -c dbf=ul_udb_CRID.udb;palm_fs=vfs my_schema.xml

When deployed to the device, the database name must follow the pattern ul_udb_XXXX.udb
where XXXX is the creator id of the application. Furthermore, the file must
reside in the /PALM/UltraLite/ folder.

================(Build #3160 - Engineering Case #398799)================

The UltraLite utility would not have run when the system did not have VFS
Manager services e.g. devices running Palm OS 3.5. This is now fixed. The
presence and proper version of the VFS Manager is now checked when the utility
starts.

================(Build #3126 - Engineering Case #390940)================

The ulload utility could have crashed due to a stack overflow exception,
when very large data sets were loaded into PalmOS databases. The loop that
loaded rows into a table did an implicit memory allocation. When the scope
of the loop was exited, the memory was not freed, eventually after very many
rows caused a stack overflow. This has now been corrected.

================(Build #3094 - Engineering Case #382072)================

When the UltraLite Interactive SQL utility was displaying a result set in
the “Results” tab, selecting (with the mouse) an element from the first column
twice would have made that item editable. Attempting to change the value
would then have failed (hitting ENTER would return the value to its original
state). Then disconnecting (F12), while the item was in this edit mode, would
have caused the UltraLite Interactive SQL utility to crash. This has been
fixed by no longer allowing the result set to be editted (it must be done
via a SQL statement), and the crash no longer occurs.

================(Build #3018 - Engineering Case #377161)================

The error code displayed by the UltraLite Interactive SQL utility when a
query failed, or after an unsuccessful connection, did not correctly display
the SQL Code associated with the error. This has been fixed, it now will
display the SQL code after the initial error message.

================(Build #3018 - Engineering Case #377141)================

The UltraLite Interactive SQL utility would have displayed only part of a
column's name in the header of the result set after a query result was initially
executed. This has been fixed, it will now display the entire column name,
making it easier to read the result set

================(Build #3011 - Engineering Case #376892)================

The following issues with UltraLite Interactive SQL's Open Connection dialog
have been addressed:

- If the extension (.udb or .pdb) of the database file was missed, it was
not automatically added. Now a connection will be attempted with the file
name as specified, and then with a .udb extension, and then finally with
a .pdb extension.

- The browse button would initially display only .udb files. Now both .udb
and .pdb files will be displayed.

- It was not possible to scroll the Filename combo box. This has been fixed.

================(Build #2936 - Engineering Case #369030)================

If ulisql utility was configured to fetch all data for each column (i.e.
not truncate values), attempting to execute a DDL statement after executing
a query, would have resulted in the error “A schema upgrade is not currently
allowed”. This has been fixed.

================(Build #2538 - Engineering Case #372615)================

When the UltraLite Initialization utility ulinit, was run against a blank
padded ASA database, each object (table, column, index, publication etc.)
in the generated UltraLite schema was padded by many spaces. Since the –z
switch on ulinit (specify a table ordering) required a list of tables, ulinit
could not properly handle this switch. This has been fixed.

The workaround is to unload and reload the ASA database into a non-blank
padded reference database.

================(Build #2535 - Engineering Case #373250)================

When creating a foreign key with one of the UltraLite utilities (Schema Painter,
ULXML, ulload, ulcreate, ulconv or ulisql), the application could have crashed,
if the foreign key referenced a table that had a self-referencing foreign
key. This is now fixed.

================(Build #2531 - Engineering Case #371911)================

Two problems with the UltraLite Interactive SQL utilitu ulisql, have been
fixed. First, statements with carriage returns and tabs had these characters
stripped off after they were executed. Recalling the statement would have
caused it to have been displayed all on one line. Now the format is preserved.
Second, when ulisql was launched, immediately recalling the last command
would have incorrectly displayed the second last command.

================(Build #2531 - Engineering Case #371909)================

When running the UltraLite Interactive SQL utility ulisql with the Plan tab
selected, executing a query, then disconnecting, then reconnecting again
and re-executing the query, would have caused ulisql to crash. This has
been fixed.

================(Build #2529 - Engineering Case #370446)================

The return values from the UltraLite utilities ULCONV, ULCREATE, ULDBSGEN,
ULLOAD, ULSYNC, ULUNLOAD, and ULXML have been changed from negative to positive
values. This allows batch files to use ERRORLEVEL.

================(Build #2529 - Engineering Case #370320)================

The Quiet command line option (-q) was missing from the UltraLite XML utility's
(ulxml) usage message, as well as the documentation. It has now been added.

================(Build #2529 - Engineering Case #369985)================

When attempting to start ULISQL on operating systems older than Windows 2000,
a message would have been displayed complaining that SHGetSpecialFolderPath
could not be found in shell32.dll. This entry point is available in newer
versions of shell32.dll (sometimes available with updates of Internet Explorer)
and in shfolder.dll on older systems.

Now, ULISQL will use shfolder.dll if the entry point is not found in shell32.dll.

================(Build #2529 - Engineering Case #369735)================

Executing a statement with an error and then switching to the Plan tab, would
have caused ULISQL to crash. This has been fixed.

================(Build #2529 - Engineering Case #368015)================

The following changes have been made to generate correct values and foreign
names in the output SQL stream:
1. UltraLite tables with TIME columns that defaulted to CURRENT TIME, or
a specific date, was incorrectly generated.
2. A uniqueidentifier column that defaulted to NEWID was incorrectly generated
as new_uuid.
3. Foreign key names were not being output in the ALTER TABLE ADD FOREIGN
KEY statement.

================(Build #2452 - Engineering Case #370129)================

Japanese characters would not have been displayed properly in the SQL command
window of ULISQL. This has been fixed.