Skip to main content

Other Compatibility Issues


Dates with Caché and MultiValue

The Caché epoch is January 1, 1840, which differs from the typical MultiValue epoch. Caché comes with a complete set of functions for handling dates. These include $ZDate, $ZDateTime, $ZDateH, and $ZDateTimeH.

Locales Other Than Latin-1

MultiValue assumes a character set where the numeric values of the characters range from 0 to 255, inclusive. This is defined in ISO-8859–1 and is often referred to as “Latin-1”.

Caché supports ISO-8859–1 directly, but it also supports a number of other locales. These include single-byte character sets like French, Czech and Finnish, and multi-byte sets like Japanese, Korean, and Thai.

If you install Caché and choose a locale other than Latin-1, you are inherently accepting the Caché rules for that locale, for example, which character is used for the decimal point and the names of months. Refer to “Supported Languages” in the online InterSystems Supported PlatformsOpens in a new tab document for this release for a list of supported languages. If you wish to establish a new locale, see the section on “System Classes for National Language Support” in Caché Specialized System Tools and Utilities.

Right-Justified Sort Ordering

The various MultiValue systems sort right-justified fields differently from one another. For example, consider the following set of three-character strings: “0A”, “1”, “01”, “1A”, “1.2”, “01.2”, “2”, “02”, “12A”. When sorted as right-justified values, the various platform results are:

  • UniVerse Ideal

    0A, 01, 1, 01.2, 1.2, 1A, 2, 02, 12A

  • Reality

    0A, 01, 1, 1A, 01.2, 1.2, 02, 2, 12A

  • D3, jBASE

    0A, 01, 1, 01.2, 1.2, 1A, 02, 2, 12A

  • UniVerse PICK

    0A, 1, 01, 1.2, 01.2, 1A, 02, 2, 12A

  • Caché

    0A, 1, 01, 1A, 1.2, 01.2, 2, 02, 12A

Limitations on Strings, Arrays and Dates

The current implementation sets these limits:

  • The maximum number of characters allowed in a string is 3,641,144.

  • The maximum number of elements allowed in an array is 16,381 regardless of the number of dimensions.

  • Valid dates must be in the range 12/31/1840 to 12/31/9999, inclusive. These are day numbers -46,385 to 2,933,628) respectively.

  • MultiValue programs should only use default date formats that display months as numbers (2– or 4–digits), and not as month names, even though Caché allows the latter.


Caché is case-sensitive. D3 is not case-sensitive. MultiValue applications using D3 emulation, or those that have turned off case sensitivity via by the $OPTIONS -CASE statement, will need to make sure that all such variables in Caché are declared as uppercase. Otherwise, they will be inaccessible by MultiValue applications. Some of the possible situations where case may be important are:

  • The names of globals are always case-sensitive regardless of the setting of $OPTIONS -CASE.

  • Basic command syntax such as CRT is not case-sensitive in all emulations.

  • Variable names are not case-sensitive in D3, and if you use $OPTIONS -CASE in other emulations.

  • Strings are always case-sensitive in the Caché environment. In the D3 emulation mode (and possibly others depending on $OPTIONS CASE), they are not case-sensitive.

  • Executed commands may or may not be case-sensitive depending on environment settings, but literals in queries are always sensitive.

  • Called subroutine names are case-sensitive.


The last item may change is the near future. That is, called subroutine names may be treated as not case-sensitive.

Literals In PQN PROCs

Caché will report an error if a literal is not enclosed in quotes. This behavior is not uniform across all MultiValue platforms: UniVerse, for example, requires the quotes while Reality does not. Therefore, if you are importing PROCS from Reality, Caché will report an error when attempting to compile the PROC. To correct the error, simply change the code to add quotes around the literal.

However, if when moving procs from jBASE, and the compiler reports this sort of error, additional analysis is needed. If the PROCs originally came from Reality, there may be a silent bug in the code when running on jBASE, because jBASE ignores the literal, and actually uses the empty string. If your procs were written for jBASE, or you expect that behavior, then you need to change the literal to “”.

For example:

MV %1 0

should be changed to either:

MV %1 "0"


MV %1 ""

depending on what platform you are porting from, and the desired behavior.


This applies only to those systems (beside Caché) that support PQN PROC: UniVerse, jBASE, Reality, and MVBase.

Execution Levels

Caché allows 30 levels of nested execution. Attempts to exceed this limit cause Caché to report an error and return to the previous level.

The Caché Debugger

When using the Caché to debug MultiValue programs, quitting from the debugger exits the MV shell. In doing so, it does not run any associated ON.ABORT or ON.ERROR exits.

Failures During CALL or ENTER

A failure during a CALL or ENTER aborts back to the TCL with no recovery. On some MultiValue systems, it may or not be possible to gain control (for example, in the debugger) when this situation occurs.

Verb Differences


Caché MultiValue supports the verb, but does not provide an equivalent MVBasic function. If an application needs this, the same functionality can be had by,


