Skip to main content

Defining a Computed Property

Defining a Computed Property

In InterSystems IRIS, you can define computed properties, whose values are computed via ObjectScript, possibly based on other properties. The generic phrase computed properties (or computed fields) includes both of the following variations:

  • Always computed — The value of this property is calculated when it is accessed. It is not stored in the database unless you defined an index, in which case that index is stored.

  • Triggered computed — The value of this property is recalculated when triggered (details given below).

    If the property is defined in a persistent class, its value is stored in the database.

In both cases, the recalculation is performed whether you use object access or an SQL query.

There are six property keywords (SqlComputed, SqlComputeCode, SqlComputeOnChange, Transient, Calculated, ComputeLocalOnly) that control if and how a property is computed. Instead of specifying SqlComputeCode, you can write compute code in a PropertyComputation method, where Property is the name of the computed property. For more details, see Computed Values.

The following table summarizes the possibilities:

How to Tell if a Property Is Computed
    SqlComputed is true (and SqlComputeCode is defined) SqlComputed is false
Calculated is true Transient is true Property is always computed Property is not computed
Calculated is true Transient is false Property is always computed Property is not computed
Calculated is false Transient is true Property is always computed Property is not computed
Calculated is false Transient is false Property is triggered computed (SqlComputeOnChange can also be specified in this case) Property is not computed

To define a computed property, do the following:

  • Include the SqlComputed keyword in the property definition. (That is, specify the SqlComputed keyword as true.)

  • Include the SqlComputeCode keyword in the property definition. For the value of this keyword, specify (in curly braces) a line of ObjectScript code that sets the value of the property, according to rules given in SqlComputeCode. For example:

    Class Sample.Population Extends %Persistent
    {
    Property FirstName As %String;
    
    Property LastName As %String;
    
    Property FullName As %String [ SqlComputeCode = {set {*}={FirstName}_" "_{LastName}}, SqlComputed ];
    // ...
    
    }
    

    Alternatively, specify a PropertyComputation method using ObjectScript or another language, such as Python, to set the value of the property. For example:

    Class Sample.Population Extends %Persistent
    {
    Property FirstName As %String;
    
    Property LastName As %String;
    
    Property FullName As %String [ SqlComputed ];
    // ...
    
    ClassMethod FullNameComputation(cols As %Library.PropertyHelper) As %String
    {
        return cols.getfield("FirstName")_" "_cols.getfield("LastName")
    }
    // ...
    }
    
    Class Sample.Population Extends %Persistent
    {
    Property FirstName As %String;
    
    Property LastName As %String;
    
    Property FullName As %String [ SqlComputed ];
    // ...
    
    ClassMethod FullNameComputation(cols As %Library.PropertyHelper) As %String [ Language = python ]
    {
        return cols.getfield("FirstName") + " " + cols.getfield("LastName")
    }
    // ...
    }
    
  • If you want to make the property always computed, specify the Calculated keyword as true in the property definition.

    Or, if you want to make the property triggered computed, do not include the Calculated and Transient keywords in the property definition. (That is, make sure both keywords are false.)

  • If the property is triggered computed, optionally specify SqlComputeOnChange.

    This keyword can specify one or more properties. When any of these properties change in value, the triggered property is recomputed. Note that you must use the property names rather than the names given by SqlFieldName, which is discussed later). For example (with artificial line breaks):

    Property messageId As %Integer [ 
    SqlComputeCode = { set {*}=$Select({Status}="":0,1:$List($List($Extract({Status},3,$Length({Status}))))) }, 
    SqlComputed, SqlComputeOnChange = Status ];
    

    For another example (with artificial line breaks):

    Property Test2 As %String [ SqlComputeCode = { set {*}={Refprop1}_{Refprop2}}, SqlComputed, 
    SqlComputeOnChange = (Refprop1, Refprop2) ];
    

    The value of SqlComputeOnChange can also include the values %%INSERT or %%UPDATE; for details, see SqlComputeOnChange.

  • In a sharded or federated environment, if you want to return data stored in a computed field only from the server that the query was issued from, you can additionally specify the ComputeLocalOnly keyword.

If you intend to index this field, use deterministic codeOpens in a new tab, rather than nondeterministic code. InterSystems IRIS cannot maintain an index on the results of nondeterministic code because it is not possible to reliably remove stale index key values. (Deterministic code returns the same value every time when passed the same arguments. So for example, code that returns $h is nondeterministic, because $h is modified outside of the control of the function.)

Also see Calculated. And see Controlling the SQL Projection of Computed Properties, below.

FeedbackOpens in a new tab