I will assume that you are using "Normal" (in which the user _SYSTEM is turned off) or even "Locked Down" (the user "UnknownUser" has no roles at all): Initial User Security SettingsDOC

I'm using "Locked Down", IRIS 2025.2CE and ran into a lot of different bugs when using WebTerminal v4.9.5:

  • <PROTECT>endSession+25^%SYS.cspServer
  • <LICENSE LIMIT EXCEEDED>
  • etc.

Fortunately, the WebTerminal source code is available for analysis and editing.

The problem can be solved in two ways: either fix the source code or add the missing role. I chose the latter.

In my case, it is enough for the web application /terminalsocket to add the %Admin_Secure role in addition to the existing roles. After that, it doesn't hurt to clean up all existing sessions:

kill ^WebTerminal("AuthUser")

If the <LICENSE LIMIT EXCEEDED> error persists after this, restart the IRIS instance.

PS: Advisory for IRISSECURITY in InterSystems IRIS 2025.2

"Real life" *.inc entry is to execute macro routine "Entry^HS.Local.VA.Util.Log(%arr,,"D")" if Global ^GlFSL("Debug") is >0 by calling from a classmethod as $$$TestIf(arr) - no return value is required.

#define TestIf(%arr) if (^GlFSL("Debug")>0) {do Entry^HS.Local.VA.Util.Log(%arr,,"D")}
;or
#define TestIf(%arr) do:^GlFSL("Debug")>0 Entry^HS.Local.VA.Util.Log(%arr,,"D")

Usage:

$$$TestIf(5)

If the array is multidimensional, then you can't do without loops (the code is without error handling):

  #define ArrayToStr(%arr,%str) set ref=$name(%arr),%str="s " for  {set ref=$query(@ref,1,val) quit:ref=""  set %str=%str_$$FormatName^%qcr(ref,1)_"="_##class(%Utility).FormatString(val)_","} set $extract(%str,*)=""
  #define StrToArray(%str) xecute %str

Usage:

  set a(0)=7
  set a(1,"color")="green"
  set a(1,"color","green")=""
  set a("color",$listbuild($double(3)))=$listbuild("red","blue")

  $$$ArrayToStr(a,str)
  zwrite str
  kill a
  $$$StrToArray(str)
  zwrite a

I would like to have *inc file entry to convert an array into a string and string into an array.

If the array is one-dimensional, then you can do without cycles altogether. I'll give you a small example below:

  #define Array1ToJSONString(%arr,%json)##continue
  s ##unique(new)=##class(%ZEN.proxyObject).%New()##continue
  d ##unique(old).%CopyFromArray(.%arr),##continue
    ##class(%ZEN.Auxiliary.altJSONProvider).%WriteJSONStreamFromObject(.%json,##unique(old))##continue
  s %json=%json.Read(3641144)
  
  #define JSONStringToArray1(%json,%arr)##continue
  d ##class(%ZEN.Auxiliary.altJSONProvider).%ConvertJSONToObject(%json,,.##unique(new)),##continue
    ##unique(old).%CopyToArray(.%arr)

Usage:

  set a("color")=$listbuild("red","blue")
  set a("price")="expensive"
  set a("size")=$listbuild("large","small")
    
  $$$Array1ToJSONString(a,jsonStr)
  zwrite jsonStr
  $$$JSONStringToArray1(jsonStr,b)
  zwrite b
import iris

# first, we connect to the %SYS namespace
conn = iris.connect('localhost:1972/%SYS','_SYSTEM',pwd,10,True)
irispy = iris.createIRIS(conn)

# here we switch to the USER namespace
newNameSpace = irispy.classMethodString('%SYSTEM.Process','SetNamespace','USER')

# now we can call the method from the new namespace
#print(irispy.classMethodInteger('DC.Unix','RoundPosixToSeconds',1154669852181849976))

conn.close()
#Include %sqlx
set newposix $$$sqlxPosixTimeEncode(+$p($$$sqlxPosixTimeDecode(posix),".",1))

Сheck:

for posix = 1154669852181849976, -6979664624441081856, 1406323805406846975 {

  set newposix $$$sqlxPosixTimeEncode(+$p($$$sqlxPosixTimeDecode(posix),".",1))

  write ##class(%PosixTime).LogicalToTimeStamp(posix),!,
        ##class(%PosixTime).LogicalToTimeStamp(newposix),!!
}

2025-05-27 12:06:15.003
2025-05-27 12:06:15
 
0001-01-01 00:00:00
0001-01-01 00:00:00
 
9999-12-31 23:59:59.999999
9999-12-31 23:59:59
 
source code of dc.observation_lab

The following query does not use iCode/iCodeText indexes (2025.2.CE):

select code_1_textcount(code_1_text)
  from dc.observation_lab
  group by code_1_text
  order by desc

PS: if possible, I would try to convert the text into a number in some way and index this number already, perhaps even with the bitmap type.

Here explained to us that this is not a bug, but a feature: <PROTECT> *Function not allowed in IRIS Native python

Starting from 2024.1 IRIS Native disallows routine invocations. Please use class methods instead.

For reference, these changes can be identified as DP-422635 and DP-424156.

PS: and yes, additional roles and resources like %Native_*/%All etc. no eliminate the <PROTECT> error. Checked on version 2025.2.CE

Very strange syntax:

But if we tried at once with a single statment with a select into (1 value) it fails

INSERT INTO Sample.YoungPeople (PASReligionCodevalues (SELECT internalPatientNumber FROM
Pennine_TIE_Clinicom_Link.PMISPECIALREGNCA where InternalPatientNumber=100)

See: