From 55a4a059603a35aa2a42af821ef9dc2336ccd443 Mon Sep 17 00:00:00 2001 From: Alex Zaw Date: Wed, 25 Feb 2026 23:01:22 +0000 Subject: [PATCH] Update Function JSON_TYPE --- CISTOOLS/Functions/JSON_TYPE.sql | 104 ++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/CISTOOLS/Functions/JSON_TYPE.sql b/CISTOOLS/Functions/JSON_TYPE.sql index a58b217..87cac52 100644 --- a/CISTOOLS/Functions/JSON_TYPE.sql +++ b/CISTOOLS/Functions/JSON_TYPE.sql @@ -1 +1,103 @@ -@@\@^@ % %@@@@Km@M@ %@M]@]@ %@M]@@@ %@@ %@Km@ %@ %@@@ %@@@@ %@@@ %@@@@~@\@k@ %@~@\@k@ %@~@\@k@ %@~@Mk@k@]@k@ %@~@\@k@ %@~@\@k@ %@~@\@@@ %@ %@@@M@@@]@^@ %@@@M@@]@^@ %@@@M@@@]@^@ %@@@M@@]@^@ %@@@@@^@ %``@䓣`z@@k@@@@@M@}}]@ %@@@@@@@~@@^@ %@@~@@M@@]@^@ %@@@@ %@@~@}}@@ %@}}@^@ %@@^@ %``@⣙@@@@ %@m@M@@k@}Mo][}@]@@ %@}}@^@ %@@^@ %a\@~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@ %׈@z@Ɓ@@@M@N@@]@ %׈@z@偓@@@@Mm@a@m]@ %Ɇ@@@~n@@}}@ %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@\a@ %``@@ %@m@M@@k@}K\[}@k@}}@]@@ %@@~@}}@^@ %``@m@@@@@a^@@@@@ %@@~@m@M@@k@}[}@]@^@ %@@~@@ %@@@@@ %@}}@^@ %@@^@ %@@^@ %@@^@ %``@@ %@m@M@@k@}K\[}@k@}}@]@@ %@@~@}}@^@ %@@~@m@M@@k@}[}@]@^@ %@@~@@ %@@@@@ %@}}@^@ %@@^@ %@@^@ %@@^@ %``@@M`]@ %@m@M@@k@}MKO]\[}@]@@ %@@~@}}@^@ %``@m@@@@@@^@@@@@ %@@~@@M@@M@m@M@@k@}[}@]@k@}}@]@k@@k@@]@^@ %@@~@@@ %@}}@^@ %@@^@ %@@^@ %@@^@ %``@@ %@m@M@@k@}MozO][}@]@@ %@@~@}}@^@ %@@~@@M@@M@m@M@@k@}[}@]@k@}}@]@k@@k@@]@^@ %@@~@@@ %@}}@^@ %@@^@ %@@^@ %@@^@ %``@@M`]@ %@m@M@@k@}`oMO``\]MK`N]oMŻN`o`N]o[}@]@ %@ %@@~@}}@^@ %``@偓@@@@ %@@~@@M@@M@m@M@@k@}[}@]@k@}}@]@k@@k@@]@^@ %@@~@@@ %@}}@^@ %@@^@ %@@^@ %@@^@ %``@@@@@@@@ %@}}@^@ %@@^@ % %@@k@@@@ %@@@Km@ %@@ \ No newline at end of file +SET PATH *LIBL ; + +CREATE OR REPLACE FUNCTION CISTOOLS.JSON_TYPE ( + INJSON CLOB(2097152) ) + RETURNS VARCHAR(20) + LANGUAGE SQL + SPECIFIC CISTOOLS.JSON_TYPE + DETERMINISTIC + READS SQL DATA + CALLED ON NULL INPUT + NO EXTERNAL ACTION + SET OPTION ALWBLK = *ALLREAD , + ALWCPYDTA = *OPTIMIZE , + COMMIT = *NONE , + DECRESULT = (31, 31, 00) , + DYNDFTCOL = *NO , + DYNUSRPRF = *USER , + SRTSEQ = *HEX + BEGIN +DECLARE V CLOB ( 2 M ) ; +DECLARE T VARCHAR ( 20 ) ; +DECLARE DUMMYC CLOB ( 2 M ) ; +DECLARE DUMMYV VARCHAR ( 1 ) ; +DECLARE BAD SMALLINT DEFAULT 0 ; +-- Ultra-safe: never throw, always return a type (or 'invalid') +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET BAD = 1 ; +SET V = TRIM ( INJSON ) ; +IF V IS NULL +OR V = '' THEN +RETURN 'null' ; +END IF ; +-- Strict JSON null keyword +IF REGEXP_LIKE ( V , '^(?i)null$' ) THEN +RETURN 'null' ; +END IF ; +/* ============================================================ +Phase 1: Fast REGEXP classification (shape + scalar patterns) +Phase 2: Validate with JSON parser (JSON_QUERY / JSON_VALUE) +If parser fails => return 'invalid' +============================================================ */ +-- OBJECT +IF REGEXP_LIKE ( V , '^\{.*\}$' , 'n' ) THEN +SET T = 'object' ; +-- JSON_QUERY returns JSON text for objects/arrays; will throw if invalid JSON +SET DUMMYC = JSON_QUERY ( V , '$' ) ; +IF BAD = 1 +OR DUMMYC IS NULL THEN +RETURN 'invalid' ; +END IF ; +RETURN T ; +END IF ; +-- ARRAY +IF REGEXP_LIKE ( V , '^\[.*\]$' , 'n' ) THEN +SET T = 'array' ; +SET DUMMYC = JSON_QUERY ( V , '$' ) ; +IF BAD = 1 +OR DUMMYC IS NULL THEN +RETURN 'invalid' ; +END IF ; +RETURN T ; +END IF ; +-- STRING (JSON-escaped) +IF REGEXP_LIKE ( V , '^"(\\.|[^"\\])*"$' ) THEN +SET T = 'string' ; +-- JSON_VALUE parses scalar and returns SQL scalar; throws on invalid JSON +SET DUMMYV = SUBSTR ( COALESCE ( JSON_VALUE ( V , '$' ) , '' ) , 1 , 1 ) ; +IF BAD = 1 THEN +RETURN 'invalid' ; +END IF ; +RETURN T ; +END IF ; +-- BOOLEAN +IF REGEXP_LIKE ( V , '^(?i:true|false)$' ) THEN +SET T = 'boolean' ; +SET DUMMYV = SUBSTR ( COALESCE ( JSON_VALUE ( V , '$' ) , '' ) , 1 , 1 ) ; +IF BAD = 1 THEN +RETURN 'invalid' ; +END IF ; +RETURN T ; +END IF ; +-- NUMBER (RFC-like) +IF REGEXP_LIKE ( V , '^-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?$' ) +THEN +SET T = 'number' ; +-- Validate as JSON scalar +SET DUMMYV = SUBSTR ( COALESCE ( JSON_VALUE ( V , '$' ) , '' ) , 1 , 1 ) ; +IF BAD = 1 THEN +RETURN 'invalid' ; +END IF ; +RETURN T ; +END IF ; +-- Anything else is not valid JSON text +RETURN 'invalid' ; +END ; + +GRANT ALTER , EXECUTE +ON SPECIFIC FUNCTION CISTOOLS.JSON_TYPE +TO AMAPICS WITH GRANT OPTION ; + +GRANT EXECUTE +ON SPECIFIC FUNCTION CISTOOLS.JSON_TYPE +TO PUBLIC ; +