Skip to main content

Caché 2011.1

This chapter provides the following information for Caché 2011.1:

New and Enhanced Features for Caché 2011.1

The following major new features have been added to Caché for the 2011.1 release:

In addition, many more localized improvements and corrections are also included. In particular, if you are upgrading an existing installation, please review the detailed list of changes in the Upgrade Checklist.

Rapid Application Development

Multiple Session Callback Events

In previous versions, the only user-defined Session Events triggered at the beginning, end or timeout of a CSP session occurred based on the last CSP application accessed by that user. In this version, this behavior has changed. Caché will now execute the SessionEvent logic for the current CSP application, plus the most recently accessed CSP Application that was used by this session prior to the event, if more than one application was accessed.

WebStress Testing Facility

This version introduces a new core utility called WebStress. InterSystems has used this tool in prior releases to record, randomize and playback HTTP-based scripts against various applications for the purpose of QA, scalability, and network load testing. The tool runs on a Caché or Ensemble system on any supported platform and can test any web-based application. It includes additional hooks required for correctly benchmarking CSP- and Zen-based applications making use of hyperevents. For recording scripts, users must employ a supported browser and the ability to define a proxy server.

New DeepSee Implementation

This release of Caché introduces a new version of DeepSee (previously referred to as “DeepSee II”) with the following improvements:

  • Data Modeling

    Data modeling has been simplified. This version uses Caché classes that reference application transactional classes. Therefore, there is no need to modify application classes before use as in the preceding version. DeepSee models are defined via these reference classes and can be edited using the DeepSee Architect or Studio. Furthermore, data models now support many MDX concepts including multi-level hierarchies.

  • Query Engine

    This version of DeepSee uses the MDX query language for all queries. Its query engine has been optimized to support parallel query execution which takes advantage of the power of multi-core architectures. Multi-level result caching improves query performance by retaining the results of queries so the results can be used when the queries are run again.

  • User Interface

    Built with the InterSystems Zen technology, the new DeepSee user interface supports multiple browsers including IE, FireFox, and Chrome. Control of the user interface is done via the DeepSee option on the Management Portal. The options include: Architect for creating DeepSee data models, Analyzer for exploring the data, User Portal for creating and viewing dashboards.

Performance And Scalability

Improved Class Compiler Performance

As a result of changes we have introduced in previous versions, and by moving performance-critical components into the system level, InterSystems has noticeably improved the performance of the class compiler.

Compilation Using Multiple Jobs

In addition to the gains from the Improved Class Compiler Performance in this release, Caché can now be directed to use multiple processes for the compilation of classes and the import of XML files. The number of jobs started will depend on licensed CPU cores and upon observed efficiency (more than 16 gains no added advantage).

Support For Large Routines And Classes

Large Routines

In prior releases, the maximum size of a routine was 64KB. Starting with this release, the maximum routine size has been extended to 8MB. For routines larger than 32KB, Caché will use up to 128 64KB routine buffers to hold the routine. These buffers will be allocated and managed as a unit.

The class compiler and the SQL processor have been changed to use this new limit. Customers can take advantage of this improvement merely by recompiling.

Large Classes

Beginning with this release the system now supports a larger class descriptor. Among the consequences are that classes now can contain a larger number of members to be declared in the class. The limits on class inheritance depth, and the number of superclasses allowed have also been defined. For a complete list of the applicable bounds, see “Guide General System Limits” in the Caché Programming Orientation Guide.

Please consult the Caché 2011.1 Upgrade Checklist for further information.

Journaling Additions

This version of Caché now provides an API for journal restore. See the Journal.RestoreOpens in a new tab class for information on how to use it. In addition, the process Id (PID) is now once again part of each journal record; journal restore in this release has been changed to deal with this difference in format across release boundaries.

Reliability, Availability, Maintainability, Monitoring

Management Portal Improvements

The Management Portal now provides access to all functions using one interface, including DeepSee and Ensemble (for Ensemble installations). By providing a new path to each of the functional components, there is now a mechanism to specify access control on each navigational option and granular control for security-critical operations. In addition, users can now specify the most commonly used areas as “favorites” for even faster navigation.

Mirroring Enhancements

In this release, several enhancements have been added to mirroring:

  • Asynchronous mirror members now purge mirror journal files that have been applied locally and are no longer needed

  • The mirroring communication / data transfer process has been optimized for performance by sending larger chunks of data from the primary to the backup failover member

  • The mirror Virtual IP (VIP) now supports IPv6 addresses

Caché Monitor History Database

The Caché Monitor History Database introduces a facility to capture and analyze historical system statistics such as performance metrics, and errors reported. It supplies a baseline for analyzing performance anomalies and provides historical data to facilitate capacity planning.

A default set of metrics is defined and the schedule for capturing these metrics can be defined by the user. These metrics are fully SQL-enabled, and an API is provided to query the results stored in the database.


Web Services Control Separate From CSP Control

In this release, for each web application (formerly known as CSP application), users can specify if CSP and or Web Service access is enabled as part of the web application definition.

Two-Factor Authentication For CSP

In this version, InterSystems has broadened the use of two-factor authentication, introduced with 2010.2, to also be used with CSP applications. If enabled, users will, after successful authentication, be challenged to enter an additional code, which has been separately transmitted to their mobile device.

Web Service Licensing

Beginning with this release, Caché will now consume a license unit for anonymous connections, and will hold this license unit for a grace period of ten seconds, or for the duration of the web service connection, whichever is longer.

Web service connection with named users (login), already consumed a license unit, and there is no change for these type of connections.

Managed Encryption Keys

Based on the existing Caché implementation of data-at-rest (for example, database encryption) keys, this release enables application developers to use the same strong keys, and key management capabilities on more granular data. Managed encryption keys are loaded into memory and applications refer to these keys via a unique key identifier, therefore protecting access to the key itself.

The system is designed to load four keys into protected memory. In addition, Caché now provides a new encryption function which will embed the key identifier in the resulting cipher text. This enables the system to automatically identify the corresponding key, and allows application developers to design re-encryption methods, which are completely transparent to the application, without causing any down time.

This new mechanism is designed to encrypt special data elements (such as credit card numbers), and may or may not be used in conjunction with database encryption.

Caché 2011.1 Upgrade Checklist


The purpose of this section is to highlight those features of Caché 2011.1 that, because of their difference in this version, affect the administration, operation, or development activities of existing 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 2010.1 and 2011.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 2011.1. The items listed here are brief descriptions. In most cases, more complete descriptions are available elsewhere in the documentation.

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 the addition of pages to assist with database mirroring.

Packaging Changes And License Keys

The new product packaging announced in 2011 by InterSystems offers more capabilities and features for your current license types. Previously issued license keys will continue work with 2011.1. You do not require a new license key if your application uses only the capabilities offered by the previous product terms and conditions.

If, however, you wish to take advantage of the additional capabilities available for your license type, please contact your InterSystems sales representative to obtain a new, equivalent license key.

Operational Changes

This section details changes that have an effect on the way the system operates.


In prior versions, license units were not consumed for CSP sessions when $USERNAME equalled "UnknownUser". Now, if the Caché license key has the Web Add-On feature enabled, it is necessary to explicitly declare the Web application public in order to avoid consuming a license key; otherwise, CSP sessions and SOAP sessions consume a license unit.

This can be accomplished for CSP applications by creating a subclass of the %CSP.SessionEventsOpens in a new tab class and defining a method to handle the OnStartSession event, and invoking $SYSTEM.License.PublicWebAppUser() from it.

Furthermore, anonymous SOAP requests (those where no Caché login occurs) now consume a license unit for a minimum of 10 seconds. Applications do not require modification, but customers may need to purchase additional licenses if they service SOAP requests from Caché.

Calling $SYSTEM.License.Login(LicenseId) from a CSP server process or from a SOAP Web Service process will consume a license unit for the Caché server process inappropriately. This license unit is associated with the CSP or SOAP session rather than with the server process because subsequent requests may be fulfilled by different Caché processes.

The $SYSTEM.License.Login(LicenseId) API consumes a license unit that is associated with the Caché server process. Calling this API from a CSP or SOAP server process effectively creates two license instances, one for the session and one for the process. The process license instance is not released unless the process exits, which may never happen. The appropriate way to explicitly designate the license identifier for a CSP session is by calling the %CSP.Session:Login method.

2K Databases Mounted ReadOnly

Beginning with this release, 2K databases will no longer be mounted as writable by Caché. This is the next step in the announced removal of support for 2K databases. If you wish to write data to such a database, you must convert it to the 8K format. The method ##class(SYS.Database).Copy()Opens in a new tab can be used to convert a database to the larger format.

Changes To Configuration File

Two parameters have been added to the .cpf file:

  • The LibPath parameter is added to the [config] section.

    It is used for Unix® only and sets the LD_LIBRARY_PATH environment variable used to search for third-party shared libraries. It is ignored on Windows and OpenVMS. It is a string property with no required or maximum length. This settings take effect immediately; no system restart is required.

  • The QueryProcedures parameter is added to the [SQL] section.

    This defines whether or not all class queries project as SQL Stored Procedures regardless of the SqlProc setting of the query. The default is 0, that is, only class queries defined with SqlProc=1 will project as Stored Procedures. When set to 1, all class queries will project as stored procedures. This settings take effect immediately; no system restart is required. However, you must recompile the classes with the class queries in order for this change to have an affect.

  • In the [Debug] section, setting dumpstyle=3 will prevent shared memory from being included the core dump

Audit Records Contain Operating System Userid

Starting in this release, the username is now part of the audit record,. When displayed, it is truncated to 16 characters.

The real operating system username is only returned when connecting to UNIX® or OpenVMS systems; On Windows, it will return the username for a console process; for telnet it will return the $USERNAME of the process; for client connections, it contains the username of the client.

Failure To Mount Required Database At Recovery Is Now Fatal

In prior releases, Caché recovery would skip required databases that failed to mount and continue processing; but startup would later fail when processing the database section of cache.cpf which resulted in shutting down the instance. With this version, failing to mount a required database during Caché recovery is now a fatal error that will cause startup to abort at that time. This allows the underlying issue to be addressed sooner.

TaskManager Jobs Now Use Append IP Address

Customer tasks started via the Cache Task Manager use the "Run As" user name as the license identifier. Beginning with version 2010.1, Caché appended the peer IP address to the user name for such jobs. However, there is no peer address for processes started by the task manager, and no address was appended. This caused an inconsistency in license consumption between jobs started by the task manager and those started by other means. Beginning with this release, jobs started by the task manager now append the local IP address.

Emergency Login Policy

With this version, the Emergency Login policy has been expanded to accommodate two-factor authentication.; the policy is now:

  1. During emergency access only the emergency user may log in. Console, Terminal, and CSP are the only services enabled.

  2. For enabled services, only authenticated access is permitted. Caché uses its own password authentication for the services, where the emergency access username and password must be used.

  3. If the an application has a custom login page that page is used during emergency login.

  4. For /csp/sys applications, the standard login page (%CSP.Login.cls) will be used during emergency access even if there is a custom login page available. Using the system default assures that the user has access to the Management Portal in emergency mode.

  5. Two-factor authentication is ignored in emergency access mode; applications with two-factor authentication enabled will be inaccessible to the emergency user.

Collation Checking On Upgrade

In this version, during an upgrade installation, the new method ##class(SYS.Database).FixDefaultGlobalCollation(Directory)Opens in a new tab is run on all user databases which are defined in an instance, and are mountable by the instance. This method will report to the cconsole.log any errors in collation of system globals.

