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