DBA Data[Home] [Help]

PACKAGE BODY: APPS.CZ_RULE_TEXT_GEN

Source


1 PACKAGE BODY cz_rule_text_gen  AS
2 /* $Header: czruletxtb.pls 120.3.12010000.4 2010/05/18 20:43:01 smanna ship $ */
3 
4 
5 
6 PROCEDURE parse_rules(p_devl_project_id IN NUMBER, p_rule_id IN NUMBER DEFAULT NULL) IS
7   schema_version NUMBER;
8   EXPR_OPERATOR          CONSTANT PLS_INTEGER := 200;
9   EXPR_LITERAL           CONSTANT PLS_INTEGER := 201;
10   EXPR_PSNODE            CONSTANT PLS_INTEGER := 205;
11   EXPR_PROP              CONSTANT PLS_INTEGER := 207;
12   EXPR_SYS_PROP          CONSTANT PLS_INTEGER := 210;
13   EXPR_CONSTANT          CONSTANT PLS_INTEGER := 211;
14   EXPR_ARGUMENT          CONSTANT PLS_INTEGER := 221;
15   EXPR_TEMPLATE          CONSTANT PLS_INTEGER := 222;
16   EXPR_FORALL            CONSTANT PLS_INTEGER := 223;
17   EXPR_ITERATOR          CONSTANT PLS_INTEGER := 224;
18   EXPR_WHERE             CONSTANT PLS_INTEGER := 225;
19   EXPR_COMPATIBLE        CONSTANT PLS_INTEGER := 226;
20 
21   OPERATOR_CONTRIBUTE    CONSTANT PLS_INTEGER := 708;
22 
23   DATA_TYPE_INTEGER      CONSTANT PLS_INTEGER := 1;
24   DATA_TYPE_DECIMAL      CONSTANT PLS_INTEGER := 2;
25   DATA_TYPE_BOOLEAN      CONSTANT PLS_INTEGER := 3;
26   DATA_TYPE_TEXT         CONSTANT PLS_INTEGER := 4;
27 
28   PS_NODE_TYPE_REFERENCE CONSTANT PLS_INTEGER := 263;
29   PS_NODE_TYPE_CONNECTOR CONSTANT PLS_INTEGER := 264;
30 
31   EXPR_CONSTANT_E        CONSTANT PLS_INTEGER := 0;
32   EXPR_CONSTANT_PI       CONSTANT PLS_INTEGER := 1;
33 
34   CONSTANT_PI            CONSTANT VARCHAR2(3) := 'pi';
35   CONSTANT_E             CONSTANT VARCHAR2(3) := 'e';
36 
37   NewLine                CONSTANT VARCHAR2(25) := FND_GLOBAL.NEWLINE;
38 
39   CZ_UPRT_MULTIPLE_ROOTS EXCEPTION;
40   CZ_UPRT_UNKNOWN_TYPE   EXCEPTION;
41   CZ_UPRT_INCORRECT_PROP EXCEPTION;
42   CZ_UPRT_INCORRECT_NODE EXCEPTION;
43 
44   TYPE tStringTable      IS TABLE OF VARCHAR2(32767) INDEX BY VARCHAR2(15);
45   TYPE tStringTableIBI   IS TABLE OF VARCHAR2(32767) INDEX BY BINARY_INTEGER;
46   TYPE tIntegerTable     IS TABLE OF PLS_INTEGER INDEX BY VARCHAR2(15);
47   TYPE tIntegerTableIBI  IS TABLE OF PLS_INTEGER INDEX BY BINARY_INTEGER;
48   TYPE tNumberTable      IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
49   TYPE tNumberTable_idx_vc2      IS TABLE OF NUMBER INDEX BY VARCHAR2(15); -- New Array defined.
50 
51   TYPE tRuleId           IS TABLE OF cz_rules.rule_id%TYPE INDEX BY BINARY_INTEGER;
52   TYPE tRuleName         IS TABLE OF cz_rules.name%TYPE INDEX BY BINARY_INTEGER;
53   TYPE tTemplateToken    IS TABLE OF cz_rules.template_token%TYPE INDEX BY BINARY_INTEGER;
54   TYPE tPsNodeName       IS TABLE OF cz_ps_nodes.name%TYPE INDEX BY BINARY_INTEGER;
55   TYPE tPropertyName     IS TABLE OF cz_properties.name%TYPE INDEX BY BINARY_INTEGER;
56   TYPE tNodeId           IS TABLE OF cz_model_ref_expls.model_ref_expl_id%TYPE INDEX BY BINARY_INTEGER;
57   TYPE tParentId         IS TABLE OF cz_model_ref_expls.parent_expl_node_id%TYPE INDEX BY BINARY_INTEGER;
58   TYPE tComponentId      IS TABLE OF cz_model_ref_expls.component_id%TYPE INDEX BY BINARY_INTEGER;
59   TYPE tReferringId      IS TABLE OF cz_model_ref_expls.referring_node_id%TYPE INDEX BY BINARY_INTEGER;
60   TYPE tNodeType         IS TABLE OF cz_model_ref_expls.ps_node_type%TYPE INDEX BY BINARY_INTEGER;
61 
62   v_RuleId               tRuleId;
63   v_RuleName             tRuleName;
64   v_TemplateToken        tTemplateToken;
65   h_RuleName             tRuleName;
66   h_TemplateToken        tTemplateToken;
67   h_PsNodeName           tPsNodeName;
68   h_PropertyName         tPropertyName;
69   h_FullName             tIntegerTable;
70 
71   v_NodeId               tNodeId;
72   v_ParentId             tParentId;
73   v_ComponentId          tComponentId;
74   v_ReferringId          tReferringId;
75   v_NodeType             tNodeType;
76   h_ParentId             tParentId;
77   h_NodeType             tNodeType;
78   h_ReferringId          tReferringId;
79   h_ComponentId          tComponentId;
80   h_ContextPath          tStringTable;
81   h_ModelPath            tStringTable;
82   h_NodeName             tStringTable;
83 
84   xError                 BOOLEAN;
85   nDebug                 PLS_INTEGER;
86 ---------------------------------------------------------------------------------------
87 PROCEDURE populate_rule_text(p_rule_id IN NUMBER) IS
88 
89   TYPE tExprId           IS TABLE OF cz_expression_nodes.expr_node_id%TYPE INDEX BY BINARY_INTEGER;
90   TYPE tExprParentId     IS TABLE OF cz_expression_nodes.expr_parent_id%TYPE INDEX BY BINARY_INTEGER;
91   TYPE tExprType         IS TABLE OF cz_expression_nodes.expr_type%TYPE INDEX BY BINARY_INTEGER;
92   TYPE tExprTemplateId   IS TABLE OF cz_expression_nodes.template_id%TYPE INDEX BY BINARY_INTEGER;
93   TYPE tExprPsNodeId     IS TABLE OF cz_expression_nodes.ps_node_id%TYPE INDEX BY BINARY_INTEGER;
94   TYPE tExplNodeId       IS TABLE OF cz_expression_nodes.model_ref_expl_id%TYPE INDEX BY BINARY_INTEGER;
95   TYPE tExprPropertyId   IS TABLE OF cz_expression_nodes.property_id%TYPE INDEX BY BINARY_INTEGER;
96   TYPE tExprDataType     IS TABLE OF cz_expression_nodes.data_type%TYPE INDEX BY BINARY_INTEGER;
97   TYPE tExprDataValue    IS TABLE OF cz_expression_nodes.data_value%TYPE INDEX BY BINARY_INTEGER;
98   TYPE tExprDataNumValue IS TABLE OF cz_expression_nodes.data_num_value%TYPE INDEX BY BINARY_INTEGER;
99   TYPE tExprParamIndex   IS TABLE OF cz_expression_nodes.param_index%TYPE INDEX BY BINARY_INTEGER;
100   TYPE tExprArgumentName IS TABLE OF cz_expression_nodes.argument_name%TYPE INDEX BY BINARY_INTEGER;
101 
102   TYPE tCDLIndex         IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; -- Added for Bug 9650435
103   v_CDLIndex             tCDLIndex;                                  -- Added for Bug 9650435
104 
105   v_ExprId               tExprId;
106   v_ExprParentId         tExprParentId;
107   v_ExprType             tExprType;
108   v_ExprTemplateId       tExprTemplateId;
109   v_ExprPsNodeId         tExprPsNodeId;
110   v_ExplNodeId           tExplNodeId;
111   v_ExprPropertyId       tExprPropertyId;
112   v_ExprDataType         tExprDataType;
113   v_ExprDataValue        tExprDataValue;
114   v_ExprDataNumValue     tExprDataNumValue;
115   v_ExprParamIndex       tExprParamIndex;
116   v_ExprArgumentName     tExprArgumentName;
117 
118   vi_ExprId              tExprId;
119   vi_Name                tStringTableIBI;
120   vi_Depth               tIntegerTableIBI;
121   vi_Occurrence          tIntegerTable;
122   vi_Pos                 tIntegerTableIBI;
123 
124   v_ChildrenIndex        tNumberTable_idx_vc2;
125   v_NumberOfChildren     tNumberTable_idx_vc2;
126   v_RuleText             VARCHAR2(32767);
127   errmsg1                VARCHAR2(2000);
128   errmsg2                VARCHAR2(2000);
129   rootIndex              PLS_INTEGER;
130   isCompatible           PLS_INTEGER := 0;
131   isForall               PLS_INTEGER := 0;
132   currentLevel           PLS_INTEGER := 0;
133   v_pres_flag            number;
134 ---------------------------------------------------------------------------------------
135   FUNCTION parse_expr_node(j IN PLS_INTEGER) RETURN VARCHAR2 IS
136 
137     v_RuleText           VARCHAR2(32767);
138     v_Name               VARCHAR2(2000);
139     v_Index              PLS_INTEGER;
140     v_aux                PLS_INTEGER;
141     v_token              cz_rules.template_token%TYPE;
142 ---------------------------------------------------------------------------------------
143     FUNCTION generate_model_path(p_ps_node_id IN NUMBER) RETURN VARCHAR2 IS
144       v_Name             VARCHAR2(32767);
145     BEGIN
146 
147       IF(h_ModelPath.EXISTS(p_ps_node_id))THEN RETURN h_ModelPath(p_ps_node_id); END IF;
148 
149       FOR c_name IN (SELECT name, parent_id FROM cz_ps_nodes
150                       START WITH ps_node_id = p_ps_node_id
151                     CONNECT BY PRIOR parent_id = ps_node_id) LOOP
152 
153         IF(v_Name IS NULL)THEN
154 
155           v_Name := '''' || c_name.name || '''';
156           h_NodeName(p_ps_node_id) := v_Name;
157 
158           FOR c_node IN (SELECT NULL FROM cz_ps_nodes WHERE deleted_flag = '0'
159                             AND devl_project_id = p_devl_project_id
160                             AND name = c_name.name
161                             AND ps_node_id <> p_ps_node_id)LOOP
162             h_FullName(p_ps_node_id) := 1;
163             EXIT;
164           END LOOP;
165           FOR c_node IN (SELECT NULL FROM cz_ps_nodes WHERE deleted_flag = '0'
166                             AND devl_project_id IN
167                               (SELECT component_id FROM cz_model_ref_expls
168                                 WHERE deleted_flag = '0'
169                                   AND model_id = p_devl_project_id
170                                   AND ps_node_type IN (PS_NODE_TYPE_REFERENCE, PS_NODE_TYPE_CONNECTOR))
171                             AND name = c_name.name)LOOP
172             h_FullName(p_ps_node_id) := 1;
173             EXIT;
174           END LOOP;
175         ELSIF(c_name.parent_id IS NOT NULL)THEN -- This is to exclude the root model name from the path.
176           v_Name := '''' || c_name.name || '''' || FND_GLOBAL.LOCAL_CHR(8) || v_Name;
177         END IF;
178       END LOOP;
179 
180       h_ModelPath(p_ps_node_id) := v_Name;
181      RETURN v_Name;
182     END generate_model_path;
183 ---------------------------------------------------------------------------------------
184     FUNCTION generate_context_path(p_expl_id IN NUMBER) RETURN VARCHAR2 IS
185       v_Node             NUMBER;
186       v_Name             VARCHAR2(32767);
187       v_ModelName        VARCHAR2(32767);
188     BEGIN
189 
190       --The path cashing is disabled because now it depends not only on expl_id, but also on the
191       --participating node (see comment below).
192 
193       --IF(h_ContextPath.EXISTS(p_expl_id))THEN RETURN h_ContextPath(p_expl_id); END IF;
194 
195       v_Node := p_expl_id;
196 
197       WHILE(v_Node IS NOT NULL)LOOP
198 
199         IF(h_NodeType(v_Node) IN (PS_NODE_TYPE_REFERENCE, PS_NODE_TYPE_CONNECTOR))THEN
200 
201           v_ModelName := NULL;
202 
203           IF(h_NodeType(v_Node) = PS_NODE_TYPE_CONNECTOR AND
204 
205              --We do not need to add the connected model name if the participating node is the model
206              --itself, otherwise it will be twice in the path.
207 
208              h_ComponentId(v_Node) <> v_ExprPsNodeId(j))THEN
209 
210             BEGIN
211 
212               SELECT name INTO v_ModelName FROM cz_ps_nodes
213                WHERE ps_node_id = h_ComponentId(v_Node);
214             EXCEPTION
215               WHEN OTHERS THEN
216                 NULL;
217             END;
218           END IF;
219 
220           IF(v_ModelName IS NOT NULL)THEN v_ModelName := FND_GLOBAL.LOCAL_CHR(7) || '''' || v_ModelName || ''''; END IF;
221 
222           IF(v_Name IS NULL)THEN v_Name := generate_model_path(h_ReferringId(v_Node)) || v_ModelName;
223           ELSE v_Name := generate_model_path(h_ReferringId(v_Node)) || v_ModelName || FND_GLOBAL.LOCAL_CHR(8) || v_Name;
224           END IF;
225         END IF;
226 
227         v_Node := h_ParentId(v_Node);
228       END LOOP;
229 
230       --h_ContextPath(p_expl_id) := v_Name;
231      RETURN v_Name;
232     END generate_context_path;
233 ---------------------------------------------------------------------------------------
234     FUNCTION generate_name RETURN VARCHAR2 IS
235       v_expl_id          NUMBER := v_ExplNodeId(j);
236       v_this             VARCHAR2(32767);
237       v_that             VARCHAR2(32767);
238       v_subthis          VARCHAR2(32767);
239       v_subthat          VARCHAR2(32767);
240       v_name             VARCHAR2(32767);
241       v_level            PLS_INTEGER;
242       v_depth            PLS_INTEGER := 0;
243     BEGIN
244 
245       IF(v_ExprPsNodeId(j) = h_ReferringId(v_expl_id))THEN
246         v_expl_id := h_ParentId(v_expl_id);
247       END IF;
248 
249       IF(v_expl_id IS NOT NULL)THEN v_this := generate_context_path(v_expl_id); END IF;
250       v_name := generate_model_path(v_ExprPsNodeId(j));
251 
252       IF(v_this IS NULL)THEN
253         IF(NOT h_FullName.EXISTS(v_ExprPsNodeId(j)))THEN v_name := h_NodeName(v_ExprPsNodeId(j)); END IF;
254       ELSE
255 
256         FOR i IN 1..v_NodeId.COUNT LOOP
257 
258           IF(h_ComponentId(v_NodeId(i)) = h_ComponentId(v_expl_id) AND v_NodeId(i) <> v_expl_id)THEN
259 
260             v_that := generate_context_path(v_NodeId(i));
261             v_level := 1;
262 
263             LOOP
264 
265               v_subthis := SUBSTR(v_this, INSTR(v_this, FND_GLOBAL.LOCAL_CHR(8), -1, v_level) + 1);
266               v_subthat := SUBSTR(v_that, INSTR(v_that, FND_GLOBAL.LOCAL_CHR(8), -1, v_level) + 1);
267 
268               IF(v_subthis = v_this)THEN EXIT; END IF;
269               IF(v_subthat = v_that)THEN v_Level := v_Level + 1; EXIT; END IF;
270               IF(v_subthis <> v_subthat)THEN EXIT; END IF;
271 
272               v_level := v_level + 1;
273             END LOOP;
274 
275             IF(v_level > v_depth)THEN v_depth := v_level; END IF;
276           END IF;
277         END LOOP;
278 
279         IF(v_depth = 0)THEN
280 
281           --Bug #4590481 - in this case we also need to concatenate the path. If the full path is not
282           --required, the second line will reset it to just the node name.
283 
284           v_name := v_this || FND_GLOBAL.LOCAL_CHR(8) || v_name;
285           IF(NOT h_FullName.EXISTS(v_ExprPsNodeId(j)))THEN v_name := h_NodeName(v_ExprPsNodeId(j)); END IF;
286         ELSE v_name := SUBSTR(v_this, INSTR(v_this, FND_GLOBAL.LOCAL_CHR(8), -1, v_depth) + 1) || FND_GLOBAL.LOCAL_CHR(8) || v_name;
287         END IF;
288       END IF;
289 
290       v_Index := vi_ExprId.COUNT + 1;
291       vi_ExprId(v_Index) := v_ExprId(j);
292 
293       v_Level := 1;
294       WHILE(INSTR(v_name, FND_GLOBAL.LOCAL_CHR(8), 1, v_Level) <> 0)LOOP v_Level := v_Level + 1; END LOOP;
295       vi_Depth(v_Index) := v_Level;
296 
297       v_name := REPLACE(v_name, '''' || FND_GLOBAL.LOCAL_CHR(7) || '''', '''.''');
298       v_name := REPLACE(v_name, '''' || FND_GLOBAL.LOCAL_CHR(8) || '''', '''.''');
299 
300       v_aux := 1;
301 
302       FOR i IN 1..vi_Name.COUNT LOOP
303         IF(v_name = vi_Name(i))THEN v_aux := v_aux + 1; END IF;
304       END LOOP;
305 
306       vi_Occurrence(v_Index) := v_aux;
307       vi_Name(v_Index) := v_name;
308 
309      RETURN v_name;
310     END generate_name;
311 ---------------------------------------------------------------------------------------
312   BEGIN
313 
314     currentLevel := currentLevel + 1;
315 
316     IF(v_ExprType(j) = EXPR_OPERATOR)THEN
317 
318 nDebug := 1000;
319 
320       --First correct a data_type upgrade problem from czrules1.sql. This is an operator, its children
321       --has not been generated into text yet. We will update data_type and data_num_value for children
322       --in memory, if necessary, so that children will or will not be enclosed in quotes correctly. At
323       --the end, we physically update the columns in cz_expression_nodes.
324 
325       IF(v_ExprTemplateId(j) IN
326           (318,320,321,322,323,350,351,352,353,399,401,402,403,
327            404,405,406,407,408,409,410,411,412,413,414,415,416,
328            417,418,430,431,432,433,434,435,436,437,438,439,551)
329          AND v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
330 
331         --This is one of the operators with only numeric operands or = or <>.
332 
333         v_Index := v_ChildrenIndex(v_ExprId(j));
334 
335         LOOP
336 
337           IF(v_ExprType(v_Index) = EXPR_LITERAL AND v_ExprDataType(v_Index) IS NULL AND
338              v_ExprDataNumValue(v_Index) IS NULL)THEN
339 
340             --This is a literal child of the operator with undefined data_type and data_num_value.
341             --Here we fix data only for such operands.
342 
346               v_ExprDataType(v_Index) := DATA_TYPE_DECIMAL;
343             BEGIN
344 
345               v_ExprDataNumValue(v_Index) := TO_NUMBER(v_ExprDataValue(v_Index));
347               IF(v_ExprTemplateId(j) = 551)THEN v_ExprDataType(v_Index) := DATA_TYPE_INTEGER; END IF;
348 
349             EXCEPTION
350               WHEN OTHERS THEN
351                 v_ExprDataType(v_Index) := DATA_TYPE_TEXT;
352             END;
353           END IF;
354 
355           v_Index := v_Index + 1;
356           EXIT WHEN (NOT v_ExprParentId.EXISTS(v_Index)) OR
357                      (v_ExprParentId(v_Index) IS NULL) OR
358                      (v_ExprParentId(v_Index) <> v_ExprId(j));
359         END LOOP;
360       END IF;
361 
362       --Done with the data fix for data_type, data_num_value population after czrules1.sql.
363 
364       v_token := h_TemplateToken(v_ExprTemplateId(j));
365 
366       IF((v_token IS NULL AND UPPER(h_RuleName(v_ExprTemplateId(j))) NOT IN ('CONTRIBUTESTO', 'CONSUMESFROM', 'ADDSTO')) OR
367           v_NumberOfChildren(v_ExprId(j)) > 2)THEN
368 
369         v_RuleText := NVL(h_RuleName(v_ExprTemplateId(j)), v_token) || '(';
370 
371         IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
372 
373           v_Index := v_ChildrenIndex(v_ExprId(j));
374 
375           LOOP
376 
377             v_RuleText := v_RuleText || parse_expr_node(v_Index);
378             v_Index := v_Index + 1;
379 
380             EXIT WHEN (NOT v_ExprParentId.EXISTS(v_Index)) OR
381                       (v_ExprParentId(v_Index) IS NULL) OR
382                       (v_ExprParentId(v_Index) <> v_ExprId(j));
383 
384             v_RuleText := v_RuleText || ', ';
385           END LOOP;
386         END IF;
387 
388         v_RuleText := v_RuleText || ')';
389       ELSE
390 
391         IF(v_token IS NULL)THEN v_token := h_RuleName(v_ExprTemplateId(j)); END IF;
392 
393         IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
394 
395           v_Index := v_ChildrenIndex(v_ExprId(j));
396 
397           IF(v_NumberOfChildren(v_ExprId(j)) = 2)THEN
398             IF(UPPER(v_token) = 'CONTRIBUTESTO')THEN
399 
400               v_RuleText := 'Contribute ' || parse_expr_node(v_Index) || ' TO';
401               v_token := NULL;
402             ELSIF(UPPER(v_token) = 'ADDSTO')THEN
403 
404               v_RuleText := 'ADD ' || parse_expr_node(v_Index) || ' TO';
405               v_token := NULL;
406             ELSE
407 
408               v_RuleText := parse_expr_node(v_Index) || ' ';
409             END IF;
410 
411             v_Index := v_Index + 1;
412           END IF;
413 
414           v_RuleText := v_RuleText || v_token || ' ' || parse_expr_node(v_Index);
415         ELSE
416 
417           v_RuleText := v_token;
418         END IF;
419 
420         IF((isForall = 0 AND currentLevel > 1) OR (isForall = 1 AND currentLevel > 2))THEN
421 
422             v_RuleText := '(' || v_RuleText || ')';
423         END IF;
424       END IF;
425     ELSIF(v_ExprType(j) = EXPR_LITERAL)THEN
426 
427 nDebug := 1001;
428 
429       IF(v_ExprDataType(j) IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL))THEN
430 
431         v_RuleText := v_ExprDataNumValue(j);
432       ELSIF(v_ExprDataType(j) = DATA_TYPE_TEXT OR (v_ExprDataType(j) IS NULL AND v_ExprDataNumValue(j) IS NULL))THEN
433 
434         v_RuleText := '"' || v_ExprDataValue(j) || '"';
435       ELSIF(v_ExprDataType(j) = DATA_TYPE_BOOLEAN) THEN
436         IF(v_ExprDataValue(j)=1) THEN
437 	    v_RuleText := 'TRUE ' ;
438         ELSE
439 	    v_RuleText := 'FALSE ';
440 
441 	END IF;
442       ELSE
443 
444         v_RuleText := v_ExprDataValue(j);
445       END IF;
446 
447     ELSIF(v_ExprType(j) = EXPR_PSNODE)THEN
448 
449 nDebug := 1002;
450 
451       v_RuleText := generate_name;
452 
453       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
454 
455         v_Index := v_ChildrenIndex(v_ExprId(j));
456 
457         WHILE(v_ExprParentId.EXISTS(v_Index) AND v_ExprParentId(v_Index) = v_ExprId(j))LOOP
458 
459           v_RuleText := v_RuleText || parse_expr_node(v_Index);
460           v_Index := v_Index + 1;
461         END LOOP;
462       END IF;
463 
464     ELSIF(v_ExprType(j) = EXPR_PROP)THEN
465 
466 nDebug := 1003;
467 
468       IF(NOT h_PropertyName.EXISTS(v_ExprPropertyId(j)))THEN
469 
470         --We don't want to account for deleted_flag in this query because we want to parse a rule even
471         --if it refers to a deleted property instead of ignoring the rule.
472 
473         BEGIN
474           SELECT name INTO v_Name FROM cz_properties
475            WHERE property_id = v_ExprPropertyId(j);
476 
477           h_PropertyName(v_ExprPropertyId(j)) := v_Name;
478 
479         EXCEPTION
480           WHEN OTHERS THEN
481             errmsg1 := TO_CHAR(v_ExprId(j));
482             errmsg2 := TO_CHAR(v_ExprPropertyId(j));
483             RAISE CZ_UPRT_INCORRECT_PROP;
484         END;
485       ELSE
486 
487         v_Name := h_PropertyName(v_ExprPropertyId(j));
488       END IF;
489 
490       v_Name := '"' || v_Name || '"';
491       v_RuleText := '.Property(' || v_Name || ')';
492       v_aux := 1;
493 
494       FOR i IN 1..vi_Name.COUNT LOOP
495         IF(v_Name = vi_Name(i))THEN v_aux := v_aux + 1; END IF;
496       END LOOP;
497 
498       v_Index := vi_ExprId.COUNT + 1;
499       vi_ExprId(v_Index) := v_ExprId(j);
500       vi_Occurrence(v_Index) := v_aux;
501       vi_Depth(v_Index) := 0;
502       vi_Name(v_Index) := v_Name;
503 
507 
504     ELSIF(v_ExprType(j) = EXPR_SYS_PROP)THEN
505 
506 nDebug := 1004;
508       IF(isCompatible = 0)THEN v_RuleText := '.' || h_RuleName(v_ExprTemplateId(j)) || '()'; END IF;
509 
510     ELSIF(v_ExprType(j) = EXPR_ARGUMENT)THEN
511 
512 nDebug := 1005;
513 
514       v_RuleText := v_ExprArgumentName(j);
515 
516       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
517 
518         v_Index := v_ChildrenIndex(v_ExprId(j));
519 
520         WHILE(v_ExprParentId.EXISTS(v_Index) AND v_ExprParentId(v_Index) = v_ExprId(j))LOOP
521 
522           v_RuleText := v_RuleText || parse_expr_node(v_Index);
523           v_Index := v_Index + 1;
524         END LOOP;
525       END IF;
526 
527     ELSIF(v_ExprType(j) = EXPR_TEMPLATE)THEN
528 
529 nDebug := 1006;
530 
531       v_RuleText := '@' || h_RuleName(v_ExprTemplateId(j));
532 
533     ELSIF(v_ExprType(j) = EXPR_FORALL)THEN
534 
535 nDebug := 1007;
536 
537       isForall := 1;
538       v_RuleText := ' FOR ALL' || NewLine;
539 
540       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
541 
542         v_Index := v_ChildrenIndex(v_ExprId(j)) + v_NumberOfChildren(v_ExprId(j)) - 1;
543 
544         IF(v_ExprParentId.EXISTS(v_Index) AND v_ExprParentId(v_Index) = v_ExprId(j) AND
545            v_ExprType(v_Index) NOT IN (EXPR_ITERATOR, EXPR_WHERE))THEN
546 
547           v_RuleText := parse_expr_node(v_Index) || v_RuleText;
548         END IF;
549 
550         v_Index := v_ChildrenIndex(v_ExprId(j));
551 
552         LOOP
553 
554           v_RuleText := v_RuleText || parse_expr_node(v_Index);
555           v_Index := v_Index + 1;
556 
557           EXIT WHEN (NOT v_ExprParentId.EXISTS(v_Index)) OR
558                     (v_ExprType(v_Index) NOT IN (EXPR_ITERATOR, EXPR_WHERE)) OR
559                     (v_ExprParentId(v_Index) IS NULL) OR
560                     (v_ExprParentId(v_Index) <> v_ExprId(j));
561 
562           IF(v_ExprType(v_Index - 1) = EXPR_ITERATOR AND v_ExprType(v_Index) = EXPR_ITERATOR)THEN
563             v_RuleText := v_RuleText || ',';
564           END IF;
565           v_RuleText := v_RuleText || NewLine;
566         END LOOP;
567       END IF;
568       isForall := 0;
569 
570     ELSIF(v_ExprType(j) = EXPR_ITERATOR)THEN
571 
572 nDebug := 1008;
573 
574       IF(isCompatible = 1)THEN v_RuleText := v_ExprArgumentName(j) || ' OF ';
575       ELSE v_RuleText := v_ExprArgumentName(j) || ' IN {'; END IF;
576 
577       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
578 
579         v_Index := v_ChildrenIndex(v_ExprId(j));
580 
581         LOOP
582 
583           v_RuleText := v_RuleText || parse_expr_node(v_Index);
584           v_Index := v_Index + 1;
585 
586           EXIT WHEN (NOT v_ExprParentId.EXISTS(v_Index)) OR
587                     (v_ExprParentId(v_Index) IS NULL) OR
588                     (v_ExprParentId(v_Index) <> v_ExprId(j));
589 
590           v_RuleText := v_RuleText || ', ';
591         END LOOP;
592       END IF;
593 
594       IF(isCompatible = 0)THEN v_RuleText := v_RuleText || '}'; END IF;
595 
596     ELSIF(v_ExprType(j) = EXPR_WHERE)THEN
597 
598 nDebug := 1009;
599 
600       v_RuleText := ' WHERE' || NewLine;
601 
602       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
603 
604         v_Index := v_ChildrenIndex(v_ExprId(j));
605 
606         WHILE(v_ExprParentId.EXISTS(v_Index) AND v_ExprParentId(v_Index) = v_ExprId(j))LOOP
607 
608           v_RuleText := v_RuleText || parse_expr_node(v_Index);
609           v_Index := v_Index + 1;
610         END LOOP;
611       END IF;
612 
613     ELSIF(v_ExprType(j) = EXPR_COMPATIBLE)THEN
614 
615 nDebug := 1010;
616 
617       isCompatible := 1;
618       v_RuleText := 'COMPATIBLE' || NewLine;
619 
620       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
621 
622         v_Index := v_ChildrenIndex(v_ExprId(j));
623 
624         LOOP
625 
626           v_RuleText := v_RuleText || parse_expr_node(v_Index);
627           v_Index := v_Index + 1;
628 
629           EXIT WHEN (NOT v_ExprParentId.EXISTS(v_Index)) OR
630                     (v_ExprParentId(v_Index) IS NULL) OR
631                     (v_ExprParentId(v_Index) <> v_ExprId(j));
632 
633           IF(v_ExprType(v_Index - 1) = EXPR_ITERATOR AND v_ExprType(v_Index) = EXPR_ITERATOR)THEN
634             v_RuleText := v_RuleText || ',';
635           END IF;
636           v_RuleText := v_RuleText || NewLine;
637         END LOOP;
638       END IF;
639       isCompatible := 0;
640     ELSIF(v_ExprType(j) = EXPR_CONSTANT)THEN
641 
642       IF(v_ExprTemplateId(j) =  EXPR_CONSTANT_E)THEN
643 
644         v_RuleText := CONSTANT_E;
645       ELSE
646 
647         v_RuleText := CONSTANT_PI;
648       END IF;
649     ELSE
650       errmsg1 := TO_CHAR(v_ExprId(j));
651       errmsg2 := TO_CHAR(v_ExprType(j));
652       RAISE CZ_UPRT_UNKNOWN_TYPE;
653     END IF;
654 
655    currentLevel := currentLevel - 1;
656    RETURN v_RuleText;
657   END parse_expr_node;
658 ---------------------------------------------------------------------------------------
659 
660 
661 BEGIN
662 
663 nDebug := 2;
664 
665    v_pres_flag:=1;
666 
667    SELECT presentation_flag
668       INTO v_pres_flag
669    FROM cz_rules ru
670    WHERE rule_id = p_rule_id
671    AND(rule_text IS NULL
672      OR EXISTS
673       (SELECT 1
674        FROM cz_expression_nodes
675        WHERE rule_id = ru.rule_id
679    if v_pres_flag=1  then
676        AND template_id IN(712,    714 , 552 , 2))
677      );
678 
680 	return;
681    end if;
682    --Read the expression into memory.
683 
684    SELECT expr_node_id, expr_parent_id, expr_type, template_id,
685           ps_node_id, model_ref_expl_id, property_id, data_type, data_value, data_num_value,
686           param_index, argument_name
687      BULK COLLECT INTO v_ExprId, v_ExprParentId, v_ExprType, v_ExprTemplateId,
688                        v_ExprPsNodeId, v_ExplNodeId, v_ExprPropertyId, v_ExprDataType, v_ExprDataValue, v_ExprDataNumValue,
689                        v_ExprParamIndex, v_ExprArgumentName
690      FROM cz_expression_nodes
691     WHERE rule_id = p_rule_id
692       AND expr_type <> 208
693       AND deleted_flag = '0'
694     ORDER BY expr_parent_id, seq_nbr;
695 
696    rootIndex := 0;
697 
698    FOR i IN 1..v_ExprId.COUNT LOOP
699 
700      IF(NOT v_NumberOfChildren.EXISTS(v_ExprId(i)))THEN v_NumberOfChildren(v_ExprId(i)) := 0; END IF;
701 
702      IF(v_ExprParentId(i) IS NOT NULL)THEN
703 
704        IF(v_NumberOfChildren.EXISTS(v_ExprParentId(i)))THEN
705          v_NumberOfChildren(v_ExprParentId(i)) := v_NumberOfChildren(v_ExprParentId(i)) + 1;
706        ELSE
707          v_NumberOfChildren(v_ExprParentId(i)) := 1;
708        END IF;
709 
710        IF(NOT v_ChildrenIndex.EXISTS(v_ExprParentId(i)))THEN
711          v_ChildrenIndex(v_ExprParentId(i)) := i;
712        END IF;
713      ELSE
714 
715        --IF(rootIndex = 0)THEN rootIndex := i; ELSE RAISE CZ_UPRT_MULTIPLE_ROOTS; END IF;
716        -- Bug 9650435 - Fix - Start
717        rootIndex := rootIndex + 1;
718        v_CDLIndex(rootIndex) := i;
719        -- Bug 9650435 - Fix - End
720      END IF;
721    END LOOP;
722 
723 nDebug := 3;
724 
725    -- v_RuleText := parse_expr_node(rootIndex);
726    -- Bug 9650435 Fix  - Start
727    v_RuleText := '';
728    FOR i IN 1..v_CDLIndex.COUNT LOOP
729       IF (i <> v_CDLIndex.COUNT) THEN
730          v_RuleText := v_RuleText || parse_expr_node(v_CDLIndex(i)) || ';' || NewLine;
731       ELSE
732          v_RuleText := v_RuleText || parse_expr_node(v_CDLIndex(i)) || ';';
733       END IF;
734    END LOOP;
735    -- Bug 9650435 Fix 1 - End
736    FOR i IN 1..vi_ExprId.COUNT LOOP
737 
738      --We are trying to find the position of an occurence of the name in the text. We need to
739      --handle the situation when the name can be a part of another name. For example, if both
740      --'A'.'B'.'C' and 'A'.'B' are in the text, we should skip 'A'.'B' found as a part of
741      --'A'.'B'.'C'. So, when an occurence of 'A'.'B' is found, we check the next symbol, and
742      --if it is '.''', we need to keep looking. Note, that we can't check for just '.' as
743      --there may be a property following the name.
744 
745      currentLevel := 0;
746 
747      FOR j IN 1..vi_Occurrence(i) LOOP
748 
749        currentLevel := INSTR(v_RuleText, vi_Name(i), currentLevel + 1);
750 
751        WHILE(SUBSTR(v_RuleText, currentLevel + LENGTH(vi_Name(i)), 2) = '.''')LOOP
752 
753          currentLevel := INSTR(v_RuleText, vi_Name(i), currentLevel + 1);
754        END LOOP;
755      END LOOP;
756 
757      vi_Pos(i) := currentLevel;
758    END LOOP;
759 
760    FORALL i IN 1..vi_ExprId.COUNT
761      UPDATE cz_expression_nodes SET
762        display_node_depth = vi_Depth(i),
763        source_offset = vi_Pos(i),
764        source_length = LENGTH(vi_Name(i))
765      WHERE expr_node_id = vi_ExprId(i);
766 
767    --We need to update these columns as they may have been corrected in parse_expr_node procedure.
768 
769    FORALL i IN 1..v_ExprId.COUNT
770      UPDATE cz_expression_nodes SET
771        data_type = v_ExprDataType(i),
772        data_num_value = v_ExprDataNumValue(i)
773      WHERE expr_node_id = v_ExprId(i);
774 
775    UPDATE cz_rules SET rule_text = v_RuleText WHERE rule_id = p_rule_id;
776 
777 EXCEPTION
778   WHEN CZ_UPRT_MULTIPLE_ROOTS THEN
779     xError := cz_utils.report('rule_id = ' || p_rule_id || ': more than one record with null expr_parent_id', 1, 'CDL Rule Upgrade', 13000);
780   WHEN CZ_UPRT_UNKNOWN_TYPE THEN
781     xError := cz_utils.report('rule_id = ' || p_rule_id || ', expr_node_id = ' || errmsg1 || ': unknown expression type, expr_type = ' || errmsg2, 1, 'CDL Rule Upgrade', 13000);
782   WHEN CZ_UPRT_INCORRECT_PROP THEN
783     xError := cz_utils.report('rule_id = ' || p_rule_id || ', expr_node_id = ' || errmsg1 || ': no such property, property_id = ' || errmsg2, 1, 'CDL Rule Upgrade', 13000);
784   WHEN CZ_UPRT_INCORRECT_NODE THEN
785     xError := cz_utils.report('rule_id = ' || p_rule_id || ', expr_node_id = ' || errmsg1 || ': no such node, ps_node_id = ' || errmsg2, 1, 'CDL Rule Upgrade', 13000);
786   WHEN OTHERS THEN
787     errmsg1 := SQLERRM;
788     xError := cz_utils.report('rule_id = ' || p_rule_id || ' at ' || nDebug || ': ' || errmsg1, 1, 'CDL Rule Upgrade', 13000);
789 END populate_rule_text;
790 ---------------------------------------------------------------------------------------
791 BEGIN
792 
793 
794 DECLARE
795   xERROR  BOOLEAN;
796 BEGIN
797 
798   SELECT TO_NUMBER(value) INTO schema_version
799     FROM cz_db_settings
800    WHERE setting_id = 'MAJOR_VERSION'
801      AND section_name = 'SCHEMA';
802 
803 EXCEPTION
804   WHEN OTHERS THEN
805     xERROR:=CZ_UTILS.REPORT('Unable to resolve schema version: ' || SQLERRM, 1, 'czrules2.sql' , 13000);
806     RAISE;
807 END;
808 
809 
810 nDebug := 1;
811 
812    --Initialize the rule data for resolving token names.
813 
814    SELECT rule_id, name, template_token BULK COLLECT INTO v_RuleId, v_RuleName, v_TemplateToken
815      FROM cz_rules
816     WHERE deleted_flag = '0'
820    FOR i IN 1..v_RuleId.COUNT LOOP
817       AND disabled_flag = '0'
818       AND rule_id < 1000;
819 
821 
822      h_RuleName(v_RuleId(i)) := v_RuleName(i);
823      h_TemplateToken(v_RuleId(i)) := v_TemplateToken(i);
824    END LOOP;
825 
826    --Intitialize the explosion data.
827 
828    SELECT model_ref_expl_id, parent_expl_node_id, component_id, referring_node_id, ps_node_type
829      BULK COLLECT INTO v_NodeId, v_ParentId, v_ComponentId, v_ReferringId, v_NodeType
830      FROM cz_model_ref_expls
831     WHERE model_id = p_devl_project_id
832       AND deleted_flag = '0';
833 
834    FOR i IN 1..v_NodeId.COUNT LOOP
835 
836      h_ParentId(v_NodeId(i)) := v_ParentId(i);
837      h_NodeType(v_NodeId(i)) := v_NodeType(i);
838      h_ReferringId(v_NodeId(i)) := v_ReferringId(i);
839      h_ComponentId(v_NodeId(i)) := v_ComponentId(i);
840    END LOOP;
841 
842    IF(p_rule_id IS NOT NULL)THEN
843 
844      populate_rule_text(p_rule_id);
845    ELSE
846 
847      FOR c_rule IN (SELECT rule_id FROM cz_rules
848                      WHERE deleted_flag = '0'
849                        AND devl_project_id = p_devl_project_id
850                        AND rule_type IN (100, 200)) LOOP
851        populate_rule_text(c_rule.rule_id);
852      END LOOP;
853    END IF;
854 END parse_rules;
855 
856 END cz_rule_text_gen ;