refs #739: unify Smilegate game target planning
This commit is contained in:
@@ -4,16 +4,17 @@
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE q'[
|
||||
CREATE TABLE sg_game_catalog (
|
||||
game_key VARCHAR2(128) PRIMARY KEY,
|
||||
game_id VARCHAR2(128) NOT NULL,
|
||||
game_prefix VARCHAR2(128),
|
||||
game_nm VARCHAR2(512),
|
||||
game_alias_nm VARCHAR2(512),
|
||||
search_text CLOB NOT NULL,
|
||||
embedding VECTOR(1536, FLOAT32),
|
||||
active_yn CHAR(1) DEFAULT 'Y' NOT NULL,
|
||||
priority NUMBER DEFAULT 100 NOT NULL,
|
||||
updated_at TIMESTAMP(6) DEFAULT SYSTIMESTAMP NOT NULL
|
||||
game_key VARCHAR2(128) PRIMARY KEY,
|
||||
game_id VARCHAR2(128) NOT NULL,
|
||||
game_prefix VARCHAR2(128),
|
||||
game_nm VARCHAR2(512),
|
||||
game_alias_nm VARCHAR2(512),
|
||||
user_master_object_name VARCHAR2(128),
|
||||
search_text CLOB NOT NULL,
|
||||
embedding VECTOR(1536, FLOAT32),
|
||||
active_yn CHAR(1) DEFAULT 'Y' NOT NULL,
|
||||
priority NUMBER DEFAULT 100 NOT NULL,
|
||||
updated_at TIMESTAMP(6) DEFAULT SYSTIMESTAMP NOT NULL
|
||||
)]';
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
@@ -21,6 +22,20 @@ EXCEPTION
|
||||
END;
|
||||
/
|
||||
|
||||
DECLARE
|
||||
v_count PLS_INTEGER;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO v_count
|
||||
FROM user_tab_columns
|
||||
WHERE table_name = 'SG_GAME_CATALOG'
|
||||
AND column_name = 'USER_MASTER_OBJECT_NAME';
|
||||
IF v_count = 0 THEN
|
||||
EXECUTE IMMEDIATE
|
||||
'ALTER TABLE sg_game_catalog ADD (user_master_object_name VARCHAR2(128))';
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
|
||||
MERGE INTO sg_game_catalog c
|
||||
USING (
|
||||
SELECT
|
||||
@@ -51,10 +66,93 @@ VALUES
|
||||
(s.game_key, s.game_id, s.game_prefix, s.game_nm, s.game_alias_nm, s.search_text);
|
||||
/
|
||||
|
||||
-- Keep operator-maintained games in the same canonical catalog. These rows
|
||||
-- remain observable even when their current approved physical object is null.
|
||||
MERGE INTO sg_game_catalog c
|
||||
USING (
|
||||
SELECT
|
||||
r.game_key,
|
||||
r.game_key AS game_id,
|
||||
MAX(r.game_prefix) AS game_prefix,
|
||||
MAX(r.display_name) AS game_nm,
|
||||
LISTAGG(r.game_alias, ' ') WITHIN GROUP (ORDER BY r.game_alias) AS game_alias_nm,
|
||||
r.game_key || ' ' || MAX(NVL(r.display_name, '')) || ' '
|
||||
|| LISTAGG(NVL(r.game_alias, ''), ' ') WITHIN GROUP (ORDER BY r.game_alias)
|
||||
|| ' ' || MAX(NVL(r.game_prefix, '')) AS search_text
|
||||
FROM sg_game_scope_registry r
|
||||
WHERE r.active_yn = 'Y'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM comn_game_alias_bas a
|
||||
WHERE a.use_yn = 'Y'
|
||||
AND a.game_id = r.game_key
|
||||
)
|
||||
GROUP BY r.game_key
|
||||
) s
|
||||
ON (c.game_key = s.game_key)
|
||||
WHEN MATCHED THEN UPDATE SET
|
||||
c.game_id = s.game_id,
|
||||
c.game_prefix = s.game_prefix,
|
||||
c.game_nm = s.game_nm,
|
||||
c.game_alias_nm = s.game_alias_nm,
|
||||
c.search_text = s.search_text,
|
||||
c.active_yn = 'Y',
|
||||
c.updated_at = SYSTIMESTAMP
|
||||
WHEN NOT MATCHED THEN INSERT
|
||||
(game_key, game_id, game_prefix, game_nm, game_alias_nm, search_text)
|
||||
VALUES
|
||||
(s.game_key, s.game_id, s.game_prefix, s.game_nm, s.game_alias_nm, s.search_text);
|
||||
/
|
||||
|
||||
-- Resolve the physical user-master object from current valid objects and the
|
||||
-- current Select AI object lists. No game, prefix, or object name is embedded
|
||||
-- in this policy.
|
||||
MERGE INTO sg_game_catalog c
|
||||
USING (
|
||||
WITH approved_objects AS (
|
||||
SELECT DISTINCT UPPER(j.object_name) AS object_name
|
||||
FROM user_cloud_ai_profile_attributes p,
|
||||
JSON_TABLE(
|
||||
p.attribute_value,
|
||||
'$[*]' COLUMNS (object_name VARCHAR2(128) PATH '$.name')
|
||||
) j
|
||||
INNER JOIN user_objects o
|
||||
ON o.object_name = UPPER(j.object_name)
|
||||
AND o.object_type IN ('TABLE', 'VIEW', 'MATERIALIZED VIEW')
|
||||
AND o.status = 'VALID'
|
||||
WHERE p.attribute_name = 'object_list'
|
||||
)
|
||||
SELECT c2.game_key,
|
||||
MIN(a.object_name) AS user_master_object_name
|
||||
FROM sg_game_catalog c2
|
||||
LEFT JOIN approved_objects a
|
||||
ON c2.game_prefix IS NOT NULL
|
||||
AND a.object_name = UPPER(c2.game_prefix || '_COMN_USER_MST')
|
||||
GROUP BY c2.game_key
|
||||
) s
|
||||
ON (c.game_key = s.game_key)
|
||||
WHEN MATCHED THEN UPDATE SET
|
||||
c.user_master_object_name = s.user_master_object_name,
|
||||
c.updated_at = SYSTIMESTAMP;
|
||||
/
|
||||
|
||||
-- The catalog is small. Recompute embeddings after synchronization so changed
|
||||
-- aliases and registry-only games cannot retain a stale or null vector.
|
||||
UPDATE sg_game_catalog c
|
||||
SET c.embedding = DBMS_VECTOR.UTL_TO_EMBEDDING(
|
||||
c.search_text,
|
||||
JSON(sg_qa_vector_params('search_document'))
|
||||
),
|
||||
c.updated_at = SYSTIMESTAMP
|
||||
WHERE c.active_yn = 'Y';
|
||||
/
|
||||
|
||||
COMMENT ON TABLE sg_game_catalog IS
|
||||
'Customer-owned game catalog used to resolve query scope before NL2SQL.';
|
||||
COMMENT ON COLUMN sg_game_catalog.embedding IS
|
||||
'Vector representation of game names and aliases; populated by the configured embedding job.';
|
||||
'Vector representation of game names and aliases, generated with the configured vector credential.';
|
||||
COMMENT ON COLUMN sg_game_catalog.user_master_object_name IS
|
||||
'Current valid Select AI-approved physical user-master object for this game; null when unavailable.';
|
||||
/
|
||||
|
||||
CREATE OR REPLACE FUNCTION sg_game_catalog_search(
|
||||
@@ -70,6 +168,7 @@ BEGIN
|
||||
);
|
||||
OPEN v_result FOR
|
||||
SELECT game_key, game_id, game_prefix, game_nm, game_alias_nm,
|
||||
user_master_object_name,
|
||||
VECTOR_DISTANCE(embedding, v_query, COSINE) AS cosine_distance
|
||||
FROM sg_game_catalog
|
||||
WHERE active_yn = 'Y' AND embedding IS NOT NULL
|
||||
|
||||
@@ -43,6 +43,8 @@ IS
|
||||
v_extract JSON_OBJECT_T;
|
||||
v_mentions JSON_ARRAY_T;
|
||||
v_scope_type VARCHAR2(30);
|
||||
v_target_type VARCHAR2(20);
|
||||
v_targets JSON_ARRAY_T := JSON_ARRAY_T();
|
||||
v_supported JSON_ARRAY_T := JSON_ARRAY_T();
|
||||
v_unmatched JSON_ARRAY_T := JSON_ARRAY_T();
|
||||
v_mention_results JSON_ARRAY_T := JSON_ARRAY_T();
|
||||
@@ -59,6 +61,7 @@ IS
|
||||
v_reason VARCHAR2(4000);
|
||||
v_matched_candidate JSON_OBJECT_T;
|
||||
v_mention_result JSON_OBJECT_T;
|
||||
v_target JSON_OBJECT_T;
|
||||
v_unmatched_item JSON_OBJECT_T;
|
||||
|
||||
v_cursor SYS_REFCURSOR;
|
||||
@@ -67,6 +70,7 @@ IS
|
||||
v_game_prefix VARCHAR2(128);
|
||||
v_game_nm VARCHAR2(512);
|
||||
v_game_alias_nm VARCHAR2(512);
|
||||
v_user_master_object_name VARCHAR2(128);
|
||||
v_cosine_distance NUMBER;
|
||||
BEGIN
|
||||
v_extract_raw := sg_game_extract_mentions(p_question);
|
||||
@@ -74,119 +78,218 @@ BEGIN
|
||||
v_mentions := v_extract.get_array('game_mentions');
|
||||
v_scope_type := NVL(v_extract.get_string('scope_hint'), 'UNKNOWN');
|
||||
|
||||
FOR i IN 0 .. v_mentions.get_size - 1 LOOP
|
||||
v_mention := v_mentions.get_string(i);
|
||||
v_candidates := JSON_ARRAY_T();
|
||||
v_cursor := sg_game_catalog_search(
|
||||
v_mention,
|
||||
LEAST(GREATEST(NVL(p_top_k, 5), 1), 20)
|
||||
);
|
||||
IF v_scope_type = 'ALL_GAMES' THEN
|
||||
v_target_type := 'ALL';
|
||||
ELSIF v_mentions.get_size = 0 THEN
|
||||
v_target_type := 'NONE';
|
||||
ELSIF v_mentions.get_size = 1 THEN
|
||||
v_target_type := 'SINGLE';
|
||||
ELSE
|
||||
v_target_type := 'MULTI';
|
||||
END IF;
|
||||
|
||||
LOOP
|
||||
FETCH v_cursor INTO
|
||||
v_game_key,
|
||||
v_game_id,
|
||||
v_game_prefix,
|
||||
v_game_nm,
|
||||
v_game_alias_nm,
|
||||
v_cosine_distance;
|
||||
EXIT WHEN v_cursor%NOTFOUND;
|
||||
|
||||
v_candidate := JSON_OBJECT_T();
|
||||
v_candidate.put('gameKey', v_game_key);
|
||||
v_candidate.put('gameId', v_game_id);
|
||||
v_candidate.put('gamePrefix', v_game_prefix);
|
||||
v_candidate.put('gameName', v_game_nm);
|
||||
v_candidate.put('aliases', v_game_alias_nm);
|
||||
v_candidate.put('cosineDistance', v_cosine_distance);
|
||||
v_candidates.append(v_candidate);
|
||||
END LOOP;
|
||||
CLOSE v_cursor;
|
||||
|
||||
v_decision_raw := sg_game_match_candidate(
|
||||
v_mention,
|
||||
v_candidates.to_clob
|
||||
);
|
||||
v_decision := JSON_OBJECT_T.parse(v_decision_raw);
|
||||
v_decision_status := UPPER(
|
||||
NVL(v_decision.get_string('status'), 'UNMATCHED')
|
||||
);
|
||||
v_selected_key := v_decision.get_string('game_key');
|
||||
v_reason := v_decision.get_string('reason');
|
||||
v_matched_candidate := NULL;
|
||||
|
||||
IF v_decision_status = 'MATCHED' AND v_selected_key IS NOT NULL THEN
|
||||
FOR j IN 0 .. v_candidates.get_size - 1 LOOP
|
||||
v_candidate := TREAT(v_candidates.get(j) AS JSON_OBJECT_T);
|
||||
IF v_candidate.get_string('gameKey') = v_selected_key THEN
|
||||
v_matched_candidate := v_candidate;
|
||||
EXIT;
|
||||
END IF;
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
v_mention_result := JSON_OBJECT_T();
|
||||
v_mention_result.put('mention', v_mention);
|
||||
v_mention_result.put('candidateGames', v_candidates);
|
||||
v_mention_result.put('reason', v_reason);
|
||||
|
||||
IF v_matched_candidate IS NOT NULL THEN
|
||||
v_mention_result.put('status', 'MATCHED');
|
||||
v_mention_result.put('reasonCode', 'LLM_CANDIDATE_MATCH');
|
||||
v_mention_result.put('matchedGameKey', v_selected_key);
|
||||
IF NOT v_seen_game_keys.EXISTS(v_selected_key) THEN
|
||||
v_supported.append(v_matched_candidate);
|
||||
v_seen_game_keys(v_selected_key) := TRUE;
|
||||
END IF;
|
||||
ELSE
|
||||
v_mention_result.put('status', 'UNMATCHED');
|
||||
IF v_decision_status = 'MATCHED' THEN
|
||||
v_mention_result.put(
|
||||
'reasonCode',
|
||||
'LLM_SELECTED_UNKNOWN_CANDIDATE'
|
||||
);
|
||||
ELSE
|
||||
v_mention_result.put('reasonCode', 'LLM_NO_CANDIDATE_MATCH');
|
||||
END IF;
|
||||
|
||||
v_unmatched_item := JSON_OBJECT_T();
|
||||
v_unmatched_item.put('mention', v_mention);
|
||||
v_unmatched_item.put(
|
||||
'reasonCode',
|
||||
v_mention_result.get_string('reasonCode')
|
||||
IF v_target_type = 'ALL' THEN
|
||||
FOR game_row IN (
|
||||
SELECT game_key, game_id, game_prefix, game_nm, game_alias_nm,
|
||||
user_master_object_name
|
||||
FROM sg_game_catalog
|
||||
WHERE active_yn = 'Y'
|
||||
ORDER BY priority, game_key
|
||||
) LOOP
|
||||
v_target := JSON_OBJECT_T();
|
||||
v_target.put_null('mention');
|
||||
v_target.put('status', 'CATALOG');
|
||||
v_target.put('gameKey', game_row.game_key);
|
||||
v_target.put('gameId', game_row.game_id);
|
||||
v_target.put('gamePrefix', game_row.game_prefix);
|
||||
v_target.put('gameName', game_row.game_nm);
|
||||
v_target.put('aliases', game_row.game_alias_nm);
|
||||
v_target.put(
|
||||
'userMasterObjectName',
|
||||
game_row.user_master_object_name
|
||||
);
|
||||
v_target.put(
|
||||
'objectStatus',
|
||||
CASE WHEN game_row.user_master_object_name IS NULL
|
||||
THEN 'UNAVAILABLE' ELSE 'AVAILABLE' END
|
||||
);
|
||||
v_target.put_null('cosineDistance');
|
||||
v_target.put('reasonCode', 'ALL_GAMES_CATALOG');
|
||||
v_target.put('reason', 'Active game returned from the database catalog.');
|
||||
v_targets.append(v_target);
|
||||
IF game_row.user_master_object_name IS NOT NULL THEN
|
||||
v_supported.append(v_target);
|
||||
END IF;
|
||||
END LOOP;
|
||||
ELSIF v_target_type = 'NONE' THEN
|
||||
v_target := JSON_OBJECT_T();
|
||||
v_target.put_null('mention');
|
||||
v_target.put('status', 'NONE');
|
||||
v_target.put_null('gameKey');
|
||||
v_target.put_null('gameId');
|
||||
v_target.put_null('gamePrefix');
|
||||
v_target.put_null('gameName');
|
||||
v_target.put_null('aliases');
|
||||
v_target.put_null('userMasterObjectName');
|
||||
v_target.put('objectStatus', 'NOT_APPLICABLE');
|
||||
v_target.put_null('cosineDistance');
|
||||
v_target.put('reasonCode', 'NO_GAME_TARGET');
|
||||
v_target.put(
|
||||
'reason',
|
||||
'The question does not select a particular game.'
|
||||
);
|
||||
v_targets.append(v_target);
|
||||
ELSE
|
||||
FOR i IN 0 .. v_mentions.get_size - 1 LOOP
|
||||
v_mention := v_mentions.get_string(i);
|
||||
v_candidates := JSON_ARRAY_T();
|
||||
v_cursor := sg_game_catalog_search(
|
||||
v_mention,
|
||||
LEAST(GREATEST(NVL(p_top_k, 5), 1), 20)
|
||||
);
|
||||
v_unmatched_item.put('reason', v_reason);
|
||||
v_unmatched.append(v_unmatched_item);
|
||||
END IF;
|
||||
v_mention_results.append(v_mention_result);
|
||||
END LOOP;
|
||||
|
||||
v_result.put('scopeType', v_scope_type);
|
||||
IF v_supported.get_size = 0 THEN
|
||||
v_result.put('status', 'NO_MATCH');
|
||||
LOOP
|
||||
FETCH v_cursor INTO
|
||||
v_game_key,
|
||||
v_game_id,
|
||||
v_game_prefix,
|
||||
v_game_nm,
|
||||
v_game_alias_nm,
|
||||
v_user_master_object_name,
|
||||
v_cosine_distance;
|
||||
EXIT WHEN v_cursor%NOTFOUND;
|
||||
|
||||
v_candidate := JSON_OBJECT_T();
|
||||
v_candidate.put('gameKey', v_game_key);
|
||||
v_candidate.put('gameId', v_game_id);
|
||||
v_candidate.put('gamePrefix', v_game_prefix);
|
||||
v_candidate.put('gameName', v_game_nm);
|
||||
v_candidate.put('aliases', v_game_alias_nm);
|
||||
v_candidate.put(
|
||||
'userMasterObjectName',
|
||||
v_user_master_object_name
|
||||
);
|
||||
v_candidate.put(
|
||||
'objectStatus',
|
||||
CASE WHEN v_user_master_object_name IS NULL
|
||||
THEN 'UNAVAILABLE' ELSE 'AVAILABLE' END
|
||||
);
|
||||
v_candidate.put('cosineDistance', v_cosine_distance);
|
||||
v_candidates.append(v_candidate);
|
||||
END LOOP;
|
||||
CLOSE v_cursor;
|
||||
|
||||
v_decision_raw := sg_game_match_candidate(
|
||||
v_mention,
|
||||
v_candidates.to_clob
|
||||
);
|
||||
v_decision := JSON_OBJECT_T.parse(v_decision_raw);
|
||||
v_decision_status := UPPER(
|
||||
NVL(v_decision.get_string('status'), 'UNMATCHED')
|
||||
);
|
||||
v_selected_key := v_decision.get_string('game_key');
|
||||
v_reason := v_decision.get_string('reason');
|
||||
v_matched_candidate := NULL;
|
||||
|
||||
IF v_decision_status = 'MATCHED' AND v_selected_key IS NOT NULL THEN
|
||||
FOR j IN 0 .. v_candidates.get_size - 1 LOOP
|
||||
v_candidate := TREAT(v_candidates.get(j) AS JSON_OBJECT_T);
|
||||
IF v_candidate.get_string('gameKey') = v_selected_key THEN
|
||||
v_matched_candidate := v_candidate;
|
||||
EXIT;
|
||||
END IF;
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
v_mention_result := JSON_OBJECT_T();
|
||||
v_mention_result.put('mention', v_mention);
|
||||
v_mention_result.put('candidateGames', v_candidates);
|
||||
v_mention_result.put('reason', v_reason);
|
||||
|
||||
IF v_matched_candidate IS NOT NULL THEN
|
||||
v_mention_result.put('status', 'MATCHED');
|
||||
v_mention_result.put('reasonCode', 'LLM_CANDIDATE_MATCH');
|
||||
v_mention_result.put('matchedGameKey', v_selected_key);
|
||||
|
||||
v_target := JSON_OBJECT_T.parse(v_matched_candidate.to_clob);
|
||||
v_target.put('mention', v_mention);
|
||||
v_target.put('status', 'MATCHED');
|
||||
v_target.put('reasonCode', 'LLM_CANDIDATE_MATCH');
|
||||
v_target.put('reason', v_reason);
|
||||
v_targets.append(v_target);
|
||||
|
||||
IF NOT v_seen_game_keys.EXISTS(v_selected_key) THEN
|
||||
v_supported.append(v_matched_candidate);
|
||||
v_seen_game_keys(v_selected_key) := TRUE;
|
||||
END IF;
|
||||
ELSE
|
||||
v_mention_result.put('status', 'UNMATCHED');
|
||||
IF v_decision_status = 'MATCHED' THEN
|
||||
v_mention_result.put(
|
||||
'reasonCode',
|
||||
'LLM_SELECTED_UNKNOWN_CANDIDATE'
|
||||
);
|
||||
ELSE
|
||||
v_mention_result.put('reasonCode', 'LLM_NO_CANDIDATE_MATCH');
|
||||
END IF;
|
||||
|
||||
v_target := JSON_OBJECT_T();
|
||||
v_target.put('mention', v_mention);
|
||||
v_target.put('status', 'UNMATCHED');
|
||||
v_target.put_null('gameKey');
|
||||
v_target.put_null('gameId');
|
||||
v_target.put_null('gamePrefix');
|
||||
v_target.put_null('gameName');
|
||||
v_target.put_null('aliases');
|
||||
v_target.put_null('userMasterObjectName');
|
||||
v_target.put('objectStatus', 'UNAVAILABLE');
|
||||
v_target.put_null('cosineDistance');
|
||||
v_target.put(
|
||||
'reasonCode',
|
||||
v_mention_result.get_string('reasonCode')
|
||||
);
|
||||
v_target.put('reason', v_reason);
|
||||
v_targets.append(v_target);
|
||||
|
||||
v_unmatched_item := JSON_OBJECT_T();
|
||||
v_unmatched_item.put('mention', v_mention);
|
||||
v_unmatched_item.put(
|
||||
'reasonCode',
|
||||
v_mention_result.get_string('reasonCode')
|
||||
);
|
||||
v_unmatched_item.put('reason', v_reason);
|
||||
v_unmatched.append(v_unmatched_item);
|
||||
END IF;
|
||||
v_mention_results.append(v_mention_result);
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
v_result.put('targetType', v_target_type);
|
||||
v_result.put('scopeType', v_target_type);
|
||||
v_result.put('extractScopeHint', v_scope_type);
|
||||
IF v_target_type = 'NONE' THEN
|
||||
v_result.put('status', 'NO_TARGET');
|
||||
ELSIF v_target_type = 'ALL' THEN
|
||||
v_result.put('status', 'SUPPORTED');
|
||||
ELSIF v_supported.get_size = 0 THEN
|
||||
v_result.put('status', 'UNMATCHED');
|
||||
ELSIF v_unmatched.get_size > 0 THEN
|
||||
v_result.put('status', 'PARTIAL');
|
||||
ELSE
|
||||
v_result.put('status', 'SUPPORTED');
|
||||
END IF;
|
||||
v_result.put('targets', v_targets);
|
||||
v_result.put('matchedGames', v_supported);
|
||||
v_result.put('mentionResults', v_mention_results);
|
||||
v_result.put('supportedGames', v_supported);
|
||||
v_result.put('unmatchedGames', v_unmatched);
|
||||
v_result.put('nextAction', 'CALL_FEWSHOT');
|
||||
|
||||
IF v_supported.get_size = 0 THEN
|
||||
v_result.put('nextAction', 'STOP_NO_MATCH');
|
||||
ELSIF v_scope_type = 'MULTI_GAME' THEN
|
||||
v_result.put('nextAction', 'CALL_FEWSHOT_PER_GAME');
|
||||
ELSE
|
||||
v_result.put('nextAction', 'CALL_FEWSHOT');
|
||||
END IF;
|
||||
|
||||
CASE v_scope_type
|
||||
WHEN 'SINGLE_GAME' THEN v_result.put('executionMode', 'SINGLE');
|
||||
WHEN 'MULTI_GAME' THEN v_result.put('executionMode', 'FAN_OUT');
|
||||
WHEN 'ALL_GAMES' THEN v_result.put('executionMode', 'GROUPED');
|
||||
ELSE v_result.put('executionMode', 'BLOCKED');
|
||||
CASE v_target_type
|
||||
WHEN 'NONE' THEN v_result.put('executionMode', 'UNSCOPED');
|
||||
WHEN 'SINGLE' THEN v_result.put('executionMode', 'SINGLE');
|
||||
WHEN 'MULTI' THEN v_result.put('executionMode', 'COMBINED');
|
||||
WHEN 'ALL' THEN v_result.put('executionMode', 'ALL');
|
||||
END CASE;
|
||||
|
||||
RETURN v_result.to_clob;
|
||||
|
||||
Reference in New Issue
Block a user