If any errors are detected, the user should run the method again from a programmer prompt, and pass the modify database flag as the second argumentOpens in a new tab which will recollate the global in the correct order.

System Freezes When Journal Daemon Is Hung

On a system set to freeze on journal error, if the Caché control process detects that journal daemon (JD) is hung (no activity for 10 seconds) while there is journal data to write, it will stop the write daemon and the system will freeze.

Platform-specific Items

This section holds items of interest to users of specific platforms.

All platforms

The OpenSSL libraries built and installed with our products have been updated to version 1.0.0b. All InterSystems projects dependent on OpenSSL have been updated to use new version.

FOP has been updated to Version 1.0 with a specific InterSystems patch for processing in Arabic.

Mac OS X — JOB Command Changes

The mechanism for the JOB command on Mac OS X has changed. It solves a problem but may introduce side effects. Due to the way that the underlying kernel interacts with Mac OS X processes, and to the existence of GUI sessions, the traditional UNIX® way of creating daemons (fork/exec) is not enough for Mac OS X. Apple recommends the use of launchd (or launchctl, which is its user interface) to start all background daemons.

This release implements that recommendation. The JOB command on Mac OS X now calls launchctl to start the Caché JOBs.

AIX — Change Direct I/O Handling

On AIX systems when opening databases, journal files and/or the WIJ for “direct I/O” Caché specifies the O_CIO option to open the file for concurrent I/O rather than direct I/O. The use of O_DIRECTIO allows other openers which can cause problems if the other process employs buffered I/O.

  • Changes to $ZF

    On OpenVMS, user-supplied $ZF() functions may be written in either C or MACRO. Because of a mismatch in the definitions of PRIV and NOPRIV between the two different header files (cdzf.h and czf.m64), the PRIVS=YES feature in czf.m64), was set opposite of what it should be. User $ZF() functions written in C that depend on the PRIV/NOPRIV feature must be recompiled.

  • Changes To Compiler Version

    Due to support requirements, OpenVMS compilers have changed. They are now at Version 7.2. Executables built under the previous compilers are not compatible with the new runtimes.

    This in turn implied that Xalan and Xerces needed to be recompiled. InterSystems has taken advantage of this to upgrade Xalan to version 1.10 and Xerces to version 2.7 and incorporated them as libraries (.olb) which are compiled into our executables and no longer distributed separately.

  • Changes To Xalan, Xerces, and unixODBC

    The change in compiler version implies that Xalan, Xerces and unixODBC needed to be recompiled. InterSystems has taken advantage of this to upgrade Xalan to version 1.10 and Xerces to version 2.7 and incorporated them as libraries (.olb) which are compiled into our executables and no longer distributed separately.

    The OpenVMS version of unixODBC has been upgraded to version 2.2.12 which is the same used by other platforms.

  • Informix SQL Converter Not Supported

    The SQL converter from Informix to Caché is not supported on OpenVMS. Attempts to run the Informix conversion on an OpenVMS system will now produce an error instead of logging a message in the console log.

  • SHA-2 Functions Not available On OpenVMS Versions Prior To 8.4

    On OpenVMS 8.2-1 and 8.3, the functions $System.Encryption.RSASHASign() and $System.Encryption.RSASHAVerify() do not support the SHA-2 hash functions when using bitlengths of 224, 256, 384, or 512 bits. The HP-supplied OpenSSL libraries in these releases are based on OpenSSL 0.9.7e, which does not include support for the SHA-2 functions.

  • Upgrade Quotas For Background JOBs

    In this version several defaults for OpenVMS process quotas for JOBbed processes have been updated. The primary one is PGFLQUOTA, which limits allocation of virtual memory and was causing problems processing very large XML files. BYTLM and FILLM have also been raised to bring them in line with recent vendor recommendations.

Windows — Installer Change

If the installer finds that the IIS virtual directory, /csp, is already configured, it will no longer update the IIS configuration data.

In addition, new properties have been defined to control updating Apache and IIS:




Setting any of these to a value of 1 will result in installation updating of the corresponding CSP binary files, but will not make any changes to the corresponding web server configuration. Setting the property to 0 will make the installer update the appropriate web server configuration regardless of the existence of the /csp virtual directory.


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.

System Operational Changes

Compiler Version Changed Due To Support For Large Routines

The internal compiler version has been incremented to reflect changes in the object code to support large routines. This means that routines and classes compiled on this version cannot be copied to and executed on previous versions. Attempts to do so will result in <RECOMPILE> errors.

Caché Fully Qualified Domain Names And Kerberos

The normal form of Kerberos server principal names is specified in RFC 4120, Kerberos V5, section 6.2.1. The principal name is composed of several pieces. They are:

  • the name of the service

  • a “/”

  • the Internet domain name of the host

  • an “@”

  • realm of the key distribution center (KDC) where the server is registered

An example of such a name is cache/

In previous versions, Kerberos authentication for non-terminal connection to Caché on platforms other than Windows used an ambiguous format: (cache/host@KDC-realm) which was incompatible with the usage when accessing Caché with csession. In this version, Caché has been changed to always generate the correct form of the service principal name.

In most cases, this should have no impact because it is thought that the vast majority of sites will have used the FQDN form when defining the server principal name in the instance keytab. However, it is possible that some sites have defined the server principal name using just the host name, for example for host oakland, the value cache/oakland@KEYDISTRIBUTION.COM. These sites will experience a problem after upgrading to a version of Cache with this revision.

To correct this error, a keytab entry for the server principal should be created; in this example, cache/ should be created to replace the non-standard cache/oakland@KEYDISTRIBUTION.COM.

ECP Will Now Use Process ID In Place Of Job Id

In this release, ECP will log the PID instead of the job ID in the journal entries when the job is not a thread. This means that the ECP session will not be backward compatible; in mirror or cluster configuration a new version of the master cannot failover to an earlier version of the product.


The ECP protocol will remain backward and forward compatible, however.

Shadowing Initiation Requires Start Event

When starting a shadow in the Management Portal, or via ^SHADOW, the user is required to select a source event to start shadowing at. This is true regardless of the value of the StartPoint property of the shadow configuration object, which is deprecated as of this change. One should always specify the StartPoint parameter in ##class(SYS.Shadowing.Shadow).Start()Opens in a new tab method to start a shadow non-interactively.

Shadow Information Is Now In The CPF

When a customer upgrades to version 2011.1 or later, and there are shadow systems defined, the shadow information is converted and moved to the CPF file. There are now two new sections in the file:

  • The [Shadows] section defines the name of the shadow and its properties.

  • The [MapShadows.NAME] contains the shadow directory mappings.

Exporting Globals No Longer Checks Name Format

An application which relied on %Library.Global.Export() to reject names which did not end in “.gbl” may no longer work as expected. Names that do not end in that suffix will be accepted and, if globals with those names exist, they will be exported. If not, they will not be part of the export, but no error will be generated. $SYSTEM.OBJ.Export() can be used in situations where the caller wants the “type” to be required.

%GSIZE Output Format Alterations

Applications which parse %GSIZE output and expect a fixed number of columns may now have problems. The numberof columns in the output is now a constant for a given run of %GSIZE (prior to this it was variable), but the number of columns can vary from run torun depending on the size of the longest global name in the output. Rather than parsing the %GSIZE output, applications should use the Size query in %SYS.GlobalQueryOpens in a new tab to retrieve global size information.

Journaling Turned On For Multiple Compiles

In previous versions, Caché defaulted to disabling journaling while doing a class compile to avoid filling up journal files and to improve the speed of the compile slightly. Due to recent changes in the class compiler, such as multiple compilation, this is no longer necessary (or desirable when using mirroring).

Beginning with this version, class compiles will now be journaled by default. This will add more data to the journal files if many class compliations are done. On a development system, administrators may wish to consider changing the default /journal qualifier setting to disable journaling. On a production system, however, administrators almost certainly want the new default of journaling the class compile.

Library Path Now Part Of cache.cpf

Using LD_LIBRARY_PATH per user can lead to spoofs that could execute code at root level. Beginning with this version, the LD_LIBRARY_PATH data will be part of cache.cpf. Other than <install_directory>/bin, nothing will be in the current library search path for the session other than what is in the LibPath field in cache.cpf. The field will be updatable via the Management Portal. All applications relying on the LD_LIBRARY_PATH environment variable to set search paths for third-party shared libraries will be affected.

Device Aliases Must Be Unique

This release checks the aliases specified for devices. If the same alias is used for more than one device, Caché will report an error at startup and ignore the second definition.

Changes To Emergency Startup

Emergency Startup has been enhanced in this version so that the following occurs:

  • TASKMGR is not started.

  • Shadowing is not started.

  • Ensemble productions are not started.

  • Mirroring is not started.

  • ZSTU,%ZSTART,%ZSTOP,ZSHUTDOW are not run when the system starts or stops.

  • User processes which log in using the emergency id do not run %ZSTART or %ZSTOP.

In addition, the STU=1 parameter in the CPF file has been removed. If you need to start the system for maintenance, use the Emergency Startup option.

Improved Key Management

Beginning in this version, it is no longer necessary to have a database or managed encryption key activated in order to manage a key file. It is, however, now necessary to know a valid encryption key file administrator username and password in order to add new administrators to a key file or to configure unattended database key activation at startup.


This is yet another reason why it is critical to have a backup key file containing an administrator entry stored along with a copy of that administrator's password in a physically secure location.

TROLLBACK Does Not Initiate Database Mount

One of the general principles of Caché is that when a database has been explicitly DISMOUNTed, a database access attempt should not implicitly cause it to be MOUNTed; it must be explicitly mounted by operator action. TROLLBACK has been corrected to be consistent with this principle.

New Locales

A new collation is available for the Slovenian locale. Slovenian2 is similar to Slovenian1, except that upper and lowercase letters collate together (merged cases).

Turkish (Unicode)

A Unicode Turkish locale is now available (“turw”). By default it uses the Turkish1 collation.

New DDL Type Mapping For VARCHAR(Max) And NVARCHAR(Max)

Beginning with this version of Caché, there are new default system-defined DDL mappings for VARCHAR(Max) and NVARCHA(Max); both of these map to %Stream.GlobalCharacter. Prior to getting a version with this change, systems can simply add these mappings to the user-defined DDL Mappings. This change allows VARCHAR(Max) and NVARCHAR(Max) to be used as an argument to a procedure in a TSQL CREATE PROCEDURE DDL statement.

Routine Compiler Changes

Support For Larger Routines

Beginning in this release, the compiler will now allow routines up to 8MB in length. When a compiled routine exceeds 32KB, Caché will use up to 128 64KB routine buffers to hold the routine. These buffers will be allocated and managed as a unit. Therefore, the use of large routines compiled in this release will affect routine buffer allocation. Generally, more 64KB buffers will be required than in previous releases; however, the distribution of memory among the buffer pools will depend on the realtime distribution of routine sizes in use at a specific site.


Routines compiled on this version will not run on earlier versions of Caché.

Routine Changes

Implement Japanese Datetime Formats

Two new date formats have been added to the list of dformats for $ZDATE and related functions:

  • 16 – year, month, and day values with Japanese kanji for year, month and day following each one, respectively; that is, YYYY$CHAR(24180)MM$CHAR(26376)DD$CHAR(26085)


  • 17 – like format 16 with the addition of a space after the year signifier, and another after the month signifier.

Make URL Translation Symmetric For Non-Latin1 8-Bit Character Sets

In 8-bit locales not based on Latin1 (for example, “ruw8”, the CP1251-based Russian locale),

$ZCVT("%XX", "I", "URL")

now interprets XX as the hex code of a character in the current character set. In previous releases, this was assumed to be a Unicode character; in some character sets this codepoint did not have a corresponding value in the current character set and was replaced by a default character such as “?”.

