Caché Release Notes and Upgrade Checklist Archive
Caché 2009.1 Upgrade Checklist
[Back] [Next]
Go to:

The purpose of this section is to highlight those features of Caché 2009.1 that, because of their difference in this version, affect the administration, operation, or development activities of earlier systems.
Those customers upgrading their applications from earlier releases are strongly urged to read the upgrade checklist for the intervening versions as well. This document addresses only the differences between 2008.2 and 2009.1.

The upgrade instructions listed at the beginning of this document apply to this version.
This section contains information of interest to those who are familiar with administering prior versions of Caché and wish to learn what is new or different in this area for version 2009.1. The items listed here are brief descriptions. In most cases, more complete descriptions are available elsewhere in the documentation.
CPF File Changes
Significant changes have been made to the format and content of the configuration parameter file (CPF). In addition, more stringent validation of the file is done during system startup. Valid files from earlier releases will be automatically converted to the new format upon first upgrade to 2009.1.
Invalid CPF files will prevent Caché from installing or starting up. The currently active CPF file must be validated, and errors fixed, BEFORE the system is upgraded to this version. Validation and correction of the CPF file should occur a few days before the system is upgraded, and rechecked just before upgrade to make sure any issues are addressed in advance of the upgrade.
There are two ways to validate the CPF file before upgrading a particular system:
  1. For those customers who subscribe to the Technical Assistance program, InterSystems provides a standalone program to check the validity of CPF files before installing 2009.1 to valid customers. The program is available from the WRC Direct page. Once you login, choose CPF Validation from the available options.
    You will be prompted to enter the directory and filename of the CPF file you want to validate. The file will be uploaded to the WRC, validated, and a list of any errors will be displayed. You can then correct any errors, and revalidate the file until all errors are corrected.
    If you do not have a userid and password, contact InterSystems Worldwide Response Center (WRC).
  2. From a system where 2009.1 is already installed, start a terminal session. From the terminal session, in the %SYS namespace, you can run the validation routine as follows:
    Set Status = ##Class(Config.CPF).Validate(<CPFFILE>)
    where <CPFFILE> is the directory and filename of the currently active CPF file. A list of errors will be displayed on the terminal screen. You can then edit the CPF file, correct the errors, and rerun the validation routine.
In both cases, after all corrections have been made, and the CPF file has been completely validated, you can replace the CPF file and restart your system to have the new settings take effect.
If you use any additional CPF files other than the currently active one, you must also run the validation routine and correct any errors against those CPF files before they can be used.
Changes In Package, Routine, And Global Mappings
In version 2009.1, two major changes have been made to the way globals, routines, and global subscripts are mapped:
  1. The rules for these items have been unified.
  2. Erroneous mapping definitions now result in configuration file validation errors that prevent Caché from starting up.
In prior versions, global subscript mappings could not have overlapping ranges such as
but this was not true of global and routine mappings. In these instances, the mappings were applied in the order found in the configuration file and errors were silently reconciled. For example, a mapping like
A:D ->DB1
B:E ->DB2
would have been silently interpreted as the mapping
A:D -> DB1
D:E -> DB2
when the system was started.
The range “A:D” is treated as the mathematically half-open interval [A-D), that is, beginning with “A” up to, but not including, “D”.
In prior versions, the order of the mappings was important. In the conversion of the mappings for use in 2009.1, any overlaps are converted to an equivalent set of non-overlapped mappings. The following table gives some examples:
Prior Version Mapping Converted Mapping For 2009.1
Because the conversion process produces non-overlapped mappings, the order of the mapping is no longer important.
In 2009.1, overlapped mappings can still be present in the CPF file or entered into the Management Portal as long as they form proper subsets. This means that mappings such as those in the first column of the last row of the table will be converted as shown when upgrading to version 2009.1. However, this same set will result in errors if found once the system has been upgraded.
Before upgrading a system from 2008.2 to 2009.1, sites are strongly urged run the CPF validator to determine if the configuration file it intends to use is correct. The ways to do this were described in a preceding section.
Sites that have overlapped mappings are strongly encouraged to test the converted mappings to make sure that all previous data remains accessible and that new data is stored where it was intended.
It is good practice to validate all the CPF files a site intends to use before they are first employed in production. If a site switches to an alternate CPF file without converting it, the CPF file will be converted to the new format when it is used for the first time.
If you need assistance with the conversion process, please contact InterSystems Worldwide Response Center (WRC).
Management Portal Changes
Because of the new rules for resolving overlaps, the order of the mappings in a configuration file no longer matters. For this reason,
Other Mapping Changes
The mappings of the ^oddPROJECT, ^CacheMsg, and ^CacheMsgNames globals have been changed; they will be stored in the default ROUTINE database for a namespace, rather than in the default GLOBAL database for a namespace. On some systems where the global is already defined, and the namespace had separate routine and global databases for the namespace, these would be merged from the GLOBALS database to the ROUTINES database defined by the namespace, for all namespaces defined on the system during installation.
If the application has an ^oddPROJECT global defined in two different namespaces which share the same global database and different routine databases, the end result of this would move the ^oddPROJECT global into one of the namespaces, and it would not be visible in the other. The solution for this is for the customer to manually copy the ^oddPROJECT global from one namespace to the other.
Version Interoperability
A table showing the interoperability of recent releases is now part of the Supported Platforms document.
Management Portal Changes
Numerous changes have been made in the Management Portal for this release both to accommodate new features and to reorganize the existing material to make it easier to use. Among the more prominent changes are:
Operational Changes
Journal Wait Time Extended For System Shutdown
During shutdown, the system tries to wait for the end of the journal file to appear in the Write-Image Journal (WIJ) recovery information. When this happens, the system can remember its shutdown state as "no journal recovery required at startup". This change extends the time allowed for that to happen from one minute to 30 minutes, if the write daemon is busy writing blocks to disk. This doesn't change the behavior of shutdown, only the amount of time taken. On clustered systems, when the write daemon exits and no recovery is required, the daemon removes the journaling information from the WIJ as a signal that no recovery is required.
Mounting Databases At Caché Startup
In version 2008.2, Caché would attempt to mount all databases. Those having the “mount required at startup” set to YES would cause startup to fail if Caché could not mount them.
In 2009.1, the behavior for databases required at startup is the same. However, other databases will not be mounted until they are first accessed. This is most visible in the Management Portal right after Caché begins execution.
Caché distinguishes between “dismounted” databases which have been made inaccessible to instances, and “unmounted” databases which are available and will be mounted the first time they are accessed.
Audit Database Changes
Index Record Changes
An index on timestamps has been added to improve query performance in the audit database. Previously, the audit data was not indexed by datetime. When Caché is restarted following an upgrade to 2009.1, the existing audit database will be converted to the new format by a background job which is launched during startup.
As a result of this change, the format of the audit record global has been changed. Previously, it was:
^CacheAuditD(<System>, <ID>) = $lb(<AuditDdata>)
The new format is:
^CacheAuditD(<UTCTimeStamp>, <System>, <ID>) = $lb(<AuditDdata>)
If the site has copied audit data to a different namespace for archival and reporting, that audit data will be converted the first time it is accessed by the ^%AUDIT routine for reporting.
If an application only uses SQL to report on an archived audit database, then it must be changed to do one of two things:
  1. Run ^%AUDIT in the namespace where the data is archived and run a list report on the data. This will cause the conversion of the data.
  2. Run the ##Class(%SYS.Audit).Convert() method in the namespace where the data is archived.
