Operational Differences between MultiValue and Caché
Other Compatibility Issues
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
, and $ZDateTimeH
MultiValue assumes a character set where the numeric values of the characters range from 0 to 255, inclusive. This is defined in ISO-88591 and is often referred to as Latin-1.
Caché supports ISO-88591 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.
The various MultiValue systems sort right-justified fields differently from one another. For example, consider the following set of three-character strings: 0A
. When sorted as right-justified values, the various platform results are:
0A, 01, 1, 01.2, 1.2, 1A, 2, 02, 12A
0A, 01, 1, 1A, 01.2, 1.2, 02, 2, 12A
0A, 01, 1, 01.2, 1.2, 1A, 02, 2, 12A
0A, 1, 01, 1.2, 01.2, 1A, 02, 2, 12A
0A, 1, 01, 1A, 1.2, 01.2, 2, 02, 12A
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 4digits), 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.
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
should be changed to either:
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.
Caché allows 30 levels of nested execution. Attempts to exceed this limit cause Caché to report an error and return to the previous level.
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.
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.
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 2digit to 4digit 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
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
, 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:
does not function in Caché the way UniVerse users on UNIX® platforms would expect. The equivalent for Caché is
The output formats for these verbs differ among the various implementations of MultiValue. Caché produces the output for these verbs in LIST format.
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.
Select lists are stored as ANODES in order to support large list sizes.
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
, 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.
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.
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.
By default, the terminal type is assumed to be CACHE, but may be changed with the TERM
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'.
Class MVFILE.L1 Extends (%Persistent,%MV.Adaptor)
Class MVFILE.L2 Extends MVFILE.L1
Class MVFILE.L1 Extends %Persistent
Class MVFILE.L2 Extends (MVFILE.L1,%MV.Adaptor)
Class MVFILE.L1 Extends %Persistent
Class MVFILE.L2 Extends (MVFILE.L1,%MV.Adaptor)