Operational Differences between MultiValue and Caché
Other Compatibility Issues
Go to:

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 InterSystems Supported Platforms 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:
Limitations on Strings, Arrays and Dates
The current implementation sets these limits:
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 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:
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:
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.
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)