See the %SYS.Audit class for more details on the audit record format.
Audit Entries No Longer Mandatory
In prior versions, some system level audit events used to be marked as mandatory audit events. This meant that an administrator could not turn off auditing for these events. In 2009.1., Caché now allows any auditing event to be disabled. By default, audit entries that were marked as mandatory in previous releases remain on and must be explicitly turned off.
Queries in the Security.Events class have been updated to remove the “Mandatory” column from the query. Customers using these queries may need to update their application to remove these columns.
NetWide Domain Namespaces (NWDS) Removed
Beginning with 2009.1, the Netwide Domain Spacespaces (NWDS) feature is no longer supported. Customers who have relied on this to propagate namespace changes across system boundaries should contact InterSystems Worldwide Response Center (WRC) for guidance.
Change In Default Translation For Telnet
Beginning with this release, he following locales had their default translation for Telnet changed from RAW to UTF8:
Among other reasons for this change is the fact that the Latin1-based locales in the above list such as deuw, enuw, ptbw, and so on cannot read the the Euro sign via telnet using RAW because this character stands above 255.
UTF-8 is totally compatible with ASCII. This means that locales with languages that use ASCII exclusively won't notice any change. Customers with other Latin1-based locales which use characters between 128 and 255 might need to change the encoding used by their telnet client programs to UTF-8 so that they can correctly handle accented letters.
Platform-specific Items
This section holds items of interest to users of specific platforms.
No Support For CPUs Before Pentium P4
Beginning with this version, Caché will only install and run on Intel-based platforms using the Pentium P4 or later chipset, that is, those that support the SSE2 cpu extensions. This also applies to other manufacturers equivalent chipsets, for example, those from Advanced Micro Devices (AMD) that are functionally equivalent to the Intel Pentium P4.
In version 2008.1, this restriction only applied to server systems. Now it is applicable to BOTH client and server installations.
Tru64 UNIX® Version And Configuration Specifics
Patch Level
InterSystems recommends that Tru64 UNIX® systems be upgraded to a minimum level of 5.1B-4. This contains a correction that corrects “... a problem with pagetable page allocations that could leave a thread waiting indefinitely during a fork operation.” according to the vendor.
Stack Size Limit
Some systems running Tru64 UNIX® may display messages from the operating system that indicate the stack cannot be increased in size. The appearance of this message depends on the configuration parameters and application load. More space can be allocated to the stack through the ulimit command.
MultiValue Queries
MultiValue does not support queries on Tru64 UNIX® under this version of Caché.
Microsoft Windows
Default Windows DSN Now ODBC 3.5 Compatible
The default SAMPLES and USER DSN created during a Windows installation will use the InterSystems ODBC35 driver. This is true for new installs and upgrades from any released version. If a customer application uses default DSN created by a Caché install, it now must beODBC 3.5 compatible, or the application must be changed to reference a specific, compatible DSN.
ODBC Driver Version Management Changed With New Installer
With the new Windows installer, ODBC driver kits overwrite files in the common directory which have the same version as those in the kit. Prior to this version, kits were only overwriting files which had a lower version number. To enable old behavior, the following command line option can be used:
 ODBCDriver_x86.exe /V"REINSTALLMODE=omus"
To make ODBC kit overwrite any files regardless of version, the following command line option is used:
ODBCDriver_x86.exe /V"REINSTALLMODE=amus"
Details on installing Caché via a command line are given in the Installing Caché on Microsoft Windows chapter of the Caché Installation Guide.
Windows Errors In New Installer Upgrading Older Installations
When the new MSI-based install upgrades a non-MSI instance, rollback will be disabled. If the installation process encounters a problem, no files will be deleted. This behavior is similar to upgrades in the old-style installations. Normally repair should fix the instance after error is corrected.
Rollback is still enabled for new installs and upgrades over MSI instances. In this case, the system will be restored to the original state if an error is encountered during install or upgrade.
LAT Configuration
The [LAT] section of the config.cpf file is incomplete in this version of Caché. The System Management Portal does not configure the advertised services: ServiceName, ServiceDescription, and ServiceRating. Therefore, the LAT daemon (lat.exe) now it reads its startup parameters from a lat.ini file in the installation directory instead of from the cache.cpf configuration file. Users employing LAT finctionality should copy the [LAT] section from the existing cache.cpf file into a new lat.ini file or create the information with a text editor.
A sample [LAT] section is shown here. There can be a maximum of eight LAT services advertised. This sample has two. Each service consists of a ServiceName, a ServiceDescription, and a ServiceRating.
ServiceDescription_1=Cache LAT service 
ServiceDescription_2=Second LAT device 
The LAT service will be deprecated in Caché version 2010.2.
Weblink No Longer In Distribution Kit
Starting in 2009.1, Weblink is no longer packaged in the Caché installation kits. The latest Weblink packages for each platform are available free of charge to supported customers. They can be downloaded from the Worldwide Response Center distribution page.
These kits contain all the software components and documentation needed to install and use WebLink. Instructions for installing Weblink can be found in the documentation subdirectory of the Weblink kits. If you have any questions, please contact the Worldwide Response Center.
This section contains information of interest to those who have designed, developed and maintained applications running on prior versions of Caché.
The items listed here are brief descriptions. In most cases, more complete descriptions are available elsewhere in the documentation.
General Operational Changes
Change Timestamp Update For Routine Import
When importing a routine that does not have a timestamp either in XML format, or in %RO format with %apiRTN, if this routine is determined to be identical to the one already in the system, Caché will not change the last-modified time of the routine.
Global Name Truncation Changed
When a global name was truncated to the maximum length of 31 characters, an invalid name would result if the 31st character is a period. Trailing periods will now be removed when the name is truncated.
Prior to this change, application with names of this form would run without error, even though an attempt to access the global by ZWRITE, ^%GD, ^INTEGRITY, and so on would fail. With this version, the application will continue to run but will be using a different-truncated global name. In the case of an Caché upgrade, any existing data will be invisible to it.
%BuildIndices Now Includes Bitmap Extent By Default
The default list of indices built by %BuildIndices now includes the bitmap extent index, if it exists and has not been previously built. In previous versions, the bitmap extent index would only be automatically included if other bitmap indices were also built and the bitmap extent index had not been previously built.
TROLLBACK Failure Changes
This version of Caché changes what happens when a transaction fails to roll back receiving a <ROLLFAIL> error. The new behavior is based on the setting of the system flag “Freeze on Journal Error” and proceeds as follows for local (that is, non-ECP) transactions:
  1. If the system flag is NOT set, the process initiating the transaction and TROLLBACK gets a <ROLLFAIL> error. The transaction is closed. Locks retained for the transaction are released. This option trades data integrity for system availability.
  2. If the system flag is set, the initiating process halts and clean job daemon (CLNDMN) retries rolling back the open transaction. During the CLNDMN retry period, locks retained for the transaction are intact and as a result the system might hang temporarily. This option trades system availability for data integrity.
