[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 ;