The new behavior means that in CP1251

$ZCVT($C(192), "O", "URL") = "%C0"


$ZCVT("%C0", "I", "URL") = $C(192)

make a round trip using the URL translation valid for all characters.

Class Changes

Larger Class Limits

Beginning with this release the system now supports a larger class descriptor. This means that classes now can support a larger number of members declared in the class. The limits on class inheritance depth, and the number of superclasses allowed have also been defined. For a complete list of the applicable bounds, see “Guide General System Limits” in the Caché Programming Orientation Guide.

Error Reporting Changes

The standard Caché mechanism for returning an error is to use the $$$ERROR macro with a standard message. In many cases, the message contained only a description of the error without any context information. Several messages, including the “object to load not found” message now include the classname where the error was encountered. It is possible that some SQL storage applications may have to be changed to recognize the new format.

Update Of Class Dictionary To Level 25 – LegacyInstanceContext

This version of Caché updates the version of the class dictionary to level 25. Among opther changes, this introduces the LegacyInstanceContext class keyword wose presence indicates that the class relies on generated code that passes %this as the first argument to instance methods. This was previously announced in 2009 in the Compatibility BlogOpens in a new tab.

As an aid, the class dictionary upgrade looks for references to %this. It scans both code and comments in case there are usages of $XECUTE and $TEXT even though this may result in false positives. If it finds any such references, it marks the class as needing LegacyInstanceContext so the compiler will continue to generate code to pass %this as the first argument to instance methods.

If no instances of %this are found, then the class is not marked LegacyInstanceContext so instance methods will no longer assume %this is passed as the first argument.

This approach does not, however, uncover separate code that assumes %this exists and is properly set. Consider a class with a method that calls an external routine such as:

method Test()
    Quit $$Func^Routine()

where Routine is:

Func () public {
    Quit %this.Name

Because the use of %this will not be discovered in the scan of the class (it is external to that source), it will not be marked as LegacyInstanceContext. Subsequent execution may result in an <UNDEFINED> error; in much harder-to-debug situations, %this may be pointing to the wrong context or not at an object instance at all.

All new code should rely on $this for context; %this will not be set for new classes as it is deprecated.. All older classes marked as LegacyInstanceContext=1 will continue to behave the same as in previous releases.

No change is necessary to existing classes because of LegacyInstanceContext. However, if you do want to update a class, the steps are as follows:

  1. Replace all occurrences of %this with $this in a given application.

  2. Remove the LegacyInstanceContext keyword from all classes in the project or application.

  3. Recompile the application.

Class Deletions

The following classes were present in version 2010.2 and have been removed in this version:

  • %CSP.UI.Portal — ObjectGatewayStartStop

  • %ExtentMgr — Extent

  • %Library — CppApi

  • %OSQL — Debugger, Transformer

  • %SQL — Routine, RoutineColumn

  • %Studio.SourceControl — ISCCheckin

  • %WebStress — DataTransfer, Page

  • %WebStress.UI — GridDetails, Attributes, Columns, SelectOptions, Tags, Transfer, SaveData

  • %WebStress.UI — Input, Menu, Previous, Definitions, Root, Search, Criteria, Displays, SearchPage

  • %XML — SupportCode

  • %ZEN.Report — sort

  • %cspapp.op — webstress, appservers, appsystem, blank, encrypt, generators, nopagedelay, noresultstore, proxysetupmozilla, proxysetupmsie, scriptedit, scriptrecorder, scriptrecorderstatus, showerrors, showurls, testappstats, testedit, testprint, testrun, visual, visualdisplay, visualdisplayoptions, webservers

  • SYS.Info — Advertiser

  • com.intersys.jdbcgateway — JDBCGateway

  • — InputStream, OutputStream, Serializable

  • java.lang — Class, ClassLoader, Object, Package, AccessibleObject, Constructor, Field, Member, Method

  • — ContentHandler, ContentHandlerFactory, FileNameMap, URL, URLConnection, URLStreamHandler, URLStreamHandlerFactory

  • — CodeSource, Guard, Key, Permission, PermissionCollection, Principal, ProtectionDomain, PublicKey, Certificate

  • java.util — Collection, Enumeration, Iterator, Map, Set

Class Component Deletions

The following class components have been moved or removed in this version from the class where they were previously found.

Class Type Name(s)
%CSP.UI.Portal.AdvancedSettingsTemplate Method DrawTitle
%CSP.UI.Portal.AdvancedSettingsTemplate Parameter APPLICATION
%CSP.UI.Portal.AdvancedSettingsTemplate Property ParentURL
%CSP.UI.Portal.Application Method DrawTitle
%CSP.UI.Portal.Application Parameter CSSINCLUDES
%CSP.UI.Portal.Config.Device Property ParentURL
%CSP.UI.Portal.Config.SQLDataTypes Method DrawLocatorExtra
%CSP.UI.Portal.Config.SQLDataTypes Property SingleSubject
%CSP.UI.Portal.Config.SQLDataType Method DrawLocatorExtra
%CSP.UI.Portal.Config.ZenReport Method DrawTitle
%CSP.UI.Portal.Config.ZenReport Property LocatorParent
%CSP.UI.Portal.DatabaseFreespaceCleanup Method DrawTitle
%CSP.UI.Portal.DatabaseFreespaceCompact Method DrawTitle
%CSP.UI.Portal.DatabaseFreespace Method DrawTitle
%CSP.UI.Portal.DatabaseFreespace Parameter APPLICATION
%CSP.UI.Portal.FileManTemplate Method DrawTitle
%CSP.UI.Portal.FileManTemplate Parameter APPLICATION, DOMAIN
%CSP.UI.Portal.FileManTemplate Property ParentURL
%CSP.UI.Portal.FileMan Parameter APPLICATION
%CSP.UI.Portal.FileMan Property ParentURL
%CSP.UI.Portal.ISQL Method DrawTitle
%CSP.UI.Portal.ISQL Property ParentURL
%CSP.UI.Portal.Mappings Method DrawTitle
%CSP.UI.Portal.NLSEdit Method DrawTitle
%CSP.UI.Portal.NLSEdit Parameter APPLICATION
%CSP.UI.Portal.NLS Method DrawTitle
%CSP.UI.Portal.ObjectGatewayActivities Method DrawTitle
%CSP.UI.Portal.ObjectGatewayStart Method DrawTitle
%CSP.UI.Portal.ObjectGatewayStop Method DrawTitle
%CSP.UI.Portal.ObjectGateways Method DrawTitle
%CSP.UI.Portal.ObjectGateway Method DrawTitle
%CSP.UI.Portal.RoutineCompare Method DrawTitle
%CSP.UI.Portal.SSLList Parameter APPLICATION
%CSP.UI.Portal.SSL Method CheckAllBlanks, DrawTitle
%CSP.UI.Portal.Template Method DrawTitle, GetQuickLinks
%CSP.UI.Portal.X509Credentials Method DrawTitle
%CSP.UI.Portal.X509Credentials Parameter APPLICATION
%CSP.UI.Portal.X509Credential Method CheckAllBlanks, DrawTitle
%CSP.UI.Portal.X509Credential Parameter APPLICATION
%Dictionary.ClassDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledClass Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledConstraintMethod Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledConstraintMethod Property RuntimeImplementation
%Dictionary.CompiledConstraint Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledForeignKey Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledIndexMethod Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledIndexMethod Property RuntimeImplementation
%Dictionary.CompiledIndexProperty Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledIndex Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledInstanceVar Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledInstanceVar Property RefSlot
%Dictionary.CompiledMethod Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledMethod Property RuntimeImplementation
%Dictionary.CompiledParameter Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledProjection Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledPropertyMethod Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledPropertyMethod Property RuntimeImplementation
%Dictionary.CompiledPropertyUDLText Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledProperty Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledQueryMethod Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledQueryMethod Property RuntimeImplementation
%Dictionary.CompiledQuery Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledStorageDataValue Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledStorageData Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledStorageIndex Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledStorageProperty Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledStorageSQLMapData Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledStorageSQLMapRowIdSpec Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledStorageSQLMapSubAccessvar Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledStorageSQLMapSubInvalidcondition Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledStorageSQLMapSub Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledStorageSQLMap Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledStorage Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledTrigger Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledUDLText Method %AcquireLock, %ReleaseLock
%Dictionary.CompiledXData Method %AcquireLock, %ReleaseLock
%Dictionary.ForeignKeyDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.IndexDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.MethodDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.ParameterDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.ProjectionDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.PropertyDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.PropertyUDLTextDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.QueryDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.StorageDataDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.StorageDataValueDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.StorageDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.StorageIndexDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.StoragePropertyDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.StorageSQLMapDataDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.StorageSQLMapDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.StorageSQLMapRowIdSpecDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.StorageSQLMapSubAccessvarDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.StorageSQLMapSubDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.StorageSQLMapSubInvalidconditionDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.TriggerDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.UDLTextDefinition Method %AcquireLock, %ReleaseLock
%Dictionary.XDataDefinition Method %AcquireLock, %ReleaseLock
%Installer.User Property Password
%Library.CacheSQLStorage Method %SaveDataInsert, %SaveDataUpdate
%Library.EnsembleMgr Method check4Install
%Library.GlobalStreamAdaptor Parameter TEMPGLOBALNAME
%MV.StudioRoutines Method Compile
%Net.Remote.Proxy Method %Execute0, %Execute0R, %Execute1, %Execute1R, %Execute2, %Execute2R, %Execute3, %Execute3R, %Execute4, %Execute4R, %ExecuteGetter, %ExecuteOL0, %ExecuteOL1, %ExecuteOL2, %ExecuteOL3, %ExecuteOL4, %ExecuteOLR0, %ExecuteOLR1, %ExecuteOLR2, %ExecuteOLR3, %ExecuteOLR4, %ExecuteSetter
%Net.RemoteConnection Method ExecuteCode
%Net.abstractMQ Property mqCOptID, mqCloseID, mqCommitID, mqConnID, mqDisconnID, mqErrLogID, mqGetID, mqGetLastErrID, mqGetStreamID, mqInitID, mqMsgDescID, mqMsgDescIID, mqMsgDescSetID, mqPutID, mqPutStreamID
%SOAP.WebBase Method GetElementQualified
%SOAP.WebClient Property MethodName
%SOAP.WebService Property ImportHandler
%SQL.DynamicStatement Method LookupCache
%SQL.Shell Method load
%SYS.Audit Property ZPad3, ZPad4, ZPad5
%SYS.PTools.Stats Method Init
%SYS.PhoneProviders Method DeleteId, Save
%Studio.SourceControl.ISC Method DisplayUncommitted, GetUncommitted, ListUncommitted, RefreshUncommitted, RemoveAllUncommitted, RemoveUncommitted, SetUncommitted, UpdateUncommitted
%Studio.SourceControl.ItemSetWS Parameter CCRSrc
%Studio.SourceControl.ItemSet Method %OnBeforeSave, MarkCommitted
%WebStress.Control Method BuildCode, CheckGeneratorDataValid, DownloadData, GeneratorDataValid, GetExportType, GetIterationData, GetNextRunNumber, GetRunData, GlobalData, GlobalDataBuild, IterationData, ResetControlData, RunData, SetControlData, Transfer, Upload, UploadAllData, UploadCode, UploadData, UploadMiscData
%WebStress.Control Property ValidData
%WebStress.Utils.Recorder.Summary Property lines
%XML.DataSet Method TypeToXSD, XMLExport, XMLImport
%XML.Security.EncryptedType Property CipherData, EncryptionProperties
%XML.Utils.SchemaReader Property TargetElementQualified
%ZEN.Report.Display.Chart.plot Method needsDataMax, needsDataMin
%ZEN.Report.Display.atthtml Method %DrawToHTML
%ZEN.Report.Display.atthtml Property name, value
%ZEN.Report.Display.attxslfo Method %DrawToXSLFO
%ZEN.Report.Display.attxslfo Property name, value Property colspan, rowspan Property colspan, rowspan
%ZEN.SVGComponent.chart Method buildLabelArray
Config.CPF Method ConvertTo201022
Config.Mirror Property Heartbeat
Config.MirrorMember Method StartMirror, StopMirror
SYS.WSMon.wsen.Items Parameter NAMESPACE
Security.System Method LDAPSearchPasswordGet, LDAPSearchPasswordSet
Security.System Property DefaultSecurityDomain, InactiveLimit, InvalidLoginAction, InvalidLoginLimit, LDAPAttributeComment, LDAPAttributeFullName, LDAPAttributeNameSpace, LDAPAttributeRoles, LDAPAttributeRoutine, LDAPAttributes, LDAPBaseDN, LDAPCACertFile, LDAPClientTimeout, LDAPDomainName, LDAPFlags, LDAPHostNames, LDAPSearchPassword, LDAPSearchUsername, LDAPServerTimeout, LDAPUniqueDNIdentifier, PasswordExpirationDays, PasswordPattern, PasswordValidationRoutine, SecurityDomains
Method Return Changes

The following methods have different return values in this version of Caché:

  • %CSP.UI.System.Index — ProcessIndexZen

  • %Library.ProcedureContext — AddContext

  • %SYSTEM.Encryption — RSAEncrypt

  • %UnitTest.TestCase — AssertSkippedViaMacro, AssertStatusNotOKViaMacro, AssertStatusOKViaMacro

  • %WebStress.Control — StartMonitor

  • %ZEN.Datatype.boolean — XSDToLogical

  • %ZEN.Report.Version — getVersion

Method Signature Changes

The following methods have different calling sequences in this version of Caché:

Class Name Method Name(s)
%CSP.Response SetCookie
%CSP.Session %OnNew, GetSession, Login, SetContext
%CSP.UI.Portal.Config.ZenReport SaveData, doBrowse
%CSP.UI.Portal.NLSEdit SaveInternalDefaults
%CSP.UI.System.ExpResultPage IntegrityCheckBack
%CSP.UI.System.ImportPane DrawContent
%CSP.Util.Librarian FindDocBookLink
%IO.FileStream NewTempFilename
%Installer.Installer CSPApplication
%Library.AbstractStream DeleteStream, IODeleteStream
%Library.Collation MVDLEDate
%Library.File CopyDir, CopyFile, NormalizeDirectory, NormalizeFilename
%Library.FileStreamAdaptor IODeleteStream, ReadLine
%Library.GTWCatalog SQLFieldsExecute, SQLFieldsJExecute, SQLForeignKeysExecute, SQLForeignKeysJExecute, SQLPrimaryKeysExecute, SQLPrimaryKeysJExecute, SQLProcedureColumnsExecute, SQLProcedureColumnsJExecute, SQLProceduresExecute, SQLProceduresJExecute, SQLSpecialColumnsExecute, SQLTablesExecute, SQLTablesJExecute, getIndexInfoExecute
%Library.Global Export
%Library.GlobalEdit CheckGlobalIntegrity
%Library.GlobalStreamAdaptor IODeleteStream
%Library.Persistent %DeleteExtent
%Library.RoutineMgr ImportItemListExecute
%Net.FtpSession sendCommand
%Net.Remote.Proxy %PostInvoke, %PreInvoke, %ProcessError
%SOAP.Security.SecurityTokenReference GetX509Data, GetX509KeyIdentifier
%SOAP.WebBase GetEncodedAttribute, ProcessHeaders, ProcessSOAPEnvelope
%SQL.DynamicStatement Prepare
%SQL.Shell %Go, cmdSet
%SQL.Statement %OnNew
%SYS.Audit ListByEventExecute, ListByPidExecute, ListByUserExecute, ListExecute
%SYS.AuditString LogicalToXSD
%SYS.GlobalQuery SizeExecute
%SYS.PTools.SQLStats Init
%SYS.PTools.Stats LogSave, Report, Start, Stop
%SYS.ZENReportServer %ServeTransform
%SYSTEM.Encryption RSADecrypt, RSAEncrypt
%SYSTEM.INetInfo GetInterfacesInfo
%SYSTEM.OBJ Compile, CompileList, Delete, Export, MakeClassDeployed, SetQualifiers, UnCompile
%SYSTEM.SQL SetDefaultSchema
%SYSTEM.Version Format, GetBuildDate, GetBuildNumber, GetBuildOS, GetBuildTime, GetMajor, GetMinor, GetNumber, GetOS, GetPatchId, GetPlatform, GetPoint, GetProduct, GetVersion
%Stream.FileBinary ReadLine
%Studio.Debugger WatchListExecute, WatchListOrefExecute
%Studio.Project FindInFiles, FindInProject
%Studio.SASchemaUtil loadSchema
%Studio.SourceControl.ISC GetSharedWorkspace, SetCredentials, SetSharedWorkspace
%Studio.SourceControl.ItemSet Load, LoadToNS, LoadToOS
%UnitTest.ODBCSQL runODBCSQLStatement
%UnitTest.TSQL runSQLStatement
%WebStress.Control Prepare
%WebStress.Utils.Recorder Summary
%XML.Adaptor XMLImportAttributes
%XML.DataSet ParseSchema
%XML.Implementation WriteHeaderBinding
%XML.Namespaces AddNamespace, DefineNamespacePrefix, PushNodeForExport
%XML.Schema DefineNamespace
%XML.Security.KeyInfo CreateX509
%XML.Security.Signature ComputeSha1Digest, CreateX509
%XML.Security.X509Data Create
%XML.Utils.SchemaReader AddNS
%XML.Writer CharsText
%ZEN.Auxiliary.abstractController getDataByName
%ZEN.Component.calendar selectDay XMLImportAttributes
%ZEN.Datatype.boolean LogicalToXSD
%ZEN.Dialog.finderDialog GetClassInfo, openSuper
%ZEN.FinderUtils %GetArrayForQuery, sortData
%ZEN.Portal.Application %DrawSmallMenu, %DrawTitleHTML
%ZEN.Portal.selector GetDropdownContent
%ZEN.Report.Display.Chart.chart render, renderLegend
%ZEN.Report.Display.Chart.lineChart renderMarkers
%ZEN.Report.Display.Chart.plot calculateRangeValues
%ZEN.Report.Display.document %DrawPageToXSLFO
%ZEN.Report.reportPage %DisplayPDF, %DisplayPDF1, DeleteTempFiles
%cspapp.op.utilsystaskbuildercontent ContentSave
%cspapp.sec.utilsysapplication SaveConfig
Backup.General ExternalFreeze, SuspendWD
Config.CPF MergeMaps, RemoveDuplicates, UpdateLines, UpdateLinesAgain
SYS.Database SilentIntegrityCheck
SYS.MirrorConfiguration ValidateVirtualAddress
Security.Roles Export
Security.Users Export
%Library.Decimal Now Defaults To Scale=0

The Caché datatype, %Library.DecimalOpens in a new tab, now defaults to a SCALE=0. In previous releases, there was no default SCALE. Upon INSERT/UPDATE or Object Save, the Normalize method will now round to the default SCALE=0 when no SCALE is specified or the property.

Class Compiler Changes

This version of Caché continues the work begun in earlier releases of improving the class compiler. The changes that may require changes to applications are detailed in this section.

Identical Labels In Multiple Methods Of The Same Class

As part of compiling a class, the compiler attempts to pack as many methods of the class into one compiled unit as possible. If two or more methods of that class define a label of the same name, and the methods are marked as PROCEDUREBLOCK = 0, there was the risk that the compiler would include them in the same compiled unit and report a duplicate label error.

Recent improvements in the class compiler have increased the size of the compiled unit and therefore increased the probability that non-procedureblock methods with identical labels could trigger this error. Applications which trigger his condition mustbe written to either use procedurblocks, or to change the label values so there is no overlap.

Avoid Duplicating Properties Inherited From Superclasses In Subclasses

Previously, if an application defined a property X in a superclass, and then created a subclass which did not modify property X at all (just inherited it from the superclass), the class compiler would redefine this property in the class descriptor of the subclass. This was because Caché needed an internal slot number to reference this property by in the class compiler. This requirement has now been removed. Caché now avoids duplicating the properties in the subclass and allows the system code to dynamically inherit the property from the superclass.


No customer should have applications that depend on the internals of the class compiler (deliberately not publicly documented). Any applications using undocumented internal functions such as $zobjval to access data via slot numbers will have to be rewritten.

Users Must Normalize ID Values

Beginning with this release, passing an unnormalized integer to %Open, %OpenId, %Exists, and %ExistsId will no longer work. The applications passing such values must apply normalization prior to calling the method.

Simple ID values are no longer normalized by the various methods that accept an ID as a parameter. ID values passed to the various methods of a class are expected to be in the normalized form that is returned by the <OREF>.%Id() method. If an ID is a simple integer and a value is passed that is not in the integer normal form (01 vs. 1, for example) then the methods named here will fail.

SQL Storage Compiler Now Recognizes SQLCHILDSUB Name

A class that defines a relationship with a cardinality of PARENT is often referred to as a "child class"; and the type class of the relationship is referred to as the "parent class". The ID of the child class is based on the relationship (the ID of the parent) and either a property value or a system assigned value. When the ID is based on a system assigned value, a column is generated in the SQL table projected by the child class. That generated column corresponds to the system assigned value and is referred to as the “childsub”; it is also, by default, the generated column name.

This name can be specified in the storage definition by entering a name in the SQLCHILDSUB keyword of the storage definition. The expression used by the system to assign a value to the childsub (ID in the case of objects) is defined in the SQLIDEXPRESSION keyword.

In prior releases, if an existing child class defined SQLCHILDSUB and compiled the class prior to this release, then the generated childsub column would be named “childsub”. Beginning with this release, the value of SQLCHILDSUB will be used. This presents a backward incompatibility. The prior behavior is the result of an error; the new behavior is correct. The typical workaround for this was to define a property representing the childsub; if that is done then this change will have no effect.

Cardinality Relationships Can Not Enforce REQUIRED

Previously, a relationship with a cardinality of MANY or CHILDREN and also specifing REQUIRED would compile cleanly. Now, an error is reported by the compiler indicating that the REQUIRED constraint for n-cardinality relationships is not supported.

To compile cleanly, remove the REQUIRED constraint.

Compilation Using Multiple Jobs

Beginning with this version, Caché provides the ability to use multiple jobs for large compilations. This is enabled using the qualifier /multicompile; it is disabled by default.

When it is enabled, and the compiler detects that it can employ multiple jobs usefully, it will start up slave jobs which will show up in %SS as being in the %occCompileUtils routine. It communicates with these slave jobs using a global and $SYSTEM.Event to signal that some work should be done. When a slave job completes, it sends back to the main process an indication that the work is complete along with any error information or output to display. So the typical behavior is: workers jobs are started, then work is queued, and the worker jobs process their part of the work. The main process waits for each job to finish its part, and displays the errors or any other output destined for display. When all the work is complete at this level, the main process will loop round and start queuing any remaining work.

Once a worker job is started it will remain around for 10 minutes after the last piece of work it receives in case more work appears to avoid the cost of starting and shutting down jobs.

This code will not improve the speed of compiling a single class, it is only focused on compiling multiple classes in parallel. In addition, the only part of the compilation process that supports this multiple cpu compile is compiling the MAC code into INT code, assembling these into routines, compiling these routines and building the class descriptor. This can only be done in parallel when there is no dependency between the classes being compiled. The compiler detects the dependencies and breaks down the compile based on this automatically. Thus, if classes A and B are not dependent on each other , they can be compiled at the same time. If A is a superclass of B, however, A must be fully compiled before compilation can begin on B; no parallelism is possible.

Use of parallel compilation assumes that all relevant dependencies between classes are expressed in the class declaration. The order classes are compiled in may be slightly different from previous versions of Caché, but the order chosen still satisfies all the dependency rules. If two classes did not specify a dependency, the order in which they are done cannot be predicted; this could potentially cause a problem if two classes were dependent on each other but no dependency had been specified and the sequential compilation order just happened to work correctly. If this occurs, add a CompileAfter or DependsOn dependency between the classes to specify their relation.

Also, the worker jobs will obviously have a different $JOB number from the main process. This means that if data being stored by one slave job during the compile, and another slave job is attempting to access that data using $JOB as an index, that attempt will fail because the $JOB numbers of the two processes differ. This situation can occur, for example, in sophisticated generator methods that interact with one another. The solution for this is to use the %ISCName local variable which is defined in the compiler context; it is a consistent name between the main job and all the worker jobs and so can be used to share information.

The number of jobs used is limited to 16 jobs maximum as recent benchmarks have shown that more jobs than this do not improve overall performance.

Removal Of InterSystems Internal Items

This version removes the method keyword, RuntimeImplementation. It was only intended for use by InterSystems and is no longer required.

It also removes the $$$cIVARrefslot macro. This was undocumented and should not appear in user code. Any code that uses this macro will fail to compile in this version.

Synchronization Order Correction

Sync sets contain entries that represent object filing events - inserts, updates, and deletes. If a sync set contains more than one entry that affects the same object, those entries must be applied in the same chronological order as they occurred originally.

In prior releases, an error existed that caused some entries to be processed out of order. The cause was an unresolved dependency on import. Unresolved dependencies trigger a sync set entry to be scheduled for processing at a later time. This rescheduling could cause entries to be applied out of order and could introduce data corruption.

That error is now fixed, however, it is possible that an application has made some assumptions about the order in which SyncSet entries are processed. If that is the case, the aplication needs to be examined and retested to make certain problems do not occur.

Control Global Kills On %DeleteExtent

The %DeleteExtent method attempts to delete all instances of a class. If all instances are successfully deleted %KillExtent is called to kill any globals that might be left defined. Not all globals are killed, especially in cases where multiple classes share the same globals.

%DeleteExtent has a new parameter, pInitializeExtent, that, if true, causes %KillExtent to be called when all instances of the class are successfully deleted. The default value of pInitializeExtent is 1 (true). If pInitializeExtent is not true, then %KillExtent is not called and some empty globals could still be defined after %DeleteExtent returns. If the class uses a global counter to assign new object ID values, then that global counter will also remain defined in most cases.

Extent Query In %Library.Persistent

%Library.PersistentOpens in a new tab defines a query that is inherited by every class that extends %Library.PersistentOpens in a new tab. The query, Extent, is used to produce a result set containing all instances of a persistent class. The Extent query can be overridden, either as a %Library.ExtentSQLQueryOpens in a new tab or as some other query type. The overridden query must return rows corresponding to each instance of the class and the first column must be %ID.

Change To i%var Handling

The usage i%var is used in <var>Get and <var>Put methods to make direct references to an instance variable. The class compiler previously converted i%var references into the internal slot number where the instance variable was stored. In this version, this is done by the system code which allows the class compiler to be more dynamic. A side effect of this is that the i%var name is not validated at compile time. The code will compile and a runtime runtime error will be generated if the var is not defined in the superclass tree.


The class keyword, SQLROWIDNAME, allows the user to define the name of the SQL column generated as the ROWID. This SQL column corresponds to the object ID which is only accessible through a method call such as %Id(). It is not valid to override the SQLFIELDNAME of a property in a subclass because it violates the rule that every instance of a subclass is implicitly an instance of its primary super class. The SQL ROWID column name cannot be overridden for the same reasons.

Previously, this rule was not enforced on the SQLROWIDNAME value. It is enforced beginning in this version. Failure to observe it will result in a failure to compile the class.

%GUID Invalid As Column Name

If the user class has an existing column whose name is %GUID, then this will now trigger an error during class compile. If the class has GUIDENABLED as true, then the class cannot implement a method named %OverrideGuidAssignment(), a property named %%GUID, or a property whose SQLFIELDNAME is %GUID.

/foldmethod Qualifier Deprecated

The class compiler /foldmethod qualifier used to detect identical methods preserving only one in the generated code has been deprecated. The qualifier no longer has any effect on the generated code.

Bind Properties With CLASSNAME=1 As %Library.List

Any property that specifies CLASSNAME=1 will be bound to SQL as type %Library.ListOpens in a new tab; CLASSNAME=1 means the value for the property is an OID which is in Objectscript $LIST format. A property defined as:

Property OID As %Library.Persistent(CLASSNAME = 1) [ Required ]; 

would, in previous releases, bind to SQL as %Library.IntegerOpens in a new tab. starting with this release, it binds to %Library.ListOpens in a new tab.

Inheriting A Relationship Property From A Secondary Superclass Prohibited

In previous versions, an attempted to inherit a relationship from a secondary superclass would get invalid results due to silent failures of the relationship at runtime. Beginning with this version, the compiler nows detects this in the class compiler and reports an error:

ERROR #5572: Can not inherit relationship property 'X' in class 'Y.Z' as a secondary superclass.

The failure occurred because a primary subclass of a persistent class shares the same extent as the superclass; but a secondary subclass does not. Inherited queries in the secondary subclass could not find the extent of the originating class to properly reference the class data.

Studio Changes

INT/MAC Save Does Not Compile Automatically

In prior versions, there was an option in Studio that allowed a Save of an INT/MAC routine to execute a compile as well. With this version, that feature has been removed because the behavior was already available when using the Compile option; so it was redundant. In addition, not being able to save a modification without having it be projected immediately as executable code, while fine perhaps on a test system, was potentially disastrous on a live environment or a shared one.

A Save for any given document type now simply saves the current version of the document back to the server. A Compile always saves the document and compiles the document into its descendant forms as well. For most users this is simply going to require using a different button or keystroke combination in the Studio. To compile a collection of documents you can make use of a Project and the "Build" option.

Language Binding Changes

Refactor Java .jar Files

In this release, InterSystems has refectored its Java libraries into four parts:

  • cachejdbc.jar – This contains the Caché JDBC driver and is required for all applications using the Java binding. It includes the following com.intersys packages: jdbc, jsse, jgss, and util (newly added in this release).

  • cachegateway.jar – This contains Java and JDBC Gateway. It depends on cachejdbc.jar and includes the packages: com.intersys.gateway and com.intersys.jdbcgate.

  • CacheexTRreme.jar – It contains the components for Java eXtreme, namely the com.intersys packages: gloals, mds, xdo, and xep.

  • cachedb.jar – This contains the remainder of the InterSystems Java components, including Java Binding, Jalapeno, EJB (Enterprise Java Beans), and so on. It holds the com.intersys packages: cache, classes, codegenerator, EJB, jsp, and objects, as well as com.jalapeno package

For more details, please consult The Caché Java Class Packages.

Jalapeño Configuration

Since Jalapeño was first made available, InterSystems introduced multiple configuration options for it that affect performance. Having the “correct” configuration in most cases can improve Jalapeño application performance, in many cases dramatically. The default configuration, however, was not optimized for performance of a typical application but rather was aimed to preserve full compatibility with original version of Jalapeño.

With this version of Caché, the default configuration for Jalapeño has been changed to make it transparent to the application programmer and end user. Specifically, the following features are now available:

  • There is now the ability to set a site-wide default Jalapeño configuration in addition to the existing ability to load a configuration for a given application.

  • The sample default configuration file was reworked to make it self-explanatory. This file can be modified for site-wide defaults as well as copied and adjusted for specific applications.

  • The default configuration has been tuned to provide better performance for the average application.

Default Jalapeño configuration is now stored in Caché Installation directory in /dev/java/conf/ The file is a properties file with comments identifying what options can be configured and how. If the installation lacks this file because it is using an older server version, the hard-wired default is used. However, this configuration file can be added to any Caché server from 2010.1 and later. This file affects all clients connecting to the server, not the clients working on current machine.


The default configuration file now uses a LAZY fetch policy and a GENERATE_HELPERS access method. This requires third-party open source libraries (available under Apache license). If this is not acceptable to a specific site, the configuration file MUST be changed.

Changes To Java Generated Code For Properties

Because of the new object dispatch Java driver in 2010.1 and beyond no longer uses projected values fields ii_<PropertyName>, jj_<PropertyName>, or kk_<PropertyName>. Generated samples will need to have the CacheDB.jar from 2010.1 or later in order to work properly.

Class Name Changes For Caché eXtreme

This change renames the Java package for eXTreme dynamic objects, previously com.intersys.extreme, to com.intersys.xdo (where “xdo” is an acronym for “eXTreme Dynamic Objects”, analogous to “xep” for “eXTreme Event Persistence”). The classes within this package are renamed as follows:

From To
com.intersys.extreme.XTDatabaseConnection com.intersys.xdo.DatabaseConnection
com.intersys.extreme.XTDatabaseConnectionFactory com.intersys.xdo.DatabaseConnectionFactory
com.intersys.extreme.XTDynamicObject com.intersys.xdo.DynamicObject
com.intersys.extreme.XTException com.intersys.xdo.XDOException
com.intersys.extreme.XTNullValueException com.intersys.xdo.XDONullValueException

The sample code java/samples/extreme/extreme/ has been changed to java/samples/extreme/xdo/

Change To Object Save Methodology In Jalapeño

With this version, if the fetch policy is DISCARD_AFTER_FETCH, and a list of related objects have been never accessed by the application from the parent side, then Jalapeño does not check to see if the objects in this list have been modified even on deep save. This drastically improves performance of deep saving a set of objects with a complex relationship graph.

However, there is a possible loss of data when the fetch policy is DISCARD_AFTER_FETCH in the following scenario:

  • Fetch an object (object A) from the database.

  • Make some changes to it and objects that it references.

  • Keep a referenced object (object B) in the application heap memory.

  • Save object A back using deep save to save changes in all related objects.

  • Fetch object A back.

  • Make some changes to object B using its in-memory heap reference.

  • Save object A using deep save.

In this scenario, the modifications to object B might be not saved! Under these conditions, if application expects implicit modifications of objects in the application context after they are saved to be noted, it must not use fetch policy DISCARD_AFTER_FETCH. It should use the policy REFETCH_AFTER_FETCH.

Changes to Java Mappings In Jalapeño

In this version, the mapping of Java integers has been changed from the Caché datatype class, %IntegerOpens in a new tab, to %EnumStringOpens in a new tab. This makes the handling of logical values used in ODBC more intuitive.


This is the default behavior and may be overridden by an @Extends annotation.

Use Most Specific Types In Datatype Collection Properties For ActiveX and C Bindings

Before this release, collection properties were projected as collections of strings in the dynamic C++ binding. For example, the property

property sysListColn as list of %List;

was projected as a collection of strings. This had the unfortunate consequence that if any element of the collection was incorrectly converted to a %String, it could corrupt the entire %List.

Now the dynamic class definition that is returned for the type of a collection property reflects the correct collection element type. For example, the meta information for method GetAt() of the dynamic class definition associated with sysListColn now says that the type id of the returned value is D_LIST_ID.


This change is off by default for backward compatibility. To turn it on in C binding: call cbind_set_typed_colns(). To turn it on in CacheActiveX: call .factory.SetOption("TypedCollections", 1)

Preserve The Value Of Decimal Values Used In C++ Queries

In prior versions, d_query represented d_decimal to ODBC as SQL_C_DOUBLE; now it uses SQL_C_CHAR. The string conversion preserves the exact value of the number.

SQL Changes

Parenthesized Literal Replacement Following An ID

Because of changes in the SQL parser, in some rare cases, constants that were manually surrounded with parenthesis to prevent constant replacement, would now have to be surrounded by two pairs of parenthesis to achieve the same effect. That is, instances like

WHERE f4 = ('Hello')

should be changed to

WHERE f4 = (('Hello'))

For backwards compatibility, in certain contexts, a single pair of parenthesis will continue to work as prevention for literal replacement, for example:


Before this change, literal replacement was done even for a parenthesized literal if the parenthesis followed the ID "IN". If you wanted to prevent literal replacement in that case, you would enclose it in 2 pairs of parenthesis. The logic was changed to replace parenthesized literals that follow any identifier, except for the following: TOP, SELECT, LIKE, WHERE, ON, AND, OR, NOT, BETWEEN, %STARTSWITH, CASE, WHEN, and ELSE.

Dynamic SQL Supports Statement Use In Files

The Dynamic SQL Shell now supports LOAD and SAVE commands to load and save SQL statements from/to files. SAVE was used previously to save the currently prepared statement to the statement global. It has been redefined. To save to the statement global, it is now necessary to use SAVEGLOBAL or the abbreviation, SG.

LOAD will load the contents of the specified file into the current statement buffer and prepare the statement. If EXECUTEMODE is IMMEDIATE and the statement is successfully prepared then it will be executed.

SAVE will save the currently prepared statement to a file. If the file specified already exists then the user is prompted to overwrite it. If the user chooses not to overwrite, an error is reported and the statement is not saved.

Dynamic SQL And CALL Statement

Prior to version 2010.2, embedded SQL did not support a CALL statement when the target was not a function. Functions were callable using embedded SQL. Any application that uses CALL for a function will have to be modified in beginning with this release. If the called procedure returns a result set, applications must use the new %SQL.StatementOpens in a new tab class. If the called routine is a function, and it was supported in early versions, applications should use “SELECT <SQL Routine> <arguments>” instead.

Import Utility For Sybase and MS SQL Server Reimplemented

SQL statement import for Sybase and MS SQL Server has been reimplemented. Sybase and MS SQLServer statements are now processed using Dynamic SQL and the results of preparing the statement and executing the prepared statements are logged to a file and optionally echoed to the current device. The interface has not changed, but the dialog has changed slightly. In addition, the log file format is different and the parser used is the TSQL parser. That means more syntax is handled but it also means that errors reported will be different. For successfully processed statements the end result should be the same.

CALL Is Restricted To Defined Procedures

In this release, a loophole has been closed where a class method/query could be called as a stored procedure with the SQL CALL statement, even if the method/query is not specified as a SqlProc. This may require a change to the class definition if a class method/query is called from an SQL CALL statement that is not defined as an SQL procedure; its definition will need to change to declare it as such.

Changes To Handle Queries Against Views With UNIONs

In this release, a problem has been corrected involving queries against a view that has a union as part of the query, for example:


The returned query metedata will now report a type for column one of the query as VARCHAR instead of INTEGER.

Use of %vid For Row Selection

As an alternative to TOP, this version introduces a new way to restrict the set of returned rows of a query. This release extends %vid to views and FROM clause subqueries. It represents a sequentially assigned row number. Thus, to get rows 5 through 10 of an arbitrary query, say:

SELECT *, %vid FROM (SELECT ....) v WHERE %vid BETWEEN 5 AND 10

The phrase “SELECT * ...” does not include %vid; it must be selected explicitly: “SELECT *, %vid ...”. Also, while this feature is very convenient, especially for porting Oracle queries (this maps easily to Oracle ROWNUM), performance of queries may change as compared to TOP.

SQL Statement Property Change

The %Language property of %SQL.StatementOpens in a new tab is now named %Dialect. The SQL Shell LANGUAGE option is now named DIALECT.

Informix Migration — SUBSTR Function

In previous versions, when a SUBSTR function was discovered in an SQL context, the third argument was incorrectly passed as the end position. In this version, the SQL SUBSTR function correctly accepts a length as the third argument.

TSQL Unsupported Functions

The TSQL system functions, IS_SRVROLEMEMBER, IS_MEMBER, and ServerProperty are not implemented by Caché TSQL. References to these functions are now reported as compiler errors.

TRUNCATE Collation Added

Caché SQL now supports a new collation called TRUNCATE. TRUNCATE is the same as EXACT, but the application may specify a length at which to truncate the value. This is useful when there is EXACT data that the application needs to index and the data is exceeds the maximum length allowed for a Caché subscript.

Like other collations that support a length argument, TRUNCATE(len) will truncate the exact value to “len” characters. If length is not specified for TRUNCATE, the collation will behave the same as EXACT. While it is technically supported, it may make definitions and code easier to maintain if you only use TRUNCATE when you have a length defined, and EXACT when you do not.

Like the other collations supported by Caché, %TRUNCATE can be used as a unary function in an SQL Statement. For example:

Set MyStringFirst100 = $extract(MyString, 1 ,100)
&SQL (SELECT ALongString 
      INTO :data
      FROM MyTable 
      WHERE %TRUNCATE(ALongString,100) = :InputValue)

When using TRUNCATE in a Map Script expression of a %CacheSQLStorage map definition, define the subscript using $$TRUNCATE. For example, the map subscript expression may be:

$$TRUNCATE({MyLongStringField}, 100)


$SYSTEM.SQL.TOCHAR(<null>) and $SYSTEM.SQL.TO_CHAR(<null_value>) will now return NULL and not 0 for numeric-to-character conversion.

Support Optional Second Argument Of %inlist() To Provide A Selectivity Hint

The %inlist operator can now also be used as a function with optional second argument. This is intended to give an order of magnitude estimate of the number of elements involved in the query. Thus, using a small number of different cached queries, you can get different plans for different cases, for example:

  • small lists – %inlist <list> SIZE ((10))

  • medium lists – %inlist <list> SIZE ((100))

  • large lists – %inlist <list> SIZE ((1000))

  • huge lists – %inlist <list> SIZE ((10000))

The second argument must be a constant when it is compiled. From clients except embedded SQL, this means that parentheses must be used as in the example above.

Changes In TO_CHAR Handling

In this version of Caché, TO_CHAR has been enhanced in order to support conversion of logical %TimeOpens in a new tab values to String values. If the value for the expression top be converted is a numeric value and the format contains only the following TIME related format codes:

  • HH – Hour of Day (1 through 12)

    HH12 – Hour of Day (1 through 12)

    HH24 – Hour of Day (0 through 23)

    MI – Minute (0 through 59)

    SS – Second (0 through 59)

    SSSSS – Seconds since midnight (0 through 86388)

    AM – Meridian Indicator (before noon)

    PM – Meridian Indicator (after noon)

The expression will be treated as a logical %TimeOpens in a new tab value and not a Logical %DateOpens in a new tab value. For example, the selection

SELECT TO_CHAR($piece($horolog, ',' ,2), 'HH12:MI:SS PM') AS THE_TIME

will result in THE-TIME having a value formatted as something lilke 11:43:26 AM.

Evaluation Of Macros And Functions In SQL Preprocessor

Beginning with this release, there has been a change in the behavior of the DDL CREATE PROCEDURE, CREATE FUNCTION, CREATE METHOD, CREATE QUERY, and CREATE TRIGGER statements, when compiled as embedded SQL statements or prepared as dynamic statements. This change is not fully backward-compatible and may require modifications to your applications, especially when code bodies of type ObjectScript are used in the CREATE statement.

The macro preprocessor evaluates # commands, ## functions and $$$macro references before any embedded SQL statement is processed. Consider the following statement:

                      LANGUAGE COS { 
                          #define Square(%val) %val*%val
                          QUIT $$$Square(value) 

Prior to this change the #define and $$$Square macro references would be expanded and processed when the CREATE PROCEDURE statement was compiled resulting in a method declaration as follows:

ClassMethod SquareIt(value As %Library.Integer(MAXVAL=2147483647,MINVAL=-2147483648))
            As %Library.Integer(MAXVAL=2147483647,MINVAL=-2147483648)
            [ SqlName = SquareIt, SqlProc ]
    QUIT value*value 

With this change the processing and expansion will be included in the procedure method definition, and get processed and expanded when the method is compiled:

ClassMethod SquareIt(value As %Library.Integer(MAXVAL=2147483647,MINVAL=-2147483648))
            As %Library.Integer(MAXVAL=2147483647,MINVAL=-2147483648)
            [ SqlName = SquareIt, SqlProc ] 
    #define Square(%val) %val*%val 
        QUIT $$$Square(value) 

Code that relies on the old behavior of the macro expansion occurring during the compilation of the CREATE PROCEDURE statement will have to be changed. Alternatively, use %SQL.Statement to prepare and execute the CREATE PROCEDURE statement dynamically.

Finally, in prior releases, ObjectScript program code is enclosed within curly braces, for example, { code }. If material needs to be included, the #include preprocessor command must be prefaced by a colon and appear in the first column, as shown in the following example:

:#include %occConstant 

Beginning with this release, the leading colon (:) is no longer required, but it will be accepted without error if present.

Corrections To Date/Timestamp Comparisons And SQL Categories

The datatype classes %Library.DateOpens in a new tab,%Library.TimeStampOpens in a new tab, %Library.FilemanDateOpens in a new tab, %Library.FilemanTimeStampOpens in a new tab, and %MV.DateOpens in a new tab are now treated as follows with regard to SqlCategory:

  1. %Library.DateOpens in a new tab classes, and any user-defined datatype class that has a logical value of +$HOROLOG should use DATE as the SqlCategory.

  2. %Library.FilemanDateOpens in a new tab classes, or any user-defined datatype class that has a logical date value of CYYMMDD, should use FMDATE as theSqlCategory.

  3. %MV.DateOpens in a new tab classes, or any user-defined datatype class that has a logical date value of $HOROLOG-46385, should use MVDATE as theSqlCategory.

  4. %Library.FilemanTimeStampOpens in a new tab classes, or any user-defined datatype class that has a logical date value of CYYMMDD.HHMMSS, should use FMTIMESTAMP as theSqlCategory.

  5. A user-defined date datatype that does not fit into any of the preceding logical values should define the SqlCategory of the datatype as DATE and provide a LogicalToDate method in the datatype class to convert the user-defined logical date value to a %Library.DateOpens in a new tab logical value.

  6. A user-defined timestamp datatype that does not fit into any of the preceding logical values should define the SqlCategory of the datatype as TIMESTAMP and provide a LogicalToTimeStamp method in the datatype class to convert the user-defined logical timestamp value to a %Library.TimeStampOpens in a new tab logical value.

  7. Finally,

    • The SqlCategory of %Library.FilemanDate is now FMDATE.

    • The SqlCategory of %Library.FilemanTimeStamp is now FMTIMESTAMP.

    • The SqlCategory of %MV.Date is now MVDATE.

This version also changes the outcome of comparing FMTIMESTAMP category values with DATE category values. Caché no longer strips the time from the FMTIMESTAMP value before comparing it to the DATE. This is now identical behavior to comparing TIMESTAMP with DATE values, and TIMESTAMP compared with MVDATE values. It is also compatible with how other SQL vendors compare TIMESTAMPS and DATES. This means a comparison of a FMTIMESTAMP 320110202.12 and DATE 62124 will no longer be equal when compared with the SQL = operator. Applications must convert the FMTIMESTAMP to a DATE or FMDATE value to compare only the date portions of the values.

Datatype Of A CASE Expression

When using a CASE expression, if any of the potential return values is of type LONGVARBINARY, the return value of the CASE will be of type LONGVARBINARY; otherwise, if any of the potential return values is of type LONGVARCHAR, then the return value of the CASE function will be of type LONGVARCHAR. After that, the datatype of the value will be the first applicable from among: VARBINARY, VARCHAR, TIMESTAMP, DOUBLE, NUMERIC, BIGINT, INTEGER, DATE, TIME, SMALLINT, TINYINT, BIT.

CSP Changes

Error Handling While Changing CSP Applications

An event class can be attached to a CSP application. In particular, a callback is made when the session moves from one application to another. According to the design intent, if an error code is returned, the flow will be redirected to the error page.

In previous releases, this error code was “partially” ignored. If an error code was returned, the user was redirected to the error page. However, if the application change completed and the user was actually in the target application, pressing the reload button would display the target page. Now, the error code aborts the application change. The user sees the same error page appear, but pressing the reload button redisplays the error page.

Sticky Login And Login Tokens For Authenticating CSP Applications

CSP logins are now “sticky”. When reentering a previously-entered application, that application will be the same user as on the exit. (Previously, when sharing sessions, the re-entered user would depend on what other applications had been visited.) When you log in as X, a login token is sent in a 'most-recently-logged-in-user' cookie to the browser. When you enter an application for the first time, if login tokens are enabled for the application, the CSP Server will attempt to log you in using that cookie.

All applications in a session now move in tandem. Logging into a new user within an application moves all applications to that user. Logging out a session, logs out all applications in that session.

Allow CSP Applications To Be Grouped By Browser

Caché has two types of Authentication Groups: by-session and by-browser. CSP applications within a group attempt to keep their authentication in sync when possible. All applications are in an Authentication Group. The default authentication group for an application is by-session. (So applications all by themselves in a Session form a single-entity authentication group.) Explicit grouping takes precedence over implicit. So if a group-by-browser application is forced into a session with some other applications, it will share authentication by-browser, not by-session, with the other applications.

Session-Sharing Depends On Exact Cookie-Path Match

In previous versions, two applications were included in the same session if, when entering an application, the Session-Path-Cookie of the first application was a prefix of the previous one. This rule introduced an inconsistency. If the applications were entered in the opposite order, they were in different (instead of the same) session.

Now, applications can be made to share (run in) the same CSP session if their Session-Path-Cookie matches exactly. Applications sharing a session can share data in the Session object and when possible, keep their authentication in sync (remain logged into the same user and are logged out as a unit.)


The global ^%SYS("CSP", "UseLegacySessionSharing") can be set to 1 to return to old-style session sharing.

Session Events And Security Context Management

There are two important changes to session event classes and their security contexts made in this release. First, a CSP session can have multiple classes notified when an event occurs. That is, the statement

SET %session.EventClass = "User.MyClass"

will add User.MyClass to the list of classes to callback, and a statement such as:

SET %session.EventClass = "User.MyClass1", %session.EventClass = "User.MyClass2"

will add both classes to the list. This behavior is both easy to explain and it assures an application does not accidentally remove existing event classes , preventing them from being able to run cleanup code which may result in a resource leak.

Second, when moving between CSP applications in the same session Caché automatically adds the event classes of the new application to the list. In previous releases, Caché ignored the new CSP applications event class preventing cleanup of temporary data created in the namespace associated with this application.

Fix CSP Language Match For * In ACCEPT_LANGUAGE

If the CGI variable, HTTP_ACCEPT_LANGUAGE, has a value of “*” (which means any language), and with the same quality rating as a specific language, then use the specific language. This implements the HTTP 1.1 rule: The language quality factor assigned to a language-tag by the Accept-Language field is the quality value of the longest language-range in the field that matches the language tag.


The default quality factor is 1 even for “*”.

XML Changes

%XML.DataSet Will Now Use Class/Property Metadata When Available

Before this version, %XML.DataSetOpens in a new tab only used SQL metadata from the query being run. In particular, this meant supporting only the xsdtype of the base datatype from the %xsd. package and not supporting property parameters (such as VALUELIST for properties) and overrides of XSDToLogical and LogicalToXSD). Now, %XML.DataSetOpens in a new tab looks at the class name and property name metadata for a column when it is available (it is not always available, for example, if the column is an expression). This change will affect applications that want to just use the SQL-based data.

Column Names With Embedded Spaces

Beginning with this version, %XML.DataSetOpens in a new tab will convert embedded spaces in column names to underscores.

Web Add-On Declaration Required

If an application wishes to be identified as an anonymous web application eligible to run under the terms of the Web Add-on license, it must call $SYSTEM.License.PublicWebAppUser() to identify itself as such.

Web Services Changes

SOAP Fault Handling

In this version, Caché now returns SOAP 1.1 faults with an HTTP status code of 400 for client errors, and 500 for server errors as defined by WS-I Basic Profile. SOAP 1.2 faults already conformed to this use of 400 and 500 status codes. Furthermore, SOAP calls OnInternalFault for all %StatusOpens in a new tab-based faults produced by the Initialize method. OnInternalFault was already being called for %StatusOpens in a new tab based faults produced in other places in the code.

If a client is expecting a status code of 200 for faults, then this will no longer work and the client application must be changed.

Wizard No Longer Generates SOAP Headers

The SOAPHEADERS parameter will no longer be generated by the SOAP wizard. Instead the parameters XData block will be used to specify which headers to expect at the method level based on the WSDL.

Additional header information for a web service or web client is added in an XData block in the web service or web client class. The XData block has the parameters element in the configuration namespace as the root element.

Maximum Method Name Length

In this release, SOAP sets the length of method names to 180 characters. Some methods may end up with different names when recreated by the SOAP wizard because truncation no longer needed.

Do Not Close Streams

Beginning with this release, the files that implement the file streams used by SOAP web service and web client will not be closed until the streams that use them are closed.


Alterations To Line Continuation Processing

BASIC and MV BASIC line continuation characters allow a source line to span multiple lines. Placing a line continuation character as the last character on a line continues that statement on the next line. The BASIC line continuation character is an underscore (_); depending on the emulation options, MVBASIC can use either a vertical bar (|) or a backslash (\)as a line continuation character.

Previous versions of BASIC and MVBASIC would sometimes allow a line continuation character to appear at places other than the last character of the line. However, this could cause problems if the line continuation character had an alternative use for another purpose. Beginning with this release, the continuation character must be the last character of the line.

xDBC Changes

Removal Of All Support For XA

This change removes some experimental XA code from the InterSystems JDBC driver. Caché does not support the XA protocol, nor did the JDBC driver. However, as this was seriously considered a number of times, some experimental code was added to test whether JDBC could fully support it one day. This feature was documented as unsupported, and InterSystems has now decided to remove this dead code as part of an overall Java cleanup.

Changes To Catalog Queries

The TABLE_TYPE argument for the ODBC Catalog Query SQLTables and the JDBC Catalog query getTables has been enhanced to support the following new types in addition to the types 'TABLE' and 'VIEW' that have always been supported:

  • SYSTEM TABLE – a table projected from a class that has a System > 0 setting

  • SYSTEM VIEW – a view projected from a class that has a System > 0 setting

  • GLOBAL TEMPORARY – a table projected from a class with class parameter:


Prior to this version, if an application called SQLTables or getTables with an empty TABLE_TYPE argument, only TABLE and VIEW types would be returned. Now all all types that exist in the catalog will be returned. If an application only wants the TABLE and VIEW types, it must be changed to pass in only 'TABLE', and 'VIEW' for the TABLE_TYPE argument.

MultiValue Changes

MVFILENAME Class Parameter

The presence of MVFILENAME corrects inconsistency issues that previously might occur between copied or imported classes, and the file references in the VOC. The use of MVFILENAME assures that the storage definition in a class that extends %MV.AdaptorOpens in a new tab closely follows the definition of the MV file. InterSystems strongly recommend the use of MVFILENAME.

Debugger Changes For D3 Emulation

When using the Studio debugger in a MultiValue account using D3 emulation, if the debugger does not find a value for a mixed or lower case variable name it will look for an uppercase name. This will help when debugging routines that use the D3 default behavior of converting all variable names to uppercase. This can cause confusion if


turns off the default for a routine and it uses two variable names that differ only in the case of the names. D3 routines compiled with case sensitivity and with variable names identical except for case may see unexpected values in the debugger.

This change applies only to displaying variables. To modify a value, the true uppercase name must be used.

SUM Verbs Changed To Return Info Via Error Messages

In this version, the SUM verb now generates its results in the form of error messages. Previously, it presented its results via the RETURNING clause.

Behavior Changes For Dynamic Arrays With Unassigned Entries

The current behavior of padding the MATBUILD/MATWRITE dynamic array with null entries for unassigned array nodes at the end is no longer supported. No legacy MultiValue system provides this behavior, so InterSystems believes no existing applications depend on it.

In prior releases, unassigned nodes would be treated as empty strings and the resulting dynamic array could have many empty entries at the end if the higher array subscripts were undefined. Beginning with this release, the behavior of MATBUILD and MATWRITE has changed for arrays that have unassigned nodes. Now the behavior depends on an emulation option, which is set to match the behavior of existing legacy platforms, namely:

  • Cache, Universe, and Unidata emulations

    Empty strings will be used for unassigned nodes and the dynamic array will be truncated when the highest subscripts of the array are unassigned.

  • jBase, Reality, and D3 emulations

    An <UNDEFINED> error will be thrown when an unassigned array node is encountered.

The default behavior based on the emulation type may be overridden with the a compile option.


will cause an error to be thrown, while


will use an empty string and truncate any trailing unassigned nodes.

Timed INPUT And AUTOLOGOUT Behavior Change

In previous releases, AUTOLOGOUT was found to be unpredictable. In this release, the AUTOLOGOUT and timed INPUT statements are consistent. If an application contains a timed-out INPUT command, the behaviour has changed slightly. For example, if the timeout was 30 seconds as in

INPUT var FOR 300 ELSE ...

then in prior releases, the 30 seconds applied to the entire INPUT statement. Starting with this release, every time a key is depressed during the INPUT statement, the timeout is reset to another 30 seconds. Similar behavioral changes also apply to AUTOLOGOUT; each keystroke will reset the AUTOLOGOUT timeout.

jBase And Undimensioned Arrays

In this release, an undimensioned array reference will now be a compile error in JBASE emulation. Previously, it was treated as an implicit FMT operation.

jBase CommandInit And CommandNext Changes

Prior to this release, to call the routines CommandInit and CommandNext (or JBASECommandInit and JBASECommandNext in later releases of jBASE), you had to create an F pointer into the samples directory that was provided with the Caché installation and compile and catalog CommandInit and CommandNext.

Beginning with this release, the routines CommandInit and CommandNext (and their newer equivalents JBASECommandInit and JBASECommandNext) will be supplied by default with Caché; no compilation is required by the customer prior to use. The sources for these 2 routines will no longer be provided with the release of Caché as they are no longer needed.

The values returned by CommandNext are still defined in a file called CommandInclude and this might still be needed by the customer to decode the returned value. This source will continue to be included with the Caché release at the same location as before,that is,


When calling the CommandNext routine, the third parameter is the timeout value. Caché now supports the following timeout values:

  • timeout < 0: the routine returns immediately

  • timeout = 0: the same as timeout = 1

  • timeout > 0: Number of tenths of a second to wait until Caché returns a timeout value.


Windows platforms only support whole seconds for wait times, not fractions. Therefore, a timeout of 1 means one second.

jBase CHAIN Handling

The MVBASIC CHAIN statement was not always correctly handled when doing jBASE emulation. CHAIN under jBASE emulation should not pass the default list (list 0) if that list is local or modified. When MVBASIC was initiated by an EXECUTE statement, then a CHAIN would always pass the default list. Now, the passing the default list is always disabled for programs compiled under jBASE emulation.

Evaluation Order For Boolean Operators

The evaluation order of the Boolean-and operators (AND, “&”) versus the Boolean-or operators (OR, “!”) in MVBASIC has been changed to agree with the MVBASIC specification. Previously, the MVBASIC conjunction operators (AND, “&”) had higher precedence than the disjunction operators (OR, “!”). Without parentheses an AND operator would be evaluated before an OR operator. Now the AND and OR operators have equal precedence; they will evaluated in left-to-right order in the absence of parentheses.

Handling Of Division By Zero

Beginning with this version, the MVBASIC DIVS() and MODS() array functions now signals a <DIVIDE> error if either encounters a divide-by-zero error. This will end execution of the DIVS() function and execution will start searching for a trap handler. Previously, a divide-by-0 during a DIVS() array operation resulted in a message being sent to the operator console log, a 0 being used for the array component in error and execution of the array divide continuing with the remaining elements.

List Collections For MVENABLED Class Cannot Be Empty

The index on a list collection in an MVENABLED class will always contain at least one entry. When the collection is empty, an indexed element value of NULL, and key value = 1 will be inserted into the index.


The syntax of the CALLING clause of a DEFFUN statement has been changed. The CALLING keyword can now be followed by either an identifier or a quoted string literal. If a quoted string literal is used, the first character of that quoted string literal may be an “*” character. If the leading character is an “*:”

  • Under Unidata emulation, when a name begins with a leading “*”, the leading * is removed and the name is looked up as a global name. It is an error if the global name is not found.

  • Non-Unidata emulations allow a function to have a leading “*” character in its name but the leading “*” does not modify the function name lookup rules in these other emulations.

PRINT ON <Channel> Is Now Emulation-Specific

This release adds MultiValue emulation differences for the use of the statement


Prior to this, the output would always go to a spooler print job regardless of the use of PRINTER ON or PRINTER OFF. Now, the action depends upon the emulation. For some emulations (Reality, jBASE, D3), the output will go to the screen if the application has not executed a PRINTER ON statement. For other emulations, the behavior remains the same, that is, output to a spooled job.

SPOOLER(2) Function Return Changed

In previous releases, the SPOOLER(2) function call in MVBASIC returns 3 fields that are the same, for compatibility reasons. Beginning with this release, one of the duplicated fields (field 15 or MultiValue 15) is now the Caché user name that a user will log in as when they initially connect to Caché in a locked-down security-enabled system. The following values/fields are now of interest as they share related information:

  • 3 – user name; OS login name = Fred

  • 14 – user name; OS login name, same as 3 = Fred

  • 15 – Caché user name in a security-enabled locked-down system, or “UnknownUser”

  • 17 – MV account name; = USER

Support Universe/Unidata Behavior Of Data Stack In PROC P Command

The PROC P command now respects the emulation flag STACK.GLOBAL, so that if set, the data stack is not cleared when a PROC executes the P command but rather the secondary output buffer is appended to it.

SSELECT Result Ordering Change

In previous releases, the MVBasic SSELECT statement provided the same ordering as the SELECT statement: theCaché default collation ordering. Caché default ordering places the empty string first, and then places the canonical numbers before all other strings.

Beginning in this version, it now sorts a list created from file or another select list into ordinary string collation order. If a programmer wants numeric strings sorted into numeric order, then SELECT should be used instead of SSELECT. If the input to a SSELECT statement is a list variable that includes duplicated values, the duplicates will be replaced by a single value as part of the sorting process. Thus, SSELECT of a list variable may generate a new list variable with fewer elements.


Both SELECT and SSELECT with an MVBasic dynamic array as input do not sort the array. The elements of the list occur in the same order as the elements occur in the dynamic array.

Changes to MATBUILD And MATWRITE Behavior For Unidata

For Unidata emulation, MATBUILD and MATWRITE now handle trailing empty values differently. MATWRITE will truncate them; MATBUILD will not.

Dynamic Vector Arithmetic Changes

In earlier releases, when asked to perform a divide by the value 0,

  • the DIV() and MOD() functions, and the / division operator issued a <DIVIDE> error; but,

  • the DIVS() and MODS() functions (dynamic array vector arithmetic) returned a value of 0.

Beginning with this release, all these operation will perform the same way returning a <DIVIDE> error.

PHANTOMs Now Run The Login Verb

The handling of PHANTOMs has changed in this release. When a PHANTOM starts, it will now execute the LOGIN verb. PHANTOPMs now also supprt the CHAIN and EXIT commands.

Zen Changes

Change To showModalDialog Function In Zen For Internet Explorer

Zen defines a utility function, zenLaunchPopupWindow, that creates a popup window. One of the options it supports is "modal=true". In prior releases, this function would detect Internet Explorer and use the special IE-extension, showModalDialog. This function has proved to be unreliable for his purpose. In this release, Zen implements modal behavior as follows:

  1. When zenLaunchPopupWindow is called in modal mode, Zen turns on the modal handler for the page, and places a transparent area over the entire page and trap any mouse clicks not in the modal area.

  2. zenLaunchPopupWindow sets up surrogate callbacks to trap the end of modal behavior. Specifically, when the user clicks outside of the modal popup, Zen gives focus back to the popup.

Enforce Restrictions On seriesNames And labelValues In pieCharts

The following restrictions are now enforced begiinning with this release:

  • A seriesNames CANNOT contain literal values in a pieChart.

  • A seriesNames cannot contain more than one xpath expression in a pieChart.

  • A labelNames cannot contain an xpath in a pieChart.

Rather, use seriesNames if one needs to use an xpath in a pieChart; use labelNames if one needs to use literal values in a pieChart.

Changes To xyChart

When introduced in version 2010.2, colors and marker shapes were determined ordinally in a repeating pattern. This proved to have limited utility. Now, Zen gives points belonging to the same dataField in an xy-Chart the same marker and color.


In seriesNames, the x-coordinate dataField mustbe named so that the legend is marked correctly, even though the x-coordinate does not appear in the legend. It is the (x,y) combinations that appear in the legend and they are colored according to the color the y dataField has in the legend.

Do Not Put / Before Report Name In Generated <apply-templates>

To allow a use-case of sub-reports where each sub-report provides a sub-section of the data, Zen no longer inserts a “/” in front of the report name as that name appears in the <xsl:apply-templates> element. This aligns how the PDF works with how HTML works.

This allows a use-case that works in the HTML case to work in the PDF case, but there may be PDF reports that are relying on the <apply-templates> selecting "/reportname" rather than "reportname". The solution for these ZEN Reports is to explicitly put a "/" in front of reportname.

SVG Chart Component

This version introduces a major rework of the way axes are labeled in the chart class (parent of bar chart and line chart) It introduces a new flag, autoScaleText which defaults to true.

When set, the axes renderers mostly mimic the previous chart behavior. In this scenario, text scales with the drawing becoming arbitrarily large and potentially distorted if the aspect ratio of the chart changes. The only significant change in this mode is that, if the X axis has too much text along it (in danger of overprinting labels), it will automatically attempt to angle the text (if a label angle has not already been specified) and, in the case of a value axis, will omit some labels in the name of clarity. If the axis is plotting category names, all labels will print, but the user may need to play with font and rendering sizes to ensure legibility (not unlike the previous release).

If autoScaleText is false, the text scales (or not) independent of the size of the chart itself. In practice, this means that font sizes effective specify maximum font sizes (fonts may still scale smaller if need be on very tiny or crowded graphs). This approach allows Zen to use space more efficiently as graphs are resized and “normal” aspect ratios of text are preserved at different rendering scales.

The labeling of axes also changes under this mode. For the vertical axis, if the dimension is a continuous value scale, the system will automatically decimate the printed label set to convey maximum information in the space allotted without overprinting. For categories plotted on the vertical, labels will be shrunk to fit as needed, but no label will be omitted. On the horizontal axis, labels will first be angled in an attempt to fit more information across the line. If this fails to fit all labels into the available space, then range value labels will be decimated while category labels will be shrunken.

Selection Focus For simpleTablePane

This version alters the base behavior for the selection focus of tablePanes. Previously, clicking on a given row selected it (set the selectionIndex property and highlighted the row); subsequent clicks on the selected row were ignored. The only way to change the selection focus was to select a different row in the table. This had the effect of making it impossible to unselect _all_ rows once a selection had been made.

Under the new system, clicking on a selected row, unselects it (the selectionIndex for the table is set to -1 and no rows are highlighted). Changing the selection focus works as before, the core difference is the toggling behavior of the currently selected row.

In addition, this version implements an onunselectrow callback mechanism, allowing page designers to be notified when a given row is unselected. This event fires both when toggling a single row and when changing the selection focus from one row to another. In the multi-row case, the unselectrow event is fired FIRST with a selectionIndex of -1. Once handled, the selectrow event fires with the selectionIndex set to the newly selected row number.


Pages that display information about the currently selected row outside of the table itself (such as in a text box) based on an onselectrow callback will display stale information if the current row is toggled off and the page hasn't been updated to clear the old info. The solution is simply to listen for the onunselectrow event and clear the supplemental widgets.

Changing Handling Of Invalid Classes Used With Form Controls

In preceding versions, invalid values entered into forms would be tagged with the DOM node classname zenInvalid at the expense of any existing class name given via the controlClass attribute. All modern browsers, however, support a node belonging to multiple classes simultaneously so this either/or behavior is not necessary and, may actually disrupt the geometry of the page.

This version allows the zenInvalid class membership to supplement and existing class designation rather than wholly supplant it. This does introduce the issue that if the both the controlClass and zenInvalid attempt to set the same CSS style (such as the background color of a text box, which zenInvalid wants to turn red), the question of which rule takes precedence becomes a browser dependency. The easiest way to avoid this issue is to ensure that the CSS rules set for the zenInvalid class do not directly compete with any styles associated with developer specified controlClass designations.

Studio Changes

Save No Longer Compiles

Studio no longer supports “Compile On Save” functionality. The Save command will always perform a save operation only, but no compile will be executed. Users must manually select the compile options. The option has been removed from the compiler behavior settings.

Export And Import All Settings From A Project To XML

Before this, Studio only exported certain setting from a project to the XML export format, and only imported specific settings. This has now been changed to export/import all the useful settings to XML.


This change is fully compatible with importing XML exports of projects from older versions of Caché. However, the new export outputs many more fields. Importing the XML into an earlier version of Caché will probably fail validation. This can be worked around by passing the '-i' flag to turn off schema validation during the import so that only the fields that the older system knows about will be imported.

%Installer Changes

<Database> Create Attribute Correction

In prior versions, the <Database> tag did not properly handle the value of the Create attribute. It did not distinguish between values of “yes” and “overwrite”; both behaved as if “overwrite” had been specified. In this release, the operation has been corrected to match the documentation for the attribute.

FeedbackOpens in a new tab