For transactions on ECP configurations, it is the system flag on the ECP server that governs the behavior of the TROLLBACK failure. When the system flag on the ECP server is set, the ECP client process initiating TROLLBACK hangs (unlike the local case), while the ECP worker daemon on the server retries rolling back the open transaction. The remainder of the operation is similar to the local case.
If journaling is disabled within the process (for example, by invoking DISABLE^%SYS.NOJRN), at the time of issuing TROLLBACK, journaling will be enabled for the duration of TROLLBACK and then disabled upon exiting TROLLBACK. Previously, one would get a <ROLLFAIL> error in this case.
Streams Default Directory Is Now Per-Namespace
In version 2009.1, streams directory no longer defaults to the Caché temp directory. Instead, the default directory is a per-namespace value with a different location possible for each namespace. The default location is now defined as:
The default location can be changed programmatically by setting the value of StreamLocation via the Config.Databases class for a particular namespace.
IPv6 Changes
The ability of Caché to support IPv6 addressing and networks is an important addition to the capabilities of this version. However, IPv6 represents network addresses in a new and expanded format. Applications that expect to receive and parse the format of IP addresses will likely have to be rewritten to handle the both IPv4 and IPv6 addresses.
TCP Device Representation Changes
When IPv6 is enabled, the network address returned by Caché has the port number separated from the network address by a comma (,). This is because IPv6 addresses use the IPv4 separator, a colon (:)< as a part of the network address itself.
Wildcards Not Allowed In Selections
Caché does not support the use of a wildcard character such as “*” in an IPv6 address. In situations where one is chosen as a filter, for example, to accept or reject a connection, you must specify a hostname or specific address.
Caché Direct Connection String Issues
IPv6 address formats are fully supported in Caché Direct. In particular, the Server/MServer property of the VisM.ocx allows IPv6 addresses within the same general connection string format as previously. However, depending on how they are used by an application, there may be some issues that need to be confronted. Specifically, the format of the connection string in Caché Direct is a colon-delimited expression, of the general form
where server_address is the master server and can be an IP address, or a server DNS name, or the special name “localhost”.
Potential confusion arises with IPv6 addresses which contain colons in the server_address part. (IPv6 also supports more than one form of loopback address.) Caché Direct supports all of these format variations. But, depending on the assumptions made by application code, the new addresses could cause incorrect behavior if not parsed properly.
Objectscript Changes
Floating-point Number Rounding Improved
This version of Caché fixes a deficiency in the algorithm used to round $DOUBLE values to a particular number of decimal digits. The new algorithm increases the accuracy of this rounding and eliminates overflows that occurred in some intermediate steps.
For example, consider the expression
$NUMBER($DOUBLE(123456789.0123456) ,3)
that requests the value be rounded to 3 decimal places. In previous versions, the result would be 123456789.01200000941. In this version, the value returned is 123456789.01199999451. Neither of these are the expected, 123456789.012.
The reason for this is that the expected answer has no exact representation in binary floating-point. In 2009.1, the rounding algorithm chooses the an exact floating-point value which is closest to the expect value.
This change means that some values may differ from previous versions when rounded to a specific number of places such as xDBC conversions to numeric values with a fixed scale.
Caché has also improved the rounding behavior in the kernel with the following effects:
Remove $ZUTIL(69, 4, ...)
This $ZUTIL function originally made the principal device of the child job the same that is used by the parent. It has been non-functional since version 5.1. It has been removed from this and future versions of Caché; the documentation has also been removed. Attempts to use this entrypoint will result in a <FUNCTION> error.
ZINSERT Or ZREMOVE On Current Routine No Longer Allowed
ZINSERT and ZREMOVE cannot be used to modify the running routine. If an existing application attempts this, an <EDITED> error will be thrown when control returns to the modified routine. In prior versions, the modification was not properly detected resulting in a process access violation. The proper usage for these commands from a routine is within an XECUTE and preceded by a ZREMOVE or ZLOAD command.
Routine Compiler Changes
Macro Preprocessor Corrections
In previous versions, the compilation of the following statement:
#dim X as %String // Length = 10
would incorrectly result in a line
Set X=10
Now the comment symbol, “//” is handled correctly and no code is generated. Also, the macro preprocessor now correctly recognizes when a statement that looks like a pre-processor directive is inside a comment. So the following will no longer compile:
#include %occInclude
          A comment
#IF 0   
          Old comment
          New comment
Class Changes
Improved Signature Checking
In version 2008.2, signature checking in subclasses applied to all signature errors in a class. However, in some cases not all errors were reported. In version 2009.1, the compiler will now report all signature errors so they can all be fixed at once.
Size Field In FileSet Query
The Size property returned by the %File:FileSet query is changed from %Integer to %BigInt, It is possible for a file to be larger than 4GB in size.
Attributes In %Dictionary.ClassDefinition Can Now Be Undefined
Caché 2009.1 now allows attributes used in programmatically defining classes to be in an undefined state. Prior to this, unreferenced attributes were assumed to have their default value. Now, for each attribute in %Dictionary.ClassDefinition, there are new methods, <AttributeName>Reset() and <AttributeName>IsDefined().
This applies only to the class, %Dictionary.ClassDefinition itself, and not for the member definition classes.
XML DOM Internal Representation Changed
The Caché data structure used to represent an XML DOM has changed. The details are defined as being internal and subject to change without notice. However, if an application is accessing this data directly, it must be changed and recompiled. The recommended way to access this data is via the %XML.Node class.
Prevent IDKEY Value Change On UPDATE
The value of an ID cannot be altered once assigned. Documentation does specify that ID values cannot be changed, but the software did not properly enforce the rule. This deficiency has been fixed and the IDKEY value cannot be updated.
SYS.DataBase.Freespace Query Changed
Applications that use the SYS.Database.Freespace query directly, and reference the "% Free" data column by name in the result set, will need be changed to reference the column by number, or by using the new label “Free”. The previous label interfered with proper XML generation.
Generate Cursor Name From Incremented Counter, Not Class Query Name
The cursor name generated to implement a class query of type %Library.SQLQuery now is based on an incremented counter instead of the query name. This resolves a <LABELREDEF> error when the query name is not unique in the first 29 characters.
GUID Management Changes
If a persistent class is marked as GUIDENABLED, Caché will assign Globally Unique IDentifiers (GUIDs) to each object when it is created. A later call to delete the object via %Delete on an object will no longer delete the GUID for that object. There is history in the GUID global in each namespace where a GUIDENABLED object has been created. Users are responsible for removing entries from ^OBJ.GUID that are no longer needed.
Also, a new argument is now defined for the %LIbrary.Persistent.GUID() method that returns the GUID value for an OID. The argument, pDeepSearch, if true, will trigger a search with the extent and any registered subextents for an object that no longer exists in the database. Previously, %OnDetermineClass would fail for a deleted object and the GUID would not be found. Now, if pDeepSearch is true, the extent of the current class and all registered subextents are searched for the ID.
%Net.MailMessage And %Net.MailMessagePart Now Subclass %SerialObject
Before Caché 5.1 and Ensemble 4.0, the classes %Net.MailMessage and %Net.MailMessagePart were subclasses of %Library.SerialObject. Beginning with Caché 5.1 and Ensemble 4.0, they were changed to be subclasses of %Library.RegisteredObject. In this version of Cache and Ensemble, %Net.MailMessage and %Net.MailMessagePart are again subclasses of %Library.SerialObject.
This change allows archived data from releases earlier than Caché 5.1 and Ensemble 4.0 to be accessed by current applications.
Deprecated Classes
This class is included only for purposes of backward compatibility. In the future, applications should use either
The Config.Configuration class is deprecated beginning with this version of Caché. Applications using it should be rewritten to use other, more specific classes in this package, for example, Config.Databases, Config.Devices, or Config.Telnet. Config.Configuration will be removed in a future release.
The %NET.LDAP class is deprecated beginning with this version of Caché. Applications using it should be rewritten to use the equivalent classes in the %SYS.LDAP package.
Class Deletions
The classes listed within the following packages were present in 2008.2 and have been removed in version 2009.1:
Class Component Deletions
The following class components, present in version 2008.2, have been removed from use in this version:
Class Method Signature Changes
The following methods have been incompatibly changed in either the parameter list needed to invoke them, or in the type of the value they return:
Class And Class Component Reservations
The following list of classes and class components are being reserved for InterSystems use in the future. Applications making use of them will still function, but they may change in the future without prior notice. Therefore, applications that use these classes or class conmponents should be changed to use alternate, supported pathways to accomplish the same effect. Please contact InterSystems Worldwide Response Center (WRC) to discuss the available conversion options.
Class Compiler Changes
Generator Method Ordering
In classes containing method generators, if any generator depends on information about the state of other methods in the class, it needs to indicate this to the class compiler. This is done is including the GenerateAfter keyword in the properties of the referring generator method. The keyword is followed by the names of the methods that must be compiled before this generator is run.
Class Inheritance Order
There is a new class keyword that determines how to resolve a common member when doing multiple inheritance. This keyword is called Inheritance and it can be set to “left” or the default, “right”. If a class inherits from two superclasses that have a common member, say a method called X(), in classes A and B, for example:
Class User.C Extends (A, B)
By default, C will get the implementation of X from class B, the rightmost superclass takes priority over the other superclasses. This can cause problems if class A has another method that uses X() to perform some work and C does not expect to suddenly get an unrelated implementation of X from class B instead.
Beginning with this version, class C can specify the inheritance order using the inheritance keyword. In this example, the desired behavior is obtained by specifying “left” as the value of the keyword.
Remove The cXXXXid and cXXXinheritedid Nodes From ^oddCOM
To increase speed of class compiler and reduce the amount of data it uses, the cXXXXid and cXXXXinheritedid keyword nodes from ^oddCOM. These keywords were internal to the class compiler and should not have been used by any customer code.
However, if an application does need these values, it can call resolveIds^%occInherit(class,.inheritedid,.id) to return the values the system used to have.
SQL Queries Now Depend on SQLPROC Setting
A query is now projected as a stored procedure only if SQLPROC = 1. Prior to this change, all SQL queries were projected as stored procedures, but those with SQLPROC not set to 1 were hidden from view. Thus these “unmarked ” queries were callable but did not appear in catalog queries. Any applications taking advantage of this behavior will need to be updated.
Reconcile Use of $ET And Try/Catch In Computed Code
If the class compiler detects that the SQLCOMPUTECODE for a property contains a use of $ET/$ETRAP, then the generated <property>Compute method will not use try/catch. Error processing is therefore the responsibility of the user. This is consistent with a similar change for $ZT/$ZTRAP.
Validate Index Names Used In %PurgeIndices
Beginning with version 2009.1, %PurgeIndices validates the name of the indices it is passed. If the index does not originate in the current class then it cannot be purged.
There is an exception to this rule; if the current class is the extent root class and the index is inherited or originates here, it is valid for building and purging.
Revise Class Name Normalization For Generator Classes
When compiling an incomplete reference such as ##class(Name).Method(), the compiler attempts to normalize this classname to a fully-qualified class name. In previous versions, the normalization algorithm used the import list or the origin of this method containing the reference (that is, the class where this method was defined). However, generator methods are effectively implemented in each subclass where they occur.
Beginning with version 2009.1, the compiler normalizes names relative to the current class for generator methods rather than the class where this generator was initially defined.
Use Of %this Constrained
In prior releases, applications could access to the private properties of another object by executing code such as
New %this
Set %this=otheroref
Set LocalValue=..PrivateProperty  
Beginning with 2009.1, this code will not work as intended. Applications with similar fragments must be changed. The way Caché enforces public/private protection has been strengthened. Now, a method of class X can access private members of another instance only if the origin of the member is in class X or a superclass of class X.
Use Of ##this In Classmethods Prohibited
In prior versions, an instance method could call a classmethod and the classmethod could reference properties within the instance using the ##this reference. Because it is not possible to guarantee a valid value for ##this in classmethods, this usage is now prohibited and will result in an error when the method is executed.
Storage Interface Now Checked For Consistency
SERIAL and PERSISTENT classes both use a storage definition to describe how instances of the class will be serialized. The storage definition specifies a type class that will provide the necessary storage interface implementation. Since the requirements of a SERIAL class are different from those of a PERSISTENT class, the class compiler will now check the storage type class for compatibility with the using class to ensure that the proper storage type class is used. An incompatible storage type class will be reported as an error, and the compilation of the class will fail.
EXTENT Queries Projected As SQL Procedures
The extent query defined in %Library.Persistent is automatically projected as an SQL stored procedure. If this query is overridden in a subclass of %Library.Persistent, then the subclass determines whether or not the query is projected.
%Double.DisplayToLogical Now Returns $DOUBLE Result
This class now always returns a result type of $DOUBLE.
In prior releases, a class could specifiy another class to include into itself – a kind of inheritance. It was never used by customers and has been removed in this release.
<Property>Get Now Enforced As Method
In prior releases, it was possible to reference the <propertyname>Get() method as if it were itself a property. This means that, for a property named Age, all of the following statements compiled and executed:
  Write someobject.Age, !
  Write someobject.AgeGet(), !
  Write someobject.AgeGet, !