CENTURY.PIVOT is used to guide 2–digit to 4–digit year conversions. The command


means that any two-digit year equal to or greater than 50 should be assumed to be prefixed with 19, and any two digit year less than 50 should be assumed to lie in the next century. Most MultiValue applications should use the command


to duplicate under Caché the conversion of two-digit years they find on other MultiValue systems.


On other systems, the parameters “mod” and “sep” are used to size the file being created. Caché stores files in globals and these parameters are not needed. Ignoring them, rather than indicating an error or warning, removes the need to change every CREATE-FILE during conversion to Caché.


Caché restricts the DELETE-ACCOUNT verb to be run from the SYSPROG account. Therefore, accounts may only be deleted by those having administrative privilege.


In UniVerse, SH and DOS are VOC entries wrapping the OS commands “sh” and “cmd.exe”, respectively. All the command line parameters for those commands (and other OS commands entered this way) are available. This is very system-specific.

In Caché, SH and DOS run an internal program with limited option passing, which also handles terminal I/O in such a way that interactive programs can't be shelled. For example, the command:

SH -c "vi .profile"

does not function in Caché the way UniVerse users on UNIX® platforms would expect. The equivalent for Caché is

$ZF(-1,"vi .profile")

See the Caché ObjectScript Reference for more detail.


The output formats for these verbs differ among the various implementations of MultiValue. Caché produces the output for these verbs in LIST format.

Select Lists

Maximum Size

There is no maximum size for a select list. However, operations that involve conversions between a select list and a string are constrained by the Caché maximum string size. It is strongly recommended that you configure long strings when using Caché MultiValue. The present implementation of long strings limits a string to 3.6 million characters. Select list operations that are constrained or unconstrained by this maximum string size are as follows:

  • Unconstrained: SELECT, SAVE.LIST, GET.LIST commands. The MVBasic OPEN, SELECT, and READNEXT statements.

  • Constrained: EDIT.LIST command. The MVBasic READLIST and WRITELIST statements.

Commands that treat the &SAVEDLISTS& file as a normal file are also constrained by this maximum string size. For example, SELECT &SAVEDLISTS& WITH @ID LIKE "FP..." is not constrained, because it only uses the item id, but LIST.ITEM &SAVEDLISTS& LISTNAME is constrained. If LISTNAME is more than 3.6 million characters, LIST.ITEM returns a truncated listing.


Select lists are stored as ANODES in order to support large list sizes.

MultiValue Attribute Defaults For Dictionary Items

For UniVerse-style dictionaries (also used by UniData and Prime Information Systems), “D” type items (attribute 1) use attribute 6 as a MultiValue indicator. The possible values are S(ingle value) or M(ultiValue). If attribute 6 is unspecified, it defaults to S.

For PICK-style dictionaries where attribute 1 is an “A” or “S”, attribute 5 is the MultiValue indicator with the same allowed defaults: S or M. In this case, however, if attribute 5 is not specified, it defaults to M.


Traditionally, PICK dictionaries did not have a MultiValue indicator attribute. Caché MultiValue added one.

MultiValue File Pointers

For those porting MultiValue applications to Caché, please note the following:

  • Only one F-Pointer in any Caché system is allowed per MultiValue file. The target of the reference can be either a Caché an operating system file.

  • All other references to files named in F-Pointers must be entered as Q-Pointers.

Caché uses the F-Pointers to maintain indices. If there is more than one F-Pointer to the same MultiValue file, indices may not be updated correctly.

MultiValue Function Defaults For Queries

If attributes of the form, Fnnn (where “nnn” are digits) occur in an I-type and are not found first in the dictionary or the VOC, they are now handled by default.


UniVerse does not process defaults like this; the VOC file contains entries for F1..F10.

Default Terminal Type

By default, the terminal type is assumed to be CACHE, but may be changed with the TERM command.

Inheritance of MVENABLED Classes

An MVENABLED class needs to be the only persistent class in its hierarchy. You cannot have subclasses of MVENABLED class and you cannot have a persistent superclass of an MVENABLED class.

  • If you extend a class that extends %MV.Adaptor

  • Or if you extend a class from both %MV.Adaptor and another class that extends %Persistent

You see this error message:

ERROR #5135: An MVENABLED persistent class does not support polymorphic dispatch
so you can not create a subclass 'MVFILE.L2' to the extent root class 'MVFILE.L1'.


This fails:

Class MVFILE.L1 Extends (%Persistent,%MV.Adaptor)
Class MVFILE.L2 Extends MVFILE.L1

This fails:

Class MVFILE.L1 Extends %Persistent
Class MVFILE.L2 Extends (MVFILE.L1,%MV.Adaptor)

This compiles:

Class MVFILE.L1 Extends %Persistent
Class MVFILE.L2 Extends (MVFILE.L1,%MV.Adaptor)
FeedbackOpens in a new tab