In this release, the compiler syntax checking is improved. The last form is now properly detected and reported as an error.
Suppress %%CLASSNAME Generation For Final Extent Root Class
The extent root class is the uppermost class in the hierarchy that instantiates an extent. This means that there are no persistent superclasses that can instantiate instances of themselves. In most cases, the class is one that extends %Library.Persistent (which does not itself allocate storage). The extent root class has the class keyword,CLASSTYPE, equal to “PERSISTENT” and NOEXTENT “FALSE”. Therefore, the list of superclasses of this class that allocate storage, %%CLASSNAME, is empty; this is the first such class to do so.
If the extent root class is declared FINAL, then the compiler can be sure that no subclasses exist as well. In this instance, the compiler will not generate the property, %%CLASSNAME, since it would always have a null value.
Remove IVARmultidimensional Keyword
The planned use for this keyword was never implemented. As part of cleaning up the class compiler, it has been removed.
Object Binding Changes
Projections Of %Library Collections
The several “ListOf” and “ArrayOf” collection classes in %Library are now projected externally as follows:
%Library Class Projection Superclass
ListOfDataTypes CacheListOfDataTypes CacheListOfStrings
ArrayOfDataTypes CacheArrayOfDataTypes CacheArrayOfStrings
ListOfObjects CacheLibListOfObjects CacheListOfObjects
ArrayOfObjects CacheLibArrayOfObjects CacheArrayOfObjects
Each of the classes, CacheListOfDataTypes, CacheArrayOfDataTypes, CacheLibListOfObjects, CacheLibArrayOfObjects has a constructor (equivalent to the %New class method) that takes a CacheConnection argument.
Client Name Handling Changes
In prior versions, client names were always deduced from server names by removing or replacing characters not permitted as part of client names in C++ and C#. In 2009.1, if the server defines a client name for some name in the class definition, that name will be used instead of the constructed name. In order to get client names from the server, it is necessary to set the GetClientNamesFromServer property of CacheConnection to true before calling Open() on the connection.
MultiValue Collections Projected To .NET
MultiValue collections are now projected to the .NET binding similar to other Caché collections. That is,
SQL Changes
FOR ALL Extension In Caché SQL Deprecated
Caché SQL includes a proprietary extension, FOR ALL. This was added many years ago as a complement to the standard FOR SOME clause. However, in several preceding versions, the use of FOR ALL would cause an SQL parse error. Since none have been reported by customers, it appears that this is not being used in existing application code.
Therefore, in 2009.1 InterSystems deprecates the use of FOR ALL. If any existing application programs use this feature, they should be rewritten since this feature will be removed in a future release.
Type Reporting For UNION Queries
The SQL compiler has been changed to report the proper type for columns constructed from UNIONs. In previous versions, a SELECT statement such as
SELECT 0 AS var1 FROM Table1
SELECT 0.1 AS var1 FROM table2
would report INTEGER as the column type to xDBC, and the 0.1 value would be sent to the client as an integer with the data truncated.
Now the SQL engine will properly examine all legs of the union and return the type of the highest precedence for each column. The order of precedence for Cache' types is: VARCHAR, DOUBLE, NUMERIC, BIGINT, INTEGER, SMALLINT, TINYINT. So a query such as
SELECT MyTinyIntField AS var1 FROM Table1 
SELECT MyIntegerField AS var1 FROM Table2
SELECT MyNumericField AS var1 FROM Table3
will return type NUMERIC for the column since it has a higher precedence than TINYINT and INTEGER. At this time Caché will only use the type precedence in UNIONs as listed above. If other types are involved, no automatic type detection will be done. The type of the union fields with the highest precedence will be returned. Other types will be ignored. To explicitly change the type, use explicit CAST statement.
Caché SQL now supports the use of the TOP clause in the top-level query of an INSERT ... SELECT statement. For example:
INSERT INTO Table2 (field1, field2)
SELECT TOP 10 fld1,fld2 FROM Table1
will only insert the top 10 rows retrieved by the select query.
Prior to this change the query would Prepare without error, but the TOP clause would be ignored. This led to confusion where it appeared the results did not match the query. In addition, the TOP clause was not previously supported in subqueries. Now if a SELECT attempts to use the TOP clause in a subquery, an error will be returned when the statement is Prepared. The error is:
SQLCODE = -145 :: TOP clause is not valid in a subquery
New Keyword: %NOTOPOPT
Beginning with Caché 5.2.2, optimizations have been done for TOP ... ORDER BY to decrease the interval before the first row was produced. Usually these changes substantially improved performance. However, on rare occasions, these optimization heuristics make the query worse. For these cases, a %NOTOPOPT hint is now available to force normal total cost optimization processing The syntax for this is:
Improve DISTINCT Speed While Preserving Case
Beginning with version 5.2, Caché supported using indexes for DISTINCT and GROUP BY. However, in most cases, this optimization caused case-insensitive columns to be returned in uppercase. To override this behavior, application had to select %EXACT() of the column.
In version 2007.1, Caché allowed a clause to control the behavior of this optimization: FASTDISTINCT ON or OFF. With FASTDISTINCT OFF, the actual row data was returned, rather than a data value possibly in uppercase. Unfortunately, with FASTDISTINCT OFF, an index-assisted DISTINCT improvement occurs if uncollated data is stored with the index. Since most indexes do not store data, and for bit map indexes, the improvement cannot be realized.
Correct Processing For FULL JOIN Clauses
Beginning with version 2008.1, Caché supported FULL OUTER JOIN. However, Caché does not support the NATURAL FULL JOIN or FULL JOIN ... USING clauses. These syntax forms were accepted but processed as if they were NATURAL LEFT JOIN or LEFT JOIN ... USING. Beginning in this version, use of these forms will generate an error message rather than incorrectly processing the clauses.
Computed Property Changes
Properties that are SQLCOMPUTED can reference the current property value in the SQLCOMPUTECODE, if the property is not CALCULATED and it is not a collection.
Support UPDATE And DELETE On Abstract Tables
Caché SQL now supports UPDATE and DELETE on an Abstract table where it is assumed the actual row being updated or deleted is in a sub-extent of the table. Prior to this change, SQL considered READONLY and Abstract to be the same resulting in READONLY behavior. Now, if the class is defined as abstract, Caché generates appropriate logic for the UPDATE and DELETE filer to dispatch to the extent of the row being updated for filing.
It is still invalid to attempt to INSERT into an Abstract table; this will result in an SQLCODE=-115 error. In addition, if an application prepares and executes an UPDATE or DELETE statement against an Abstract table that doesn't actually UPDATE or DELETE any rows, a SQLCODE=100 is returned, and not an error.
If an application actually intends to define a READONLY table, the READONLY class parameter must be explicitly declared. A class/table defined as READONLY will return SQLCODE=-115 if an application attempts to prepare an INSERT, UPDATE, or DELETE statement against the table.
Perform String Comparisons For %PATTERN, %STARTSWITH And String Operators
When a %PATTERN, %STARTSWITH, “[” (follows), “]” (contains), or LIKE operation is performed in an SQL statement, the operation is done as a String operation. It is assumed both side of the operator are string values and they are treated as such, for example:
or the even more extreme,
If X is a Numeric type Caché will not normalize '5.' to a number as with other operators because that changes the intention of the condition (to find all numbers that are 5.<something>, or all negative numbers bigger than -1, respectively.
Reduce %Float Usage In SQL
Data declared as %Library.Float is defined as ODBC type DOUBLE. Because of this, when a %Library.Float field used in a WHERE clause and is compared against a literal value or host variable, the value is normalized by calling the appropriate method of %Library.Float. However, if the field uses a subclass of %Library.Float and one of the functions ACOS, ASIN, ATAN, COS, COT, EXP, LOG, LOG10, POWER, SIN, SQRT, TAN, TRUNCATE, or one of the arithmetic operators (“+”,“-”,“*”,“/”,“\”, and “#”) are used on the field, Caché can only determine that a numeric value needs to be returned unless the argument to the function is ODBC type DOUBLE, then the function returns DOUBLE.
For example, assume a class named TEST with a property named, ABC and the type of ABC is User.MyFloat, where User.MyFloat extends %Library.Float, and the ODBC type of User.MyFloat is DOUBLE. In the SQL query:
If TEST contains a row where ABC has the value .48259, this row will not be found because the literal input .482 with go through the normalization method of %Library.DOUBLE and $DOUBLE(.482) = .48199999999999998401.
Applications using data of type %Float or extensions of %Library.Float need to be very careful about the actual values of the data. %Library.Float returns a DOUBLE value to ODBC, but does not store a DOUBLE value in the database.
The use of %Library.Float and any extensions of this type is discouraged. The class %Library.Double is preferred instead.
Perform Simple Normalization On Input Values
Beginning with 2009.1, SQL statements that expect literal values or host variables as input into the query will now receive those values "lightly normalized" before they are used by the SQL statement. For example, suppose a query has one of the forms
in ODBC mode and/or Runtime node. When processing of the query begins, the <literal> or <host variable> will undergo any OdbcToLogical or DisplayToLogical conversion needed (based on the datatype of the item). After this first conversion (if any), the value will then be "lightly normalized" using the following:
Correct Issues With SCALE Reporting And Aggregates
Beginning with 2009.1, a column generated using AVG is reported as type DECIMAL, unless the argument to AVG is a $DOUBLE value; in that instance, the AVG function will return a $DOUBLE value. If the AVG function returns DECIMAL, and the argument to AVG has a precision, p and scale, s, the precision of the result is 18 and the scale is 18-p+s. If the AVG function returns a $DOUBLE, the scale for the column will be 0.
NEW SQLCODE When Returning Multiple Rows
This version adds a new SQLCODE error, -432, where a function returns multiple rows when only a single value is expected This is currently used in the Informix converted code to report an error when a function is called as a scalar function and is expecting a single value returned, but the procedure returned multiple rows. This corresponds with the Informix error -686.
Report Error When Using SUM() on Dates, Times, or Timestamps
There is a new error, SQLCODE=-379, that will be reported when an application attempts to prepare an SQL statement that has a SUM aggregate function with an argument of type DATE, TIME, or TIMESTAMP.
An Embedded CALL Statement Creates New %sqlcontext
An embedded SQL CALL statement will now execute the NEW command on the %sqlcontext variable during its execution. The %sqlcontext variable will be removed when the CALL finishes.
Caché does not support returning result sets from CALL statements in embedded SQL statements.
Report Error For INSERT Statements With A Subquery
Caché has never supported a subquery in an INSERT statement such as:
INSERT INTO Addressee 
   SET LetterId = ? , 
   RelationshipId = ( SELECT id 
                      FROM Dictionary . AddresseeRelationshipToPatient 
                      WHERE code = ? ) , 
   AddresseeIEN = ? , 
   recipientType = ? , 
   Name = ?)
Prior to this version, it would simply give a syntax error at compile time. Now an error will be returned when the query is prepared/compiled that explains this is not supported. The SQLCODE value for this error -144, “Sub-queries are not allowed in insert statements”.
Return BINARY Type For SUBSTRING(<LongVarBinary>)
When using SUBSTRING() with an argument of type LONGVARBINARY, the result returned is now of type BINARY (%Library.Binary), not VARCHAR (%Library.String).
Specifying The Collation For A Field In DDL
When a the collation of a field is specified via a DDL CREATE TABLE or ALTER TABLE statement, an error will now be returned if the collation specified is not a collation support by Caché. In previous versions, an indicating an unsupported collation name would be returned during CREATE TABLE, but not during ALTER TABLE. Now, both CREATE TABLE and ALTER TABLE will return a meaningful error message.
Also, when the class is defined and a collation is specified via DDL, the collation value in the collation property parameter will be forced to all uppercase.
No Collation Specified Defaults to EXACT
Subscript information for collated fields is now reported as %EXACT when no collation (or so-called EXACT collation) is applied to a property.
Return OREFs Instead Of OIDs In SQL Queries
In prior versions, when embedded and dynamic SQL queries returned external streams as part of their results, the references to the streams were returned as OIDs (object ids; %Library.ObjectIdentity). Beginning in this version, the stream references will be returned as OREFs (object references; %Library.ObjectHandle).
Existing applications returning external streams as results must be modified to use the new type.
Trailing Delimiter Modified After SQL UPDATE
A change has been made to the SQL data filer for UPDATE to prevent a trailing delimiter value from being added to a global node. This happens if %CacheSQLStorage is used with delimited identifiers for the node. For example suppose the node looks like
^Patient({ID},10) = {Name} ^ {Age} 
After an SQL UPDATE, in some cases, the node would be changed to look like
^Patient({ID},10) = {Name} ^ {Age} ^
While this data is still valid, it may interfere with applications that look at the global data directly. SQL adds the trailing delimiter if the data in the table beyond the trailing delimiter is defined.
SQL Gateway Changes
Use %Library.Double For Linked Tables
Caché now represents floating-point values in linked tables by %Library.Double instead of %Library.Float.
CSP Changes
Keep CSP Info Off Insecure Channels When Using HTTPS
In previous versions, the CSP sessionId cookie that Caché sent to the browser did not have the 'secure' flag set. This meant that if an https CSP application could force the browser to go to the same web site with http rather than https. In this case, the browser would send the sessionId cookie in clear text which would make it possible to sniff this off the network and then use the cookie information to impersonate this user.
To improve security in version 2009.1, if the CSP session has only ever seen https requests then Caché will send the session cookie with the secure bit set. If the CSP session has seen any http requests, it will the session cookie without the secure bit set. This also means a CSP application that starts on an https page, and then goes to an http page, will start a new session (and take out a license and so on). This is by design as it prevents the sniffing of the sessionId.
If the user application is willing to allow this sessionId to be sent over the network unencrypted there are two ways to accomplish this:
  1. Start on an http page first, and then link to the https page. This will ensure the sessionId will never have the 'secure' flag set.
  2. When linking to the http page from the https page pass the sessionId with the property CSPCHD=<sessionId>&CSPSHARE=1
Convert CSP Parameter Names And Values On Input
In prior versions, when a CSP pages was submitted, Caché did not convert the parameters names based on the characters set of the page. If an application used a non-ASCII name, it would therefore not appear correctly in the %request.Data array. Beginning with this version, Caché will convert both the value and the name.
Change Value of Serve FIles For CSP Applications
For the InterSystems-supplied CSP application settings for the csp applications /isc/studio/templates and /isc/studio/usertemplates, the Serve Files parameter has been changed from “No” to “Always and Cached”. In addition, in the portal the default setting for Serve Files has been changed from “No” to “Always” for new applications. This matches the settings in the ^SECURITY routine. Customers may want to review their current CSP application settings, and change the value for their applications to “Always”.
Zen Changes
Zen dynaTree Component Improvements
A number of extensions were added to this component:
Display Controls
The component now has the ability to show lines between folder and leaf nodes (like a windows tree control). This is activated by setting the new showLines property to true. In this mode, the size and images used by the tree control are fixed. If that is not appropriate, set showLines to false.
New Callback Provides Tree Contents
A new callback allows an application to obtain the contents of the tree. This callback is set via the OnGetTreeInfo property.
The callback method returns the entire contents of the tree as one array. This structure is designed to make it easy to programatically provide tree contents. Each node in this array corresponds to one node within the tree. At each node there is a $LIST of information about this node:
$LB(caption, value, hasChildren, link, expanded, icon)
The node structure is a directed graph of the form
node(0) = $LB(info about this node) 
node(0,"ch",1) = "" // index of first child of this node 
node(0,"ch",2) = "" // index of second child of this node 
Support For Lazy Loading
If the node structure indicates that a node has children (hasChildren=1), but this children are not in the node graph, then the dynaTree component supports “lazy” loading. The initial contents of the tree are displayed, and when the user expands a folder node that currently has no children loaded, a call is made to server to fetch them. This call invokes the OnGetTreeInfo callback passing it the logical value of the folder node.
Drag Support
This change also adds drag support for the dynaTree.
Name Mangling Changes
To simplify bookkeeping for forms, Zen mangles the names of controls used when a form is submitted. CSP reserves control names starting with "Cache" for the purpose of writing login-related pages. With this change, any control whose name starts with "Cache" will be considered to be a special case for Login pages and will not have its name mangled.
Zen Pages Using SVG
Pages that load SVG dynamically (and do not have an svgFrame in their initial definition) will need to add
<page ... useSVG="true">
to their page definition. Failure to do so will result in Javascript errors. Zen no longer loads the Javascript code for SVG by default.
Changes For radioSet And radioButton Components
Changes were made to the radioSet and radioButton components:
This change introduces and uses new CSS class for these components to represent the disabled state for captions. These are “a.radioSetCaptionDisabled” and “a.radioButtonCaptionDisabled”. The style for radioButton captions also changes from “span.radioButtonCaption” to “a.radioButtonCaption” to be consistent with radioSet and to support the“:hover” selector.
This means that applications that override the captionClass for this component may have to add addition CSS style information such as
color: none;
text-decoration: none; 
dynaGrid Focus Changes
When the edit control within the dynaGrid gets/loses focus, it would raise an onselectcell event. In some cases, this lead to extra events being fired. Zen no longer raises this event in this case. Applications that subclass from dynaGrid and depend on this behavior may need to be reworked.
Disable Keyboard Shortcuts And Context Keys For Zen Client-Side Menu Widgets
Changes in the keyboard handling in Safari and Firefox 3 effectively disabled the keyboard shortcut mechanism built into the csMenu subsystem. This resulted in the csMenus becoming incompatible with textBox and textArea components on those platforms.
In the short term interest of maintaining some of the utility of the csMenu subsystem, the keyboard handler has been disabled until a cross-platform solution (or bug fixes on the part of Apple and/or Mozilla) are developed. This means that all keyboard shortcuts (including use of the ESC key to close an open menu) have been disabled under Internet Explorer and Chrome as well. Additionally, the csComboBox widget makes heavy use of this same keyboard engine and is likewise disabled.
Zen Reports Changes
Allow No Width Or New defaultWidth Attribute On Table
In prior versions, when no width is specified, Zen Reports specified proportional-column-width(1). This can be undesirable in some circumstances when the application actually wants no column-width attribute specified. With this version, if an application specifies width="none", no width attribute specified. This change also defines a new table attribute: defaultWidth, which can be used to over ride the current default width (when no width specified) with whatever the application specifies, even “none”, which means no column-width attribute will be generated.
Zen Reports And Table Privileges
In this version, Zen Reports can be used to generate reports (PDF, HTML, or text) even if the application is running as UnknownUser and have no privileges to do anything. This could allow previously invisible information (because of a lack of execute and output privileges) to be seen.
The ZEN Report writer can no longer depend on lack of privileges to execute an operating system command to protect information. Instead, sensitive information in tables must be protected through user security or ability to run CSP applications with appropriate safeguards. Users are expected to protect the tables/result sets/stored procedures from which ZEN Reports derives its information with SQL privileges. If an application has permission to view the table, then it can generate XML from it and produce a report.
Element Handling Redefined
The specification for element generation is now defined as the following: for each row of a ResultSet that a group processes, an element will display once in the group. Applications that expect only one element may now fail; there is now one element per row of ResultSet processed by a group even if an element repeats. It is always possible to NOT repeat elements by using "SELECT DISTINCT" or other mechanisms in the generation of the result set.
Individual Margin Settings Overridden By Non-Null Margin Setting
In this version, the values for marginTop, marginBottom, marginLeft, and marginRight are ignored if the margin setting is non-null.
Custom Aggregate Definitions Changed
Custom aggregates Var and StDev now correspond to MDX in being unbiased estimators, that is, dividing by n-1 where n is population size. The new, biased estimators (divide by n) are now VarP and StDevP.
Large Reports May Fail to Compile
In this version, some very complex report definitions may fail to compile because the code they generate exceeds 32K characters. In this case, please contact the InterSystems Worldwide Response Center (WRC).
Web Services Changes
SOAP Client Wizard — Multiple Return Values
A method that returns multiple values is now represented as explicitly having Output parameters. This change is required to handle the case where an optional parameter is missing. In prior versions, this would cause the first value returned to be incorrectly assigned as the return value of the method.
xDBC Changes
Privilege Checking Extended To More Catalog Queries
When calling the following catalog queries, privilege checking is now enforced and no catalog metadata will be returned if the user does not have at least one privilege for the table or view.
SQLSpecialColumns (SQL_BEST_ROWID=1) getBestRowIdentifier()
SQLForeignKeys (Cross Reference) getCrossReference()
SQLForeignKeys (Exported Keys) getExportedKeys()
SQLForeignKeys (Imported Keys) getImportedKeys()
SQLPrimaryKeys getIndexInfo()
SQLStatistics getPrimaryKeys()
Improvements To Precision/Scale For Numeric Values And Expressions
The following assumptions are now made when preparing SQL statements via xDBC:
Numeric literals
When a numeric literal value is specified in an SQL statement that is Prepared through xDBC, its value is replaced with a host variable (unless it is enclosed in ((val)) ). The type of this variable is NUMERIC with a length of 20, a precision of 18, and a scale of 9. If a different type, precision, or scale is desired, a CAST should be used in the SQL statement.
Addition and Subtraction
The type of the resulting expression will be NUMERIC unless one or both of the arguments is a double, then the result will be a DOUBLE. If the type is NUMERIC,
The type of the result will be NUMERIC unless one or both of the arguments is a double, then the result will be a DOUBLE. If the type is NUMERIC,
The type of the result will be NUMERIC unless one or both of the arguments is a double, then the result will be a DOUBLE. If the type is NUMERIC,
Return ODBC 3.5 Catalog Metadata
Beginning with 2009.1, ODBC catalog queries have been updated to support ODBC 3.5. This has the following implications. (The column name changes do not affect backward compatibility because applications bind by column number.)
MetaData Table Name ODBC 2.0 ODBC 3.x
SQLColumns <none> COLUMN_DEF
SQLColumns <none> SQL_DATA_TYPE
SQLColumns <none> IS_NULLABLE
SQLProcedureColumns <none> COLUMN_DEF
SQLProcedureColumns <none> SQL_DATA_TYPE
SQLProcedureColumns <none> SQL_DATETIME_SUB
SQLProcedureColumns <none> CHAR_OCTET_LENGTH
SQLProcedureColumns <none> ORDINAL_POSITION
SQLProcedureColumns <none> IS_NULLABLE
SQLGetTypeInfo <none> SQL_DATA_TYPE
SQLGetTypeInfo <none> NUM_PREC_RADIX
Add IS_AUTOINCREMENT Column To getColumns Catalog Query
The JDBC DatabaseMetaData method getColumns() now returns a twenty-third column titled, IS_AUTOINCREMENT. This column will return YES if the column is one that is automatically incremented upon INSERT, otherwise NO is returned.
Change To Query Return Value
This version of Caché now always returns a value for %SQLGatewayConnection.Fetch(). However, it no longer returns the value 100 when all the data has been consumed. Applications must examine the value of SQLCODE to determine this.
Preserve Leading Zeros In Fractional Seconds Of SQL_TIMESTAMP
The fractions portion of the SQL_TIMESTAMP structure is an integer that represents the number of nanoseconds. Prior to this release, there was a conversion problem in the ODBC driver when there were leading “0”s before additional digits. For example,
2008-02-02 12:23:45.0012
would be interpreted as if it were
2008-02-02 12:23:45.12
This error is corrected in version 2009.1.
JDK1.4 Deprecated
JDK 1.4 is deprecated as of this release. It is officially out of support by Sun (END OF SERVICE LIFE) except through extended contracts that require payment. JDK 1.4 developed libraries (JAR files) can run without issue in most cases on JDK 1.5+. JDK 1.4 support will dropped as of Caché 2010.x.
The current InterSystems plans for Java are to continue all new product development on JDK 1.6. JDK 1.5 will be supported for current features (and subsequent bugfixes). As of the policy above, JDK 1.5 will reach the end of its service life on 30 October 2009. InterSystems will continue to support for JDK 1.5 for a period of at least 1 year after this date.
Generally, InterSystems will continue to support each version of the JDK for at least one year after its end of service date. This will allow product features to evolve and take advantage of virtual machine improvements in stability and speed.
MultiValue Changes
MVBasic MATWRITE And MATREAD Statements And Triggers
The MATREAD and MATWRITE statements will now call the appropriate trigger if one is defined for the file. In prior versions, the trigger was ignored.
SYSTEM(11) Changes
SYSTEM(11) will now return a boolean flag for whether the default select list exists in these emulations: Pick, Information, PIOpen, IN2, and Universe. Previously it returned a count of the number of items in the list. Applications relying on the previous (incorrect) implementation will have to change to a different method of getting the list count.
Change Line Numbers Reported By SYSTEM(49)
In prior versions of Caché, the line number reported by SYSTEM(49) was relative to the intermediate (MVI) routine instead of the source (MVB) routine. It will now be adjusted to properly show the source line number. Also, a <SUBSCRIPT> error would be thrown if the routine had been recompiled while it was running. SYSTEM(49) will now report the line number as 0 if the actual source line cannot be determined.
Sort WHERE Command By Port Number
The WHERE command outout is now sorted by port number by default. This makes Caché consistent with other commands such as LISTU and WHO. In addition, there is a new (D) option to WHERE which allows the sort and selection to be based by the Caché job number. When the (D) option is used , then the selection criteria is Caché job number, not MV port number.
Correct Echoing And Prompts On MultiValue INPUT And IN Statements
Beginning in version 2009.1, Caché obeys the following rules for the INPUT , INPUT @ , IN and KEYIN functions relating to how they echo, what device they echo to, and what prompts they support (the PROMPT statement).
  1. If any echoing is to be done, it is only done to the screen, never to the printer.
  2. The prompt string, defined by the PROMPT statement, is always honoured for the INPUT and INPUT @ statement. The prompt string only goes to the screen, never to the printer.
  3. The INPUT @ statement, when echo is turned off, needs to be emulation dependent. Some platform emulations will echo the characters during INPUT @ even when echo turned off (for example, Cache, Universe), while others (such as jBASE , and D3) need to respect the echo status.
  4. The KEYIN and IN statements, when echo is turned on, are emulation-dependent. Some emulations will honour the echo setting and others will never echo the character.
Remove Pagination From Some Emulations For MultiValue
Beginning with version 2009.1, some MultiValue emulations will no longer paginate their output by default. In those emulations, applications wishing to have paginated output must explicitly enable it with the SP.CONDUCT command. Now, only Cache, Universe and Unidata emulations paginate output by default.
New Functions Added
The functions LISTVALID and LISTNEXT have been added to MVBasic. The semantics of each is the same as the ObjectScript functions $LISTVALID and $LISTNEXT, respectively. Applications that use either of these identifiers as variables will need to be edited to remove the name conflict.
Open Trigger No Longer Invoked
Because an error in a trigger routine could prevent trigger commands from being run, trigger commands no longer call the OPEN trigger.
Truncate Fractional Dates To Integer For OCONV
Prior to this version, an OCONV of fractional date values would sometimes not do any conversion, instead returning the original value. Now fractional values will always be truncated to an integer before conversion.
Match Select List To Emulation Correctly
The PROC P command now correctly retains or throw away the active select list, depending on the emulation mode, as follows:
READNEXT Correction To Handle An Empty List Variable
In prior versions, READNEXT from an empty list variable would read from the default list 0 instead of treating it as an error. Beginning with this release, READNEXT will now check for "" and treat that as an invalid OREF, setting STATUS() = -2.
Changes To INDEX Search Of Empty String
Using CACHE emulation in previous versions, the expression
INDEX(string, "" ,1)
would return 0. In this version, it now returns the correct value, 1.
MAT READ Gives Error For Non-MultiValue Array
MATREAD will now throw an error when an application attempts to read from a non-MultiValue input. In previous versions, MATREAD would execute the ELSE clause. MATREAD has also been changed to provide a more descriptive error code when a non-MultiValue array is used in an operation that requires an MultiValue array.
READ Setting Changes
The default setting of READV0 for Ultimate emulation was changed from RV0.KEY to RV0.EXISTS. The default setting of READ.RETAIN was changed for these emulations – Information: off; PIOpen: off; Ultimate=: on.
SPOOLER Heading Processing Changed
In this version, a number of changes have been made to the HEADING and FOOTING statements, and general printer/terminal output in this context. Applications that depend on the format of SPOOLed output should be carefully checked to make sure the output still conforms to expectations.
Reset Spooler Job Numbers Daily
In previous versions, the job numbers for MultiValue spooler print jobs was never reset. Thus, after some weeks or months the values become very large and difficult to manage. In this version, the job number will be reset to 1 every day. Checks will be made to ensure existing jobs are not overwritten, for example if job 1 exists already then we'll use job number 2, and if that exists then we'll use job number 3 and so on. But application can no longer predict spooler job numbers.
SQLPROJECTION defines the default projection of a collection to SQL. For MVENABLED classes,
indicates that a child table is to be projected as well as a column. The SQLTABLENAME property defines the name of that table.
MVASSOCIATION allows properties in an MVENABLED class to define multiple collections as forming one SQL child table. If MVASSOCIATION is defined for a property, then SQLPROJECTION and SQLTABLENAME are now ignored and the value of MVASSOCIATION is used as the name of the child table projected by the associated properties.
This change alters the name of SQL tables projected by MVASSOCIATION. The prior behavior was wrong and not expected by customers using MVASSOCIATION. Some MultiValue customers may have to adapt their applications to recognize the new (and correct) table name.
Jalapeño Changes
NetBeans 5.5 Plugin Removed
Jalapeño now only builds for the NetBeans plugin for version 6.0; not both 5.5 and 6.0.
Select Access To Compiled Class Table Required
Jalapeño now examines all known subclasses of a given class to determine which instance to use. It does this by using the %Dictionary.CompiledClass table to locate them. Therefore, a user needs SELECT privilege on this table for the operation to succeed.
Exception Generated For Non-Unique Client Name
It is possible that several different Caché classes refer to the same Java class using clientname. In this case, the Jalapeño Object Manager is unable to determine which of those Caché classes should be used. In previous versions, it used the first one returned by a query. Now it checks that only one class satisfies the condition, and returns an error if this is not the case.
Object Save Algorithm Changed
This version changes the way Jalapeño saves multiple objects in a single method call. It moves most of the logic of resolving dependencies between objects from the Caché server to the Java client. The new implementation of save should be functionally equivalent to the old one but since more logic is now moved to Java client changes in the behavior (for example, timing changes) may manifest themselves.
In particular, before this change if an object being saved had a collection, the type of this collection was always preserved. In the new algorithm, to optimize the save, this might be no longer true because an ArrayList can be replaced with a LazyList.
Schema Builder Handles Arrays Differently
This version changes the behavior of the schema builder for some Java properties that are primitive arrays. Suppose in Java we have an array such as one of the following:
byte [] SomeBytes;
char [] SomeChars;
int [] WholeNumbers;
By default such properties are projected as a Caché Collection which is not usually a convenient choice. What is worse, if they are annotated like:
@CacheProperty(type = "%CacheString")
they were projected as List of %CacheString. Now, the following rules determine how a primitive array is projected:
  1. As collection of primitive types if it is not annotated. This is the same as previous versions.
  2. As single property with a given type if it is annotated with
    @CacheProperty(type = "...")
    and is NOT annotated as either @Collection or @Lob. This differs from previous versions.
  3. As a collection of given types if annotated as: @Collection(type = CollectionType.LIST)@CacheProperty(type = "...") (no change)
    @Collection(type = CollectionType.LIST)@CacheProperty(type = "...")
    This is the same as previous versions.
  4. As %Stream if annotated as
    @Lob (type in @CacheProperty ignored)
    This is the same as previous versions.
Source Control Changes
%Project Global Renamed
Prior to this version, Studio used to keep a copy of the currently active %Studio.Project in the public variable, %Project. This prevented the object from being closed correctly when Studio removed the project. Beginning with this version, the current project name is stored in a process private global, ^||%Studio.Project. Functions that need data about this object shold use this new location.
Platform-specific Items
This section holds items of interest to users of specific platforms.
Change Default Telnet Translation From Raw To UTF8 On Unicode Systems
The following locales had their default translation for Telnet (“Other Terminal”) changed from RAW to UTF8:
When this default was created, almost no telnet emulator supported UTF-8; it made sense to use RAW. Currently, most emulators support UTF-8 by default. Furthermore, those locales not based on Latin1 (for example, araw, csyw, ellw, hebw, hunw, ltuw, plkw, rusw, and thaw) had problems with non-ASCII characters because these characters fell outside the range supported by RAW and would thus be translated as "?". Finally, the Latin1-based locales in the above list (such as deuw, enuw, ptbw, and so on) were not able to handle the Euro sign via telnet using RAW because this character value is also above 255.
UTF-8 is fully compatible with ASCII. This means that locales with languages that use ASCII exclusively (such as English) will not notice any change. Customers with other Latin1-based locales which use characters between 128 and 255 might need to change the encoding used by their telnet client programs to UTF-8 so that they can correctly handle accented letters.
Terminal Log Files From Unicode Systems Now In Unicode
Beginning with version 2009.1, the log files produced by the Caché TERMINAL will be encoded as ANSI for 8–bit installations, and as Unicode for Unicode installations.
$LISTSAME On Big-Endian Systems
On prior versions, the $LISTSAME() function could report that two lists were not equal when one list contained an integer and the corresponding position in the other list was a different representation of that same integer (such as string or floating point). The failure occurred only on big-endian platforms.
MQ Context Changed
Prior versions of Caché unconditionally set the Context to 2 (SET_ALL_CONTEXT). This behavior caused authorization errors when using MQ.
Now, a flag is defined for an MQ Put connection (Net.MQSend) called Context. The context flag is:
Setting the context to Identity (1) or All (2) may have authorization implications. Applications that succeeded before may now fail with an MQ Authorization error (2035). Please see your IBM Websphere MQ documentation for additional details.
OpenVMS Stream Record Size Increased
Caché now allows applications running on OpenVMS to create records on OpenVMS in Stream mode up to 32767 bytes in length (the maximum allowed by OpenVMS RMS sequential files). This length includes the CR/LF that ends the record. Prior versions of Caché would handle requests to write records longer 163853 by silently splitting them into 2 (or more) records in the sequential file. This change will also report a <WRITE> error if the 32767 limit is exceeded; applications will get a clear indicator that they have exceeded the maximum record size, rather than unknowingly creating multiple records.
Comparisons On 64–Bit Systems Corrected
Caché version 2008.2 introduced a discrepancy in floating-point comparisons between nearly equal values that is corrected in this version. The problem occurred in comparisons between a $DOUBLE value and a Cache decimal value where the 20 digit expansion of the $DOUBLE value (rounded to be a decimal value) was equal to the Cache decimal value. In this case, comparing the $DOUBLE value with the Cache decimal value resulted in all three of the relations less than, equal to, and greater than being false. Now, these comparisons always have at least one of the relationships as true.
Windows Interfaces Now Built With Visual Studio 2008
Version 2009.1 now builds its Windows components using Microsoft Visual Studio 2008. Applications using C, C++, CallIn, or CallOut should also be built using that version of Visual Studio. The Windows samples in the SAMPLES namespace were also built with that version.
Windows Installation Now Uses Lowercase Directory Names
Caché now uses lowercase for installation directory names. In previous versions, for example, it installed into the \Bin directory. In version 2009.1, it is \bin.
System Management Portal
There have been a number of changes and improvements to the system management portal since 2007.1 was released. These are detailed in the administrator section.