DBA Data[Home] [Help]

PACKAGE BODY: APPS.CZ_LOGIC_GEN

Source


1 PACKAGE BODY CZ_LOGIC_GEN AS
2 /*      $Header: czlcegnb.pls 120.37.12020000.5 2013/01/11 21:39:21 smanna ship $                */
3 ---------------------------------------------------------------------------------------
4 TYPE tShortStringArray      IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;
5 TYPE tIntegerArray          IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; --kdande; Bug 6881902; 11-Mar-2008
6 TYPE tIntegerArray_idx_vc2  IS TABLE OF NUMBER INDEX BY VARCHAR2(15);
7 TYPE refCursor              IS REF CURSOR;
8 OperatorLiterals            tShortStringArray;
9 OperatorLetters             tShortStringArray;
10 CodeByCodeLookup            tIntegerArray;
11 GenHeader                   VARCHAR2(100) := '$Header: czlcegnb.pls 120.37.12020000.5 2013/01/11 21:39:21 smanna ship $';
12 
13 DATATYPE_TRANSLATABLE_PROP  CONSTANT PLS_INTEGER := 8;
14 CZ_SEQUENCE_INCREMENT       CONSTANT NUMBER := 20;
15 ---------------------------------------------------------------------------------------
16 PROCEDURE GENERATE_LOGIC_(inDevlProjectId IN NUMBER,
17                           thisRunId       IN OUT NOCOPY NUMBER,
18                           TwoPhaseCommit  IN PLS_INTEGER)
19 IS
20 
21   TYPE tStringArray       IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
22   TYPE tNumberArray       IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; --kdande; Bug 6881902; 11-Mar-2008
23   TYPE tNumberArray_idx_vc2 IS TABLE OF NUMBER INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
24   TYPE tDateArray         IS TABLE OF DATE INDEX BY BINARY_INTEGER;
25   TYPE table_of_number_tables IS TABLE OF tNumberArray INDEX BY BINARY_INTEGER;
26   TYPE table_of_tNumberArray_idx_vc2 IS TABLE OF tNumberArray_idx_vc2 INDEX BY BINARY_INTEGER;  -- jonatara:bug7041718
27   TYPE tVarcharHashType   IS TABLE OF VARCHAR2(4000) INDEX BY VARCHAR2(4000);
28 
29   TYPE tPsNodeId          IS TABLE OF cz_ps_nodes.ps_node_id%TYPE INDEX BY VARCHAR2(15);
30   TYPE tItemId            IS TABLE OF cz_ps_nodes.item_id%TYPE INDEX BY BINARY_INTEGER;
31   TYPE tPersistentId      IS TABLE OF cz_ps_nodes.persistent_node_id%TYPE INDEX BY BINARY_INTEGER;
32   TYPE tPersistentId_idx_vc2  IS TABLE OF cz_ps_nodes.persistent_node_id%TYPE INDEX BY VARCHAR2(15);
33   TYPE tPsNodeType        IS TABLE OF cz_ps_nodes.ps_node_type%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
34   TYPE tInitialValue      IS TABLE OF cz_ps_nodes.initial_value%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
35   TYPE tParentId          IS TABLE OF cz_ps_nodes.parent_id%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
36   TYPE tMinimum           IS TABLE OF cz_ps_nodes.minimum%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
37   TYPE tMaximum           IS TABLE OF cz_ps_nodes.maximum%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
38   TYPE tVirtualFlag       IS TABLE OF cz_ps_nodes.virtual_flag%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
39   TYPE tFeatureType       IS TABLE OF cz_ps_nodes.feature_type%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
40   TYPE tName              IS TABLE OF cz_ps_nodes.name%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
41   TYPE tDescriptionId     IS TABLE OF cz_ps_nodes.intl_text_id%TYPE INDEX BY BINARY_INTEGER;
42   TYPE tMinimumSel        IS TABLE OF cz_ps_nodes.minimum_selected%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
43   TYPE tMaximumSel        IS TABLE OF cz_ps_nodes.maximum_selected%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
44   TYPE tBomRequired       IS TABLE OF cz_ps_nodes.bom_required_flag%TYPE INDEX BY BINARY_INTEGER;
45   TYPE tReferenceId       IS TABLE OF cz_ps_nodes.reference_id%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
46   TYPE tUsageMask         IS TABLE OF cz_ps_nodes.effective_usage_mask%TYPE INDEX BY BINARY_INTEGER;
47   TYPE tDecimalQty        IS TABLE OF cz_ps_nodes.decimal_qty_flag%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
48   TYPE tIbTrackable       IS TABLE OF cz_ps_nodes.ib_trackable%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
49   TYPE tAccumulator       IS TABLE OF cz_ps_nodes.accumulator_flag%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
50   TYPE tInitialNumValue   IS TABLE OF cz_ps_nodes.initial_num_value%TYPE INDEX BY BINARY_INTEGER;
51   TYPE tInstantiableFlag  IS TABLE OF cz_ps_nodes.instantiable_flag%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
52   TYPE tShippableFlag     IS TABLE OF cz_ps_nodes.shippable_item_flag%TYPE INDEX BY BINARY_INTEGER;
53   TYPE tTransactableFlag  IS TABLE OF cz_ps_nodes.inventory_transactable_flag%TYPE INDEX BY BINARY_INTEGER;
54   TYPE tAtoFlag           IS TABLE OF cz_ps_nodes.assemble_to_order_flag%TYPE INDEX BY BINARY_INTEGER;
55   TYPE tSerializableFlag  IS TABLE OF cz_ps_nodes.serializable_item_flag%TYPE INDEX BY BINARY_INTEGER;
56 
57   TYPE tSetEffFrom        IS TABLE OF cz_effectivity_sets.effective_from%TYPE INDEX BY BINARY_INTEGER;
58   TYPE tSetEffUntil       IS TABLE OF cz_effectivity_sets.effective_until%TYPE INDEX BY BINARY_INTEGER;
59   TYPE tSetEffId          IS TABLE OF cz_effectivity_sets.effectivity_set_id%TYPE INDEX BY BINARY_INTEGER;
60   TYPE tSetName           IS TABLE OF cz_effectivity_sets.name%TYPE INDEX BY BINARY_INTEGER;
61 
62   TYPE tHeaderId          IS TABLE OF cz_lce_headers.lce_header_id%TYPE INDEX BY VARCHAR2(15);
63   TYPE tExplNodeId        IS TABLE OF cz_model_ref_expls.component_id%TYPE INDEX BY BINARY_INTEGER; --kdande; Bug 6881902; 11-Mar-2008
64   TYPE tExplNodeId_idx_vc2 IS TABLE OF cz_model_ref_expls.component_id%TYPE INDEX BY VARCHAR2(15); --kdande; Bug 6881902; 11-Mar-2008
65 
66   TYPE tExprType          IS TABLE OF cz_expression_nodes.expr_type%TYPE INDEX BY BINARY_INTEGER;
67   TYPE tExprSubtype       IS TABLE OF cz_expression_nodes.expr_subtype%TYPE INDEX BY BINARY_INTEGER;
68   TYPE tExprId            IS TABLE OF cz_expression_nodes.expr_node_id%TYPE INDEX BY BINARY_INTEGER;
69   TYPE tExprParentId      IS TABLE OF cz_expression_nodes.expr_parent_id%TYPE INDEX BY BINARY_INTEGER;
70   TYPE tExprTemplateId    IS TABLE OF cz_expression_nodes.template_id%TYPE INDEX BY BINARY_INTEGER;
71   TYPE tExprParamIndex    IS TABLE OF cz_expression_nodes.param_index%TYPE INDEX BY BINARY_INTEGER;
72   TYPE tExprArgumentIndex IS TABLE OF cz_expression_nodes.argument_index%TYPE INDEX BY BINARY_INTEGER;
73   TYPE tExprArgumentName  IS TABLE OF cz_expression_nodes.argument_name%TYPE INDEX BY BINARY_INTEGER;
74   TYPE tExprDataType      IS TABLE OF cz_expression_nodes.data_type%TYPE INDEX BY BINARY_INTEGER;
75   TYPE tExpressId         IS TABLE OF cz_expression_nodes.express_id%TYPE INDEX BY BINARY_INTEGER;
76   TYPE tExprDataValue     IS TABLE OF cz_expression_nodes.data_value%TYPE INDEX BY BINARY_INTEGER;
77   TYPE tExprPropertyId    IS TABLE OF cz_expression_nodes.property_id%TYPE INDEX BY BINARY_INTEGER;
78   TYPE tPresentType       IS TABLE OF cz_expressions.present_type%TYPE INDEX BY BINARY_INTEGER;
79   TYPE tOptionId          IS TABLE OF cz_des_chart_cells.secondary_opt_id%TYPE INDEX BY BINARY_INTEGER;
80   TYPE tConsequentFlag    IS TABLE OF cz_expression_nodes.consequent_flag%TYPE INDEX BY BINARY_INTEGER;
81   TYPE tDesFeatureType    IS TABLE OF cz_des_chart_features.feature_type%TYPE INDEX BY BINARY_INTEGER;
82   TYPE tExprDataNumValue  IS TABLE OF cz_expression_nodes.data_num_value%TYPE INDEX BY BINARY_INTEGER;
83   TYPE tExprArgSignature  IS TABLE OF cz_expression_nodes.argument_signature_id%TYPE INDEX BY BINARY_INTEGER;
84   TYPE tExprParSignature  IS TABLE OF cz_expression_nodes.param_signature_id%TYPE INDEX BY BINARY_INTEGER;
85 
86   TYPE tRuleId            IS TABLE OF cz_rules.rule_id%TYPE INDEX BY BINARY_INTEGER;
87   TYPE tRuleName          IS TABLE OF cz_rules.name%TYPE INDEX BY BINARY_INTEGER;
88 
89   TYPE tArgumentName      IS TABLE OF cz_signature_arguments.argument_name%TYPE INDEX BY BINARY_INTEGER;
90   TYPE tArgumentIndex     IS TABLE OF cz_signature_arguments.argument_index%TYPE INDEX BY BINARY_INTEGER;
91   TYPE tDataType          IS TABLE OF cz_signature_arguments.data_type%TYPE INDEX BY BINARY_INTEGER;
92 
93   commit_counter       PLS_INTEGER := 0;
94   CommitBlockSize      PLS_INTEGER;
95   OptimizeNotTrue      PLS_INTEGER;
96   OptimizeAllAnyOf     PLS_INTEGER;
97   GenerateGatedCombo   PLS_INTEGER;
98   ChangeChildrenOrder  PLS_INTEGER;
99   StopOnFatalRuleError PLS_INTEGER;
100   GenerateUpdatedOnly  PLS_INTEGER;
101   StoreNlsCharacters   VARCHAR2(16) := NlsNumericCharacters;
102 
103   rootProjectName      cz_devl_projects.name%TYPE;
104   rootProjectType      cz_devl_projects.model_type%TYPE;
105 
106   NewHeaders           tIntegerArray;
107   OldHeaders           tIntegerArray;
108   NewHeadersComponents tIntegerArray;
109   NewHeadersExplosions tIntegerArray;
110   counterNewHeaders    PLS_INTEGER := 1;
111 
112   IsLogicGenerated     tIntegerArray_idx_vc2;
113   modelChecked         tIntegerArray_idx_vc2;
114   vSeqNbrByHeader      tNumberArray_idx_vc2; --kdande; Bug 6881902; 11-Mar-2008
115   v_HeaderByAccId      tHeaderId;
116   v_HeaderByNotTrueId  tHeaderId;
117   h_HeaderPiDefined    tStringArray;
118   h_HeaderEDefined     tStringArray;
119 
120   memoryTemplateStart  tIntegerArray;
121   memoryTemplateEnd    tIntegerArray;
122   v_tTmplNodeId        tExplNodeId;
123   v_tTmplType          tExprType;
124   v_tTmplSubtype       tExprSubtype;
125   v_tTmplId            tExprId;
126   v_tTmplParentId      tExprParentId;
127   v_tTmplTemplateId    tExprTemplateId;
128   v_tTmplExpressId     tExpressId;
129   v_tTmplPsNodeId      tExplNodeId;
130   v_tTmplDataValue     tExprDataValue;
131   v_tTmplDataType      tExprDataType;
132   v_tTmplPropertyId    tExprPropertyId;
133   v_tTmplArgumentIndex tExprArgumentIndex;
134   v_tTmplArgumentName  tExprArgumentName;
135   v_tTmplConsequent    tConsequentFlag;
136 
137   t_RuleId             tRuleId;
138   t_SignatureId        tRuleId;
139   t_RuleName           tRuleName;
140   h_SeededName         tRuleName;
141   h_ReportName         tRuleName;
142   h_SignatureId        tRuleId;
143   h_SignatureDataType  tIntegerArray;
144 
145   glPsNodeId           tPsNodeId;
146   glItemId             tItemId;
147   glPersistentId       tPersistentId_idx_vc2;
148   glReferenceId        tReferenceId;
149   glPsNodeType         tPsNodeType;
150   glIndexByPsNodeId    tIntegerArray_idx_vc2;
151   glLastChildIndex     tIntegerArray_idx_vc2;
152   glParentId           tParentId;
153   glFeatureType        tFeatureType;
154   glName               tName;
155   glBomRequired        tBomRequired;
156   glHeaderByPsNodeId   tNumberArray_idx_vc2; --kdande; Bug 6881902; 11-Mar-2008
157   glEffFrom            tDateArray;
158   glEffUntil           tDateArray;
159   glUsageMask          tUsageMask;
160   glMinimum            tMinimum;
161   glMaximum            tMaximum;
162   glMinimumSel         tMinimumSel;
163   glMaximumSel         tMaximumSel;
164   glVirtualFlag        tVirtualFlag;
165   glDecimalQty         tDecimalQty;
166   glIbTrackable        tIbTrackable;
167   glInitialValue       tInitialValue;
168   glAccumulator        tAccumulator;
169   glInitialNumValue    tInitialNumValue;
170   glInstantiableFlag   tInstantiableFlag;
171   featOptionsCount     tIntegerArray_idx_vc2;
172 
173   v_NodeIdByComponent  tExplNodeId_idx_vc2; --kdande; Bug 6881902; 11-Mar-2008
174 
175 --Support for effectivity sets
176   gvEffFrom            tSetEffFrom;
177   gvEffUntil           tSetEffUntil;
178   gvSetId              tSetEffId;
179   gvIndexBySetId       tIntegerArray;
180 
181   globalCount          PLS_INTEGER := 1;
182  --Just to support debugging
183   nDebug               PLS_INTEGER := 7777777;
184  --Auxiliery parameters for reporting
185   nParam               NUMBER; --kdande; Bug 6881902; 11-Mar-2008
186   errorMessage         VARCHAR2(4000);
187   thisName             VARCHAR2(4000);
188   parentName           VARCHAR2(4000);
189 
190 --Referencing level indicator and model stack
191   globalLevel          PLS_INTEGER := 0;
192   globalStack          tIntegerArray;
193   globalRef            tIntegerArray;
194   globalInstance       tIntegerArray;
195   instanceModel        tIntegerArray_idx_vc2;
196   trackableAncestor    tIntegerArray_idx_vc2;
197 
198 --Set of data for implementing the locking mechanism
199   l_msg_data           VARCHAR2(4000);
200   l_msg_count          NUMBER := 0;
201   l_return_status      VARCHAR2(1);
202   l_lock_status        VARCHAR2(1) := FND_API.G_RET_STS_SUCCESS;
203   l_locked_models      cz_security_pvt.number_type_tbl;
204   FAILED_TO_LOCK_MODEL EXCEPTION;
205 
206  --bug fix 8689041 Modified the criteria to retrieve last_logic_update and logic creation_date
207   logicSQL  VARCHAR2(4000) := 'SELECT proj.devl_project_id, max(proj.last_logic_update),max(head.creation_date)' ||
208                               '  FROM cz_devl_projects proj, cz_model_ref_expls expl, cz_lce_headers head' ||
209                               ' WHERE proj.deleted_flag = ''' || FLAG_NOT_DELETED ||
210                               ''' AND expl.deleted_flag = ''' || FLAG_NOT_DELETED ||
211                               ''' AND head.deleted_flag = ''' || FLAG_NOT_DELETED ||
212                               ''' AND expl.node_depth = 1' ||
213                               '   AND expl.model_id = :1' ||
214                               '   AND head.net_type in (1,2)' ||
215                               '   AND proj.devl_project_id = expl.component_id' ||
216                               '   AND proj.devl_project_id = head.component_id' ||
217                               '   AND head.component_id = head.devl_project_id' ||
218                               '   GROUP BY proj.devl_project_id';
219 
220 
221   h_containerReferred  tIntegerArray_idx_vc2;
222   containerReferred    VARCHAR2(4000) :=
223 
224     'SELECT 1 FROM DUAL WHERE EXISTS' ||
225     '  (SELECT model_id FROM cz_model_ref_expls' ||
226     '    WHERE deleted_flag = ''' || FLAG_NOT_DELETED || '''' ||
227     '      AND ps_node_type IN (' || PS_NODE_TYPE_REFERENCE || ', ' || PS_NODE_TYPE_CONNECTOR || ')' ||
228     '      AND component_id = :1' ||
229     '      AND (SELECT model_type FROM cz_devl_projects' ||
230     '            WHERE devl_project_id = model_id) = ''' || MODEL_TYPE_CONTAINER_MODEL || ''')';
231 
232   GENERATION_REQUIRED         CONSTANT PLS_INTEGER := 1;
233   GENERATION_NOT_REQUIRED     CONSTANT PLS_INTEGER := 2;
234 
235   table_name_generator        PLS_INTEGER := 1;
236   table_hash_propval          tVarcharHashType;
237 ---------------------------------------------------------------------------------------
238 --Bug #5727549.
239 
240 last_id_allocated  NUMBER := NULL;
241 next_id_to_use     NUMBER := 0;
242 
243 FUNCTION next_lce_header_id RETURN NUMBER IS
244   id_to_return  NUMBER;
245 BEGIN
246   IF((last_id_allocated IS NULL) OR
247      (next_id_to_use = (NVL(last_id_allocated, 0) + CZ_SEQUENCE_INCREMENT)))THEN
248 
249     SELECT cz_lce_headers_s.NEXTVAL INTO last_id_allocated FROM DUAL;
250     next_id_to_use := last_id_allocated;
251   END IF;
252 
253   id_to_return := next_id_to_use;
254   next_id_to_use := next_id_to_use + 1;
255  RETURN id_to_return;
256 END next_lce_header_id;
257 ---------------------------------------------------------------------------------------
258 --Reporting procedure
259 
260 PROCEDURE REPORT(inMessage IN VARCHAR2, inUrgency IN PLS_INTEGER) IS
261 BEGIN
262 
263   INSERT INTO cz_db_logs (message, statuscode, caller, urgency, run_id)
264   VALUES (inMessage, nDebug, 'Logic Generator', inUrgency, thisRunId);
265 
266 EXCEPTION
267   WHEN OTHERS THEN
268     RAISE CZ_G_UNABLE_TO_REPORT_ERROR;
269 END;
270 ---------------------------------------------------------------------------------------
271 PROCEDURE SET_NLS_CHARACTERS(p_nls_characters IN VARCHAR2) IS
272 BEGIN
273   IF(NlsNumericCharacters <> StoreNlsCharacters)THEN
274 
275     EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ''' || p_nls_characters || '''';
276   END IF;
277 END;
278 ---------------------------------------------------------------------------------------
279 PROCEDURE GENERATE_COMPONENT_TREE(inComponentId         IN NUMBER,
280                                   inProjectId           IN NUMBER,
281                                   inParentLogicHeaderId IN NUMBER)
282 IS
283 
284  TYPE tNodeDepth      IS TABLE OF cz_model_ref_expls.node_depth%TYPE INDEX BY BINARY_INTEGER;
285  TYPE tNodeType       IS TABLE OF cz_model_ref_expls.ps_node_type%TYPE INDEX BY BINARY_INTEGER;
286  TYPE tVirtualFlag    IS TABLE OF cz_model_ref_expls.virtual_flag%TYPE INDEX BY BINARY_INTEGER;
287  TYPE tParentId       IS TABLE OF cz_model_ref_expls.component_id%TYPE INDEX BY BINARY_INTEGER;
288  TYPE tPsNodeId       IS TABLE OF cz_model_ref_expls.component_id%TYPE INDEX BY BINARY_INTEGER;
289  TYPE tChildModelExpl IS TABLE OF cz_model_ref_expls.child_model_expl_id%TYPE INDEX BY BINARY_INTEGER;
290  TYPE tExplNodeType   IS TABLE OF cz_model_ref_expls.expl_node_type%TYPE INDEX BY BINARY_INTEGER;
291  --kdande; Bug 6881902; 11-Mar-2008; Made the following PLSQL types local to the procedure as they are used for Bulk Collects
292  TYPE tPsNodeType     IS TABLE OF cz_ps_nodes.ps_node_type%TYPE INDEX BY BINARY_INTEGER;
293  TYPE tReferenceId    IS TABLE OF cz_ps_nodes.reference_id%TYPE INDEX BY BINARY_INTEGER;
294  TYPE tDecimalQty     IS TABLE OF cz_ps_nodes.decimal_qty_flag%TYPE INDEX BY BINARY_INTEGER;
295  TYPE tIbTrackable    IS TABLE OF cz_ps_nodes.ib_trackable%TYPE INDEX BY BINARY_INTEGER;
296  TYPE tAccumulator    IS TABLE OF cz_ps_nodes.accumulator_flag%TYPE INDEX BY BINARY_INTEGER;
297  TYPE tInstantiableFlag  IS TABLE OF cz_ps_nodes.instantiable_flag%TYPE INDEX BY BINARY_INTEGER;
298  TYPE tFeatureType       IS TABLE OF cz_ps_nodes.feature_type%TYPE INDEX BY BINARY_INTEGER;
299  TYPE tName              IS TABLE OF cz_ps_nodes.name%TYPE INDEX BY BINARY_INTEGER;
300  TYPE tInitialValue      IS TABLE OF cz_ps_nodes.initial_value%TYPE INDEX BY BINARY_INTEGER;
301  TYPE tMinimum           IS TABLE OF cz_ps_nodes.minimum%TYPE INDEX BY BINARY_INTEGER;
302  TYPE tMaximum           IS TABLE OF cz_ps_nodes.maximum%TYPE INDEX BY BINARY_INTEGER;
303  TYPE tMinimumSel        IS TABLE OF cz_ps_nodes.minimum_selected%TYPE INDEX BY BINARY_INTEGER;
304  TYPE tMaximumSel        IS TABLE OF cz_ps_nodes.maximum_selected%TYPE INDEX BY BINARY_INTEGER;
305 
306  ntPsNodeId           tPsNodeId;
307  ntItemId             tItemId;
308  ntPersistentId       tPersistentId;
309  ntPsNodeType         tPsNodeType;
310  ntInitialValue       tInitialValue;
311  ntParentId           tParentId;
312  ntMinimum            tMinimum;
313  ntMaximum            tMaximum;
314  ntVirtualFlag        tVirtualFlag;
315  ntFeatureType        tFeatureType;
316  ntName               tName;
317  ntDescriptionId      tDescriptionId;
318  ntMinimumSel         tMinimumSel;
319  ntMaximumSel         tMaximumSel;
320  ntBomRequired        tBomRequired;
321  ntReferenceId        tReferenceId;
322  dtEffFrom            tDateArray;
323  dtEffUntil           tDateArray;
324  vtUsageMask          tUsageMask;
325  ntEffSetId           tSetEffId;
326  ntDecimalQty         tDecimalQty;
327  ntIbTrackable        tIbTrackable;
328  ntAccumulator        tAccumulator;
329  ntInitialNumValue    tInitialNumValue;
330  ntInstantiableFlag   tInstantiableFlag;
331  ntShippableFlag      tShippableFlag;
332  ntTransactableFlag   tTransactableFlag;
333  ntAtoFlag            tAtoFlag;
334  ntSerializableFlag   tSerializableFlag;
335 
336  v_tNodeDepth         tNodeDepth;
337  v_tNodeType          tNodeType;
338  v_tVirtualFlag       tVirtualFlag;
339  v_tParentId          tParentId;
340  v_tPsNodeId          tPsNodeId;
341  v_tReferringId       tPsNodeId;
342  v_tChildModelExpl    tChildModelExpl;
343  v_tExplNodeType      tExplNodeType;
344  v_NodeId             tExplNodeId;
345 
346  v_IndexByNodeId      tIntegerArray_idx_vc2;
347  v_TypeByExplId       tExplNodeType;
348 
349  thisComponentExplId  cz_model_ref_expls.model_ref_expl_id%TYPE;
350  thisProjectId        cz_devl_projects.devl_project_id%TYPE;
351  thisProjectName      cz_devl_projects.name%TYPE;
352  thisProjectType      cz_devl_projects.model_type%TYPE;
353  thisRootExplIndex    PLS_INTEGER;
354 
355  nStructureHeaderId   cz_lce_headers.lce_header_id%TYPE;
356  PrevEffFrom          DATE := EpochBeginDate;
357  PrevEffUntil         DATE := EpochEndDate;
358  PrevUsageMask        cz_ps_nodes.effective_usage_mask%TYPE := AnyUsageMask;
359  CurrentEffFrom       DATE;
360  CurrentEffUntil      DATE;
361  CurrentUsageMask     cz_ps_nodes.effective_usage_mask%TYPE;
362  FeatureEffFrom       DATE;
363  FeatureEffUntil      DATE;
364  FeatureUsageMask     cz_ps_nodes.effective_usage_mask%TYPE;
365  nSequenceNbr         NUMBER := 1;
366  vLogicText           VARCHAR2(4000);
367  vLogicLine           VARCHAR2(4000);
368  vLogicName           VARCHAR2(4000);
369 
370  CurrentFromDate      VARCHAR2(25);
371  CurrentUntilDate     VARCHAR2(25);
372  localMinString       VARCHAR2(25);
373  localMaxString       VARCHAR2(25);
374 
375  CurrentlyPacking     PLS_INTEGER;
376  LastPacked           PLS_INTEGER := PACKING_GENERIC;
377  generatingFeature    PLS_INTEGER := 0;
378 
379  i                    PLS_INTEGER;
380  j                    PLS_INTEGER;
381  localCount           PLS_INTEGER;
382  optionCounter        PLS_INTEGER;
383  trackableContext     NUMBER; -- jonatara:bug7041718
384  instantiableContext  NUMBER; -- jonatara:bug7041718
385 
386  -- LA 13733007 : OC with No children
387  TYPE tNoChildOCName        IS TABLE OF cz_ps_nodes.name%TYPE INDEX BY BINARY_INTEGER;
388  TYPE tNoChildOCModelName   IS TABLE OF cz_rp_entries.name%TYPE INDEX BY BINARY_INTEGER;
389  lNoChildOCName        tNoChildOCName ;
390  lNoChildOCModelName   tNoChildOCModelName;
391 
392 ---------------------------------------------------------------------------------------
393  PROCEDURE PACK IS
394  BEGIN
395     IF(vLogicLine IS NOT NULL)THEN
396      IF(LENGTHB(vLogicText) + LENGTHB(vLogicLine)>2000)THEN
397 
398        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
399         (nStructureHeaderId, nSequenceNbr, vLogicText);
400        vLogicText := NULL;
401        nSequenceNbr := nSequenceNbr + 1;
402 
403        --Commit in blocks if not disabled
404 
405        IF(TwoPhaseCommit = 0)THEN
406          commit_counter := commit_counter + 1;
407          IF(commit_counter = CommitBlockSize)THEN
408           COMMIT;
409           commit_counter := 0;
410          END IF;
411        END IF;
412      END IF;
413      vLogicText := vLogicText || vLogicLine;
414      vLogicLine := NULL;
415 
416      LastPacked := PACKING_GENERIC;
417 
418     END IF;
419  END PACK;
420 ---------------------------------------------------------------------------------------
421  PROCEDURE PACK_EFFECTIVITY IS
422  BEGIN
423     IF(vLogicLine IS NOT NULL)THEN
424      IF(LENGTHB(vLogicText) + LENGTHB(vLogicLine)>2000)THEN
425 
426        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
427         (nStructureHeaderId, nSequenceNbr, vLogicText);
428        vLogicText := NULL;
429        nSequenceNbr := nSequenceNbr + 1;
430 
431        --Commit in blocks if not disabled
432 
433        IF(TwoPhaseCommit = 0)THEN
434          commit_counter := commit_counter + 1;
435          IF(commit_counter = CommitBlockSize)THEN
436           COMMIT;
437           commit_counter := 0;
438          END IF;
439        END IF;
440      END IF;
441 
442      IF(LastPacked = PACKING_EFFECTIVITY AND CurrentlyPacking = LastPacked)THEN
443 
444       --We are inserting one effectivity statement after another. Replace the last
445       --one with the current one.
446 
447       vLogicText := SUBSTR(vLogicText, 1, INSTR(vLogicText, 'EFF', -1, 1) - 1) || vLogicLine;
448 
449      ELSE
450        vLogicText := vLogicText || vLogicLine;
451      END IF;
452 
453      vLogicLine := NULL;
454      LastPacked := CurrentlyPacking;
455 
456     END IF;
457  END PACK_EFFECTIVITY;
458 ---------------------------------------------------------------------------------------
459 PROCEDURE GENERATE_EFFECTIVITY_LOGIC(inCurrentEffFrom   IN DATE,
460                                      inCurrentEffUntil  IN DATE,
461                                      inCurrentUsageMask IN VARCHAR2) IS
462 BEGIN
463   IF((inCurrentEffFrom <> PrevEffFrom) OR (inCurrentEffUntil <> PrevEffUntil) OR
464      (inCurrentUsageMask <> PrevUsageMask))THEN
465 
466        vLogicLine := LTRIM(inCurrentUsageMask, '0');
467        IF(vLogicLine IS NOT NULL) THEN
468          vLogicLine := EffUsagePrefix || vLogicLine;
469        END IF;
470 
471        IF(inCurrentEffFrom = EpochBeginDate)THEN
472          CurrentFromDate := NULL;
473        ELSE
474          CurrentFromDate := TO_CHAR(inCurrentEffFrom, EffDateFormat);
475        END IF;
476 
477        IF(inCurrentEffUntil = EpochEndDate)THEN
478          CurrentUntilDate := NULL;
479        ELSE
480          CurrentUntilDate := TO_CHAR(inCurrentEffUntil, EffDateFormat);
481        END IF;
482 
483        vLogicLine := 'EFF ' || CurrentFromDate || ', ' || CurrentUntilDate || ', ' || vLogicLine || NewLine;
484 
485        CurrentlyPacking := PACKING_EFFECTIVITY;
486        PACK_EFFECTIVITY;
487 
488        PrevEffFrom := inCurrentEffFrom;
489        PrevEffUntil := inCurrentEffUntil;
490        PrevUsageMask := inCurrentUsageMask;
491   END IF;
492 END;
493 ---------------------------------------------------------------------------------------
494 --This procedure is used for marking BOM items that are ancestors of a trackable BOM
495 --item. Such items cannot have default quantity greater than 1, and cannot be on the
496 --RHS of a numeric rule.
497 --The procedure can be called only for a BOM Option Class or Standard or a reference,
498 --so parent always exists.
499 
500 PROCEDURE PROPAGATE_TRACKABLE_ANCESTOR IS
501 
502   auxIndex  NUMBER := glIndexByPsNodeId(ntParentId(i));  --kdande; Bug 6881902; 11-Mar-2008
503 BEGIN
504   WHILE((NOT trackableAncestor.EXISTS(glPsNodeId(auxIndex))) AND
505         glPsNodeType(auxIndex) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))LOOP
506 
507     IF(glInitialValue(auxIndex) > 1)THEN
508 
509       nParam := auxIndex;
510       RAISE CZ_S_INCORRECT_QUANTITY;
511     END IF;
512 
513     trackableAncestor(glPsNodeId(auxIndex)) := 1;
514     EXIT WHEN glParentId(auxIndex) IS NULL;
515 
516     auxIndex := glIndexByPsNodeId(glParentId(auxIndex));
517   END LOOP;
518 END;
519 ---------------------------------------------------------------------------------------
520 FUNCTION IS_NODE_LOGICAL(j IN PLS_INTEGER) RETURN BOOLEAN IS
521   l_node_type  NUMBER := ntPsNodeType(j);
522 BEGIN
523   RETURN
524     l_node_type <> PS_NODE_TYPE_TOTAL AND l_node_type <> PS_NODE_TYPE_RESOURCE AND
525     (l_node_type <> PS_NODE_TYPE_FEATURE OR
526        ntFeatureType(j) IN (PS_NODE_FEATURE_TYPE_BOOLEAN, PS_NODE_FEATURE_TYPE_OPTION) OR
527          (ntFeatureType(j) = PS_NODE_FEATURE_TYPE_INTEGER AND
528           ntMinimum(j) IS NOT NULL AND ntMinimum(j) >= 0));
529 END;
530 ---------------------------------------------------------------------------------------
531 PROCEDURE GENERATE_ACCUMULATOR(j IN PLS_INTEGER) IS
532 BEGIN
533 
534   --Check if we need to create an accumulator for this node. Note that accumulator must be
535   --always effective. Part of the fix for the bug #2857955.
536 
537   IF(ntAccumulator(j) IS NOT NULL AND ntAccumulator(j) <> FLAG_NO_ACCUMULATOR)THEN
538 
539     GENERATE_EFFECTIVITY_LOGIC(EpochBeginDate, EpochEndDate, AnyUsageMask);
540     vLogicName := 'P_' || TO_CHAR(ntPersistentId(j));
541 
542     IF((NOT v_HeaderByAccId.EXISTS(ntPsNodeId(j))) AND
543        TO_NUMBER(UTL_RAW.BIT_AND(ntAccumulator(j), FLAG_ACCUMULATOR_ACC)) = TO_NUMBER(FLAG_ACCUMULATOR_ACC))THEN
544 
545       vLogicLine := 'TOTAL ' || vLogicName || '_ACC' || NewLine ||
546                     'INC ' || vLogicName || '_ACC' || ' ' || vLogicName ||
547                     OperatorLiterals(OPERATOR_ROUND) || NewLine;
548 
549       v_HeaderByAccId(ntPsNodeId(j)) := nStructureHeaderId;
550     END IF;
551 
552     IF((NOT v_HeaderByNotTrueId.EXISTS(ntPsNodeId(j))) AND
553        TO_NUMBER(UTL_RAW.BIT_AND(ntAccumulator(j), FLAG_ACCUMULATOR_NT)) = TO_NUMBER(FLAG_ACCUMULATOR_NT))THEN
554 
555       --Bug #5015333. Only node that has a 'logical' value can have this type of accumulator. Initially the
556       --accumulator_flag may have been set by a NOTTRUE operator. At this time the node had to have logical
557       --value, otherwise the rule would have been rejected by a verification (HAS_LOGICAL_VALUE function in
558       --GENERATE_NOTTRUE procedure). However later the rule may have been deleted, and the type of the node
559       --changed, so that the node does not have a 'logical' value anymore. As the accumulator_flag is still
560       --set, the code below will create a 'logical' relation that may crash the engine.
561 
562       IF(IS_NODE_LOGICAL(j))THEN
563 
564         vLogicLine := 'OBJECT ' || vLogicName || '_NT' || NewLine ||
565                       'NOTTRUE ' || vLogicName || ' ' || vLogicName || '_NT' || NewLine;
566         v_HeaderByNotTrueId(ntPsNodeId(j)) := nStructureHeaderId;
567 
568       ELSE
569 
570         --Although it is not necessary to reset the accumulator_flag here, doing so will allow to skip this
571         --verification in the future. This should not have any effect on the currency of the model's logic.
572 
573         UPDATE cz_ps_nodes SET
574              accumulator_flag = TO_CHAR(TO_NUMBER(UTL_RAW.BIT_AND(ntAccumulator(j), FLAG_ACCUMULATOR_ACC)))
575          WHERE ps_node_id = ntPsNodeId(j);
576       END IF;
577     END IF;
578 
579     PACK;
580   END IF;
581 END;
582 ---------------------------------------------------------------------------------------
583 PROCEDURE GENERATE_RULES IS
584 
585  TYPE iteratorNode       IS RECORD (node_type  NUMBER,
586                                     node_id    NUMBER,
587                                     node_value VARCHAR2(4000),
588                                     node_obj   VARCHAR2(4000),
589                                     node_id_ex NUMBER);
590  TYPE tIteratorArray     IS TABLE OF iteratorNode INDEX BY BINARY_INTEGER;
591 
592  --The cursor returns all the rules assigned in this project (model).
593 
594  CURSOR c_rules IS
595   SELECT rule_id, rule_type, antecedent_id, consequent_id, name, reason_id,
596          expr_rule_type, rule_folder_id, component_id, model_ref_expl_id,
597          effective_from, effective_until, effective_usage_mask, effectivity_set_id,
598          unsatisfied_msg_id, unsatisfied_msg_source, presentation_flag, class_name
599   FROM cz_rules
600   WHERE devl_project_id = inComponentId
601     AND deleted_flag = FLAG_NOT_DELETED
602     AND disabled_flag = FLAG_NOT_DISABLED;
603 
604  v_tExplNodeId        tExplNodeId;
605  v_tExprType          tExprType;
606  v_tExprSubtype       tExprSubtype;
607  v_tExprId            tExprId;
608  v_tExprParentId      tExprParentId;
609  v_tExprTemplateId    tExprTemplateId;
610  v_tExprParamIndex    tExprParamIndex;
611  v_tExprArgumentName  tExprArgumentName;
612  v_tExprDataType      tExprDataType;
613  v_tExpressId         tExpressId;
614  v_tExprPsNodeId      tExplNodeId;
615  v_tRealPsNodeId      tExplNodeId;
616  v_tExprDataValue     tExprDataValue;
617  v_tExprPropertyId    tExprPropertyId;
618  v_tConsequentFlag    tConsequentFlag;
619  v_tFeatureType       tDesFeatureType;
620  v_tExprDataNumValue  tExprDataNumValue;
621  v_tExprArgSignature  tExprArgSignature;
622  v_tExprParSignature  tExprParSignature;
623  v_LoadConditionId    tExplNodeId;
624  v_ExplByPsNodeId     tExplNodeId_idx_vc2; --kdande; Bug 6881902; 11-Mar-2008
625 
626  v_tArgumentName      tArgumentName;
627  v_tArgumentIndex     tArgumentIndex;
628  v_tDataType          tDataType;
629 
630  v_InstByLevel        tIntegerArray;
631  v_IndexByExprNodeId  tIntegerArray_idx_vc2;
632  v_Assignable         tIntegerArray;
633  v_Participant        tIntegerArray;
634  v_DistinctIndex      tIntegerArray;
635  v_ParticipantIndex   tIntegerArray;
636  v_RuleConnectorNet   tIntegerArray;
637  v_LevelCount         tIntegerArray;
638  v_LevelIndex         tIntegerArray;
639  v_LevelType          tIntegerArray;
640  v_MarkLoadCondition  tIntegerArray;
641  v_tIsHeaderGenerated tIntegerArray;
642  v_tSequenceNbr       tIntegerArray;
643  v_tLogicNetType      tIntegerArray;
644 
645  v_NodeLogicLevel     tIntegerArray;
646  v_NodeAssignable     tIntegerArray;
647  v_NodeInstantiable   tIntegerArray;
648  v_NodeTrackable      tIntegerArray;
649  v_IsConnectorNet     tIntegerArray;
650  v_ChildrenIndex      tIntegerArray_idx_vc2;
651  v_NumberOfChildren   tIntegerArray_idx_vc2;
652  v_MaxRuleExists      tIntegerArray;
653  v_ProhibitInRules    tIntegerArray;
654  v_ProhibitOptional   tIntegerArray;
655  v_ProhibitConnector  tIntegerArray;
656  v_NodeIndexPath      tIntegerArray;
657  v_NodeDownPath       tStringArray;
658  v_RelativeNodePath   tStringArray;
659  v_AssignedDownPath   tStringArray;
660  v_NodeUpPath         tStringArray;
661  v_RuleQualifiedName  tStringArray;
662  v_FuncQualifiedName  tStringArray;
663 
664  v_LoadHeaders        tHeaderId;
665  v_LoadConditions     tStringArray;
666 
667  h_EffFrom            tDateArray;
668  h_EffUntil           tDateArray;
669  h_EffUsageMask       tUsageMask;
670 
671  PrevRuleEffFrom      tDateArray;
672  PrevRuleEffUntil     tDateArray;
673  PrevRuleUsageMask    tUsageMask;
674 
675  nAntecedentId        cz_rules.antecedent_id%TYPE;
676  nConsequentId        cz_rules.consequent_id%TYPE;
677  nRuleId              cz_rules.rule_id%TYPE;
678  nRuleFolderId        cz_rules.rule_folder_id%TYPE;
679  nRuleType            cz_rules.rule_type%TYPE;
680  RuleTemplateType     cz_rules.rule_type%TYPE;
681  nRuleOperator        cz_rules.expr_rule_type%TYPE;
682  nReasonId            cz_rules.reason_id%TYPE;
683  nComponentId         cz_rules.component_id%TYPE;
684  nModelRefExplId      cz_rules.model_ref_expl_id%TYPE;
685  dEffFrom             cz_rules.effective_from%TYPE;
686  dEffUntil            cz_rules.effective_until%TYPE;
687  nRuleEffSetId        cz_rules.effectivity_set_id%TYPE;
688  nUnsatisfiedId       cz_rules.unsatisfied_msg_id%TYPE;
689  nUnsatisfiedSource   cz_rules.unsatisfied_msg_source%TYPE;
690  nPresentationFlag    cz_rules.presentation_flag%TYPE;
691  vRuleName            cz_rules.name%TYPE;
692  vUsageMask           cz_rules.effective_usage_mask%TYPE;
693  vClassName           cz_rules.class_name%TYPE;
694  MaxDepthId           cz_model_ref_expls.model_ref_expl_id%TYPE;
695  nAux                 cz_model_ref_expls.model_ref_expl_id%TYPE;
696  MaxDepthValue        cz_model_ref_expls.node_depth%TYPE;
697  baseDepthValue       cz_model_ref_expls.node_depth%TYPE;
698  nHeaderId            cz_lce_headers.lce_header_id%TYPE;
699  nPreviousHeaderId    cz_lce_headers.lce_header_id%TYPE;
700  nNewLogicFileFlag    PLS_INTEGER := 0;
701  nRuleAssignedLevel   PLS_INTEGER;
702  MaxDepthIndex        PLS_INTEGER;
703  logicNetType         PLS_INTEGER;
704  expressionSize       PLS_INTEGER;
705  expressionStart      PLS_INTEGER;
706  expressionEnd        PLS_INTEGER;
707  numericLHS           PLS_INTEGER;
708  generateCompare      PLS_INTEGER;
709  generateCollect      PLS_INTEGER;
710 
711  ConnectorIndex       PLS_INTEGER;
712  InstantiableIndex    PLS_INTEGER;
713  OptionalIndex        PLS_INTEGER;
714  AssignableIndex      PLS_INTEGER;
715  TrackableIndex       PLS_INTEGER;
716 
717  jAntecedentRoot      PLS_INTEGER;
718  jConsequentRoot      PLS_INTEGER;
719  jAntecedentRootCount PLS_INTEGER;
720  jConsequentRootCount PLS_INTEGER;
721  ListType             PLS_INTEGER;
722  nLocalDefaults       PLS_INTEGER := 0;
723  nLocalExprId         PLS_INTEGER := 1000;
724 
725  nCounter             PLS_INTEGER;
726  distinctCount        PLS_INTEGER;
727  participantCount     PLS_INTEGER;
728  localFeatureType     PLS_INTEGER;
729  localMinimum         PLS_INTEGER;
730  auxIndex             NUMBER; --kdande; Bug 6881902; 11-Mar-2008
731  auxCount             NUMBER; --kdande; Bug 6881902; 11-Mar-2008
732  localString          VARCHAR2(32000);
733  pathString           VARCHAR2(32000);
734  baseString           VARCHAR2(32000);
735  localNodeId          NUMBER;
736  localRunId           NUMBER;
737 
738  generateRound        PLS_INTEGER;
739  optimizeChain        PLS_INTEGER;
740  optimizeContribute   PLS_INTEGER;
741  optimizeTarget       VARCHAR2(4000);
742  t_prefix             VARCHAR2(128);
743 
744  returnListType       PLS_INTEGER;
745  returnStringArray    tStringArray;
746 
747  parameterScope       tIteratorArray;
748  parameterName        tStringArray;
749 
750  --This type is used when it is necessary to hash a table name by a text key.
751 
752  TYPE temp_table_hash_type IS TABLE OF VARCHAR2(30) INDEX BY VARCHAR2(4000);
753  temp_table_hash      temp_table_hash_type;
754  temp_cmpt_table_hash temp_table_hash_type;
755 
756  --Some of the variables are level specific for embedded FORALL, so we need to know the
757  --the current level. One example is the table hash key below.
758  --COMPATIBLE currently cannot be embedded, so the variable will never be greater than 1.
759 
760  forallLevel          PLS_INTEGER := 0;
761  compatLevel          PLS_INTEGER := 0;
762 
763  --This key is used to identify a temporary table constructed for an iterator and hash its
764  --name in temp_table_hash or temp_cmpt_table_hash.
765  --The format of this key is:
766  --<ps_node_id>-<model_ref_expl_id>-<property_id-1>-...-<property_id_N>
767 
768  --We need tables of keys because of the possibility of embedded FORALL - on every level
769  --the level specific key should be considered.
770  --Although currently FORALL cannot be embedded into COMPATIBLE, this may change in the
771  --future, therefore it is better to have separate keys.
772 
773  temp_table_hash_key  tStringArray;
774  temp_cmpt_hash_key   tStringArray;
775 
776  --This is a universal array accumulating all the temp tables we need to delete across
777  --all FORALL(s) and COMPATIBLE(s).
778 
779  temp_tables          tStringArray;
780 
781  --For logic and comparison rules having an unsatisified message (unsatisfied_msg_source <> 0)
782  --this string will be populated with unsatisfied_msg_id, and used as a part of GS syntax when
783  --the relation has more then one operand on either side. For all the other types of rules the
784  --string will be null.
785 
786  sUnsatisfiedId       VARCHAR2(4000);
787 ---------------------------------------------------------------------------------------
788 FUNCTION GET_PROPERTY_VALUE(p_node_id     IN cz_ps_nodes.ps_node_id%TYPE,
789                             p_property_id IN cz_properties.property_id%TYPE,
790                             p_item_id     IN cz_item_masters.item_id%TYPE,
791                             x_data_type   IN OUT NOCOPY cz_properties.data_type%TYPE)
792   RETURN VARCHAR2 IS
793     l_def_value  cz_properties.def_value%TYPE;
794     l_tab        tStringArray;
795 BEGIN
796 
797   SELECT NVL(TO_CHAR(def_num_value), def_value), data_type INTO l_def_value, x_data_type
798     FROM cz_properties
799    WHERE property_id = p_property_id
800      AND deleted_flag = FLAG_NOT_DELETED;
801 
802   SELECT NVL(TO_CHAR(data_num_value), data_value) BULK COLLECT INTO l_tab
803     FROM cz_ps_prop_vals
804    WHERE ps_node_id = p_node_id
805      AND property_id = p_property_id
806      AND deleted_flag = FLAG_NOT_DELETED;
807 
808   IF(l_tab.COUNT = 0 AND p_item_id IS NOT NULL)THEN
809 
810      SELECT NVL(TO_CHAR(property_num_value), property_value) BULK COLLECT INTO l_tab
811        FROM cz_item_property_values
812       WHERE property_id = p_property_id
813         AND item_id = p_item_id
814         AND deleted_flag = FLAG_NOT_DELETED;
815 
816      IF(l_tab.COUNT = 0)THEN
817 
818          SELECT NULL BULK COLLECT INTO l_tab
819            FROM cz_item_type_properties t, cz_item_masters m
820           WHERE m.item_id = p_item_id
821             AND m.deleted_flag = FLAG_NOT_DELETED
822             AND t.deleted_flag = FLAG_NOT_DELETED
823             AND t.property_id = p_property_id
824             AND t.item_type_id = m.item_type_id;
825      END IF;
826   END IF;
827 
828   IF(l_tab.EXISTS(1))THEN
829 
830     IF(x_data_type = DATATYPE_TRANSLATABLE_PROP)THEN
831 
832       SELECT localized_str INTO l_tab(1) FROM cz_localized_texts
833        WHERE intl_text_id = l_tab(1) AND language = USERENV('LANG');
834 
835       IF(l_tab(1) IS NULL)THEN
836 
837         SELECT localized_str INTO l_tab(1) FROM cz_localized_texts
838          WHERE intl_text_id = l_def_value AND language = USERENV('LANG');
839       END IF;
840     END IF;
841 
842      RETURN NVL(l_tab(1), l_def_value);
843   END IF;
844 
845   x_data_type := NULL;
846   RETURN NULL;
847 
848 EXCEPTION
849   WHEN NO_DATA_FOUND THEN
850     x_data_type := NULL;
851     RETURN NULL;
852 END;
853 ---------------------------------------------------------------------------------------
854 --The local procedure is required because the sequence numbers must be different
855 --Still works with global buffers and commit parameters
856 
857  PROCEDURE PACK IS
858  BEGIN
859     IF(vLogicLine IS NOT NULL)THEN
860      IF(LENGTHB(vLogicText) + LENGTHB(vLogicLine)>2000)THEN
861 
862        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
863         (nHeaderId, v_tSequenceNbr(nHeaderId), vLogicText);
864        vLogicText := NULL;
865        v_tSequenceNbr(nHeaderId) := v_tSequenceNbr(nHeaderId) + 1;
866 
867        --Commit in blocks if not disabled
868 
869        IF(TwoPhaseCommit = 0)THEN
870          commit_counter := commit_counter + 1;
871          IF(commit_counter = CommitBlockSize)THEN
872           COMMIT;
873           commit_counter := 0;
874          END IF;
875        END IF;
876      END IF;
877      vLogicText := vLogicText || vLogicLine;
878      vLogicLine := NULL;
879     END IF;
880  END PACK;
881 ---------------------------------------------------------------------------------------
882 --This function returns fully qualified rule name given rule_folder_id of a rule
883 --and puts generated names into a hash table for reuse.
884 
885 FUNCTION RULE_NAME RETURN VARCHAR2 IS
886   vQualified  VARCHAR2(4000) := '.';
887   nRuleName   PLS_INTEGER;
888 BEGIN
889   IF(nRuleFolderId IS NULL OR nRuleFolderId = -1)THEN RETURN vRuleName; END IF;
890   IF(v_RuleQualifiedName.EXISTS(nRuleFolderId))THEN RETURN v_RuleQualifiedName(nRuleFolderId) || vRuleName; END IF;
891   nRuleName := LENGTHB(vRuleName);
892   FOR folder IN (SELECT name FROM cz_rule_folders
893                   WHERE deleted_flag = FLAG_NOT_DELETED
894                     AND parent_rule_folder_id IS NOT NULL
895                   START WITH rule_folder_id = nRuleFolderId
896                     AND object_type = 'RFL'
897                 CONNECT BY PRIOR parent_rule_folder_id = rule_folder_id
898                     AND object_type = 'RFL')LOOP
899      IF(LENGTHB(folder.name) + LENGTHB(vQualified) + 1 < 2000 - nRuleName)THEN
900       vQualified := '.' || folder.name || vQualified;
901      ELSE
902       EXIT;
903      END IF;
904   END LOOP;
905   v_RuleQualifiedName(nRuleFolderId) := vQualified;
906   RETURN vQualified || vRuleName;
907 END;
908 ---------------------------------------------------------------------------------------
909 --This function returns fully qualified name of a functional companion given
910 --rule_folder_id.
911 
912 FUNCTION COMPANION_NAME(inCompanionName IN VARCHAR2, inFolderId IN NUMBER) RETURN VARCHAR2 IS
913   vQualified  VARCHAR2(4000) := '.';
914   nameLen     PLS_INTEGER;
915 BEGIN
916   IF(inFolderId IS NULL OR inFolderId = -1)THEN RETURN inCompanionName; END IF;
917   IF(v_FuncQualifiedName.EXISTS(inFolderId))THEN RETURN v_FuncQualifiedName(inFolderId) || inCompanionName; END IF;
918   nameLen := LENGTHB(inCompanionName);
919   FOR folder IN (SELECT name FROM cz_rule_folders
920                   WHERE deleted_flag = FLAG_NOT_DELETED
921                     AND parent_rule_folder_id IS NOT NULL
922                  START WITH rule_folder_id = inFolderId
923                  CONNECT BY PRIOR parent_rule_folder_id = rule_folder_id)LOOP
924      IF(LENGTHB(folder.name) + LENGTHB(vQualified) + 1 < 2000 - nameLen)THEN
925       vQualified := '.' || folder.name || vQualified;
926      ELSE
927       EXIT;
928      END IF;
929   END LOOP;
930   v_FuncQualifiedName(inFolderId) := vQualified;
931   RETURN vQualified || inCompanionName;
932 END;
933 ---------------------------------------------------------------------------------------
934 --The ps_node_id value is fixed in the memory for references to BOM. This function can
935 --be called when the original value (ps_node_id of the reference node) is required.
936 
937 FUNCTION REAL_PS_NODE_ID(j IN PLS_INTEGER) RETURN NUMBER IS
938 BEGIN
939   IF(v_tRealPsNodeId.EXISTS(j))THEN RETURN v_tRealPsNodeId(j); ELSE RETURN v_tExprPsNodeId(j); END IF;
940 END;
941 ---------------------------------------------------------------------------------------
942 FUNCTION SIGNATURE_DATA_TYPE(p_signature_id IN NUMBER) RETURN PLS_INTEGER IS
943   v_data_type  PLS_INTEGER;
944 BEGIN
945   IF(h_SignatureDataType.EXISTS(p_signature_id))THEN RETURN h_SignatureDataType(p_signature_id); END IF;
946 
947   BEGIN
948     SELECT data_type INTO v_data_type FROM cz_signatures
949      WHERE deleted_flag = FLAG_NOT_DELETED
950        AND signature_id = p_signature_id;
951 
952     h_SignatureDataType(p_signature_id) := v_data_type;
953     RETURN v_data_type;
954   EXCEPTION
955     WHEN OTHERS THEN
956       RAISE CZ_R_NO_SIGNATURE_ID;
957   END;
958 END;
959 ---------------------------------------------------------------------------------------
960 FUNCTION COMPATIBLE_DATA_TYPES(p_object_type IN PLS_INTEGER, p_subject_type PLS_INTEGER) RETURN BOOLEAN IS
961   v_null  PLS_INTEGER;
962 BEGIN
963   SELECT NULL INTO v_null FROM cz_conversion_rels_v
964    WHERE object_type = p_object_type AND subject_type = p_subject_type;
965   RETURN TRUE;
966 EXCEPTION
967   WHEN NO_DATA_FOUND THEN
968     RETURN FALSE;
969   WHEN TOO_MANY_ROWS THEN
970     RETURN TRUE;
971   WHEN OTHERS THEN
972     RETURN FALSE;
973 END;
974 ---------------------------------------------------------------------------------------
975 FUNCTION GET_ARGUMENT_INFO(p_param_index  IN NUMBER,
976                            p_signature_id IN NUMBER,
977                            x_mutable      IN OUT NOCOPY VARCHAR2,
978                            x_collection   IN OUT NOCOPY VARCHAR2)
979 RETURN NUMBER IS
980   v_data_type  cz_signature_arguments.data_type%TYPE;
981 BEGIN
982   SELECT data_type, mutable_flag, collection_flag INTO v_data_type, x_mutable, x_collection
983     FROM cz_signature_arguments
984    WHERE deleted_flag = FLAG_NOT_DELETED
985      AND argument_signature_id = p_signature_id
986      AND argument_index = p_param_index;
987   RETURN v_data_type;
988 EXCEPTION
989   WHEN OTHERS THEN
990     RETURN DATA_TYPE_VOID;
991 END;
992 ---------------------------------------------------------------------------------------
993 FUNCTION APPLICABLE_SYS_PROP(j IN PLS_INTEGER, p_ps_node_id IN NUMBER, p_rule_id IN NUMBER) RETURN BOOLEAN IS
994   v_null        PLS_INTEGER;
995   v_ps_node_id  NUMBER;
996   v_data_type   cz_signature_arguments.data_type%TYPE;
997   v_mutable     cz_signature_arguments.mutable_flag%TYPE;
998   v_collection  cz_signature_arguments.collection_flag%TYPE;
999 BEGIN
1000 
1001   --Some of the upgraded rules may not have param_index and param_signature_id populated. However, upgraded
1002   --rules are not real statement rules, so they are not supposed to have any user error in them and in this
1003   --case the verification is not required.
1004 
1005   IF(v_tExprParamIndex(j) IS NULL OR v_tExprParSignature(j) IS NULL)THEN RETURN TRUE; END IF;
1006 
1007   IF(p_ps_node_id IS NULL)THEN v_ps_node_id := REAL_PS_NODE_ID(j); ELSE v_ps_node_id := p_ps_node_id; END IF;
1008   v_data_type := GET_ARGUMENT_INFO(v_tExprParamIndex(j), v_tExprParSignature(j), v_mutable, v_collection);
1009 
1010   SELECT NULL INTO v_null
1011     FROM cz_rul_typedpsn_v psn,
1012          cz_conversion_rels_v cnv,
1013          cz_system_property_rels_v rel,
1014          cz_system_properties_v sys,
1015          cz_conversion_rels_v cnv2
1016    WHERE psn.detailed_type_id = cnv.object_type
1017      AND cnv.subject_type = rel.subject_type
1018      AND rel.object_type = sys.rule_id
1019      AND rel.rel_type_code = 'SYS'
1020      AND sys.data_type = cnv2.object_type
1021      AND psn.ps_node_id = v_ps_node_id
1022      AND sys.rule_id = p_rule_id
1023      AND sys.mutable_flag >= v_mutable
1024      AND sys.collection_flag <= v_collection
1025      AND cnv2.subject_type = v_data_type;
1026 
1027   RETURN TRUE;
1028 EXCEPTION
1029   WHEN NO_DATA_FOUND THEN
1030     RETURN FALSE;
1031   WHEN TOO_MANY_ROWS THEN
1032     RETURN TRUE;
1033   WHEN OTHERS THEN
1034     RETURN FALSE;
1035 END;
1036 ---------------------------------------------------------------------------------------
1037 FUNCTION APPLICABLE_SYS_PROP(j IN PLS_INTEGER, p_ps_node_id IN NUMBER, p_rule_name IN VARCHAR2) RETURN BOOLEAN IS
1038   v_null        PLS_INTEGER;
1039   v_ps_node_id  NUMBER;
1040   v_data_type   cz_signature_arguments.data_type%TYPE;
1041   v_mutable     cz_signature_arguments.mutable_flag%TYPE;
1042   v_collection  cz_signature_arguments.collection_flag%TYPE;
1043 BEGIN
1044 
1045   --Some of the upgraded rules may not have param_index and param_signature_id populated. However, upgraded
1046   --rules are not real statement rules, so they are not supposed to have any user error in them and in this
1047   --case the verification is not required.
1048 
1049   IF(v_tExprParamIndex(j) IS NULL OR v_tExprParSignature(j) IS NULL)THEN RETURN TRUE; END IF;
1050 
1051   IF(p_ps_node_id IS NULL)THEN v_ps_node_id := REAL_PS_NODE_ID(j); ELSE v_ps_node_id := p_ps_node_id; END IF;
1052   v_data_type := GET_ARGUMENT_INFO(v_tExprParamIndex(j), v_tExprParSignature(j), v_mutable, v_collection);
1053 
1054   SELECT NULL INTO v_null
1055     FROM cz_rul_typedpsn_v psn,
1056          cz_conversion_rels_v cnv,
1057          cz_system_property_rels_v rel,
1058          cz_system_properties_v sys,
1059          cz_conversion_rels_v cnv2
1060    WHERE psn.detailed_type_id = cnv.object_type
1061      AND cnv.subject_type = rel.subject_type
1062      AND rel.object_type = sys.rule_id
1063      AND rel.rel_type_code = 'SYS'
1064      AND sys.data_type = cnv2.object_type
1065      AND psn.ps_node_id = v_ps_node_id
1066      AND UPPER(sys.name) = p_rule_name
1067      AND sys.mutable_flag >= v_mutable
1068      AND sys.collection_flag <= v_collection
1069      AND cnv2.subject_type = v_data_type;
1070 
1071   RETURN TRUE;
1072 EXCEPTION
1073   WHEN NO_DATA_FOUND THEN
1074     RETURN FALSE;
1075   WHEN TOO_MANY_ROWS THEN
1076     RETURN TRUE;
1077   WHEN OTHERS THEN
1078     RETURN FALSE;
1079 END;
1080 ---------------------------------------------------------------------------------------
1081 --Splits the CHR(7)-separated path into an array of node names.
1082 
1083 FUNCTION SPLIT_PATH(p_path IN VARCHAR2) RETURN tStringArray IS
1084 
1085   l_substr      VARCHAR2(32000) := p_path;
1086   l_index       PLS_INTEGER;
1087   l_return_tbl  tStringArray;
1088 BEGIN
1089 
1090   IF(p_path IS NULL)THEN RETURN l_return_tbl; END IF;
1091   LOOP
1092 
1093     l_index := INSTR(l_substr, FND_GLOBAL.LOCAL_CHR(7));
1094 
1095     IF(l_index > 0)THEN
1096 
1097       l_return_tbl(l_return_tbl.COUNT + 1) := SUBSTR(l_substr, 1, l_index - 1);
1098       l_substr := SUBSTR(l_substr, l_index + 1);
1099     ELSE
1100 
1101       l_return_tbl(l_return_tbl.COUNT + 1) := l_substr;
1102       EXIT;
1103     END IF;
1104   END LOOP;
1105 
1106   RETURN l_return_tbl;
1107 END;
1108 ---------------------------------------------------------------------------------------
1109 PROCEDURE RESOLVE_NODE(p_node_tbl        IN tStringArray,
1110                        p_parent_node_id  IN NUMBER,
1111                        p_parent_expl_id  IN NUMBER,
1112                        x_child_node_id   IN OUT NOCOPY NUMBER,
1113                        x_child_expl_id   IN OUT NOCOPY NUMBER) IS
1114 
1115   l_eff_from            DATE := EpochBeginDate;
1116   l_eff_until           DATE := EpochEndDate;
1117   l_index               PLS_INTEGER;
1118   l_parent_id           NUMBER;
1119 
1120   l_return_node_id_tbl  tNumberArray;
1121   l_return_expl_id_tbl  tNumberArray;
1122 
1123   FUNCTION REPORT_PATH RETURN VARCHAR2 IS
1124 
1125     l_return  VARCHAR2(32000) := NULL;
1126   BEGIN
1127 
1128     FOR i IN 1..p_node_tbl.COUNT LOOP
1129 
1130       IF(l_return IS NOT NULL)THEN l_return := l_return || '.'; END IF;
1131       l_return := l_return || p_node_tbl(i);
1132     END LOOP;
1133    RETURN l_return;
1134   END;
1135 
1136   PROCEDURE RESOLVE_CHILDREN(p_index      IN PLS_INTEGER,
1137                              p_node_id    IN NUMBER,
1138                              p_expl_id    IN NUMBER,
1139                              p_eff_from   IN DATE,
1140                              p_eff_until  IN DATE) IS
1141 
1142     t_eff_from_tbl   tDateArray;
1143     t_eff_until_tbl  tDateArray;
1144     t_node_id_tbl    tNumberArray;
1145     t_expl_id_tbl    tNumberArray;
1146     l_eff_from_tbl   tDateArray;
1147     l_eff_until_tbl  tDateArray;
1148     l_node_id_tbl    tNumberArray;
1149     l_expl_id_tbl    tNumberArray;
1150 
1151     l_counter        PLS_INTEGER := 0;
1152     l_index          PLS_INTEGER;
1153   BEGIN
1154 
1155     SELECT ps_node_id, model_ref_expl_id, effective_from, effective_until
1156       BULK COLLECT INTO l_node_id_tbl, l_expl_id_tbl, l_eff_from_tbl, l_eff_until_tbl
1157       FROM cz_explmodel_nodes_v
1158      WHERE model_id = inComponentId
1159        AND parent_psnode_expl_id = p_expl_id
1160        AND effective_parent_id = p_node_id
1161        AND suppress_flag = '0'
1162        AND name = p_node_tbl(p_index);
1163 
1164     FOR i IN 1..l_node_id_tbl.COUNT LOOP
1165 
1166       IF(p_eff_from > l_eff_from_tbl(i))THEN l_eff_from_tbl(i) := p_eff_from; END IF;
1167       IF(p_eff_until < l_eff_until_tbl(i))THEN l_eff_until_tbl(i) := p_eff_until; END IF;
1168 
1169       IF(l_eff_from_tbl(i) <= l_eff_until_tbl(i))THEN
1170 
1171         l_counter := l_counter + 1;
1172 
1173         t_eff_from_tbl(l_counter) := l_eff_from_tbl(i);
1174         t_eff_until_tbl(l_counter) := l_eff_until_tbl(i);
1175         t_node_id_tbl(l_counter) := l_node_id_tbl(i);
1176         t_expl_id_tbl(l_counter) := l_expl_id_tbl(i);
1177       END IF;
1178     END LOOP;
1179 
1180     FOR i IN 1..t_node_id_tbl.COUNT LOOP
1181 
1182       IF(p_index = p_node_tbl.COUNT)THEN
1183 
1184         l_index := l_return_node_id_tbl.COUNT + 1;
1185 
1186         l_return_node_id_tbl(l_index) := t_node_id_tbl(i);
1187         l_return_expl_id_tbl(l_index) := t_expl_id_tbl(i);
1188       ELSE
1189 
1190         RESOLVE_CHILDREN(p_index + 1, t_node_id_tbl(i), t_expl_id_tbl(i), t_eff_from_tbl(i), t_eff_until_tbl(i));
1191       END IF;
1192     END LOOP;
1193   END;
1194 BEGIN
1195 
1196   --Propagate effectivity from all the bom references down from the root model.
1197 
1198   FOR i IN 1..globalLevel LOOP
1199 
1200     --We need to stop on the model, in which the rule is defined.
1201 
1202     IF(globalStack(i) = inComponentId)THEN EXIT; END IF;
1203 
1204     --Account only for references to bom(s).
1205 
1206     IF(glPsNodeType(glIndexByPsNodeId(globalStack(i))) IN (PS_NODE_TYPE_BOM_MODEL,PS_NODE_TYPE_BOM_OPTIONCLASS,PS_NODE_TYPE_BOM_STANDARD))THEN
1207 
1208       l_index := glIndexByPsNodeId(globalRef(i));
1209 
1210       IF(glEffFrom(l_index) > l_eff_from)THEN l_eff_from := glEffFrom(l_index); END IF;
1211       IF(glEffUntil(l_index) < l_eff_until)THEN l_eff_until := glEffUntil(l_index); END IF;
1212     END IF;
1213   END LOOP;
1214 
1215   --Adjust effectivities for the least unambiguous parent.
1216 
1217   l_index := glIndexByPsNodeId(p_parent_node_id);
1218 
1219   IF(glEffFrom(l_index) > l_eff_from)THEN l_eff_from := glEffFrom(l_index); END IF;
1220   IF(glEffUntil(l_index) < l_eff_until)THEN l_eff_until := glEffUntil(l_index); END IF;
1221 
1222   --Finally adjust for the rule effectivity.
1223 
1224   IF(dEffFrom > l_eff_from)THEN l_eff_from := dEffFrom; END IF;
1225   IF(dEffUntil < l_eff_until)THEN l_eff_until := dEffUntil; END IF;
1226 
1227   --If effectivity range is empty, it will be impossible to resolve the node.
1228 
1229   IF(l_eff_until < l_eff_from)THEN
1230 
1231     localString := REPORT_PATH;
1232     RAISE CZ_R_INCORRECT_REFERENCE;
1233   END IF;
1234 
1235   IF(p_node_tbl.COUNT = 0)THEN
1236 
1237     x_child_node_id := p_parent_node_id;
1238     x_child_expl_id := p_parent_expl_id;
1239     RETURN;
1240   END IF;
1241 
1242   RESOLVE_CHILDREN(1, p_parent_node_id, p_parent_expl_id, l_eff_from, l_eff_until);
1243 
1244   IF(l_return_node_id_tbl.COUNT = 0)THEN
1245 
1246     localString := REPORT_PATH;
1247     RAISE CZ_R_INCORRECT_REFERENCE;
1248   ELSIF(l_return_node_id_tbl.COUNT > 1)THEN
1249 
1250     localString := REPORT_PATH;
1251     RAISE CZ_R_AMBIGUOUS_REFERENCE;
1252   ELSE
1253 
1254     x_child_node_id := l_return_node_id_tbl(1);
1255     x_child_expl_id := l_return_expl_id_tbl(1);
1256   END IF;
1257 END;
1258 ---------------------------------------------------------------------------------------
1259 --Forward declarations block.
1260 
1261 FUNCTION GENERATE_EXPRESSION(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray;
1262 FUNCTION GENERATE_REFNODE(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray;
1263 FUNCTION LOOKUP_ARGUMENT(j IN PLS_INTEGER) RETURN PLS_INTEGER;
1264 FUNCTION GENERATE_ARGUMENT(j IN PLS_INTEGER, ListType IN OUT NOCOPY PLS_INTEGER) RETURN tStringArray;
1265 ---------------------------------------------------------------------------------------
1266 FUNCTION HAS_LOGICAL_VALUE(j IN PLS_INTEGER) RETURN BOOLEAN IS
1267   NodeType     PLS_INTEGER := v_tExprType(j);
1268   PsNodeType   PLS_INTEGER;
1269   PsNodeIndex  PLS_INTEGER;
1270 BEGIN
1271 
1272   --When the validation is made from the high-level section of a logic rule, some of the participants
1273   --may still be arguments, so we need to look up the value of the argument before validating its
1274   --type. The argument in this case can be either a literal or a node (bug #3388169).
1275 
1276   IF(NodeType = EXPR_ARGUMENT)THEN
1277 
1278     PsNodeIndex := LOOKUP_ARGUMENT(j);
1279     IF(parameterScope(PsNodeIndex).node_id IS NULL)THEN RETURN FALSE; END IF;
1280 
1281     NodeType := EXPR_PSNODE;
1282     v_tExprPsNodeId(j) := parameterScope(PsNodeIndex).node_id;
1283   END IF;
1284 
1285   IF(NodeType = EXPR_NODE_TYPE_LITERAL)THEN
1286     RETURN (v_tExprDataType(j) = DATA_TYPE_BOOLEAN);
1287   ELSIF(NodeType = EXPR_PSNODE)THEN
1288     IF(v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN RETURN TRUE;
1289     ELSE
1290 
1291       PsNodeIndex := glIndexByPsNodeId(v_tExprPsNodeId(j));
1292       PsNodeType := glPsNodeType(PsNodeIndex);
1293 
1294       RETURN
1295          PsNodeType <> PS_NODE_TYPE_TOTAL
1296            AND
1297          PsNodeType <> PS_NODE_TYPE_RESOURCE
1298            AND
1299             (
1300              PsNodeType <> PS_NODE_TYPE_FEATURE
1301               OR
1302              glFeatureType(PsNodeIndex) IN (PS_NODE_FEATURE_TYPE_BOOLEAN, PS_NODE_FEATURE_TYPE_OPTION)
1303               OR
1304              (
1305                glFeatureType(PsNodeIndex) = PS_NODE_FEATURE_TYPE_INTEGER
1306                 AND
1307                glMinimum(PsNodeIndex) IS NOT NULL
1308                 AND
1309                glMinimum(PsNodeIndex) >= 0
1310              )
1311             );
1312     END IF;
1313   ELSIF(NodeType = EXPR_NODE_TYPE_OPERATOR)THEN
1314      RETURN COMPATIBLE_DATA_TYPES(SIGNATURE_DATA_TYPE(h_SignatureId(v_tExprSubtype(j))), DATA_TYPE_BOOLEAN);
1315   ELSIF(NodeType IN (EXPR_FORALL, EXPR_FORALL_DISTINCT))THEN
1316    RETURN TRUE;
1317   ELSE
1318    RETURN FALSE;
1319   END IF;
1320 END;
1321 ---------------------------------------------------------------------------------------
1322 FUNCTION HAS_OPTIONS_APPLIED(j IN PLS_INTEGER) RETURN BOOLEAN IS
1323 BEGIN
1324   RETURN (v_ChildrenIndex.EXISTS(v_tExprId(j)) AND
1325           h_SeededName.EXISTS(v_tExprSubtype(v_ChildrenIndex(v_tExprId(j)))) AND
1326           h_SeededName(v_tExprSubtype(v_ChildrenIndex(v_tExprId(j)))) = RULE_SYS_PROP_OPTIONS);
1327 END;
1328 ---------------------------------------------------------------------------------------
1329 FUNCTION GENERATE_NODE_CHILDREN(j IN PLS_INTEGER) RETURN tStringArray IS
1330  v_return  tStringArray;
1331  nChild    PLS_INTEGER;
1332  nCount    PLS_INTEGER;
1333  oper      tStringArray;
1334  ListType  PLS_INTEGER;
1335 BEGIN
1336 
1337 --nDebug := 7000005;
1338 
1339   nCount := 1;
1340   nChild := v_ChildrenIndex(v_tExprId(j));
1341 
1342 --nDebug := 7000006;
1343 
1344   WHILE(v_tExprParentId(nChild) = v_tExprId(j)) LOOP
1345 
1346 --nDebug := 7000007;
1347 
1348    oper.DELETE;
1349    oper := GENERATE_EXPRESSION(nChild, ListType);
1350 
1351    FOR i IN 1..oper.COUNT LOOP
1352 
1353     v_return(nCount) := oper(i);
1354     nCount := nCount + 1;
1355 
1356    END LOOP;
1357 
1358    nChild := nChild + 1;
1359 
1360   END LOOP;
1361 
1362 --nDebug := 7000008;
1363 
1364  RETURN v_return;
1365 END;
1366 ---------------------------------------------------------------------------------------
1367 FUNCTION GENERATE_NAME(j IN PLS_INTEGER, id IN NUMBER) RETURN VARCHAR2 IS --kdande; Bug 6881902; 11-Mar-2008
1368  v_return   VARCHAR2(4000);
1369  counter    PLS_INTEGER;
1370  val        PLS_INTEGER;
1371  delimiter  CHAR(1) := NULL;
1372  ExplId     cz_model_ref_expls.model_ref_expl_id%TYPE := v_tExplNodeId(j);
1373 BEGIN
1374 
1375  IF(NOT v_NodeUpPath.EXISTS(ExplId))THEN
1376    counter := nRuleAssignedLevel;
1377    val := v_NodeLogicLevel(ExplId);
1378    WHILE(counter > val) LOOP
1379      v_return := v_return || PATH_DELIMITER || 'parent';
1380      counter := counter - 1;
1381    END LOOP;
1382    v_NodeUpPath(ExplId) := v_return;
1383  ELSE
1384    v_return := v_NodeUpPath(ExplId);
1385  END IF;
1386 
1387  IF(v_tLogicNetType(nHeaderId) = LOGIC_NET_TYPE_NETWORK AND (NOT v_IsConnectorNet.EXISTS(ExplId)))THEN
1388 
1389    --If we are generating into a conditional net, we add an extra ^parent to the path, but only if
1390    --this is not a connector's net.
1391 
1392    v_return := PATH_DELIMITER || 'parent' || v_return;
1393  END IF;
1394 
1395  IF(v_return IS NOT NULL OR v_AssignedDownPath(ExplId) IS NOT NULL)THEN
1396    delimiter := PATH_DELIMITER;
1397  END IF;
1398 
1399  v_return := v_return || v_AssignedDownPath(ExplId) || delimiter;
1400 
1401  --The description below is only true if the reference participates in the rule as an
1402  --object, because if this is a rule against this reference's system property than we
1403  --still should generate the regular name. So, we need to make sure that we construct
1404  --the new name only if this reference participates in compatibility rules - the only
1405  --type of rules where it can participate as an object (an option). Bug #2567898.
1406 
1407  IF(nRuleType IN (RULE_TYPE_COMPAT_RULE, RULE_TYPE_COMPAT_TABLE, RULE_TYPE_DESIGNCHART_RULE) AND
1408     glPsNodeType(glIndexByPsNodeId(id)) = PS_NODE_TYPE_REFERENCE)THEN
1409 
1410    --The following comment is not exactly correct, see the above description.
1411    --The node identified by <id> is a reference. In this case we should not generate
1412    --the regular P_<id>, because such object would never exist. Instead, we generate
1413    --^N_<id>^P_<reference_id> to refer to the referenced object in the child subnet.
1414    --This fixes the base bug #2128641.
1415 
1416    IF(v_return IS NULL)THEN v_return := PATH_DELIMITER; END IF;
1417    v_return := v_return || 'N_' || TO_CHAR(glPersistentId(id)) || PATH_DELIMITER ||
1418                            'P_' || TO_CHAR(glReferenceId(id));
1419  ELSE
1420 
1421    v_return := v_return || 'P_' || TO_CHAR(glPersistentId(id));
1422  END IF;
1423 
1424  RETURN v_return;
1425 END;
1426 ---------------------------------------------------------------------------------------
1427 --Special version of GENERATE_NAME that accepts model_ref_expl_id value as a parameter
1428 --instead of extracting it from cz_expression nodes by index j.
1429 
1430 FUNCTION GENERATE_NAME_EXPL(ExplId IN PLS_INTEGER, id IN NUMBER) RETURN VARCHAR2 IS  --kdande; Bug 6881902; 11-Mar-2008
1431  v_return   VARCHAR2(4000);
1432  counter    PLS_INTEGER;
1433  val        PLS_INTEGER;
1434  delimiter  CHAR(1) := NULL;
1435 BEGIN
1436 
1437  IF(NOT v_NodeUpPath.EXISTS(ExplId))THEN
1438    counter := nRuleAssignedLevel;
1439    val := v_NodeLogicLevel(ExplId);
1440    WHILE(counter > val) LOOP
1441      v_return := v_return || PATH_DELIMITER || 'parent';
1442      counter := counter - 1;
1443    END LOOP;
1444    v_NodeUpPath(ExplId) := v_return;
1445  ELSE
1446    v_return := v_NodeUpPath(ExplId);
1447  END IF;
1448 
1449  IF(v_tLogicNetType(nHeaderId) = LOGIC_NET_TYPE_NETWORK AND (NOT v_IsConnectorNet.EXISTS(ExplId)))THEN
1450 
1451    --If we are generating into a conditional net, we add an extra ^parent to the path, but only if
1452    --this is not a connector's net.
1453 
1454    v_return := PATH_DELIMITER || 'parent' || v_return;
1455  END IF;
1456 
1457  IF(v_return IS NOT NULL OR v_AssignedDownPath(ExplId) IS NOT NULL)THEN
1458    delimiter := PATH_DELIMITER;
1459  END IF;
1460 
1461  v_return := v_return || v_AssignedDownPath(ExplId) || delimiter;
1462 
1463  --The description below is only true if the reference participates in the rule as an
1464  --object, because if this is a rule against this reference's system property than we
1465  --still should generate the regular name. So, we need to make sure that we construct
1466  --the new name only if this reference participates in compatibility rules - the only
1467  --type of rules where it can participate as an object (an option). Bug #2567898.
1468 
1469  IF(nRuleType IN (RULE_TYPE_COMPAT_RULE, RULE_TYPE_COMPAT_TABLE, RULE_TYPE_DESIGNCHART_RULE) AND
1470     glPsNodeType(glIndexByPsNodeId(id)) = PS_NODE_TYPE_REFERENCE)THEN
1471 
1472    --The following comment is not exactly correct, see the above description.
1473    --The node identified by <id> is a reference. In this case we should not generate
1474    --the regular P_<id>, because such object would never exist. Instead, we generate
1475    --^N_<id>^P_<reference_id> to refer to the referenced object in the child subnet.
1476    --This fixes the base bug #2128641.
1477 
1478    IF(v_return IS NULL)THEN v_return := PATH_DELIMITER; END IF;
1479    v_return := v_return || 'N_' || TO_CHAR(glPersistentId(id)) || PATH_DELIMITER ||
1480                            'P_' || TO_CHAR(glReferenceId(id));
1481  ELSE
1482 
1483    v_return := v_return || 'P_' || TO_CHAR(glPersistentId(id));
1484  END IF;
1485 
1486  RETURN v_return;
1487 END;
1488 ---------------------------------------------------------------------------------------
1489 FUNCTION GENERATE_NODE(j IN PLS_INTEGER) RETURN tStringArray IS
1490  v_return  tStringArray;
1491 BEGIN
1492 
1493   v_return(1) := GENERATE_NAME(j, v_tExprPsNodeId(j));
1494   RETURN v_return;
1495 
1496 END;
1497 ---------------------------------------------------------------------------------------
1498 FUNCTION ADJUSTED_EXPLOSION(p_parent_expl_id IN NUMBER, p_child_node_id IN NUMBER) RETURN NUMBER IS
1499 BEGIN
1500   FOR i IN 1..v_NodeId.COUNT LOOP
1501     IF(v_tParentId(i) = p_parent_expl_id AND v_tReferringId(i) = p_child_node_id)THEN
1502       RETURN v_NodeId(i);
1503     END IF;
1504   END LOOP;
1505 END;
1506 ---------------------------------------------------------------------------------------
1507 FUNCTION EXPAND_NODE(j IN PLS_INTEGER) RETURN tIntegerArray IS
1508   v_result       tIntegerArray;
1509   nCount         PLS_INTEGER;
1510   v_ps_node_id   NUMBER; --kdande; Bug 6881902; 11-Mar-2008
1511   v_node_type    PLS_INTEGER;
1512   v_index        PLS_INTEGER;
1513   v_start_index  PLS_INTEGER;
1514   v_end_index    PLS_INTEGER;
1515 BEGIN
1516 
1517   IF(v_tExprType(j) = EXPR_OPERATOR)THEN
1518 
1519     --The function is called on an operator node. We assume that this is OptionsOf, and so it has one
1520     --operand which represents a structure node. This structure node has its explosion populated in
1521     --cz_expression_nodes table. It is often convenient to associate this explosion also with the
1522     --operator itself. This is a fix for the bug #2232741.
1523 
1524     v_ps_node_id := v_tExprPsNodeId(v_ChildrenIndex(v_tExprId(j)));
1525     v_tExplNodeId(j) := v_tExplNodeId(v_ChildrenIndex(v_tExprId(j)));
1526 
1527   ELSIF(v_tExprType(j) = EXPR_PSNODE AND v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
1528 
1529     v_ps_node_id := v_tExprPsNodeId(j);
1530   ELSE
1531 
1532     --Left for backward compatibility.
1533 
1534     v_result(1) := v_tExprPsNodeId(j);
1535     RETURN v_result;
1536   END IF;
1537 
1538   v_index := glIndexByPsNodeId(v_ps_node_id);
1539   v_node_type := glPsNodeType(v_index);
1540   v_start_index := v_index + 1;
1541 
1542   IF(NOT glLastChildIndex.EXISTS(v_ps_node_id))THEN
1543 
1544     localString := glName(v_index);
1545     RAISE CZ_E_NO_EXPECTED_CHILDREN;
1546   END IF;
1547 
1548   v_end_index := glLastChildIndex(v_ps_node_id);
1549   nCount := 1;
1550 
1551   --If the function is called on a feature, we return options. If the function is called on a
1552   --BOM node, we return BOM children.
1553 
1554   IF(v_node_type = PS_NODE_TYPE_FEATURE)THEN
1555 
1556     FOR i IN v_start_index..v_end_index LOOP
1557 
1558       v_result(nCount) := glPsNodeId(i);
1559       v_ExplByPsNodeId(glPsNodeId(i)) := v_tExplNodeId(j);
1560       nCount := nCount + 1;
1561     END LOOP;
1562   ELSIF(v_node_type IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
1563 
1564     FOR i IN v_start_index..v_end_index LOOP
1565 
1566       IF((glPsNodeType(i) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD) OR
1567           (glPsNodeType(i) = PS_NODE_TYPE_REFERENCE AND
1568           glPsNodeType(glIndexByPsNodeId(glReferenceId(glPsNodeId(i)))) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD)))
1569           AND glParentId(i) = v_ps_node_id)THEN
1570 
1571            IF(glPsNodeType(i) = PS_NODE_TYPE_REFERENCE)THEN
1572              v_result(nCount) := glReferenceId(glPsNodeId(i));
1573              v_ExplByPsNodeId(glReferenceId(glPsNodeId(i))) := ADJUSTED_EXPLOSION(v_tExplNodeId(j), glPsNodeId(i));
1574            ELSE
1575              v_result(nCount) := glPsNodeId(i);
1576              v_ExplByPsNodeId(glPsNodeId(i)) := v_tExplNodeId(j);
1577            END IF;
1578            nCount := nCount + 1;
1579       END IF;
1580     END LOOP;
1581   END IF;
1582  RETURN v_result;
1583 END;
1584 ---------------------------------------------------------------------------------------
1585 FUNCTION GENERATE_CHILDRENOF(p_expl_id IN PLS_INTEGER, p_ps_node_id IN NUMBER) RETURN tStringArray IS  --kdande; Bug 6881902; 11-Mar-2008
1586   v_return       tStringArray;
1587   nCount         PLS_INTEGER;
1588   v_node_type    PLS_INTEGER;
1589   v_index        PLS_INTEGER;
1590   v_start_index  PLS_INTEGER;
1591   v_end_index    PLS_INTEGER;
1592 BEGIN
1593 
1594 nDebug := 7004050;
1595 
1596   --This function does basically the same as the previous one. The difference is that it can be used
1597   --only for system property, it is called on the system property node, taking the ps_node_id of the
1598   --parent as a parameter, and it returns generated names.
1599 
1600   v_index := glIndexByPsNodeId(p_ps_node_id);
1601   v_node_type := glPsNodeType(v_index);
1602   v_start_index := v_index + 1;
1603 
1604   IF(NOT glLastChildIndex.EXISTS(p_ps_node_id))THEN
1605 
1606     localString := glName(v_index);
1607     RAISE CZ_E_NO_EXPECTED_CHILDREN;
1608   END IF;
1609 
1610   v_end_index := glLastChildIndex(p_ps_node_id);
1611   nCount := 1;
1612 
1613   --If the function is called on a feature, we return options. If the function is called on a
1614   --BOM node, we return BOM children.
1615 
1616   IF(v_node_type = PS_NODE_TYPE_FEATURE)THEN
1617 
1618     FOR i IN v_start_index..v_end_index LOOP
1619 
1620       v_return(nCount) := GENERATE_NAME_EXPL(p_expl_id, glPsNodeId(i));
1621       nCount := nCount + 1;
1622     END LOOP;
1623 
1624   ELSIF(v_node_type IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
1625 
1626     FOR i IN v_start_index..v_end_index LOOP
1627       IF((glPsNodeType(i) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD) OR
1628           (glPsNodeType(i) = PS_NODE_TYPE_REFERENCE AND
1629           glPsNodeType(glIndexByPsNodeId(glReferenceId(glPsNodeId(i)))) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD)))
1630           AND glParentId(i) = p_ps_node_id)THEN
1631 
1632            IF(glPsNodeType(i) = PS_NODE_TYPE_REFERENCE)THEN
1633              v_return(nCount) := GENERATE_NAME_EXPL(ADJUSTED_EXPLOSION(p_expl_id, glPsNodeId(i)), glReferenceId(glPsNodeId(i)));
1634            ELSE
1635              v_return(nCount) := GENERATE_NAME_EXPL(p_expl_id, glPsNodeId(i));
1636            END IF;
1637            nCount := nCount + 1;
1638       END IF;
1639     END LOOP;
1640   END IF;
1641 
1642 nDebug := 7004059;
1643 
1644  RETURN v_return;
1645 END;
1646 ---------------------------------------------------------------------------------------
1647 FUNCTION GENERATE_ARITHMETIC(j IN PLS_INTEGER) RETURN tStringArray IS
1648 
1649   v_return     tStringArray;
1650   nChild       PLS_INTEGER;
1651   nCount       PLS_INTEGER;
1652   lhs          tStringArray;
1653   rhs          tStringArray;
1654   ListType     PLS_INTEGER;
1655   v_rounding   VARCHAR2(16) := ' ';
1656   v_target     VARCHAR2(4000);
1657   v_parj       PLS_INTEGER;
1658   optimizeFlag PLS_INTEGER := 0;
1659 
1660 BEGIN
1661 
1662   IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
1663    RAISE CZ_E_WRONG_ARITHMETIC_OPER;
1664   END IF;
1665 
1666   nCount := 1;
1667   nChild := v_ChildrenIndex(v_tExprId(j));
1668   IF(v_tExprParentId.EXISTS(nChild + 1) AND v_tExprParentId(nChild + 1) = v_tExprId(j))THEN
1669    nCount := 2;
1670   END IF;
1671 
1672 nDebug := 8004002;
1673 
1674   --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
1675   nLocalDefaults := nLocalDefaults + 1;
1676   v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
1677   v_target := 'TOTAL ' || v_return(1) || NewLine;
1678 
1679   --Check if this procedure has been called for generation of a direct child expression of a rounding
1680   --operator. If so, set a flag to generate an enhanced contribute relation and no temporary total.
1681   --If the rounding operator is a root operator of a numeric rule with an advanced lhs expression,
1682   --which is indicated by the optimizeChain flag, generate the optimized contribute relation.
1683 
1684   IF(v_tExprParentId(j) IS NOT NULL)THEN
1685 
1686     v_parj := v_IndexByExprNodeId(v_tExprParentId(j));
1687 
1688     IF(v_tExprType(v_parj) = EXPR_NODE_TYPE_OPERATOR AND
1689        v_tExprSubtype(v_parj) IN (OPERATOR_ROUND, OPERATOR_CEILING, OPERATOR_FLOOR, OPERATOR_TRUNCATE))THEN
1690 
1691        v_rounding := OperatorLiterals(v_tExprSubtype(v_parj));
1692        generateRound := OPTIMIZATION_COMPLETED;
1693 
1694        IF(optimizeChain = OPTIMIZATION_REQUESTED)THEN
1695 
1696          v_return(1) := optimizeTarget;
1697          v_target := NULL;
1698          optimizeChain := OPTIMIZATION_COMPLETED;
1699        END IF;
1700     END IF;
1701   ELSIF(optimizeContribute = OPTIMIZATION_REQUESTED)THEN
1702 
1703     optimizeFlag := 1;
1704     optimizeContribute := OPTIMIZATION_COMPLETED;
1705   END IF;
1706 
1707   IF(nCount = 1)THEN
1708 
1709 nDebug := 8004003;
1710 
1711     lhs := GENERATE_EXPRESSION(nChild, ListType);
1712     IF(v_tExprSubtype(j) = OPERATOR_SUB)THEN
1713 
1714       IF(optimizeFlag = 0)THEN
1715 
1716         vLogicLine := v_target || 'CONTRIBUTE ' || lhs(1) || OperatorLiterals(OPERATOR_MULT) || '-1 ' ||
1717                       v_return(1) || v_rounding || '... ' || TO_CHAR(nReasonId) || NewLine;
1718       ELSE
1719 
1720         v_return(1) := lhs(1) || OperatorLiterals(OPERATOR_MULT) || '-1 ';
1721       END IF;
1722     ELSE
1723 
1724       v_return(1) := lhs(1);
1725     END IF;
1726   ELSE
1727 
1728 nDebug := 8004004;
1729 
1730     lhs := GENERATE_EXPRESSION(nChild, ListType);
1731 
1732 nDebug := 8004005;
1733 
1734     rhs := GENERATE_EXPRESSION(nChild + 1, ListType);
1735 
1736 nDebug := 8004006;
1737 
1738     IF(optimizeFlag = 0)THEN
1739 
1740       vLogicLine := v_target || 'CONTRIBUTE ' || lhs(1) || OperatorLiterals(v_tExprSubtype(j)) ||
1741                     rhs(1) || ' ' || v_return(1) || v_rounding || '... ' || TO_CHAR(nReasonId) || NewLine;
1742     ELSE
1743 
1744       v_return(1) := lhs(1) || OperatorLiterals(v_tExprSubtype(j)) || rhs(1) || ' ';
1745     END IF;
1746   END IF;
1747 
1748  PACK;
1749  RETURN v_return;
1750 END;
1751 ---------------------------------------------------------------------------------------
1752 FUNCTION GENERATE_MATH_UNARY(j IN PLS_INTEGER) RETURN tStringArray IS
1753   v_return  tStringArray;
1754   v_result  tStringArray;
1755   nChild    PLS_INTEGER;
1756   ListType  PLS_INTEGER;
1757 BEGIN
1758 
1759 nDebug := 7000100;
1760 
1761   IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 1)THEN
1762     nParam := v_tExprSubtype(j);
1763     RAISE CZ_E_MATH_PARAMETERS;
1764   END IF;
1765 
1766   nChild := v_ChildrenIndex(v_tExprId(j));
1767 
1768 nDebug := 7000101;
1769 
1770   --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
1771   nLocalDefaults := nLocalDefaults + 1;
1772   v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
1773 
1774 nDebug := 7000102;
1775 
1776   v_result := GENERATE_EXPRESSION(nChild, ListType);
1777 
1778 nDebug := 7000103;
1779 
1780   vLogicLine := 'TOTAL ' || v_return(1) || NewLine ||
1781                 'MF ' || v_result(1) || OperatorLiterals(v_tExprSubtype(j)) ||
1782                 v_return(1) || ' ... ' || TO_CHAR(nReasonId) || NewLine;
1783   PACK;
1784 
1785  RETURN v_return;
1786 END;
1787 ---------------------------------------------------------------------------------------
1788 FUNCTION GENERATE_MATH_BINARY(j IN PLS_INTEGER) RETURN tStringArray IS
1789   v_return  tStringArray;
1790   nChild    PLS_INTEGER;
1791   lhs       tStringArray;
1792   rhs       tStringArray;
1793   ListType  PLS_INTEGER;
1794 BEGIN
1795 
1796 nDebug := 7000200;
1797 
1798   IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 2)THEN
1799     nParam := v_tExprSubtype(j);
1800     RAISE CZ_E_MATH_PARAMETERS;
1801   END IF;
1802 
1803   nChild := v_ChildrenIndex(v_tExprId(j));
1804 
1805 nDebug := 7000201;
1806 
1807   --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
1808   nLocalDefaults := nLocalDefaults + 1;
1809   v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
1810 
1811 nDebug := 7000202;
1812 
1813   lhs := GENERATE_EXPRESSION(nChild, ListType);
1814 
1815 nDebug := 7000203;
1816 
1817   rhs := GENERATE_EXPRESSION(nChild + 1, ListType);
1818 
1819   --Bug #1990405. For the pow function, the second operand must evaluate to an integer. This
1820   --requirement may be removed or modified later.
1821 
1822   IF(v_tExprSubtype(j) = OPERATOR_POW)THEN
1823 
1824     --The generated expression should be an integer constant.
1825 
1826     IF(REPLACE(TRANSLATE(rhs(1), '0123456789', '0000000000'), '0', NULL) IS NOT NULL)THEN
1827       RAISE CZ_E_INCORRECT_POWER;
1828     END IF;
1829   END IF;
1830 
1831 nDebug := 7000204;
1832 
1833   vLogicLine := 'TOTAL ' || v_return(1) || NewLine ||
1834                 'MF ' || lhs(1) || ' ' || rhs(1) || OperatorLiterals(v_tExprSubtype(j)) ||
1835                 v_return(1) || ' ... ' || TO_CHAR(nReasonId) || NewLine;
1836   PACK;
1837 
1838  RETURN v_return;
1839 END;
1840 ---------------------------------------------------------------------------------------
1841 FUNCTION GENERATE_MATH_ROUND(j IN PLS_INTEGER) RETURN tStringArray IS
1842   v_return   tStringArray;
1843   nChild     PLS_INTEGER;
1844   lhs        tStringArray;
1845   rhs        tStringArray;
1846   ListType   PLS_INTEGER;
1847   sReasonId  VARCHAR2(4000) := TO_CHAR(nReasonId);
1848 BEGIN
1849 
1850 nDebug := 7000300;
1851 
1852   IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 2)THEN
1853     nParam := v_tExprSubtype(j);
1854     RAISE CZ_E_MATH_PARAMETERS;
1855   END IF;
1856 
1857   nChild := v_ChildrenIndex(v_tExprId(j));
1858 
1859 nDebug := 7000301;
1860 
1861   --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
1862   nLocalDefaults := nLocalDefaults + 1;
1863   v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
1864 
1865 nDebug := 7000302;
1866 
1867   lhs := GENERATE_EXPRESSION(nChild, ListType);
1868 
1869 nDebug := 7000303;
1870 
1871   rhs := GENERATE_EXPRESSION(nChild + 1, ListType);
1872 
1873 nDebug := 7000304;
1874 
1875   vLogicLine := 'TOTAL ' || v_return(1) || '_1' || NewLine ||
1876                 'MF ' || lhs(1) || ' ' || rhs(1) || OperatorLiterals(OPERATOR_MATHDIV) ||
1877                 v_return(1) || '_1 ... ' || sReasonId || NewLine;
1878   PACK;
1879   vLogicLine := 'TOTAL ' || v_return(1) || '_2' || NewLine ||
1880                 'MF ' || v_return(1) || '_1' || OperatorLiterals(v_tExprSubtype(j)) ||
1881                 v_return(1) || '_2 ... ' || sReasonId || NewLine;
1882   PACK;
1883   vLogicLine := 'TOTAL ' || v_return(1) || NewLine ||
1884                 'CONTRIBUTE ' || rhs(1) || OperatorLiterals(OPERATOR_MULT) ||
1885                 v_return(1) || '_2 ' || v_return(1) || ' ... ' || sReasonId || NewLine;
1886   PACK;
1887 
1888  RETURN v_return;
1889 END;
1890 ---------------------------------------------------------------------------------------
1891 FUNCTION GENERATE_LITERAL(j IN PLS_INTEGER) RETURN tStringArray IS
1892  v_return  tStringArray;
1893 BEGIN
1894 
1895   v_return(1) := v_tExprDataValue(j);
1896 
1897   IF(v_tExprDataType(j) = DATA_TYPE_BOOLEAN)THEN
1898     IF(UPPER(v_tExprDataValue(j)) IN ('1', LOGICAL_CONSTANT_TRUE))THEN
1899 
1900       v_return(1) := ALWAYS_TRUE;
1901     ELSIF(UPPER(v_tExprDataValue(j)) IN ('0', LOGICAL_CONSTANT_FALSE))THEN
1902 
1903       v_return(1) := ALWAYS_FALSE;
1904     END IF;
1905 
1906     --Bug #4375977.
1907 
1908     IF(v_tLogicNetType(nHeaderId) = LOGIC_NET_TYPE_NETWORK AND (NOT v_IsConnectorNet.EXISTS(v_tExplNodeId(j))))THEN
1909 
1910        --If we are generating into a conditional net, we add an extra ^parent to the path, but only if
1911        --this is not a connector's net.
1912 
1913        v_return(1) := PATH_DELIMITER || 'parent' || PATH_DELIMITER || v_return(1);
1914     END IF;
1915   END IF;
1916  RETURN v_return;
1917 END;
1918 ---------------------------------------------------------------------------------------
1919 FUNCTION GENERATE_CONSTANT(j IN PLS_INTEGER) RETURN tStringArray IS
1920  v_return  tStringArray;
1921 BEGIN
1922   IF(v_tExprSubtype(j) = EXPR_SUBTYPE_CONSTANT_E)THEN
1923 
1924     IF(NOT h_HeaderEDefined.EXISTS(nHeaderId))THEN
1925       h_HeaderEDefined(nHeaderId) := 'T_' || TO_CHAR(nHeaderId) || '_E';
1926       vLogicLine := 'TOTAL ' || h_HeaderEDefined(nHeaderId) || ' ' || MATH_CONSTANT_E || NewLine;
1927       PACK;
1928     END IF;
1929     v_return(1) := h_HeaderEDefined(nHeaderId);
1930 
1931   ELSIF(v_tExprSubtype(j) = EXPR_SUBTYPE_CONSTANT_PI)THEN
1932 
1933     IF(NOT h_HeaderPiDefined.EXISTS(nHeaderId))THEN
1934       h_HeaderPiDefined(nHeaderId) := 'T_' || TO_CHAR(nHeaderId) || '_PI';
1935       vLogicLine := 'TOTAL ' || h_HeaderPiDefined(nHeaderId) || ' ' || MATH_CONSTANT_PI || NewLine;
1936       PACK;
1937     END IF;
1938     v_return(1) := h_HeaderPiDefined(nHeaderId);
1939 
1940   ELSE
1941     RAISE CZ_E_UNKNOWN_EXPR_TYPE;
1942   END IF;
1943  RETURN v_return;
1944 END;
1945 ---------------------------------------------------------------------------------------
1946 FUNCTION GENERATE_MINMAX(j IN PLS_INTEGER) RETURN tStringArray IS
1947  v_return         tStringArray;
1948  v_child          tStringArray;
1949  v_current        VARCHAR2(4000);
1950  v_oper           VARCHAR2(10) := OperatorLiterals(v_tExprSubtype(j));
1951  v_rounding       VARCHAR2(16) := ' ';
1952  v_actual         VARCHAR2(16) := ' ';
1953  v_parj           PLS_INTEGER;
1954  v_target         VARCHAR2(4000);
1955  doOptimize       PLS_INTEGER := 0;
1956  v_name           VARCHAR2(128);
1957 BEGIN
1958 
1959  nLocalDefaults := nLocalDefaults + 1;
1960  v_name := TO_CHAR(nLocalDefaults);
1961 
1962  v_child := GENERATE_NODE_CHILDREN(j);
1963  v_return(1) := t_prefix || v_name || '_1';
1964  v_target := 'TOTAL ' || v_return(1) || NewLine;
1965 
1966  IF(v_child.COUNT < 2)THEN
1967    RAISE CZ_E_WRONG_MINMAX_OPERATOR;
1968  END IF;
1969 
1970  --Check if this procedure has been called for generation of a direct child expression of a rounding
1971  --operator. If so, set a flag to generate an enhanced contribute relation and no temporary total.
1972  --If the rounding operator is a root operator of a numeric rule with an advanced lhs expression,
1973  --which is indicated by the optimizeChain flag, generate the optimized contribute relation.
1974 
1975  IF(v_tExprParentId(j) IS NOT NULL)THEN
1976 
1977    v_parj := v_IndexByExprNodeId(v_tExprParentId(j));
1978 
1979    IF(v_tExprType(v_parj) = EXPR_NODE_TYPE_OPERATOR AND
1980       v_tExprSubtype(v_parj) IN (OPERATOR_ROUND, OPERATOR_CEILING, OPERATOR_FLOOR, OPERATOR_TRUNCATE))THEN
1981 
1982       v_rounding := OperatorLiterals(v_tExprSubtype(v_parj));
1983       generateRound := OPTIMIZATION_COMPLETED;
1984 
1985       IF(optimizeChain = OPTIMIZATION_REQUESTED)THEN
1986 
1987         optimizeChain := OPTIMIZATION_COMPLETED;
1988         doOptimize := 1;
1989       END IF;
1990    END IF;
1991  END IF;
1992 
1993  --If the operator has just two operands, only one contribute relation will be generated, prepare
1994  --variables for this relation.
1995 
1996  IF(v_child.COUNT = 2)THEN
1997 
1998    v_actual := v_rounding;
1999    IF(doOptimize = 1)THEN
2000 
2001      v_target := NULL;
2002      v_return(1) := optimizeTarget;
2003    END IF;
2004  END IF;
2005 
2006  vLogicLine := v_target || 'CONTRIBUTE ' || v_child(1) || v_oper || v_child(2) || ' ' ||
2007                v_return(1) || v_actual || '... ' || TO_CHAR(nReasonId) || NewLine;
2008 
2009  PACK;
2010 
2011  v_current := v_return(1);
2012  v_actual := ' ';
2013 
2014  FOR i IN 3..v_child.COUNT LOOP
2015 
2016   v_return(1) := t_prefix || v_name || '_' || TO_CHAR(i-1);
2017   v_target := 'TOTAL ' || v_return(1) || NewLine;
2018 
2019   --If the operator has more than two operands, two or more contribute relations will be
2020   --generated. We want to modify only the last of them, so prepare the variables before
2021   --generating the last one.
2022 
2023   IF(i = v_child.COUNT)THEN
2024 
2025    v_actual := v_rounding;
2026    IF(doOptimize = 1)THEN
2027 
2028      v_target := NULL;
2029      v_return(1) := optimizeTarget;
2030    END IF;
2031   END IF;
2032 
2033   vLogicLine := v_target || 'CONTRIBUTE ' || v_child(i) || v_oper || v_current || ' ' ||
2034                 v_return(1) || v_actual || '... ' || TO_CHAR(nReasonId) || NewLine;
2035 
2036   v_current := v_return(1);
2037   PACK;
2038 
2039  END LOOP;
2040  RETURN v_return;
2041 END;
2042 ---------------------------------------------------------------------------------------
2043 FUNCTION GENERATE_OF(j IN PLS_INTEGER) RETURN tStringArray IS
2044  v_return  tStringArray;
2045  v_result  tIntegerArray;
2046  nChild    PLS_INTEGER;
2047 BEGIN
2048 
2049  IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
2050   RAISE CZ_E_WRONG_OF_OPERATOR;
2051  END IF;
2052 
2053  nChild := v_ChildrenIndex(v_tExprId(j));
2054  v_result := EXPAND_NODE(j);
2055 
2056  FOR i IN 1..v_result.COUNT LOOP
2057 
2058    v_return(i) := GENERATE_NAME_EXPL(v_ExplByPsNodeId(v_result(i)), v_result(i));
2059  END LOOP;
2060 
2061  RETURN v_return;
2062 END;
2063 ---------------------------------------------------------------------------------------
2064 FUNCTION GENERATE_NOT(j IN PLS_INTEGER) RETURN tStringArray IS
2065  v_return  tStringArray;
2066  nChild    PLS_INTEGER;
2067  oper      tStringArray;
2068  ListType  PLS_INTEGER;
2069 BEGIN
2070 
2071  IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
2072   RAISE CZ_E_WRONG_NOT_OPERATOR;
2073  END IF;
2074 
2075  nChild := v_ChildrenIndex(v_tExprId(j));
2076  IF(v_tExprParentId.EXISTS(nChild + 1) AND v_tExprParentId(nChild + 1) = v_tExprId(j))THEN
2077   RAISE CZ_E_WRONG_NOT_OPERATOR;
2078  END IF;
2079 
2080  IF(NOT HAS_LOGICAL_VALUE(nChild))THEN
2081   nParam := j;
2082   RAISE CZ_E_INVALID_OPERAND_TYPE;
2083  END IF;
2084 
2085  --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
2086  nLocalDefaults := nLocalDefaults + 1;
2087  v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2088 
2089  oper := GENERATE_EXPRESSION(nChild, ListType);
2090 
2091  vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2092                'GS N ... ' || TO_CHAR(nReasonId) || NewLine ||
2093                'GL' || OperatorLetters(OPERATOR_ANYOF) || oper(1) || NewLine ||
2094                'GR' || OperatorLetters(OPERATOR_ANYOF) || v_return(1) || NewLine;
2095  PACK;
2096 
2097  RETURN v_return;
2098 END;
2099 ---------------------------------------------------------------------------------------
2100 FUNCTION GENERATE_NOTTRUE(j IN PLS_INTEGER) RETURN tStringArray IS
2101  v_return    tStringArray;
2102  nChild      PLS_INTEGER;
2103  oper        tStringArray;
2104  ListType    PLS_INTEGER;
2105  v_NodeId    NUMBER; --kdande; Bug 6881902; 11-Mar-2008
2106  v_HeaderId  NUMBER;
2107  v_nodename  VARCHAR2(4000);
2108  v_accuname  VARCHAR2(4000);
2109  iLocal      PLS_INTEGER;
2110 BEGIN
2111 
2112  IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
2113   RAISE CZ_E_WRONG_NOTTRUE_OPERATOR;
2114  END IF;
2115 
2116  nChild := v_ChildrenIndex(v_tExprId(j));
2117  IF(v_tExprParentId.EXISTS(nChild + 1) AND v_tExprParentId(nChild + 1) = v_tExprId(j))THEN
2118   RAISE CZ_E_WRONG_NOTTRUE_OPERATOR;
2119  END IF;
2120 
2121  IF(NOT HAS_LOGICAL_VALUE(nChild))THEN
2122   nParam := j;
2123   RAISE CZ_E_INVALID_OPERAND_TYPE;
2124  END IF;
2125 
2126  --OptimizeNotTrue is a db setting which is disabled by default.
2127 
2128  IF(OptimizeNotTrue = 0 OR v_tExprType(nChild) <> EXPR_NODE_TYPE_NODE)THEN
2129 
2130    --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
2131    nLocalDefaults := nLocalDefaults + 1;
2132    v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2133 
2134    oper := GENERATE_EXPRESSION(nChild, ListType);
2135 
2136    vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2137                  'NOTTRUE ' || oper(1) || ' ' || v_return(1) || ' ... ' || TO_CHAR(nReasonId) || NewLine;
2138    PACK;
2139  ELSE
2140 
2141    v_NodeId := v_tExprPsNodeId(nChild);
2142 
2143    IF((NOT v_HeaderByNotTrueId.EXISTS(v_NodeId)) AND
2144       (glAccumulator(v_NodeId) IS NULL OR glAccumulator(v_NodeId) = FLAG_NO_ACCUMULATOR))THEN
2145 
2146      --Need to generate a new NOTTRUE relation in the node's structure file
2147 
2148      v_HeaderId := glHeaderByPsNodeId(v_NodeId);
2149      v_nodename := 'P_' || TO_CHAR(glPersistentId(v_NodeId));
2150      v_accuname := v_nodename || '_NT';
2151 
2152      --Flush off the buffer because we are about to write to another file
2153 
2154      IF(vLogicText IS NOT NULL)THEN
2155        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
2156         (nHeaderId, v_tSequenceNbr(nHeaderId), vLogicText);
2157        vLogicText := NULL;
2158        v_tSequenceNbr(nHeaderId) := v_tSequenceNbr(nHeaderId) + 1;
2159      END IF;
2160 
2161      --Fix for the bug #2398832 - we may be re-using the accumulator, so we should not
2162      --assign to it effectivities and usages of a particular node.
2163      --Do not write the effectivity dates using the actual effective date interval of
2164      --the corresponding node.
2165 
2166      --iLocal := glIndexByPsNodeId(v_NodeId);
2167      --CurrentEffFrom := glEffFrom(iLocal);
2168      --CurrentEffUntil := glEffUntil(iLocal);
2169      --CurrentUsageMask := glUsageMask(iLocal);
2170 
2171      --Instead make the accumulator always effective and universal.
2172 
2173      CurrentEffFrom := EpochBeginDate;
2174      CurrentEffUntil := EpochEndDate;
2175      CurrentUsageMask := AnyUsageMask;
2176 
2177      IF((NOT h_EffFrom.EXISTS(v_HeaderId)) OR
2178         (h_EffFrom(v_HeaderId) <> CurrentEffFrom OR h_EffUntil(v_HeaderId) <> CurrentEffUntil OR
2179          h_EffUsageMask(v_HeaderId) <> CurrentUsageMask))THEN
2180 
2181        h_EffFrom(v_HeaderId) := CurrentEffFrom;
2182        h_EffUntil(v_HeaderId) := CurrentEffUntil;
2183        h_EffUsageMask(v_HeaderId) := CurrentUsageMask;
2184 
2185        vLogicText := LTRIM(CurrentUsageMask, '0');
2186        IF(vLogicText IS NOT NULL) THEN
2187          vLogicText := EffUsagePrefix || vLogicText;
2188        END IF;
2189 
2190        IF(CurrentEffFrom = EpochBeginDate)THEN
2191          CurrentFromDate := NULL;
2192        ELSE
2193          CurrentFromDate := TO_CHAR(CurrentEffFrom, EffDateFormat);
2194        END IF;
2195 
2196        IF(CurrentEffUntil = EpochEndDate)THEN
2197          CurrentUntilDate := NULL;
2198        ELSE
2199          CurrentUntilDate := TO_CHAR(CurrentEffUntil, EffDateFormat);
2200        END IF;
2201 
2202        vLogicText := 'EFF ' || CurrentFromDate || ', ' || CurrentUntilDate || ', ' || vLogicText || NewLine;
2203      END IF;
2204 
2205      vLogicText := vLogicText || 'OBJECT ' || v_accuname || NewLine ||
2206                    'NOTTRUE ' || v_nodename || ' ' || v_accuname || ' ... ' || TO_CHAR(nReasonId) || NewLine;
2207 
2208      INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
2209       (v_HeaderId, vSeqNbrByHeader(v_HeaderId), vLogicText);
2210      vLogicText := NULL;
2211      vSeqNbrByHeader(v_HeaderId) := vSeqNbrByHeader(v_HeaderId) + 1;
2212 
2213      v_HeaderByNotTrueId(v_NodeId) := v_HeaderId;
2214 
2215      --Part of the fix for the bug #2857955. We will never be here if glAccumulator(v_NodeId) was
2216      --FLAG_ACCUMULATOR_NT because the accumulator would have already been created.
2217 
2218      UPDATE cz_ps_nodes SET
2219        accumulator_flag = DECODE(glAccumulator(v_NodeId), FLAG_ACCUMULATOR_ACC, FLAG_ACCUMULATOR_BOTH, FLAG_ACCUMULATOR_NT)
2220      WHERE ps_node_id = v_NodeId;
2221 
2222    END IF;
2223 
2224    v_return(1) := GENERATE_NAME(nChild, v_NodeId) || '_NT';
2225  END IF;
2226 
2227  RETURN v_return;
2228 END;
2229 ---------------------------------------------------------------------------------------
2230 FUNCTION COMPARE_VALUES(val1 IN VARCHAR2, val2 IN VARCHAR2, OperType IN PLS_INTEGER)
2231 RETURN BOOLEAN IS
2232   v_null  NUMBER;
2233 BEGIN
2234   IF(OperType = OPERATOR_EQUALS)THEN
2235     RETURN (val1 = val2);
2236   ELSIF(OperType = OPERATOR_NOTEQUALS)THEN
2237     RETURN (val1 <> val2);
2238   ELSIF(OperType = OPERATOR_EQUALS_INT)THEN
2239     RETURN (val1 = val2);
2240   ELSIF(OperType = OPERATOR_NOTEQUALS_INT)THEN
2241     RETURN (val1 <> val2);
2242   ELSIF(OperType = OPERATOR_GT)THEN
2243     RETURN (val1 > val2);
2244   ELSIF(OperType = OPERATOR_LT)THEN
2245     RETURN (val1 < val2);
2246   ELSIF(OperType = OPERATOR_GE)THEN
2247     RETURN (val1 >= val2);
2248   ELSIF(OperType = OPERATOR_LE)THEN
2249     RETURN (val1 <= val2);
2250   ELSIF(OperType = OPERATOR_BEGINSWITH)THEN
2251     RETURN (INSTR(val1, val2) = 1);
2252   ELSIF(OperType = OPERATOR_ENDSWITH)THEN
2253     RETURN (INSTR(val1, val2, -1) = (LENGTH(val1) - LENGTH(val2) + 1));
2254   ELSIF(OperType = OPERATOR_CONTAINS)THEN
2255     RETURN (INSTR(val1, val2) <> 0);
2256   ELSIF(OperType = OPERATOR_LIKE)THEN
2257     BEGIN
2258       SELECT NULL INTO v_null FROM DUAL WHERE val1 LIKE val2;
2259       RETURN TRUE;
2260     EXCEPTION
2261       WHEN NO_DATA_FOUND THEN
2262         RETURN FALSE;
2263     END;
2264   ELSIF(OperType = OPERATOR_MATCHES)THEN
2265     BEGIN
2266       SELECT NULL INTO v_null FROM DUAL WHERE val1 LIKE val2;
2267       RETURN TRUE;
2268     EXCEPTION
2269       WHEN NO_DATA_FOUND THEN
2270         RETURN FALSE;
2271     END;
2272   ELSIF(OperType = OPERATOR_DOESNOTBEGINWITH)THEN
2273     RETURN (INSTR(val1, val2) <> 1);
2274   ELSIF(OperType = OPERATOR_DOESNOTENDWITH)THEN
2275     RETURN (INSTR(val1, val2, -1) <> (LENGTH(val1) - LENGTH(val2) + 1));
2276   ELSIF(OperType = OPERATOR_DOESNOTCONTAIN)THEN
2277     RETURN (INSTR(val1, val2) = 0);
2278   ELSIF(OperType = OPERATOR_NOTLIKE)THEN
2279     BEGIN
2280       SELECT NULL INTO v_null FROM DUAL WHERE val1 NOT LIKE val2;
2281       RETURN TRUE;
2282     EXCEPTION
2283       WHEN NO_DATA_FOUND THEN
2284         RETURN FALSE;
2285     END;
2286   ELSE
2287     RAISE CZ_E_WRONG_COMPARISON_OPER;
2288   END IF;
2289 END;
2290 ---------------------------------------------------------------------------------------
2291 FUNCTION EXTRACT_PROPERTY_VALUE(inVal IN VARCHAR2, inType IN PLS_INTEGER)
2292 RETURN VARCHAR2 IS
2293 BEGIN
2294   IF(inType = DATATYPE_STRING)THEN
2295     RETURN SUBSTR(inVal, INSTR(inVal, PROPERTY_DELIMITER) + 1);
2296   ELSE
2297     RETURN inVal;
2298   END IF;
2299 END;
2300 ---------------------------------------------------------------------------------------
2301 FUNCTION EXTRACT_PROPERTY_VALUE(inVal IN VARCHAR2)
2302 
2303 --This simplified version is used in GENERATE_REFNODE to extract boolean property values
2304 --represented as character '0'/'1' in the database.
2305 
2306 RETURN VARCHAR2 IS
2307 BEGIN
2308     RETURN SUBSTR(inVal, INSTR(inVal, PROPERTY_DELIMITER) + 1);
2309 END;
2310 ---------------------------------------------------------------------------------------
2311 FUNCTION EXTRACT_PROPERTY_NODE(inVal IN VARCHAR2) RETURN VARCHAR2 IS
2312 BEGIN
2313   RETURN SUBSTR(inVal, 1, INSTR(inVal, PROPERTY_DELIMITER) - 1);
2314 END;
2315 ---------------------------------------------------------------------------------------
2316 FUNCTION GENERATE_CONCAT(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
2317  v_return  tStringArray;
2318  nChild    PLS_INTEGER;
2319  lhs       tStringArray;
2320  rhs       tStringArray;
2321  lListType PLS_INTEGER;
2322  rListType PLS_INTEGER;
2323  ExprId    NUMBER := v_tExprId(j); --Bug13566997
2324 BEGIN
2325 
2326   IF(NOT v_ChildrenIndex.EXISTS(ExprId))THEN
2327    RAISE CZ_E_WRONG_COMPARISON_OPER;
2328   END IF;
2329 
2330   nChild := v_ChildrenIndex(ExprId);
2331   IF(NOT v_tExprParentId.EXISTS(nChild + 1) OR v_tExprParentId(nChild + 1) IS NULL OR
2332      v_tExprParentId(nChild + 1) <> ExprId)THEN
2333    RAISE CZ_E_WRONG_COMPARISON_OPER;
2334   END IF;
2335 
2336   lhs := GENERATE_EXPRESSION(nChild, lListType);
2337   rhs := GENERATE_EXPRESSION(nChild+1, rListType);
2338 
2339   v_return(1) := EXTRACT_PROPERTY_VALUE(lhs(1)) || EXTRACT_PROPERTY_VALUE(rhs(1));
2340   ListType := DATA_TYPE_TEXT;
2341  RETURN v_return;
2342 END;
2343 ---------------------------------------------------------------------------------------
2344 --Bug 5620750 - function to generate the new ToText operator when used outside of PBC
2345 --context.
2346 
2347 FUNCTION GENERATE_TOTEXT(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
2348  v_return  tStringArray;
2349  ExprId    NUMBER := v_tExprId(j); --Bug13566997
2350 BEGIN
2351 
2352   IF((NOT v_ChildrenIndex.EXISTS(ExprId)) OR v_NumberOfChildren(ExprId) <> 1)THEN
2353     RAISE CZ_R_WRONG_EXPRESSION_NODE;
2354   END IF;
2355 
2356   v_return(1) := TO_CHAR(v_tExprDataNumValue(v_ChildrenIndex(ExprId)));
2357   ListType := DATA_TYPE_TEXT;
2358  RETURN v_return;
2359 END;
2360 ---------------------------------------------------------------------------------------
2361 FUNCTION GENERATE_COMPARE(j IN PLS_INTEGER) RETURN tStringArray IS
2362  v_return  tStringArray;
2363  v_left    tStringArray;
2364  nChild    PLS_INTEGER;
2365  lhs       tStringArray;
2366  rhs       tStringArray;
2367  lListType PLS_INTEGER;
2368  rListType PLS_INTEGER;
2369  OperType  PLS_INTEGER := v_tExprSubtype(j);
2370  ExprId    NUMBER := v_tExprId(j); --Bug13566997
2371  nCount    PLS_INTEGER := 1;
2372 BEGIN
2373 
2374  IF(NOT v_ChildrenIndex.EXISTS(ExprId))THEN
2375   RAISE CZ_E_WRONG_COMPARISON_OPER;
2376  END IF;
2377 
2378  nChild := v_ChildrenIndex(ExprId);
2379  IF(NOT v_tExprParentId.EXISTS(nChild + 1) OR v_tExprParentId(nChild + 1) IS NULL OR
2380     v_tExprParentId(nChild + 1) <> ExprId)THEN
2381   RAISE CZ_E_WRONG_COMPARISON_OPER;
2382  END IF;
2383 
2384 nDebug := 8001120;
2385 
2386  --v_return(1) := 'T_' || TO_CHAR(ExprId);
2387  nLocalDefaults := nLocalDefaults + 1;
2388  v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2389 
2390 nDebug := 8001121;
2391 
2392  generateCompare := 1;
2393  lhs := GENERATE_EXPRESSION(nChild, lListType);
2394 
2395 nDebug := 8001122;
2396 
2397  rhs := GENERATE_EXPRESSION(nChild+1, rListType);
2398  generateCompare := 0;
2399 
2400   --Bug #4191838.
2401 
2402   IF(lhs.COUNT = 1 AND lListType = DATA_TYPE_TEXT AND rhs.COUNT = 1 AND rListType = DATA_TYPE_TEXT)THEN
2403 
2404      v_left(1) := 'OBJECT ' || v_return(1) || NewLine;
2405      v_left(2) := TO_CHAR(nReasonId) || NewLine ||
2406                   'GL' || OperatorLetters(OPERATOR_ALLOF) || ALWAYS_TRUE || NewLine ||
2407                   'GR' || OperatorLetters(OPERATOR_ALLOF) || v_return(1) || NewLine;
2408 
2409      IF(COMPARE_VALUES(EXTRACT_PROPERTY_VALUE(lhs(1), lListType),
2410                        EXTRACT_PROPERTY_VALUE(rhs(1), rListType), OperType))THEN
2411        vLogicLine := v_left(1) || 'GS R ... ' || v_left(2);
2412      ELSE
2413        vLogicLine := v_left(1) || 'GS E ... ' || v_left(2);
2414      END IF;
2415     PACK;
2416     RETURN v_return;
2417    END IF;
2418 
2419 nDebug := 8001123;
2420 
2421  IF(lListType = DATATYPE_STRING OR rListType = DATATYPE_STRING)THEN
2422 
2423 nDebug := 8001124;
2424 
2425   FOR ii IN 1..lhs.COUNT LOOP
2426    FOR jj IN 1..rhs.COUNT LOOP
2427 
2428     IF(COMPARE_VALUES(EXTRACT_PROPERTY_VALUE(lhs(ii), lListType),
2429                       EXTRACT_PROPERTY_VALUE(rhs(jj), rListType), OperType))THEN
2430      IF(lListType = DATATYPE_STRING AND rListType = DATATYPE_STRING)THEN
2431 
2432 nDebug := 8001125;
2433 
2434        v_left(nCount) := v_return(1) || '_' || TO_CHAR(nCount);
2435 
2436        vLogicLine := 'OBJECT ' || v_left(nCount) || NewLine ||
2437                      'GS R ' || sUnsatisfiedId || '... ' || TO_CHAR(nReasonId) || NewLine ||
2438                      'GL' || OperatorLetters(OPERATOR_ALLOF) ||
2439                       EXTRACT_PROPERTY_NODE(lhs(ii)) || ' ' || EXTRACT_PROPERTY_NODE(rhs(jj)) || NewLine ||
2440                      'GR' || OperatorLetters(OPERATOR_ALLOF) || v_left(nCount) || NewLine;
2441        PACK;
2442        nCount := nCount + 1;
2443 
2444      ELSIF(lListType = DATATYPE_STRING)THEN
2445 
2446 nDebug := 8001126;
2447 
2448        v_left(nCount) := EXTRACT_PROPERTY_NODE(lhs(ii));
2449        nCount := nCount + 1;
2450 
2451      ELSIF(rListType = DATATYPE_STRING)THEN
2452 
2453 nDebug := 8001127;
2454 
2455        v_left(nCount) := EXTRACT_PROPERTY_NODE(rhs(jj));
2456        nCount := nCount + 1;
2457 
2458      END IF;
2459     END IF;
2460    END LOOP;
2461   END LOOP;
2462 
2463 nDebug := 8001128;
2464 
2465   IF(v_left.COUNT = 0)THEN
2466 
2467     vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2468                   'GS E ...' || TO_CHAR(nReasonId) || NewLine ||
2469                   'GL' || OperatorLetters(OPERATOR_ALLOF) || ALWAYS_TRUE || NewLine ||
2470                   'GR' || OperatorLetters(OPERATOR_ALLOF) || v_return(1) || NewLine;
2471 
2472   ELSE
2473 
2474     localString := NULL;
2475     IF(v_left.COUNT > 1)THEN localString := sUnsatisfiedId; END IF;
2476 
2477     vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2478                   'GS R ' || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
2479                   'GL' || OperatorLetters(OPERATOR_ANYOF);
2480 
2481     PACK;
2482 
2483 nDebug := 8001129;
2484 
2485     FOR i IN 1..v_left.COUNT LOOP
2486 
2487       vLogicLine := v_left(i) || ' ';
2488       PACK;
2489 
2490     END LOOP;
2491 
2492     vLogicLine := NewLine || 'GR' || OperatorLetters(OPERATOR_ALLOF) || v_return(1) || NewLine;
2493 
2494 nDebug := 8001130;
2495 
2496   END IF;
2497 
2498  ELSE
2499 
2500 nDebug := 8001131;
2501 
2502    vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2503                  'COMPARE ' || lhs(1) || OperatorLiterals(OperType) ||
2504                  rhs(1) || ' ' || v_return(1) || ' ... ' || TO_CHAR(nReasonId) || NewLine;
2505  END IF;
2506 
2507  PACK;
2508 
2509  RETURN v_return;
2510 END;
2511 ---------------------------------------------------------------------------------------
2512 FUNCTION GENERATE_ANYALLOF(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
2513  v_return    tStringArray;
2514  v_child     tStringArray;
2515  v_parentid  NUMBER;
2516  v_parj      PLS_INTEGER;
2517  nChild      PLS_INTEGER;
2518 BEGIN
2519 
2520 --nDebug := 7000001;
2521 
2522  --Bug #5015333 - need a verification for the logical nature of the operands.
2523 
2524  nChild := v_ChildrenIndex(v_tExprId(j));
2525 
2526  WHILE(v_tExprParentId(nChild) = v_tExprId(j)) LOOP
2527 
2528    IF(NOT HAS_LOGICAL_VALUE(nChild))THEN
2529 
2530      nParam := j;
2531      RAISE CZ_E_INVALID_OPERAND_TYPE;
2532    END IF;
2533 
2534    nChild := nChild + 1;
2535  END LOOP;
2536 
2537  v_child := GENERATE_NODE_CHILDREN(j);
2538  v_parentid := v_tExprParentId(j);
2539 
2540  --This is important that this assignment goes after the node children generation, because the
2541  --type of the parent operator can be changed during the children generation in some cases
2542  --(see internal case #3 below).
2543 
2544  ListType := v_tExprSubtype(j);
2545 
2546  IF(OptimizeAllAnyOf = 1)THEN
2547    IF(v_parentid IS NOT NULL)THEN
2548 
2549      v_parj := v_IndexByExprNodeId(v_parentid);
2550 
2551      IF(v_tExprType(v_parj) = EXPR_NODE_TYPE_OPERATOR AND
2552         v_tExprSubtype(v_parj) IN (OPERATOR_ANYOF, OPERATOR_ALLOF))THEN
2553 
2554        IF(ListType = v_tExprSubtype(v_parj))THEN
2555 
2556          --AllOf(AllOf(...) , ...), AnyOf(AnyOf(...) , ...).
2557          --Internal case #1.
2558 
2559          return v_child;
2560        ELSIF(v_child.COUNT = 1)THEN
2561 
2562          --This operator is either AnyOf or AllOf. It is different from the parent operator which
2563          --is also AnyOf or AllOf. Therefore, this is AllOf(AnyOf(...) , ...) or
2564          --AnyOf(AllOf(...) , ...). If only one child has been generated for this operator than
2565          --we have the case of AllOf(AnyOf(1) , ...) or AnyOf(AllOf(1) , ...).
2566          --Internal case #2.
2567 
2568          return v_child;
2569 
2570        ELSIF(v_NumberOfChildren(v_parentid) = 1)THEN
2571 
2572          --We have AllOf(AnyOf(...)) or AnyOf(AllOf(...)), i. e. this AllOf or AnyOf operator is
2573          --the only child of its parent.If so, we not only carry over the children list but also
2574          --reverse the type of the parent operator.
2575          --Internal case #3.
2576 
2577          v_tExprSubtype(v_parj) := ListType;
2578          return v_child;
2579        END IF;
2580      END IF;
2581    ELSIF(nRuleType = RULE_TYPE_LOGIC_RULE)THEN
2582      IF(nRuleOperator <> RULE_OPERATOR_DEFAULTS OR j = jConsequentRoot)THEN
2583        return v_child;
2584      ELSIF(v_child.COUNT = 1)THEN
2585        return v_child;
2586      END IF;
2587    END IF;
2588  END IF;
2589 
2590 --nDebug := 7000002;
2591 
2592  --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
2593  nLocalDefaults := nLocalDefaults + 1;
2594  v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2595 
2596 --nDebug := 7000003;
2597 
2598  localString := NULL;
2599  IF(v_child.COUNT > 1)THEN localString := sUnsatisfiedId; END IF;
2600 
2601  vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2602                'GS R ' || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
2603                'GL' || OperatorLetters(ListType);
2604 
2605  PACK;
2606 
2607  IF(ChangeChildrenOrder = 1)THEN
2608    FOR i IN REVERSE 1..v_child.COUNT LOOP
2609 
2610      vLogicLine := v_child(i) || ' ';
2611      PACK;
2612 
2613    END LOOP;
2614  ELSE
2615    FOR i IN 1..v_child.COUNT LOOP
2616 
2617      vLogicLine := v_child(i) || ' ';
2618      PACK;
2619 
2620    END LOOP;
2621  END IF;
2622 
2623 --nDebug := 7000004;
2624 
2625  vLogicLine := NewLine || 'GR' || OperatorLetters(OPERATOR_ALLOF) || v_return(1) || NewLine;
2626  PACK;
2627  RETURN v_return;
2628 END;
2629 ---------------------------------------------------------------------------------------
2630 FUNCTION GENERATE_ANDOR(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
2631  v_return  tStringArray;
2632  nChild    PLS_INTEGER;
2633  lhs       tStringArray;
2634  rhs       tStringArray;
2635  lListType PLS_INTEGER;
2636  rListType PLS_INTEGER;
2637 BEGIN
2638 
2639  IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 2)THEN
2640   RAISE CZ_E_WRONG_ANDOR_OPERATOR;
2641  END IF;
2642 
2643  nChild := v_ChildrenIndex(v_tExprId(j));
2644 
2645  IF(NOT (HAS_LOGICAL_VALUE(nChild) AND HAS_LOGICAL_VALUE(nChild + 1)))THEN
2646   nParam := j;
2647   RAISE CZ_E_INVALID_OPERAND_TYPE;
2648  END IF;
2649 
2650  IF(OptimizeAllAnyOf = 1)THEN
2651    IF(v_tExprSubtype(j) = OPERATOR_AND)THEN
2652      v_tExprSubtype(j) := OPERATOR_ALLOF;
2653    ELSE
2654      v_tExprSubtype(j) := OPERATOR_ANYOF;
2655    END IF;
2656    RETURN GENERATE_ANYALLOF(j, ListType);
2657  END IF;
2658 
2659 nDebug := 8001700;
2660 
2661  --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
2662  nLocalDefaults := nLocalDefaults + 1;
2663  v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2664 
2665  lhs := GENERATE_EXPRESSION(nChild, lListType);
2666  rhs := GENERATE_EXPRESSION(nChild+1, rListType);
2667 
2668 nDebug := 8001701;
2669 
2670  vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2671                'GS R ' || sUnsatisfiedId || '... ' || TO_CHAR(nReasonId) || NewLine ||
2672                'GL' || OperatorLetters(v_tExprSubtype(j)) || lhs(1) || ' ' || rhs(1) || NewLine ||
2673                'GR' || OperatorLetters(OPERATOR_ANYOF) || v_return(1) || NewLine;
2674  PACK;
2675 
2676 nDebug := 8001702;
2677 
2678  RETURN v_return;
2679 END;
2680 ---------------------------------------------------------------------------------------
2681 FUNCTION GENERATE_ROUND(j IN PLS_INTEGER) RETURN tStringArray IS
2682  v_return  tStringArray;
2683  nChild    PLS_INTEGER;
2684  oper      tStringArray;
2685  ListType  PLS_INTEGER;
2686 BEGIN
2687 
2688  IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
2689   RAISE CZ_E_WRONG_ROUND_OPERATOR;
2690  END IF;
2691 
2692  nChild := v_ChildrenIndex(v_tExprId(j));
2693  IF(v_tExprParentId.EXISTS(nChild + 1) AND v_tExprParentId(nChild + 1)= v_tExprId(j))THEN
2694 
2695   RAISE CZ_E_WRONG_ROUND_OPERATOR;
2696  END IF;
2697 
2698  generateRound := OPTIMIZATION_REQUESTED;
2699 
2700  oper := GENERATE_EXPRESSION(nChild, ListType);
2701 
2702  --The value may have been changed by the child expression generation. In this case we are
2703  --optimizing and do not want the increment relation to be generated at all.
2704 
2705  IF(generateRound = OPTIMIZATION_REQUESTED)THEN
2706 
2707    --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
2708    nLocalDefaults := nLocalDefaults + 1;
2709    v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2710 
2711    vLogicLine := 'TOTAL ' || v_return(1) || NewLine || 'INC ' || oper(1) || ' ' || v_return(1) ||
2712                  OperatorLiterals(v_tExprSubtype(j)) || '... ' || TO_CHAR(nReasonId) || NewLine;
2713    PACK;
2714    generateRound := OPTIMIZATION_COMPLETED;
2715  ELSE
2716 
2717    v_return(1) := oper(1);
2718  END IF;
2719 
2720  RETURN v_return;
2721 END;
2722 ---------------------------------------------------------------------------------------
2723 FUNCTION PROPERTY_VALUE(j IN PLS_INTEGER, iPSN IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER)
2724 RETURN VARCHAR2 IS
2725   v_return      VARCHAR2(4000);
2726   nChild        NUMBER;
2727   c_values      refCursor;
2728   optionId      cz_ps_nodes.ps_node_id%TYPE := glPsNodeId(iPSN);
2729   propertyId    cz_expression_nodes.property_id%TYPE := v_tExprPropertyId(j);
2730   itemId        cz_ps_nodes.item_id%TYPE := glItemId(iPSN);
2731   sysPropName   VARCHAR2(30);
2732 BEGIN
2733 
2734   IF(v_tExprType(j) = EXPR_SYS_PROP)THEN
2735 
2736    IF(NOT h_SeededName.EXISTS(v_tExprSubtype(j)))THEN RAISE CZ_E_BAD_PROPERTY_TYPE; END IF;
2737    sysPropName := h_SeededName(v_tExprSubtype(j));
2738 
2739    IF(sysPropName = RULE_SYS_PROP_NAME)THEN
2740 
2741 --nDebug := 8001160;
2742 
2743      v_return := glName(iPSN);
2744      ListType := DATATYPE_STRING;
2745 
2746    ELSIF(sysPropName = RULE_SYS_PROP_QUANTITY)THEN
2747 
2748      --Related bug: #2317427.
2749 
2750      v_return := GENERATE_NAME(j, optionId);
2751      ListType := DATATYPE_INTEGER;
2752 
2753    ELSIF(sysPropName = RULE_SYS_PROP_INSTANCECOUNT)THEN
2754 
2755 --nDebug := 8001161;
2756 
2757      --If it is a non-virtual component/product/reference, we add _ACTUALCOUNT to the name.
2758      --If it is a virtual component/product/reference, we return '1'.
2759      --If it is an option, we just generate the name.
2760 
2761      IF(glPsNodeType(iPSN) IN (PS_NODE_TYPE_COMPONENT,
2762                                PS_NODE_TYPE_REFERENCE,
2763                                PS_NODE_TYPE_PRODUCT))THEN
2764       IF(glVirtualFlag(iPSN) = FLAG_NON_VIRTUAL)THEN
2765        v_return := GENERATE_NAME(j, optionId)||'_ACTUALCOUNT';
2766       ELSE
2767        v_return := '1';
2768       END IF;
2769      ELSE
2770        v_return := GENERATE_NAME(j, optionId);
2771      END IF;
2772      ListType := DATATYPE_INTEGER;
2773 
2774 --nDebug := 8001162;
2775 
2776    ELSIF(sysPropName = RULE_SYS_PROP_MININSTANCE)THEN
2777 
2778 --nDebug := 8001163;
2779 
2780      v_return := GENERATE_NAME(j, optionId)||'_MIN';
2781      ListType := DATATYPE_INTEGER;
2782 
2783    ELSIF(sysPropName = RULE_SYS_PROP_MAXINSTANCE)THEN
2784 
2785 --nDebug := 8001164;
2786 
2787      v_return := GENERATE_NAME(j, optionId)||'_MAX';
2788      ListType := DATATYPE_INTEGER;
2789 
2790    ELSE
2791 
2792      RAISE CZ_E_BAD_PROPERTY_TYPE;
2793    END IF;
2794   ELSE
2795 
2796    BEGIN
2797 
2798 --nDebug := 8001165;
2799 
2800      v_return := GET_PROPERTY_VALUE(optionId, propertyId, itemId, ListType);
2801 
2802      IF(v_return IS NULL)THEN RAISE CZ_E_NULL_PROPERTY_VALUE; END IF;
2803 
2804      IF(ListType IN (DATATYPE_INTEGER, DATATYPE_FLOAT))THEN
2805 
2806        BEGIN
2807          nChild := TO_NUMBER(v_return);
2808        EXCEPTION
2809          WHEN OTHERS THEN
2810 
2811            SELECT name INTO errorMessage
2812              FROM cz_properties
2813             WHERE property_id = propertyId;
2814 
2815            localString := v_return;
2816            RAISE CZ_R_INCORRECT_DATA_TYPE;
2817        END;
2818      END IF;
2819 
2820    EXCEPTION
2821      WHEN NO_DATA_FOUND THEN
2822        RAISE CZ_E_NO_SUCH_PROPERTY;
2823      WHEN TOO_MANY_ROWS THEN
2824        RAISE CZ_E_INCORRECT_PROPERTY;
2825      WHEN OTHERS THEN
2826        RAISE;
2827    END;
2828   END IF;
2829 
2830  RETURN v_return;
2831 END;
2832 ---------------------------------------------------------------------------------------
2833 FUNCTION STATIC_SYSPROP_VALUE(p_node_id IN NUMBER, p_rule_id IN NUMBER, p_parent_up IN PLS_INTEGER)
2834 RETURN VARCHAR2 IS
2835 
2836   optionIndex  PLS_INTEGER;
2837   v_step       PLS_INTEGER := p_parent_up;
2838   sysPropName  cz_rules.name%TYPE;
2839   v_return     VARCHAR2(4000);
2840 BEGIN
2841 
2842   sysPropName := h_SeededName(p_rule_id);
2843   errorMessage := h_ReportName(p_rule_id);
2844   optionIndex := glIndexByPsNodeId(p_node_id);
2845 
2846   BEGIN
2847     WHILE(v_step > 1)LOOP
2848       optionIndex := glIndexByPsNodeId(glParentId(optionIndex));
2849       v_step := v_step - 1;
2850     END LOOP;
2851   EXCEPTION
2852     WHEN OTHERS THEN
2853       RAISE CZ_E_INCORRECT_PROPERTY;
2854   END;
2855 
2856   IF(sysPropName = RULE_SYS_PROP_NAME)THEN
2857 
2858     v_return := glName(optionIndex);
2859 
2860   ELSIF(sysPropName IN (RULE_SYS_PROP_MINVALUE, RULE_SYS_PROP_MINQUANTITY, RULE_SYS_PROP_MINSELECTED))THEN
2861 
2862     v_return := glMinimum(optionIndex);
2863 
2864   ELSIF(sysPropName IN (RULE_SYS_PROP_MAXVALUE, RULE_SYS_PROP_MAXQUANTITY, RULE_SYS_PROP_MAXSELECTED))THEN
2865 
2866     v_return := glMaximum(optionIndex);
2867 
2868   ELSIF(sysPropName = RULE_SYS_PROP_DESCRIPTION)THEN
2869 
2870     RAISE CZ_E_DESCRIPTION_IN_WHERE;
2871   ELSE
2872 
2873     RAISE CZ_E_PROPERTY_NOT_STATIC;
2874   END IF;
2875 
2876  RETURN v_return;
2877 END;
2878 ---------------------------------------------------------------------------------------
2879 FUNCTION SYSTEM_PROPERTY_VALUE(j IN PLS_INTEGER, iPSN IN tStringArray, ListType OUT NOCOPY PLS_INTEGER)
2880 RETURN tStringArray IS
2881 
2882   v_return     tStringArray;
2883   v_result     tStringArray;
2884   optionId     cz_ps_nodes.ps_node_id%TYPE;
2885   propertyId   cz_expression_nodes.property_id%TYPE := v_tExprPropertyId(j);
2886   itemId       cz_ps_nodes.item_id%TYPE;
2887   c_values     refCursor;
2888   nChild       NUMBER;
2889   optionIndex  PLS_INTEGER;
2890   sysPropName  VARCHAR2(30);
2891 BEGIN
2892 
2893 nDebug := 9001000;
2894 
2895  FOR i IN 1..iPSN.COUNT LOOP
2896 
2897    optionId := TO_NUMBER(iPSN(i));
2898    optionIndex := glIndexByPsNodeId(optionId);
2899 
2900    IF(v_tExprType(j) = EXPR_NODE_TYPE_SYSPROP)THEN
2901 
2902      sysPropName := h_SeededName(v_tExprSubtype(j));
2903 
2904      IF(sysPropName = RULE_SYS_PROP_NAME)THEN
2905 
2906        v_return(i) := glName(optionIndex);
2907        ListType := DATA_TYPE_TEXT;
2908 
2909      ELSIF(sysPropName = RULE_SYS_PROP_DESCRIPTION)THEN
2910 
2911        v_return(i) := glName(optionIndex);
2912        ListType := DATA_TYPE_TEXT;
2913 
2914      ELSIF(sysPropName = RULE_SYS_PROP_PARENT)THEN
2915 
2916        v_return(i) := TO_CHAR(glParentId(optionIndex));
2917        ListType := DATA_TYPE_NODE;
2918 
2919      ELSIF(sysPropName = RULE_SYS_PROP_OPTIONS)THEN
2920 
2921        v_result.DELETE;
2922        v_result := GENERATE_CHILDRENOF(v_tExplNodeId(j), TO_NUMBER(iPSN(i)));
2923 
2924        FOR ii IN 1..v_result.COUNT LOOP
2925          v_return(v_return.COUNT + 1) := v_result(ii);
2926        END LOOP;
2927        ListType := DATA_TYPE_NODE_COLL;
2928 
2929      ELSIF(sysPropName = RULE_SYS_PROP_MINVALUE)THEN
2930 
2931        v_return(i) := GENERATE_NAME(j, optionId)||'_MIN';
2932        ListType := DATA_TYPE_INTEGER;
2933 
2934      ELSIF(sysPropName = RULE_SYS_PROP_MAXVALUE)THEN
2935 
2936        v_return(i) := GENERATE_NAME(j, optionId)||'_MAX';
2937        ListType := DATA_TYPE_INTEGER;
2938 
2939      ELSIF(sysPropName = RULE_SYS_PROP_MINQUANTITY)THEN
2940 
2941        v_return(i) := TO_CHAR(glMinimum(optionIndex));
2942        ListType := DATA_TYPE_INTEGER;
2943 
2944      ELSIF(sysPropName = RULE_SYS_PROP_MAXQUANTITY)THEN
2945 
2946        v_return(i) := TO_CHAR(glMaximum(optionIndex));
2947        ListType := DATA_TYPE_INTEGER;
2948 
2949      ELSIF(sysPropName = RULE_SYS_PROP_MINSELECTED)THEN
2950 
2951        v_return(i) := TO_CHAR(glMinimumSel(optionIndex));
2952        ListType := DATA_TYPE_INTEGER;
2953 
2954      ELSIF(sysPropName = RULE_SYS_PROP_MAXSELECTED)THEN
2955 
2956        v_return(i) := TO_CHAR(glMaximumSel(optionIndex));
2957        ListType := DATA_TYPE_INTEGER;
2958 
2959      ELSIF(sysPropName = RULE_SYS_PROP_MININSTANCE)THEN
2960 
2961        IF(v_tExprSubtype(j) = 53)THEN
2962 
2963          --For MinInstances and MaxInstances this is a fix for the bug #3558753.
2964 
2965          --The reason we put two sets of MinInstances/MaxInstances was to support backward compatibility
2966          --of rules using those properties in the LHS. 53 and 54 are not mutable, thus they should not
2967          --be on the RHS (generic validation using the view already takes care of that). The remaining
2968          --part is to hard-code generating '0' for 53 (MinInstances) and '1' for 54 (MaxINstances).
2969          --(see also bug #4366895).
2970 
2971          v_return(i) := '0';
2972        ELSE
2973 
2974          v_return(i) := GENERATE_NAME(j, optionId)||'_MIN';
2975        END IF;
2976        ListType := DATA_TYPE_INTEGER;
2977 
2978      ELSIF(sysPropName = RULE_SYS_PROP_MAXINSTANCE)THEN
2979 
2980        IF(v_tExprSubtype(j) = 54)THEN
2981 
2982          v_return(i) := '1';
2983        ELSE
2984 
2985          v_return(i) := GENERATE_NAME(j, optionId)||'_MAX';
2986        END IF;
2987        ListType := DATA_TYPE_INTEGER;
2988 
2989      ELSIF(sysPropName = RULE_SYS_PROP_STATE)THEN
2990 
2991        v_return(i) := GENERATE_NAME(j, optionId);
2992        ListType := DATA_TYPE_BOOLEAN;
2993 
2994      ELSIF(sysPropName = RULE_SYS_PROP_VALUE)THEN
2995 
2996        v_return(i) := GENERATE_NAME(j, optionId);
2997        ListType := DATA_TYPE_VOID;
2998 
2999      ELSIF(sysPropName = RULE_SYS_PROP_QUANTITY)THEN
3000 
3001        v_return(i) := GENERATE_NAME(j, optionId);
3002        ListType := DATA_TYPE_INTEGER;
3003 
3004      ELSIF(sysPropName = RULE_SYS_PROP_INSTANCECOUNT)THEN
3005 
3006        IF(glPsNodeType(optionIndex) IN (PS_NODE_TYPE_COMPONENT,
3007                                         PS_NODE_TYPE_REFERENCE,
3008                                         PS_NODE_TYPE_PRODUCT))THEN
3009 
3010          --If it is a non-virtual component/product/reference, we add _ACTUALCOUNT to the name.
3011          --If it is a virtual component/product/reference, we return '1'.
3012          --If it is an option, we just generate the name.
3013 
3014          IF(glVirtualFlag(optionIndex) = FLAG_NON_VIRTUAL)THEN
3015            v_return(i) := GENERATE_NAME(j, optionId)||'_ACTUALCOUNT';
3016          ELSE
3017            v_return(i) := '1';
3018          END IF;
3019        ELSE
3020          v_return(i) := GENERATE_NAME(j, optionId);
3021        END IF;
3022 
3023        ListType := DATA_TYPE_INTEGER;
3024      ELSE
3025 
3026        RAISE CZ_E_NO_SUCH_PROPERTY;
3027      END IF;
3028    ELSE
3029 
3030      BEGIN
3031 
3032        itemId := glItemId(optionIndex);
3033 
3034        v_return(i) := GET_PROPERTY_VALUE(optionId, propertyId, itemId, ListType);
3035 
3036        IF(v_return(i) IS NULL)THEN RAISE CZ_E_NULL_PROPERTY_VALUE; END IF;
3037 
3038        IF(ListType IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL))THEN
3039 
3040          BEGIN
3041            nChild := TO_NUMBER(v_return(i));
3042          EXCEPTION
3043            WHEN OTHERS THEN
3044 
3045              SELECT name INTO errorMessage
3046                FROM cz_properties
3047               WHERE property_id = propertyId;
3048 
3049              localString := v_return(i);
3050              RAISE CZ_R_INCORRECT_DATA_TYPE;
3051          END;
3052        END IF;
3053 
3054      EXCEPTION
3055        WHEN NO_DATA_FOUND THEN
3056          RAISE CZ_E_NO_SUCH_PROPERTY;
3057        WHEN TOO_MANY_ROWS THEN
3058          RAISE CZ_E_INCORRECT_PROPERTY;
3059        WHEN OTHERS THEN
3060          RAISE;
3061      END;
3062    END IF;
3063  END LOOP;
3064 
3065 nDebug := 9001009;
3066 
3067  RETURN v_return;
3068 END;
3069 ---------------------------------------------------------------------------------------
3070 FUNCTION GENERATE_PROPERTY(j IN PLS_INTEGER) RETURN tStringArray IS
3071  v_return     tStringArray;
3072  ListType     PLS_INTEGER;
3073 BEGIN
3074 
3075   v_return(1) := PROPERTY_VALUE(j, glIndexByPsNodeId(v_tExprPsNodeId(j)), ListType);
3076   RETURN v_return;
3077 END;
3078 ---------------------------------------------------------------------------------------
3079 FUNCTION EXPAND_NODE_OPTIONAL(pvPsNodeId IN NUMBER) RETURN tIntegerArray IS  --kdande; Bug 6881902; 11-Mar-2008
3080  v_return     tIntegerArray;
3081  nCount       PLS_INTEGER;
3082  nStartIndex  PLS_INTEGER;
3083  nEndIndex    PLS_INTEGER;
3084  indicator    PLS_INTEGER := 0;
3085 BEGIN
3086 
3087   nStartIndex := glIndexByPsNodeId(pvPsNodeId) + 1;
3088 
3089   IF(NOT glLastChildIndex.EXISTS(pvPsNodeId))THEN
3090     localString := glName(glIndexByPsNodeId(pvPsNodeId));
3091     RAISE CZ_E_NO_EXPECTED_CHILDREN;
3092   END IF;
3093 
3094   nEndIndex := glLastChildIndex(pvPsNodeId);
3095   nCount := 1;
3096 
3097   IF(glPsNodeType(glIndexByPsNodeId(pvPsNodeId)) = PS_NODE_TYPE_FEATURE)THEN
3098 
3099     indicator := 1;
3100     FOR i IN nStartIndex..nEndIndex LOOP
3101 
3102       v_return(nCount) := i;
3103       nCount := nCount + 1;
3104 
3105     END LOOP;
3106   ELSE
3107 
3108    FOR i IN nStartIndex..nEndIndex LOOP
3109 
3110      IF(glParentId(i) = pvPsNodeId AND glBomRequired(i) = FLAG_BOM_OPTIONAL)THEN
3111 
3112        v_return(nCount) := i;
3113        nCount := nCount + 1;
3114 
3115      END IF;
3116    END LOOP;
3117   END IF;
3118 
3119  --Validate that there are any optional children, otherwise the rule has no sense so
3120  --just ignore it.
3121 
3122  IF(v_return.COUNT = 0)THEN
3123    localString := glName(glIndexByPsNodeId(pvPsNodeId));
3124    IF(indicator = 1)THEN
3125      RAISE CZ_E_NO_EXPECTED_CHILDREN;
3126    END IF;
3127    RAISE CZ_E_NO_OPTIONAL_CHILDREN;
3128  END IF;
3129 
3130  RETURN v_return;
3131 END;
3132 ---------------------------------------------------------------------------------------
3133 FUNCTION GENERATE_VAL(j IN PLS_INTEGER) RETURN tStringArray IS
3134  v_return  tStringArray;
3135  nChild    PLS_INTEGER;
3136  ListType  PLS_INTEGER;
3137  nCheck    NUMBER;
3138 BEGIN
3139 
3140  IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
3141   RAISE CZ_E_WRONG_VAL_EXPRESSION;
3142  END IF;
3143 
3144  nChild := v_ChildrenIndex(v_tExprId(j));
3145  IF(v_tExprParentId.EXISTS(nChild + 1) AND v_tExprParentId(nChild + 1) = v_tExprId(j))THEN
3146   RAISE CZ_E_WRONG_VAL_EXPRESSION;
3147  END IF;
3148 
3149  v_return := GENERATE_EXPRESSION(nChild, ListType);
3150 
3151  BEGIN
3152   nCheck := TO_NUMBER(v_return(1));
3153  EXCEPTION
3154    WHEN OTHERS THEN
3155      RAISE CZ_E_WRONG_VAL_EXPRESS_TYPE;
3156  END;
3157 
3158  RETURN v_return;
3159 END;
3160 ---------------------------------------------------------------------------------------
3161 FUNCTION GENERATE_LOGIC_SIDE(j IN PLS_INTEGER, Operator OUT NOCOPY PLS_INTEGER)
3162 RETURN tStringArray IS
3163   v_return     tStringArray;
3164   ListType     PLS_INTEGER := NEVER_EXISTS_ID;
3165 BEGIN
3166 
3167 nDebug := 8001110;
3168 
3169    --Removing the 'simple expression' branch as a part of the fix for the bug #3371279.
3170 
3171    IF(v_tExprType(j) = EXPR_OPERATOR AND NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
3172 
3173      RAISE CZ_R_INCOMPLETE_LOGIC_RULE;
3174    END IF;
3175 
3176    v_return := GENERATE_EXPRESSION(j, ListType);
3177    Operator := OPERATOR_ALLOF;
3178    IF(ListType IN (OPERATOR_ANYOF, OPERATOR_ALLOF))THEN
3179      Operator := ListType;
3180    END IF;
3181  RETURN v_return;
3182 END;
3183 ---------------------------------------------------------------------------------------
3184 PROCEDURE GENERATE_LOGIC_RULE IS
3185  defaultName  tStringArray;
3186  itemName     tStringArray;
3187  v_lefts      tStringArray;
3188  v_rights     tStringArray;
3189  LeftOp       PLS_INTEGER;
3190  RightOp      PLS_INTEGER;
3191  ListType     PLS_INTEGER;
3192  ObjectName   VARCHAR2(16);
3193 BEGIN
3194 
3195     IF(jAntecedentRoot IS NULL OR jConsequentRoot IS NULL)THEN
3196       RAISE CZ_R_INVALID_LOGIC_RULE;
3197     END IF;
3198 
3199 nDebug := 8001100;
3200 
3201     IF(nRuleOperator = RULE_OPERATOR_DEFAULTS)THEN
3202 
3203 nDebug := 8001101;
3204 
3205       defaultName := GENERATE_EXPRESSION(jAntecedentRoot, ListType);
3206       ListType := NEVER_EXISTS_ID;
3207       itemName := GENERATE_EXPRESSION(jConsequentRoot, ListType);
3208       IF(ListType NOT IN (OPERATOR_ANYOF, OPERATOR_ALLOF))THEN
3209         ListType := OPERATOR_ANYOF;
3210       END IF;
3211 
3212 nDebug := 8001102;
3213 
3214       localString := NULL;
3215       IF(itemName.COUNT > 1)THEN localString := sUnsatisfiedId; END IF;
3216 
3217       nLocalDefaults := nLocalDefaults + 1;
3218       ObjectName := 'D_' || TO_CHAR(nLocalDefaults) || '_' || TO_CHAR(MaxDepthId);
3219 
3220       vLogicLine := 'OBJECT ' || ObjectName || NewLine ||
3221         'WITH _default = ' || defaultName(1) || NewLine ||
3222         'GS R ' || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
3223         'GL' || OperatorLetters(ListType);
3224 
3225       PACK;
3226 
3227 nDebug := 8001103;
3228 
3229       FOR i IN 1..itemName.COUNT LOOP
3230 
3231         vLogicLine := itemName(i) || ' ';
3232         PACK;
3233 
3234       END LOOP;
3235 
3236       vLogicLine := NewLine || 'GR N ' || ObjectName || NewLine;
3237       PACK;
3238 
3239 nDebug := 8001104;
3240 
3241     ELSE
3242 
3243 nDebug := 8001105;
3244 
3245         v_lefts := GENERATE_LOGIC_SIDE(jAntecedentRoot, LeftOp);
3246         v_rights := GENERATE_LOGIC_SIDE(jConsequentRoot, RightOp);
3247 
3248 nDebug := 8001106;
3249 
3250         localString := NULL;
3251         IF(v_lefts.COUNT > 1 OR v_rights.COUNT > 1)THEN localString := sUnsatisfiedId; END IF;
3252 
3253         vLogicLine := 'GS' || OperatorLetters(nRuleOperator) || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
3254                       'GL' || OperatorLetters(LeftOp);
3255         PACK;
3256 
3257 nDebug := 8001107;
3258 
3259         FOR i IN 1..v_lefts.COUNT LOOP
3260 
3261           vLogicLine := v_lefts(i) || ' ';
3262           PACK;
3263 
3264         END LOOP;
3265 
3266 nDebug := 8001108;
3267 
3268         vLogicLine := NewLine || 'GR' || OperatorLetters(RightOp);
3269         PACK;
3270 
3271         FOR i IN 1..v_rights.COUNT LOOP
3272 
3273           vLogicLine := v_rights(i) || ' ';
3274           PACK;
3275 
3276         END LOOP;
3277 
3278         vLogicLine := NewLine;
3279         PACK;
3280 
3281 nDebug := 8001109;
3282 
3283     END IF;
3284 END;
3285 ---------------------------------------------------------------------------------------
3286 FUNCTION HAS_INTEGER_VALUE(j IN PLS_INTEGER) RETURN PLS_INTEGER IS
3287   NodeType     PLS_INTEGER := v_tExprType(j);
3288   FeatureType  PLS_INTEGER;
3289   SysPropType  PLS_INTEGER;
3290   PsNodeIndex  PLS_INTEGER;
3291 BEGIN
3292 
3293   IF(NodeType = EXPR_ARGUMENT)THEN
3294 
3295     PsNodeIndex := LOOKUP_ARGUMENT(j);
3296     IF(parameterScope(PsNodeIndex).node_id IS NULL)THEN RETURN GENERATE_SCOPE_ERROR; END IF;
3297 
3298     NodeType := EXPR_PSNODE;
3299     v_tExprPsNodeId(j) := parameterScope(PsNodeIndex).node_id;
3300   END IF;
3301 
3302   IF(NodeType = EXPR_PSNODE)THEN
3303 
3304     NodeType := glPsNodeType(glIndexByPsNodeId(v_tExprPsNodeId(j)));
3305     FeatureType := glFeatureType(glIndexByPsNodeId(v_tExprPsNodeId(j)));
3306     localString := glName(glIndexByPsNodeId(v_tExprPsNodeId(j)));
3307 
3308     IF(NodeType = PS_NODE_TYPE_FEATURE AND FeatureType IN
3309                  (PS_NODE_FEATURE_TYPE_OPTION, PS_NODE_FEATURE_TYPE_BOOLEAN)
3310                   AND (NOT v_ChildrenIndex.EXISTS(v_tExprId(j))))THEN
3311 
3312       IF(FeatureType = PS_NODE_FEATURE_TYPE_OPTION)THEN
3313         errorMessage := 'Option Feature';
3314       ELSE
3315         errorMessage := 'Boolean Feature';
3316       END IF;
3317       RAISE CZ_R_INCORRECT_NUMERIC_RHS;
3318     ELSIF(NodeType = PS_NODE_TYPE_COMPONENT AND (NOT v_ChildrenIndex.EXISTS(v_tExprId(j))))THEN
3319 
3320       --Bug #3800339. This is a component without a system property applied. As the data is corrupted,
3321       --it may not be possible to catch things like that by queries against the seed data.
3322 
3323       errorMessage := 'Component';
3324       RAISE CZ_R_INCORRECT_NUMERIC_RHS;
3325     END IF;
3326 
3327     IF(v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
3328       IF(v_tExprType(v_ChildrenIndex(v_tExprId(j))) = EXPR_PROP)THEN
3329 
3330         --User properties are not allowed in the consequent expression.
3331 
3332         RAISE CZ_R_INVALID_NUMERIC_RULE;
3333       END IF;
3334 
3335       SysPropType := v_tExprSubtype(v_ChildrenIndex(v_tExprId(j)));
3336       IF(NOT h_SeededName.EXISTS(SysPropType))THEN RAISE CZ_E_BAD_PROPERTY_TYPE; END IF;
3337 
3338       IF(h_SeededName(SysPropType) = RULE_SYS_PROP_SELECTION)THEN RETURN GENERATE_DYNAMIC; END IF;
3339 
3340       IF(h_SeededName(SysPropType) <> RULE_SYS_PROP_SELECTION AND
3341          (NOT APPLICABLE_SYS_PROP(j, NULL, SysPropType)))THEN
3342 
3343         localString := h_ReportName(sysPropType);
3344         auxIndex := glIndexByPsNodeId(v_tExprPsNodeId(j));
3345         RAISE CZ_R_INCOMPATIBLE_SYSPROP;
3346       ELSE
3347 
3348         --Bug #4677027. No rounding operator for contributions to any bom nodes.
3349 
3350         IF(NodeType IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN RETURN GENERATE_CONTRIBUTE; END IF;
3351 
3352         IF(COMPATIBLE_DATA_TYPES(SIGNATURE_DATA_TYPE(h_SignatureId(SysPropType)), DATATYPE_INTEGER))THEN
3353           RETURN GENERATE_INCREMENT;
3354         END IF;
3355       END IF;
3356     ELSE
3357       IF(NodeType = PS_NODE_TYPE_OPTION OR
3358          (NodeType = PS_NODE_TYPE_FEATURE AND FeatureType = PS_NODE_FEATURE_TYPE_INTEGER))THEN
3359             RETURN GENERATE_INCREMENT;
3360       END IF;
3361     END IF;
3362    RETURN GENERATE_CONTRIBUTE;
3363   ELSE
3364    RETURN GENERATE_CONTRIBUTE;
3365   END IF;
3366 END;
3367 ---------------------------------------------------------------------------------------
3368 FUNCTION GENERATE_NUMERIC_PART(j IN PLS_INTEGER, NodeId IN OUT NOCOPY NUMBER)  --kdande; Bug 6881902; 11-Mar-2008
3369 RETURN VARCHAR2 IS
3370   ExprType  PLS_INTEGER := v_tExprType(j);
3371   v_return  VARCHAR2(4000);
3372   v_propval tStringArray;
3373   ListType  PLS_INTEGER;
3374   nChild    NUMBER;
3375 BEGIN
3376   IF(ExprType IN (EXPR_PSNODE, EXPR_ARGUMENT))THEN
3377 
3378     v_propval := GENERATE_EXPRESSION(j, ListType);
3379     v_return := v_propval(1);
3380     NodeId := v_tExprPsNodeId(j);
3381 
3382   ELSIF(ExprType = EXPR_NODE_TYPE_COUNT)THEN
3383 
3384     v_return := GENERATE_NAME(j, v_tExprPsNodeId(j));
3385     NodeId := v_tExprPsNodeId(j);
3386 
3387   ELSIF(ExprType = EXPR_NODE_TYPE_LITERAL)THEN
3388 
3389     v_return := v_tExprDataValue(j);
3390     NodeId := 0;
3391 
3392   ELSIF(ExprType = EXPR_NODE_TYPE_PROP)THEN
3393 
3394     v_return := PROPERTY_VALUE(j, glIndexByPsNodeId(NodeId), ListType);
3395     NodeId := 0;
3396 
3397     BEGIN
3398      nChild := TO_NUMBER(v_return);
3399      IF(nChild = 0)THEN NodeId := -1; END IF;
3400     EXCEPTION
3401       WHEN OTHERS THEN
3402 
3403         SELECT name INTO errorMessage
3404           FROM cz_properties
3405          WHERE property_id = v_tExprPropertyId(j);
3406 
3407         RAISE CZ_R_INCORRECT_NUMERICLHS;
3408     END;
3409 
3410   ELSIF(ExprType = EXPR_NODE_TYPE_OPERATOR AND v_tExprSubtype(j) = OPERATOR_DOT)THEN
3411 
3412     nChild := v_ChildrenIndex(v_tExprId(j));
3413     v_tExplNodeId(nChild + 1) := v_tExplNodeId(nChild);
3414     v_return := PROPERTY_VALUE(nChild + 1, glIndexByPsNodeId(v_tExprPsNodeId(nChild)), ListType);
3415     NodeId := v_tExprPsNodeId(nChild);
3416 
3417   ELSE
3418 
3419     RAISE CZ_R_INVALID_NUMERIC_PART;
3420 
3421   END IF;
3422  RETURN v_return;
3423 END;
3424 ---------------------------------------------------------------------------------------
3425 FUNCTION GENERATE_BOOLEAN_PART(j IN PLS_INTEGER) RETURN VARCHAR2 IS
3426   nChild    PLS_INTEGER;
3427   v_return  VARCHAR2(4000);
3428   v_index   tIntegerArray;
3429   ExprId    NUMBER := v_tExprId(j); --Bug13566997
3430 BEGIN
3431 
3432 nDebug := 8001001;
3433 
3434   nChild := v_ChildrenIndex(ExprId);
3435 
3436 nDebug := 8001002;
3437 
3438   nLocalDefaults := nLocalDefaults + 1;
3439   v_return := t_prefix || TO_CHAR(nLocalDefaults);
3440 
3441   vLogicLine := 'OBJECT ' || v_return || NewLine ||
3442                 'GS R ... ' || TO_CHAR(nReasonId) || NewLine ||
3443                 'GL' || OperatorLetters(v_tExprSubtype(j));
3444   PACK;
3445 
3446 nDebug := 8001004;
3447 
3448   WHILE(v_tExprParentId(nChild) = ExprId) LOOP
3449 
3450     v_index := EXPAND_NODE(nChild);
3451 
3452     FOR i IN 1..v_index.COUNT LOOP
3453 
3454       vLogicLine := GENERATE_NAME_EXPL(v_ExplByPsNodeId(v_index(i)), v_index(i)) || ' ';
3455       PACK;
3456     END LOOP;
3457 
3458     nChild := nChild + 1;
3459   END LOOP;
3460 
3461 nDebug := 8001005;
3462 
3463   vLogicLine := NewLine || 'GR' || OperatorLetters(OPERATOR_ALLOF) || v_return || NewLine;
3464   PACK;
3465 
3466 nDebug := 8001006;
3467 
3468  RETURN v_return;
3469 END;
3470 ---------------------------------------------------------------------------------------
3471 PROCEDURE GENERATE_INCREMENT_LOGIC IS
3472   v_NodeId        NUMBER; --kdande; Bug 6881902; 11-Mar-2008
3473   v_HeaderId      NUMBER;
3474   v_return        VARCHAR2(4000);
3475   v_result        tStringArray;
3476   v_index         tStringArray;
3477   v_acname        VARCHAR2(4000);
3478   v_nodename      VARCHAR2(4000);
3479   v_accuname      VARCHAR2(4000);
3480   ListType        PLS_INTEGER;
3481   sSign           VARCHAR2(8) := NULL;
3482   lhsNode         PLS_INTEGER := 0;
3483   rhsNode         PLS_INTEGER := 0;
3484   lhsName         VARCHAR2(4000);
3485   rhsName         VARCHAR2(4000);
3486   nOpNode         PLS_INTEGER;
3487   nChild          PLS_INTEGER;
3488   nGrandChild     PLS_INTEGER;
3489   nSuffix         PLS_INTEGER := 0;
3490   iLocal          PLS_INTEGER;
3491   operatorLiteral VARCHAR2(4000);
3492   v_name          VARCHAR2(128);
3493 ---------------------------------------------------------------------------------------
3494 PROCEDURE GENERATE_INCREMENT_RECORD IS
3495   v_total  VARCHAR2(4000) := NULL;
3496 BEGIN
3497 
3498   IF(v_tExprSubtype(nOpNode) = OPERATOR_DIV)THEN
3499 
3500     v_total := t_prefix || v_name || '_' || TO_CHAR(nSuffix);
3501     vLogicLine := 'TOTAL ' || v_total || NewLine ||
3502                   'CONTRIBUTE ' || lhsName || OperatorLiterals(OPERATOR_DIV) ||
3503                   rhsName || ' ' || v_total || ' ... ' || TO_CHAR(nReasonId) || NewLine;
3504     PACK;
3505   ELSIF(v_tExprSubtype(nOpNode) = OPERATOR_MATHDIV)THEN
3506 
3507     v_total := t_prefix || v_name || '_' || TO_CHAR(nSuffix);
3508     vLogicLine := 'TOTAL ' || v_total || NewLine ||
3509                   'MF ' || lhsName || ' ' || rhsName || OperatorLiterals(OPERATOR_MATHDIV) ||
3510                   v_total || ' ... ' || TO_CHAR(nReasonId) || NewLine;
3511     PACK;
3512   END IF;
3513 
3514   sSign := NULL;
3515   IF(nRuleOperator = RULE_OPERATOR_CONSUMES)THEN
3516     sSign := '-1 ';
3517   END IF;
3518 
3519   IF(v_total IS NULL)THEN
3520 
3521    vLogicLine := 'INC ' || sSign || lhsName || ' ' || rhsName || ' ' || v_acname ||
3522                  OperatorLiteral || '... ' || TO_CHAR(nReasonId) || NewLine;
3523 
3524   ELSE
3525 
3526    vLogicLine := 'INC ' || sSign || v_total || ' ' || v_acname ||
3527                  OperatorLiteral || '... ' || TO_CHAR(nReasonId) || NewLine;
3528 
3529   END IF;
3530  PACK;
3531 END;
3532 ---------------------------------------------------------------------------------------
3533 BEGIN
3534 
3535   nLocalDefaults := nLocalDefaults + 1;
3536   v_name := TO_CHAR(nLocalDefaults);
3537 
3538   --Generate the accumulator and corresponding increment relation if necessary
3539 
3540 nDebug := 8001200;
3541 
3542   v_return := GENERATE_NUMERIC_PART(jConsequentRoot, v_NodeId);
3543 
3544 nDebug := 8001201;
3545 
3546   IF(v_tExprType(jConsequentRoot) = EXPR_NODE_TYPE_OPERATOR AND
3547      v_tExprSubtype(jConsequentRoot) = OPERATOR_DOT)THEN
3548 
3549 nDebug := 8001202;
3550 
3551    nChild := v_ChildrenIndex(v_tExprId(jConsequentRoot)) + 1;
3552    v_acname := v_return;
3553 
3554    --Commenting the following block out as the fix to bug #1657701. Assuming that this code
3555    --was necessary until some fixes in participants' model_ref_expl_id population hadn't
3556    --been done, and now it's obsolete.
3557 /*
3558    IF(v_NodeId = v_tPsNodeId(v_IndexByNodeId(MaxDepthId)))THEN
3559      v_acname := PATH_DELIMITER || 'parent' || PATH_DELIMITER || v_acname;
3560    END IF;
3561 */
3562 
3563   ELSIF(v_tExprType(jConsequentRoot) = EXPR_PSNODE AND v_ChildrenIndex.EXISTS(v_tExprId(jConsequentRoot)))THEN
3564 
3565     nChild := jConsequentRoot;
3566     v_acname := v_return;
3567 
3568   ELSIF((NOT v_HeaderByAccId.EXISTS(v_NodeId)) AND
3569         (glAccumulator(v_NodeId) IS NULL OR glAccumulator(v_NodeId) = FLAG_NO_ACCUMULATOR))THEN
3570 
3571 nDebug := 8001203;
3572 
3573    v_HeaderId := glHeaderByPsNodeId(v_NodeId);
3574    v_nodename := 'P_' || TO_CHAR(glPersistentId(v_NodeId));
3575    v_accuname := v_nodename || '_ACC';
3576 
3577    --Flush off the buffer because we are about to write to another file
3578 
3579    IF(vLogicText IS NOT NULL)THEN
3580     INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
3581      (nHeaderId, v_tSequenceNbr(nHeaderId), vLogicText);
3582     vLogicText := NULL;
3583     v_tSequenceNbr(nHeaderId) := v_tSequenceNbr(nHeaderId) + 1;
3584    END IF;
3585 
3586    --Fix for the bug #2398832 - we may be re-using the accumulator, so we should not
3587    --assign to it effectivities and usages of a particular node.
3588    --Do not write the effectivity dates using the actual effective date interval of
3589    --the corresponding node.
3590 
3591    --iLocal := glIndexByPsNodeId(v_NodeId);
3592    --CurrentEffFrom := glEffFrom(iLocal);
3593    --CurrentEffUntil := glEffUntil(iLocal);
3594    --CurrentUsageMask := glUsageMask(iLocal);
3595 
3596    --Instead make the accumulator always effective and universal.
3597 
3598    CurrentEffFrom := EpochBeginDate;
3599    CurrentEffUntil := EpochEndDate;
3600    CurrentUsageMask := AnyUsageMask;
3601 
3602    IF((NOT h_EffFrom.EXISTS(v_HeaderId)) OR
3603       (h_EffFrom(v_HeaderId) <> CurrentEffFrom OR h_EffUntil(v_HeaderId) <> CurrentEffUntil OR
3604        h_EffUsageMask(v_HeaderId) <> CurrentUsageMask))THEN
3605 
3606      h_EffFrom(v_HeaderId) := CurrentEffFrom;
3607      h_EffUntil(v_HeaderId) := CurrentEffUntil;
3608      h_EffUsageMask(v_HeaderId) := CurrentUsageMask;
3609 
3610      vLogicText := LTRIM(CurrentUsageMask, '0');
3611      IF(vLogicText IS NOT NULL) THEN
3612        vLogicText := EffUsagePrefix || vLogicText;
3613      END IF;
3614 
3615      IF(CurrentEffFrom = EpochBeginDate)THEN
3616        CurrentFromDate := NULL;
3617      ELSE
3618        CurrentFromDate := TO_CHAR(CurrentEffFrom, EffDateFormat);
3619      END IF;
3620 
3621      IF(CurrentEffUntil = EpochEndDate)THEN
3622        CurrentUntilDate := NULL;
3623      ELSE
3624        CurrentUntilDate := TO_CHAR(CurrentEffUntil, EffDateFormat);
3625      END IF;
3626 
3627      vLogicText := 'EFF ' || CurrentFromDate || ', ' || CurrentUntilDate || ', ' || vLogicText || NewLine;
3628    END IF;
3629 
3630    vLogicText := vLogicText || 'TOTAL ' || v_accuname || NewLine ||
3631                  'INC ' || v_accuname || ' ' || v_nodename ||
3632                  OperatorLiterals(OPERATOR_ROUND) || '... ' || TO_CHAR(nReasonId) || NewLine;
3633 
3634    INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
3635     (v_HeaderId, vSeqNbrByHeader(v_HeaderId), vLogicText);
3636    vLogicText := NULL;
3637    vSeqNbrByHeader(v_HeaderId) := vSeqNbrByHeader(v_HeaderId) + 1;
3638 
3639    v_HeaderByAccId(v_NodeId) := v_HeaderId;
3640    v_acname := v_return || '_ACC';
3641 
3642    --Part of the fix for the bug #2857955. We will never be here if glAccumulator(v_NodeId) was
3643    --FLAG_ACCUMULATOR_ACC because the accumulator would have already been created.
3644 
3645    UPDATE cz_ps_nodes SET
3646      accumulator_flag = DECODE(glAccumulator(v_NodeId), FLAG_ACCUMULATOR_NT, FLAG_ACCUMULATOR_BOTH, FLAG_ACCUMULATOR_ACC)
3647    WHERE ps_node_id = v_NodeId;
3648 
3649   ELSE
3650 
3651 nDebug := 8001204;
3652 
3653    v_acname := v_return || '_ACC';
3654   END IF;
3655 
3656 nDebug := 8001205;
3657 
3658   --If we are here, than the RHS expression has an integer value and so the LHS expression
3659   --should have a root rounding operator. So go down one level.
3660   --However, as a fix for the bug #3558699 we now don't require the root rounding operator
3661   --if the data type of antecedent is convertible to integer. Therefore we have to be more
3662   --flexible here.
3663 
3664   IF(v_tExprType(jAntecedentRoot) <> EXPR_OPERATOR OR v_tExprSubtype(jAntecedentRoot) NOT IN
3665            (OPERATOR_ROUND, OPERATOR_CEILING, OPERATOR_FLOOR, OPERATOR_TRUNCATE, OPERATOR_NONE))THEN
3666     nOpNode := jAntecedentRoot;
3667     OperatorLiteral := OperatorLiterals(OPERATOR_NONE);
3668   ELSE
3669     nOpNode := v_ChildrenIndex(v_tExprId(jAntecedentRoot));
3670     OperatorLiteral := OperatorLiterals(v_tExprSubtype(jAntecedentRoot));
3671   END IF;
3672 
3673   IF(v_tExprType(nOpNode) = EXPR_OPERATOR AND (NOT v_ChildrenIndex.EXISTS(v_tExprId(nOpNode))))THEN
3674     RAISE CZ_R_INCOMPLETE_NUMERIC_RULE;
3675   END IF;
3676 
3677   IF(v_ChildrenIndex.EXISTS(v_tExprId(nOpNode)))THEN
3678     lhsNode := v_ChildrenIndex(v_tExprId(nOpNode));
3679     rhsNode := lhsNode + v_NumberOfChildren(v_tExprId(nOpNode)) - 1;
3680   END IF;
3681 
3682   IF(nPresentationFlag = FLAG_FREEFORM_RULE)THEN
3683 
3684     --Check if this is a simple numeric rule that has been upgraded to become a free-form rule. For such
3685     --rules we want to generate an optimized INC relation.
3686     --Bug #4047086. However, the operator can only be multiplication to be able to optimize.
3687     --Bugs #4256960, #4254591. The RHS operand must also be simple, not an operator.
3688 
3689     IF((v_tExprType(nOpNode) = EXPR_OPERATOR AND v_tExprSubtype(nOpNode) = OPERATOR_MULT) AND
3690        (v_tExprType(rhsNode) <> EXPR_OPERATOR) AND (v_tExprType(lhsNode) = EXPR_LITERAL OR
3691        (v_tExprType(lhsNode) IN (EXPR_PSNODE, EXPR_ARGUMENT) AND (NOT HAS_OPTIONS_APPLIED(lhsNode)))))THEN
3692 
3693       rhsNode := lhsNode + 1;
3694 
3695       lhsName := GENERATE_NUMERIC_PART(lhsNode, v_NodeId);
3696       rhsName := GENERATE_NUMERIC_PART(rhsNode, v_NodeId);
3697       GENERATE_INCREMENT_RECORD;
3698       RETURN;
3699     ELSE
3700 
3701 nDebug := 8001206;
3702 
3703       numericLHS := 1;
3704       v_result := GENERATE_EXPRESSION(nOpNode, ListType);
3705       IF(nRuleOperator = RULE_OPERATOR_CONSUMES)THEN
3706         sSign := '-1 ';
3707       END IF;
3708       vLogicLine := 'INC ' || sSign || v_result(1) || ' ' || v_acname ||
3709                     OperatorLiteral || '... ' || TO_CHAR(nReasonId) || NewLine;
3710       PACK;
3711       RETURN;
3712     END IF;
3713   END IF;
3714 
3715 nDebug := 8001207;
3716 
3717   FOR i IN lhsNode..rhsNode - 1 LOOP
3718     IF(v_tExprType(i) = EXPR_PSNODE AND HAS_OPTIONS_APPLIED(i))THEN
3719 
3720       v_index := GENERATE_CHILDRENOF(v_tExplNodeId(i), v_tExprPsNodeId(i));
3721 
3722       FOR ich IN 1..v_index.COUNT LOOP
3723 
3724         lhsName := v_index(ich);
3725         rhsName := GENERATE_NUMERIC_PART(rhsNode, v_NodeId);
3726         GENERATE_INCREMENT_RECORD;
3727         nSuffix := nSuffix + 1;
3728       END LOOP;
3729     ELSIF(v_tExprType(i) IN (EXPR_LITERAL, EXPR_PSNODE))THEN
3730 
3731       lhsName := GENERATE_NUMERIC_PART(i, v_NodeId);
3732       v_NodeId := v_tExprPsNodeId(i);
3733       rhsName := GENERATE_NUMERIC_PART(rhsNode, v_NodeId);
3734 
3735       GENERATE_INCREMENT_RECORD;
3736       nSuffix := nSuffix + 1;
3737     ELSE
3738 
3739       RAISE CZ_R_INVALID_NUMRULE_NODE;
3740     END IF;
3741   END LOOP;
3742 END;
3743 ---------------------------------------------------------------------------------------
3744 PROCEDURE GENERATE_CONTRIBUTE_LOGIC IS
3745   v_return     VARCHAR2(4000);
3746   v_result     tStringArray;
3747   v_index      tStringArray;
3748   ListType     PLS_INTEGER;
3749   sSign        VARCHAR2(8);
3750   lhsNode      PLS_INTEGER;
3751   rhsNode      PLS_INTEGER;
3752   lhsName      VARCHAR2(4000);
3753   rhsName      VARCHAR2(4000);
3754   nChild       PLS_INTEGER;
3755   nGrandChild  PLS_INTEGER;
3756   v_NodeId     NUMBER; --kdande; Bug 6881902; 11-Mar-2008
3757   nSuffix      PLS_INTEGER := 0;
3758   nOpNode      PLS_INTEGER := jAntecedentRoot;
3759   sOpRoot      VARCHAR2(16):= ' ';
3760   v_HeaderId   NUMBER;
3761   v_nodename   VARCHAR2(4000);
3762   v_accuname   VARCHAR2(4000);
3763   iLocal       PLS_INTEGER;
3764   v_name       VARCHAR2(128);
3765 ---------------------------------------------------------------------------------------
3766 PROCEDURE GENERATE_CONTRIBUTE_RECORD IS
3767   v_total  VARCHAR2(4000);
3768   v_local  VARCHAR2(4000) := v_return;
3769 BEGIN
3770   IF(nRuleOperator = RULE_OPERATOR_CONSUMES)THEN
3771 
3772     v_total := t_prefix || v_name || '_' || TO_CHAR(nSuffix);
3773     vLogicLine := 'TOTAL ' || v_total || NewLine ||
3774                   'CONTRIBUTE ' || v_total || OperatorLiterals(OPERATOR_MULT) ||
3775                   '-1 ' || v_local || ' ... ' || TO_CHAR(nReasonId) || NewLine;
3776     v_local := v_total;
3777     PACK;
3778   END IF;
3779 
3780   IF(v_NodeId = -1 AND v_tExprSubtype(nOpNode) = OPERATOR_MULT)THEN
3781 
3782     vLogicLine := 'CONTRIBUTE ' || lhsName || OperatorLiterals(OPERATOR_SUB) ||
3783                   lhsName || ' ' || v_local || sOpRoot || '... ' || TO_CHAR(nReasonId) || NewLine;
3784   ELSIF(v_tExprSubtype(nOpNode) = OPERATOR_MATHDIV)THEN
3785 
3786     v_total := t_prefix || v_name || '_' || TO_CHAR(nSuffix);
3787     vLogicLine := 'TOTAL ' || v_total || NewLine ||
3788                   'MF ' || lhsName || ' ' || rhsName || OperatorLiterals(OPERATOR_MATHDIV) ||
3789                   v_total || ' ... ' || TO_CHAR(nReasonId) || NewLine;
3790     PACK;
3791     vLogicLine := 'CONTRIBUTE 1 ' || v_total || ' ' || v_local || sOpRoot || '... ' || TO_CHAR(nReasonId) || NewLine;
3792   ELSE
3793 
3794     vLogicLine := 'CONTRIBUTE ' || lhsName || OperatorLiterals(v_tExprSubtype(nOpNode)) ||
3795                   rhsName || ' ' || v_local || sOpRoot || '... ' || TO_CHAR(nReasonId) || NewLine;
3796   END IF;
3797   PACK;
3798 END;
3799 ---------------------------------------------------------------------------------------
3800 BEGIN
3801 
3802   nLocalDefaults := nLocalDefaults + 1;
3803   v_name := TO_CHAR(nLocalDefaults);
3804 
3805 nDebug := 8002;
3806 
3807   v_return := GENERATE_NUMERIC_PART(jConsequentRoot, v_NodeId);
3808   optimizeChain := OPTIMIZATION_UNKNOWN;
3809   optimizeContribute := OPTIMIZATION_UNKNOWN;
3810 
3811   IF(v_tLogicNetType(nHeaderId) = LOGIC_NET_TYPE_NETWORK AND
3812      glPsNodeType(glIndexByPsNodeId(v_NodeId)) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
3813 
3814     --This is a conditional numeric rule against a BOM node. We will create an accumulator and
3815     --a 'contribute' relation from the accumulator to the BOM object, if such accumulator does
3816     --not exist. We'll need to temporarily switch context to the BOM object's structure file.
3817 
3818     IF((NOT v_HeaderByAccId.EXISTS(v_NodeId)) AND
3819        (glAccumulator(v_NodeId) IS NULL OR glAccumulator(v_NodeId) = FLAG_NO_ACCUMULATOR))THEN
3820 
3821       --Retrieve the corresponding structure file header and prepare the names.
3822 
3823       v_HeaderId := glHeaderByPsNodeId(v_NodeId);
3824       v_nodename := 'P_' || TO_CHAR(glPersistentId(v_NodeId));
3825       v_accuname := v_nodename || '_ACC';
3826 
3827       --Flush off the buffer because we are about to write to another file.
3828 
3829       IF(vLogicText IS NOT NULL)THEN
3830         INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
3831          (nHeaderId, v_tSequenceNbr(nHeaderId), vLogicText);
3832         vLogicText := NULL;
3833         v_tSequenceNbr(nHeaderId) := v_tSequenceNbr(nHeaderId) + 1;
3834       END IF;
3835 
3836       --Fix for the bug #2398832 - we may be re-using the accumulator, so we should not
3837       --assign to it effectivities and usages of a particular node.
3838       --Do not write the effectivity dates using the actual effective date interval of
3839       --the corresponding node.
3840 
3841       --iLocal := glIndexByPsNodeId(v_NodeId);
3842       --CurrentEffFrom := glEffFrom(iLocal);
3843       --CurrentEffUntil := glEffUntil(iLocal);
3844       --CurrentUsageMask := glUsageMask(iLocal);
3845 
3846       --Instead make the accumulator always effective and universal.
3847 
3848       CurrentEffFrom := EpochBeginDate;
3849       CurrentEffUntil := EpochEndDate;
3850       CurrentUsageMask := '0';
3851 
3852       IF((NOT h_EffFrom.EXISTS(v_HeaderId)) OR
3853          (h_EffFrom(v_HeaderId) <> CurrentEffFrom OR h_EffUntil(v_HeaderId) <> CurrentEffUntil OR
3854           h_EffUsageMask(v_HeaderId) <> CurrentUsageMask))THEN
3855 
3856         h_EffFrom(v_HeaderId) := CurrentEffFrom;
3857         h_EffUntil(v_HeaderId) := CurrentEffUntil;
3858         h_EffUsageMask(v_HeaderId) := CurrentUsageMask;
3859 
3860         vLogicText := LTRIM(CurrentUsageMask, '0');
3861         IF(vLogicText IS NOT NULL) THEN
3862           vLogicText := EffUsagePrefix || vLogicText;
3863         END IF;
3864 
3865         IF(CurrentEffFrom = EpochBeginDate)THEN
3866           CurrentFromDate := NULL;
3867         ELSE
3868           CurrentFromDate := TO_CHAR(CurrentEffFrom, EffDateFormat);
3869         END IF;
3870 
3871         IF(CurrentEffUntil = EpochEndDate)THEN
3872           CurrentUntilDate := NULL;
3873         ELSE
3874           CurrentUntilDate := TO_CHAR(CurrentEffUntil, EffDateFormat);
3875         END IF;
3876 
3877         vLogicText := 'EFF ' || CurrentFromDate || ', ' || CurrentUntilDate || ', ' || vLogicText || NewLine;
3878       END IF;
3879 
3880       --Write the logic record in the structure file.
3881 
3882       vLogicText := vLogicText || 'TOTAL ' || v_accuname || NewLine ||
3883                     'CONTRIBUTE 1 ' || v_accuname || ' ' || v_nodename ||
3884                     ' ... ' || TO_CHAR(nReasonId) || NewLine;
3885 
3886       INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
3887        (v_HeaderId, vSeqNbrByHeader(v_HeaderId), vLogicText);
3888 
3889       vLogicText := NULL;
3890       vSeqNbrByHeader(v_HeaderId) := vSeqNbrByHeader(v_HeaderId) + 1;
3891       v_HeaderByAccId(v_NodeId) := v_HeaderId;
3892 
3893       --This line and the ELSE branch below are to fix the bug #2702587 - we need not only create the
3894       --accumulator and a relation for it to the object but we also need to generate the rule so that
3895       --it contributes to the accumulator, not the objects.
3896 
3897       v_return := v_return || '_ACC';
3898 
3899       --Part of the fix for the bug #2857955. We will never be here if glAccumulator(v_NodeId) was
3900       --FLAG_ACCUMULATOR_ACC because the accumulator would have already been created.
3901 
3902       UPDATE cz_ps_nodes SET
3903         accumulator_flag = DECODE(glAccumulator(v_NodeId), FLAG_ACCUMULATOR_NT, FLAG_ACCUMULATOR_BOTH, FLAG_ACCUMULATOR_ACC)
3904       WHERE ps_node_id = v_NodeId;
3905 
3906     ELSE
3907 
3908       v_return := v_return || '_ACC';
3909     END IF;
3910   END IF;
3911 
3912 nDebug := 8003;
3913 
3914   IF(v_tExprSubtype(jAntecedentRoot) IN
3915       (OPERATOR_ROUND, OPERATOR_FLOOR, OPERATOR_CEILING, OPERATOR_TRUNCATE, OPERATOR_NONE))THEN
3916     nOpNode := v_ChildrenIndex(v_tExprId(jAntecedentRoot));
3917     sOpRoot := OperatorLiterals(v_tExprSubtype(jAntecedentRoot));
3918   END IF;
3919 
3920   IF(nPresentationFlag = FLAG_FREEFORM_RULE)THEN
3921 
3922 nDebug := 8004;
3923 
3924    IF(nRuleOperator = RULE_OPERATOR_CONTRIBUTES)THEN
3925 
3926      sSign := '1 ';
3927 
3928      --If this is a numeric contribute rule with a root rounding operator, set the flag and store
3929      --the target from the Motorola optimization (bug #2540163).
3930 
3931      IF(v_tExprSubtype(jAntecedentRoot) IN
3932          (OPERATOR_ROUND, OPERATOR_FLOOR, OPERATOR_CEILING, OPERATOR_TRUNCATE))THEN
3933 
3934        optimizeChain := OPTIMIZATION_REQUESTED;
3935        optimizeTarget := v_return;
3936      ELSE
3937 
3938        optimizeContribute := OPTIMIZATION_REQUESTED;
3939      END IF;
3940    ELSE
3941 
3942      sSign := '-1 ';
3943    END IF;
3944 
3945 nDebug := 8004001;
3946 
3947    numericLHS := 1;
3948    v_result := GENERATE_EXPRESSION(jAntecedentRoot, ListType);
3949 
3950    --The value may have been changed during the expression generation. If it is not 0, we still
3951    --want to generate the rule's contribute relation. However, if it is 0 than the relation has
3952    --already been generated as a part of the optimization so here we just skip it.
3953 
3954    IF(optimizeChain IN (OPTIMIZATION_REQUESTED, OPTIMIZATION_UNKNOWN))THEN
3955      IF(optimizeContribute = OPTIMIZATION_COMPLETED)THEN
3956 
3957        vLogicLine := 'CONTRIBUTE ' || v_result(1) || v_return || ' ... ' || TO_CHAR(nReasonId) || NewLine;
3958      ELSE
3959 
3960        vLogicLine := 'CONTRIBUTE ' || v_result(1) || OperatorLiterals(OPERATOR_MULT) ||
3961                      sSign || v_return || sOpRoot || '... ' || TO_CHAR(nReasonId) || NewLine;
3962      END IF;
3963 
3964      PACK;
3965      optimizeChain := OPTIMIZATION_UNKNOWN;
3966    END IF;
3967 
3968    RETURN;
3969   END IF;
3970 
3971 nDebug := 8005;
3972 
3973   lhsNode := v_ChildrenIndex(v_tExprId(nOpNode));
3974   rhsNode := lhsNode + v_NumberOfChildren(v_tExprId(nOpNode)) - 1;
3975 
3976 nDebug := 8006;
3977 
3978   FOR i IN lhsNode..rhsNode - 1 LOOP
3979 
3980     IF(v_tExprType(i) = EXPR_PSNODE AND HAS_OPTIONS_APPLIED(i))THEN
3981 
3982       v_index := GENERATE_CHILDRENOF(v_tExplNodeId(i), v_tExprPsNodeId(i));
3983 
3984       FOR ich IN 1..v_index.COUNT LOOP
3985 
3986         lhsName := v_index(ich);
3987         rhsName := GENERATE_NUMERIC_PART(rhsNode, v_NodeId);
3988 
3989         GENERATE_CONTRIBUTE_RECORD;
3990         nSuffix := nSuffix + 1;
3991       END LOOP;
3992     ELSIF(v_tExprType(i) IN (EXPR_LITERAL, EXPR_PSNODE))THEN
3993 
3994       lhsName := GENERATE_NUMERIC_PART(i, v_NodeId);
3995       v_NodeId := v_tExprPsNodeId(i);
3996       rhsName := GENERATE_NUMERIC_PART(rhsNode, v_NodeId);
3997 
3998       GENERATE_CONTRIBUTE_RECORD;
3999       nSuffix := nSuffix + 1;
4000     ELSE
4001 
4002       RAISE CZ_R_INVALID_NUMRULE_NODE;
4003     END IF;
4004   END LOOP;
4005 END;
4006 ---------------------------------------------------------------------------------------
4007 PROCEDURE GENERATE_DYNAMIC_LOGIC IS
4008   v_result        tStringArray;
4009   v_children      tIntegerArray;
4010   ListType        PLS_INTEGER;
4011   v_name          VARCHAR2(4000);
4012   v_return        VARCHAR2(4000);
4013   v_object        VARCHAR2(4000);
4014   v_index         PLS_INTEGER;
4015 BEGIN
4016 
4017   IF(v_tExprType(jConsequentRoot) = EXPR_ARGUMENT)THEN
4018 
4019    ListType := DATA_TYPE_NODE;
4020    v_result := GENERATE_ARGUMENT(jConsequentRoot, ListType);
4021   END IF;
4022 
4023   nLocalDefaults := nLocalDefaults + 1;
4024   v_return := t_prefix || TO_CHAR(nLocalDefaults);
4025   v_index := 1;
4026 
4027   v_result.DELETE;
4028   v_result := GENERATE_EXPRESSION(jAntecedentRoot, ListType);
4029   v_children := EXPAND_NODE_OPTIONAL(v_tExprPsNodeId(jConsequentRoot));
4030 
4031   FOR i IN 1..v_result.COUNT LOOP
4032     FOR ii IN 1..v_children.COUNT LOOP
4033 
4034       v_name := GENERATE_NAME_EXPL(v_tExplNodeId(jConsequentRoot), glPsNodeId(v_children(ii)));
4035       v_object := v_return || '_' || TO_CHAR(v_index);
4036 
4037       vLogicLine := 'OBJECT ' || v_object || NewLine ||
4038                     'GS I ... ' || TO_CHAR(nReasonId) || NewLine ||
4039                     'GL' || OperatorLetters(OPERATOR_ALLOF) || v_name || NewLine ||
4040                     'GR' || OperatorLetters(OPERATOR_ALLOF) || v_object || NewLine ||
4041                     'INC ' || v_result(i) || ' ' || v_object || ' ' || v_name ||
4042                     ' ... ' || TO_CHAR(nReasonId) || NewLine;
4043       PACK;
4044 
4045       v_index := v_index + 1;
4046     END LOOP;
4047   END LOOP;
4048 END GENERATE_DYNAMIC_LOGIC;
4049 ---------------------------------------------------------------------------------------
4050 PROCEDURE GENERATE_NUMERIC_RULE IS
4051 
4052   v_index  PLS_INTEGER;
4053 BEGIN
4054 
4055     IF(jAntecedentRoot IS NULL OR jConsequentRoot IS NULL)THEN
4056       RAISE CZ_R_INVALID_NUMERIC_RULE;
4057     END IF;
4058 
4059     IF(v_tExprType(jAntecedentRoot) = EXPR_OPERATOR AND (NOT v_ChildrenIndex.EXISTS(v_tExprId(jAntecedentRoot))))THEN
4060       RAISE CZ_R_INCOMPLETE_NUMERIC_RULE;
4061     END IF;
4062 
4063     IF(HAS_INTEGER_VALUE(jConsequentRoot) = GENERATE_INCREMENT)THEN
4064 
4065       --For a numeric rule, if RHS has an integer value, the antecedent root should be a rounding operator.
4066       --As a fix for the bug #3558699, we are making this check more flexible - we require the rounding
4067       --operator only if the data type of the antecedent is not convertible to integer.
4068       --As a fix for the bug #3764347, if the antecedent root is a multiply operator, we drill down into
4069       --its operands and check their data types.
4070 
4071       IF(v_tExprType(jAntecedentRoot) <> EXPR_OPERATOR OR v_tExprSubtype(jAntecedentRoot) NOT IN
4072            (OPERATOR_ROUND, OPERATOR_CEILING, OPERATOR_FLOOR, OPERATOR_TRUNCATE))THEN
4073 
4074         v_index := jAntecedentRoot;
4075         IF(v_tExprType(v_index) = EXPR_OPERATOR AND v_tExprSubtype(v_index) = OPERATOR_NONE)THEN
4076 
4077           --Bug #4180719. This is an empty operator, drill down one level.
4078 
4079           v_index:= v_ChildrenIndex(v_tExprId(v_index));
4080         END IF;
4081 
4082         IF(v_tExprType(v_index) = EXPR_OPERATOR AND v_tExprSubtype(v_index) = OPERATOR_MULT)THEN
4083 
4084           --This is a multiply operator, check the data types of the children.
4085 
4086           v_index := v_ChildrenIndex(v_tExprId(v_index));
4087 
4088           IF((NOT COMPATIBLE_DATA_TYPES(v_tExprDataType(v_index), DATA_TYPE_INTEGER)) OR
4089              (NOT COMPATIBLE_DATA_TYPES(v_tExprDataType(v_index + 1), DATA_TYPE_INTEGER)))THEN
4090 
4091             RAISE CZ_R_INVALID_NUM_SIMPLE_EXPR;
4092           END IF;
4093         ELSIF(NOT COMPATIBLE_DATA_TYPES(v_tExprDataType(v_index), DATA_TYPE_INTEGER))THEN
4094 
4095           RAISE CZ_R_INVALID_NUM_SIMPLE_EXPR;
4096         END IF;
4097       END IF;
4098 
4099       GENERATE_INCREMENT_LOGIC;
4100     ELSIF(HAS_INTEGER_VALUE(jConsequentRoot) = GENERATE_CONTRIBUTE)THEN
4101       GENERATE_CONTRIBUTE_LOGIC;
4102     ELSIF(HAS_INTEGER_VALUE(jConsequentRoot) = GENERATE_DYNAMIC)THEN
4103       GENERATE_DYNAMIC_LOGIC;
4104     ELSE
4105       RAISE CZ_R_PARAMETER_NOT_FOUND;
4106     END IF;
4107 END;
4108 ---------------------------------------------------------------------------------------
4109 PROCEDURE GENERATE_COMPARISON_RULE IS
4110  leftOper   tStringArray;
4111  rightOper  tStringArray;
4112  ListType   PLS_INTEGER;
4113  jRoot      PLS_INTEGER;
4114  jChild     PLS_INTEGER;
4115 BEGIN
4116 
4117     IF(jAntecedentRoot IS NULL OR jConsequentRoot IS NULL)THEN
4118       RAISE CZ_R_INVALID_COMPARISON_RULE;
4119     END IF;
4120 
4121     leftOper := GENERATE_EXPRESSION(jAntecedentRoot, ListType);
4122 
4123     jRoot := jConsequentRoot;
4124 
4125     IF(v_tExprType(jRoot) = EXPR_OPERATOR AND v_tExprSubtype(jRoot) IN (OPERATOR_ALLOF, OPERATOR_ANYOF) AND
4126        v_NumberOfChildren(v_tExprId(jRoot)) = 1)THEN
4127 
4128       jChild := v_ChildrenIndex(v_tExprId(jRoot));
4129       IF(v_tExprType(jChild) = EXPR_PSNODE AND (NOT v_ChildrenIndex.EXISTS(v_tExprId(jChild))))THEN
4130 
4131         jRoot := jChild;
4132       END IF;
4133     END IF;
4134 
4135     rightOper := GENERATE_EXPRESSION(jRoot, ListType);
4136 
4137     vLogicLine := 'GS' || OperatorLetters(nRuleOperator) || '... ' || TO_CHAR(nReasonId) || NewLine ||
4138                   'GL' || OperatorLetters(OPERATOR_ALLOF) || leftOper(1) || NewLine ||
4139                   'GR' || OperatorLetters(OPERATOR_ALLOF) || rightOper(1) || NewLine;
4140 
4141     PACK;
4142 END;
4143 ---------------------------------------------------------------------------------------
4144 FUNCTION GENERATE_LOGIC_TREE(j IN PLS_INTEGER) RETURN tStringArray IS
4145   v_return  tStringArray;
4146 BEGIN
4147 
4148   IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 2)THEN
4149     RAISE CZ_R_INVALID_LOGIC_RULE;
4150   END IF;
4151 
4152   nRuleOperator := v_tExprSubtype(j);
4153   jAntecedentRoot := v_ChildrenIndex(v_tExprId(j));
4154   jConsequentRoot := jAntecedentRoot + 1;
4155 
4156   v_tExprParentId(jAntecedentRoot) := NULL;
4157   v_tExprParentId(jConsequentRoot) := NULL;
4158 
4159   --High-level logic rule validation section. Should not do these validations for comparison rules.
4160   --Make sure antecedent and consequent nodes have logical value.
4161   --If this is a comparison rule with a DEFAULT operator, which was not allowed before, we will
4162   --generate this rule as a logic rule (bug #3343569).
4163 
4164   IF(RuleTemplateType = RULE_TYPE_LOGIC_RULE OR nPresentationFlag = FLAG_FREEFORM_RULE OR
4165      nRuleOperator = RULE_OPERATOR_DEFAULTS)THEN
4166 
4167     nRuleType := RULE_TYPE_LOGIC_RULE;
4168 
4169     IF(NOT HAS_LOGICAL_VALUE(jAntecedentRoot))THEN
4170       nParam := jAntecedentRoot;
4171       IF(v_tExprPsNodeId(nParam) IS NULL)THEN
4172         localString := NULL;
4173       ELSE
4174         localString := glName(glIndexByPsNodeId(v_tExprPsNodeId(nParam)));
4175       END IF;
4176 
4177       RAISE CZ_R_LOGIC_RULE_WRONG_FEAT;
4178     END IF;
4179 
4180     IF(NOT HAS_LOGICAL_VALUE(jConsequentRoot))THEN
4181       nParam := jConsequentRoot;
4182       IF(v_tExprPsNodeId(nParam) IS NULL)THEN
4183         localString := NULL;
4184       ELSE
4185         localString := glName(glIndexByPsNodeId(v_tExprPsNodeId(nParam)));
4186       END IF;
4187 
4188       RAISE CZ_R_LOGIC_RULE_WRONG_FEAT;
4189     END IF;
4190 
4191     GENERATE_LOGIC_RULE;
4192 
4193   ELSIF(RuleTemplateType = RULE_TYPE_COMPARISON_RULE)THEN
4194 
4195     nRuleType := RULE_TYPE_COMPARISON_RULE;
4196     GENERATE_COMPARISON_RULE;
4197 
4198   ELSE
4199 
4200     RAISE CZ_R_UNKNOWN_RULE_TYPE;
4201   END IF;
4202  RETURN v_return;
4203 END;
4204 ---------------------------------------------------------------------------------------
4205 FUNCTION GENERATE_NUMERIC_TREE(j IN PLS_INTEGER) RETURN tStringArray IS
4206   v_return  tStringArray;
4207 BEGIN
4208 
4209   IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 2)THEN
4210     RAISE CZ_R_INVALID_NUMERIC_RULE;
4211   END IF;
4212 
4213   nRuleType := RULE_TYPE_NUMERIC_RULE;
4214 
4215   nRuleOperator := v_tExprSubtype(j);
4216   jAntecedentRoot := v_ChildrenIndex(v_tExprId(j));
4217   jConsequentRoot := jAntecedentRoot + 1;
4218 
4219   v_tExprParentId(jAntecedentRoot) := NULL;
4220   v_tExprParentId(jConsequentRoot) := NULL;
4221 
4222   --High-level numeric rule validation section.
4223   --Make sure participating features have correct types.
4224 
4225   FOR i IN expressionStart..expressionEnd LOOP
4226     IF(v_tExprPsNodeId(i) IS NOT NULL)THEN
4227 
4228       localMinimum := glIndexByPsNodeId(v_tExprPsNodeId(i));
4229 
4230       IF(glPsNodeType(localMinimum) = PS_NODE_TYPE_FEATURE AND
4231          glFeatureType(localMinimum) = PS_NODE_FEATURE_TYPE_STRING)THEN
4232 
4233          nParam := i;
4234          RAISE CZ_R_NUMERIC_RULE_WRONG_FEAT;
4235        END IF;
4236 
4237        IF(i = jConsequentRoot AND trackableAncestor.EXISTS(v_tExprPsNodeId(i)))THEN
4238 
4239           --This node is an ancestor of a BOM trackable item. It should be prohibited from
4240           --participating on the RHS of a numeric rule.
4241 
4242           nParam := glIndexByPsNodeId(v_tExprPsNodeId(i));
4243           RAISE CZ_R_TRACKABLE_ANCESTOR;
4244         END IF;
4245     END IF;
4246   END LOOP;
4247 
4248   GENERATE_NUMERIC_RULE;
4249   RETURN v_return;
4250 END;
4251 ---------------------------------------------------------------------------------------
4252 FUNCTION GENERATE_TEMPLATE_APPLICATION(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER)
4253 RETURN tStringArray IS
4254 
4255   v_return         tStringArray;
4256   h_mapExprId      tIntegerArray_idx_vc2;
4257 
4258   jdef             PLS_INTEGER;
4259   templateStart    PLS_INTEGER;
4260   templateEnd      PLS_INTEGER;
4261   v_index          PLS_INTEGER;
4262 
4263 ---------------------------------------------------------------------------------------
4264 PROCEDURE READ_TEMPLATE(p_template_id IN NUMBER) IS
4265 
4266   --These are local arrays used only to transfer data to the relevant expression arrays.
4267 
4268   v_NodeId          tExplNodeId;
4269   v_Type            tExprType;
4270   v_Subtype         tExprSubtype;
4271   v_Id              tExprId;
4272   v_ParentId        tExprParentId;
4273   v_TemplateId      tExprTemplateId;
4274   v_ExpressId       tExpressId;
4275   v_PsNodeId        tExplNodeId;
4276   v_DataValue       tExprDataValue;
4277   v_PropertyId      tExprPropertyId;
4278   v_ArgumentIndex   tExprArgumentIndex;
4279   v_ArgumentName    tExprArgumentName;
4280   v_ConsequentFlag  tConsequentFlag;
4281   v_DataNumValue    tExprDataNumValue;
4282   v_DataType        tExprDataType;
4283 
4284 BEGIN
4285 
4286 nDebug := 8010100;
4287 
4288   IF(NOT memoryTemplateStart.EXISTS(p_template_id))THEN
4289 
4290     SELECT model_ref_expl_id, expr_type, expr_node_id, expr_parent_id, template_id,
4291            express_id, expr_subtype, ps_node_id, data_value, property_id, argument_index,
4292            argument_name, consequent_flag, data_num_value, data_type
4293     BULK COLLECT INTO v_NodeId, v_Type, v_Id, v_ParentId, v_TemplateId,
4294                       v_ExpressId, v_Subtype, v_PsNodeId, v_DataValue, v_PropertyId, v_ArgumentIndex,
4295                       v_ArgumentName, v_ConsequentFlag, v_DataNumValue, v_DataType
4296       FROM cz_expression_nodes
4297      WHERE rule_id = p_template_id
4298        AND expr_type <> EXPR_NODE_TYPE_PUNCT
4299        AND deleted_flag = FLAG_NOT_DELETED
4300      ORDER BY expr_parent_id, seq_nbr;
4301 
4302 nDebug := 8010101;
4303 
4304     IF(v_Id.COUNT = 0)THEN
4305       RAISE CZ_R_TEMPLATE_UNKNOWN;
4306     END IF;
4307 
4308     v_index := v_tTmplId.COUNT + 1;
4309     memoryTemplateStart(p_template_id) := v_index;
4310 
4311 nDebug := 8010102;
4312 
4313     FOR i IN 1..v_Id.COUNT LOOP
4314 
4315       IF(v_DataNumValue(i) IS NOT NULL)THEN v_DataValue(i) := TO_CHAR(v_DataNumValue(i)); END IF;
4316 
4317       v_tTmplNodeId(v_index)        := v_NodeId(i);
4318       v_tTmplType(v_index)          := v_Type(i);
4319       v_tTmplSubtype(v_index)       := v_Subtype(i);
4320       v_tTmplId(v_index)            := v_Id(i);
4321       v_tTmplParentId(v_index)      := v_ParentId(i);
4322       v_tTmplTemplateId(v_index)    := v_TemplateId(i);
4323       v_tTmplExpressId(v_index)     := v_ExpressId(i);
4324       v_tTmplPsNodeId(v_index)      := v_PsNodeId(i);
4325       v_tTmplPropertyId(v_index)    := v_PropertyId(i);
4326       v_tTmplArgumentIndex(v_index) := v_ArgumentIndex(i);
4327       v_tTmplArgumentName(v_index)  := v_ArgumentName(i);
4328       v_tTmplConsequent(v_index)    := v_ConsequentFlag(i);
4329       v_tTmplDataValue(v_index)     := v_DataValue(i);
4330       v_tTmplDataType(v_index)      := v_DataType(i);
4331 
4332       v_index := v_index + 1;
4333     END LOOP;
4334 
4335     memoryTemplateEnd(p_template_id) := v_tTmplId.COUNT;
4336   END IF;
4337 END;
4338 ---------------------------------------------------------------------------------------
4339 FUNCTION COPY_EXPRESSION_NODE(j_from IN PLS_INTEGER, j_parent IN PLS_INTEGER)
4340 RETURN PLS_INTEGER IS
4341   j_to  PLS_INTEGER;
4342 BEGIN
4343 
4344 nDebug := 8010105;
4345 
4346    j_to := v_tExprId.COUNT + 1;
4347    nLocalExprId := nLocalExprId + 1;
4348 
4349    v_tExprId(j_to) := nLocalExprId;
4350    v_tExprParentId(j_to) := j_parent;
4351 
4352    v_tExplNodeId(j_to)       := v_tExplNodeId(j_from);
4353    v_tExprType(j_to)         := v_tExprType(j_from);
4354    v_tExprSubtype(j_to)      := v_tExprSubtype(j_from);
4355    v_tExprTemplateId(j_to)   := v_tExprTemplateId(j_from);
4356    v_tExprParamIndex(j_to)   := v_tExprParamIndex(j_from);
4357    v_tExprParSignature(j_to) := v_tExprParSignature(j_from);
4358    v_tExpressId(j_to)        := v_tExpressId(j_from);
4359    v_tExprPsNodeId(j_to)     := v_tExprPsNodeId(j_from);
4360    v_tExprDataValue(j_to)    := v_tExprDataValue(j_from);
4361    v_tExprDataType(j_to)     := v_tExprDataType(j_from);
4362    v_tExprPropertyId(j_to)   := v_tExprPropertyId(j_from);
4363    v_tConsequentFlag(j_to)   := v_tConsequentFlag(j_from);
4364    v_tExprArgumentName(j_to) := v_tExprArgumentName(j_from);
4365 
4366 nDebug := 8010106;
4367 
4368  RETURN j_to;
4369 END;
4370 ---------------------------------------------------------------------------------------
4371 PROCEDURE COPY_EXPRESSION_TREE(j_from IN PLS_INTEGER, j_parent IN PLS_INTEGER) IS
4372   j_child     PLS_INTEGER;
4373   j_children  tIntegerArray;
4374 BEGIN
4375 
4376 nDebug := 8010107;
4377 
4378   IF(v_ChildrenIndex.EXISTS(v_tExprId(j_from)))THEN
4379 
4380     j_child := v_ChildrenIndex(v_tExprId(j_from));
4381 
4382     WHILE(v_tExprParentId(j_child) = v_tExprId(j_from))LOOP
4383 
4384       j_children(j_child) := COPY_EXPRESSION_NODE(j_child, j_parent);
4385       j_child := j_child + 1;
4386     END LOOP;
4387 
4388     j_child := v_ChildrenIndex(v_tExprId(j_from));
4389 
4390     WHILE(v_tExprParentId(j_child) = v_tExprId(j_from))LOOP
4391 
4392       COPY_EXPRESSION_TREE(j_child, j_children(j_child));
4393       j_child := j_child + 1;
4394     END LOOP;
4395   END IF;
4396 
4397 nDebug := 8010108;
4398 
4399 END;
4400 ---------------------------------------------------------------------------------------
4401 BEGIN
4402 
4403   RuleTemplateType := v_tExprSubtype(j);
4404   READ_TEMPLATE(RuleTemplateType);
4405   templateStart := v_tExprId.COUNT + 1;
4406 
4407   FOR i IN memoryTemplateStart(RuleTemplateType)..memoryTemplateEnd(RuleTemplateType) LOOP
4408 
4409     IF(v_tTmplType(i) = EXPR_ARGUMENT AND v_tTmplArgumentIndex(i) IS NOT NULL)THEN
4410 
4411 nDebug := 8010109;
4412 
4413       --This is an argument, may correspond to a collection of paramaters in the template
4414       --application.
4415 
4416       jdef := 0;
4417 
4418       FOR ii IN expressionStart..expressionEnd LOOP
4419 
4420         IF(v_tExprParamIndex(ii) = v_tTmplArgumentIndex(i))THEN
4421 
4422           jdef := 1;
4423           v_index := v_tExprId.COUNT + 1;
4424           nLocalExprId := nLocalExprId + 1;
4425 
4426           v_tExprId(v_index)           := nLocalExprId;
4427           h_mapExprId(v_tExprId(ii))   := nLocalExprId;
4428 
4429           --If this entry gets overwritten many times, it is not a problem because in this case it
4430           --will never be used.
4431 
4432           h_mapExprId(v_tTmplId(i))    := nLocalExprId;
4433 
4434           v_tExprParentId(v_index)     := v_tTmplParentId(i);
4435           v_tExplNodeId(v_index)       := v_tExplNodeId(ii);
4436           v_tExprType(v_index)         := v_tExprType(ii);
4437           v_tExprSubtype(v_index)      := v_tExprSubtype(ii);
4438           v_tExprTemplateId(v_index)   := v_tExprTemplateId(ii);
4439           v_tExpressId(v_index)        := v_tExpressId(ii);
4440           v_tExprPsNodeId(v_index)     := v_tExprPsNodeId(ii);
4441           v_tExprDataValue(v_index)    := v_tExprDataValue(ii);
4442           v_tExprDataType(v_index)     := v_tExprDataType(ii);
4443           v_tExprPropertyId(v_index)   := v_tExprPropertyId(ii);
4444           v_tConsequentFlag(v_index)   := v_tConsequentFlag(ii);
4445           v_tExprArgumentName(v_index) := v_tExprArgumentName(ii);
4446           v_tExprParamIndex(v_index)   := v_tExprParamIndex(ii);
4447           v_tExprParSignature(v_index) := v_tExprParSignature(ii);
4448 
4449           IF(v_tExprType(v_index) = EXPR_TEMPLATE)THEN v_tExprType(v_index) := EXPR_OPERATOR; END IF;
4450         END IF;
4451       END LOOP;
4452 
4453       --No parameter was found for this argument - incomplete rule.
4454 
4455       IF(jdef = 0)THEN RAISE CZ_R_INCORRECT_NODE_ID; END IF;
4456     ELSE
4457 
4458 nDebug := 8010110;
4459 
4460       --This is a regular node in the template definition, just copy.
4461 
4462       v_index := v_tExprId.COUNT + 1;
4463       nLocalExprId := nLocalExprId + 1;
4464 
4465       v_tExprId(v_index)           := nLocalExprId;
4466       h_mapExprId(v_tTmplId(i))    := nLocalExprId;
4467 
4468       v_tExprParentId(v_index)     := v_tTmplParentId(i);
4469       v_tExplNodeId(v_index)       := v_tTmplNodeId(i);
4470       v_tExprType(v_index)         := v_tTmplType(i);
4471       v_tExprSubtype(v_index)      := v_tTmplSubtype(i);
4472       v_tExprTemplateId(v_index)   := v_tTmplTemplateId(i);
4473       v_tExpressId(v_index)        := v_tTmplExpressId(i);
4474       v_tExprPsNodeId(v_index)     := v_tTmplPsNodeId(i);
4475       v_tExprDataValue(v_index)    := v_tTmplDataValue(i);
4476       v_tExprDataType(v_index)     := v_tTmplDataType(i);
4477       v_tExprPropertyId(v_index)   := v_tTmplPropertyId(i);
4478       v_tConsequentFlag(v_index)   := v_tTmplConsequent(i);
4479       v_tExprArgumentName(v_index) := v_tTmplArgumentName(i);
4480     END IF;
4481   END LOOP;
4482 
4483 nDebug := 8010111;
4484 
4485   templateEnd := v_tExprId.COUNT;
4486 
4487   FOR i IN templateStart..templateEnd LOOP
4488 
4489     IF(v_tExprParentId(i) IS NOT NULL)THEN
4490 
4491       IF(NOT h_mapExprId.EXISTS(v_tExprParentId(i)))THEN RAISE CZ_R_INCORRECT_NODE_ID; END IF;
4492       v_tExprParentId(i) := h_mapExprId(v_tExprParentId(i));
4493     END IF;
4494   END LOOP;
4495 
4496 nDebug := 8010112;
4497 
4498   FOR i IN expressionStart..expressionEnd LOOP
4499 
4500     IF(h_mapExprId.EXISTS(v_tExprId(i)))THEN
4501 
4502       COPY_EXPRESSION_TREE(i, h_mapExprId(v_tExprId(i)));
4503     END IF;
4504   END LOOP;
4505 
4506   expressionStart := templateStart;
4507   expressionEnd := v_tExprId.COUNT;
4508 
4509 nDebug := 8010114;
4510 
4511   --We need to populate all the auxiliary arrays because now this is the expression we will be
4512   --processing. We don't really have to empty these arrays.
4513 
4514   v_IndexByExprNodeId.DELETE;
4515   v_NumberOfChildren.DELETE;
4516   v_ChildrenIndex.DELETE;
4517 
4518   FOR i IN expressionStart..expressionEnd LOOP
4519 
4520     v_tExprSubtype(i) := v_tExprTemplateId(i);
4521 
4522     --Add the indexing option.
4523 
4524     v_IndexByExprNodeId(v_tExprId(i)) := i;
4525 
4526     IF(v_tExprParentId(i) IS NOT NULL)THEN
4527 
4528       IF(v_NumberOfChildren.EXISTS(v_tExprParentId(i)))THEN
4529         v_NumberOfChildren(v_tExprParentId(i)) := v_NumberOfChildren(v_tExprParentId(i)) + 1;
4530       ELSE
4531         v_NumberOfChildren(v_tExprParentId(i)) := 1;
4532       END IF;
4533 
4534       IF(NOT v_ChildrenIndex.EXISTS(v_tExprParentId(i)))THEN
4535         v_ChildrenIndex(v_tExprParentId(i)) := i;
4536       END IF;
4537 
4538     ELSE
4539 
4540       --This is the root of the exploded template application expression tree.
4541 
4542       jdef := i;
4543     END IF;
4544 
4545 nDebug := 8010115;
4546 
4547   END LOOP;
4548 
4549 nDebug := 8010116;
4550 
4551   v_return := GENERATE_EXPRESSION(jdef, ListType);
4552   RETURN v_return;
4553 END;
4554 ---------------------------------------------------------------------------------------
4555 FUNCTION LOOKUP_ARGUMENT(j IN PLS_INTEGER) RETURN PLS_INTEGER IS
4556   argIndex  PLS_INTEGER := 0;
4557 BEGIN
4558 
4559   IF(parameterScope.COUNT = 0)THEN
4560     RAISE CZ_R_EMPTY_PARAMETER_SCOPE;
4561   END IF;
4562 
4563   FOR i IN 1..parameterName.COUNT LOOP
4564     IF(parameterName(i) = v_tExprArgumentName(j))THEN argIndex := i; EXIT; END IF;
4565   END LOOP;
4566 
4567   IF(argIndex = 0)THEN
4568     RAISE CZ_R_PARAMETER_NOT_FOUND;
4569   END IF;
4570 
4571  RETURN argIndex;
4572 END;
4573 ---------------------------------------------------------------------------------------
4574 FUNCTION GENERATE_ARGUMENT(j IN PLS_INTEGER, ListType IN OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
4575   v_return  tStringArray;
4576   argIndex  PLS_INTEGER := 0;
4577 BEGIN
4578 
4579 nDebug := 7004010;
4580 
4581   --The procedure can be called with a particular ListType to get a specific field from the
4582   --parameter scope.
4583   --Call with ListType = 0 to get the data type from cz_expression_nodes.
4584   --When called with ListType NULL, generate name or return value field.
4585 
4586   --Bug #4681261 - with re-using of temporary tables, we cannot use stored generated names
4587   --anymore because these names depend not only on ps_node_id, model_ref_expl_id but also
4588   --on where the rule is assined. Therefore need to generate the name here instead of in
4589   --generate_iterator.
4590 
4591   argIndex := LOOKUP_ARGUMENT(j);
4592 
4593   v_tExprPsNodeId(j) := parameterScope(argIndex).node_id;
4594   v_tExplNodeId(j) := parameterScope(argIndex).node_id_ex;
4595 
4596   --If this is a node, generate name here.
4597 
4598   IF(v_tExprPsNodeId(j) IS NOT NULL AND v_tExplNodeId(j) IS NOT NULL AND
4599      parameterScope(argIndex).node_value IS NULL AND parameterScope(argIndex).node_obj IS NULL)THEN
4600 
4601        v_return(1) := GENERATE_NAME_EXPL(v_tExplNodeId(j), v_tExprPsNodeId(j));
4602        parameterScope(argIndex).node_value := v_return(1);
4603        parameterScope(argIndex).node_obj := v_return(1);
4604   END IF;
4605 
4606   IF(ListType = DATA_TYPE_VOID)THEN ListType := v_tExprDataType(j); END IF;
4607   IF(ListType IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL, DATA_TYPE_BOOLEAN, DATA_TYPE_TEXT))THEN
4608 
4609     v_return(1) := parameterScope(argIndex).node_value;
4610   ELSIF(ListType = DATA_TYPE_NODE)THEN
4611 
4612     v_return(1) := parameterScope(argIndex).node_id;
4613   ELSIF(ListType = DATA_TYPE_VARIANT)THEN
4614 
4615     v_return(1) := parameterScope(argIndex).node_obj;
4616   ELSE
4617 
4618     v_return(1) := parameterScope(argIndex).node_value;
4619   END IF;
4620 
4621 nDebug := 7004019;
4622 
4623   RETURN v_return;
4624 END;
4625 ---------------------------------------------------------------------------------------
4626 FUNCTION GENERATE_FORALL(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tIteratorArray;
4627 ---------------------------------------------------------------------------------------
4628 FUNCTION GENERATE_REFNODE(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
4629   v_children    tIntegerArray;
4630   v_object      VARCHAR2(128);
4631   nodeChild     NUMBER;
4632   featChild     NUMBER;
4633   featPsNodeId  NUMBER; --kdande; Bug 6881902; 11-Mar-2008
4634   LocalType     PLS_INTEGER;
4635   IsNumeric     PLS_INTEGER;
4636   IsNotZero     PLS_INTEGER;
4637   nCheck        NUMBER;
4638   countTrue     PLS_INTEGER := 0;
4639   countFalse    PLS_INTEGER := 0;
4640   v_actual      VARCHAR2(16) := ' ';
4641   v_return      tStringArray;
4642   v_propval     tStringArray;
4643   v_psnode      tStringArray;
4644   CurrentId     NUMBER;
4645   nodeId        NUMBER; --jonatara:bug7041718
4646   v_sysprop     PLS_INTEGER;
4647   v_mutable     VARCHAR2(1);
4648   v_collection  VARCHAR2(1);
4649   v_context     PLS_INTEGER;
4650 BEGIN
4651 
4652 nDebug := 7004070;
4653 
4654  CurrentId := v_tExprId(j);
4655  nodeChild := v_ChildrenIndex(CurrentId);
4656  nLocalDefaults := nLocalDefaults + 1;
4657 
4658  IF(v_tExprType(j) = EXPR_ARGUMENT)THEN
4659 
4660    --This is an argument, we assume that it is of type 'node'.
4661 
4662    LocalType := DATA_TYPE_NODE;
4663    v_return := GENERATE_ARGUMENT(j, LocalType);
4664 
4665  ELSE
4666 
4667    --It's not an argument, so it's a ps_node.
4668 
4669    v_return(1) := TO_CHAR(v_tExprPsNodeId(j));
4670  END IF;
4671 
4672  nodeId := v_return(1);
4673 
4674  WHILE(v_tExprParentId.EXISTS(nodeChild) AND v_tExprParentId(nodeChild) = CurrentId)LOOP
4675    IF(v_tExplNodeId(nodeChild) IS NULL OR v_tExplNodeId(nodeChild) = -1 OR
4676 
4677       --Bug #3821827, caused by a corruption, when the explosion_id value was neither NULL or -1,
4678       --but was just some incorrect value when it is expected to be NULL.
4679 
4680       (NOT v_NodeLogicLevel.EXISTS(v_tExplNodeId(nodeChild))))THEN
4681 
4682      v_tExplNodeId(nodeChild) := v_ExplByPsNodeId(nodeId);
4683    END IF;
4684 
4685    IF(h_SeededName.EXISTS(v_tExprSubtype(nodeChild)) AND h_SeededName(v_tExprSubtype(nodeChild)) = RULE_SYS_PROP_SELECTION)THEN
4686 
4687      featChild := v_ChildrenIndex(CurrentId);
4688      featPsNodeId := v_return(1);
4689      v_children := EXPAND_NODE_OPTIONAL(featPsNodeId);
4690      v_sysprop := nodeChild + 1;
4691      LocalType := DATA_TYPE_VOID;
4692      v_context := 1;
4693 
4694      IF(v_tExprParentId.EXISTS(v_sysprop) AND v_tExprParentId(v_sysprop) = CurrentId)THEN
4695 
4696        --The system property was explicitly specified.
4697 
4698 nDebug := 7004073;
4699 
4700        IF(v_tExprType(v_sysprop) = EXPR_NODE_TYPE_SYSPROP)THEN
4701          IF(NOT h_SeededName.EXISTS(v_tExprSubtype(v_sysprop)))THEN RAISE CZ_E_BAD_PROPERTY_TYPE; END IF;
4702 
4703          IF(NOT APPLICABLE_SYS_PROP(j, glPsNodeId(v_children(1)), v_tExprSubtype(v_sysprop)))THEN
4704 
4705            auxIndex := v_children(1);
4706            localString := h_ReportName(v_tExprSubtype(v_sysprop));
4707            RAISE CZ_R_INCOMPATIBLE_SYSPROP;
4708          END IF;
4709        END IF;
4710 
4711        v_tExplNodeId(v_sysprop) := v_ExplByPsNodeId(nodeId);
4712        v_context := 0;
4713      ELSE
4714 
4715        --This is Node.Selection(), the actual system property is not specified. It can be either .State()
4716        --or .Quantity() depending on the context.
4717 
4718        IF(COMPATIBLE_DATA_TYPES(GET_ARGUMENT_INFO(v_tExprParamIndex(j), v_tExprParSignature(j),
4719                                                   v_mutable, v_collection), DATA_TYPE_BOOLEAN))THEN
4720          --The context is boolean.
4721 
4722 nDebug := 7004071;
4723 
4724          IF(NOT APPLICABLE_SYS_PROP(j, NULL, RULE_SYS_PROP_STATE))THEN
4725 
4726            auxIndex := glIndexByPsNodeId(nodeId);
4727            localString := 'State';
4728            RAISE CZ_R_INCOMPATIBLE_SYSPROP;
4729          END IF;
4730 
4731          ListType := DATA_TYPE_BOOLEAN;
4732          v_return.DELETE;
4733          v_return(1) := GENERATE_NAME(j, nodeId);
4734 
4735          --This is Feature.Selection().State(), which in a boolean context is equivalent to Feature.
4736 
4737          EXIT;
4738        ELSE
4739 
4740          --The context is numeric.
4741 
4742 nDebug := 7004072;
4743 
4744          IF(NOT APPLICABLE_SYS_PROP(j, glPsNodeId(v_children(1)), RULE_SYS_PROP_QUANTITY))THEN
4745 
4746            auxIndex := v_children(1);
4747            localString := 'Quantity';
4748            RAISE CZ_R_INCOMPATIBLE_SYSPROP;
4749          END IF;
4750 
4751          LocalType := DATA_TYPE_DECIMAL;
4752        END IF;
4753      END IF;
4754 
4755      v_return.DELETE;
4756 
4757      IF(nRuleType = RULE_TYPE_NUMERIC_RULE AND v_context = 0 AND
4758         v_tExprType(v_sysprop) = EXPR_NODE_TYPE_SYSPROP AND
4759         h_SeededName(v_tExprSubtype(v_sysprop)) = RULE_SYS_PROP_STATE)THEN
4760 
4761        --This is Node.Selection().State() in a numeric rule, State() was explicitly specified.
4762        --Bugs #4198455, #4366598.
4763 
4764        v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
4765        vLogicLine := 'OBJECT ' || v_return(1) || NewLine;
4766        PACK;
4767 
4768        FOR i IN 1..v_children.COUNT LOOP
4769 
4770          vLogicLine := 'OBJECT ' || v_return(1) || '_' || TO_CHAR(i) || NewLine ||
4771                        'GS I ... ' || TO_CHAR(nReasonId) || NewLine ||
4772                        'GL' || OperatorLetters(OPERATOR_ANYOF) || GENERATE_NAME(j, glPsNodeId(v_children(i))) || NewLine ||
4773                        'GR' || OperatorLetters(OPERATOR_ANYOF) || v_return(1) || '_' || TO_CHAR(i) || NewLine;
4774          PACK;
4775 
4776          vLogicLine := 'INC ' || v_return(1) || '_' || TO_CHAR(i) || ' ' || v_return(1) ||
4777                           OperatorLiterals(OPERATOR_ROUND) || '... ' || TO_CHAR(nReasonId) || NewLine;
4778          PACK;
4779        END LOOP;
4780 
4781        RETURN v_return;
4782      END IF;
4783 
4784      FOR i IN 1..v_children.COUNT LOOP
4785 
4786        v_propval(1) := TO_CHAR(glPsNodeId(v_children(i)));
4787 
4788        IF(v_context = 1)THEN v_propval(1) := GENERATE_NAME(j, glPsNodeId(v_children(i)));
4789        ELSE v_propval := SYSTEM_PROPERTY_VALUE(v_sysprop, v_propval, LocalType); END IF;
4790        ListType := LocalType;
4791 
4792        BEGIN
4793          nCheck := TO_NUMBER(v_propval(1));
4794          IsNumeric := 1;
4795          IsNotZero := 1;
4796          IF(nCheck = 0)THEN
4797            IsNotZero := 0;
4798          END IF;
4799        EXCEPTION
4800          WHEN OTHERS THEN
4801            IsNumeric := 0;
4802            IsNotZero := 1;
4803        END;
4804 
4805        IF(LocalType IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL))THEN
4806 
4807          v_object := t_prefix || TO_CHAR(nLocalDefaults) || '_' || TO_CHAR(i);
4808 
4809          IF(IsNumeric = 1)THEN
4810 
4811             --If a number, we have to GATE it throught the real option. We will do
4812             --it even if the property value is 0 for consistency.
4813 
4814             vLogicLine := 'OBJECT ' || v_object || NewLine ||
4815                           'GS I ... ' || TO_CHAR(nReasonId) || NewLine ||
4816                           'GL' || OperatorLetters(OPERATOR_ANYOF) || GENERATE_NAME(featChild, glPsNodeId(v_children(i))) || NewLine ||
4817                           'GR' || OperatorLetters(OPERATOR_ANYOF) || v_object || NewLine;
4818          ELSE
4819 
4820             --If the property value is not numeric, then it is a "P_" name returned
4821             --as a result of Feat.#Selection.Count. In this case we have to GATE it
4822             --by making an INC from the real option. This prevents from propagating
4823             --when the option is FALSE.
4824 
4825             vLogicLine := 'OBJECT ' || v_object || NewLine ||
4826                           'INC ' || GENERATE_NAME(featChild, glPsNodeId(v_children(i))) || ' ' || v_object ||
4827                           OperatorLiterals(OPERATOR_NONE) ||
4828                           '... ' || TO_CHAR(nReasonId) || NewLine;
4829          END IF;
4830 
4831          PACK;
4832 
4833          IF(NOT v_return.EXISTS(1))THEN
4834 
4835            v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
4836            vLogicLine := 'TOTAL ' || v_return(1) || NewLine;
4837            PACK;
4838          END IF;
4839 
4840          --In any case we multiply the property count (a number if it's .property or
4841          --the actual option if it is .#Count) by the intermediate object (the gate)
4842          --which is only true if the option is true. That way if no options selected
4843          --the result will be UNKNOWN.
4844 
4845          IF(IsNumeric = 0)THEN
4846 
4847            --If the property is not numeric then we multiply by 1 because it is the
4848            --count of the option.
4849 
4850            vLogicLine := 'CONTRIBUTE ' || v_object || OperatorLiterals(OPERATOR_MULT) ||
4851                          '1 ' || v_return(1) || v_actual || '... ' || TO_CHAR(nReasonId) || NewLine;
4852 
4853          ELSIF(IsNotZero = 1)THEN
4854 
4855            --If the property is not zero we have to multiply the gate by the property.
4856 
4857            vLogicLine := 'CONTRIBUTE ' || v_object || OperatorLiterals(OPERATOR_MULT) ||
4858                          v_propval(1) || ' ' || v_return(1) || v_actual || '... ' || TO_CHAR(nReasonId) || NewLine;
4859 
4860          ELSE
4861 
4862            --If the property value is 0, we will subtract the gate from the gate. This
4863            --is required in order to propagate 0 only if the option is selected. If we
4864            --used "gate * 0" it would always propagate 0, even if the gate is UNKNOWN,
4865            --and we don't want that to happen.
4866 
4867            vLogicLine := 'CONTRIBUTE ' || v_object || OperatorLiterals(OPERATOR_SUB) ||
4868                          v_object || ' ' || v_return(1) || v_actual || '... ' || TO_CHAR(nReasonId) || NewLine;
4869 
4870          END IF;
4871          PACK;
4872 
4873        ELSE
4874 
4875          IF(LocalType <> DATA_TYPE_TEXT OR generateCompare = 1)THEN
4876 
4877             v_return(i) := GENERATE_NAME(featChild, glPsNodeId(v_children(i))) || PROPERTY_DELIMITER || v_propval(1);
4878          ELSE
4879            --The expression contained a Text property which is only allowed in a comparison expression.
4880            --A Text property is not allowed in the context of your expression. Rule '%RULENAME' in
4881            --Model '%MODELNAME' ignored.
4882 
4883             RAISE CZ_R_PROPERTY_NOT_ALLOWED;
4884          END IF;
4885        END IF;
4886      END LOOP;
4887 
4888      IF(LocalType = DATA_TYPE_BOOLEAN)THEN
4889 
4890        --The code inside this block has been changed as a fix for bug #1862896.
4891        --Start with creating gating objects and INC relations for all the extracted
4892        --options.
4893 
4894        FOR i IN 1..v_return.COUNT LOOP
4895 
4896          v_object := t_prefix || TO_CHAR(nLocalDefaults) || '_' || TO_CHAR(i);
4897          vLogicLine := 'OBJECT ' || v_object || NewLine ||
4898                        'INC ' || EXTRACT_PROPERTY_NODE(v_return(i)) || ' ' || v_object ||
4899                        OperatorLiterals(OPERATOR_ROUND) || '... ' || TO_CHAR(nReasonId) || NewLine;
4900 
4901          --We are going to calculate the counts of true/false options in order to decide whether
4902          --we need to include the unsatisfied message id in the following GS relations. First we
4903          --overwrite the concatenated name/property value string in v_return to be just property
4904          --value as we don't use the concatenated format of v_return in this branch anymore.
4905 
4906          v_return(i) := EXTRACT_PROPERTY_VALUE(v_return(i));
4907          IF(v_return(i) = BOOLEAN_TRUE_REPRESENTATION)THEN countTrue := countTrue + 1;
4908          ELSIF(v_return(i) = BOOLEAN_FALSE_REPRESENTATION)THEN countFalse := countFalse + 1;
4909          END IF;
4910 
4911          PACK;
4912        END LOOP;
4913 
4914        --This is the resulting object that will be returned. Any of the TRUE gating
4915        --objects requires this object, any of the FALSE gating objects negates it.
4916 
4917        v_object := t_prefix || TO_CHAR(nLocalDefaults);
4918        vLogicLine := 'OBJECT ' || v_object || NewLine;
4919 
4920        IF(countTrue > 0)THEN
4921 
4922          localString := NULL;
4923          IF(countTrue > 1)THEN localString := sUnsatisfiedId; END IF;
4924 
4925          vLogicLine := vLogicLine || 'GS R ' || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
4926                      'GL' || OperatorLetters(OPERATOR_ANYOF);
4927          PACK;
4928 
4929 nDebug := 8001156;
4930 
4931          --Generate the list of all the TRUE gating objects.
4932 
4933          FOR i IN 1..v_return.COUNT LOOP
4934 
4935            IF(v_return(i) = BOOLEAN_TRUE_REPRESENTATION)THEN
4936              vLogicLine := v_object || '_' || TO_CHAR(i) || ' ';
4937              PACK;
4938            END IF;
4939          END LOOP;
4940 
4941          vLogicLine := NewLine || 'GR' || OperatorLetters(OPERATOR_ANYOF) || v_object || NewLine;
4942        END IF;
4943 
4944        IF(countFalse > 0)THEN
4945 
4946          localString := NULL;
4947          IF(countFalse > 1)THEN localString := sUnsatisfiedId; END IF;
4948 
4949          vLogicLine := vLogicLine || 'GS N ' || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
4950                        'GL' || OperatorLetters(OPERATOR_ANYOF);
4951          PACK;
4952 
4953 nDebug := 8001157;
4954 
4955          --Generate the list of all the FALSE gating objects.
4956 
4957          FOR i IN 1..v_return.COUNT LOOP
4958 
4959            IF(v_return(i) = BOOLEAN_FALSE_REPRESENTATION)THEN
4960              vLogicLine := v_object || '_' || TO_CHAR(i) || ' ';
4961              PACK;
4962            END IF;
4963          END LOOP;
4964 
4965          vLogicLine := NewLine || 'GR' || OperatorLetters(OPERATOR_ANYOF) || v_object || NewLine;
4966        END IF;
4967        PACK;
4968 
4969        v_return.DELETE;
4970        v_return(1) := v_object;
4971 
4972      END IF;
4973 
4974      --We don't need to move on as we already processed the following expression node(s).
4975 
4976      EXIT;
4977    ELSE
4978 
4979      IF(v_tExprType(nodeChild) = EXPR_NODE_TYPE_SYSPROP)THEN
4980        IF(NOT h_SeededName.EXISTS(v_tExprSubtype(nodeChild)))THEN RAISE CZ_E_BAD_PROPERTY_TYPE; END IF;
4981 
4982        IF(NOT APPLICABLE_SYS_PROP(j, NULL, v_tExprSubtype(nodeChild)))THEN
4983 
4984          auxIndex := glIndexByPsNodeId(nodeId);
4985          localString := h_ReportName(v_tExprSubtype(nodeChild));
4986          RAISE CZ_R_INCOMPATIBLE_SYSPROP;
4987        END IF;
4988      END IF;
4989 
4990      v_propval := SYSTEM_PROPERTY_VALUE(nodeChild, v_return, ListType);
4991 
4992      IF(ListType = DATA_TYPE_TEXT)THEN
4993 
4994        --This is a direct user or system property of DATA_TYPE_TEXT. Currently we don't allow
4995        --any operations to work with strings other than the comparison operators, therefore we
4996        --are going from here back to the GENERATE_COMPARE procedure , which expects the output
4997        --to be a combination of the node's P_ name and the property value.
4998 
4999        --This whole IF block is a part of the fix for the bug #1706286.
5000 
5001        IF(generateCompare = 1)THEN
5002 
5003          FOR i IN 1..v_propval.COUNT LOOP
5004 
5005            v_return(i) := GENERATE_NAME(v_ChildrenIndex(CurrentId), v_return(i)) || PROPERTY_DELIMITER || v_propval(i);
5006          END LOOP;
5007        ELSIF(generateCollect = 1)THEN
5008 
5009          --Exclusion from the above comment: we can be generating the COLLECT expression. Such expression
5010          --can contain references to text properties to be used for comparison in the WHERE clause, but
5011          --at this time we do not know that they will be used in comparison. We need to just return the
5012          --value of the property.
5013 
5014          v_return := v_propval;
5015        ELSE
5016          --The expression contained a Text property which is only allowed in a comparison expression.
5017          --A Text property is not allowed in the context of your expression. Rule '%RULENAME' in
5018          --Model '%MODELNAME' ignored.
5019 
5020          RAISE CZ_R_PROPERTY_NOT_ALLOWED;
5021        END IF;
5022      ELSIF(ListType = DATA_TYPE_BOOLEAN AND v_tExprType(nodeChild) = EXPR_PROP)THEN
5023 
5024        --For boolean user properties we replace the 0/1 values with corresponding object names.
5025        --Bug #3371279.
5026 
5027        FOR i IN 1..v_propval.COUNT LOOP
5028          IF(v_propval(i) = BOOLEAN_TRUE_REPRESENTATION)THEN v_return(i) := ALWAYS_TRUE;
5029          ELSE v_return(i) := ALWAYS_FALSE; END IF;
5030        END LOOP;
5031      ELSE
5032 
5033        v_return := v_propval;
5034      END IF;
5035    END IF;
5036 
5037    nodeChild := nodeChild + 1;
5038  END LOOP;
5039 
5040 nDebug := 7004080;
5041 
5042  RETURN v_return;
5043 END;
5044 ---------------------------------------------------------------------------------------
5045 FUNCTION GENERATE_ITERATOR(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tIteratorArray IS
5046 
5047   v_return  tIteratorArray;
5048   v_iterin  tIteratorArray;
5049   nChild    PLS_INTEGER;
5050   nCount    PLS_INTEGER;
5051   nGrand    PLS_INTEGER;
5052   nType     PLS_INTEGER;
5053   v_result  tIntegerArray;
5054   v_record  tStringArray;
5055   nodeName  VARCHAR2(4000);
5056 
5057 BEGIN
5058 
5059 nDebug := 7004000;
5060 
5061   nChild := v_ChildrenIndex(v_tExprId(j));
5062 
5063   WHILE(v_tExprParentId(nChild) = v_tExprId(j))LOOP
5064 
5065     v_result.DELETE;
5066     v_record.DELETE;
5067     v_iterin.DELETE;
5068 
5069     nCount := v_return.COUNT + 1;
5070 
5071     IF(v_tExprType(nChild) = EXPR_PSNODE)THEN
5072       IF(v_ChildrenIndex.EXISTS(v_tExprId(nChild)))THEN
5073         IF(HAS_OPTIONS_APPLIED(nChild))THEN
5074 
5075           IF(v_NumberOfChildren(v_tExprId(j)) = 1)THEN
5076 
5077             temp_table_hash_key(forallLevel) := TO_CHAR(v_tExprPsNodeId(nChild)) || '-' || TO_CHAR(v_tExplNodeId(nChild));
5078             temp_cmpt_hash_key(compatLevel) := temp_table_hash_key(forallLevel);
5079           END IF;
5080 
5081           v_result := EXPAND_NODE(nChild);
5082 
5083           FOR i IN 1..v_result.COUNT LOOP
5084 
5085             --Bug #4681261 - with re-using of temporary tables, we cannot use stored generated names
5086             --anymore because these names depend not only on ps_node_id, model_ref_expl_id but also
5087             --on where the rule is assined. Name will be generated in generate_argument.
5088             --nodeName := GENERATE_NAME_EXPL(v_ExplByPsNodeId(v_result(i)), v_result(i));
5089 
5090             v_return(nCount).node_type := DATA_TYPE_NODE;
5091             v_return(nCount).node_value := NULL;
5092             v_return(nCount).node_id := v_result(i);
5093             v_return(nCount).node_obj := NULL;
5094             v_return(nCount).node_id_ex := v_ExplByPsNodeId(v_result(i));
5095 
5096             nCount := nCount + 1;
5097           END LOOP;
5098         ELSE
5099 
5100           v_record := GENERATE_REFNODE(nChild, ListType);
5101 
5102           FOR i IN 1..v_record.COUNT LOOP
5103 
5104             v_return(nCount).node_type := ListType;
5105             v_return(nCount).node_value := v_record(i);
5106             v_return(nCount).node_id := NULL;
5107             v_return(nCount).node_obj := v_record(i);
5108 
5109             nCount := nCount + 1;
5110           END LOOP;
5111         END IF;
5112       ELSE
5113 
5114         --Bug #4681261 - with re-using of temporary tables, we cannot use stored generated names
5115         --anymore because these names depend not only on ps_node_id, model_ref_expl_id but also
5116         --on where the rule is assined. Name will be generated in generate_argument.
5117         --nodeName := GENERATE_NAME(nChild, v_tExprPsNodeId(nChild));
5118 
5119         v_return(nCount).node_type := DATA_TYPE_NODE;
5120         v_return(nCount).node_value := NULL;
5121         v_return(nCount).node_id := v_tExprPsNodeId(nChild);
5122         v_return(nCount).node_obj := NULL;
5123         v_return(nCount).node_id_ex := v_tExplNodeId(nChild);
5124       END IF;
5125     ELSIF(v_tExprType(nChild) = EXPR_LITERAL)THEN
5126 
5127       v_return(nCount).node_type := v_tExprDataType(nChild);
5128       v_return(nCount).node_value := v_tExprDataValue(nChild);
5129       v_return(nCount).node_id := NULL;
5130       v_return(nCount).node_obj := NULL;
5131 
5132     ELSIF(v_tExprType(nChild) = EXPR_OPERATOR AND v_tExprSubtype(nChild) IN (OPERATOR_OPTIONSOF, OPERATOR_BOMOPTIONSOF))THEN
5133 
5134       nGrand := v_ChildrenIndex(v_tExprId(nChild));
5135 
5136       IF(v_NumberOfChildren(v_tExprId(j)) = 1)THEN
5137 
5138         temp_table_hash_key(forallLevel) := TO_CHAR(v_tExprPsNodeId(nGrand)) || '-' || TO_CHAR(v_tExplNodeId(nGrand));
5139         temp_cmpt_hash_key(compatLevel) := temp_table_hash_key(forallLevel);
5140       END IF;
5141 
5142       v_result := EXPAND_NODE(nChild);
5143 
5144       FOR i IN 1..v_result.COUNT LOOP
5145 
5146         --Bug #4681261 - with re-using of temporary tables, we cannot use stored generated names
5147         --anymore because these names depend not only on ps_node_id, model_ref_expl_id but also
5148         --on where the rule is assined. Name will be generated in generate_argument.
5149         --nodeName := GENERATE_NAME_EXPL(v_ExplByPsNodeId(v_result(i)), v_result(i));
5150 
5151         v_return(nCount).node_type := DATA_TYPE_NODE;
5152         v_return(nCount).node_value := NULL;
5153         v_return(nCount).node_id := v_result(i);
5154         v_return(nCount).node_obj := NULL;
5155         v_return(nCount).node_id_ex := v_ExplByPsNodeId(v_result(i));
5156 
5157         nCount := nCount + 1;
5158       END LOOP;
5159 
5160     ELSIF(v_tExprType(nChild) IN (EXPR_FORALL, EXPR_FORALL_DISTINCT))THEN
5161 
5162       v_iterin := GENERATE_FORALL(nChild, ListType);
5163 
5164       FOR i IN 1..v_iterin.COUNT LOOP
5165 
5166         v_return(nCount) := v_iterin(i);
5167         nCount := nCount + 1;
5168       END LOOP;
5169     ELSE
5170 
5171       v_record := GENERATE_EXPRESSION(nChild, ListType);
5172 
5173       IF(v_tExprPsNodeId(nChild) IS NOT NULL)THEN
5174 
5175          nType := v_tExprType(nChild);
5176          v_tExprType(nChild) := EXPR_PSNODE;
5177 
5178          v_iterin := GENERATE_ITERATOR(j, ListType);
5179          v_tExprType(nChild) := nType;
5180 
5181          FOR i IN 1..v_iterin.COUNT LOOP
5182 
5183            v_return(nCount) := v_iterin(i);
5184            nCount := nCount + 1;
5185          END LOOP;
5186 
5187       ELSE
5188 
5189          FOR i IN 1..v_record.COUNT LOOP
5190 
5191            v_return(nCount).node_type := DATA_TYPE_VARIANT;
5192            v_return(nCount).node_value := v_record(i);
5193 
5194            --If it's a 'P_' object, the node_id should still be populated, otherwise it will be impossible
5195            --to use properties of this objects.
5196 
5197            v_return(nCount).node_id := NULL;
5198            v_return(nCount).node_obj := v_record(i);
5199 
5200            nCount := nCount + 1;
5201          END LOOP;
5202       END IF;
5203     END IF;
5204 
5205     nChild := nChild + 1;
5206   END LOOP;
5207 
5208 nDebug := 7004009;
5209 
5210   RETURN v_return;
5211 END;
5212 ---------------------------------------------------------------------------------------
5213 FUNCTION EXTRACT_PROPERTY_INFO(j IN PLS_INTEGER, PropName OUT NOCOPY VARCHAR2,
5214                                DataType OUT NOCOPY PLS_INTEGER,
5215                                PropertyType OUT NOCOPY PLS_INTEGER)
5216 RETURN PLS_INTEGER IS
5217   propChild   PLS_INTEGER := v_ChildrenIndex(v_tExprId(j));
5218   propertyId  PLS_INTEGER;
5219   tempVal NUMBER := -1;
5220 BEGIN
5221 
5222 nDebug := 7004040;
5223 
5224   PropertyType := 0;
5225 
5226   WHILE(v_tExprParentId(propChild) = v_tExprId(j) AND
5227         v_tExprPropertyId(propChild) IS NULL AND v_tExprType(propChild) NOT IN
5228         (EXPR_NODE_TYPE_SYSPROP, EXPR_LITERAL))LOOP
5229        propChild := propChild + 1;
5230   END LOOP;
5231 
5232 nDebug := 7004042;
5233 
5234   IF(v_tExprParentId(propChild) = v_tExprId(j))THEN
5235     BEGIN
5236       IF(v_tExprPropertyId(propChild) IS NOT NULL)THEN
5237 
5238         SELECT data_type, name INTO DataType, PropName
5239           FROM cz_properties
5240            WHERE deleted_flag = FLAG_NOT_DELETED
5241              AND property_id = v_tExprPropertyId(propChild);
5242 nDebug := 7004043;
5243 
5244         RETURN v_tExprPropertyId(propChild);
5245 
5246       ELSIF(v_tExprType(propChild) = EXPR_LITERAL)THEN
5247 
5248         SELECT property_id, data_type, name INTO propertyId, DataType, PropName
5249           FROM cz_properties
5250          WHERE deleted_flag = FLAG_NOT_DELETED
5251            AND name = v_tExprDataValue(propChild);
5252 
5253         RETURN propertyId;
5254       ELSE
5255 
5256         PropertyType := 1;
5257         WHILE(v_tExprParentId(propChild) = v_tExprId(j) AND
5258               h_SeededName(v_tExprSubtype(propChild)) = RULE_SYS_PROP_PARENT)LOOP
5259 
5260           propChild := propChild + 1;
5261           PropertyType := PropertyType + 1;
5262         END LOOP;
5263         IF(v_tExprParentId(propChild) = v_tExprId(j))THEN
5264 
5265           SELECT data_type, name INTO DataType, PropName
5266             FROM cz_system_properties_v
5267            WHERE rule_id = v_tExprSubtype(propChild);
5268 
5269           RETURN v_tExprSubtype(propChild);
5270         ELSE
5271           RAISE CZ_E_INCORRECT_PROPERTY;
5272         END IF;
5273       END IF;
5274     EXCEPTION
5275       WHEN OTHERS THEN
5276         RAISE CZ_E_INCORRECT_PROPERTY;
5277     END;
5278   ELSE
5279     RAISE CZ_E_INCORRECT_PROPERTY;
5280   END IF;
5281 nDebug := 7004049;
5282 END;
5283 ---------------------------------------------------------------------------------------
5284 FUNCTION GENERATE_FORALL_(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tIteratorArray IS
5285 
5286   iteratorIndex    tIntegerArray;
5287   iterator         tIteratorArray;
5288   whereIndex       PLS_INTEGER := 0;
5289   expressionIndex  PLS_INTEGER := 0;
5290   nChild           PLS_INTEGER;
5291   nCount           PLS_INTEGER;
5292   v_property_id    tIntegerArray;
5293   v_data_type      tIntegerArray;
5294   v_prop_name      tStringArray;
5295   v_return         tIteratorArray;
5296   v_express        tStringArray;
5297   SQLCreate        VARCHAR2(8000);
5298   SQLInsert        VARCHAR2(8000);
5299   SQLValues        VARCHAR2(8000);
5300   SQLSelect        VARCHAR2(8000);
5301   SQLFrom          VARCHAR2(8000);
5302   SQLWhere         VARCHAR2(8000) := NULL;
5303   tableName        VARCHAR2(4000);
5304   tableAlias       VARCHAR2(4000);
5305   nodeId           NUMBER; --jonatara:bug7041718
5306   itemId           PLS_INTEGER;
5307   propertyId       PLS_INTEGER;
5308   c_values         refCursor;
5309   v_cursor         NUMBER;
5310   propertyVal      VARCHAR2(4000);
5311   localNumber      NUMBER;
5312   localString      VARCHAR2(4000);
5313   bindValue        tStringArray;
5314   v_flag           tIntegerArray;
5315   v_stack_start    PLS_INTEGER;
5316   v_stack_end      PLS_INTEGER;
5317   v_value_exists   PLS_INTEGER := 0;
5318 
5319   bind_node_id     DBMS_SQL.NUMBER_TABLE;
5320   bind_node_id_ex  DBMS_SQL.NUMBER_TABLE;
5321   bind_node_type   DBMS_SQL.NUMBER_TABLE;
5322   bind_node_value  DBMS_SQL.VARCHAR2_TABLE;
5323   bind_node_obj    DBMS_SQL.VARCHAR2_TABLE;
5324 
5325   TYPE bind_value_table IS TABLE OF DBMS_SQL.VARCHAR2_TABLE INDEX BY BINARY_INTEGER;
5326   bind_values      bind_value_table;
5327   arg_table_name   temp_table_hash_type;
5328   hash_propval_key VARCHAR2(4000);
5329 ---------------------------------------------------------------------------------------
5330 PROCEDURE EXPLORE_WHERE(j IN PLS_INTEGER, v_argument IN VARCHAR2) IS
5331   nChild      PLS_INTEGER;
5332   nCount      PLS_INTEGER;
5333   propertyId  PLS_INTEGER;
5334   dataType    PLS_INTEGER;
5335   propType    PLS_INTEGER;
5336   propName    cz_properties.name%TYPE;
5337 BEGIN
5338 
5339 nDebug := 7004020;
5340 
5341   nChild := v_ChildrenIndex(v_tExprId(j));
5342 
5343   WHILE(v_tExprParentId(nChild) = v_tExprId(j))LOOP
5344 
5345     nCount := v_property_id.COUNT + 1;
5346 
5347     IF(v_ChildrenIndex.EXISTS(v_tExprId(nChild)))THEN
5348       IF(v_tExprType(nChild) = EXPR_ARGUMENT AND v_tExprArgumentName(nChild) = v_argument)THEN
5349 
5350         propertyId := EXTRACT_PROPERTY_INFO(nChild, propName, dataType, propType);
5351 
5352         nDebug := 7004021;
5353 
5354         IF(NOT v_flag.EXISTS(propertyId))THEN
5355 
5356           v_property_id(nCount) := propertyId;
5357           v_data_type(nCount) := dataType;
5358           v_prop_name(nCount) := propName;
5359           v_flag(propertyId) := propType;
5360         END IF;
5361       ELSE
5362 
5363         EXPLORE_WHERE(nChild, v_argument);
5364       END IF;
5365     END IF;
5366     nChild := nChild + 1;
5367   END LOOP;
5368 
5369 nDebug := 7004029;
5370 END;
5371 ---------------------------------------------------------------------------------------
5372 --This function finds every reference to iterators in the FORALL WHERE clause, replaces
5373 --arguments with <table_alias>.value string and reference nodes with <table_alias>.i_<property_id>
5374 --string. It returns the generated SQL WHERE clause of the SELECT statement. All the literal
5375 --values are collected in an array for later binding.
5376 
5377 FUNCTION EXAMINE_WHERE_CLAUSE(j IN PLS_INTEGER) RETURN VARCHAR2 IS
5378   argChild         PLS_INTEGER;
5379   propType         PLS_INTEGER;
5380   jChild           PLS_INTEGER;
5381   isLocal          PLS_INTEGER := 0;
5382   LocalType        PLS_INTEGER := DATA_TYPE_VOID;
5383   propName         cz_properties.name%TYPE;
5384   v_extern         tStringArray;
5385   v_quotes         VARCHAR2(2);
5386 BEGIN
5387 
5388 nDebug := 7004030;
5389 
5390   IF(v_tExprType(j) = EXPR_ARGUMENT)THEN
5391 
5392     --This is an argument. First of all, find out if it corresponds to one of the local iterators - only
5393     --in this case there will be a temporary table with the corresponding name. Otherwise, it can be an
5394     --external argument from an upper level FORALL. In this case we have to get the value from the
5395     --parameter scope and use it as a literal in the generated WHERE clause.
5396 
5397     FOR i IN 1..iteratorIndex.COUNT LOOP
5398 
5399       IF(v_tExprArgumentName(iteratorIndex(i)) = v_tExprArgumentName(j))THEN isLocal := 1; END IF;
5400     END LOOP;
5401 
5402     IF(isLocal = 1)THEN
5403 
5404       --This is an argument that corresponds to a local iterator.
5405 
5406       IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
5407 
5408         --Add <table_name>.value to the WHERE clause being generated.
5409 
5410         RETURN arg_table_name(v_tExprArgumentName(j)) || '.node_value';
5411       ELSE
5412 
5413         --Add <table_name>.i_<property_id> to the WHERE clause being generated.
5414         RETURN arg_table_name(v_tExprArgumentName(j)) || '.i_' ||
5415                TO_CHAR(EXTRACT_PROPERTY_INFO(j, propName, jChild, propType));
5416       END IF;
5417     ELSE
5418 
5419       --This is an external argument, must be in the parameter scope.
5420       --We assume that it is of type 'node'.
5421 
5422       v_extern := GENERATE_ARGUMENT(j, LocalType);
5423       IF(LocalType = DATA_TYPE_TEXT)THEN v_quotes := ''''; END IF;
5424 
5425       IF(v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
5426 
5427         RETURN v_quotes || PROPERTY_VALUE(v_ChildrenIndex(v_tExprId(j)), glIndexByPsNodeId(v_tExprPsNodeId(j)), LocalType) || v_quotes;
5428       ELSE
5429 
5430         RETURN v_quotes || v_extern(1) || v_quotes;
5431       END IF;
5432     END IF;
5433   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_NODE AND v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
5434 
5435     --Nodes can participate in the WHERE clause only with a property applied.
5436     --Bug #4648386.
5437 
5438     v_extern(1) := EXTRACT_PROPERTY_INFO(j, propName, jChild, propType);
5439     nDebug := 7004032;
5440     IF(jChild IN (DATATYPE_TRANSLATABLE_PROP, DATA_TYPE_TEXT))THEN v_quotes := ''''; END IF;
5441 
5442     IF(propType = 0)THEN
5443 
5444       RETURN v_quotes || PROPERTY_VALUE(v_ChildrenIndex(v_tExprId(j)), glIndexByPsNodeId(v_tExprPsNodeId(j)), LocalType) || v_quotes;
5445     ELSE
5446 
5447       RETURN v_quotes || STATIC_SYSPROP_VALUE(v_tExprPsNodeId(j), v_tExprPropertyId(j), propType) || v_quotes;
5448     END IF;
5449   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_LITERAL)THEN
5450 
5451     bindValue(bindValue.COUNT + 1) := v_tExprDataValue(j);
5452     RETURN ':x' || TO_CHAR(bindValue.COUNT);
5453 
5454   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_OPERATOR)THEN
5455 
5456     jChild := v_ChildrenIndex(v_tExprId(j));
5457 
5458     IF(v_tExprSubtype(j) = OPERATOR_TOTEXT)THEN
5459 
5460         --Added for the bug #5620750. Just need ignore the ToText operator to continue using
5461         --default type conversion.
5462 
5463         RETURN EXAMINE_WHERE_CLAUSE(jChild);
5464     END IF;
5465 
5466     IF(v_tExprParentId.EXISTS(jChild + 1) AND v_tExprParentId(jChild + 1)= v_tExprId(j))THEN
5467 
5468       IF(v_tExprSubtype(j) IN (OPERATOR_EQUALS,
5469                                OPERATOR_NOTEQUALS,
5470                                OPERATOR_EQUALS_INT,
5471                                OPERATOR_NOTEQUALS_INT,
5472                                OPERATOR_GT,
5473                                OPERATOR_LT,
5474                                OPERATOR_GE,
5475                                OPERATOR_LE,
5476                                OPERATOR_AND,
5477                                OPERATOR_OR))THEN
5478 
5479         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || OperatorLiterals(v_tExprSubtype(j)) ||
5480                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5481 
5482       ELSIF(v_tExprSubtype(j) = OPERATOR_CONCAT)THEN
5483 
5484         RETURN EXAMINE_WHERE_CLAUSE(jChild) || ' || ' || EXAMINE_WHERE_CLAUSE(jChild + 1);
5485 
5486       ELSIF(v_tExprSubtype(j) = OPERATOR_BEGINSWITH)THEN
5487 
5488         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
5489                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
5490 
5491       ELSIF(v_tExprSubtype(j) = OPERATOR_ENDSWITH)THEN
5492 
5493         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ''%'' || ' ||
5494                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5495 
5496       ELSIF(v_tExprSubtype(j) = OPERATOR_CONTAINS)THEN
5497 
5498         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ''%'' || ' ||
5499                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
5500 
5501       ELSIF(v_tExprSubtype(j) = OPERATOR_LIKE)THEN
5502 
5503         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
5504                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5505 
5506       ELSIF(v_tExprSubtype(j) = OPERATOR_MATCHES)THEN
5507 
5508         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
5509                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5510 
5511       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTBEGINWITH)THEN
5512 
5513         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ' ||
5514                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
5515 
5516       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTENDWITH)THEN
5517 
5518         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ''%'' || ' ||
5519                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5520 
5521       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTCONTAIN)THEN
5522 
5523         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ''%'' || ' ||
5524                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
5525 
5526       ELSIF(v_tExprSubtype(j) = OPERATOR_NOTLIKE)THEN
5527 
5528         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ' ||
5529                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5530 
5531       ELSE
5532 
5533         RAISE CZ_E_UKNOWN_OPER_IN_COMPAT;
5534       END IF;
5535 
5536     ELSIF(v_tExprSubtype(j) = OPERATOR_NOT)THEN
5537 
5538       RETURN '(NOT ' || EXAMINE_WHERE_CLAUSE(jChild) || ')';
5539 
5540     ELSE
5541 
5542       RAISE CZ_E_WRONG_OPER_IN_COMPAT;
5543     END IF;
5544   ELSE
5545 
5546     RAISE CZ_R_WRONG_COMPAT_EXPRESSION;
5547   END IF;
5548 END;
5549 ---------------------------------------------------------------------------------------
5550 BEGIN
5551 
5552 nDebug := 7004100;
5553 
5554   nChild := v_ChildrenIndex(v_tExprId(j));
5555 
5556   WHILE(v_tExprParentId(nChild) = v_tExprId(j)) LOOP
5557     IF(v_tExprType(nChild) = EXPR_ITERATOR)THEN
5558 
5559       iteratorIndex(iteratorIndex.COUNT + 1) := nChild;
5560     ELSIF(v_tExprType(nChild) = EXPR_WHERE)THEN
5561 
5562       whereIndex := nChild;
5563     ELSE
5564 
5565       expressionIndex := nChild;
5566     END IF;
5567 
5568     nChild := nChild + 1;
5569   END LOOP;
5570 
5571   v_stack_start := parameterScope.COUNT + 1;
5572   v_stack_end := v_stack_start + iteratorIndex.COUNT - 1;
5573 
5574 nDebug := 7004101;
5575 
5576   FOR i IN 1..iteratorIndex.COUNT LOOP
5577 
5578     bind_node_id.DELETE;
5579     bind_node_id_ex.DELETE;
5580     bind_node_type.DELETE;
5581     bind_node_value.DELETE;
5582     bind_node_obj.DELETE;
5583     bind_values.DELETE;
5584 
5585     v_property_id.DELETE;
5586     v_data_type.DELETE;
5587     v_prop_name.DELETE;
5588     v_flag.DELETE;
5589 
5590     temp_table_hash_key(forallLevel) := NULL;
5591     tableAlias := 'T' || TO_CHAR(i);
5592 
5593     iterator.DELETE;
5594     iterator := GENERATE_ITERATOR(iteratorIndex(i), ListType);
5595 
5596     IF(whereIndex <> 0)THEN
5597       EXPLORE_WHERE(whereIndex, v_tExprArgumentName(iteratorIndex(i)));
5598     END IF;
5599 
5600     IF(temp_table_hash_key(forallLevel) IS NOT NULL)THEN
5601       FOR ii IN 1..v_property_id.COUNT LOOP
5602         temp_table_hash_key(forallLevel) := temp_table_hash_key(forallLevel) || '-' || TO_CHAR(v_property_id(ii));
5603       END LOOP;
5604     END IF;
5605 
5606 nDebug := 7004102;
5607 
5608     IF(temp_table_hash_key(forallLevel) IS NOT NULL AND temp_table_hash.EXISTS(temp_table_hash_key(forallLevel)))THEN
5609 
5610       tableName := temp_table_hash(temp_table_hash_key(forallLevel));
5611       arg_table_name(v_tExprArgumentName(iteratorIndex(i))) := tableAlias;
5612 
5613       IF(SQLSelect IS NULL)THEN SQLSelect := 'SELECT '; ELSE SQLSelect := SQLSelect || ', '; END IF;
5614       SQLSelect := SQLSelect || tableAlias || '.node_type, ' ||
5615                                 tableAlias || '.node_id, ' ||
5616                                 tableAlias || '.node_value, ' ||
5617                                 tableAlias || '.node_obj, ' ||
5618                                 tableAlias || '.node_id_ex';
5619       IF(SQLFrom IS NULL)THEN SQLFrom := ' FROM '; ELSE SQLFrom := SQLFrom || ', '; END IF;
5620       SQLFrom := SQLFrom || tableName || ' ' || tableAlias;
5621 
5622     ELSE
5623 
5624 --tableName := 'G_' || TO_CHAR(table_name_generator);
5625 -- SMANNA : Bug11822849 : Want to make these global temp table name unique between the sessions.
5626     tableName := 'G_' ||TO_CHAR(thisRunId)||'_'|| TO_CHAR(table_name_generator);
5627     table_name_generator := table_name_generator + 1;
5628     arg_table_name(v_tExprArgumentName(iteratorIndex(i))) := tableAlias;
5629 
5630     IF(SQLSelect IS NULL)THEN SQLSelect := 'SELECT '; ELSE SQLSelect := SQLSelect || ', '; END IF;
5631     SQLSelect := SQLSelect || tableAlias || '.node_type, ' ||
5632                               tableAlias || '.node_id, ' ||
5633                               tableAlias || '.node_value, ' ||
5634                               tableAlias || '.node_obj, ' ||
5635                               tableAlias || '.node_id_ex';
5636     IF(SQLFrom IS NULL)THEN SQLFrom := ' FROM '; ELSE SQLFrom := SQLFrom || ', '; END IF;
5637     SQLFrom := SQLFrom || tableName || ' ' || tableAlias;
5638 
5639     SQLCreate := 'CREATE GLOBAL TEMPORARY TABLE ' || tableName ||
5640                  '(node_type NUMBER, node_id NUMBER, node_value VARCHAR2(' || TO_CHAR(MAXIMUM_INDEX_LENGTH) ||
5641                  '), node_obj VARCHAR2(' || TO_CHAR(MAXIMUM_INDEX_LENGTH) || '), node_id_ex NUMBER';
5642 
5643     FOR ii IN 1..v_property_id.COUNT LOOP
5644 
5645       SQLCreate := SQLCreate || ', i_' || TO_CHAR(v_property_id(ii));
5646 
5647       IF(v_data_type(ii) IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL))THEN
5648 
5649         SQLCreate := SQLCreate || ' NUMBER';
5650       ELSE
5651 
5652         SQLCreate := SQLCreate || ' VARCHAR2(' || TO_CHAR(MAXIMUM_INDEX_LENGTH) || ')';
5653       END IF;
5654     END LOOP;
5655 
5656     SQLCreate := SQLCreate || ') ON COMMIT PRESERVE ROWS';
5657 
5658 nDebug := 7004103;
5659 
5660     BEGIN
5661       EXECUTE IMMEDIATE SQLCreate;
5662     EXCEPTION
5663       WHEN OTHERS THEN
5664 
5665         --If the table already exists, truncate it, drop and try to create again.
5666 
5667         IF(SQLCODE = ORACLE_OBJECT_ALREADY_EXISTS)THEN
5668           EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || tableName;
5669           EXECUTE IMMEDIATE 'DROP TABLE ' || tableName;
5670           EXECUTE IMMEDIATE SQLCreate;
5671         ELSE
5672           RAISE;
5673         END IF;
5674     END;
5675 
5676     --The table is created, add its name to the delete list.
5677 
5678     temp_tables(temp_tables.COUNT + 1) := tableName;
5679 
5680 nDebug := 7004104;
5681 
5682     SQLInsert := 'INSERT INTO ' || tableName || '(node_type, node_id, node_value, node_obj, node_id_ex';
5683     SQLValues := ' VALUES (:y1, :y2, :y3, :y4, :y5';
5684 
5685     FOR ii IN 1..v_property_id.COUNT LOOP
5686 
5687       BEGIN
5688 
5689         EXECUTE IMMEDIATE 'CREATE INDEX ' || tableName || '_I' || TO_CHAR(ii) || ' ON ' || tableName ||
5690                           '(i_' || v_property_id(ii) || ')';
5691       EXCEPTION
5692         WHEN OTHERS THEN
5693           IF(SQLCODE <> ORACLE_OBJECT_ALREADY_EXISTS)THEN RAISE; END IF;
5694       END;
5695 
5696       SQLInsert := SQLInsert || ', i_' || TO_CHAR(v_property_id(ii));
5697       SQLValues := SQLValues || ', :x' || TO_CHAR(ii);
5698     END LOOP;
5699 
5700     SQLInsert := SQLInsert || ')';
5701     SQLValues := SQLValues || ')';
5702 
5703 nDebug := 7004105;
5704 
5705     FOR ii IN 1..iterator.COUNT LOOP
5706 
5707       IF(LENGTH(iterator(ii).node_value) > MAXIMUM_INDEX_LENGTH OR
5708          LENGTH(iterator(ii).node_obj) > MAXIMUM_INDEX_LENGTH)THEN
5709 
5710         --Bug #3416994. This structure is internally generated, so we give the 'internal error' message.
5711         RAISE CZ_R_TYPE_NO_PROPERTY;
5712       END IF;
5713 
5714       bind_node_id(ii) := iterator(ii).node_id;
5715       bind_node_id_ex(ii) := iterator(ii).node_id_ex;
5716       bind_node_value(ii) := iterator(ii).node_value;
5717       bind_node_obj(ii) := iterator(ii).node_obj;
5718       bind_node_type(ii) := iterator(ii).node_type;
5719 
5720       IF(v_property_id.COUNT > 0)THEN
5721 
5722         --This is only valid if there are properties.
5723 
5724         IF(iterator(ii).node_id IS NULL)THEN RAISE CZ_R_TYPE_NO_PROPERTY; END IF;
5725 
5726         nodeId := glPsNodeId(glIndexByPsNodeId(iterator(ii).node_id));
5727         itemId := glItemId(glIndexByPsNodeId(iterator(ii).node_id));
5728       END IF;
5729 
5730       --Get the property values and insert the data.
5731 
5732       FOR jj IN 1..v_property_id.COUNT LOOP
5733 
5734         propertyId := v_property_id(jj);
5735         hash_propval_key := TO_CHAR(nodeId) || '-' || TO_CHAR(itemId) || '-' ||
5736                             TO_CHAR(propertyId) || '-' || TO_CHAR(v_flag(propertyId));
5737 
5738         IF(NOT table_hash_propval.EXISTS(hash_propval_key))THEN
5739 
5740           IF(v_flag(propertyId) = 0)THEN
5741 
5742             --User property.
5743 
5744             propertyVal := GET_PROPERTY_VALUE(nodeId, propertyId, itemId, localNumber);
5745 
5746             --Bug #4554100.
5747 
5748             IF(localNumber IS NULL)THEN
5749 
5750                errorMessage := v_prop_name(jj);
5751                auxIndex := glIndexByPsNodeId(iterator(ii).node_id);
5752                IF(glParentId(auxIndex) IS NULL)THEN nParam := auxIndex; ELSE
5753                nParam := glIndexByPsNodeId(glParentId(auxIndex)); END IF;
5754                RAISE CZ_R_OPTION_NO_PROPERTY;
5755             END IF;
5756           ELSE
5757 
5758             --System property.
5759 
5760             propertyVal := STATIC_SYSPROP_VALUE(nodeId, propertyId, v_flag(v_property_id(jj)));
5761           END IF;
5762 
5763           IF(LENGTH(propertyVal) > MAXIMUM_INDEX_LENGTH)THEN
5764 
5765             --Bug #3416994.
5766 
5767             errorMessage := v_prop_name(jj);
5768             auxIndex := glIndexByPsNodeId(iterator(ii).node_id);
5769             IF(glParentId(auxIndex) IS NULL)THEN nParam := auxIndex; ELSE
5770             nParam := glIndexByPsNodeId(glParentId(auxIndex)); END IF;
5771             RAISE CZ_R_LONG_PROPERTY_VALUE;
5772           END IF;
5773 
5774           bind_values(jj)(ii) := propertyVal;
5775           table_hash_propval(hash_propval_key) := propertyVal;
5776         ELSE
5777           bind_values(jj)(ii) := table_hash_propval(hash_propval_key);
5778         END IF;
5779       END LOOP;
5780     END LOOP;
5781 
5782 nDebug := 7004106;
5783 
5784     v_cursor := DBMS_SQL.OPEN_CURSOR;
5785     DBMS_SQL.PARSE(v_cursor, SQLInsert || SQLValues, DBMS_SQL.NATIVE);
5786 
5787     DBMS_SQL.BIND_ARRAY(v_cursor, ':y1', bind_node_type);
5788     DBMS_SQL.BIND_ARRAY(v_cursor, ':y2', bind_node_id);
5789     DBMS_SQL.BIND_ARRAY(v_cursor, ':y3', bind_node_value);
5790     DBMS_SQL.BIND_ARRAY(v_cursor, ':y4', bind_node_obj);
5791     DBMS_SQL.BIND_ARRAY(v_cursor, ':y5', bind_node_id_ex);
5792 
5793     FOR ii IN 1..v_property_id.COUNT LOOP
5794       DBMS_SQL.BIND_ARRAY(v_cursor, ':x' || TO_CHAR(ii), bind_values(ii));
5795     END LOOP;
5796 
5797     localNumber := DBMS_SQL.EXECUTE(v_cursor);
5798     DBMS_SQL.CLOSE_CURSOR(v_cursor);
5799 
5800 nDebug := 7004107;
5801 
5802     EXECUTE IMMEDIATE 'ANALYZE TABLE ' || tableName || ' COMPUTE STATISTICS';
5803 
5804     --The table is created and populated, add its name to the hash for re-use if it is eligible.
5805 
5806     IF(temp_table_hash_key(forallLevel) IS NOT NULL)THEN temp_table_hash(temp_table_hash_key(forallLevel)) := tableName; END IF;
5807     END IF;
5808   END LOOP;
5809 
5810   --Generate the WHERE clause and run the query with bind variables. For every row returned,
5811   --generate the expression and return the object.
5812   --To do this, add GENERATE_ARGUMENT to the GENERATE_EXPRESSION.
5813 
5814 nDebug := 7004108;
5815 
5816   IF(whereIndex <> 0)THEN
5817 
5818     SQLWhere := ' WHERE ' || EXAMINE_WHERE_CLAUSE(v_ChildrenIndex(v_tExprId(whereIndex)));
5819   END IF;
5820 
5821   v_cursor := DBMS_SQL.OPEN_CURSOR;
5822   DBMS_SQL.PARSE(v_cursor, SQLSelect || SQLFrom || SQLWhere, DBMS_SQL.NATIVE);
5823 
5824   FOR i IN 1..bindValue.COUNT LOOP
5825     DBMS_SQL.BIND_VARIABLE(v_cursor, ':x' || TO_CHAR(i), bindValue(i));
5826   END LOOP;
5827 
5828   FOR i IN 1..iteratorIndex.COUNT LOOP
5829 
5830     DBMS_SQL.DEFINE_COLUMN(v_cursor, 5 * (i - 1) + 1, localNumber);
5831     DBMS_SQL.DEFINE_COLUMN(v_cursor, 5 * (i - 1) + 2, localNumber);
5832     DBMS_SQL.DEFINE_COLUMN(v_cursor, 5 * (i - 1) + 3, localString, 2000);
5833     DBMS_SQL.DEFINE_COLUMN(v_cursor, 5 * (i - 1) + 4, localString, 2000);
5834     DBMS_SQL.DEFINE_COLUMN(v_cursor, 5 * (i - 1) + 5, localNumber);
5835   END LOOP;
5836 
5837 nDebug := 7004109;
5838 
5839   localNumber := DBMS_SQL.EXECUTE(v_cursor);
5840 
5841   --For every returned row, store the values in the parameter scope, from where GENERATE_EXPRESSION
5842   --will be retrieving it when generating an argument.
5843 
5844   FOR i IN 1..iteratorIndex.COUNT LOOP
5845 
5846     parameterName(v_stack_start + i - 1) := v_tExprArgumentName(iteratorIndex(i));
5847   END LOOP;
5848 
5849   WHILE(DBMS_SQL.FETCH_ROWS(v_cursor) > 0)LOOP
5850 
5851     FOR i IN 1..iteratorIndex.COUNT LOOP
5852 
5853       DBMS_SQL.COLUMN_VALUE(v_cursor, 5 * (i - 1) + 1, parameterScope(v_stack_start + i - 1).node_type);
5854       DBMS_SQL.COLUMN_VALUE(v_cursor, 5 * (i - 1) + 2, parameterScope(v_stack_start + i - 1).node_id);
5855       DBMS_SQL.COLUMN_VALUE(v_cursor, 5 * (i - 1) + 3, parameterScope(v_stack_start + i - 1).node_value);
5856       DBMS_SQL.COLUMN_VALUE(v_cursor, 5 * (i - 1) + 4, parameterScope(v_stack_start + i - 1).node_obj);
5857       DBMS_SQL.COLUMN_VALUE(v_cursor, 5 * (i - 1) + 5, parameterScope(v_stack_start + i - 1).node_id_ex);
5858     END LOOP;
5859 
5860     IF(expressionIndex <> 0 AND v_ChildrenIndex.EXISTS(v_tExprId(expressionIndex)))THEN
5861 
5862       --Bug #5497235. This is a FORALL with an expression, need to generate the expression.
5863 
5864       generateCollect := 1;
5865 
5866       v_express := GENERATE_EXPRESSION(expressionIndex, ListType);
5867       generateCollect := 0;
5868 
5869       nCount := v_return.COUNT + 1;
5870 
5871       FOR i IN 1..v_express.COUNT LOOP
5872 
5873         IF(v_tExprType(j) = EXPR_FORALL_DISTINCT)THEN
5874 
5875           --For COLLECT DISTINCT we need to leave only distinct values in the results.
5876 
5877           v_value_exists := 0;
5878 
5879           FOR ii IN 1..nCount - 1 LOOP
5880             IF(v_return(ii).node_value = v_express(i))THEN v_value_exists := 1; EXIT; END IF;
5881           END LOOP;
5882         END IF;
5883 
5884         IF(v_value_exists = 0)THEN
5885 
5886           v_return(nCount).node_obj := v_express(i);
5887           v_return(nCount).node_value := v_express(i);
5888           v_return(nCount).node_id := NULL;
5889           v_return(nCount).node_type := DATA_TYPE_VARIANT;
5890           nCount := nCount + 1;
5891         END IF;
5892       END LOOP;
5893 
5894     ELSE
5895 
5896       --Bug #5497235. This is a COLLECT because there is no expression or the expression is just an argument.
5897       --In this case we need a direct copy of the parameter scope.
5898 
5899       nCount := v_return.COUNT + 1;
5900 
5901       /* Changing this for loop from 1..parameterscope.count to the below as part of the fix for the bug : 6355526*/
5902 
5903       FOR i IN v_stack_start..v_stack_end LOOP
5904 
5905 
5906         v_return(nCount).node_id := parameterScope(i).node_id;
5907         v_return(nCount).node_type := parameterScope(i).node_type;
5908         v_return(nCount).node_value := parameterScope(i).node_value;
5909         v_return(nCount).node_obj := parameterScope(i).node_obj;
5910         v_return(nCount).node_id_ex := parameterScope(i).node_id_ex;
5911         nCount := nCount + 1;
5912       END LOOP;
5913     END IF;
5914   END LOOP;
5915 
5916   parameterScope.DELETE(v_stack_start, v_stack_end);
5917   parameterName.DELETE(v_stack_start, v_stack_end);
5918 
5919 nDebug := 7004110;
5920 
5921   DBMS_SQL.CLOSE_CURSOR(v_cursor);
5922 
5923   IF(v_tExprParentId(j) IS NOT NULL AND v_return.COUNT = 0)THEN
5924 
5925     --The FORALL or COLLECT did not yield any rows while it is not the root operator.
5926     --Need a new message to report this.
5927 
5928     RAISE CZ_R_COMPAT_NO_COMBINATIONS;
5929   END IF;
5930 
5931  RETURN v_return;
5932 END;
5933 ---------------------------------------------------------------------------------------
5934 --This function is introduced to support the level of embedding.
5935 
5936 FUNCTION GENERATE_FORALL(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tIteratorArray IS
5937   v_return  tIteratorArray;
5938 BEGIN
5939   forallLevel := forallLevel + 1;
5940   v_return := GENERATE_FORALL_(j, ListType);
5941   forallLevel := forallLevel - 1;
5942  RETURN v_return;
5943 EXCEPTION
5944   WHEN OTHERS THEN
5945     forallLevel := forallLevel - 1;
5946     RAISE;
5947 END;
5948 ---------------------------------------------------------------------------------------
5949 FUNCTION GENERATE_COMPATIBLE_(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
5950 
5951   iteratorIndex    tIntegerArray;
5952   iterator         tIteratorArray;
5953   whereIndex       PLS_INTEGER := 0;
5954   featureIndex     PLS_INTEGER;
5955   nChild           NUMBER; -- jonatara:bug7041718
5956   nCounter         NUMBER; -- jonatara:bug7041718
5957   v_property_id    tIntegerArray;
5958   v_data_type      tIntegerArray;
5959   v_prop_name      tStringArray;
5960   v_return         tStringArray;
5961   SQLCreate        VARCHAR2(8000);
5962   SQLInsert        VARCHAR2(8000);
5963   SQLValues        VARCHAR2(8000);
5964   SQLSelect        VARCHAR2(8000);
5965   SQLFrom          VARCHAR2(8000);
5966   SQLWhere         VARCHAR2(8000) := NULL;
5967   tableName        VARCHAR2(4000);
5968   tableAlias       VARCHAR2(4000);
5969   nodeId           NUMBER; -- jonatara:bug7041718
5970   itemId           PLS_INTEGER;
5971   propertyId       PLS_INTEGER;
5972   c_values         refCursor;
5973   v_cursor         NUMBER;
5974   propertyVal      VARCHAR2(4000);
5975   localNumber      NUMBER;
5976   localString      VARCHAR2(4000);
5977   bindValue        tStringArray;
5978   typeCheck        NUMBER;
5979   v_tOptionId      DBMS_SQL.NUMBER_TABLE;
5980   v_tFeatureId     tExplNodeId;
5981   v_BackIndex      tIntegerArray;
5982   v_tExplId        tExplNodeId;
5983   rowThreshold     PLS_INTEGER := 0;
5984   v_OptionExists   tIntegerArray_idx_vc2; --kdande; Bug 6881902; 11-Mar-2008
5985   v_OptionsChain   tIntegerArray;
5986   v_FeatureIndex   tIntegerArray;
5987   v_ItemIndex      tIntegerArray;
5988   chainIndex       PLS_INTEGER := 1;
5989   currentIndex     PLS_INTEGER;
5990   itemIndex        PLS_INTEGER;
5991   itemCount        PLS_INTEGER := 1;
5992   v_RowLines       tStringArray;
5993   v_ItemLines      tStringArray;
5994   ExcludesRequired PLS_INTEGER;
5995   v_flag           tIntegerArray;
5996 
5997   bind_node_id     DBMS_SQL.NUMBER_TABLE;
5998 
5999   TYPE bind_value_table IS TABLE OF DBMS_SQL.VARCHAR2_TABLE INDEX BY BINARY_INTEGER;
6000   bind_values      bind_value_table;
6001   arg_table_name   temp_table_hash_type;
6002 
6003   h_OptionExplId   table_of_tNumberArray_idx_vc2;-- jonatara:bug7041718
6004   hash_propval_key VARCHAR2(4000);
6005 ---------------------------------------------------------------------------------------
6006 PROCEDURE EXPLORE_WHERE(j IN PLS_INTEGER, v_argument IN VARCHAR2) IS
6007   nChild      PLS_INTEGER;
6008   nCount      PLS_INTEGER;
6009   propertyId  PLS_INTEGER;
6010   dataType    PLS_INTEGER;
6011   propType    PLS_INTEGER;
6012   propName    cz_properties.name%TYPE;
6013 BEGIN
6014 
6015 nDebug := 7005020;
6016 
6017   nChild := v_ChildrenIndex(v_tExprId(j));
6018 
6019   WHILE(v_tExprParentId(nChild) = v_tExprId(j))LOOP
6020 
6021     nCount := v_property_id.COUNT + 1;
6022 
6023     IF(v_ChildrenIndex.EXISTS(v_tExprId(nChild)))THEN
6024       IF(v_tExprType(nChild) = EXPR_ARGUMENT AND v_tExprArgumentName(nChild) = v_argument)THEN
6025 
6026         propertyId := EXTRACT_PROPERTY_INFO(nChild, propName, dataType, propType);
6027         nDebug := 7005021;
6028         IF(NOT v_flag.EXISTS(propertyId))THEN
6029 
6030           v_property_id(nCount) := propertyId;
6031           v_data_type(nCount) := dataType;
6032           v_prop_name(nCount) := propName;
6033           v_flag(propertyId) := propType;
6034         END IF;
6035       ELSE
6036 
6037         EXPLORE_WHERE(nChild, v_argument);
6038       END IF;
6039     END IF;
6040     nChild := nChild + 1;
6041   END LOOP;
6042 
6043 nDebug := 7005029;
6044 END;
6045 ---------------------------------------------------------------------------------------
6046 --This function finds every reference to iterators in the FORALL WHERE clause, replaces
6047 --arguments with 'G_<argument_name>.value' string and reference nodes with
6048 --'G_<argument_name>.i_<property_id>' string. It returns the generated SQL
6049 --WHERE clause of the SELECT statement.
6050 --All the literal values are collected in an array for later binding.
6051 
6052 FUNCTION EXAMINE_WHERE_CLAUSE(j IN PLS_INTEGER) RETURN VARCHAR2 IS
6053   argChild         PLS_INTEGER;
6054   propType         PLS_INTEGER;
6055   jChild           PLS_INTEGER;
6056   propName         cz_properties.name%TYPE;
6057   LocalType        PLS_INTEGER := DATA_TYPE_VOID;
6058   v_extern         tStringArray;
6059   v_quotes         VARCHAR2(2);
6060 BEGIN
6061 
6062 nDebug := 7005030;
6063 
6064   IF(v_tExprType(j) = EXPR_ARGUMENT)THEN
6065     IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
6066 
6067       --Add <table_name>.value to the WHERE clause being generated.
6068 
6069       RETURN arg_table_name(v_tExprArgumentName(j)) || '.node_value';
6070     ELSE
6071 
6072       --Add <table_name>.i_<property_id> to the WHERE clause being generated.
6073       RETURN arg_table_name(v_tExprArgumentName(j)) || '.i_' ||
6074              TO_CHAR(EXTRACT_PROPERTY_INFO(j, propName, jChild, propType));
6075     END IF;
6076   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_NODE AND v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
6077 
6078     --Nodes can participate in the WHERE clause only with a property applied.
6079     --Bug #4648386.
6080 
6081     v_extern(1) := EXTRACT_PROPERTY_INFO(j, propName, jChild, propType);
6082 
6083     nDebug := 7005032;
6084 
6085     IF(jChild IN (DATATYPE_TRANSLATABLE_PROP, DATA_TYPE_TEXT))THEN v_quotes := ''''; END IF;
6086 
6087     IF(propType = 0)THEN
6088 
6089       RETURN v_quotes || PROPERTY_VALUE(v_ChildrenIndex(v_tExprId(j)), glIndexByPsNodeId(v_tExprPsNodeId(j)), LocalType) || v_quotes;
6090     ELSE
6091 
6092       RETURN v_quotes || STATIC_SYSPROP_VALUE(v_tExprPsNodeId(j), v_tExprPropertyId(j), propType) || v_quotes;
6093     END IF;
6094   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_LITERAL)THEN
6095 
6096     bindValue(bindValue.COUNT + 1) := v_tExprDataValue(j);
6097     RETURN ':x' || TO_CHAR(bindValue.COUNT);
6098 
6099   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_OPERATOR)THEN
6100 
6101     jChild := v_ChildrenIndex(v_tExprId(j));
6102 
6103     IF(v_tExprSubtype(j) = OPERATOR_TOTEXT)THEN
6104 
6105         --Added for the bug #5620750. Just need to ignore the ToText operator to preserve the
6106         --default type conversion.
6107 
6108         RETURN EXAMINE_WHERE_CLAUSE(jChild);
6109     END IF;
6110 
6111     IF(v_tExprParentId.EXISTS(jChild + 1) AND v_tExprParentId(jChild + 1)= v_tExprId(j))THEN
6112 
6113       IF(v_tExprSubtype(j) IN (OPERATOR_EQUALS,
6114                                OPERATOR_NOTEQUALS,
6115                                OPERATOR_EQUALS_INT,
6116                                OPERATOR_NOTEQUALS_INT,
6117                                OPERATOR_GT,
6118                                OPERATOR_LT,
6119                                OPERATOR_GE,
6120                                OPERATOR_LE,
6121                                OPERATOR_AND,
6122                                OPERATOR_OR))THEN
6123 
6124         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || OperatorLiterals(v_tExprSubtype(j)) ||
6125                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6126 
6127       ELSIF(v_tExprSubtype(j) = OPERATOR_CONCAT)THEN
6128 
6129         RETURN EXAMINE_WHERE_CLAUSE(jChild) || ' || ' || EXAMINE_WHERE_CLAUSE(jChild + 1);
6130 
6131       ELSIF(v_tExprSubtype(j) = OPERATOR_BEGINSWITH)THEN
6132 
6133         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
6134                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
6135 
6136       ELSIF(v_tExprSubtype(j) = OPERATOR_ENDSWITH)THEN
6137 
6138         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ''%'' || ' ||
6139                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6140 
6141       ELSIF(v_tExprSubtype(j) = OPERATOR_CONTAINS)THEN
6142 
6143         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ''%'' || ' ||
6144                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
6145 
6146       ELSIF(v_tExprSubtype(j) = OPERATOR_LIKE)THEN
6147 
6148         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
6149                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6150 
6151       ELSIF(v_tExprSubtype(j) = OPERATOR_MATCHES)THEN
6152 
6153         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
6154                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6155 
6156       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTBEGINWITH)THEN
6157 
6158         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ' ||
6159                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
6160 
6161       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTENDWITH)THEN
6162 
6163         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ''%'' || ' ||
6164                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6165 
6166       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTCONTAIN)THEN
6167 
6168         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ''%'' || ' ||
6169                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
6170 
6171       ELSIF(v_tExprSubtype(j) = OPERATOR_NOTLIKE)THEN
6172 
6173         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ' ||
6174                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6175 
6176       ELSE
6177 
6178         RAISE CZ_E_UKNOWN_OPER_IN_COMPAT;
6179       END IF;
6180 
6181     ELSIF(v_tExprSubtype(j) = OPERATOR_NOT)THEN
6182 
6183       RETURN '(NOT ' || EXAMINE_WHERE_CLAUSE(jChild) || ')';
6184 
6185     ELSE
6186 
6187       RAISE CZ_E_WRONG_OPER_IN_COMPAT;
6188     END IF;
6189   ELSE
6190 
6191     RAISE CZ_R_WRONG_COMPAT_EXPRESSION;
6192   END IF;
6193 END;
6194 ---------------------------------------------------------------------------------------
6195 PROCEDURE GET_ITEM_INDEX(OptionId IN NUMBER, ColumnIndex IN PLS_INTEGER) IS  --kdande; Bug 6881902; 11-Mar-2008
6196 BEGIN
6197 
6198  IF(NOT v_OptionExists.EXISTS(OptionId))THEN
6199    v_OptionExists(OptionId) := chainIndex;
6200  ELSE
6201    currentIndex := v_OptionExists(OptionId);
6202    LOOP
6203 
6204     IF(v_FeatureIndex(currentIndex) = ColumnIndex)THEN
6205       itemIndex := v_ItemIndex(currentIndex);
6206       RETURN;
6207     END IF;
6208 
6209     EXIT WHEN v_OptionsChain(currentIndex) IS NULL;
6210     currentIndex := v_OptionsChain(currentIndex);
6211    END LOOP;
6212 
6213    v_OptionsChain(currentIndex) := chainIndex;
6214  END IF;
6215 
6216   --Bug #4546828. Use the hashed explosion id for each option.
6217 
6218   v_ItemLines(itemCount) := GENERATE_NAME_EXPL(h_OptionExplId(ColumnIndex)(OptionId), OptionId) || ' ' || TO_CHAR(ColumnIndex - 1);
6219 
6220   v_OptionsChain(chainIndex) := NULL;
6221   v_FeatureIndex(chainIndex) := ColumnIndex;
6222   v_ItemIndex(chainIndex) := itemCount;
6223   itemIndex := itemCount;
6224   itemCount := itemCount + 1;
6225   chainIndex := chainIndex + 1;
6226 END;
6227 ---------------------------------------------------------------------------------------
6228 PROCEDURE GENERATE_STANDARD_PBC IS
6229 BEGIN
6230   v_cursor := DBMS_SQL.OPEN_CURSOR;
6231   DBMS_SQL.PARSE(v_cursor, SQLSelect || SQLFrom || SQLWhere, DBMS_SQL.NATIVE);
6232 
6233   FOR i IN 1..bindValue.COUNT LOOP
6234     DBMS_SQL.BIND_VARIABLE(v_cursor, ':x' || TO_CHAR(i), bindValue(i));
6235   END LOOP;
6236 
6237 nDebug := 7005109;
6238 
6239   localNumber := DBMS_SQL.EXECUTE(v_cursor);
6240 
6241   LOOP
6242 
6243     FOR i IN 1..iteratorIndex.COUNT LOOP
6244       DBMS_SQL.DEFINE_ARRAY(v_cursor, i, v_tOptionId, DBMS_SQL_MAX_BUFFER_SIZE, 1);
6245     END LOOP;
6246 
6247     localNumber := DBMS_SQL.FETCH_ROWS(v_cursor);
6248 
6249     FOR i IN 1..v_tFeatureId.COUNT LOOP
6250 
6251       DBMS_SQL.COLUMN_VALUE(v_cursor, i, v_tOptionId);
6252 
6253       FOR n IN 1..localNumber LOOP
6254 
6255         GET_ITEM_INDEX(v_tOptionId(n), i);
6256 
6257         --Fix for the bug #2256166: changed n to rowThreshold + n in the EXISTS operator.
6258 
6259         IF(v_RowLines.EXISTS(rowThreshold + n))THEN
6260           v_RowLines(rowThreshold + n) := v_RowLines(rowThreshold + n) || ' ' || TO_CHAR(itemIndex - 1);
6261         ELSE
6262           v_RowLines(rowThreshold + n) := ' ' || TO_CHAR(itemIndex - 1);
6263         END IF;
6264       END LOOP;
6265     END LOOP;
6266     EXIT WHEN localNumber <> DBMS_SQL_MAX_BUFFER_SIZE;
6267     rowThreshold := rowThreshold + DBMS_SQL_MAX_BUFFER_SIZE;
6268   END LOOP;
6269 
6270 nDebug := 7005110;
6271 
6272   DBMS_SQL.CLOSE_CURSOR(v_cursor);
6273 
6274   --If there's no valid combinations, report the rule and ignore it.
6275 
6276   IF(v_RowLines.COUNT = 0)THEN
6277     RAISE CZ_R_COMPAT_NO_COMBINATIONS;
6278   END IF;
6279 
6280   --Generate the combo structure
6281 
6282   vLogicLine := 'OBJECT P_R' || TO_CHAR(nRuleId) || '_' || TO_CHAR(v_tExprId(j)) || NewLine ||
6283                 'COMBO P_R' || TO_CHAR(nRuleId) || '_' || TO_CHAR(v_tExprId(j)) || ' ' ||
6284                 TO_CHAR(v_ItemLines.COUNT) || ' ' || TO_CHAR(v_RowLines.COUNT) || ' ' ||
6285                 TO_CHAR(v_tFeatureId.COUNT) || ' ... ' || TO_CHAR(nReasonId) || NewLine;
6286   PACK;
6287 
6288   FOR i IN 1..v_ItemLines.COUNT LOOP
6289 
6290     vLogicLine := 'CI ' || TO_CHAR(i - 1) || ' ' || v_ItemLines(i) || NewLine;
6291     PACK;
6292   END LOOP;
6293 
6294   FOR i IN 1..v_tFeatureId.COUNT LOOP
6295 
6296     IF(GenerateGatedCombo = 0)THEN
6297 
6298       --Use intermediate variable instead of using NVL because this is faster
6299 
6300       localNumber := glIndexByPsNodeId(v_tFeatureId(i));
6301       localString := TO_CHAR(glMaximum(localNumber));
6302 
6303       --If it's a BOM item, we use maximum_selected instead of maximum
6304 
6305       IF(glPsNodeType(localNumber) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
6306         localString := TO_CHAR(glMaximumSel(localNumber));
6307       END IF;
6308 
6309       IF(localString IS NULL)THEN localString := '-1'; END IF;
6310       vLogicLine := ' O';
6311     ELSE
6312 
6313       --Generate gated combinations: maximum is always -1, the 'G' argument is followed
6314       --by the feature name.
6315 
6316       localString := '-1';
6317       vLogicLine := ' G ' || GENERATE_NAME(v_BackIndex(i), v_tFeatureId(i));
6318     END IF;
6319 
6320     vLogicLine := 'CC ' || TO_CHAR(i - 1) || ' 0 ' || localString || vLogicLine || NewLine;
6321     PACK;
6322   END LOOP;
6323 
6324   FOR i IN 1..v_RowLines.COUNT LOOP
6325 
6326     vLogicLine := 'CR ' || TO_CHAR(i - 1) || v_RowLines(i) || NewLine;
6327     PACK;
6328   END LOOP;
6329 
6330   vLogicLine := 'COMBO_END' || NewLine;
6331   PACK;
6332 
6333   --Generate the exclude relations if necessary.
6334   --The code is re-written as part of the fix for the bug #4546828 to use the new hash table.
6335 
6336   FOR i IN 1..v_tFeatureId.COUNT LOOP
6337 
6338     --We will use this array in the local context now
6339 
6340     v_OptionExists.DELETE;
6341 
6342     FOR n IN 1..v_ItemLines.COUNT LOOP
6343 
6344      itemIndex := INSTR(v_ItemLines(n), ' ', -1) + 1;
6345 
6346      IF(TO_NUMBER(SUBSTR(v_ItemLines(n), itemIndex)) = i - 1)THEN
6347 
6348        currentIndex := INSTR(v_ItemLines(n), '_', -1) + 1;
6349        v_OptionExists(TO_NUMBER(SUBSTR(v_ItemLines(n), currentIndex, itemIndex - currentIndex - 1))) := 1;
6350      END IF;
6351     END LOOP;
6352 
6353     ExcludesRequired := 0;
6354     nChild := h_OptionExplId(i).FIRST;
6355     nCounter := nChild;
6356 
6357     WHILE(nChild IS NOT NULL) LOOP
6358       IF(NOT v_OptionExists.EXISTS(glPersistentId(nChild)))THEN
6359          ExcludesRequired := 1;
6360          EXIT;
6361       END IF;
6362       nChild := h_OptionExplId(i).NEXT(nChild);
6363     END LOOP;
6364 
6365     IF(ExcludesRequired = 1)THEN
6366 
6367      nChild := nCounter;
6368 
6369      vLogicLine := 'GS E ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N ';
6370      PACK;
6371 
6372      WHILE(nChild IS NOT NULL) LOOP
6373        IF(NOT v_OptionExists.EXISTS(glPersistentId(nChild)))THEN
6374          vLogicLine := GENERATE_NAME_EXPL(h_OptionExplId(i)(nChild), nChild) || ' ';
6375          PACK;
6376        END IF;
6377        nChild := h_OptionExplId(i).NEXT(nChild);
6378      END LOOP;
6379 
6380      vLogicLine := NewLine || 'GR L ';
6381      PACK;
6382 
6383      FOR n IN 1..v_tFeatureId.COUNT LOOP
6384        IF(n <> i)THEN
6385          vLogicLine := GENERATE_NAME(v_BackIndex(n), v_tFeatureId(n)) || ' ';
6386          PACK;
6387        END IF;
6388      END LOOP;
6389 
6390      vLogicLine := NewLine;
6391      PACK;
6392     END IF; --Excludes required
6393   END LOOP;
6394 END GENERATE_STANDARD_PBC;
6395 ---------------------------------------------------------------------------------------
6396 PROCEDURE GENERATE_OPTIMIZED_PBC IS
6397 
6398   TYPE tVarcharTable IS TABLE OF VARCHAR2(32000) INDEX BY VARCHAR2(32000);
6399 
6400   v_options              SYSTEM.cz_lce_compat_tab_type := SYSTEM.cz_lce_compat_tab_type();
6401   a_min                  PLS_INTEGER;
6402   b_min                  PLS_INTEGER;
6403   a_object_name          VARCHAR2(4000);
6404   b_object_name          VARCHAR2(4000);
6405   v_option_a             DBMS_SQL.NUMBER_TABLE;
6406   v_option_b             DBMS_SQL.NUMBER_TABLE;
6407   current_option         NUMBER;
6408   v_bitpos_a             tIntegerArray_idx_vc2; --jonatara:bug7041718
6409   v_bitpos_b             tIntegerArray_idx_vc2;
6410   v_bitinv_a             tIntegerArray;
6411   v_bitinv_b             tIntegerArray;
6412   v_mask                 VARCHAR2(32000);
6413   v_group                VARCHAR2(32000);
6414   v_rel                  VARCHAR2(1);
6415   v_group_by_set_mask_a  tVarcharTable;
6416   v_group_by_set_mask_b  tVarcharTable;
6417 /*-------------------------------------------------------------------------------------
6418   CREATE OR REPLACE TYPE cz_lce_compat_rec_type IS OBJECT (option_a NUMBER, option_b NUMBER);
6419   CREATE OR REPLACE TYPE cz_lce_compat_tab_type IS TABLE OF cz_lce_compat_rec_type;
6420 ---------------------------------------------------------------------------------------*/
6421   FUNCTION get_feature_minimum(p_feature_id IN NUMBER) RETURN PLS_INTEGER IS
6422     v_idx  NUMBER; --kdande; Bug 6881902; 11-Mar-2008
6423     v_min  NUMBER; --kdande; Bug 6881902; 11-Mar-2008
6424   BEGIN
6425       v_idx := glIndexByPsNodeId(p_feature_id);
6426       v_min := glMinimum(v_idx);
6427 
6428       IF(glPsNodeType(v_idx) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
6429         v_min := glMinimumSel(v_idx);
6430       END IF;
6431     if(v_min IS NULL OR v_min < 1)THEN RETURN 0; END IF;
6432    RETURN 1;
6433   END;
6434 ---------------------------------------------------------------------------------------
6435 PROCEDURE init_set_mask(p_size IN PLS_INTEGER) IS
6436 BEGIN
6437   v_mask := '0';
6438   v_mask := RPAD(v_mask, p_size, '0');
6439 END;
6440 ---------------------------------------------------------------------------------------
6441 PROCEDURE set_mask(p_bitpos IN PLS_INTEGER) IS
6442 BEGIN
6443   v_mask := SUBSTR(v_mask, 1, p_bitpos - 1) || '1' || SUBSTR(v_mask, p_bitpos + 1);
6444 END;
6445 ---------------------------------------------------------------------------------------
6446 PROCEDURE init_group_mask_a(p_key IN VARCHAR2) IS
6447 BEGIN
6448   v_group_by_set_mask_a(p_key) := '0';
6449   v_group_by_set_mask_a(p_key) := RPAD(v_group_by_set_mask_a(p_key), v_bitpos_a.COUNT, '0');
6450 END;
6451 ---------------------------------------------------------------------------------------
6452 PROCEDURE set_group_mask_a(p_key IN VARCHAR2, p_bitpos IN PLS_INTEGER) IS
6453 BEGIN
6454   v_group_by_set_mask_a(p_key) := SUBSTR(v_group_by_set_mask_a(p_key), 1, p_bitpos - 1)
6455                         || '1' || SUBSTR(v_group_by_set_mask_a(p_key), p_bitpos + 1);
6456 END;
6457 ---------------------------------------------------------------------------------------
6458 PROCEDURE init_group_mask_b(p_key IN VARCHAR2) IS
6459 BEGIN
6460   v_group_by_set_mask_b(p_key) := '0';
6461   v_group_by_set_mask_b(p_key) := RPAD(v_group_by_set_mask_b(p_key), v_bitpos_b.COUNT, '0');
6462 END;
6463 ---------------------------------------------------------------------------------------
6464 PROCEDURE set_group_mask_b(p_key IN VARCHAR2, p_bitpos IN PLS_INTEGER) IS
6465 BEGIN
6466   v_group_by_set_mask_b(p_key) := SUBSTR(v_group_by_set_mask_b(p_key), 1, p_bitpos - 1)
6467                         || '1' || SUBSTR(v_group_by_set_mask_b(p_key), p_bitpos + 1);
6468 END;
6469 ---------------------------------------------------------------------------------------
6470 FUNCTION in_mask(p_bitpos IN PLS_INTEGER) RETURN BOOLEAN IS
6471 BEGIN
6472   RETURN (SUBSTR(v_mask, p_bitpos, 1) = '1');
6473 END;
6474 ---------------------------------------------------------------------------------------
6475 FUNCTION in_group(p_bitpos IN PLS_INTEGER) RETURN BOOLEAN IS
6476 BEGIN
6477   RETURN (SUBSTR(v_group, p_bitpos, 1) = '1');
6478 END;
6479 ---------------------------------------------------------------------------------------
6480 BEGIN
6481 nDebug := 8000000;
6482   v_cursor := DBMS_SQL.OPEN_CURSOR;
6483   DBMS_SQL.PARSE(v_cursor, SQLSelect || SQLFrom || SQLWhere, DBMS_SQL.NATIVE);
6484 
6485   FOR i IN 1..bindValue.COUNT LOOP
6486     DBMS_SQL.BIND_VARIABLE(v_cursor, ':x' || TO_CHAR(i), bindValue(i));
6487   END LOOP;
6488 
6489   localNumber := DBMS_SQL.EXECUTE(v_cursor);
6490 nDebug := 8000001;
6491   LOOP
6492 
6493     DBMS_SQL.DEFINE_ARRAY(v_cursor, 1, v_option_a, DBMS_SQL_MAX_BUFFER_SIZE, 1);
6494     DBMS_SQL.DEFINE_ARRAY(v_cursor, 2, v_option_b, DBMS_SQL_MAX_BUFFER_SIZE, 1);
6495 
6496     localNumber := DBMS_SQL.FETCH_ROWS(v_cursor);
6497 
6498     DBMS_SQL.COLUMN_VALUE(v_cursor, 1, v_option_a);
6499     DBMS_SQL.COLUMN_VALUE(v_cursor, 2, v_option_b);
6500 nDebug := 8000002;
6501     FOR i IN 1..localNumber LOOP
6502       v_options.EXTEND();
6503       v_options(rowThreshold + i) := SYSTEM.cz_lce_compat_rec_type(v_option_a(i), v_option_b(i));
6504 nDebug := 8000003;
6505       --These arrays store 'bit positions' for every a or b option. Later they will be used in construction
6506       --of the 'bit masks' for compatibility groups and sets.
6507       --The 'inv' arrays allow to quickly get an option_id by its bit position.
6508 
6509       IF(NOT v_bitpos_a.EXISTS(v_option_a(i)))THEN
6510 
6511          v_bitpos_a(v_option_a(i)) := v_bitpos_a.COUNT + 1;
6512          v_bitinv_a(v_bitpos_a(v_option_a(i))) := v_option_a(i);
6513       END IF;
6514       IF(NOT v_bitpos_b.EXISTS(v_option_b(i)))THEN
6515 
6516          v_bitpos_b(v_option_b(i)) := v_bitpos_b.COUNT + 1;
6517          v_bitinv_b(v_bitpos_b(v_option_b(i))) := v_option_b(i);
6518       END IF;
6519     END LOOP;
6520 
6521     v_option_a.DELETE;
6522     v_option_b.DELETE;
6523 
6524     EXIT WHEN localNumber <> DBMS_SQL_MAX_BUFFER_SIZE;
6525     rowThreshold := rowThreshold + DBMS_SQL_MAX_BUFFER_SIZE;
6526   END LOOP;
6527 nDebug := 8000005;
6528   DBMS_SQL.CLOSE_CURSOR(v_cursor);
6529 
6530   --If there's no valid combinations, report the rule and ignore it.
6531 
6532   IF(v_options.COUNT = 0)THEN
6533     RAISE CZ_R_COMPAT_NO_COMBINATIONS;
6534   END IF;
6535 
6536   IF (v_options.COUNT = (featOptionsCount(v_tFeatureId(1)) * featOptionsCount(v_tFeatureId(2)))) THEN
6537 
6538      --This is a two-column pbc rule, and the number of valid combinations is equal to the
6539      --number of possible combinations. The rule can be ignored.
6540 
6541      RETURN;
6542   END IF;
6543 
6544   a_min := get_feature_minimum(v_tFeatureId(1));
6545   b_min := get_feature_minimum(v_tFeatureId(2));
6546 
6547   --Generate the main relations.
6548 
6549   IF(a_min = 0)THEN
6550 
6551     --We need a temporary object to represent Not(A).
6552 
6553     nLocalDefaults := nLocalDefaults + 1;
6554     a_object_name := t_prefix || TO_CHAR(nLocalDefaults);
6555 
6556     vLogicLine := 'OBJECT ' || a_object_name || NewLine ||
6557                   'GS N ... ' || TO_CHAR(nReasonId) || NewLine ||
6558                   'GL' || OperatorLetters(OPERATOR_ANYOF) || GENERATE_NAME(v_BackIndex(1), v_tFeatureId(1)) || NewLine ||
6559                   'GR' || OperatorLetters(OPERATOR_ANYOF) || a_object_name || NewLine;
6560     PACK;
6561     a_object_name := a_object_name || ' ';
6562   END IF;
6563 
6564   IF(b_min = 0)THEN
6565 
6566     --We need a temporary object to represent Not(B).
6567 
6568     nLocalDefaults := nLocalDefaults + 1;
6569     b_object_name := t_prefix || TO_CHAR(nLocalDefaults);
6570 
6571     vLogicLine := 'OBJECT ' || b_object_name || NewLine ||
6572                   'GS N ... ' || TO_CHAR(nReasonId) || NewLine ||
6573                   'GL' || OperatorLetters(OPERATOR_ANYOF) || GENERATE_NAME(v_BackIndex(2), v_tFeatureId(2)) || NewLine ||
6574                   'GR' || OperatorLetters(OPERATOR_ANYOF) || b_object_name || NewLine;
6575     PACK;
6576     b_object_name := b_object_name || ' ';
6577   END IF;
6578 
6579   current_option := -1;
6580 nDebug := 8000010;
6581   FOR a IN (SELECT option_a, option_b FROM TABLE(v_options) ORDER BY option_a) LOOP
6582 
6583     IF(a.option_a <> current_option)THEN
6584 
6585       IF(current_option <> -1)THEN
6586 
6587         --We just moved to the next option. current_option is still the previous option for
6588         --which the generating of the compatible set mask is completed, and the actual mask
6589         --is still in v_mask.
6590         --Here either add the options to an existing compatibility group mask, or create a
6591         --new compatibility group mask.
6592 
6593         IF(NOT v_group_by_set_mask_a.EXISTS(v_mask))THEN init_group_mask_a(v_mask); END IF;
6594         set_group_mask_a(v_mask, v_bitpos_a(current_option));
6595       END IF;
6596 
6597       current_option := a.option_a;
6598       init_set_mask(v_bitpos_b.COUNT);
6599     END IF;
6600 
6601     set_mask(v_bitpos_b(a.option_b));
6602   END LOOP;
6603 
6604   --Need to repeat that for the last option.
6605 
6606   IF(NOT v_group_by_set_mask_a.EXISTS(v_mask))THEN init_group_mask_a(v_mask); END IF;
6607   set_group_mask_a(v_mask, v_bitpos_a(current_option));
6608 
6609   current_option := -1;
6610 
6611   FOR b IN (SELECT option_a, option_b FROM TABLE(v_options) ORDER BY option_b) LOOP
6612 
6613     IF(b.option_b <> current_option)THEN
6614 
6615       IF(current_option <> -1)THEN
6616 
6617         IF(NOT v_group_by_set_mask_b.EXISTS(v_mask))THEN init_group_mask_b(v_mask); END IF;
6618         set_group_mask_b(v_mask, v_bitpos_b(current_option));
6619       END IF;
6620 
6621       current_option := b.option_b;
6622       init_set_mask(v_bitpos_a.COUNT);
6623     END IF;
6624 
6625     set_mask(v_bitpos_a(b.option_a));
6626   END LOOP;
6627 
6628   --Need to repeat that for the last option.
6629 nDebug := 8000015;
6630   IF(NOT v_group_by_set_mask_b.EXISTS(v_mask))THEN init_group_mask_b(v_mask); END IF;
6631   set_group_mask_b(v_mask, v_bitpos_b(current_option));
6632 
6633   --The tables of compatibility group masks hashed by compatibility set masks have been built
6634   --for both sides. Now we can use them to generate the relations.
6635 
6636   v_mask := v_group_by_set_mask_a.FIRST;
6637 
6638   WHILE(v_mask IS NOT NULL)LOOP
6639 
6640     v_group := v_group_by_set_mask_a(v_mask);
6641     v_rel := 'I';
6642 
6643     IF(a_min = 1 AND b_min = 1 AND
6644        v_group_by_set_mask_b.EXISTS(v_group) AND v_group_by_set_mask_b(v_group) = v_mask)THEN
6645 
6646       --This is A Implies B, B Implies A. A Requires relation will be generated between v_group and
6647       --v_mask and v_group_by_set_mask_b(v_group) will be deleted so that it will not be processed
6648       --by the cycle on the other side.
6649 
6650       v_rel := 'R';
6651       v_group_by_set_mask_b.DELETE(v_group);
6652     END IF;
6653 
6654     --Generate an Implies or Requires relation between AnyTrue(v_group) and AnyTrue(v_mask)
6655 
6656     vLogicLine := 'GS ' || v_rel || ' ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N '; PACK;
6657 
6658     FOR i IN 1..v_bitpos_a.COUNT LOOP
6659       IF(in_group(i))THEN
6660         vLogicLine := GENERATE_NAME(v_BackIndex(1), v_bitinv_a(i)) || ' '; PACK;
6661       END IF;
6662     END LOOP;
6663 
6664     vLogicLine := NewLine || 'GR N ' || b_object_name; PACK;
6665 nDebug := 8000020;
6666     FOR i IN 1..v_bitpos_b.COUNT LOOP
6667       IF(in_mask(i))THEN
6668         vLogicLine := GENERATE_NAME(v_BackIndex(2), v_bitinv_b(i)) || ' '; PACK;
6669       END IF;
6670     END LOOP;
6671 
6672     vLogicLine := NewLine;
6673     PACK;
6674     v_mask := v_group_by_set_mask_a.NEXT(v_mask);
6675   END LOOP;
6676 
6677   v_mask := v_group_by_set_mask_b.FIRST;
6678 
6679   WHILE(v_mask IS NOT NULL)LOOP
6680 
6681     v_group := v_group_by_set_mask_b(v_mask);
6682     v_rel := 'I';
6683 
6684     IF(a_min = 1 AND b_min = 1 AND
6685        v_group_by_set_mask_a.EXISTS(v_group) AND v_group_by_set_mask_a(v_group) = v_mask)THEN
6686 
6687       --This is B Implies A, A Implies B. A Requires relation will be generated between v_group and
6688       --v_mask. We don't need to delete anything from the other side.
6689 
6690       v_rel := 'R';
6691     END IF;
6692 
6693     --Generate an Implies or Requires relation between AnyTrue(v_group) and AnyTrue(v_mask)
6694 
6695     vLogicLine := 'GS ' || v_rel || ' ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N '; PACK;
6696 nDebug := 8000025;
6697     FOR i IN 1..v_bitpos_b.COUNT LOOP
6698       IF(in_group(i))THEN
6699         vLogicLine := GENERATE_NAME(v_BackIndex(2), v_bitinv_b(i)) || ' '; PACK;
6700       END IF;
6701     END LOOP;
6702 
6703     vLogicLine := NewLine || 'GR N ' || a_object_name; PACK;
6704 
6705     FOR i IN 1..v_bitpos_a.COUNT LOOP
6706       IF(in_mask(i))THEN
6707         vLogicLine := GENERATE_NAME(v_BackIndex(1), v_bitinv_a(i)) || ' '; PACK;
6708       END IF;
6709     END LOOP;
6710 
6711     vLogicLine := NewLine;
6712     PACK;
6713     v_mask := v_group_by_set_mask_b.NEXT(v_mask);
6714   END LOOP;
6715 
6716   -- The following block can be optimized by splitting into two (for a and b), and
6717   -- 1) using featOptionsCount table and compare it to v_bitpos_a(b).COUNT to find out if excludes
6718   --    are required instead of cycling through the feature options;
6719   -- 2) using v_bitpos_a(b) instead of v_OptionExists thus avoiding populating this table.
6720 
6721   v_OptionExists.DELETE;
6722 
6723   --Hash all the options of both features that are compatible. If an option is not in the hash,
6724   --exclude relation will be generated later.
6725 nDebug := 8000030;
6726   FOR i IN 1..v_options.COUNT LOOP
6727     v_OptionExists(v_options(i).option_a) := 1;
6728     v_OptionExists(v_options(i).option_b) := 1;
6729   END LOOP;
6730 
6731   --Generate the exclude relations if necessary.
6732   --The code is re-written as part of the fix for the bug #4546828 to use the new hash table.
6733 
6734   FOR i IN 1..v_tFeatureId.COUNT LOOP
6735 
6736     ExcludesRequired := 0;
6737     nChild := h_OptionExplId(i).FIRST;
6738     nCounter := nChild;
6739 
6740     WHILE(nChild IS NOT NULL) LOOP
6741       IF(NOT v_OptionExists.EXISTS(nChild))THEN
6742          ExcludesRequired := 1;
6743          EXIT;
6744       END IF;
6745       nChild := h_OptionExplId(i).NEXT(nChild);
6746     END LOOP;
6747 
6748     IF(ExcludesRequired = 1)THEN
6749 
6750      nChild := nCounter;
6751 nDebug := 8000040;
6752      vLogicLine := 'GS E ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N ';
6753      PACK;
6754 
6755      WHILE(nChild IS NOT NULL) LOOP
6756        IF(NOT v_OptionExists.EXISTS(nChild))THEN
6757          vLogicLine := GENERATE_NAME_EXPL(h_OptionExplId(i)(nChild), nChild) || ' ';
6758          PACK;
6759        END IF;
6760        nChild := h_OptionExplId(i).NEXT(nChild);
6761      END LOOP;
6762 
6763      vLogicLine := NewLine || 'GR L ';
6764      PACK;
6765 
6766      FOR n IN 1..v_tFeatureId.COUNT LOOP
6767        IF(n <> i)THEN
6768          vLogicLine := GENERATE_NAME(v_BackIndex(n), v_tFeatureId(n)) || ' ';
6769          PACK;
6770        END IF;
6771      END LOOP;
6772 
6773      vLogicLine := NewLine;
6774      PACK;
6775     END IF; --Excludes required
6776   END LOOP;
6777 END GENERATE_OPTIMIZED_PBC;
6778 ---------------------------------------------------------------------------------------
6779 BEGIN
6780 
6781   --High-level property-based compatibility rule validation section
6782   --Make sure the rule has at least 2 participant features
6783 
6784   IF(participantCount < 2)THEN
6785     RAISE CZ_R_COMPAT_SINGLE_FEATURE;
6786   END IF;
6787 
6788 nDebug := 7005100;
6789 
6790   nChild := v_ChildrenIndex(v_tExprId(j));
6791   nCounter := 1;
6792 
6793   WHILE(v_tExprParentId(nChild) = v_tExprId(j)) LOOP
6794     IF(v_tExprType(nChild) = EXPR_ITERATOR)THEN
6795 
6796       iteratorIndex(nCounter) := nChild;
6797       featureIndex := v_ChildrenIndex(v_tExprId(nChild));
6798 
6799       v_tFeatureId(nCounter) := v_tExprPsNodeId(featureIndex);
6800       v_tExplId(nCounter) := v_tExplNodeId(featureIndex);
6801       v_BackIndex(nCounter) := featureIndex;
6802 
6803       nCounter := nCounter + 1;
6804 
6805     ELSIF(v_tExprType(nChild) = EXPR_WHERE)THEN
6806 
6807       whereIndex := nChild;
6808     END IF;
6809 
6810     nChild := nChild + 1;
6811   END LOOP;
6812 
6813 nDebug := 7005101;
6814 
6815   FOR i IN 1..iteratorIndex.COUNT LOOP
6816 
6817     bind_node_id.DELETE;
6818     bind_values.DELETE;
6819 
6820     v_property_id.DELETE;
6821     v_data_type.DELETE;
6822     v_prop_name.DELETE;
6823     v_flag.DELETE;
6824 
6825     temp_cmpt_hash_key(compatLevel) := NULL;
6826     tableAlias := 'C' || TO_CHAR(i);
6827 
6828     iterator.DELETE;
6829     iterator := GENERATE_ITERATOR(iteratorIndex(i), ListType);
6830 
6831     IF(whereIndex <> 0)THEN
6832       EXPLORE_WHERE(whereIndex, v_tExprArgumentName(iteratorIndex(i)));
6833     END IF;
6834 
6835     IF(temp_cmpt_hash_key(compatLevel) IS NOT NULL)THEN
6836       FOR ii IN 1..v_property_id.COUNT LOOP
6837         temp_cmpt_hash_key(compatLevel) := temp_cmpt_hash_key(compatLevel) || '-' || TO_CHAR(v_property_id(ii));
6838       END LOOP;
6839     END IF;
6840 
6841 nDebug := 7005102;
6842 
6843     IF(temp_cmpt_hash_key(compatLevel) IS NOT NULL AND temp_cmpt_table_hash.EXISTS(temp_cmpt_hash_key(compatLevel)))THEN
6844 
6845       tableName := temp_cmpt_table_hash(temp_cmpt_hash_key(compatLevel));
6846       arg_table_name(v_tExprArgumentName(iteratorIndex(i))) := tableAlias;
6847 
6848       IF(SQLSelect IS NULL)THEN SQLSelect := 'SELECT '; ELSE SQLSelect := SQLSelect || ', '; END IF;
6849       SQLSelect := SQLSelect || tableAlias || '.node_id';
6850       IF(SQLFrom IS NULL)THEN SQLFrom := ' FROM '; ELSE SQLFrom := SQLFrom || ', '; END IF;
6851       SQLFrom := SQLFrom || tableName || ' ' || tableAlias;
6852 
6853       FOR ii IN 1..iterator.COUNT LOOP
6854         h_OptionExplId(i)(iterator(ii).node_id) := iterator(ii).node_id_ex;
6855       END LOOP;
6856     ELSE
6857 
6858 --tableName := 'G_' || TO_CHAR(table_name_generator);
6859 -- SMANNA : Bug11822849 : Want to make these global temp table name unique between the sessions.
6860     tableName := 'G_' ||TO_CHAR(thisRunId)||'_'|| TO_CHAR(table_name_generator);
6861     table_name_generator := table_name_generator + 1;
6862     arg_table_name(v_tExprArgumentName(iteratorIndex(i))) := tableAlias;
6863 
6864     IF(SQLSelect IS NULL)THEN SQLSelect := 'SELECT '; ELSE SQLSelect := SQLSelect || ', '; END IF;
6865     SQLSelect := SQLSelect || tableAlias || '.node_id';
6866     IF(SQLFrom IS NULL)THEN SQLFrom := ' FROM '; ELSE SQLFrom := SQLFrom || ', '; END IF;
6867     SQLFrom := SQLFrom || tableName || ' ' || tableAlias;
6868 
6869     SQLCreate := 'CREATE GLOBAL TEMPORARY TABLE ' || tableName || '(node_id NUMBER ';
6870 
6871     FOR ii IN 1..v_property_id.COUNT LOOP
6872 
6873       SQLCreate := SQLCreate || ', i_' || TO_CHAR(v_property_id(ii));
6874 
6875       IF(v_data_type(ii) IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL))THEN
6876 
6877         SQLCreate := SQLCreate || ' NUMBER';
6878       ELSE
6879 
6880         SQLCreate := SQLCreate || ' VARCHAR2(' || TO_CHAR(MAXIMUM_INDEX_LENGTH) || ')';
6881       END IF;
6882     END LOOP;
6883 
6884     SQLCreate := SQLCreate || ') ON COMMIT PRESERVE ROWS';
6885 
6886 nDebug := 7005103;
6887 
6888     BEGIN
6889       EXECUTE IMMEDIATE SQLCreate;
6890     EXCEPTION
6891       WHEN OTHERS THEN
6892 
6893         --If the table already exists, truncate it, drop and try to create again.
6894 
6895         IF(SQLCODE = ORACLE_OBJECT_ALREADY_EXISTS)THEN
6896           EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || tableName;
6897           EXECUTE IMMEDIATE 'DROP TABLE ' || tableName;
6898           EXECUTE IMMEDIATE SQLCreate;
6899         ELSE
6900           RAISE;
6901         END IF;
6902     END;
6903 
6904     --The table is created, add its name to the delete list.
6905 
6906     temp_tables(temp_tables.COUNT + 1) := tableName;
6907 
6908 nDebug := 7005104;
6909 
6910     SQLInsert := 'INSERT INTO ' || tableName || '(node_id';
6911     SQLValues := ' VALUES (:y1';
6912 
6913     FOR ii IN 1..v_property_id.COUNT LOOP
6914 
6915       BEGIN
6916 
6917         EXECUTE IMMEDIATE 'CREATE INDEX ' || tableName || '_I' || TO_CHAR(ii) || ' ON ' || tableName ||
6918                           '(i_' || v_property_id(ii) || ')';
6919       EXCEPTION
6920         WHEN OTHERS THEN
6921           IF(SQLCODE <> ORACLE_OBJECT_ALREADY_EXISTS)THEN RAISE; END IF;
6922       END;
6923 
6924       SQLInsert := SQLInsert || ', i_' || TO_CHAR(v_property_id(ii));
6925       SQLValues := SQLValues || ', :x' || TO_CHAR(ii);
6926     END LOOP;
6927 
6928     SQLInsert := SQLInsert || ')';
6929     SQLValues := SQLValues || ')';
6930 
6931 nDebug := 7005105;
6932 
6933     FOR ii IN 1..iterator.COUNT LOOP
6934 
6935       bind_node_id(ii) := iterator(ii).node_id;
6936 
6937       IF(v_property_id.COUNT > 0)THEN
6938 
6939         --This is only valid if there are properties.
6940 
6941         IF(iterator(ii).node_id IS NULL)THEN RAISE CZ_R_TYPE_NO_PROPERTY; END IF;
6942 
6943         nodeId := glPsNodeId(glIndexByPsNodeId(iterator(ii).node_id));
6944         itemId := glItemId(glIndexByPsNodeId(iterator(ii).node_id));
6945       END IF;
6946 
6947       --Get the property values and insert the data.
6948 
6949 nDebug := 7005106;
6950 
6951       FOR jj IN 1..v_property_id.COUNT LOOP
6952 
6953         propertyId := v_property_id(jj);
6954         hash_propval_key := TO_CHAR(nodeId) || '-' || TO_CHAR(itemId) || '-' ||
6955                             TO_CHAR(propertyId) || '-' || TO_CHAR(v_flag(propertyId));
6956 
6957         IF(NOT table_hash_propval.EXISTS(hash_propval_key))THEN
6958 
6959           IF(v_flag(propertyId) = 0)THEN
6960 
6961             --User property.
6962 
6963             propertyVal := NULL;
6964             localNumber := NULL;
6965             propertyVal := GET_PROPERTY_VALUE(nodeId, propertyId, itemId, localNumber);
6966           ELSE
6967 
6968             --System property.
6969 
6970             localNumber := 1;
6971             propertyVal := STATIC_SYSPROP_VALUE(nodeId, propertyId, v_flag(v_property_id(jj)));
6972           END IF;
6973 
6974           --Bug #3829438. Second and third columns of the cursor are not null, so localNumber can be NULL
6975           --only if no rows are fetched.
6976 
6977           IF(localNumber IS NOT NULL)THEN
6978             IF(v_data_type(jj) IN (DATATYPE_INTEGER, DATATYPE_FLOAT))THEN
6979 
6980               --If the property has numeric type, but the data is corrupted and the value
6981               --cannot be actually converted to a number, the generated SQL statement may
6982               --produce incomprehensive syntax errors, like 'too many columns'. To avoid
6983               --this verify the value.
6984 
6985               BEGIN
6986                 typeCheck := TO_NUMBER(propertyVal);
6987               EXCEPTION
6988                 WHEN OTHERS THEN
6989                   errorMessage := v_prop_name(jj);
6990                   localString := propertyVal;
6991                   RAISE CZ_R_INCORRECT_DATA_TYPE;
6992               END;
6993             ELSIF(LENGTH(propertyVal) > MAXIMUM_INDEX_LENGTH)THEN
6994 
6995                errorMessage := v_prop_name(jj);
6996                nParam := glIndexByPsNodeId(v_tFeatureId(i));
6997                auxIndex := glIndexByPsNodeId(iterator(ii).node_id);
6998                RAISE CZ_R_LONG_PROPERTY_VALUE;
6999             END IF;
7000           ELSE
7001             errorMessage := v_prop_name(jj);
7002             nParam := glIndexByPsNodeId(v_tFeatureId(i));
7003             auxIndex := glIndexByPsNodeId(iterator(ii).node_id);
7004             RAISE CZ_R_OPTION_NO_PROPERTY;
7005           END IF;
7006 
7007           bind_values(jj)(ii) := propertyVal;
7008           table_hash_propval(hash_propval_key) := propertyVal;
7009         ELSE
7010           bind_values(jj)(ii) := table_hash_propval(hash_propval_key);
7011         END IF;
7012       END LOOP;
7013 
7014       --Bug #4546828.
7015       --In a BOM model, options can really be references to other BOM models, therefore each option
7016       --can have its own explosion id, which should be used to generate correct logic name.
7017       --Hash the explosion id(s) here in a two-dimensional table (iterator, option_id).
7018       --Here we are supposed to hash all eligible options of the parent (the eligibility determined
7019       --by EXPAND_NODE inside the GENERATE_ITERATOR). For example, if a BOM model has BOM standard
7020       --items and a non-BOM feature, only the bom items are eligible. Therefore, this table will be
7021       --used later when generating exclusions.
7022 
7023       h_OptionExplId(i)(nodeId) := iterator(ii).node_id_ex;
7024     END LOOP;
7025 
7026 nDebug := 7005107;
7027 
7028     v_cursor := DBMS_SQL.OPEN_CURSOR;
7029     DBMS_SQL.PARSE(v_cursor, SQLInsert || SQLValues, DBMS_SQL.NATIVE);
7030 
7031     DBMS_SQL.BIND_ARRAY(v_cursor, ':y1', bind_node_id);
7032 
7033     FOR ii IN 1..v_property_id.COUNT LOOP
7034       DBMS_SQL.BIND_ARRAY(v_cursor, ':x' || TO_CHAR(ii), bind_values(ii));
7035     END LOOP;
7036 
7037     localNumber := DBMS_SQL.EXECUTE(v_cursor);
7038     DBMS_SQL.CLOSE_CURSOR(v_cursor);
7039 
7040     EXECUTE IMMEDIATE 'ANALYZE TABLE ' || tableName || ' COMPUTE STATISTICS';
7041 
7042     --The table is created and populated, add its name to the hash for re-use if it is eligible.
7043 
7044     IF(temp_cmpt_hash_key(compatLevel) IS NOT NULL)THEN temp_cmpt_table_hash(temp_cmpt_hash_key(compatLevel)) := tableName; END IF;
7045     END IF;
7046   END LOOP;
7047 
7048   --Generate the WHERE clause and run the query with bind variables. For every row returned,
7049   --generate the expression and return the object.
7050   --To do this, add GENERATE_ARGUMENT to the GENERATE_EXPRESSION.
7051 
7052 nDebug := 7005108;
7053 
7054   IF(whereIndex <> 0)THEN
7055     SQLWhere := ' WHERE ' || EXAMINE_WHERE_CLAUSE(v_ChildrenIndex(v_tExprId(whereIndex)));
7056   END IF;
7057 
7058   IF(v_tFeatureId.COUNT = 2)THEN
7059     GENERATE_OPTIMIZED_PBC;
7060   ELSE
7061 
7062     GENERATE_STANDARD_PBC;
7063   END IF;
7064 
7065  RETURN v_return;
7066 END;
7067 ---------------------------------------------------------------------------------------
7068 --This function is introduced to support the level of embedding.
7069 
7070 FUNCTION GENERATE_COMPATIBLE(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
7071   v_return  tStringArray;
7072 BEGIN
7073   compatLevel := compatLevel + 1;
7074   v_return := GENERATE_COMPATIBLE_(j, ListType);
7075   compatLevel := compatLevel - 1;
7076  RETURN v_return;
7077 EXCEPTION
7078   WHEN OTHERS THEN
7079     compatLevel := compatLevel - 1;
7080     RAISE;
7081 END;
7082 ---------------------------------------------------------------------------------------
7083 FUNCTION GENERATE_EXPRESSION(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
7084  v_return  tStringArray;
7085  v_result  tIteratorArray;
7086 BEGIN
7087 
7088   ListType := DATATYPE_GENERIC;
7089 
7090   IF(v_tExprType(j) = EXPR_NODE_TYPE_NODE)THEN
7091 
7092     IF(v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
7093 
7094       RETURN GENERATE_REFNODE(j, ListType);
7095     ELSE
7096 
7097       RETURN GENERATE_NODE(j);
7098     END IF;
7099 
7100   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_FEATPROP)THEN
7101 
7102     RETURN GENERATE_PROPERTY(j);
7103 
7104   ELSIF(v_tExprType(j) = EXPR_PROP)THEN
7105 
7106     v_return(1) := PROPERTY_VALUE(j, glIndexByPsNodeId(v_tExprPsNodeId(j - 1)), ListType);
7107 
7108   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_OPERATOR)THEN
7109 
7110     IF(v_tExprSubtype(j) IN (OPERATOR_ADD,
7111                              OPERATOR_SUB,
7112                              OPERATOR_MULT,
7113                              OPERATOR_DIV,
7114                              OPERATOR_ADD_INT,
7115                              OPERATOR_SUB_INT,
7116                              OPERATOR_MULT_INT))THEN
7117       RETURN GENERATE_ARITHMETIC(j);
7118 
7119     ELSIF(v_tExprSubtype(j) IN (OPERATOR_COS,
7120                                 OPERATOR_ACOS,
7121                                 OPERATOR_COSH,
7122                                 OPERATOR_SIN,
7123                                 OPERATOR_ASIN,
7124                                 OPERATOR_SINH,
7125                                 OPERATOR_TAN,
7126                                 OPERATOR_ATAN,
7127                                 OPERATOR_TANH,
7128                                 OPERATOR_LOG,
7129                                 OPERATOR_LOG10,
7130                                 OPERATOR_EXP,
7131                                 OPERATOR_ABS,
7132                                 OPERATOR_SQRT))THEN
7133       RETURN GENERATE_MATH_UNARY(j);
7134 
7135     ELSIF(v_tExprSubtype(j) IN (OPERATOR_MATHDIV,
7136                                 OPERATOR_POW,
7137                                 OPERATOR_POW_INT,
7138                                 OPERATOR_ATAN2,
7139                                 OPERATOR_MOD))THEN
7140       RETURN GENERATE_MATH_BINARY(j);
7141 
7142     ELSIF(v_tExprSubtype(j) IN (OPERATOR_ROUNDTONEAREST,
7143                                 OPERATOR_ROUNDUPTONEAREST,
7144                                 OPERATOR_ROUNDDOWNTONEAREST))THEN
7145       RETURN GENERATE_MATH_ROUND(j);
7146 
7147     ELSIF(v_tExprSubtype(j) IN (OPERATOR_CEILING,
7148                                 OPERATOR_FLOOR,
7149                                 OPERATOR_ROUND,
7150                                 OPERATOR_TRUNCATE))THEN
7151       RETURN GENERATE_ROUND(j);
7152 
7153     ELSIF(v_tExprSubtype(j) IN (OPERATOR_AND,
7154                                 OPERATOR_OR))THEN
7155       RETURN GENERATE_ANDOR(j, ListType);
7156 
7157     ELSIF(v_tExprSubtype(j) IN (OPERATOR_ANYOF,
7158                                 OPERATOR_ALLOF))THEN
7159       RETURN GENERATE_ANYALLOF(j, ListType);
7160 
7161     ELSIF(v_tExprSubtype(j) = OPERATOR_NOT)THEN
7162       RETURN GENERATE_NOT(j);
7163 
7164     ELSIF(v_tExprSubtype(j) = OPERATOR_NOTTRUE)THEN
7165       RETURN GENERATE_NOTTRUE(j);
7166 
7167     ELSIF(v_tExprSubtype(j) IN (OPERATOR_EQUALS,
7168                                 OPERATOR_NOTEQUALS,
7169                                 OPERATOR_GT,
7170                                 OPERATOR_LT,
7171                                 OPERATOR_GE,
7172                                 OPERATOR_LE,
7173                                 OPERATOR_EQUALS_INT,
7174                                 OPERATOR_NOTEQUALS_INT,
7175                                 OPERATOR_GT_INT,
7176                                 OPERATOR_LT_INT,
7177                                 OPERATOR_GE_INT,
7178                                 OPERATOR_LE_INT,
7179                                 OPERATOR_BEGINSWITH,
7180                                 OPERATOR_ENDSWITH,
7181                                 OPERATOR_CONTAINS,
7182                                 OPERATOR_LIKE,
7183                                 OPERATOR_MATCHES,
7184                                 OPERATOR_DOESNOTBEGINWITH,
7185                                 OPERATOR_DOESNOTENDWITH,
7186                                 OPERATOR_DOESNOTCONTAIN,
7187                                 OPERATOR_NOTLIKE))THEN
7188       RETURN GENERATE_COMPARE(j);
7189 
7190     ELSIF(v_tExprSubtype(j) = OPERATOR_CONCAT)THEN
7191       RETURN GENERATE_CONCAT(j, ListType);
7192 
7193     ELSIF(v_tExprSubtype(j) = OPERATOR_TOTEXT)THEN
7194 
7195       --Bug 5620750 - recognize and handle the new ToText operator when used outside of PBC
7196       --context.
7197 
7198       RETURN GENERATE_TOTEXT(j, ListType);
7199 
7200     ELSIF(v_tExprSubtype(j) IN (OPERATOR_OPTIONSOF, OPERATOR_BOMOPTIONSOF))THEN
7201       RETURN GENERATE_OF(j);
7202 
7203     ELSIF(v_tExprSubtype(j) IN (OPERATOR_MIN,
7204                                 OPERATOR_MAX))THEN
7205       RETURN GENERATE_MINMAX(j);
7206 
7207     ELSIF(v_tExprSubtype(j) IN (OPERATOR_VAL))THEN
7208       RETURN GENERATE_VAL(j);
7209 
7210     ELSIF(v_tExprSubtype(j) IN (RULE_OPERATOR_REQUIRES,
7211                                 RULE_OPERATOR_IMPLIES,
7212                                 RULE_OPERATOR_EXCLUDES,
7213                                 RULE_OPERATOR_NEGATES,
7214                                 RULE_OPERATOR_DEFAULTS))THEN
7215       RETURN GENERATE_LOGIC_TREE(j);
7216 
7217     ELSIF(v_tExprSubtype(j) IN (RULE_OPERATOR_CONTRIBUTES,
7218                                 RULE_OPERATOR_CONSUMES))THEN
7219       RETURN GENERATE_NUMERIC_TREE(j);
7220 
7221     ELSE
7222 
7223       --This is not a built-in operator (primitive template), so generate it as a template application.
7224       --Right now there is no reason to report it as unknown.
7225 
7226       RETURN GENERATE_TEMPLATE_APPLICATION (j, ListType);
7227 
7228       --nParam := v_tExprSubtype(j);
7229       --RAISE CZ_E_UNKNOWN_OPERATOR_TYPE;
7230     END IF;
7231 
7232   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_LITERAL)THEN
7233 
7234     RETURN GENERATE_LITERAL(j);
7235 
7236   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_CONSTANT)THEN
7237 
7238     RETURN GENERATE_CONSTANT(j);
7239 
7240   ELSIF(v_tExprType(j) IN (EXPR_FORALL, EXPR_FORALL_DISTINCT))THEN
7241 
7242     v_result := GENERATE_FORALL(j, ListType);
7243 
7244     FOR i IN 1..v_result.COUNT LOOP
7245          v_return(i) := v_result(i).node_obj;
7246          IF(v_return(i) IS NULL AND v_result(i).node_id IS NOT NULL AND v_result(i).node_id_ex IS NOT NULL)THEN
7247                 v_return(i) := GENERATE_NAME_EXPL(v_result(i).node_id_ex, v_result(i).node_id);
7248          END IF;
7249     END LOOP;
7250 
7251   ELSIF(v_tExprType(j) = EXPR_COMPATIBLE)THEN
7252 
7253     RETURN GENERATE_COMPATIBLE(j, ListType);
7254 
7255   ELSIF(v_tExprType(j) = EXPR_ARGUMENT)THEN
7256 
7257     IF(v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
7258 
7259       RETURN GENERATE_REFNODE(j, ListType);
7260     ELSE
7261 
7262       ListType := DATA_TYPE_VOID;
7263       RETURN GENERATE_ARGUMENT(j, ListType);
7264     END IF;
7265 
7266   ELSE
7267 
7268     RAISE CZ_E_UNKNOWN_EXPR_TYPE;
7269   END IF;
7270  RETURN v_return;
7271 END;
7272 ---------------------------------------------------------------------------------------
7273 PROCEDURE GENERATE_COMPATIBILITY_TABLE IS
7274   v_tOptionId       tOptionId;
7275   v_OptionExists    tIntegerArray_idx_vc2; --kdande; Bug 6881902; 11-Mar-2008
7276   v_RowLines        tStringArray;
7277   v_ItemLines       tStringArray;
7278   itemIndex         PLS_INTEGER;
7279   itemCount         PLS_INTEGER := 1;
7280   nChild            PLS_INTEGER;
7281   nCounter          PLS_INTEGER;
7282   ExcludesRequired  PLS_INTEGER;
7283   PrimaryCount      PLS_INTEGER;
7284   localString       VARCHAR2(25);
7285   localNumber       PLS_INTEGER;
7286 BEGIN
7287 
7288 nDebug := 5000001;
7289 
7290   FOR i IN 1..v_tExprPsNodeId.COUNT LOOP
7291 
7292     v_tOptionId.DELETE;
7293     v_OptionExists.DELETE;
7294 
7295 nDebug := 5000002;
7296 
7297     SELECT secondary_opt_id BULK COLLECT INTO v_tOptionId
7298     FROM cz_des_chart_cells
7299     WHERE deleted_flag = FLAG_NOT_DELETED
7300       AND rule_id = nRuleId
7301       AND secondary_feature_id = v_tExprPsNodeId(i)
7302       AND secondary_feat_expl_id = v_tExplNodeId(i);
7303 
7304     IF(v_tOptionId.COUNT = 0)THEN
7305       RAISE CZ_R_EMPTY_COMPAT_RULE;
7306     ELSIF(i = 1)THEN
7307       PrimaryCount := v_tOptionId.COUNT;
7308     ELSE
7309       IF(v_tOptionId.COUNT <> PrimaryCount)THEN
7310         RAISE CZ_R_WRONG_COMPAT_TABLE;
7311       END IF;
7312     END IF;
7313 
7314 nDebug := 5000003;
7315 
7316     FOR n IN 1..v_tOptionId.COUNT LOOP
7317 
7318       --Make sure the option exists
7319 
7320       IF(NOT glIndexByPsNodeId.EXISTS(v_tOptionId(n)))THEN
7321         RAISE CZ_R_INCORRECT_NODE_ID;
7322       END IF;
7323 
7324       IF(NOT v_OptionExists.EXISTS(v_tOptionId(n)))THEN
7325 
7326 nDebug := 5000004;
7327 
7328        v_ItemLines(itemCount) := GENERATE_NAME(i, v_tOptionId(n)) || ' ' || TO_CHAR(i - 1);
7329        v_OptionExists(v_tOptionId(n)) := itemCount;
7330        itemCount := itemCount + 1;
7331 
7332       END IF;
7333 
7334 nDebug := 5000005;
7335 
7336       itemIndex := v_OptionExists(v_tOptionId(n));
7337 
7338       IF(v_RowLines.EXISTS(n))THEN
7339         v_RowLines(n) := v_RowLines(n) || ' ' || TO_CHAR(itemIndex - 1);
7340       ELSE
7341         v_RowLines(n) := ' ' || TO_CHAR(itemIndex - 1);
7342       END IF;
7343 
7344     END LOOP;
7345 
7346 nDebug := 5000006;
7347 
7348     nChild := glIndexByPsNodeId(v_tExprPsNodeId(i)) + 1;
7349     nCounter := nChild;
7350     ExcludesRequired := 0;
7351 
7352 nDebug := 5000007;
7353 
7354     WHILE(glParentId.EXISTS(nChild) AND glParentId(nChild) = v_tExprPsNodeId(i))LOOP
7355      IF(NOT v_OptionExists.EXISTS(glPsNodeId(nChild)))THEN
7356        ExcludesRequired := 1;
7357        EXIT;
7358      END IF;
7359      nChild := nChild + 1;
7360     END LOOP;
7361 
7362 nDebug := 5000008;
7363 
7364     IF(ExcludesRequired = 1)THEN
7365 
7366      nChild := nCounter;
7367 
7368      vLogicLine := 'GS E ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N ';
7369      PACK;
7370 
7371      WHILE(glParentId.EXISTS(nChild) AND glParentId(nChild) = v_tExprPsNodeId(i))LOOP
7372       IF(NOT v_OptionExists.EXISTS(glPsNodeId(nChild)))THEN
7373         vLogicLine := GENERATE_NAME(i, glPsNodeId(nChild)) || ' ';
7374         PACK;
7375       END IF;
7376       nChild := nChild + 1;
7377      END LOOP;
7378 
7379 nDebug := 5000009;
7380 
7381      vLogicLine := NewLine || 'GR L ';
7382      PACK;
7383 
7384      FOR n IN 1..v_tExprPsNodeId.COUNT LOOP
7385        IF(n <> i)THEN
7386          vLogicLine := GENERATE_NAME(n, v_tExprPsNodeId(n)) || ' ';
7387          PACK;
7388        END IF;
7389      END LOOP;
7390 
7391 nDebug := 5000010;
7392 
7393      vLogicLine := NewLine;
7394      PACK;
7395     END IF; --Excludes required
7396   END LOOP;
7397 
7398 nDebug := 5000011;
7399 
7400   vLogicLine := 'OBJECT P_R' || TO_CHAR(nRuleId) || NewLine ||
7401                 'COMBO P_R' || TO_CHAR(nRuleId) || ' ' || TO_CHAR(v_ItemLines.COUNT) || ' ' ||
7402                 TO_CHAR(v_RowLines.COUNT) || ' ' || TO_CHAR(v_tExprPsNodeId.COUNT) || ' ... ' ||
7403                 TO_CHAR(nReasonId) || NewLine;
7404   PACK;
7405 
7406 nDebug := 5000012;
7407 
7408   FOR i IN 1..v_ItemLines.COUNT LOOP
7409 
7410     vLogicLine := 'CI ' || TO_CHAR(i - 1) || ' ' || v_ItemLines(i) || NewLine;
7411     PACK;
7412 
7413   END LOOP;
7414 
7415 nDebug := 5000013;
7416 
7417   FOR i IN 1..v_tExprPsNodeId.COUNT LOOP
7418 
7419     IF(GenerateGatedCombo = 0)THEN
7420 
7421       --Use intermediate variable instead of using NVL because this is faster
7422 
7423       localNumber := glIndexByPsNodeId(v_tExprPsNodeId(i));
7424       localString := TO_CHAR(glMaximum(localNumber));
7425 
7426       --If it's a BOM item, we use maximum_selected instead of maximum
7427 
7428       IF(glPsNodeType(localNumber) IN (PS_NODE_TYPE_BOM_MODEL,PS_NODE_TYPE_BOM_OPTIONCLASS,PS_NODE_TYPE_BOM_STANDARD))THEN
7429        localString := TO_CHAR(glMaximumSel(localNumber));
7430       END IF;
7431 
7432       IF(localString IS NULL)THEN localString := '-1'; END IF;
7433       vLogicLine := ' O';
7434     ELSE
7435 
7436       --Generate gated combinations: maximum is always -1, the 'G' argument is followed
7437       --by the feature name.
7438 
7439       localString := '-1';
7440       vLogicLine := ' G ' || GENERATE_NAME(i, v_tExprPsNodeId(i));
7441     END IF;
7442 
7443     vLogicLine := 'CC ' || TO_CHAR(i - 1) || ' 0 ' || localString || vLogicLine || NewLine;
7444     PACK;
7445 
7446   END LOOP;
7447 
7448 nDebug := 5000014;
7449 
7450   FOR i IN 1..v_RowLines.COUNT LOOP
7451 
7452     vLogicLine := 'CR ' || TO_CHAR(i - 1) || v_RowLines(i) || NewLine;
7453     PACK;
7454 
7455   END LOOP;
7456 
7457 nDebug := 5000015;
7458 
7459   vLogicLine := 'COMBO_END' || NewLine;
7460   PACK;
7461 
7462 END;
7463 ---------------------------------------------------------------------------------------
7464 PROCEDURE GENERATE_DESIGNCHART_RULE IS
7465   vGridColumns      tPsNodeId;
7466   vBackIndex        tIntegerArray;
7467   nIndex            PLS_INTEGER;
7468 ---------------------------------------------------------------------------------------
7469 PROCEDURE GENERATE_COMPAT_TEMPLATE(inSuffix IN PLS_INTEGER) IS
7470   v_tOptionId         tOptionId;
7471   v_tPrimaryOptId     tOptionId;
7472   v_tPrimaryId        tOptionId;
7473   v_OptionExists      tIntegerArray_idx_vc2; --kdande; Bug 6881902; 11-Mar-2008
7474   v_OptionsUsed       tIntegerArray;
7475   v_StartOptionsUsed  tIntegerArray;
7476   v_EndOptionsUsed    tIntegerArray;
7477   v_ExcludesRequired  tIntegerArray;
7478   v_RowLinesIndex     tIntegerArray;
7479   v_RowLines          tStringArray;
7480   v_tailRowLines      tStringArray;
7481   v_ItemLines         tStringArray;
7482   itemIndex           PLS_INTEGER;
7483   itemCount           PLS_INTEGER := 1;
7484   startCount          PLS_INTEGER;
7485   nChild              PLS_INTEGER;
7486   localString         VARCHAR2(25);
7487   localNumber         PLS_INTEGER;
7488 ---------------------------------------------------------------------------------------
7489 FUNCTION OPTION_EXISTS(nIndex IN PLS_INTEGER) RETURN PLS_INTEGER IS
7490 BEGIN
7491   FOR j IN v_StartOptionsUsed(nIndex)..v_EndOptionsUsed(nIndex) LOOP
7492    IF(v_OptionsUsed(j) = glPsNodeId(nChild))THEN RETURN 1; END IF;
7493   END LOOP;
7494  RETURN 0;
7495 END;
7496 ---------------------------------------------------------------------------------------
7497 --This procedure implements a version of QuickSort algorythm which sorts not the array
7498 --itself, but the array of pointers instead
7499 
7500 PROCEDURE SORT_ARRAY_INDEX(indexStart IN PLS_INTEGER, indexEnd IN PLS_INTEGER) IS
7501   localStart  PLS_INTEGER;
7502   localEnd    PLS_INTEGER;
7503   localSwap   PLS_INTEGER;
7504   RowLine     VARCHAR2(4000);
7505 BEGIN
7506 
7507   IF(indexStart >= indexEnd)THEN RETURN; END IF;
7508 
7509   localStart := indexStart;
7510   localEnd := indexEnd;
7511   RowLine := v_tailRowLines(v_RowLinesIndex((localStart + localEnd) / 2));
7512 
7513   WHILE(localStart < localEnd)LOOP
7514 
7515     WHILE(localStart < localEnd AND v_tailRowLines(v_RowLinesIndex(localStart)) < RowLine) LOOP
7516       localStart := localStart + 1;
7517     END LOOP;
7518 
7519     WHILE(localStart < localEnd AND v_tailRowLines(v_RowLinesIndex(localEnd)) > RowLine) LOOP
7520       localEnd := localEnd - 1;
7521     END LOOP;
7522 
7523     IF(localStart < localEnd)THEN
7524       localSwap := v_RowLinesIndex(localStart);
7525       v_RowLinesIndex(localStart) := v_RowLinesIndex(localEnd);
7526       v_RowLinesIndex(localEnd) := localSwap;
7527     END IF;
7528 
7529     localStart := localStart + 1;
7530     localEnd := localEnd - 1;
7531 
7532   END LOOP;
7533 
7534   IF(localEnd < localStart)THEN
7535     localSwap := localEnd;
7536     localEnd := localStart;
7537     localStart := localSwap;
7538   END IF;
7539 
7540   SORT_ARRAY_INDEX(indexStart, localStart);
7541   IF(localStart = indexStart)THEN localStart := localStart + 1; END IF;
7542   SORT_ARRAY_INDEX(localStart, indexEnd);
7543 END;
7544 ---------------------------------------------------------------------------------------
7545 BEGIN
7546 
7547 nDebug := 5000200;
7548 
7549   FOR i IN 1..vGridColumns.COUNT LOOP --Validation and initial data for features
7550 
7551 nDebug := 5000201;
7552 
7553     IF(i = 1)THEN
7554 
7555       --Read the list of participating options of the primary feature. Make a copy of the list
7556       --for the rule verification purposes (bug #2257421).
7557 
7558        SELECT primary_opt_id, primary_opt_id BULK COLLECT INTO v_tOptionId, v_tPrimaryOptId
7559        FROM cz_des_chart_cells
7560        WHERE rule_id = nRuleId
7561          AND secondary_feature_id = vGridColumns(2)
7562          AND secondary_feat_expl_id = v_tExplNodeId(vBackIndex(2))
7563          AND deleted_flag = FLAG_NOT_DELETED
7564        ORDER BY 1, 2;
7565 
7566        IF(v_tOptionId.COUNT = 0)THEN
7567 
7568        --The previous query returned no rows. That means that there're no selections made for
7569        --any of the primary feature options. It's OK if we are processing an optional table,
7570        --but for the defining table we raise an exception.
7571 
7572          IF(inSuffix = 0)THEN --we are processing the defining table
7573            RAISE CZ_R_NO_DEFINING_SELECTION;
7574          END IF;
7575 
7576        --This is an optional table with no selections - don't generate the COMBO, just generate
7577        --an EXCLUDE relation and exit the procedure.
7578 
7579          vLogicLine := 'GS E ... ' || TO_CHAR(nReasonId) || NewLine ||
7580                        'GL N ' || GENERATE_NAME(vBackIndex(1), vGridColumns(1)) || NewLine ||
7581                        'GR L ' || GENERATE_NAME(vBackIndex(2), vGridColumns(2)) || NewLine;
7582          PACK;
7583          RETURN;
7584 
7585        END IF;
7586 
7587     ELSE
7588 
7589 nDebug := 5000202;
7590 
7591       v_tOptionId.DELETE;
7592       v_tPrimaryId.DELETE;
7593       v_OptionExists.DELETE;
7594 
7595       --Read the list of participating options of defining or optional feature.
7596 
7597       SELECT secondary_opt_id, primary_opt_id BULK COLLECT INTO v_tOptionId, v_tPrimaryId
7598       FROM cz_des_chart_cells
7599       WHERE rule_id = nRuleId
7600         AND secondary_feature_id = vGridColumns(i)
7601         AND secondary_feat_expl_id = v_tExplNodeId(vBackIndex(i))
7602         AND deleted_flag = FLAG_NOT_DELETED
7603       ORDER BY primary_opt_id;
7604 
7605       FOR n IN 1..v_tOptionId.COUNT LOOP
7606 
7607         IF(NOT glIndexByPsNodeId.EXISTS(v_tPrimaryId(n)))THEN
7608 
7609           BEGIN
7610             SELECT name INTO errorMessage FROM cz_ps_nodes
7611              WHERE ps_node_id = v_tPrimaryId(n);
7612           EXCEPTION
7613             WHEN OTHERS THEN
7614               errorMessage := 'Unknown';
7615           END;
7616 
7617           RAISE CZ_R_DELETED_OPTION;
7618         END IF;
7619 
7620         --Bug #2257421. The list of corresponding primary options which participate in the rule should be
7621         --equal for all defining features.
7622         --v_tPrimaryOptId - the ordered list of primary options checked for the first defining feature.
7623         --v_tPrimaryId - the ordered list of primary options checked for the current feature.
7624 
7625         IF((NOT v_tPrimaryOptId.EXISTS(n)) OR (v_tPrimaryOptId(n) > v_tPrimaryId(n)))THEN
7626 
7627            --Too many selections made.
7628 
7629            auxCount := glIndexByPsNodeId(vGridColumns(1));
7630            auxIndex := glIndexByPsNodeId(v_tPrimaryId(n));
7631            RAISE CZ_R_INCOMPLETE_DES_CHART;
7632 
7633         ELSIF(v_tPrimaryOptId(n) < v_tPrimaryId(n))THEN
7634 
7635            --Too few selections made.
7636 
7637            auxCount := glIndexByPsNodeId(vGridColumns(1));
7638            auxIndex := glIndexByPsNodeId(v_tPrimaryOptId(n));
7639            RAISE CZ_R_INCOMPLETE_DES_CHART;
7640         END IF;
7641       END LOOP;
7642 
7643       IF(v_tPrimaryOptId.EXISTS(v_tOptionId.COUNT + 1))THEN
7644 
7645            --Too few selections made.
7646 
7647            auxCount := glIndexByPsNodeId(vGridColumns(1));
7648            auxIndex := glIndexByPsNodeId(v_tPrimaryOptId(v_tOptionId.COUNT + 1));
7649            RAISE CZ_R_INCOMPLETE_DES_CHART;
7650       END IF;
7651     END IF;
7652 
7653     startCount := itemCount;
7654 
7655     FOR n IN 1..v_tOptionId.COUNT LOOP
7656 
7657       --Make sure the option exists.
7658 
7659       IF(NOT glIndexByPsNodeId.EXISTS(v_tOptionId(n)))THEN
7660 
7661         BEGIN
7662           SELECT name INTO errorMessage FROM cz_ps_nodes
7663            WHERE ps_node_id = v_tOptionId(n);
7664         EXCEPTION
7665           WHEN OTHERS THEN
7666             errorMessage := 'Unknown';
7667         END;
7668 
7669         RAISE CZ_R_DELETED_OPTION;
7670       END IF;
7671 
7672       IF(NOT v_OptionExists.EXISTS(v_tOptionId(n)))THEN
7673 
7674 nDebug := 5000203;
7675 
7676        v_ItemLines(itemCount) := GENERATE_NAME(vBackIndex(i), v_tOptionId(n)) || ' ' || TO_CHAR(i - 1);
7677        v_OptionsUsed(itemCount) := v_tOptionId(n);
7678        v_OptionExists(v_tOptionId(n)) := itemCount;
7679        itemCount := itemCount + 1;
7680 
7681       END IF;
7682 
7683 nDebug := 5000204;
7684 
7685       itemIndex := v_OptionExists(v_tOptionId(n));
7686       v_RowLinesIndex(n) := n;
7687 
7688       IF(v_RowLines.EXISTS(n))THEN
7689         v_RowLines(n) := v_RowLines(n) || ' ' || TO_CHAR(itemIndex - 1);
7690       ELSE
7691         v_RowLines(n) := ' ' || TO_CHAR(itemIndex - 1);
7692       END IF;
7693 
7694     END LOOP;
7695 
7696     v_ExcludesRequired(i) := 0;
7697 
7698 nDebug := 5000205;
7699 
7700     IF(featOptionsCount(vGridColumns(i)) <> itemCount - startCount)THEN
7701 
7702       v_StartOptionsUsed(i) := startCount;
7703       v_EndOptionsUsed(i) := itemCount - 1;
7704       v_ExcludesRequired(i) := 1;
7705 
7706     END IF;
7707   END LOOP; --Validation and initial data for features
7708 
7709   --Design chart rule specific validation - uniqueness of every column in the chart table.
7710   --At the current step this requirement is equivalent to the requirement of no duplicate
7711   --elements in v_RowLines table. We use the modified QuickSort algorythm to sort out the
7712   --table and then check for duplicate values in one pass.
7713 
7714   IF(inSuffix = 0)THEN --This is the defining table
7715 
7716    --We need a substring of the row starting with the 4th character
7717 
7718    FOR i IN 1..v_RowLines.COUNT LOOP
7719     v_tailRowLines(i) := SUBSTR(v_RowLines(i),4);
7720    END LOOP;
7721 
7722    SORT_ARRAY_INDEX(1, v_tailRowLines.COUNT);
7723    FOR i IN 2..v_tailRowLines.COUNT LOOP
7724     IF(v_tailRowLines(v_RowLinesIndex(i)) = v_tailRowLines(v_RowLinesIndex(i - 1)))THEN
7725 
7726       --Duplicate combination of defining options for a primary option
7727       RAISE CZ_R_DUPLICATE_COMBINATION;
7728 
7729     END IF;
7730    END LOOP;
7731   END IF; --This is the defining table
7732 
7733 nDebug := 5000206;
7734 
7735   FOR i IN 1..vGridColumns.COUNT LOOP
7736 
7737 nDebug := 5000207;
7738 
7739     IF(v_ExcludesRequired(i) = 1)THEN
7740 
7741      nChild := glIndexByPsNodeId(vGridColumns(i)) + 1;
7742 
7743      vLogicLine := 'GS E ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N ';
7744      PACK;
7745 
7746 nDebug := 5000208;
7747 
7748      WHILE(glParentId.EXISTS(nChild) AND glParentId(nChild) = vGridColumns(i))LOOP
7749       IF(OPTION_EXISTS(i) = 0)THEN
7750         vLogicLine := GENERATE_NAME(vBackIndex(i), glPsNodeId(nChild)) || ' ';
7751         PACK;
7752       END IF;
7753       nChild := nChild + 1;
7754      END LOOP;
7755 
7756      vLogicLine := NewLine || 'GR L ';
7757      PACK;
7758 
7759 nDebug := 5000209;
7760 
7761      FOR n IN 1..vGridColumns.COUNT LOOP
7762        IF(n <> i)THEN
7763          vLogicLine := GENERATE_NAME(vBackIndex(n), vGridColumns(n)) || ' ';
7764          PACK;
7765        END IF;
7766      END LOOP;
7767 
7768      vLogicLine := NewLine;
7769      PACK;
7770     END IF; --Excludes required
7771   END LOOP;
7772 
7773 nDebug := 5000210;
7774 
7775   vLogicLine := 'OBJECT P_R' || TO_CHAR(nRuleId) || '_' || TO_CHAR(inSuffix) || NewLine ||
7776                 'COMBO P_R' || TO_CHAR(nRuleId) || '_' || TO_CHAR(inSuffix) || ' ' || TO_CHAR(v_ItemLines.COUNT) || ' ' ||
7777                 TO_CHAR(v_RowLines.COUNT) || ' ' || TO_CHAR(vGridColumns.COUNT) || ' ... ' ||
7778                 TO_CHAR(nReasonId) || NewLine;
7779   PACK;
7780 
7781 nDebug := 5000211;
7782 
7783   FOR i IN 1..v_ItemLines.COUNT LOOP
7784 
7785     vLogicLine := 'CI ' || TO_CHAR(i - 1) || ' ' || v_ItemLines(i) || NewLine;
7786     PACK;
7787 
7788   END LOOP;
7789 
7790 nDebug := 5000212;
7791 
7792   FOR i IN 1..vGridColumns.COUNT LOOP
7793 
7794     IF(GenerateGatedCombo = 0)THEN
7795 
7796       IF(inSuffix = 0 OR i = 1)THEN
7797 
7798         --This is the defining table or the primary feature in an optional table.
7799         --In this case we currently use actual feature's maximum value for the column
7800         --(or maximum_selected for BOM).
7801 
7802         --Use intermediate variable instead of using NVL because this is faster
7803 
7804         localNumber := glIndexByPsNodeId(vGridColumns(i));
7805         localString := TO_CHAR(glMaximum(localNumber));
7806 
7807         --If it's a BOM item, we use maximum_selected instead of maximum
7808 
7809         IF(glPsNodeType(localNumber) IN (PS_NODE_TYPE_BOM_MODEL,PS_NODE_TYPE_BOM_OPTIONCLASS,PS_NODE_TYPE_BOM_STANDARD))THEN
7810          localString := TO_CHAR(glMaximumSel(localNumber));
7811         END IF;
7812 
7813         IF(localString IS NULL)THEN localString := '-1'; END IF;
7814 
7815       ELSE
7816         --For optional features in optional tables we always use '-1' for columns' maximum value.
7817 
7818         localString := '-1';
7819       END IF;
7820 
7821       vLogicLine := ' O';
7822     ELSE
7823 
7824       --Generate gated combinations: maximum is always -1, the 'G' argument is followed
7825       --by the feature name.
7826 
7827       localString := '-1';
7828       vLogicLine := ' G ' || GENERATE_NAME(vBackIndex(i), vGridColumns(i));
7829     END IF;
7830 
7831     vLogicLine := 'CC ' || TO_CHAR(i - 1) || ' 0 ' || localString || vLogicLine || NewLine;
7832     PACK;
7833 
7834   END LOOP;
7835 
7836 nDebug := 5000213;
7837 
7838   FOR i IN 1..v_RowLines.COUNT LOOP
7839 
7840     vLogicLine := 'CR ' || TO_CHAR(i - 1) || v_RowLines(i) || NewLine;
7841     PACK;
7842 
7843   END LOOP;
7844 
7845 nDebug := 5000214;
7846 
7847   vLogicLine := 'COMBO_END' || NewLine;
7848   PACK;
7849 END;
7850 ---------------------------------------------------------------------------------------
7851 BEGIN
7852 
7853   --Generate the defining table
7854 
7855   nIndex := 2;
7856 
7857   FOR i IN expressionStart..expressionEnd LOOP
7858 
7859     IF(v_tFeatureType(i) = FEATURE_TYPE_DEFINING)THEN
7860       vGridColumns(nIndex) := v_tExprPsNodeId(i);
7861       vBackIndex(nIndex) := i;
7862       nIndex := nIndex + 1;
7863     ELSIF(v_tFeatureType(i) = FEATURE_TYPE_PRIMARY)THEN
7864       vGridColumns(1) := v_tExprPsNodeId(i);
7865       vBackIndex(1) := i;
7866     END IF;
7867 
7868   END LOOP;
7869 
7870   IF(vGridColumns.COUNT = 0)THEN
7871     RAISE CZ_R_NO_PRIMARY_FEATURE;
7872   ELSIF(vGridColumns.COUNT > 1)THEN
7873     GENERATE_COMPAT_TEMPLATE(0);
7874     vGridColumns.DELETE(2, vGridColumns.COUNT);
7875     vBackIndex.DELETE(2, vBackIndex.COUNT);
7876   END IF;
7877 
7878   --Generate all the optional tables
7879 
7880   nIndex := 1;
7881 
7882   FOR i IN expressionStart..expressionEnd LOOP
7883 
7884     IF(v_tFeatureType(i) = FEATURE_TYPE_OPTIONAL)THEN
7885       vGridColumns(2) := v_tExprPsNodeId(i);
7886       vBackIndex(2) := i;
7887       GENERATE_COMPAT_TEMPLATE(nIndex);
7888       nIndex := nIndex + 1;
7889     END IF;
7890 
7891   END LOOP;
7892 END;
7893 ---------------------------------------------------------------------------------------
7894 BEGIN --GENERATE_RULES
7895 
7896 nDebug := 0;
7897 
7898   IF(t_RuleId.COUNT = 0)THEN
7899 
7900     --This should be done only once during the generation session. The data is static and common
7901     --to all models.
7902 
7903     SELECT rule_id, signature_id, name BULK COLLECT INTO t_RuleId, t_SignatureId, t_RuleName
7904       FROM cz_rules
7905      WHERE devl_project_id = 0
7906        AND seeded_flag = FLAG_SEEDED
7907        AND deleted_flag = FLAG_NOT_DELETED
7908        AND disabled_flag = FLAG_NOT_DISABLED;
7909 
7910     --Make the table of names hashed by rule_id.
7911 
7912     FOR i IN 1..t_RuleId.COUNT LOOP
7913 
7914       h_SeededName(t_RuleId(i)) := UPPER(t_RuleName(i));
7915       h_ReportName(t_RuleId(i)) := t_RuleName(i);
7916       h_SignatureId(t_RuleId(i)) := t_SignatureId(i);
7917     END LOOP;
7918   END IF;
7919 
7920 nDebug := 1;
7921 
7922   --Make a quick and simple verification of all functional companions defined in this
7923   --project. All other rule related instances that do not reside in cz_rules can also
7924   --be processed in this section.
7925   --Added as a fix for the bug #2200481.
7926 
7927   --Restoring this block in 11.5.10+, bug #3989382.
7928 
7929   FOR c_func IN (SELECT component_id, model_ref_expl_id, program_string, name, rule_folder_id
7930                    FROM cz_func_comp_specs
7931                   WHERE devl_project_id = inComponentId
7932                     AND deleted_flag = FLAG_NOT_DELETED) LOOP
7933 
7934     IF(c_func.component_id IS NULL)THEN
7935 
7936       --'Incomplete data: No base component specified for functional companion ''%COMPANION'' in model ''%MODELNAME''.'
7937       REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_FC_BASE_COMPONENT', 'COMPANION', COMPANION_NAME(c_func.name, c_func.rule_folder_id), 'MODELNAME', glName(glIndexByPsNodeId(inComponentId))), 1);
7938 
7939     ELSIF(c_func.program_string IS NULL)THEN
7940 
7941       --'Incomplete data: No program string specified for functional companion ''%COMPANION'' in model ''%MODELNAME''.'
7942       REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_FC_PROGRAM_STRING', 'COMPANION', COMPANION_NAME(c_func.name, c_func.rule_folder_id), 'MODELNAME', glName(glIndexByPsNodeId(inComponentId))), 1);
7943 
7944     ELSIF(NOT glIndexByPsNodeId.EXISTS(c_func.component_id))THEN
7945 
7946       --'Internal data error. Incorrect product structure data for functional companion ''%COMPANION'' in model ''%MODELNAME''.'
7947       REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_INCORRECT_COMPONENT', 'COMPANION', COMPANION_NAME(c_func.name, c_func.rule_folder_id), 'MODELNAME', glName(glIndexByPsNodeId(inComponentId))), 1);
7948 
7949     ELSIF(c_func.model_ref_expl_id IS NULL OR (NOT v_IndexByNodeId.EXISTS(c_func.model_ref_expl_id)))THEN
7950 
7951       --'Internal data error. Incorrect explosion data for functional companion ''%COMPANION'' in model ''%MODELNAME''.'
7952       REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_INCORRECT_EXPLOSION', 'COMPANION', COMPANION_NAME(c_func.name, c_func.rule_folder_id), 'MODELNAME', glName(glIndexByPsNodeId(inComponentId))), 1);
7953     END IF;
7954   END LOOP;
7955 
7956   --Calculate downpathes for all explosion nodes here
7957 
7958 nDebug := 1000007;
7959 
7960   FOR i IN 1..v_NodeId.COUNT LOOP
7961 
7962 nDebug := 1000002;
7963 
7964    --Unconditionally create rule files for all the non-virtual components of the
7965    --model primary structure and all first-level reference nodes and put the INC
7966    --relation there.
7967 
7968     IF(v_tVirtualFlag(i) = FLAG_NON_VIRTUAL AND v_tNodeDepth(i) > 0 AND
7969        (v_tChildModelExpl(i) IS NULL OR
7970         (v_tNodeType(i) = PS_NODE_TYPE_REFERENCE AND
7971          v_tChildModelExpl(v_IndexByNodeId(v_tParentId(i))) IS NULL)
7972        ))THEN
7973 
7974 nDebug := 1000003;
7975 
7976      nHeaderId := next_lce_header_id;
7977 
7978      BEGIN
7979 
7980 nDebug := 1000004;
7981 
7982       --Insert the rule net logic header record into the table.
7983 
7984       INSERT INTO cz_lce_headers
7985        (lce_header_id, gen_version, gen_header, component_id, net_type,
7986         devl_project_id, model_ref_expl_id, nbr_required_expls, deleted_flag)
7987       VALUES
7988        (nHeaderId, VersionString, GenHeader, v_tPsNodeId(i), LOGIC_NET_TYPE_MANDATORY,
7989         thisProjectId, v_NodeId(i), 1, FLAG_PENDING);
7990 
7991       INSERT INTO cz_lce_load_specs
7992        (attachment_expl_id, lce_header_id, required_expl_id, attachment_comp_id,
7993         model_id, net_type, deleted_flag)
7994       VALUES
7995        (v_NodeId(i), nHeaderId, v_NodeId(i), v_tPsNodeId(i), thisProjectId,
7996         LOGIC_NET_TYPE_MANDATORY, FLAG_PENDING);
7997 
7998       EXCEPTION
7999         WHEN OTHERS THEN
8000           errorMessage := SQLERRM;
8001           RAISE CZ_R_UNABLE_TO_CREATE_HEADER;
8002       END;
8003 
8004 nDebug := 1000005;
8005 
8006       NewHeaders(counterNewHeaders) := nHeaderId;
8007       NewHeadersComponents(counterNewHeaders) := v_tPsNodeId(i);
8008       NewHeadersExplosions(counterNewHeaders) := v_NodeId(i);
8009       counterNewHeaders := counterNewHeaders + 1;
8010 
8011 nDebug := 1000006;
8012 
8013       --Use intermediate variable instead of using NVL because this is faster
8014 
8015       IF(v_tReferringId(i) IS NOT NULL)THEN
8016        localString := TO_CHAR(glPersistentId(v_tReferringId(i)));
8017       ELSE
8018        localString := TO_CHAR(glPersistentId(v_tPsNodeId(i)));
8019       END IF;
8020 
8021       vLogicLine := 'CONTROL NOSPEC' || NewLine || 'VERSION 3 3' || NewLine || NewLine ||
8022                     'REM -- Rules file for component: ' || TO_CHAR(v_tPsNodeId(i)) ||
8023                     ', explosion node: ' || TO_CHAR(v_NodeId(i)) || NewLine || NewLine ||
8024                     'EFF , , ' || NewLine || NewLine ||
8025                     'INC 1 ' || PATH_DELIMITER || 'parent' || PATH_DELIMITER || 'P_' ||
8026                     localString || '_ACTUALCOUNT round' || NewLine;
8027 
8028       INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES (nHeaderId, 1, vLogicLine);
8029 
8030       v_tIsHeaderGenerated(v_NodeId(i)) := nHeaderId;
8031       v_tSequenceNbr(nHeaderId) := 2;
8032       v_tLogicNetType(nHeaderId) := LOGIC_NET_TYPE_MANDATORY;
8033 
8034       --This variable is not supposed to be used as an accumulator for logic text. Instead,  it
8035       --is used as a buffer every time to store a piece of text to be accumulated in vLogicText
8036       --(see PACK procedure). Therefore, it should be safe to null it out here even if it's not
8037       --necessary.
8038 
8039       vLogicLine := NULL;
8040     END IF;
8041 
8042 nDebug := 1000008;
8043 
8044     --Here we will construct model level downpaths, which do not depend on a particular rule,
8045     --but only on explosion id within the model's explosion tree. When a particular rule is
8046     --assigned, downpaths of its participants may be prepended with segments including all A
8047     --type nodes from assignee to assignable. This corrected downpaths are always used when
8048     --generating names of the rule's participants.
8049 
8050     nAux := v_NodeId(i);
8051     auxIndex := v_tNodeDepth(i) + 1;
8052 
8053     IF(NOT v_NodeDownPath.EXISTS(nAux))THEN
8054 
8055 nDebug := 1000009;
8056 
8057       v_NodeDownPath(nAux) := ''; --start building the downpath
8058       v_NodeIndexPath.DELETE; --reset the table
8059 
8060       --These all are index values in v_NodeIndexPath.
8061 
8062       ConnectorIndex := 0;
8063       InstantiableIndex := auxIndex;
8064       OptionalIndex := auxIndex;
8065       TrackableIndex := auxIndex;
8066       nCounter := 1;
8067       auxCount := 0;
8068 
8069       --Go all the way up from the explosion id and find the deepest D node and the
8070       --shallowest connector, and also the deepest optional node.
8071       --We are interested in the shallowest reference to a trackable model as well.
8072       --It will be used only if the root model is marked as a network container. If
8073       --there is no such reference above the explosion node the root node is used.
8074 
8075       WHILE(nAux IS NOT NULL) LOOP
8076 
8077         localCount := v_IndexByNodeId(nAux);
8078 
8079         --Detect infinite loops which may be caused by data corruption.
8080 
8081         auxCount := auxCount + 1;
8082         IF(auxCount > LOOP_DETECTED_LOOPS_NUMBER)THEN
8083 
8084           errorMessage := glName(glIndexByPsNodeId(inProjectId));
8085           RAISE CZ_G_INVALID_MODEL_EXPLOSION;
8086         END IF;
8087 
8088         --The next IF statement has been added as a fix for the bug #2802049. In case of circular
8089         --connectors it is possible that the explosion table of the second level-referenced model
8090         --contains pointers to ps node structure of the parent model that hasn't been read yet.
8091         --As in this case we do not need to generate downpaths, we can just ignore such pointers.
8092 
8093         IF(NOT glIndexByPsNodeId.EXISTS(NVL(v_tReferringId(localCount), v_tPsNodeId(localCount))))THEN
8094 
8095           auxCount := -1;
8096           EXIT;
8097         END IF;
8098 
8099         IF(v_TypeByExplId(nAux) = EXPL_NODE_TYPE_CONNECTOR)THEN
8100 
8101           ConnectorIndex := nCounter;
8102         ELSIF(v_TypeByExplId(nAux) = EXPL_NODE_TYPE_OPTIONAL AND OptionalIndex = auxIndex)THEN
8103 
8104           OptionalIndex := nCounter;
8105         ELSIF(v_TypeByExplId(nAux) = EXPL_NODE_TYPE_INSTANTIABLE)THEN
8106 
8107           IF(InstantiableIndex = auxIndex)THEN InstantiableIndex := nCounter; END IF;
8108 
8109           IF(v_tNodeType(localCount) = PS_NODE_TYPE_REFERENCE AND
8110              glIbTrackable(v_tPsNodeId(localCount)) = FLAG_IB_TRACKABLE)THEN
8111 
8112              TrackableIndex := nCounter;
8113           END IF;
8114         END IF;
8115 
8116        v_NodeIndexPath(nCounter) := localCount;
8117        nCounter := nCounter + 1;
8118 
8119        nAux := v_tParentId(localCount);
8120       END LOOP;
8121 
8122       IF(auxCount = -1)THEN
8123 
8124         --This is the 'circular connectors' case, we don't need any downpath.
8125         NULL;
8126 
8127       ELSIF(InstantiableIndex < ConnectorIndex)THEN
8128 
8129         --There are D nodes under connectors on the path - this explosion cannot participate
8130         --in any rule because it would be impossible to assign such a rule. No downpath.
8131         --For reporting purposes store the cz_ps_nodes indexes of the instantiable component
8132         --and the connector, corresponding exception/message is CZ_R_UNASSIGNABLE_RULE.
8133 
8134         v_ProhibitInRules(v_NodeId(i)) := glIndexByPsNodeId(v_tPsNodeId(v_NodeIndexPath(InstantiableIndex)));
8135         v_ProhibitConnector(v_NodeId(i)) := glIndexByPsNodeId(v_tReferringId(v_NodeIndexPath(ConnectorIndex)));
8136 
8137       ELSIF(OptionalIndex < ConnectorIndex)THEN
8138 
8139         --There are A nodes under connectors on the path - this explosion cannot participate
8140         --in any rule - bug #2217450. No downpath.
8141         --For reporting purposes store the cz_ps_nodes indexes of the optional component
8142         --and the connector, corresponding exception/message is CZ_R_OPTIONAL_INSIDE.
8143 
8144         v_ProhibitOptional(v_NodeId(i)) := glIndexByPsNodeId(v_tPsNodeId(v_NodeIndexPath(OptionalIndex)));
8145         v_ProhibitConnector(v_NodeId(i)) := glIndexByPsNodeId(v_tReferringId(v_NodeIndexPath(ConnectorIndex)));
8146 
8147       ELSE
8148 
8149 nDebug := 1000010;
8150 
8151         AssignableIndex := InstantiableIndex;
8152 
8153         --Find the deepest A node between the deepest D node and the shallowest connector.
8154         --This node is the assignable for the explosion id (can be the D node itself).
8155 
8156         FOR n IN ConnectorIndex + 1..InstantiableIndex LOOP
8157           IF(v_tExplNodeType(v_NodeIndexPath(n)) = EXPL_NODE_TYPE_OPTIONAL)THEN
8158 
8159             AssignableIndex := n;
8160             EXIT;
8161           END IF;
8162         END LOOP;
8163 
8164         v_NodeLogicLevel(v_NodeId(i)) := v_tNodeDepth(v_NodeIndexPath(AssignableIndex));
8165 
8166         --Store the main index of the assignable of the explosion node.
8167 
8168         v_NodeAssignable(v_NodeId(i)) := v_NodeIndexPath(AssignableIndex);
8169 
8170         --Store the main index of the deepest instantiable component above the explosion
8171         --node (may be the node itself if it is instantiable, or the root node if there
8172         --is no instantiable components on the way up from the explosion node).
8173 
8174         v_NodeInstantiable(v_NodeId(i)) := v_NodeIndexPath(InstantiableIndex);
8175 
8176         --Store the main index of the shallowest reference to a trackable model.
8177 
8178         v_NodeTrackable(v_NodeId(i)) := v_NodeIndexPath(TrackableIndex);
8179 
8180 nDebug := 1000011;
8181 
8182         --Finally, construct the downpath from the assignable to the explosion id.
8183 
8184         FOR n IN 1..AssignableIndex - 1 LOOP
8185           IF(v_tExplNodeType(v_NodeIndexPath(n)) IN (EXPL_NODE_TYPE_OPTIONAL, EXPL_NODE_TYPE_MANDATORY))THEN
8186 
8187            --This is a mandatory reference or optional component, add N_<persistent_node_id>
8188            --to the path.
8189 
8190            v_NodeDownPath(v_NodeId(i)) := PATH_DELIMITER || 'N_' ||
8191              TO_CHAR(glPersistentId(NVL(v_tReferringId(v_NodeIndexPath(n)), v_tPsNodeId(v_NodeIndexPath(n))))) ||
8192              v_NodeDownPath(v_NodeId(i));
8193 
8194           ELSIF(v_tExplNodeType(v_NodeIndexPath(n)) = EXPL_NODE_TYPE_CONNECTOR)THEN
8195 
8196            --This is a connector, add C_<model_ref_expl_id> to the path.
8197 
8198            v_NodeDownPath(v_NodeId(i)) := PATH_DELIMITER || 'C_' ||
8199              TO_CHAR(v_NodeId(v_NodeIndexPath(n))) || v_NodeDownPath(v_NodeId(i));
8200 
8201            --We will stop here, we do not want anything above the deepest connector to be reflected
8202            --in the path. Set a flag for this explosion because we do not want to prepend downpaths
8203            --for these explosions after the rule is assigned either. Actually, not just a flag, but
8204            --store the connector itself (main index) which may be useful for reporting purposes.
8205 
8206            v_IsConnectorNet(v_NodeId(i)) := v_NodeIndexPath(n);
8207            EXIT;
8208           END IF;
8209         END LOOP;
8210       END IF;
8211     END IF;
8212   END LOOP;
8213 
8214 nDebug := 2;
8215 
8216   OPEN c_rules;
8217   LOOP
8218   BEGIN
8219 
8220     --To generate effectivity information for the first rule. Uses the fact that
8221     --effective mask can not be null.
8222 
8223     vUsageMask := NULL;
8224 
8225     FETCH c_rules INTO
8226      nRuleId, nRuleType, nAntecedentId, nConsequentId, vRuleName, nReasonId, nRuleOperator,
8227      nRuleFolderId, nComponentId, nModelRefExplId, dEffFrom, dEffUntil, vUsageMask,
8228      nRuleEffSetId, nUnsatisfiedId, nUnsatisfiedSource, nPresentationFlag, vClassName;
8229     EXIT WHEN c_rules%NOTFOUND;
8230 
8231    --Do nothing for those rules.
8232 
8233   --Fix for the bug6502787
8234     IF(nRuleEffSetId IS NOT NULL)THEN
8235           IF(gvIndexBySetId.EXISTS(nRuleEffSetId))THEN
8236 
8237        nDebug := 111111;
8238               dEffFrom := gvEffFrom(gvIndexBySetId(nRuleEffSetId));
8239               dEffUntil := gvEffUntil(gvIndexBySetId(nRuleEffSetId));
8240           ELSE
8241          --This is a fatal error - data corruption
8242                RAISE CZ_R_WRONG_EFFECTIVITY_SET;
8243           END IF;
8244     END IF;
8245 
8246    IF(nRuleType NOT IN (RULE_TYPE_FUNC_COMP, RULE_TYPE_RULE_FOLDER, RULE_TYPE_BINDING_RULE,
8247                         RULE_TYPE_RULE_SYS_PROP, RULE_TYPE_JAVA_SYS_PROP,
8248                         RULE_TYPE_CAPTION_RULE, RULE_TYPE_DISPLAY_CONDITION))THEN
8249 
8250     v_tExplNodeId.DELETE;
8251     v_tExprType.DELETE;
8252     v_tExprSubtype.DELETE;
8253     v_tExprId.DELETE;
8254     v_tExprParentId.DELETE;
8255     v_tExprTemplateId.DELETE;
8256     v_tExpressId.DELETE;
8257     v_tExprPsNodeId.DELETE;
8258     v_tRealPsNodeId.DELETE;
8259     v_tExprDataValue.DELETE;
8260     v_tExprPropertyId.DELETE;
8261     v_tConsequentFlag.DELETE;
8262     v_tExprParamIndex.DELETE;
8263     v_tExprArgumentName.DELETE;
8264     v_tExprDataType.DELETE;
8265     v_tExprDataNumValue.DELETE;
8266     v_tExprArgSignature.DELETE;
8267     v_tExprParSignature.DELETE;
8268     v_tArgumentIndex.DELETE;
8269     v_tDataType.DELETE;
8270     v_tArgumentName.DELETE;
8271     v_InstByLevel.DELETE;
8272     v_Assignable.DELETE;
8273     v_Participant.DELETE;
8274     v_DistinctIndex.DELETE;
8275     v_ParticipantIndex.DELETE;
8276     v_RuleConnectorNet.DELETE;
8277     v_LevelCount.DELETE;
8278     v_LevelIndex.DELETE;
8279     v_LevelType.DELETE;
8280     v_MarkLoadCondition.DELETE;
8281     v_LoadConditionId.DELETE;
8282     v_ChildrenIndex.DELETE;
8283     v_NodeUpPath.DELETE;
8284     v_IndexByExprNodeId.DELETE;
8285     v_NumberOfChildren.DELETE;
8286     v_ExplByPsNodeId.DELETE;
8287     v_RelativeNodePath.DELETE;
8288     parameterScope.DELETE;
8289     parameterName.DELETE;
8290 
8291     jAntecedentRoot  := NULL;
8292     jConsequentRoot  := NULL;
8293     sUnsatisfiedId   := NULL;
8294     RuleTemplateType := RULE_TYPE_UNKNOWN;
8295     numericLHS       := 0;
8296     generateCompare  := 0;
8297     t_prefix         := 'T' || TO_CHAR(nRuleId) || '_';
8298 
8299     --We need to reset the assigned down paths for every rule. Bug #3431166.
8300 
8301     FOR i IN 1..v_NodeId.COUNT LOOP
8302 
8303       --Make a copy that will be used as a rule-specific downpath which may have to be prepended
8304       --after the rule is assigned. It is this copy that will be used for name generation.
8305 
8306       v_AssignedDownPath(v_NodeId(i)) := v_NodeDownPath(v_NodeId(i));
8307     END LOOP;
8308 
8309     --Bug #3180819.
8310 
8311     IF(nPresentationFlag IS NULL)THEN nPresentationFlag := FLAG_FREEFORM_RULE; END IF;
8312 
8313 nDebug := 3;
8314 
8315     --Get the rule participants, differently for different types of rules
8316 
8317     IF(nRuleType = RULE_TYPE_JAVA_METHOD)THEN
8318 
8319       --This is a CX. Call the CX validation procedure and continue with rules.
8320 
8321       localRunId := thisRunId;
8322       cz_developer_utils_pvt.verify_special_rule(nRuleId, vRuleName, localRunId);
8323       RAISE CZ_LCE_CONTINUE;
8324 
8325     ELSIF(nRuleType IN (RULE_TYPE_TEMPLATE, RULE_TYPE_EXPRESSION))THEN
8326 
8327       --Set the unsatisfied message id string.
8328 
8329       IF(nUnsatisfiedSource <> UNSATISFIED_TYPE_NONE)THEN
8330 
8331         sUnsatisfiedId := TO_CHAR(nUnsatisfiedId);
8332         IF(sUnsatisfiedId IS NOT NULL)THEN sUnsatisfiedId := sUnsatisfiedId || ' '; END IF;
8333       END IF;
8334 
8335       SELECT model_ref_expl_id, expr_type, expr_node_id, expr_parent_id, template_id,
8336              express_id, expr_subtype, ps_node_id, data_value, property_id, consequent_flag,
8337              param_index, argument_name, data_type, data_num_value, param_signature_id,
8338              relative_node_path
8339       BULK COLLECT INTO v_tExplNodeId, v_tExprType, v_tExprId, v_tExprParentId, v_tExprTemplateId,
8340                         v_tExpressId, v_tExprSubtype, v_tExprPsNodeId, v_tExprDataValue,
8341                         v_tExprPropertyId, v_tConsequentFlag, v_tExprParamIndex, v_tExprArgumentName,
8342                         v_tExprDataType, v_tExprDataNumValue, v_tExprParSignature,
8343                         v_RelativeNodePath
8344        FROM cz_expression_nodes
8345       WHERE rule_id = nRuleId
8346         AND expr_type <> EXPR_NODE_TYPE_PUNCT
8347         AND deleted_flag = FLAG_NOT_DELETED
8348       ORDER BY expr_parent_id, seq_nbr;
8349 
8350      --Determine the size of the expression for all eventual purposes.
8351 
8352      expressionSize := v_tExprType.COUNT;
8353 
8354      IF(expressionSize = 0)THEN
8355        RAISE CZ_R_NO_PARTICIPANTS;
8356      END IF;
8357 
8358      expressionStart := 1;
8359      expressionEnd := expressionSize;
8360 
8361      FOR i IN expressionStart..expressionEnd LOOP
8362 
8363        IF(v_tExprDataNumValue(i) IS NOT NULL)THEN v_tExprDataValue(i) := TO_CHAR(v_tExprDataNumValue(i)); END IF;
8364 
8365        --Bug #3800352. Resolve the codes by names and emulate regular node types.
8366 
8367        IF(v_tExprType(i) IN (EXPR_PROPERTYBYNAME, EXPR_OPERATORBYNAME, EXPR_JAVAPROPERTYBYNAME))THEN
8368 
8369          FOR n IN 1..t_RuleId.COUNT LOOP
8370 
8371            IF(t_RuleName(n) = v_tExprArgumentName(i))THEN v_tExprTemplateId(i) := t_RuleId(n); EXIT; END IF;
8372          END LOOP;
8373 
8374          IF(v_tExprType(i) = EXPR_PROPERTYBYNAME)THEN
8375 
8376            v_tExprType(i) := EXPR_SYS_PROP;
8377          ELSIF(v_tExprType(i) = EXPR_OPERATORBYNAME)THEN
8378 
8379            v_tExprType(i) := EXPR_OPERATOR;
8380          ELSIF(v_tExprType(i) = EXPR_JAVAPROPERTYBYNAME)THEN
8381 
8382            v_tExprType(i) := EXPR_JAVA_PROPERTY;
8383          END IF;
8384        END IF;
8385 
8386        --Populate the expression node subtype from template_id for all expression nodes for backward
8387        --compatibility.
8388 
8389        v_tExprSubtype(i) := v_tExprTemplateId(i);
8390 
8391        --Use the code lookup to fix irregularities in new codes. May become unnecessary when real
8392        --metadata lookup is implemented.
8393 
8394        IF(CodeByCodeLookup.EXISTS(v_tExprTemplateId(i)))THEN
8395 
8396          v_tExprSubtype(i) := CodeByCodeLookup(v_tExprTemplateId(i));
8397          v_tExprTemplateId(i) := v_tExprSubtype(i);
8398        END IF;
8399 
8400        IF(v_tExprParentId(i) IS NOT NULL)THEN
8401 
8402          IF(v_NumberOfChildren.EXISTS(v_tExprParentId(i)))THEN
8403            v_NumberOfChildren(v_tExprParentId(i)) := v_NumberOfChildren(v_tExprParentId(i)) + 1;
8404          ELSE
8405            v_NumberOfChildren(v_tExprParentId(i)) := 1;
8406          END IF;
8407 
8408          IF(NOT v_ChildrenIndex.EXISTS(v_tExprParentId(i)))THEN
8409            v_ChildrenIndex(v_tExprParentId(i)) := i;
8410          END IF;
8411        END IF;
8412 
8413        --If this rule is against max of some component, mark this component as having such a rule.
8414        --Later we will generate INC for this component's actual max.
8415 
8416        IF(v_tExprType(i) = EXPR_SYS_PROP AND h_SeededName.EXISTS(v_tExprSubtype(i)) AND
8417           h_SeededName(v_tExprSubtype(i)) = RULE_SYS_PROP_MAXINSTANCE AND
8418           v_tConsequentFlag(i) = FLAG_IS_CONSEQUENT)THEN
8419 
8420           v_MaxRuleExists(v_tExplNodeId(i)) := 1;
8421        END IF;
8422 
8423        --Add the indexing option.
8424 
8425        v_IndexByExprNodeId(v_tExprId(i)) := i;
8426      END LOOP;
8427 
8428     ELSIF(nRuleType = RULE_TYPE_COMPAT_TABLE)THEN
8429 
8430      --Read all the features
8431 
8432      SELECT model_ref_expl_id, feature_id, EXPR_NODE_TYPE_NODE
8433      BULK COLLECT INTO v_tExplNodeId, v_tExprPsNodeId, v_tExprType
8434      FROM cz_des_chart_features
8435      WHERE rule_id = nRuleId
8436        AND deleted_flag = FLAG_NOT_DELETED;
8437 
8438 nDebug := 32;
8439 
8440      --Determine the size of the expression for all eventual purposes.
8441 
8442      expressionSize := v_tExprType.COUNT;
8443 
8444      IF(expressionSize < 2)THEN
8445        RAISE CZ_R_NO_PARTICIPANTS;
8446      END IF;
8447 
8448      expressionStart := 1;
8449      expressionEnd := expressionSize;
8450 
8451     ELSIF(nRuleType = RULE_TYPE_DESIGNCHART_RULE)THEN
8452 
8453      --Read all the features
8454 
8455      SELECT model_ref_expl_id, feature_id, feature_type, EXPR_NODE_TYPE_NODE
8456      BULK COLLECT INTO v_tExplNodeId, v_tExprPsNodeId, v_tFeatureType, v_tExprType
8457      FROM cz_des_chart_features
8458      WHERE rule_id = nRuleId
8459        AND deleted_flag = FLAG_NOT_DELETED;
8460 
8461 nDebug := 34;
8462 
8463      --Determine the size of the expression for all eventual purposes.
8464 
8465      expressionSize := v_tExprType.COUNT;
8466 
8467      IF(expressionSize < 2)THEN
8468        RAISE CZ_R_NO_PARTICIPANTS;
8469      END IF;
8470 
8471      expressionStart := 1;
8472      expressionEnd := expressionSize;
8473 
8474     ELSE
8475 
8476      --Unknown rule type. Do nothing for those rules, just go to the next rule.
8477 
8478      RAISE CZ_LCE_CONTINUE;
8479     END IF;
8480 
8481     --General rule data validation section - all rule types----------------------------Start
8482 
8483     FOR i IN expressionStart..expressionEnd LOOP
8484 
8485       IF(v_tExprPsNodeId(i) IS NOT NULL)THEN
8486         IF(NOT glIndexByPsNodeId.EXISTS(v_tExprPsNodeId(i)))THEN
8487 
8488 nDebug := 35;
8489 
8490      --Every participating node must actually exist in the product structure.
8491 
8492           RAISE CZ_R_WRONG_EXPRESSION_NODE;
8493 
8494         ELSIF(glPsNodeType(glIndexByPsNodeId(v_tExprPsNodeId(i))) = PS_NODE_TYPE_FEATURE AND
8495               glFeatureType(glIndexByPsNodeId(v_tExprPsNodeId(i))) = PS_NODE_FEATURE_TYPE_STRING)THEN
8496 
8497      --A text feature cannot participate in any kind of rules.
8498 
8499           localString := glName(glIndexByPsNodeId(v_tExprPsNodeId(i)));
8500           RAISE CZ_R_INCORRECT_FEATURE_TYPE;
8501 
8502         ELSIF(glPsNodeType(glIndexByPsNodeId(v_tExprPsNodeId(i))) = PS_NODE_TYPE_CONNECTOR)THEN
8503 
8504      --A connector cannot participate in any kind of rules.
8505 
8506           RAISE CZ_R_CONNECTOR_RULE;
8507         END IF;
8508 
8509         IF(v_tExplNodeId(i) IS NULL)THEN
8510 
8511 nDebug := 36;
8512 
8513     --Every not null ps_node_id should have a not null assosiated model_ref_expl_id (data corruption).
8514 
8515           RAISE CZ_G_INVALID_RULE_EXPLOSION;
8516 
8517         ELSIF(NOT v_IndexByNodeId.EXISTS(v_tExplNodeId(i)))THEN
8518 
8519 nDebug := 37;
8520 
8521     --All the participants' model_ref_expl_id must be in the current model's explosion table (data corruption).
8522 
8523           RAISE CZ_G_INVALID_RULE_EXPLOSION;
8524 
8525         END IF;
8526       END IF;
8527 
8528 nDebug := 38;
8529 
8530       IF(v_tExprType(i) IN (EXPR_NODE_TYPE_NODE, EXPR_PSNODEBYNAME))THEN
8531        IF(v_tExprPsNodeId(i) IS NULL)THEN
8532 
8533 nDebug := 381;
8534 
8535       --Every node type node must have assosiated ps_node_id.
8536 
8537         RAISE CZ_R_INCORRECT_NODE_ID;
8538        END IF;
8539       ELSIF(v_tExprType(i) = EXPR_NODE_TYPE_LITERAL)THEN
8540        IF(v_tExprDataValue(i) IS NULL)THEN
8541 
8542 nDebug := 382;
8543 
8544       --Every literal must have not null value.
8545 
8546         RAISE CZ_R_LITERAL_NO_VALUE;
8547        END IF;
8548       ELSIF(v_tExprType(i) = EXPR_NODE_TYPE_FEATPROP)THEN
8549        IF(v_tExprPsNodeId(i) IS NULL)THEN
8550 
8551 nDebug := 383;
8552 
8553       --Every feature property node must have assosiated ps_node_id.
8554 
8555         RAISE CZ_R_INCORRECT_NODE_ID;
8556        ELSIF(v_tExprPropertyId(i) IS NULL)THEN
8557 
8558 nDebug := 384;
8559 
8560       --Every feature property node must have assosiated property_id.
8561 
8562         RAISE CZ_R_FEATURE_NO_PROPERTY;
8563        END IF;
8564       END IF;
8565 
8566       --Bug #4760372.
8567 
8568       IF(v_tExprType(i) = EXPR_PSNODEBYNAME)THEN
8569 
8570         --This will resolve the path if possible, populate ps_node_id and model_ref_expl_id with
8571         --resolved values and change the type of the expression node.
8572 
8573         RESOLVE_NODE(SPLIT_PATH(v_RelativeNodePath(i)), v_tExprPsNodeId(i), v_tExplNodeId(i), v_tExprPsNodeId(i), v_tExplNodeId(i));
8574         v_tExprType(i) := EXPR_NODE_TYPE_NODE;
8575       END IF;
8576     END LOOP;
8577     --General rule data validation section-----------------------------------------------End
8578 
8579 nDebug := 41;
8580 
8581     nCounter := 0;
8582     distinctCount := 0;
8583     participantCount := 0;
8584     MaxDepthValue := 0;
8585     MaxDepthIndex := thisRootExplIndex;
8586 
8587     FOR i IN expressionStart..expressionEnd LOOP
8588      IF(v_tExprPsNodeId(i) IS NOT NULL)THEN
8589 
8590       participantCount := participantCount + 1;
8591       auxIndex := glIndexByPsNodeId(v_tExprPsNodeId(i));
8592 
8593       --Soft fix the explosion nodes whenever necessary:
8594 
8595       --When a rule has a reference node as a participant,Developer would put the explosion id
8596       --of the reference node itself instead of the explosion id of its parent. This should be
8597       --fixed in some cases (see below).
8598       --If a participant is a component, then it's the component's MIN,MAX or COUNT and actual
8599       --participant should be it's parent. However,it can also be features of the component or
8600       --some other (new) operator. That's why we make sure that the parent of the component is
8601       --the operator DOT and, in addition, the component is non-virtual.
8602 
8603       --Later remark:
8604       --A reference, as well as a component, should be fixed only when they are in combination
8605       --with system property. So, it's not enough to check that the parent operator is DOT, we
8606       --also have to make sure that the another operand is EXPR_SYS_PROP with MIN,MAX or COUNT
8607       --subtype.
8608 
8609       IF(glPsNodeType(auxIndex) = PS_NODE_TYPE_REFERENCE OR
8610          (glPsNodeType(auxIndex) = PS_NODE_TYPE_COMPONENT AND glVirtualFlag(auxIndex) = FLAG_NON_VIRTUAL))THEN
8611 
8612          IF((v_ChildrenIndex.EXISTS(v_tExprId(i)) AND v_tExprType(v_ChildrenIndex(v_tExprId(i))) = EXPR_SYS_PROP AND
8613              h_SeededName.EXISTS(v_tExprSubtype(v_ChildrenIndex(v_tExprId(i)))) AND
8614              h_SeededName(v_tExprSubtype(v_ChildrenIndex(v_tExprId(i)))) IN (RULE_SYS_PROP_MININSTANCE, RULE_SYS_PROP_MAXINSTANCE, RULE_SYS_PROP_INSTANCECOUNT))
8615          )THEN
8616 
8617            --SYS_PROP_COUNT has been removed from the above condition as a part of the fix for the
8618            --bug #2317427 - we do not want to fix explosion if it is a reference to a BOM ATO. For
8619            --such a reference SYS_PROP_COUNT means #Quantity.
8620 
8621            --If this is a reference to a trackable model in a network container model, then this
8622            --rule is against its #Min or #Max, not #Quantity, and so it should be prohibited.
8623            --This exception does not just ignore the rule, it stops the generation.
8624 
8625            IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL AND glIbTrackable(v_tExprPsNodeId(i)) = FLAG_IB_TRACKABLE)THEN
8626 
8627              nParam := auxIndex;
8628              RAISE CZ_R_AGAINST_TRACKABLE;
8629            END IF;
8630 
8631            v_tExplNodeId(i) := v_tParentId(v_IndexByNodeId(v_tExplNodeId(i)));
8632 
8633          ELSIF(glPsNodeType(auxIndex) = PS_NODE_TYPE_REFERENCE)THEN
8634 
8635            --If we are here, than this is a reference to a BOM model, because it should be prohibited
8636            --for a reference to a component to participate with anything other than it's MIN or MAX.
8637            --We will fix the corresponding PS_NODE_ID value to be not the reference node's PS_NODE_ID
8638            --but the PS_NODE_ID of the referenced BOM model. This is necessary to generate the correct
8639            --object name.
8640            --In some cases we still need to use the real reference's ps_node_id.
8641 
8642            v_tRealPsNodeId(i) := v_tExprPsNodeId(i);
8643            v_tExprPsNodeId(i) := glReferenceId(v_tExprPsNodeId(i));
8644          END IF;
8645       END IF;
8646 
8647 nDebug := 42;
8648 
8649       --Select a participant and get its explosion id.
8650 
8651       nAux := v_tExplNodeId(i);
8652 
8653       IF(NOT v_Participant.EXISTS(nAux))THEN
8654 
8655 nDebug := 43;
8656 
8657         IF(v_ProhibitInRules.EXISTS(nAux))THEN
8658 
8659           --This explosion node has D nodes under connectors on the way up in the explosion table.
8660           --It will be impossible to assign this rule, so just stop here.
8661 
8662           localString := glName(glIndexByPsNodeId(v_tExprPsNodeId(i)));
8663           auxIndex := v_ProhibitInRules(nAux);
8664           auxCount := v_ProhibitConnector(nAux);
8665           RAISE CZ_R_UNASSIGNABLE_RULE;
8666 
8667         ELSIF(v_ProhibitOptional.EXISTS(nAux))THEN
8668 
8669           --This explosion node has A nodes under connectors on the way up in the explosion table.
8670           --Stop here - bug #2217450.
8671 
8672           localString := glName(glIndexByPsNodeId(v_tExprPsNodeId(i)));
8673           auxIndex := v_ProhibitOptional(nAux);
8674           auxCount := v_ProhibitConnector(nAux);
8675           RAISE CZ_R_OPTIONAL_INSIDE;
8676         END IF;
8677 
8678         --Add to the list of indexes of distinct participants' explosions.
8679 
8680         v_Participant(nAux) := 1;
8681         distinctCount := distinctCount + 1;
8682         v_ParticipantIndex(distinctCount) := v_IndexByNodeId(nAux);
8683 
8684         --The node is not prohibited from participating in rules, so both assignable exists and
8685         --corresponding deepest instantiable node is defined.
8686 
8687         auxIndex := v_NodeInstantiable(nAux);
8688         auxCount := v_NodeAssignable(nAux);
8689 
8690         --We mark the potential assignables to reflect the fact that the associated participant
8691         --belongs to a connector net. We need a separate table because this information is rule
8692         --specific while v_IsConnectorNet stores the explosion-specific information. A node can
8693         --be assignable for a connector's net participant in one rule but not in another.
8694 
8695         IF(v_IsConnectorNet.EXISTS(nAux))THEN
8696 
8697           v_RuleConnectorNet(auxIndex) := 1;
8698           v_RuleConnectorNet(auxCount) := 1;
8699         END IF;
8700 
8701         --Select and store all the distinct assignables for all the current rule's participants.
8702         --Main indexes are stored in v_DistinctIndex. Also find the deepest D node among all of
8703         --participants here. MaxDepthValue is initialized to the root (0), so that if there are
8704         --no D nodes, the root node will act as one.
8705 
8706 nDebug := 44;
8707 
8708         IF(NOT v_Assignable.EXISTS(auxIndex))THEN
8709 
8710           v_Assignable(auxIndex) := 1;
8711           nCounter := nCounter + 1;
8712           v_DistinctIndex(nCounter) := auxIndex;
8713 
8714           IF(v_tNodeDepth(auxIndex) > MaxDepthValue)THEN
8715 
8716              MaxDepthValue := v_tNodeDepth(auxIndex);
8717              MaxDepthIndex := auxIndex;
8718           END IF;
8719         END IF;
8720 
8721         IF(NOT v_Assignable.EXISTS(auxCount))THEN
8722 
8723           v_Assignable(auxCount) := 1;
8724           nCounter := nCounter + 1;
8725           v_DistinctIndex(nCounter) := auxCount;
8726         END IF;
8727       END IF; --This is a distinct participant.
8728 
8729       v_ExplByPsNodeId(v_tExprPsNodeId(i)) := v_tExplNodeId(i);
8730 
8731      END IF; --This is a participant.
8732     END LOOP;
8733 
8734 nDebug := 45;
8735 
8736     --Now populate the <index in memory>(NODE_DEPTH) table for assignables of any type which
8737     --are above the deepest D component. They should form a chain, without duplicates on the
8738     --same level. Here we verify that there are no two components on the same level. This is
8739     --necessary but not sufficient for the rule to be valid.
8740 
8741     FOR i IN 1..v_DistinctIndex.COUNT LOOP
8742 
8743       auxIndex := v_DistinctIndex(i);
8744 
8745       IF(v_tNodeDepth(auxIndex) <= MaxDepthValue)THEN
8746         IF(v_InstByLevel.EXISTS(v_tNodeDepth(auxIndex)))THEN
8747 
8748           --There is already a node on this level. Two or more non-virtual components on the
8749           --same level are prohibited.
8750 
8751           auxCount := glIndexByPsNodeId(v_tPsNodeId(auxIndex));
8752           auxIndex := glIndexByPsNodeId(v_tPsNodeId(v_InstByLevel(v_tNodeDepth(auxIndex))));
8753           RAISE CZ_R_CONFLICTING_NODES;
8754         ELSE
8755 
8756           --This level is now occupied by a node with memory index auxIndex.
8757 
8758           v_InstByLevel(v_tNodeDepth(auxIndex)) := auxIndex;
8759         END IF;
8760       END IF;
8761     END LOOP;
8762 
8763 nDebug := 46;
8764 
8765     --Now we make sure that if we move up from the deepest D assignable, we will step over
8766     --all other assignable which are above this D, so they all form a chain.
8767     --We start with the deepest D component and move up to its parent and so on thus going
8768     --through every level in the hierarchy. On every level, if an assignable exists there,
8769     --we make sure that this node is what we expect - the parent we just moved up to.
8770 
8771     nCounter := 0;
8772     auxIndex := MaxDepthIndex;
8773 
8774     LOOP
8775       IF(v_InstByLevel.EXISTS(v_tNodeDepth(auxIndex)))THEN
8776          IF(v_InstByLevel(v_tNodeDepth(auxIndex)) <> auxIndex)THEN
8777 
8778            --Incorrect node on the level. The rule goes across non-virual boundaries.
8779 
8780            auxCount := glIndexByPsNodeId(v_tPsNodeId(v_InstByLevel(v_tNodeDepth(auxIndex))));
8781            auxIndex := glIndexByPsNodeId(v_tPsNodeId(MaxDepthIndex));
8782            RAISE CZ_R_INCORRECT_NODE_LEVEL;
8783          END IF;
8784          nCounter := nCounter + 1;
8785       END IF;
8786 
8787       EXIT WHEN nCounter = v_InstByLevel.COUNT OR v_tParentId(auxIndex) IS NULL;
8788       auxIndex := v_IndexByNodeId(v_tParentId(auxIndex));
8789     END LOOP;
8790 
8791 nDebug := 47;
8792 
8793     --We verified that on the way up from the deepest D node we pass ONLY through eligible
8794     --assignables. Now lets see if we passed through ALL of them.
8795 
8796     IF(nCounter <> v_InstByLevel.COUNT)THEN
8797 
8798       --Not all the assignables have been passed on the way up. The rule goes across
8799       --non-virual boundaries.
8800 
8801       RAISE CZ_R_INVALID_RULE;
8802     END IF;
8803 
8804     --So, there exists the deepest type D assignable (it can be the root node) and we verified
8805     --that above it there is no non-virtual boundaries crossing. However, if there are A type
8806     --assignables beneath that D node, we want to assign the rule to the least common ancestor.
8807     --Or there may be not assignables but just regular A nodes between assignables and D.
8808 
8809     --First of all, let us see if there are connector's nets attached to the deepest component
8810     --among the rule participants, because if there are, then the rule will be assigned to the
8811     --deepst D already found and there's no need to work with A type components. Example:
8812 
8813     --  M
8814     --  |_D
8815     --    |_A0
8816     --    | |_A
8817     --    | | |_F2
8818     --    | |_A
8819     --    |   |_F3
8820     --    |
8821     --    |_Connector->M1-F4
8822 
8823     --For both rules relating either (F2, F3) or (F2, F3, F4), D is the deepest D node. However,
8824     --the first rule should be assigned to A0 while the second rule should be assigned to D.
8825     --Reference bug #2188507.
8826 
8827     --We also identify possible connector's nets attached to a node above the deepest D node.
8828     --Such explosions will have assignables above the deepest D and so may have passed all the
8829     --tests above, but a rule may still cross non-virual boundaries. Example:
8830 
8831     --  M
8832     --  |_D
8833     --  | |_A
8834     --  |   |_F2
8835     --  |
8836     --  |___Connector->M1-F4
8837 
8838     --F4 has M as its assignable, and although M and D form a good chain, an (F2, F4) rule is
8839     --prohibited.
8840     --Reference bug #2190399.
8841 
8842     --This block can be optimized to use v_RuleConnectorNet table which was introduced later.
8843 
8844     auxCount := 0;
8845 
8846     FOR i IN 1..v_ParticipantIndex.COUNT LOOP
8847 
8848       nAux := v_NodeId(v_ParticipantIndex(i));
8849 
8850       IF(v_IsConnectorNet.EXISTS(nAux))THEN
8851         IF(v_tNodeDepth(v_NodeAssignable(nAux)) < MaxDepthValue)THEN
8852 
8853           --This is a connector's net attached to a node above the deepest D assignable, report
8854           --the rule.
8855 
8856           auxCount := glIndexByPsNodeId(v_tReferringId(v_IsConnectorNet(nAux)));
8857           auxIndex := glIndexByPsNodeId(v_tPsNodeId(MaxDepthIndex));
8858           RAISE CZ_R_CONNECTOR_ASIDE;
8859         ELSIF(v_NodeAssignable(nAux) = MaxDepthIndex)THEN
8860 
8861           --This is a connector's net attached to the D, so the rule will be assigned to the D.
8862 
8863           auxCount := 1;
8864 
8865           --Just one attached net is enough, but we cannot exit here because we need to examine
8866           --all other participants on account of connector's nets attached above the D node
8867           --(the previous IF does that).
8868         END IF;
8869       END IF;
8870     END LOOP;
8871 
8872     IF(auxCount = 0)THEN
8873 
8874       --We know that the rule can be assigned somewhere under the deepest D node. It can be
8875       --one of the A type nodes under the deepest D, assignable or not. We start from every
8876       --assignable A node underneath the deepest D and go up all the way to the D. If we do
8877       --not end up on the deepest D, the rule crosses non-virtual boundaries and is invalid.
8878 
8879       --On the way up we collect the following information:
8880 
8881       --  for every level the number of distinct components of any type on this level
8882       --  (v_LevelCount);
8883       --  index of the first of such components (v_LevelIndex);
8884       --  type of the first of such components (v_LevelType);
8885 
8886 nDebug := 48;
8887 
8888       nCounter := MaxDepthValue;
8889 
8890       FOR i IN 1..v_DistinctIndex.COUNT LOOP
8891 
8892         auxIndex := v_DistinctIndex(i);
8893         nAux := v_tNodeDepth(auxIndex);
8894 
8895         IF(v_tExplNodeType(auxIndex) = EXPL_NODE_TYPE_OPTIONAL AND nAux > MaxDepthValue)THEN
8896 
8897            IF(nCounter < nAux)THEN nCounter := nAux; END IF;
8898 
8899            FOR n IN REVERSE MaxDepthValue + 1..nAux LOOP
8900 
8901              IF(NOT v_LevelCount.EXISTS(nAux))THEN
8902 
8903                v_LevelCount(nAux) := 1;
8904                v_LevelIndex(nAux) := auxIndex;
8905                v_LevelType(nAux) := v_tExplNodeType(auxIndex);
8906              END IF;
8907 
8908              IF(auxIndex <> v_LevelIndex(nAux))THEN
8909 
8910                v_LevelCount(nAux) := v_LevelCount(nAux) + 1;
8911              END IF;
8912 
8913              auxIndex := v_IndexByNodeId(v_tParentId(auxIndex));
8914              nAux := nAux - 1;
8915            END LOOP;
8916 
8917            IF(auxIndex <> MaxDepthIndex)THEN
8918 
8919              --The way up from the A node doesn't pass through the D node on level MaxDepthValue.
8920              --Crossing of non-virtual boundaries detected.
8921 
8922              auxCount := glIndexByPsNodeId(v_tPsNodeId(v_DistinctIndex(i)));
8923              auxIndex := glIndexByPsNodeId(v_tPsNodeId(MaxDepthIndex));
8924              RAISE CZ_R_OPTIONAL_ASIDE;
8925            END IF;
8926         END IF;
8927       END LOOP;
8928 
8929 nDebug := 49;
8930 
8931       --We want to find the deepest A component we can assign the rule to. So we move from the
8932       --top down shifting MaxDepthIndex with every A component we find. When we hit a fork, we
8933       --stop.
8934 
8935       FOR i IN MaxDepthValue + 1..nCounter LOOP
8936 
8937         IF(v_LevelCount(i) = 1 AND v_LevelType(i) = EXPL_NODE_TYPE_OPTIONAL)THEN
8938 
8939           MaxDepthIndex := v_LevelIndex(i);
8940         END IF;
8941 
8942         --We stop when we hit a fork or when we see that there is a connector net attached to
8943         --the optional component which is another kind of fork. Example:
8944 
8945         --  A1
8946         --  |_A2
8947         --    |_A3
8948         --    | |_A4
8949         --    |
8950         --    |_Connector->participant
8951 
8952         --We don't want to go below A2.
8953 
8954         IF(v_LevelCount(i) > 1 OR v_RuleConnectorNet.EXISTS(v_LevelIndex(i))) THEN
8955 
8956           EXIT;
8957         END IF;
8958       END LOOP;
8959     END IF;  --We finished processing the tree of A nodes beneath the deepest D node which
8960              --may have resulted in assigning the rule to an A node under the deepest D.
8961 
8962     --If this rule is defined in a network container model, it can't have participants across
8963     --instantiable references to trackable models. We have already calculated indexes of such
8964     --references for every explosion. The requirement above means that, if one of the indexes
8965     --belongs to a non-trackable model, then all the indexes should belong to a non-trackable
8966     --model.
8967 
8968     IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
8969 
8970       localCount := 0;
8971 
8972       FOR i IN 1..v_ParticipantIndex.COUNT LOOP
8973 
8974         IF(glIbTrackable(v_tPsNodeId(v_NodeTrackable(v_NodeId(v_ParticipantIndex(i))))) = FLAG_NOT_IB_TRACKABLE)
8975         THEN localCount := localCount + 1; END IF;
8976       END LOOP;
8977 
8978       IF(localCount > 0 AND localCount < v_ParticipantIndex.COUNT)THEN
8979 
8980         RAISE CZ_R_ACROSS_TRACKABLE;
8981       END IF;
8982     END IF;
8983 
8984 nDebug := 490;
8985 
8986     --The rule is assigned to this component (identified by model_ref_expl_id). This variable
8987     --is used mostly for identification of rule logic files, but also in rule generation code.
8988 
8989     MaxDepthId := v_NodeId(MaxDepthIndex);
8990     MaxDepthValue := v_tNodeDepth(MaxDepthIndex);
8991 
8992 nDebug := 50;
8993 
8994     --We need to prepend downpaths for all the distinct participating explosions. If the
8995     --assignable of an explosion id is deeper than the rule's assignee, we are going to
8996     --prepend the downpath with all optional (type A) components or mandatory references
8997     --on the way down from the assignee to the assignable. We do not need to change the
8998     --node's logic level.
8999     --We do not prepend downpaths for explosions corresponding to connectors.
9000 
9001     FOR i IN 1..v_ParticipantIndex.COUNT LOOP
9002 
9003       nAux := v_NodeId(v_ParticipantIndex(i));
9004 
9005       IF(NOT v_IsConnectorNet.EXISTS(nAux))THEN
9006 
9007         auxIndex := v_NodeAssignable(nAux);
9008 
9009         WHILE(v_tNodeDepth(auxIndex) > MaxDepthValue)LOOP
9010           IF(v_tExplNodeType(auxIndex) IN (EXPL_NODE_TYPE_OPTIONAL, EXPL_NODE_TYPE_MANDATORY))THEN
9011 
9012             v_AssignedDownPath(nAux) := PATH_DELIMITER || 'N_' ||
9013                 TO_CHAR(glPersistentId(NVL(v_tReferringId(auxIndex), v_tPsNodeId(auxIndex)))) ||
9014                                         v_AssignedDownPath(nAux);
9015           END IF;
9016 
9017           auxIndex := v_IndexByNodeId(v_tParentId(auxIndex));
9018         END LOOP;
9019       END IF;
9020     END LOOP;
9021 
9022 nDebug := 51;
9023 
9024     --Now we can go ahead and collect the load conditions for this rule. Those would be all
9025     --type A (optional) and C (connector) descendants of the rule assignee. To collect them
9026     --we need to go up from each (distinct) rule participant's explosion id (index).
9027     --There may also be no load conditions at all and then this is the 'standard' rule file
9028     --identified by explosion id of the assignee as a load condition (NET_TYPE = 2).
9029 
9030     FOR i IN 1..v_ParticipantIndex.COUNT LOOP
9031 
9032       auxIndex := v_ParticipantIndex(i);
9033 
9034       WHILE(v_tNodeDepth(auxIndex) > MaxDepthValue AND v_tParentId(auxIndex) IS NOT NULL) LOOP
9035 
9036         IF(v_tExplNodeType(auxIndex) IN (EXPL_NODE_TYPE_OPTIONAL, EXPL_NODE_TYPE_CONNECTOR))THEN
9037 
9038           --It is enough to just mark the index as a load condition.
9039 
9040           v_MarkLoadCondition(auxIndex) := 1;
9041         END IF;
9042 
9043         auxIndex := v_IndexByNodeId(v_tParentId(auxIndex));
9044       END LOOP;
9045     END LOOP;
9046 
9047 nDebug := 52;
9048 
9049     nHeaderId := NEVER_EXISTS_ID;
9050 
9051     IF(v_MarkLoadCondition.COUNT = 0)THEN
9052 
9053       --This is going to be a mandatory (standard) rule file.
9054 
9055       logicNetType := LOGIC_NET_TYPE_MANDATORY;
9056       v_LoadConditionId(1) := MaxDepthId;
9057       IF(v_tIsHeaderGenerated.EXISTS(MaxDepthId))THEN
9058 
9059         nHeaderId := v_tIsHeaderGenerated(MaxDepthId);
9060       END IF;
9061     ELSE
9062 
9063       --There are load conditions, so this is going to be a network logic file.
9064 
9065       logicNetType := LOGIC_NET_TYPE_NETWORK;
9066 
9067 nDebug := 53;
9068 
9069       --Generate the load condition string. Note that with the algorithm used condition nodes
9070       --are ordered, otherwise it would make no sense.
9071       --There is currently no check for not to exceed the length of the localString.
9072 
9073       localString := NULL;
9074       nCounter := 0;
9075 
9076       FOR i IN 1..v_NodeId.COUNT LOOP
9077         IF(v_MarkLoadCondition.EXISTS(i))THEN
9078 
9079           nCounter := nCounter + 1;
9080           v_LoadConditionId(nCounter) := v_NodeId(i);
9081           localString := localString || ':' || TO_CHAR(v_NodeId(i));
9082         END IF;
9083       END LOOP;
9084 
9085 nDebug := 54;
9086 
9087       nCounter := 0;
9088 
9089       FOR i IN 1..v_LoadConditions.COUNT LOOP
9090         IF(localString = v_LoadConditions(i))THEN
9091 
9092           --Load condition found, fetch the corresponding header and exit the loop.
9093 
9094           nHeaderId := v_LoadHeaders(i);
9095           nCounter := 1;
9096           EXIT;
9097         END IF;
9098       END LOOP;
9099 
9100       IF(nCounter = 0)THEN
9101 
9102         --A new load condition, add it to the table. Corresponding header will be
9103         --generated and added later.
9104 
9105         v_LoadConditions(v_LoadConditions.COUNT + 1) := localString;
9106       END IF;
9107     END IF;
9108 
9109     nCounter := v_LoadConditionId.COUNT;
9110 
9111 nDebug := 7;
9112 
9113     --Generate a new logic header if necessary.
9114 
9115     IF(nHeaderId = NEVER_EXISTS_ID)THEN
9116 
9117       nHeaderId := next_lce_header_id;
9118 
9119       BEGIN
9120 
9121         --Insert the rule net logic header record into the table.
9122 
9123         INSERT INTO cz_lce_headers
9124          (lce_header_id, gen_version, gen_header, component_id, net_type,
9125           devl_project_id, model_ref_expl_id, nbr_required_expls, deleted_flag)
9126         VALUES
9127          (nHeaderId, VersionString, GenHeader, v_tPsNodeId(v_IndexByNodeId(MaxDepthId)),
9128           logicNetType, thisProjectId, MaxDepthId, nCounter, FLAG_PENDING);
9129 
9130         FOR i IN 1..nCounter LOOP
9131 
9132           nAux := v_LoadConditionId(i);
9133 
9134           --The following statement populates the new ALIAS_NAME column introduced as a fix
9135           --for the bug #2214414. The column is populated with C_<model_ref_expl_id> for
9136           --connector conditions and with NULL for other conditions (optional components).
9137 
9138           INSERT INTO cz_lce_load_specs
9139            (attachment_expl_id, lce_header_id, required_expl_id, attachment_comp_id,
9140             model_id, net_type, deleted_flag, alias_name)
9141           VALUES
9142            (MaxDepthId, nHeaderId, nAux, v_tPsNodeId(v_IndexByNodeId(MaxDepthId)),
9143             thisProjectId, logicNetType, FLAG_PENDING,
9144             DECODE(v_tExplNodeType(v_IndexByNodeId(nAux)), EXPL_NODE_TYPE_CONNECTOR, 'C_' || nAux, NULL));
9145         END LOOP;
9146 
9147       EXCEPTION
9148         WHEN OTHERS THEN
9149           errorMessage := SQLERRM;
9150           RAISE CZ_R_UNABLE_TO_CREATE_HEADER;
9151       END;
9152 
9153       NewHeaders(counterNewHeaders) := nHeaderId;
9154       NewHeadersComponents(counterNewHeaders) := v_tPsNodeId(v_IndexByNodeId(MaxDepthId));
9155       NewHeadersExplosions(counterNewHeaders) := MaxDepthId;
9156       counterNewHeaders := counterNewHeaders + 1;
9157 
9158       IF(logicNetType = LOGIC_NET_TYPE_MANDATORY)THEN
9159 
9160         v_tIsHeaderGenerated(MaxDepthId) := nHeaderId;
9161       ELSE
9162 
9163         v_LoadHeaders(v_LoadHeaders.COUNT + 1) := nHeaderId;
9164       END IF;
9165 
9166       v_tSequenceNbr(nHeaderId) := 1;
9167       v_tLogicNetType(nHeaderId) := logicNetType;
9168       nNewLogicFileFlag := 1;
9169     END IF;
9170 
9171     nRuleAssignedLevel := v_tNodeDepth(v_IndexByNodeId(MaxDepthId));
9172 
9173     --If the logic file has changed then we need to flush off the buffer
9174 
9175     IF(nHeaderId <> nPreviousHeaderId)THEN
9176 
9177      IF(vLogicText IS NOT NULL)THEN
9178        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
9179         (nPreviousHeaderId, v_tSequenceNbr(nPreviousHeaderId), vLogicText);
9180        vLogicText := NULL;
9181        v_tSequenceNbr(nPreviousHeaderId) := v_tSequenceNbr(nPreviousHeaderId) + 1;
9182      END IF;
9183 
9184     END IF;
9185 
9186     nPreviousHeaderId := nHeaderId;
9187 
9188     IF(nNewLogicFileFlag = 1)THEN
9189 
9190       --This is a new logic file, put the header lines in
9191 
9192       vLogicLine := 'CONTROL NOSPEC' || NewLine || 'VERSION 3 3' || NewLine || NewLine ||
9193                     'REM -- Rules file for component: ' || TO_CHAR(v_tPsNodeId(v_IndexByNodeId(MaxDepthId))) ||
9194                     ', explosion node: ' || TO_CHAR(MaxDepthId) || NewLine || NewLine;
9195       PACK;
9196       nNewLogicFileFlag := 0;
9197 
9198     END IF;
9199 
9200 nDebug := 8;
9201 
9202    --Prepare the effective date interval.
9203    --First get the effective date interval either from an effectivity set or
9204    --from the local values.
9205 
9206    IF(nRuleEffSetId IS NOT NULL)THEN
9207     IF(gvIndexBySetId.EXISTS(nRuleEffSetId))THEN
9208 
9209 nDebug := 8000100;
9210 
9211      CurrentEffFrom := gvEffFrom(gvIndexBySetId(nRuleEffSetId));
9212      CurrentEffUntil := gvEffUntil(gvIndexBySetId(nRuleEffSetId));
9213 
9214   --Fix for the bug6502787
9215      dEffFrom := CurrentEffFrom;
9216      dEffUntil:= CurrentEffUntil;
9217     ELSE
9218       --This is a fatal error - data corruption
9219       RAISE CZ_R_WRONG_EFFECTIVITY_SET;
9220     END IF;
9221    ELSE
9222      CurrentEffFrom := dEffFrom;
9223      CurrentEffUntil := dEffUntil;
9224    END IF;
9225 
9226 nDebug := 8000101;
9227 
9228    --Make sure effective dates are not null. Usage mask is not null anyway.
9229 
9230    IF(CurrentEffFrom IS NULL)THEN CurrentEffFrom := EpochBeginDate; END IF;
9231    IF(CurrentEffUntil IS NULL)THEN CurrentEffUntil := EpochEndDate; END IF;
9232 
9233    dEffFrom := CurrentEffFrom;
9234    dEffUntil := CurrentEffUntil;
9235 
9236    IF((NOT PrevRuleEffFrom.EXISTS(nHeaderId)) OR
9237       (CurrentEffFrom <> PrevRuleEffFrom(nHeaderId)) OR (CurrentEffUntil <> PrevRuleEffUntil(nHeaderId)) OR
9238       (vUsageMask <> PrevRuleUsageMask(nHeaderId)))THEN
9239 
9240         vLogicLine := LTRIM(vUsageMask, '0');
9241         IF(vLogicLine IS NOT NULL) THEN
9242           vLogicLine := EffUsagePrefix || vLogicLine;
9243         END IF;
9244 
9245         IF(CurrentEffFrom = EpochBeginDate)THEN
9246           CurrentFromDate := NULL;
9247         ELSE
9248           CurrentFromDate := TO_CHAR(CurrentEffFrom, EffDateFormat);
9249         END IF;
9250 
9251         IF(CurrentEffUntil = EpochEndDate)THEN
9252           CurrentUntilDate := NULL;
9253         ELSE
9254           CurrentUntilDate := TO_CHAR(CurrentEffUntil, EffDateFormat);
9255         END IF;
9256 
9257         vLogicLine := 'EFF ' || CurrentFromDate || ', ' || CurrentUntilDate || ', ' || vLogicLine || NewLine;
9258         PACK;
9259 
9260         PrevRuleEffFrom(nHeaderId) := CurrentEffFrom;
9261         PrevRuleEffUntil(nHeaderId) := CurrentEffUntil;
9262         PrevRuleUsageMask(nHeaderId) := vUsageMask;
9263    END IF;
9264 
9265 nDebug := 8000102;
9266 
9267    --Expression generation
9268 
9269    IF(nRuleType IN (RULE_TYPE_TEMPLATE, RULE_TYPE_EXPRESSION))THEN
9270 
9271     FOR i IN expressionStart..expressionEnd LOOP
9272       IF(v_tExprParentId(i) IS NULL)THEN
9273 
9274         --Because of the ordering by expr_parent_id, all the expression tree roots will be at the end
9275         --after all their children. As soon as we hit the first of them we can start generating.
9276         --The construction of children lookup arrays has been moved directly after reading the
9277         --expression tree.
9278 
9279         --Bugs #5160714, #5184017. Reset optimization and other parameters per rule. It is not enough
9280         --to do it once after for each rule record because rule text may consist of several rules.
9281         --These parameter are not used for other rule types.
9282 
9283         optimizeChain      := OPTIMIZATION_UNKNOWN;
9284         optimizeContribute := OPTIMIZATION_UNKNOWN;
9285         jAntecedentRoot  := NULL;
9286         jConsequentRoot  := NULL;
9287         RuleTemplateType := RULE_TYPE_UNKNOWN;
9288         numericLHS       := 0;
9289         generateCompare  := 0;
9290 
9291         returnStringArray := GENERATE_EXPRESSION(i, returnListType);
9292       END IF;
9293     END LOOP;
9294    ELSIF(nRuleType = RULE_TYPE_COMPAT_TABLE)THEN
9295 
9296      GENERATE_COMPATIBILITY_TABLE;
9297    ELSIF(nRuleType = RULE_TYPE_DESIGNCHART_RULE)THEN
9298 
9299      GENERATE_DESIGNCHART_RULE;
9300    END IF; --End expression and rule generation
9301    END IF; --Not a rule folder or functional companion
9302 
9303   --This block handles the exceptions during a rule generation. Every such exception
9304   --will stop generation only for the particular rule if not re-raised here.
9305 
9306   EXCEPTION
9307      WHEN CZ_R_UNKNOWN_RULE_TYPE THEN
9308 --'Unknown rule type, rule ''%RULENAME'' ignored'
9309        REPORT(CZ_UTILS.GET_TEXT('CZ_R_UNKNOWN_RULE_TYPE', 'RULENAME', RULE_NAME), 1);
9310        PACK;
9311      WHEN CZ_R_INVALID_RULE THEN
9312 --'Rule ''%RULENAME'' cannot be generated because it relates an incorrect combination of components. Rule ignored.'
9313        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_RULE', 'RULENAME', RULE_NAME), 1);
9314        PACK;
9315      WHEN CZ_R_UNASSIGNABLE_RULE THEN
9316 --'Rule ''%RULENAME'' cannot be generated because the node ''%NODENAME'' is a descendant of the multiply
9317 -- instantiable component ''%COMPONENT'' inside the connected model ''%CONNECTOR'', and therefore cannot
9318 -- participate in rules. Rule ignored.'
9319        REPORT(CZ_UTILS.GET_TEXT('CZ_R_UNASSIGNABLE_RULE', 'NODENAME', localString, 'COMPONENT', glName(auxIndex), 'CONNECTOR', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9320        PACK;
9321      WHEN CZ_R_OPTIONAL_INSIDE THEN
9322 --'Rule ''%RULENAME'' cannot be generated because the node ''%NODENAME'' is a descendant of the optional
9323 -- component ''%COMPONENT'' inside the connected model ''%CONNECTOR'', and therefore cannot  participate
9324 -- in rules. Rule ignored.'
9325        REPORT(CZ_UTILS.GET_TEXT('CZ_R_OPTIONAL_INSIDE', 'NODENAME', localString, 'COMPONENT', glName(auxIndex), 'CONNECTOR', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9326        PACK;
9327      WHEN CZ_R_OPTIONAL_ASIDE THEN
9328 --'Rule ''%RULENAME'' cannot be generated because it relates the multiply instantiable component ''%COMPONENT1''
9329 -- with the optional component ''%COMPONENT2''. Rule ignored.'
9330        REPORT(CZ_UTILS.GET_TEXT('CZ_R_OPTIONAL_ASIDE', 'COMPONENT1', glName(auxIndex), 'COMPONENT2', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9331        PACK;
9332      WHEN CZ_R_CONNECTOR_ASIDE THEN
9333 --'Rule ''%RULENAME'' cannot be generated because it relates the multiply instantiable component ''%COMPONENT''
9334 -- with the connected model ''%CONNECTOR''. Rule ignored.'
9335        REPORT(CZ_UTILS.GET_TEXT('CZ_R_CONNECTOR_ASIDE', 'COMPONENT', glName(auxIndex), 'CONNECTOR', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9336        PACK;
9337      WHEN CZ_R_CONFLICTING_NODES THEN
9338 --'Logic cannot be generated for Rule ''%RULENAME''. This is because the rule participants are descendants of
9339 -- Components ''%COMPONENT1'' and ''%COMPONENT2'' that can be instantiated multiple times. Rule ignored.'
9340        REPORT(CZ_UTILS.GET_TEXT('CZ_R_CONFLICTING_NODES', 'COMPONENT1', glName(auxIndex), 'COMPONENT2', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9341        PACK;
9342      WHEN CZ_R_INCORRECT_NODE_LEVEL THEN
9343 --'Rule ''%RULENAME'' cannot be generated because it relates the multiply instantiable component ''%COMPONENT1'' with the component ''%COMPONENT2''.
9344 -- Rule ignored.'
9345        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_NODE_LEVEL', 'COMPONENT1', glName(auxIndex), 'COMPONENT2', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9346        PACK;
9347      WHEN CZ_R_ACROSS_TRACKABLE THEN
9348 --'Logic cannot be generated for rule ''%RULENAME'' because it relates a trackable instantiable Model with
9349 -- non-trackable items inside the Container Model ''%PROJECTNAME''. Rule ignored.'
9350        REPORT(CZ_UTILS.GET_TEXT('CZ_R_ACROSS_TRACKABLE', 'PROJECTNAME', rootProjectName, 'RULENAME', RULE_NAME), 1);
9351        PACK;
9352      WHEN CZ_R_CONNECTOR_RULE THEN
9353 --'Rule ''%RULENAME'' in the Model ''%MODELNAME'' is invalid. Connectors cannot participate in rules.'
9354        REPORT(CZ_UTILS.GET_TEXT('CZ_R_CONNECTOR_RULE', 'MODELNAME', thisProjectName, 'RULENAME', RULE_NAME), 1);
9355        PACK;
9356      WHEN CZ_R_INVALID_LOGIC_RULE THEN
9357 --'Invalid logic rule, rule ''%RULENAME'' ignored'
9358        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_LOGIC_RULE', 'RULENAME', RULE_NAME), 1);
9359        PACK;
9360      WHEN CZ_R_INCOMPLETE_LOGIC_RULE THEN
9361 --'Incomplete logic rule, rule ''%RULENAME'' ignored'
9362        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCOMPLETE_LOGIC_RULE', 'RULENAME', RULE_NAME), 1);
9363        PACK;
9364      WHEN CZ_R_LOGIC_RULE_WRONG_FEAT THEN
9365 --'Incorrect feature type in logic rule, feature ''%FEATNAME'', rule ''%RULENAME'' ignored'
9366        REPORT(CZ_UTILS.GET_TEXT('CZ_R_LOGIC_RULE_WRONG_FEAT', 'FEATNAME', localString, 'RULENAME', RULE_NAME), 1);
9367        PACK;
9368      WHEN CZ_R_NUMERIC_RULE_WRONG_FEAT THEN
9369 --'Incorrect feature type in numeric rule, feature ''%FEATNAME'', rule ''%RULENAME'' ignored'
9370        REPORT(CZ_UTILS.GET_TEXT('CZ_R_NUMERIC_RULE_WRONG_FEAT', 'FEATNAME', localString, 'RULENAME', RULE_NAME), 1);
9371        PACK;
9372      WHEN CZ_R_INCORRECT_FEATURE_TYPE THEN
9373 --'Text features are not allowed to participate in rules, feature ''%FEATNAME'', rule ''%RULENAME'' ignored.'
9374        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_FEATURE_TYPE', 'FEATNAME', localString, 'RULENAME', RULE_NAME), 1);
9375        PACK;
9376      WHEN CZ_R_INVALID_NUMERIC_RULE THEN
9377 --'Invalid numeric rule, rule ''%RULENAME'' ignored'
9378        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_NUMERIC_RULE', 'RULENAME', RULE_NAME), 1);
9379        PACK;
9380      WHEN CZ_R_INCORRECT_NUMERIC_RHS THEN
9381 --'The node ''%NODENAME'' in the Model ''%MODELNAME'' is a(n) ''%NODETYPE''. This type of node cannot be
9382 -- a participant on the B side of a Numeric rule. Rule ''%RULENAME'' ignored.'
9383        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_NUMERIC_RHS', 'NODENAME', localString, 'MODELNAME', thisProjectName, 'NODETYPE', errorMessage, 'RULENAME', RULE_NAME), 1);
9384        PACK;
9385      WHEN CZ_R_INCOMPATIBLE_SYSPROP THEN
9386 --'The Property ''%PROPERTYNAME'' is invalid for the node ''%NODENAME''. Rule ''%RULENAME'' in Model ''%MODELNAME'' ignored.'
9387        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCOMPATIBLE_SYSPROP', 'PROPERTYNAME', localString, 'NODENAME', glName(auxIndex), 'MODELNAME', thisProjectName, 'RULENAME', RULE_NAME), 1);
9388        PACK;
9389      WHEN CZ_R_INVALID_COMPARISON_RULE THEN
9390 --'Invalid comparison rule, rule ''%RULENAME'' ignored'
9391        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_COMPARISON_RULE', 'RULENAME', RULE_NAME), 1);
9392        PACK;
9393      WHEN CZ_R_INVALID_NUMERIC_PART THEN
9394 --'Invalid numeric part, rule ''%RULENAME'' ignored'
9395        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_NUMERIC_PART', 'RULENAME', RULE_NAME), 1);
9396        PACK;
9397      WHEN CZ_R_INCOMPLETE_NUMERIC_RULE THEN
9398 --'Incomplete numeric rule, rule ''%RULENAME'' ignored'
9399        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCOMPLETE_NUMERIC_RULE', 'RULENAME', RULE_NAME), 1);
9400        PACK;
9401      WHEN CZ_R_INVALID_NUMRULE_NODE THEN
9402 --'Invalid numeric rule node, rule ''%RULENAME'' ignored'
9403        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_NUMRULE_NODE', 'RULENAME', RULE_NAME), 1);
9404        PACK;
9405      WHEN CZ_R_INVALID_NUM_SIMPLE_EXPR THEN
9406 --'The left-hand side expression must have a root rounding operator, rule ''%RULENAME'' ignored'
9407        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_NUM_SIMPLE_EXPR', 'RULENAME', RULE_NAME), 1);
9408        PACK;
9409      WHEN CZ_E_UNKNOWN_EXPR_TYPE THEN
9410 --'Unknown expression type, rule ''%RULENAME'' ignored'
9411        REPORT(CZ_UTILS.GET_TEXT('CZ_E_UNKNOWN_EXPR_TYPE', 'RULENAME', RULE_NAME), 1);
9412        PACK;
9413      WHEN CZ_E_WRONG_ARITHMETIC_OPER THEN
9414 --'Incorrect arithmetic operator, rule ''%RULENAME'' ignored'
9415        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_ARITHMETIC_OPER', 'RULENAME', RULE_NAME), 1);
9416        PACK;
9417      WHEN CZ_E_WRONG_COMPARISON_OPER THEN
9418 --'Incorrect comparison operator, rule ''%RULENAME'' ignored'
9419        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_COMPARISON_OPER', 'RULENAME', RULE_NAME), 1);
9420        PACK;
9421      WHEN CZ_E_WRONG_ROUND_OPERATOR THEN
9422 --'Incorrect ROUND operator, rule ''%RULENAME'' ignored'
9423        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_ROUND_OPERATOR', 'RULENAME', RULE_NAME), 1);
9424        PACK;
9425      WHEN CZ_E_WRONG_ANDOR_OPERATOR THEN
9426 --'Incorrect AND/OR operator, rule ''%RULENAME'' ignored'
9427        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_ANDOR_OPERATOR', 'RULENAME', RULE_NAME), 1);
9428        PACK;
9429      WHEN CZ_E_WRONG_NOT_OPERATOR THEN
9430 --'Incorrect NOT operator, rule ''%RULENAME'' ignored'
9431        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_NOT_OPERATOR', 'RULENAME', RULE_NAME), 1);
9432        PACK;
9433      WHEN CZ_E_WRONG_NOTTRUE_OPERATOR THEN
9434 --'Incorrect NOTTRUE operator, rule ''%RULENAME'' ignored'
9435        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_NOTTRUE_OPERATOR', 'RULENAME', RULE_NAME), 1);
9436        PACK;
9437      WHEN CZ_E_WRONG_VAL_EXPRESSION THEN
9438 --'Incorrect VAL expression, rule ''%RULENAME'' ignored'
9439        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_VAL_EXPRESSION', 'RULENAME', RULE_NAME), 1);
9440        PACK;
9441      WHEN CZ_E_WRONG_VAL_EXPRESS_TYPE THEN
9442 --'Incorrect VAL expression type, rule ''%RULENAME'' ignored'
9443        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_VAL_EXPRESS_TYPE', 'RULENAME', RULE_NAME), 1);
9444        PACK;
9445      WHEN CZ_E_WRONG_MINMAX_OPERATOR THEN
9446 --'Incorrect MIN/MAX operator, rule ''%RULENAME'' ignored'
9447        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_MINMAX_OPERATOR', 'RULENAME', RULE_NAME), 1);
9448        PACK;
9449      WHEN CZ_E_WRONG_OF_OPERATOR THEN
9450 --'Incorrect OF operator, rule ''%RULENAME'' ignored'
9451        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_OF_OPERATOR', 'RULENAME', RULE_NAME), 1);
9452        PACK;
9453      WHEN CZ_E_WRONG_DOT_OPERATOR THEN
9454 --'Incorrect DOT operator, rule ''%RULENAME'' ignored'
9455        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_DOT_OPERATOR', 'RULENAME', RULE_NAME), 1);
9456        PACK;
9457      WHEN CZ_E_DOT_TYPE_MISMATCH THEN
9458 --'DOT type mismatch, rule ''%RULENAME'' ignored'
9459        REPORT(CZ_UTILS.GET_TEXT('CZ_E_DOT_TYPE_MISMATCH', 'RULENAME', RULE_NAME), 1);
9460        PACK;
9461      WHEN CZ_E_BAD_PROPERTY_TYPE THEN
9462 --'Bad property type, rule ''%RULENAME'' ignored'
9463        REPORT(CZ_UTILS.GET_TEXT('CZ_E_BAD_PROPERTY_TYPE', 'RULENAME', RULE_NAME), 1);
9464        PACK;
9465      WHEN CZ_E_NO_SUCH_PROPERTY THEN
9466 --'No such property, rule ''%RULENAME'' ignored'
9467        REPORT(CZ_UTILS.GET_TEXT('CZ_E_NO_SUCH_PROPERTY', 'RULENAME', RULE_NAME), 1);
9468        PACK;
9469      WHEN CZ_E_NULL_PROPERTY_VALUE THEN
9470 --'Null property value, rule ''%RULENAME'' ignored'
9471        REPORT(CZ_UTILS.GET_TEXT('CZ_E_NULL_PROPERTY_VALUE', 'RULENAME', RULE_NAME), 1);
9472        PACK;
9473      WHEN CZ_E_INCORRECT_PROPERTY THEN
9474 --'Unable to identify property value, rule ''%RULENAME'' ignored'
9475        REPORT(CZ_UTILS.GET_TEXT('CZ_E_INCORRECT_PROPERTY', 'RULENAME', RULE_NAME), 1);
9476        PACK;
9477      WHEN CZ_E_UNKNOWN_OPERATOR_TYPE THEN
9478 --'Unknown operator type, type %OPERTYPE, rule ''%RULENAME'' ignored'
9479        REPORT(CZ_UTILS.GET_TEXT('CZ_E_UNKNOWN_OPERATOR_TYPE', 'OPERTYPE', TO_CHAR(nParam), 'RULENAME', RULE_NAME), 1);
9480        PACK;
9481      WHEN CZ_E_INVALID_OPERAND_TYPE THEN
9482 --'Invalid operand type, operator ''%OPERNAME'', rule ''%RULENAME'' ignored'
9483        REPORT(CZ_UTILS.GET_TEXT('CZ_E_INVALID_OPERAND_TYPE', 'OPERNAME', LTRIM(RTRIM(OperatorLiterals(v_tExprSubtype(nParam)))), 'RULENAME', RULE_NAME), 1);
9484        PACK;
9485      WHEN CZ_E_MATH_PARAMETERS THEN
9486 --'Incorrect number of parameters to mathematical function %FUNCTION, rule ''%RULENAME'' ignored'
9487        REPORT(CZ_UTILS.GET_TEXT('CZ_E_MATH_PARAMETERS', 'RULENAME', RULE_NAME, 'FUNCTION', LTRIM(RTRIM(OperatorLiterals(nParam)))), 1);
9488        PACK;
9489      WHEN CZ_E_INCORRECT_POWER THEN
9490 --'Exponent value of a POW function could not be resolved to a constant integer, rule ''%RULENAME'' ignored'
9491        REPORT(CZ_UTILS.GET_TEXT('CZ_E_INCORRECT_POWER', 'RULENAME', RULE_NAME), 1);
9492        PACK;
9493      WHEN CZ_R_UNABLE_TO_CREATE_TABLE THEN
9494 --'Unable to create a temporary table for property-based compatibility rule, rule ''%RULENAME'' ignored, error: %ERRORTEXT'
9495        REPORT(CZ_UTILS.GET_TEXT('CZ_R_UNABLE_TO_CREATE_TABLE', 'RULENAME', RULE_NAME, 'ERRORTEXT', errorMessage), 1);
9496        PACK;
9497      WHEN CZ_R_WRONG_COMPAT_EXPRESSION THEN
9498 --'Incorrect compatibility expression, rule ''%RULENAME'' ignored'
9499        REPORT(CZ_UTILS.GET_TEXT('CZ_R_WRONG_COMPAT_EXPRESSION', 'RULENAME', RULE_NAME), 1);
9500        PACK;
9501      WHEN CZ_E_WRONG_OPER_IN_COMPAT THEN
9502 --'Incorrect operator in compatibility rule, rule ''%RULENAME'' ignored'
9503        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_OPER_IN_COMPAT', 'RULENAME', RULE_NAME), 1);
9504        PACK;
9505      WHEN CZ_E_UKNOWN_OPER_IN_COMPAT THEN
9506 --'Unknown operator in compatibility rule, rule ''%RULENAME'' ignored'
9507        REPORT(CZ_UTILS.GET_TEXT('CZ_E_UKNOWN_OPER_IN_COMPAT', 'RULENAME', RULE_NAME), 1);
9508        PACK;
9509      WHEN CZ_R_COMPAT_NO_COMBINATIONS THEN
9510 --'No valid combinations, rule ''%RULENAME'' ignored'
9511        REPORT(CZ_UTILS.GET_TEXT('CZ_R_COMPAT_NO_COMBINATIONS', 'RULENAME', RULE_NAME), 1);
9512        PACK;
9513      WHEN CZ_R_WRONG_EXPRESSION_NODE THEN
9514 --'Incorrect node in expression, rule ''%RULENAME'' ignored'
9515        REPORT(CZ_UTILS.GET_TEXT('CZ_R_WRONG_EXPRESSION_NODE', 'RULENAME', RULE_NAME), 1);
9516        PACK;
9517      WHEN CZ_R_NO_DEFINING_SELECTION THEN
9518 --'No selection made between primary and defining feature in design chart rule, rule ''%RULENAME'' ignored'
9519        REPORT(CZ_UTILS.GET_TEXT('CZ_R_NO_DEFINING_SELECTION', 'RULENAME', RULE_NAME), 1);
9520        PACK;
9521      WHEN CZ_R_NO_PRIMARY_FEATURE THEN
9522 --'No primary feature in design chart rule, rule ''%RULENAME'' ignored'
9523        REPORT(CZ_UTILS.GET_TEXT('CZ_R_NO_PRIMARY_FEATURE', 'RULENAME', RULE_NAME), 1);
9524        PACK;
9525      WHEN CZ_R_DELETED_OPTION THEN
9526 --'The Model structure has changed and the Design Chart rule ''%RULENAME'' now contains deleted node ''%NODENAME''.
9527 -- The rule will be ignored.'
9528        REPORT(CZ_UTILS.GET_TEXT('CZ_R_DELETED_OPTION', 'RULENAME', RULE_NAME, 'NODENAME', errorMessage), 1);
9529        PACK;
9530      WHEN CZ_R_WRONG_DESIGNCHART_RULE THEN
9531 --'No one-to-one correspondence between options of primary and defining feature in design chart rule, rule ''%RULENAME'' ignored'
9532        REPORT(CZ_UTILS.GET_TEXT('CZ_R_WRONG_DESIGNCHART_RULE', 'RULENAME', RULE_NAME), 1);
9533        PACK;
9534      WHEN CZ_R_DUPLICATE_COMBINATION THEN
9535 --'Not unique combination of defining feature options for a primary option in design chart rule, rule ''%RULENAME'' ignored'
9536        REPORT(CZ_UTILS.GET_TEXT('CZ_R_DUPLICATE_COMBINATION', 'RULENAME', RULE_NAME), 1);
9537        PACK;
9538      WHEN CZ_R_INCOMPLETE_DES_CHART THEN
9539 --'Incorrect number of compatibility selections made for the option ''%OPTIONNAME'' of the Primary Feature ''%FEATURENAME''
9540 -- in Design Chart ''%RULENAME''. Rule ignored.'
9541        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCOMPLETE_DES_CHART', 'OPTIONNAME', glName(auxIndex), 'FEATURENAME', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9542        PACK;
9543      WHEN CZ_R_EMPTY_COMPAT_RULE THEN
9544 --'Empty compatibility rule, rule ''%RULENAME'' ignored'
9545        REPORT(CZ_UTILS.GET_TEXT('CZ_R_EMPTY_COMPAT_RULE', 'RULENAME', RULE_NAME), 1);
9546        PACK;
9547      WHEN CZ_R_COMPAT_SINGLE_FEATURE THEN
9548 --'Compatibility rule must have at least two participating features, rule ''%RULENAME'' ignored'
9549        REPORT(CZ_UTILS.GET_TEXT('CZ_R_COMPAT_SINGLE_FEATURE', 'RULENAME', RULE_NAME), 1);
9550        PACK;
9551      WHEN CZ_R_COMPAT_RULE_NO_PROPERTY THEN
9552 --'Incomplete compatibility rule, no property defined for feature ''%FEATNAME'', rule ''%RULENAME'' ignored'
9553        REPORT(CZ_UTILS.GET_TEXT('CZ_R_COMPAT_RULE_NO_PROPERTY', 'FEATNAME', glName(glIndexByPsNodeId(v_tExprPsNodeId(nParam))), 'RULENAME', RULE_NAME), 1);
9554        PACK;
9555      WHEN CZ_R_OPTION_NO_PROPERTY THEN
9556 --'Property value for ''%PROPERTYNAME'' is not defined for item ''%ITEMNAME'' with parent ''%PARENTNAME'' in model ''%MODELNAME''. Rule ''%RULENAME'' ignored.'
9557        REPORT(CZ_UTILS.GET_TEXT('CZ_R_OPTION_NO_PROPERTY', 'PROPERTYNAME', errorMessage, 'ITEMNAME', glName(auxIndex), 'PARENTNAME', glName(nParam), 'MODELNAME', glName(glIndexByPsNodeId(inProjectId)),'RULENAME', RULE_NAME), 1);
9558        PACK;
9559      WHEN CZ_R_LONG_PROPERTY_VALUE THEN
9560 --'Value of the Property ''%PROPERTYNAME'' is too long for item ''%ITEMNAME'' with parent ''%PARENTNAME'' in model ''%MODELNAME''. Rule ''%RULENAME'' ignored.'
9561        REPORT(CZ_UTILS.GET_TEXT('CZ_R_LONG_PROPERTY_VALUE', 'PROPERTYNAME', errorMessage, 'ITEMNAME', glName(auxIndex), 'PARENTNAME', glName(nParam), 'MODELNAME', glName(glIndexByPsNodeId(inProjectId)),'RULENAME', RULE_NAME), 1);
9562        PACK;
9563      WHEN CZ_R_INCORRECT_DATA_TYPE THEN
9564 --'Incorrect data: integer or decimal property ''%PROPERTYNAME'' has a text value of ''%VALUE''. Rule ''%RULENAME'' in model ''%MODELNAME'' ignored.'
9565        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_DATA_TYPE', 'PROPERTYNAME', errorMessage, 'VALUE', localString, 'MODELNAME', glName(glIndexByPsNodeId(inProjectId)), 'RULENAME', RULE_NAME), 1);
9566        PACK;
9567      WHEN CZ_R_INCORRECT_NUMERICLHS THEN
9568 --'''%PROPERTYNAME'' is invalid in the Numeric rule ''%RULENAME'' in Model ''%MODELNAME''. Text and Boolean Properties
9569 -- cannot be participants on the left-hand side of a Numeric rule. Rule ignored.'
9570        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_NUMERICLHS', 'PROPERTYNAME', errorMessage, 'MODELNAME', glName(glIndexByPsNodeId(inProjectId)), 'RULENAME', RULE_NAME), 1);
9571        PACK;
9572      WHEN CZ_R_PROPERTY_NOT_ALLOWED THEN
9573 --'The expression contained a Text property which is only allowed in a comparison expression. A Text property is not
9574 -- allowed in the context of your expression. Rule ''%RULENAME'' in Model ''%MODELNAME'' ignored.'
9575        REPORT(CZ_UTILS.GET_TEXT('CZ_R_PROPERTY_NOT_ALLOWED', 'MODELNAME', glName(glIndexByPsNodeId(inProjectId)), 'RULENAME', RULE_NAME), 1);
9576        PACK;
9577      WHEN CZ_R_VIRTUAL_COMPONENT THEN
9578 --'The system property ''%PROPERTYNAME'' is not allowed because ''%NODENAME'' is required. Refer to Oracle Configurator
9579 -- Developer documentation for details. Rule ''%RULENAME'' ignored.'
9580        REPORT(CZ_UTILS.GET_TEXT('CZ_R_VIRTUAL_COMPONENT', 'PROPERTYNAME', localString, 'NODENAME', glName(nParam), 'RULENAME', RULE_NAME), 1);
9581        PACK;
9582      WHEN CZ_R_WRONG_COMPAT_TABLE THEN
9583 --'Incorrect explicit compatibility table, rule ''%RULENAME'' ignored'
9584        REPORT(CZ_UTILS.GET_TEXT('CZ_R_WRONG_COMPAT_TABLE', 'RULENAME', RULE_NAME), 1);
9585        PACK;
9586      WHEN CZ_R_NO_PARTICIPANTS THEN
9587 --'Incomplete rule - no participants, rule ''%RULENAME'' ignored'
9588        REPORT(CZ_UTILS.GET_TEXT('CZ_R_NO_PARTICIPANTS', 'RULENAME', RULE_NAME), 1);
9589        PACK;
9590      WHEN CZ_R_NO_COMPONENT_ID THEN
9591 --'No ps_node_id defined for none of the rule participants, rule ''%RULENAME'' ignored'
9592        REPORT(CZ_UTILS.GET_TEXT('CZ_R_NO_COMPONENT_ID', 'RULENAME', RULE_NAME), 1);
9593        PACK;
9594      WHEN CZ_R_RULE_WRONG_EXPRESSION THEN
9595 --'Invalid expression specified, rule ''%RULENAME'' ignored'
9596        REPORT(CZ_UTILS.GET_TEXT('CZ_R_RULE_WRONG_EXPRESSION', 'RULENAME', RULE_NAME), 1);
9597        PACK;
9598      WHEN CZ_R_WRONG_EFFECTIVITY_SET THEN
9599 --'Invalid effectivity set assosiated with rule ''%RULENAME'', rule ignored'
9600        REPORT(CZ_UTILS.GET_TEXT('CZ_R_WRONG_EFFECTIVITY_SET', 'RULENAME', RULE_NAME), 1);
9601        PACK;
9602      WHEN CZ_R_LITERAL_NO_VALUE THEN
9603 --'No literal value specified in rule ''%RULENAME'', rule ignored'
9604        REPORT(CZ_UTILS.GET_TEXT('CZ_R_LITERAL_NO_VALUE', 'RULENAME', RULE_NAME), 1);
9605        PACK;
9606      WHEN CZ_R_INCORRECT_NODE_ID THEN
9607 --'Incomplete or invalid data in rule ''%RULENAME'', rule ignored'
9608        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_NODE_ID', 'RULENAME', RULE_NAME), 1);
9609        PACK;
9610      WHEN CZ_R_FEATURE_NO_PROPERTY THEN
9611 --'Invalid property or no property specified in rule ''%RULENAME'', rule ignored'
9612        REPORT(CZ_UTILS.GET_TEXT('CZ_R_FEATURE_NO_PROPERTY', 'RULENAME', RULE_NAME), 1);
9613        PACK;
9614      WHEN CZ_R_INCORRECT_REFERENCE THEN
9615 --'The reference %PATH is invalid. At least one node does not exist in the Model or is not effective when the rule is effective.
9616 -- Rule ''%RULENAME'' ignored.'
9617        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_REFERENCE', 'PATH', localString, 'RULENAME', RULE_NAME), 1);
9618        PACK;
9619      WHEN CZ_R_AMBIGUOUS_REFERENCE THEN
9620 --'Unable to resolve Model node reference %PATH because it is ambiguous. Rule ''%RULENAME'' ignored.'
9621        REPORT(CZ_UTILS.GET_TEXT('CZ_R_AMBIGUOUS_REFERENCE', 'PATH', localString, 'RULENAME', RULE_NAME), 1);
9622        PACK;
9623      WHEN CZ_E_NO_EXPECTED_CHILDREN THEN
9624 --'Node ''%NODENAME'' has no children, rule ''%RULENAME'' ignored'
9625        REPORT(CZ_UTILS.GET_TEXT('CZ_E_NO_EXPECTED_CHILDREN', 'NODENAME', localString, 'RULENAME', RULE_NAME), 1);
9626        PACK;
9627      WHEN CZ_E_NO_OPTIONAL_CHILDREN THEN
9628 --'All children of the BOM node ''%NODENAME'' are required when parent is selected, no optional children, rule ''%RULENAME'' ignored'
9629        REPORT(CZ_UTILS.GET_TEXT('CZ_E_NO_OPTIONAL_CHILDREN', 'NODENAME', localString, 'RULENAME', RULE_NAME), 1);
9630        PACK;
9631      WHEN CZ_R_TRACKABLE_ANCESTOR THEN
9632 --'BOM item ''%ITEMNAME'' cannot participate in the Numeric rule ''%RULENAME'' because it contains other trackable BOM items.'
9633        REPORT(CZ_UTILS.GET_TEXT('CZ_R_TRACKABLE_ANCESTOR', 'ITEMNAME', glName(nParam), 'RULENAME', RULE_NAME), 1);
9634        PACK;
9635      WHEN CZ_R_AGAINST_TRACKABLE THEN
9636 --'Numeric rule ''%RULENAME'' is invalid. In a Container Model, a Numeric rule cannot contribute to or consume
9637 -- from how many instances of a trackable Model are allowed at runtime.'
9638        REPORT(CZ_UTILS.GET_TEXT('CZ_R_AGAINST_TRACKABLE', 'RULENAME', RULE_NAME), 1);
9639        PACK;
9640 --'Only nontranslatable System Properties are allowed in the WHERE clause of a COMPATIBLE or FORALL operator.
9641 -- The System Property ''%PROPERTYNAME'' can be translated, therefore it is invalid in this context. Rule ''%RULENAME''
9642 -- in the Model ''%MODELNAME'' will be ignored.'
9643      WHEN CZ_E_DESCRIPTION_IN_WHERE THEN
9644        REPORT(CZ_UTILS.GET_TEXT('CZ_E_DESCRIPTION_IN_WHERE', 'PROPERTYNAME', errorMessage,'MODELNAME', thisProjectName, 'RULENAME', RULE_NAME), 1);
9645        PACK;
9646 --'Only static System Properties are allowed in the WHERE clause of a COMPATIBLE or FORALL operator. The value of the
9647 -- System Property ''%PROPERTYNAME'' can change at runtime, therefore it is invalid in this context. Rule ''%RULENAME''
9648 -- in the Model ''%MODELNAME'' will be ignored.'
9649      WHEN CZ_E_PROPERTY_NOT_STATIC THEN
9650        REPORT(CZ_UTILS.GET_TEXT('CZ_E_PROPERTY_NOT_STATIC', 'PROPERTYNAME', errorMessage,'MODELNAME', thisProjectName, 'RULENAME', RULE_NAME), 1);
9651        PACK;
9652      WHEN CZ_R_TEMPLATE_UNKNOWN OR CZ_R_EMPTY_PARAMETER_SCOPE OR CZ_R_PARAMETER_NOT_FOUND OR
9653           CZ_R_TYPE_NO_PROPERTY OR CZ_R_NO_SIGNATURE_ID THEN
9654 --'Unable to generate rule ''%RULENAME'', internal data error.'
9655        REPORT(CZ_UTILS.GET_TEXT('CZ_G_INTERNAL_RULE_ERROR', 'RULENAME', RULE_NAME), 1);
9656        PACK;
9657      WHEN CZ_G_INVALID_RULE_EXPLOSION THEN
9658 --This is fatal: model_ref_expl_id of one of the participants references an explosion table
9659 --other than the current model table
9660        errorMessage := RULE_NAME;
9661        IF(StopOnFatalRuleError = 1)THEN
9662          IF(c_rules%ISOPEN)THEN CLOSE c_rules; END IF;
9663          RAISE;
9664        ELSE
9665 --'Unable to generate rule ''%RULENAME'', internal data error.'
9666          REPORT(CZ_UTILS.GET_TEXT('CZ_G_INTERNAL_RULE_ERROR', 'RULENAME', errorMessage), 1);
9667          PACK;
9668        END IF;
9669      WHEN CZ_R_UNABLE_TO_CREATE_HEADER THEN
9670 
9671          --This is supposed to be a definitely fatal error, so raise the exception.
9672 
9673          IF(c_rules%ISOPEN)THEN CLOSE c_rules; END IF;
9674          RAISE;
9675      WHEN CZ_LCE_CONTINUE THEN
9676 --This exception is used to immediately move to the next loop, not an error.
9677        NULL;
9678      WHEN OTHERS THEN
9679        IF(nDebug >= 40 AND nDebug <= 54)THEN
9680          errorMessage := RULE_NAME;
9681        ELSIF(SUBSTR(TO_CHAR(nDebug), 1, 1) = '8')THEN
9682          errorMessage := TO_CHAR(nRuleId);
9683        END IF;
9684 
9685        --When the first data corruption-type error for a rule is encountered, logic gen stops.
9686        --However, it may be convenient for debugging purposes to be able to report all of such
9687        --rules. So, check the db setting here.
9688 
9689        IF(StopOnFatalRuleError = 1)THEN
9690          IF(c_rules%ISOPEN)THEN CLOSE c_rules; END IF;
9691          RAISE;
9692        ELSE
9693 --'Unable to generate rule ''%RULENAME'', internal error %ERRORTEXT'
9694          REPORT(CZ_UTILS.GET_TEXT('CZ_G_GENERAL_RULE_ERROR', 'RULENAME', RULE_NAME, 'ERRORTEXT', SQLERRM), 1);
9695          PACK;
9696        END IF;
9697   END;
9698   END LOOP;
9699   CLOSE c_rules;
9700 
9701   --Now generate the INC relations into the root rule file for the non-virtual components
9702   --that have rules against their max.
9703 
9704   IF(v_MaxRuleExists.COUNT > 0)THEN
9705     IF(v_tIsHeaderGenerated.EXISTS(thisComponentExplId))THEN
9706 
9707       --Use this header to generate the rule into
9708 
9709       nHeaderId := v_tIsHeaderGenerated(thisComponentExplId);
9710 
9711     ELSE
9712 
9713       nHeaderId := next_lce_header_id;
9714 
9715       BEGIN
9716 
9717         --Insert the rule net logic header record into the table
9718 
9719         INSERT INTO cz_lce_headers
9720          (lce_header_id, gen_version, gen_header, component_id, net_type,
9721           devl_project_id, model_ref_expl_id, nbr_required_expls, deleted_flag)
9722         VALUES
9723          (nHeaderId, VersionString, GenHeader, inComponentId, LOGIC_NET_TYPE_MANDATORY,
9724           thisProjectId, thisComponentExplId, 1, FLAG_PENDING);
9725 
9726         INSERT INTO cz_lce_load_specs
9727          (attachment_expl_id, lce_header_id, required_expl_id, attachment_comp_id,
9728           model_id, net_type, deleted_flag)
9729         VALUES
9730          (thisComponentExplId, nHeaderId, thisComponentExplId, inComponentId,
9731           thisProjectId, LOGIC_NET_TYPE_MANDATORY, FLAG_PENDING);
9732 
9733       EXCEPTION
9734         WHEN OTHERS THEN
9735           errorMessage := SQLERRM;
9736           RAISE CZ_R_UNABLE_TO_CREATE_HEADER;
9737       END;
9738 
9739       NewHeaders(counterNewHeaders) := nHeaderId;
9740       NewHeadersComponents(counterNewHeaders) := inComponentId;
9741       NewHeadersExplosions(counterNewHeaders) := thisComponentExplId;
9742       counterNewHeaders := counterNewHeaders + 1;
9743 
9744       v_tIsHeaderGenerated(thisComponentExplId) := nHeaderId;
9745       v_tSequenceNbr(nHeaderId) := 1;
9746       v_tLogicNetType(nHeaderId) := LOGIC_NET_TYPE_MANDATORY;
9747       nNewLogicFileFlag := 1;
9748 
9749     END IF;
9750 
9751     --If the logic file has changed then we need to flush off the buffer
9752 
9753     IF(nHeaderId <> nPreviousHeaderId)THEN
9754 
9755      IF(vLogicText IS NOT NULL)THEN
9756        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
9757         (nPreviousHeaderId, v_tSequenceNbr(nPreviousHeaderId), vLogicText);
9758        vLogicText := NULL;
9759        v_tSequenceNbr(nPreviousHeaderId) := v_tSequenceNbr(nPreviousHeaderId) + 1;
9760      END IF;
9761 
9762     END IF;
9763 
9764     IF(nNewLogicFileFlag = 1)THEN
9765 
9766       --This is a new logic file, put the header lines in
9767 
9768       vLogicLine := 'CONTROL NOSPEC' || NewLine || 'VERSION 3 3' || NewLine || NewLine ||
9769                     'REM -- Rules file for component: ' || TO_CHAR(inComponentId) ||
9770                     ', explosion node: ' || TO_CHAR(thisComponentExplId) || NewLine || NewLine ||
9771                     'EFF , , ' || NewLine || NewLine;
9772       PACK;
9773     END IF;
9774 
9775     FOR i IN 1..v_NodeId.COUNT LOOP
9776      IF(v_MaxRuleExists.EXISTS(v_NodeId(i)) AND v_tVirtualFlag(i) = FLAG_NON_VIRTUAL AND
9777         v_tNodeDepth(i) > 0)THEN
9778 
9779        --Use intermediate variable instead of using NVL because this is faster
9780 
9781        IF(v_tReferringId(i) IS NOT NULL)THEN
9782         localString := TO_CHAR(glPersistentId(v_tReferringId(i)));
9783        ELSE
9784         localString := TO_CHAR(glPersistentId(v_tPsNodeId(i)));
9785        END IF;
9786 
9787        vLogicLine := 'INC 1 P_' || localString || '_MAX round' || NewLine;
9788        PACK;
9789 
9790      END IF;
9791     END LOOP;
9792 
9793   END IF;
9794 
9795 nDebug := 9;
9796 
9797   --Flush off the buffer after rules generation
9798 
9799   IF(vLogicText IS NOT NULL)THEN
9800     INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
9801      (nHeaderId, v_tSequenceNbr(nHeaderId), vLogicText);
9802     vLogicText := NULL;
9803     v_tSequenceNbr(nHeaderId) := v_tSequenceNbr(nHeaderId) + 1;
9804   END IF;
9805 
9806   FOR i IN 1..temp_tables.COUNT LOOP
9807     BEGIN
9808       EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || temp_tables(i);
9809       EXECUTE IMMEDIATE 'DROP TABLE ' || temp_tables(i);
9810     EXCEPTION
9811       WHEN OTHERS THEN
9812         IF(SQLCODE <> ORACLE_OBJECT_IN_USE)THEN RAISE; END IF;
9813     END;
9814   END LOOP;
9815 
9816   IF(TwoPhaseCommit = 0)THEN COMMIT; END IF;
9817 
9818 EXCEPTION
9819   WHEN OTHERS THEN
9820     FOR i IN 1..temp_tables.COUNT LOOP
9821       BEGIN
9822         EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || temp_tables(i);
9823         EXECUTE IMMEDIATE 'DROP TABLE ' || temp_tables(i);
9824       EXCEPTION
9825         WHEN OTHERS THEN
9826           NULL;
9827       END;
9828     END LOOP;
9829     RAISE;
9830 END; --GENERATE_RULES
9831 ---------------------------------------------------------------------------------------
9832 BEGIN --GENERATE_COMPONENT_TREE - Product Structure Generation
9833 
9834   --Generate next lce_header_id for this LCE file. This is the structure net for a model or
9835   --non-virtual component.
9836 
9837 nDebug := 1110000;
9838 
9839   IF(inParentLogicHeaderId IS NULL)THEN
9840 
9841     --If this is the root model, read and store its name and type for later use.
9842 
9843     BEGIN
9844 
9845       SELECT name, model_type INTO thisProjectName, thisProjectType
9846         FROM cz_devl_projects
9847        WHERE devl_project_id = inComponentId;
9848     EXCEPTION
9849       WHEN OTHERS THEN
9850         nParam := inComponentId;
9851         RAISE CZ_S_NO_SUCH_PROJECT;
9852     END;
9853 
9854     IF(inComponentId = inDevlProjectId)THEN
9855 
9856       --Store the name and type of the root project for which the logic generation was
9857       --originally started.
9858 
9859       rootProjectName := thisProjectName;
9860       rootProjectType := thisProjectType;
9861     ELSIF(thisProjectType = MODEL_TYPE_CONTAINER_MODEL AND rootProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
9862 
9863       --Container cannot be referenced or connected to.
9864 
9865       errorMessage := thisProjectName;
9866       RAISE CZ_S_CONTAINER_REFERENCE;
9867     END IF;
9868   END IF;
9869 
9870   IF(NOT IsLogicGenerated.EXISTS(inComponentId))THEN
9871 
9872     --Read the explosions table here. It will be extensively used in rule generation. For the
9873     --structure generation, there is really no need in this table, except that now we want to
9874     --put reasonable values into CZ_LCE_HEADERS.MODEL_REF_EXPL_ID even for structure files as
9875     --this column is being made not nullable in 18.
9876 
9877     IF(inParentLogicHeaderId IS NULL)THEN
9878 
9879       --If this is the root model, read the table and populate project's id and explosion id
9880       --variables, and hash tables.
9881 
9882       SELECT model_ref_expl_id, parent_expl_node_id, node_depth,
9883              ps_node_type, virtual_flag, component_id, referring_node_id,
9884              child_model_expl_id, expl_node_type
9885       BULK COLLECT INTO v_NodeId, v_tParentId, v_tNodeDepth,
9886                         v_tNodeType, v_tVirtualFlag, v_tPsNodeId, v_tReferringId,
9887                         v_tChildModelExpl, v_tExplNodeType
9888       FROM cz_model_ref_expls
9889       WHERE model_id = inComponentId AND deleted_flag = FLAG_NOT_DELETED;
9890 
9891       FOR i IN 1..v_NodeId.COUNT LOOP
9892 
9893 nDebug := 1110010;
9894 
9895         IF(v_tVirtualFlag(i) = FLAG_NON_VIRTUAL AND v_tExplNodeType(i) = EXPL_NODE_TYPE_MANDATORY)THEN
9896 
9897           --This is introduced as a remedy to a well-known type of data corruption occured during
9898           --the development process. May be removed later on when the data become stable.
9899 
9900           errorMessage := thisProjectName;
9901           RAISE CZ_G_INVALID_EXPLOSION_TYPE;
9902         END IF;
9903 
9904 nDebug := 1110001;
9905 
9906         --Add another indexing option - by model_ref_expl_id
9907 
9908         v_IndexByNodeId(v_NodeId(i)) := i;
9909 
9910         --Store the explosion id and the index of the root node - the project node itself.
9911 
9912         IF(v_tNodeDepth(i) = 0)THEN
9913           thisComponentExplId := v_NodeId(i);
9914           thisRootExplIndex := i;
9915         END IF;
9916 
9917         --Create the EXPL_NODE_TYPE(MODEL_REF_EXPL_ID) hash table. Other explosion columns
9918         --are currently indexed through v_IndexByNodeId. Using direct hash may provide for
9919         --some performance improvement.
9920 
9921         v_TypeByExplId(v_NodeId(i)) := v_tExplNodeType(i);
9922 
9923         --Build the MODEL_REF_EXPL_ID(COMPONENT_ID) hash table for all the components
9924         --inside this project (not inside referenced projects). All such components
9925         --have CHILD_MODEL_EXPL_ID null. We need this table to populate MODEL_REF_EXPL_ID
9926         --in CZ_LCE_HEADERS records for structure file of this component.
9927 
9928         IF(v_tChildModelExpl(i) IS NULL)THEN
9929           v_NodeIdByComponent(v_tPsNodeId(i)) := v_NodeId(i);
9930         END IF;
9931       END LOOP;
9932     ELSE
9933 
9934 nDebug := 1110002;
9935 
9936       --This is a non-virtual component inside this project, so the value in the
9937       --hash table exists.
9938       --We do not have to populate thisRootExplIndex, because it is used only in
9939       --rule generation and this will not be called for a non-root component.
9940       --Have to populate the other two variables though as they are used here in
9941       --the structure generation.
9942 
9943       thisComponentExplId := v_NodeIdByComponent(inComponentId);
9944     END IF;
9945 
9946     thisProjectId := inProjectId;
9947 
9948     --Generate next lce_header_id for this LCE file. This is the structure net for a model or
9949     --non-virtual component.
9950 
9951     nStructureHeaderId := next_lce_header_id;
9952 
9953     BEGIN
9954 
9955      --Insert the structure logic header record into the table.
9956 
9957      INSERT INTO cz_lce_headers
9958       (lce_header_id, gen_version, gen_header, component_id, net_type,
9959        devl_project_id, model_ref_expl_id, nbr_required_expls, deleted_flag)
9960      VALUES
9961       (nStructureHeaderId, VersionString, GenHeader, inComponentId, LOGIC_NET_TYPE_STRUCTURE,
9962        thisProjectId, thisComponentExplId, 1, FLAG_PENDING);
9963 
9964      --Insert the structure load conditions record for this component.
9965 
9966      INSERT INTO cz_lce_load_specs
9967       (attachment_expl_id, lce_header_id, required_expl_id, attachment_comp_id,
9968        model_id, net_type, deleted_flag)
9969      VALUES
9970       (thisComponentExplId, nStructureHeaderId, thisComponentExplId, inComponentId,
9971        thisProjectId, LOGIC_NET_TYPE_STRUCTURE, FLAG_PENDING);
9972 
9973     EXCEPTION
9974       WHEN OTHERS THEN
9975         errorMessage := SQLERRM;
9976         RAISE CZ_S_UNABLE_TO_CREATE_HEADER;
9977     END;
9978 
9979     NewHeaders(counterNewHeaders) := nStructureHeaderId;
9980     NewHeadersComponents(counterNewHeaders) := inComponentId;
9981     NewHeadersExplosions(counterNewHeaders) := thisComponentExplId;
9982     counterNewHeaders := counterNewHeaders + 1;
9983 
9984   ELSIF(IsLogicGenerated(inComponentId) = 0)THEN
9985 
9986     --The flag may be set by two reasons: the model was considered up-to-date or the model has already been
9987     --processed in this session. Only in the first case a header should exist in the database and we need
9988     --to load it into memory. In the second case it should be in the memory and may not exist in the database.
9989     --Bug #3150226.
9990 
9991 nDebug := 1110003;
9992 
9993     SELECT head.lce_header_id, max(text.seq_nbr) INTO nStructureHeaderId, nSequenceNbr
9994       FROM cz_lce_headers head, cz_lce_texts text
9995      WHERE head.deleted_flag = FLAG_NOT_DELETED
9996        AND head.net_type = LOGIC_NET_TYPE_STRUCTURE
9997        AND head.component_id = inComponentId
9998        AND head.lce_header_id = text.lce_header_id
9999      GROUP BY head.lce_header_id;
10000 
10001     vSeqNbrByHeader(nStructureHeaderId) := nSequenceNbr + 1;
10002   END IF;
10003 
10004 nDebug := 1110004;
10005 
10006   vLogicText := 'CONTROL NOSPEC' || NewLine || 'VERSION 3 3' || NewLine ||
10007                 'SETDEFAULTDELTA F' || NewLine || 'EFF , , ' || NewLine || NewLine ||
10008                 'REM -- Structure file for component: ' || TO_CHAR(inComponentId) || NewLine || NewLine ||
10009                 'OBJECT _ALWAYS_TRUE' || NewLine || 'MINMAX 1 1 _ALWAYS_TRUE' || NewLine ||
10010                 'OBJECT _ALWAYS_FALSE' || NewLine ||
10011                 'GS N' || NewLine || 'GL L _ALWAYS_TRUE' || NewLine || 'GR L _ALWAYS_FALSE' || NewLine;
10012 
10013 nDebug := 1110005;
10014 
10015   --This SELECT statement reads the whole 'virtual' tree under a non-virtual component which also
10016   --includes the non-virtual component itself. Non-virtual components underneath are included in
10017   --order to recurse, and this function will be called for every non-virtual component underneath.
10018   --The resulting order provided by this statement is used later when generating list of options
10019   --for an option feature.
10020 
10021   SELECT ps_node_id, parent_id, item_id, minimum, maximum, name, intl_text_id, minimum_selected,
10022          maximum_selected, ps_node_type, initial_value, virtual_flag, feature_type, bom_required_flag,
10023          reference_id, persistent_node_id, effective_from, effective_until, effective_usage_mask,
10024          effectivity_set_id, decimal_qty_flag, ib_trackable, accumulator_flag, initial_num_value,
10025          instantiable_flag, shippable_item_flag, inventory_transactable_flag, assemble_to_order_flag,
10026          serializable_item_flag
10027   BULK COLLECT INTO
10028          ntPsNodeId, ntParentId, ntItemId, ntMinimum, ntMaximum, ntName, ntDescriptionId, ntMinimumSel,
10029          ntMaximumSel, ntPsNodeType, ntInitialValue, ntVirtualFlag, ntFeatureType, ntBomRequired,
10030          ntReferenceId, ntPersistentId, dtEffFrom, dtEffUntil, vtUsageMask,
10031          ntEffSetId, ntDecimalQty, ntIbTrackable, ntAccumulator, ntInitialNumValue,
10032          ntInstantiableFlag, ntShippableFlag, ntTransactableFlag, ntAtoFlag, ntSerializableFlag
10033   FROM cz_ps_nodes
10034   WHERE deleted_flag = FLAG_NOT_DELETED
10035   START WITH ps_node_id = inComponentId
10036   CONNECT BY PRIOR ps_node_id = parent_id
10037       AND (PRIOR virtual_flag IS NULL OR PRIOR virtual_flag = FLAG_VIRTUAL OR
10038            PRIOR ps_node_id = inComponentId);
10039 
10040 nDebug := 1110006;
10041 
10042   --Make sure there is some data returned
10043 
10044   IF(ntPsNodeId.LAST IS NOT NULL)THEN
10045 
10046 nDebug := 1110007;
10047 
10048   --Having this dummy boundary node eliminates the necessity of potentially time
10049   --consuming boundary checks during the option feature options' list generation
10050 
10051   ntParentId(ntPsNodeId.LAST + 1) := NEVER_EXISTS_ID;
10052 
10053   --Prepare to start the main cycle
10054 
10055   i := ntPsNodeId.FIRST;
10056 
10057   WHILE(i <= ntPsNodeId.LAST) LOOP --Start the main structure generating cycle
10058    BEGIN
10059 
10060     CurrentlyPacking := PACKING_GENERIC;
10061 
10062    --Populate the 'global' arrays - required for rules generation
10063 
10064 nDebug := 1110010;
10065 
10066     IF(NOT glIndexByPsNodeId.EXISTS(ntPsNodeId(i)))THEN
10067 
10068      IF(ntInitialNumValue(i) IS NOT NULL)THEN ntInitialValue(i) := TO_CHAR(ntInitialNumValue(i)); END IF;
10069 
10070      glPsNodeId(globalCount) := ntPsNodeId(i);
10071      glItemId(globalCount) := ntItemId(i);
10072      glPsNodeType(globalCount) := ntPsNodeType(i);
10073      glParentId(globalCount) := ntParentId(i);
10074      glFeatureType(globalCount) := ntFeatureType(i);
10075      glName(globalCount) := ntName(i);
10076      glBomRequired(globalCount) := ntBomRequired(i);
10077      glMinimum(globalCount) := ntMinimum(i);
10078      glMaximum(globalCount) := ntMaximum(i);
10079      glMinimumSel(globalCount) := ntMinimumSel(i);
10080      glMaximumSel(globalCount) := ntMaximumSel(i);
10081      glVirtualFlag(globalCount) := ntVirtualFlag(i);
10082      glInitialValue(globalCount) := ntInitialValue(i);
10083 
10084    --Indexing by ps_node_id, will be used in expressions generation to get back to
10085    --the structure.
10086 
10087      glIndexByPsNodeId(ntPsNodeId(i)) := globalCount;
10088 
10089    --These global arrays will be indexed differently because we only need to get
10090    --persistent_node_id or reference_id by ps_node_id. Probably, good indexing
10091    --option for some of the other global arrays, too.
10092 
10093      glPersistentId(ntPsNodeId(i)) := ntPersistentId(i);
10094      glReferenceId(ntPsNodeId(i)) := ntReferenceId(i);
10095      glDecimalQty(ntPsNodeId(i)) := ntDecimalQty(i);
10096      glIbTrackable(ntPsNodeId(i)) := ntIbTrackable(i);
10097      glAccumulator(ntPsNodeId(i)) := ntAccumulator(i);
10098      glInstantiableFlag(ntPsNodeId(i)) := ntInstantiableFlag(i);
10099 
10100    --Children of any node start right after the node. But then, the children list may
10101    --not be dense, because children may have their own children. So in order to find
10102    --all the children of a node we need to search the whole structure after the node.
10103    --Here we store the last child's index so that we need to search not the whole
10104    --structure up to the end but up to this last child's index.
10105 
10106 nDebug := 1110011;
10107 
10108      IF(ntParentId(i) IS NOT NULL)THEN
10109       glLastChildIndex(ntParentId(i)) := globalCount;
10110 
10111       --This array is used in design chart rules generation and contains the number of children
10112       --of a node. We actually use it only for features and BOM option classes.
10113 
10114       IF(NOT featOptionsCount.EXISTS(ntParentId(i)))THEN featOptionsCount(ntParentId(i)) := 0; END IF;
10115       featOptionsCount(ntParentId(i)) := featOptionsCount(ntParentId(i)) + 1;
10116      END IF;
10117 
10118      IF(ntPsNodeType(i) = PS_NODE_TYPE_BOM_STANDARD AND ntIbTrackable(i) = FLAG_IB_TRACKABLE AND
10119         thisProjectType IN (MODEL_TYPE_PTO_MODEL, MODEL_TYPE_ATO_MODEL) AND
10120         glPsNodeType(glIndexByPsNodeId(ntParentId(i))) = PS_NODE_TYPE_BOM_MODEL AND
10121         glIbTrackable(ntParentId(i)) = FLAG_NOT_IB_TRACKABLE) THEN
10122 
10123        --A trackable BOM Standard item cannot be a direct child of a non-trackable
10124        --ATO/PTO Model if this model is references from any Network Container model.
10125        --Re: bug #3644036.
10126 
10127        IF(NOT h_containerReferred.EXISTS(ntParentId(i)))THEN
10128 
10129          BEGIN
10130 
10131            EXECUTE IMMEDIATE containerReferred INTO h_containerReferred(ntParentId(i)) USING ntParentId(i);
10132 
10133          EXCEPTION
10134            WHEN NO_DATA_FOUND THEN
10135              h_containerReferred(ntParentId(i)) := 0;
10136          END;
10137        END IF;
10138 
10139        IF(h_containerReferred(ntParentId(i)) = 1)THEN
10140 
10141          errorMessage := thisProjectName;
10142          nParam := glIndexByPsNodeId(ntPsNodeId(i));
10143          RAISE CZ_S_TRACKABLE_STANDARD;
10144        END IF;
10145      END IF;
10146 
10147    --Prepare the actual effective date interval for populating global effectivity dates.
10148    --First get the nominal effective date interval either from an effectivity set or
10149    --from the local values.
10150 
10151      IF(ntEffSetId(i) IS NOT NULL)THEN
10152       IF(gvIndexBySetId.EXISTS(ntEffSetId(i)))THEN
10153        CurrentEffFrom := gvEffFrom(gvIndexBySetId(ntEffSetId(i)));
10154        CurrentEffUntil := gvEffUntil(gvIndexBySetId(ntEffSetId(i)));
10155       ELSE
10156         --This is a fatal error - data corruption.
10157         --'Invalid effectivity set associated with node ''%NODENAME'''
10158         errorMessage := CZ_UTILS.GET_TEXT('CZ_S_WRONG_EFFECTIVITY_SET', 'NODENAME', ntName(i));
10159         RAISE CZ_S_WRONG_EFFECTIVITY_SET;
10160       END IF;
10161      ELSE
10162        CurrentEffFrom := dtEffFrom(i);
10163        CurrentEffUntil := dtEffUntil(i);
10164      END IF;
10165      CurrentUsageMask := vtUsageMask(i);
10166 
10167    --Make sure effective dates are not null, so that actual effective date interval
10168    --will have no null bounds too. Usage mask is not null anyway.
10169 
10170      IF(CurrentEffFrom IS NULL)THEN CurrentEffFrom := EpochBeginDate; END IF;
10171      IF(CurrentEffUntil IS NULL)THEN CurrentEffUntil := EpochEndDate; END IF;
10172 
10173    --If this is not a model or a root component, adjust the effectivity dates by
10174    --intersecting with parent's actual effectivity dates, which have already been
10175    --calculated because of the hierarchichal order of the query.
10176    --Actual effective date interval is the intersection of parent's actual effective
10177    --date interval with child's nominal effective date interval. Again, no nulls.
10178 
10179      IF(ntParentId(i) IS NOT NULL)THEN
10180 
10181        localCount := glIndexByPsNodeId(ntParentId(i));
10182        IF(glEffFrom(localCount) > CurrentEffFrom)THEN CurrentEffFrom := glEffFrom(localCount); END IF;
10183        IF(glEffUntil(localCount) < CurrentEffUntil)THEN CurrentEffUntil := glEffUntil(localcount); END IF;
10184 
10185        --Adjust usage mask here. CurrentUsageMask is now OR-ed with glUsageMask(localCount)
10186        CurrentUsageMask := RAWTOHEX(UTL_RAW.BIT_OR(HEXTORAW(LPAD(CurrentUsageMask,16,'0')),HEXTORAW(glUsageMask(localCount))));
10187 
10188      END IF;
10189 
10190    --From now on the local variables (dtEff) or effectivity set, if defined, will contain
10191    --the nominal effective date interval while the global variables (glEff) will contain
10192    --the actual (intersected with parent) effective date interval.
10193    --The same is true for the usage mask nominal/actual values.
10194 
10195      glEffFrom(globalCount) := CurrentEffFrom;
10196      glEffUntil(globalCount) := CurrentEffUntil;
10197      glUsageMask(globalCount) := CurrentUsageMask;
10198 
10199      glHeaderByPsNodeId(ntPsNodeId(i)) := nStructureHeaderId;
10200      globalCount := globalCount + 1;
10201 
10202     ELSE
10203 
10204      localCount := glIndexByPsNodeId(ntPsNodeId(i));
10205      CurrentEffFrom := glEffFrom(localCount);
10206      CurrentEffUntil := glEffUntil(localCount);
10207      CurrentUsageMask := glUsageMask(localCount);
10208 
10209     END IF;
10210 
10211 nDebug := 1110012;
10212 
10213     IF(isLogicGenerated.EXISTS(inComponentId))THEN
10214 
10215       --We need to call the procedure for any non-virtual component (bug #2065239) and for any
10216       --component and reference.
10217 
10218       IF(ntPsNodeType(i) IN (PS_NODE_TYPE_REFERENCE, PS_NODE_TYPE_CONNECTOR))THEN
10219 
10220         --Check for circularity.
10221 
10222         localCount := 0;
10223 
10224         FOR n IN 1..globalLevel LOOP
10225          IF(globalStack(n) = ntReferenceId(i))THEN
10226 
10227            --Circularity detected.
10228 
10229            localCount := 1;
10230            EXIT;
10231          END IF;
10232         END LOOP;
10233 
10234         IF(localCount = 0)THEN
10235 
10236           globalLevel := globalLevel + 1;
10237           globalStack(globalLevel) := ntReferenceId(i);
10238           globalRef(globalLevel) := ntPsNodeId(i);
10239 
10240           IF(ntPsNodeType(i) = PS_NODE_TYPE_REFERENCE)THEN
10241 
10242             localMinString := TO_CHAR(ntMinimum(i));
10243             IF(localMinString IS NULL)THEN localMinString := '0'; END IF;
10244             localMaxString := TO_CHAR(ntMaximum(i));
10245             IF(localMaxString IS NULL)THEN localMaxString := '-1'; END IF;
10246 
10247             --Store the information on the instantiability of the reference on the stack.
10248 
10249             IF(localMinString = '1' AND localMaxString = '1')THEN
10250               globalInstance(globalLevel) := 0;
10251             ELSE
10252               globalInstance(globalLevel) := 1;
10253             END IF;
10254           ELSE
10255             --This is a connector and instantiability is not defined, but we need a value on
10256             --the stack.
10257 
10258             globalInstance(globalLevel) := 0;
10259           END IF;
10260 
10261           GENERATE_COMPONENT_TREE(ntReferenceId(i), ntReferenceId(i), NULL);
10262           globalLevel := globalLevel - 1;
10263 
10264           --Bug #5003285. Need to move the propagation of trackable flag into this branch which
10265           --executes even if child model is up-to-date.
10266 
10267           IF(ntPsNodeType(i) = PS_NODE_TYPE_REFERENCE AND rootProjectType = MODEL_TYPE_CONTAINER_MODEL AND
10268 
10269             --All the following verifications are to be made only if the referenced model is
10270             --a BOM Model - bug #2509208.
10271 
10272             glPsNodeType(glIndexByPsNodeId(ntReferenceId(i))) IN
10273               (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
10274 
10275             --If the referenced model is trackable it may be a trackable leaf. However, if its
10276             --trackableAncestor flag exists, it has trackable children. In any case we need to
10277             --mark all of its ancestors and make sure their quantities are not greater than 1,
10278             --because the root is a container model here.
10279 
10280             IF(glIbTrackable(ntReferenceId(i)) = FLAG_IB_TRACKABLE OR
10281                trackableAncestor.EXISTS(ntReferenceId(i)))THEN
10282 
10283                trackableAncestor(ntPsNodeId(i)) := 1;
10284                PROPAGATE_TRACKABLE_ANCESTOR;
10285             END IF;
10286           END IF;
10287         END IF;
10288 
10289       ELSIF(ntVirtualFlag(i) = FLAG_NON_VIRTUAL AND
10290             ntPsNodeType(i) IN (PS_NODE_TYPE_COMPONENT, PS_NODE_TYPE_PRODUCT) AND
10291             ntPsNodeId(i) <> inComponentId)THEN
10292 
10293         --We emulate the component as a model with generated logic because we do not want to
10294         --generate anything but still want to follow everything underneath this component.
10295 
10296         IsLogicGenerated(ntPsNodeId(i)) := 1;
10297 
10298         --We can pass logic header as NULL because it will never be actually used.
10299 
10300         GENERATE_COMPONENT_TREE(ntPsNodeId(i), inProjectId, 0);
10301       END IF;
10302 
10303       --Bug #5003285. Need to move the propagation of trackable flag into this branch which
10304       --executes even if child model is up-to-date.
10305 
10306       IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL AND
10307          ntPsNodeType(i) IN (PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD) AND
10308          glIbTrackable(ntPsNodeId(i)) = FLAG_IB_TRACKABLE)THEN
10309 
10310          PROPAGATE_TRACKABLE_ANCESTOR;
10311 
10312          --If the item is tangible, we should prohibit not only its ancestors but also itself
10313          --from being on the RHS of numeric rules - TSO with Equipment.
10314 
10315          IF(ntShippableFlag(i) = '1')THEN trackableAncestor(ntPsNodeId(i)) := 2; END IF;
10316       END IF;
10317 
10318     --If no logic already exists, generate the structure.
10319 
10320     ELSE
10321 
10322     GENERATE_EFFECTIVITY_LOGIC(CurrentEffFrom, CurrentEffUntil, CurrentUsageMask);
10323 
10324     IF(ntPsNodeType(i) = PS_NODE_TYPE_OPTION)THEN
10325 
10326       --We are in a feature's options. The important assumption here is that a feature
10327       --can have only options as it's children,so feature's children list is dense and
10328       --all the feature's children should be processed, and this list starts here.
10329       --In other words, we assume that as soon as we encountered the first option of a
10330       --feature, we will be dealing only with options of this feature until we process
10331       --all of them.
10332 
10333       /*--The restriction is removed (bug #1746927)-----------------------------------
10334         --First make sure that there aren't too many options.
10335       IF(optionCounter > MAX_NUMBER_OF_OPTIONS)THEN
10336         --This will be fatal and terminate the logic generation
10337         --'Option feature has more than maximum allowed number of options, feature ''%FEATNAME'''
10338         errorMessage := CZ_UTILS.GET_TEXT('CZ_S_TOO_MANY_OPTIONS', 'FEATNAME', ntName(i));
10339         RAISE CZ_S_TOO_MANY_OPTIONS;
10340       END IF;
10341       ------------------------------------------------------------------------------*/
10342 
10343       optionCounter := optionCounter + 1;
10344 
10345       --Generate the option: OBJECT P_<OptID> R
10346       vLogicLine := 'OBJECT P_' || TO_CHAR(ntPersistentId(i)) || ' R' || NewLine;
10347 
10348       --If this is the last option, we will generate the feature right here
10349 
10350       IF(ntParentId(i + 1) <> ntParentId(i))THEN
10351 
10352         --Done with options, ready to generate the feature, put in the stored
10353         --effectivity information.
10354 
10355         PACK;
10356         GENERATE_EFFECTIVITY_LOGIC(FeatureEffFrom, FeatureEffUntil, FeatureUsageMask);
10357 
10358         --This is the feature index
10359 
10360         j := i - optionCounter;
10361 
10362         --Generate the feature itself. Local variables here are inherited from the feature
10363         --generation section.
10364         --But before that adjust the minimum number of selected children to the actual number
10365         --of options - bug #2233795.
10366 
10367         IF(ntMinimum(j) IS NOT NULL AND ntMinimum(j) > optionCounter)THEN
10368 
10369           localMinString := TO_CHAR(optionCounter);
10370         END IF;
10371 
10372         vLogicLine := 'SGN P_' || TO_CHAR(ntPersistentId(j)) || ' R ' || localMinString || ' ' ||
10373         localMaxString || ' _';
10374 
10375 nDebug := 1110028;
10376 
10377         --Generate the list of options for the feature
10378 
10379         WHILE(j < i)LOOP
10380 
10381          j := j + 1;
10382 
10383          --This call is necessary here for wrapping
10384 
10385          PACK;
10386          vLogicLine := ' P_' || TO_CHAR(ntPersistentId(j));
10387 
10388 nDebug := 1110029;
10389 
10390         END LOOP;
10391 
10392         --We must put [new line] after the list of options
10393 
10394         vLogicLine := vLogicLine || NewLine;
10395         j := i - optionCounter;
10396 
10397         PACK;
10398         GENERATE_ACCUMULATOR(j);
10399         generatingFeature := 0;
10400 
10401         --Minimum number of selected options greater than the actual number of options.
10402         --The feature is already generated and now will be reported.
10403 
10404         IF(ntMinimum(j) IS NOT NULL AND ntMinimum(j) > optionCounter)THEN
10405 
10406          RAISE CZ_S_ILLEGAL_OPTION_FEATURE;
10407         END IF;
10408 
10409       END IF;
10410 
10411     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_TOTAL OR
10412        ntPsNodeType(i) = PS_NODE_TYPE_RESOURCE)THEN
10413 
10414 nDebug := 1110014;
10415 
10416     --This is a total or resource: TOTAL P_<Tot/ResID> R [tot/res initial value]
10417 
10418      vLogicLine := 'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || ' R ' ||
10419                    ntInitialValue(i) || NewLine;
10420     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_FEATURE)THEN
10421 
10422 nDebug := 1110015;
10423 
10424     --This is a feature, so consider different subtypes
10425 
10426      IF(ntFeatureType(i) IS NULL OR ntFeatureType(i) = PS_NODE_FEATURE_TYPE_INTEGER)THEN
10427 
10428 nDebug := 1110016;
10429 
10430      --This is an integer feature: real integer or count
10431 
10432       IF(ntMinimum(i) IS NULL OR ntMinimum(i) < 0)THEN
10433 
10434 nDebug := 1110017;
10435 
10436       --This is a real integer feature: TOTAL P_<FeatID> R [initial_value]
10437 
10438        vLogicLine := 'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || ' R ' ||
10439                      ntInitialValue(i) || NewLine;
10440       ELSE
10441 
10442 nDebug := 1110018;
10443 
10444       --This is a count feature: OBJECT P_<FeatID> R [initial_value]
10445 
10446 /* This is rolled back as a fix for the bug #1994924.
10447 
10448        --If initial value is not specified and minimum value is greater than 0, we
10449        --define the initial value to be equal to the minimum value. Bug #1834581.
10450 
10451        IF(ntInitialValue(i) IS NULL)THEN
10452          ntInitialValue(i) := ntMinimum(i);
10453        END IF;
10454 */
10455        vLogicLine := 'OBJECT P_' || TO_CHAR(ntPersistentId(i)) || ' R ' ||
10456                      ntInitialValue(i) || NewLine;
10457       END IF;
10458      ELSIF(ntFeatureType(i) = PS_NODE_FEATURE_TYPE_FLOAT)THEN
10459 
10460 nDebug := 1110019;
10461 
10462      --This is a decimal feature: TOTAL P_<FeatID> R [initial_value]
10463 
10464 /* This is rolled back as a fix for the bug #1994924.
10465 
10466       --If initial value is not specified and minimum value is specified and is greater than 0,
10467       --we define the initial value to be equal to the minimum value. Bug #1834581.
10468 
10469       IF(ntInitialValue(i) IS NULL AND ntMinimum(i) > 0)THEN
10470         ntInitialValue(i) := ntMinimum(i);
10471       END IF;
10472 */
10473       vLogicLine := 'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || ' R ' ||
10474                     ntInitialValue(i) || NewLine;
10475      ELSIF(ntFeatureType(i) = PS_NODE_FEATURE_TYPE_BOOLEAN)THEN
10476 
10477 nDebug := 1110020;
10478 
10479      --This is a boolean feature
10480 
10481       vLogicLine := 'OBJECT P_' || TO_CHAR(ntPersistentId(i)) || ' R' || NewLine;
10482       IF(ntInitialValue(i) IS NOT NULL)THEN
10483        IF(ntInitialValue(i) = '1')THEN
10484 
10485 nDebug := 1110021;
10486 
10487        --Initial value is 'True', create a default rule from an always true object
10488        --toward this one
10489 
10490         vLogicLine := vLogicLine || 'OBJECT D_' || TO_CHAR(ntPersistentId(i)) || '_IV' || NewLine ||
10491           'WITH _default = _ALWAYS_TRUE' || NewLine ||
10492           'GS R ... ' || TO_CHAR(ntDescriptionId(i)) || NewLine ||
10493           'GL N D_' || TO_CHAR(ntPersistentId(i)) || '_IV' || NewLine ||
10494           'GR N P_' || TO_CHAR(ntPersistentId(i)) || NewLine;
10495 
10496 --        vLogicLine := vLogicLine || 'WITH _default = _ALWAYS_TRUE' || NewLine;
10497 
10498        ELSIF(ntInitialValue(i) = '0')THEN
10499 
10500 nDebug := 1110022;
10501 
10502        --Initial value is 'False', create a temporary object and an additional
10503        --'negates' relation
10504 
10505         vLogicLine := vLogicLine || 'OBJECT D_' || TO_CHAR(ntPersistentId(i)) || '_IV' || NewLine ||
10506           'WITH _default = _ALWAYS_TRUE' || NewLine ||
10507           'GS N ... ' || TO_CHAR(ntDescriptionId(i)) || NewLine ||
10508           'GL N D_' || TO_CHAR(ntPersistentId(i)) || '_IV' || NewLine ||
10509           'GR N P_' || TO_CHAR(ntPersistentId(i)) || NewLine;
10510 
10511        ELSE
10512 
10513         RAISE CZ_S_BAD_BOOLEAN_FEAT_VALUE;
10514 
10515        END IF;
10516       END IF;
10517 
10518      ELSIF(ntFeatureType(i) = PS_NODE_FEATURE_TYPE_STRING)THEN
10519 
10520 nDebug := 1110023;
10521 
10522        NULL;
10523 
10524 /* Do not need to generate anything for text features.
10525 
10526      --This is a text feature
10527 
10528       vLogicLine := 'TEXT P_' || TO_CHAR(ntPersistentId(i)) || ' R "' ||
10529                   ntInitialValue(i) || '"' || NewLine;
10530 */
10531      ELSIF(ntFeatureType(i) = PS_NODE_FEATURE_TYPE_OPTION)THEN
10532 
10533       --Set the options counter
10534 
10535       optionCounter := 0;
10536 
10537       --Prepare Min, Max values for later use
10538       --Use intermediate variable instead of using NVL because this is faster
10539       --This values will be used also when generating the last option of the feature
10540 
10541       localMinString := TO_CHAR(ntMinimum(i));
10542       IF(localMinString IS NULL)THEN localMinString := '0'; END IF;
10543       localMaxString := TO_CHAR(ntMaximum(i));
10544       IF(localMaxString IS NULL)THEN localMaxString := '-1'; END IF;
10545 
10546       --Save feature's effective intervals and usage mask for feature generating type
10547 
10548       FeatureEffFrom := CurrentEffFrom;
10549       FeatureEffUntil := CurrentEffUntil;
10550       FeatureUsageMask := CurrentUsageMask;
10551 
10552 nDebug := 1110024;
10553 
10554       --Check if there are any children, report if not
10555 
10556       IF(ntParentId(i + 1) <> ntPsNodeId(i))THEN
10557 
10558         --No options, still want to generate the feature even with empty options list
10559 
10560         vLogicLine := 'SGN P_' || TO_CHAR(ntPersistentId(i)) || ' R ' || localMinString || ' ' ||
10561         localMaxString || ' _' || NewLine;
10562 
10563         --No children, report the feature
10564         RAISE CZ_S_FEATURE_NO_CHILDREN;
10565       END IF;
10566 
10567       --Now proceed with the cycle. As options of the feature directly follows it in memory,
10568       --we will be generating them right away. After the last option, the feature itself will
10569       --be generated (see options generating code).
10570 
10571       generatingFeature := 1;
10572 
10573 nDebug := 1110027;
10574 
10575      ELSE
10576 
10577        --'Unknown feature type, feature ''%FEATNAME'''
10578        errorMessage := CZ_UTILS.GET_TEXT('CZ_S_UNKNOWN_FEATURE_TYPE', 'FEATNAME', ntName(i));
10579        RAISE CZ_S_UNKNOWN_FEATURE_TYPE;
10580      END IF;
10581     ELSIF(ntPsNodeType(i) IN (PS_NODE_TYPE_COMPONENT, PS_NODE_TYPE_PRODUCT) AND
10582           ntVirtualFlag(i) = FLAG_NON_VIRTUAL)THEN
10583 
10584 nDebug := 1110030;
10585 
10586      --We don't want to go into an infinite cycle - don't call the procedure for the current
10587      --root component
10588 
10589      IF(ntPsNodeId(i) <> inComponentId)THEN
10590 
10591       --This is another non-virtual component. Call this function for it - recursion
10592       --Use intermediate variable instead of using NVL because this is faster
10593 
10594       localMinString := TO_CHAR(ntMinimum(i));
10595       IF(localMinString IS NULL)THEN localMinString := '0'; END IF;
10596       localMaxString := TO_CHAR(ntMaximum(i));
10597       IF(localMaxString IS NULL)THEN localMaxString := '-1'; END IF;
10598 
10599       vLogicLine := 'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_MIN R ' || localMinString || NewLine ||
10600                     'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_MAX R ' || localMaxString || NewLine ||
10601                     'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_ACTUALCOUNT R 0' || NewLine;
10602 
10603       GENERATE_COMPONENT_TREE(ntPsNodeId(i), inProjectId, nStructureHeaderId);
10604      END IF;
10605 
10606     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_REFERENCE)THEN
10607 
10608 nDebug := 1110031;
10609 
10610      --Check for circularity.
10611 
10612      localCount := 0;
10613      trackableContext := 0;
10614      instantiableContext := 0;
10615 
10616      FOR n IN 1..globalLevel LOOP
10617 
10618       IF(globalStack(n) = ntReferenceId(i))THEN
10619 
10620         --Circularity detected.
10621 
10622         localCount := 1;
10623         EXIT;
10624       END IF;
10625 
10626       IF(glIbTrackable(globalStack(n)) = FLAG_IB_TRACKABLE)THEN
10627 
10628         trackableContext := globalStack(n);
10629       END IF;
10630 
10631       IF(globalInstance(n) = 1)THEN
10632 
10633         instantiableContext := globalStack(n);
10634       END IF;
10635      END LOOP;
10636 
10637      localMinString := TO_CHAR(ntMinimum(i));
10638      IF(localMinString IS NULL)THEN localMinString := '0'; END IF;
10639      localMaxString := TO_CHAR(ntMaximum(i));
10640      IF(localMaxString IS NULL)THEN localMaxString := '-1'; END IF;
10641 
10642      IF(ntVirtualFlag(i) = FLAG_NON_VIRTUAL)THEN
10643 
10644        vLogicLine := 'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_MIN R ' || localMinString || NewLine ||
10645                      'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_MAX R ' || localMaxString || NewLine ||
10646                      'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_ACTUALCOUNT R 0' || NewLine;
10647      END IF;
10648 
10649      IF(localCount = 0)THEN
10650 
10651        --Follow the reference, doesn't affect the current LCE file.
10652        --Use intermediate variable instead of using NVL because this is faster.
10653        --Maintain the stack of references - needed to be able to detect dead-loops.
10654 
10655        globalLevel := globalLevel + 1;
10656        globalStack(globalLevel) := ntReferenceId(i);
10657        globalRef(globalLevel) := ntPsNodeId(i);
10658 
10659        --Store the information on the instantiability of the reference on the stack.
10660 
10661        IF(localMinString = '1' AND localMaxString = '1')THEN
10662          globalInstance(globalLevel) := 0;
10663        ELSE
10664          globalInstance(globalLevel) := 1;
10665        END IF;
10666 
10667        GENERATE_COMPONENT_TREE(ntReferenceId(i), ntReferenceId(i), NULL);
10668        globalLevel := globalLevel - 1;
10669 
10670        IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL AND
10671 
10672           --All the following verifications are to be made only if the referenced model is
10673           --a BOM Model - bug #2509208.
10674 
10675           glPsNodeType(glIndexByPsNodeId(ntReferenceId(i))) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
10676 
10677          errorMessage := glName(glIndexByPsNodeId(ntReferenceId(i)));
10678 
10679          --If this is a network container model, every reference to a trackable model should
10680          --have exactly minimum = 0 and maximum = -1. This validation must be made after the
10681          --referenced model is processed so that its IB_TRACKABLE flag has become available.
10682          --IB_TRACKABLE flag for the instantiably referenced model should not be null.
10683 
10684          IF(glIbTrackable(ntReferenceId(i)) IS NULL)THEN
10685 
10686            RAISE CZ_S_NO_TRACKABLE_FLAG;
10687 
10688          ELSIF(trackableContext = 0 AND glIbTrackable(ntReferenceId(i)) = FLAG_IB_TRACKABLE)THEN
10689 
10690            --This is a trackable instance model, make additional verifications.
10691 
10692            IF(instanceModel.EXISTS(ntReferenceId(i)) AND
10693               (globalLevel > 1 OR instanceModel(ntReferenceId(i)) > 1))THEN
10694 
10695              --Multiple occurrences of a trackable instance model. We allow them only if all
10696              --of them are immediate children of the container model, because they may have
10697              --different effectivity ranges.
10698 
10699              nParam := glIndexByPsNodeId(globalStack(globalLevel - 1));
10700              RAISE CZ_S_MULTIPLE_TRACKABLE;
10701 
10702            ELSIF(instantiableContext > 0)THEN
10703 
10704              --One of the ancestors of the trackable instance model is multiply instantiable.
10705 
10706              nParam := glIndexByPsNodeId(instantiableContext);
10707              RAISE CZ_S_MULTIPLE_INSTANCES;
10708 
10709            ELSIF(localMinString <> '0' OR localMaxString <> '-1')THEN
10710 
10711              --Incorrect instance numbers for a reference to a trackable instance model.
10712 
10713              RAISE CZ_S_INCORRECT_CONTAINER;
10714 
10715            ELSE
10716 
10717              instanceModel(ntReferenceId(i)) := globalLevel;
10718            END IF;
10719          END IF;
10720 
10721          --If the referenced model is trackable it may be a trackable leaf. However, if its
10722          --trackableAncestor flag exists, it has trackable children. In any case we need to
10723          --mark all of its ancestors and make sure their quantities are not greater than 1,
10724          --because the root is a container model here.
10725 
10726          IF(glIbTrackable(ntReferenceId(i)) = FLAG_IB_TRACKABLE OR
10727             trackableAncestor.EXISTS(ntReferenceId(i)))THEN
10728 
10729            trackableAncestor(ntPsNodeId(i)) := 1;
10730            PROPAGATE_TRACKABLE_ANCESTOR;
10731          END IF;
10732        END IF;
10733      END IF;
10734 
10735     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_CONNECTOR)THEN
10736 
10737      --Go and generate the connection target. At least we need to have its structure in
10738      --memory, but there is also a versioning problem.
10739      --Check for circularity.
10740 
10741      localCount := 0;
10742      trackableContext := 0;
10743 
10744      FOR n IN 1..globalLevel LOOP
10745       IF(globalStack(n) = ntReferenceId(i))THEN
10746 
10747         --Circularity detected.
10748 
10749         localCount := 1;
10750         EXIT;
10751       END IF;
10752 
10753       IF(glIbTrackable(globalStack(n)) = FLAG_IB_TRACKABLE)THEN
10754 
10755         trackableContext := globalStack(n);
10756       END IF;
10757      END LOOP;
10758 
10759      IF(localCount = 0)THEN
10760 
10761        globalLevel := globalLevel + 1;
10762        globalStack(globalLevel) := ntReferenceId(i);
10763        globalRef(globalLevel) := ntPsNodeId(i);
10764 
10765        --This is a connector and instantiability is not defined, but we need a value on
10766        --the stack.
10767 
10768        globalInstance(globalLevel) := 0;
10769 
10770        GENERATE_COMPONENT_TREE(ntReferenceId(i), ntReferenceId(i), NULL);
10771        globalLevel := globalLevel - 1;
10772 
10773        IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
10774 
10775          --Definition: trackable instance model is a trackable model that has no trackable
10776          --ancestors. In a container model no connectors to trackable instance models are
10777          --allowed. In other words, any connector to a trackable model in a container model
10778          --should be inside a trackable child of the container model.
10779 
10780          IF(glIbTrackable(ntReferenceId(i)) = FLAG_IB_TRACKABLE AND trackableContext = 0)THEN
10781 
10782            errorMessage := thisProjectName;
10783            nParam := glIndexByPsNodeId(ntReferenceId(i));
10784            RAISE CZ_S_CONNECTOR_TRACKABLE;
10785          END IF;
10786 
10787          --Inside a trackable model no connector to a non-trackable model is allowed on any
10788          --level in a container model.
10789 
10790          IF((glIbTrackable(ntReferenceId(i)) IS NULL OR glIbTrackable(ntReferenceId(i)) <> FLAG_IB_TRACKABLE) AND
10791             trackableContext > 0)THEN
10792 
10793            errorMessage := glName(glIndexByPsNodeId(ntReferenceId(i)));
10794            nParam := glIndexByPsNodeId(trackableContext);
10795            RAISE CZ_S_CONNECT_NONTRACKABLE;
10796          END IF;
10797        END IF;
10798      END IF;
10799 
10800     ELSIF(ntPsNodeType(i) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
10801 
10802 nDebug := 1110032;
10803 
10804     --Run the TSO with Equipment validations before generating logic.
10805 
10806     IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL OR
10807        thisProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
10808 
10809       errorMessage := thisProjectName;
10810       thisName := ntName(i);
10811       parentName := '';
10812       IF(ntParentId(i) IS NOT NULL)THEN parentName := glName(glIndexByPsNodeId(ntParentId(i))); END IF;
10813 
10814       IF(ntShippableFlag(i) IS NULL OR ntTransactableFlag(i) IS NULL OR
10815          ntAtoFlag(i) IS NULL OR ntSerializableFlag(i) IS NULL) THEN
10816 
10817        --'The BOM Model ''%MODELNAME'' is out of date. Please refresh the Model by running the Refresh a Single
10818        -- Configuration Model concurrent program and then regenerate the Active Model.'
10819 
10820        RAISE CZ_LCE_MODEL_OUTOFDATE;
10821       END IF; --The new flags are null, need to refresh.
10822 
10823       IF((ntPsNodeType(i) IN (PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_MODEL)) AND
10824          (ntShippableFlag(i) = '1' OR ntTransactableFlag(i) = '1'))THEN
10825 
10826        --'Incorrect BOM Model or Option Class ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
10827        -- Only BOM Standard Items can be shippable and inventory transactable.'
10828 
10829        RAISE CZ_LCE_INCORRECT_BOM;
10830       END IF; --Flags are set for a non-Standard item node.
10831 
10832       IF(ntPsNodeType(i) = PS_NODE_TYPE_BOM_STANDARD)THEN
10833         IF(ntShippableFlag(i) <> ntTransactableFlag(i))THEN
10834 
10835           --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
10836           -- All shippable items should be inventory transactable and vice versa.'
10837 
10838           RAISE CZ_LCE_INCORRECT_ITEM;
10839         END IF; -- ntShippableFlag <> ntTransactableFlag.
10840 
10841         IF(ntShippableFlag(i) = '1' AND ((ntAtoFlag(i) <> '0') OR (NVL(ntIbTrackable(i), '0') <> '1')))THEN
10842 
10843        --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
10844        -- All shippable items should be trackable non-ATO standard items with maximum quantity 1.'
10845 
10846           RAISE CZ_LCE_INCORRECT_TANGIBLE;
10847         END IF; --ntShippableFlag = '1'.
10848 
10849         IF(ntShippableFlag(i) = '1' AND ntSerializableFlag(i) = '0')THEN
10850 
10851           --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
10852           -- All shippable items should be serializable trackable non-ATO standard items.'
10853 
10854           RAISE CZ_LCE_INCORRECT_SHIPPABLE;
10855         END IF; --ntShippableFlag = '1' AND ntSerializableFlag = '0';
10856       END IF; --Standard Item.
10857     END IF; --MACD Container.
10858 
10859 nDebug := 1110033;
10860 
10861      --Generate header.
10862 
10863      vLogicLine := 'BOM P_' || TO_CHAR(ntPersistentId(i)) || ' R ';
10864 
10865      --BOM modifier.
10866 
10867      IF(ntPsNodeType(i) = PS_NODE_TYPE_BOM_STANDARD)THEN
10868        vLogicLine := vLogicLine || 'S';
10869      ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_BOM_OPTIONCLASS)THEN
10870        vLogicLine := vLogicLine || 'O';
10871      ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_BOM_MODEL)THEN
10872        vLogicLine := vLogicLine || 'M';
10873 
10874        --This is a BOM model, it can be only the root model, so that thisProjectType and
10875        --thisProjectName are currently referring to it.
10876 
10877        IF(ntIbTrackable(i) = FLAG_IB_TRACKABLE AND thisProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
10878 
10879          --A network container model should not be trackable.
10880 
10881          errorMessage := thisProjectName;
10882          RAISE CZ_S_TRACKABLE_CONTAINER;
10883        END IF;
10884      ELSE
10885 
10886        --'Unknown BOM node type, node ''%NODENAME'''
10887        errorMessage := CZ_UTILS.GET_TEXT('CZ_S_UNKNOWN_BOM_NODE_TYPE', 'NODENAME', ntName(i));
10888        RAISE CZ_S_UNKNOWN_BOM_NODE_TYPE;
10889      END IF;
10890 
10891      IF(ntPsNodeType(i) IN (PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD) AND
10892         glIbTrackable(ntPsNodeId(i)) = FLAG_IB_TRACKABLE)THEN
10893 
10894        --Trackable Standard Items/Option Classes are not allowed as immediate children of a
10895        --network container model.
10896 
10897        IF(thisProjectType = MODEL_TYPE_CONTAINER_MODEL AND
10898           glPsNodeType(glIndexByPsNodeId(ntParentId(i))) = PS_NODE_TYPE_BOM_MODEL)THEN
10899 
10900          errorMessage := thisProjectName;
10901          nParam := glIndexByPsNodeId(ntPsNodeId(i));
10902          RAISE CZ_S_TRACKABLE_CHILDREN;
10903        END IF;
10904 
10905        --As this is a trackable Standard Item or Option Class we need to mark all of its
10906        --ancestors and make sure their quantities are not greater than 1, if the root is
10907        --a container model.
10908 
10909        IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
10910 
10911          PROPAGATE_TRACKABLE_ANCESTOR;
10912 
10913          --If the item is tangible, we should prohibit not only its ancestors but also itself
10914          --from being on the RHS of numeric rules - TSO with Equipment.
10915 
10916          IF(ntShippableFlag(i) = '1')THEN trackableAncestor(ntPsNodeId(i)) := 2; END IF;
10917        END IF;
10918      END IF;
10919 
10920      --Add the decimal quantity modifier if necessary
10921 
10922      IF(ntDecimalQty(i) = FLAG_DECIMAL_QTY)THEN
10923       vLogicLine := vLogicLine || 'D';
10924      END IF;
10925 
10926 nDebug := 1110034;
10927 
10928      --BOM required flag + minimum which is always 0
10929 
10930      IF(ntBomRequired(i) = FLAG_BOM_REQUIRED)THEN
10931       vLogicLine := vLogicLine || ' RC 0 ';
10932      ELSE
10933       vLogicLine := vLogicLine || ' NRC 0 ';
10934      END IF;
10935 
10936 nDebug := 1110035;
10937 
10938      --Maximum selected
10939 
10940      IF(ntMaximumSel(i) IS NOT NULL)THEN
10941       vLogicLine := vLogicLine || TO_CHAR(ntMaximumSel(i)) || ' ';
10942      ELSE
10943       vLogicLine := vLogicLine || '-1 ';
10944      END IF;
10945 
10946 nDebug := 1110036;
10947 
10948      --Parent 'logic' name if any
10949 
10950      IF(ntParentId(i) IS NOT NULL AND
10951         glPsNodeType(glIndexByPsNodeId(ntParentId(i))) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
10952 
10953       --Fix for the bug #1745394. If a BOM parent is of decimal quantity and it's child is of
10954       --integer quantity, fatal error will be raised.
10955 
10956       IF(glDecimalQty(ntParentId(i)) = FLAG_DECIMAL_QTY AND ntDecimalQty(i) = FLAG_INTEGER_QTY)THEN
10957 
10958        --'Node ''%CHILDNAME'' must allow decimal quantity since its parent ''%PARENTNAME'' allows decimal quantity'
10959        errorMessage := CZ_UTILS.GET_TEXT('CZ_S_INCONSISTENT_QUANTITY', 'CHILDNAME', ntName(i),
10960                                                                        'PARENTNAME', glName(glIndexByPsNodeId(ntParentId(i))));
10961         RAISE CZ_S_INCONSISTENT_QUANTITY;
10962       END IF;
10963 
10964       vLogicLine := vLogicLine || 'P_' || TO_CHAR(glPersistentId(ntParentId(i))) || ' ';
10965      END IF;
10966 
10967 nDebug := 1110037;
10968 
10969      --Default quantity. If initial_value is not null and can't be converted to
10970      --a number the VALUE_ERROR exception will be raised. We catch this one and
10971      --re-raise our own exception for better reporting.
10972 
10973      BEGIN
10974       IF(ntInitialValue(i) IS NOT NULL AND TO_NUMBER(ntInitialValue(i)) > 0)THEN
10975        vLogicLine := vLogicLine || ntInitialValue(i) || ' ... ' || ntDescriptionId(i) || NewLine;
10976       ELSE
10977        vLogicLine := vLogicLine || '0' || ' ... ' || ntDescriptionId(i) || NewLine;
10978       END IF;
10979      EXCEPTION
10980        WHEN VALUE_ERROR THEN
10981          RAISE CZ_S_WRONG_INITIAL_VALUE;
10982      END;
10983 
10984     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_FEATUREGROUP)THEN
10985 
10986      NULL;
10987 
10988     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_COMPONENT)THEN
10989 
10990      NULL;
10991 
10992     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_PRODUCT)THEN
10993 
10994      NULL;
10995 
10996     ELSE
10997 
10998      --'Unknown node type, node ''%NODENAME'''
10999      errorMessage := CZ_UTILS.GET_TEXT('CZ_S_UNKNOWN_NODE_TYPE', 'NODENAME', ntName(i));
11000      RAISE CZ_S_UNKNOWN_NODE_TYPE;
11001     END IF;
11002     END IF; --End of the IF block of 'if logic does not already exist' inside the main loop
11003 
11004   --This exception handler may be used to catch the 'logic item'-level exceptions
11005   --that shouldn't stop the process. If an exception is re-raised here it becomes
11006   --a fatal exception (warning vs. errors).
11007 
11008    EXCEPTION
11009      WHEN CZ_S_BAD_BOOLEAN_FEAT_VALUE THEN
11010 --'Bad boolean feature value, feature ''%FEATNAME'''
11011        REPORT(CZ_UTILS.GET_TEXT('CZ_S_BAD_BOOLEAN_FEAT_VALUE', 'FEATNAME', ntName(i)), 1);
11012      WHEN CZ_S_FEATURE_NO_CHILDREN THEN
11013 --'Option feature has no children, feature ''%FEATNAME'''
11014        REPORT(CZ_UTILS.GET_TEXT('CZ_S_FEATURE_NO_CHILDREN', 'FEATNAME', ntName(i)), 1);
11015      WHEN CZ_S_ILLEGAL_OPTION_FEATURE THEN
11016 --'Feature ''%FEATNAME'' has no options or fewer options than its minimum count, feature ''%FEATNAME'''
11017        REPORT(CZ_UTILS.GET_TEXT('CZ_S_ILLEGAL_OPTION_FEATURE', 'FEATNAME', ntName(j)), 1);
11018      WHEN CZ_S_WRONG_INITIAL_VALUE THEN
11019 --'Initial value of BOM node is not null and can not be converted to number, node ''%NODENAME'''
11020        REPORT(CZ_UTILS.GET_TEXT('CZ_S_WRONG_INITIAL_VALUE', 'NODENAME', ntName(i)), 1);
11021 
11022   --Fatal exceptions section. Exceptions are re-raised to be reported at the higher level.
11023 
11024      WHEN CZ_S_DEADLOOP_DETECTED THEN --Currently never thrown.
11025 --As per bug #3593513, when thrown should probably be moved to the place where thrown. Otherwise going up from
11026 --the recursion overwites the message substituting incorrect names.
11027 
11028 --'An infinite loop detected: models ''%MODELNAME'' and ''%CHILDNAME'' reference each other'
11029        errorMessage := CZ_UTILS.GET_TEXT('CZ_S_DEADLOOP_DETECTED', 'MODELNAME', glName(glIndexByPsNodeId(globalStack(globalLevel))),
11030                                                                    'CHILDNAME', glName(glIndexByPsNodeId(globalStack(nParam))));
11031        RAISE;
11032    END;
11033 
11034    --This procedure implements wrapping. A call to it is included in options list generation
11035    --for an option feature above
11036 
11037    PACK;
11038 
11039 nDebug := 1110040;
11040 
11041    IF(NOT IsLogicGenerated.EXISTS(inComponentId))THEN
11042 
11043      --generatingFeature is set to 1 when we step over an option feature with actual options. It will
11044      --be unset when we finally generate the feature after all of its options. But while generating
11045      --the options we want to call this procedure for every of them. This is why we check the type
11046      --and if it is an option, call the procedure even though the flag is set.
11047 
11048      IF(generatingFeature = 0 OR ntPsNodeType(i) = PS_NODE_TYPE_OPTION)THEN GENERATE_ACCUMULATOR(i); END IF;
11049    END IF;
11050 
11051    --Increase the main cycle counter
11052 
11053    i := i + 1;
11054 
11055   END LOOP; --End of the main structure generation cycle
11056 
11057 nDebug := 1110038;
11058 
11059   ELSE --IF 'there is some data returned'
11060 
11061     --The project is empty, stop here.
11062 
11063     errorMessage := thisProjectName;
11064     RAISE CZ_S_NO_DATA_IN_PROJECT;
11065 
11066   END IF; --Ends the ELSE block of IF 'there is some data returned'
11067 
11068   IF(NOT IsLogicGenerated.EXISTS(inComponentId))THEN
11069 
11070    --Flush the buffer
11071 
11072    IF(vLogicText IS NOT NULL)THEN
11073     INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
11074      (nStructureHeaderId, nSequenceNbr, vLogicText);
11075     vLogicText := NULL;
11076    END IF;
11077 
11078    --Remember the next sequence number for this logic file. Will be used in
11079    --numeric rules generation for accumulators.
11080 
11081    vSeqNbrByHeader(nStructureHeaderId) := nSequenceNbr + 1;
11082 
11083    IF(TwoPhaseCommit = 0)THEN COMMIT; END IF;
11084   END IF;
11085 
11086 nDebug := 1110039;
11087 
11088   --If a model, generate rules and set the logic generated flag.
11089 
11090   IF(inParentLogicHeaderId IS NULL)THEN
11091 
11092 
11093      -- LA 13733007 : No children OC
11094      -- Report option classes with no children or all ineffective children
11095      -- This code is also used in FCE logic gen and BOM Import.
11096      -- Currently repeated this code in all the packages but later need to move to some common place
11097      -- This query is used to report all the OCs under Root model and it's reference chain
11098 
11099      IF(inComponentId = inDevlProjectId)THEN
11100        BEGIN
11101          SELECT MODEL.NAME,  PARENT.NAME
11102          BULK COLLECT INTO lNoChildOCModelName, lNoChildOCName
11103          FROM cz_ps_nodes PARENT, cz_rp_entries MODEL
11104          WHERE PARENT.deleted_flag = '0'
11105          AND MODEL.deleted_flag = '0'
11106          AND PARENT.devl_project_id = MODEL.object_id
11107          AND MODEL.object_type = 'PRJ'
11108          AND parent.devl_project_id IN
11109            (SELECT DISTINCT component_id FROM cz_model_ref_expls
11110             WHERE deleted_flag = '0' AND model_id = inDevlProjectId
11111             AND (ps_node_type = CZ_TYPES.PS_NODE_TYPE_REFERENCE
11112             OR ps_node_type = CZ_TYPES.PS_NODE_TYPE_BOM_MODEL))
11113          AND PARENT.ps_node_type = CZ_TYPES.PS_NODE_TYPE_BOM_OPTION_CLASS
11114          AND PARENT.effective_until > SYSDATE
11115          AND NOT EXISTS
11116            (SELECT 1 FROM cz_ps_nodes CHILD
11117             WHERE CHILD.deleted_flag = '0'
11118             AND CHILD.devl_project_id = PARENT.devl_project_id
11119             AND CHILD.parent_id = PARENT.ps_node_id
11120             AND CHILD.effective_until > SYSDATE);
11121 
11122          IF (lNoChildOCModelName.COUNT > 0) THEN
11123            FOR i IN 1..lNoChildOCModelName.COUNT
11124            LOOP
11125              REPORT('Option class has no effective children, option class ''' || lNoChildOCName(i) || '''', 1);
11126            END LOOP;
11127          END IF;
11128        EXCEPTION
11129          WHEN NO_DATA_FOUND THEN
11130            null;
11131        END;
11132      END IF;
11133 nDebug := 1110041;
11134 
11135     --Generate model's rules and expressions if necessary
11136 
11137     IF(NOT IsLogicGenerated.EXISTS(inComponentId))THEN
11138       GENERATE_RULES;
11139       IsLogicGenerated(inComponentId) := 1;
11140     END IF;
11141   END IF;
11142 END; --GENERATE_COMPONENT_TREE
11143 ---------------------------------------------------------------------------------------
11144 PROCEDURE COMMIT_HEADERS IS
11145   localOldHeaders  tIntegerArray;
11146   nCount           PLS_INTEGER := 1;
11147   localComponent   NUMBER := NULL; --kdande; Bug 6881902; 11-Mar-2008
11148 BEGIN
11149 
11150    FOR i IN 1..NewHeaders.COUNT LOOP
11151     IF(((NOT IsLogicGenerated.EXISTS(NewHeadersComponents(i))) OR IsLogicGenerated(NewHeadersComponents(i)) = 1) AND
11152        (localComponent IS NULL OR NewHeadersComponents(i) <> localComponent))THEN
11153 
11154       localOldHeaders.DELETE;
11155 
11156       SELECT lce_header_id BULK COLLECT INTO localOldHeaders FROM cz_lce_headers
11157        WHERE deleted_flag = FLAG_NOT_DELETED
11158          AND devl_project_id = NewHeadersComponents(i);
11159 
11160       FOR j IN 1..localOldHeaders.COUNT LOOP
11161         OldHeaders(nCount) := localOldHeaders(j);
11162         nCount := nCount + 1;
11163       END LOOP;
11164 
11165       localComponent := NewHeadersComponents(i);
11166     END IF;
11167    END LOOP;
11168 
11169    FORALL i IN 1..OldHeaders.COUNT
11170     UPDATE cz_lce_headers SET deleted_flag = FLAG_DELETED
11171      WHERE lce_header_id = OldHeaders(i);
11172 
11173    FORALL i IN 1..OldHeaders.COUNT
11174     UPDATE cz_lce_load_specs SET deleted_flag = FLAG_DELETED
11175      WHERE lce_header_id = OldHeaders(i);
11176 
11177    FORALL i IN 1..NewHeaders.COUNT
11178     UPDATE cz_lce_headers SET deleted_flag = FLAG_NOT_DELETED
11179      WHERE lce_header_id = NewHeaders(i);
11180 
11181    FORALL i IN 1..NewHeaders.COUNT
11182     UPDATE cz_lce_load_specs SET deleted_flag = FLAG_NOT_DELETED
11183      WHERE lce_header_id = NewHeaders(i);
11184 
11185    cz_security_pvt.unlock_model(1.0, FND_API.G_TRUE, l_locked_models, l_lock_status, l_msg_count, l_msg_data);
11186 
11187    IF(l_lock_status <> FND_API.G_RET_STS_SUCCESS)THEN
11188      FOR jmessage IN 1..l_msg_count LOOP
11189        REPORT(fnd_msg_pub.get(jmessage, FND_API.G_FALSE), 0);
11190      END LOOP;
11191    END IF;
11192 
11193    IF(TwoPhaseCommit = 0)THEN COMMIT; END IF;
11194 END;
11195 ---------------------------------------------------------------------------------------
11196 PROCEDURE ROLLBACK_HEADERS IS
11197 BEGIN
11198 
11199    FORALL i IN 1..NewHeaders.COUNT
11200     UPDATE cz_lce_headers SET deleted_flag = FLAG_DELETED
11201      WHERE lce_header_id = NewHeaders(i);
11202 
11203    FORALL i IN 1..NewHeaders.COUNT
11204     UPDATE cz_lce_load_specs SET deleted_flag = FLAG_DELETED
11205      WHERE lce_header_id = NewHeaders(i);
11206 
11207    IF(OldHeaders.COUNT > 0)THEN
11208 
11209      FORALL i IN 1..OldHeaders.COUNT
11210       UPDATE cz_lce_headers SET deleted_flag = FLAG_NOT_DELETED
11211        WHERE lce_header_id = OldHeaders(i);
11212 
11213      FORALL i IN 1..OldHeaders.COUNT
11214       UPDATE cz_lce_load_specs SET deleted_flag = FLAG_NOT_DELETED
11215        WHERE lce_header_id = OldHeaders(i);
11216    END IF;
11217 
11218    cz_security_pvt.unlock_model(1.0, FND_API.G_TRUE, l_locked_models, l_lock_status, l_msg_count, l_msg_data);
11219 
11220    IF(l_lock_status <> FND_API.G_RET_STS_SUCCESS)THEN
11221      FOR jmessage IN 1..l_msg_count LOOP
11222        REPORT(fnd_msg_pub.get(jmessage, FND_API.G_FALSE), 0);
11223      END LOOP;
11224    END IF;
11225 
11226    IF(TwoPhaseCommit = 0)THEN COMMIT; END IF;
11227 
11228 EXCEPTION
11229   WHEN OTHERS THEN
11230 --'Fatal error. Logic header maintainance not completed. Unable to rollback changes because of %ERRORTEXT'
11231     REPORT(CZ_UTILS.GET_TEXT('CZ_G_UNABLE_TO_ROLLBACK', 'ERRORTEXT', SQLERRM), 0);
11232 END;
11233 ---------------------------------------------------------------------------------------
11234 FUNCTION CHECK_DATES(inModelId IN NUMBER, inLogicUpdate IN DATE, inHeaderCreated IN DATE)
11235 RETURN PLS_INTEGER IS
11236 
11237   c_model             refCursor;
11238   childFlag           PLS_INTEGER;
11239   thisFlag            PLS_INTEGER := GENERATION_NOT_REQUIRED;
11240   childModelId        cz_devl_projects.devl_project_id%TYPE;
11241   childLogicUpdate    cz_devl_projects.last_logic_update%TYPE;
11242   childHeaderCreated  cz_lce_headers.creation_date%TYPE;
11243 
11244 BEGIN
11245 
11246   IF(NOT modelChecked.EXISTS(inModelId))THEN
11247 
11248     modelChecked(inModelId) := 1;
11249 
11250     OPEN c_model FOR logicSQL USING inModelId;
11251     LOOP
11252       FETCH c_model INTO childModelId, childLogicUpdate, childHeaderCreated;
11253       EXIT WHEN c_model%NOTFOUND;
11254 
11255       childFlag := CHECK_DATES(childModelId, childLogicUpdate, childHeaderCreated);
11256 
11257       IF(thisFlag = GENERATION_NOT_REQUIRED AND
11258          (childFlag = GENERATION_REQUIRED OR inHeaderCreated < childLogicUpdate))THEN
11259         thisFlag := GENERATION_REQUIRED;
11260       END IF;
11261     END LOOP;
11262     CLOSE c_model;
11263   END IF;
11264 
11265   IF(thisFlag = GENERATION_NOT_REQUIRED AND inHeaderCreated < inLogicUpdate)THEN
11266     thisFlag := GENERATION_REQUIRED;
11267   END IF;
11268 
11269   IF(thisFlag = GENERATION_NOT_REQUIRED)THEN
11270     IsLogicGenerated(inModelId) := 0;
11271   END IF;
11272  RETURN thisFlag;
11273 END;
11274 ---------------------------------------------------------------------------------------
11275 BEGIN --GENERATE_LOGIC_
11276 
11277     --Bug #4587682. Save current nls numeric characters and set the standard characters.
11278 
11279     SELECT value INTO StoreNlsCharacters FROM NLS_SESSION_PARAMETERS
11280      WHERE UPPER(parameter) = 'NLS_NUMERIC_CHARACTERS';
11281 
11282     SET_NLS_CHARACTERS(NlsNumericCharacters);
11283 
11284 BEGIN
11285 
11286   --Database settings processing section
11287 
11288   BEGIN
11289 
11290     --Get the commit block size - the number of records inserted into cz_lce_texts
11291     --after which the transaction is commited, if commit is not disabled at all by
11292     --TwoPhaseCommit parameter set to 1.
11293 
11294     SELECT TO_NUMBER(value) INTO CommitBlockSize
11295       FROM cz_db_settings
11296      WHERE LOWER(setting_id) = COMMIT_BLOCK_SETTING_ID
11297        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11298 
11299     IF(CommitBlockSize <= 0) THEN CommitBlockSize := DEFAULT_COMMIT_BLOCK_SIZE; END IF;
11300 
11301   EXCEPTION
11302     WHEN OTHERS THEN
11303       CommitBlockSize := DEFAULT_COMMIT_BLOCK_SIZE;
11304   END;
11305 
11306 /*  Making the optimizations unconditional, cz_db_settings ignored.
11307   BEGIN
11308 
11309     --Get the NotTrue optimization flag, no optimization by default.
11310 
11311     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11312                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11313                                 0) --default value
11314       INTO OptimizeNotTrue
11315       FROM cz_db_settings
11316      WHERE LOWER(setting_id) = OPTIMIZE_NOTTRUE_SETTING_ID
11317        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11318 
11319   EXCEPTION
11320     WHEN OTHERS THEN
11321       OptimizeNotTrue := 0;
11322   END;
11323 
11324   BEGIN
11325 
11326     --Get the AllOf/AnyOf optimization flag, no optimization by default.
11327 
11328     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11329                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11330                                 0) --default value
11331       INTO OptimizeAllAnyOf
11332       FROM cz_db_settings
11333      WHERE LOWER(setting_id) = OPTIMIZE_ALLANYOF_SETTING_ID
11334        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11335 
11336   EXCEPTION
11337     WHEN OTHERS THEN
11338       OptimizeAllAnyOf := 0;
11339   END;
11340 
11341   BEGIN
11342 
11343     --Get the Change Children Order flag, no change by default.
11344     --Currently will change children order when generating AllOf/AnyOf.
11345 
11346     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11347                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11348                                 0) --default value
11349       INTO ChangeChildrenOrder
11350       FROM cz_db_settings
11351      WHERE LOWER(setting_id) = CHILDREN_ORDER_SETTING_ID
11352        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11353 
11354   EXCEPTION
11355     WHEN OTHERS THEN
11356       ChangeChildrenOrder := 0;
11357   END;
11358 */
11359 
11360   --Enable all three optimizations here ignoring cz_db_settings.
11361 
11362   OptimizeNotTrue := 1;
11363   OptimizeAllAnyOf := 1;
11364   ChangeChildrenOrder := 1;
11365 
11366   BEGIN
11367 
11368     --See if we want to generate gated combinations, yes by default.
11369 
11370     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11371                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11372                                 1) --default value
11373       INTO GenerateGatedCombo
11374       FROM cz_db_settings
11375      WHERE LOWER(setting_id) = GATED_COMBO_SETTING_ID
11376        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11377 
11378   EXCEPTION
11379     WHEN OTHERS THEN
11380       GenerateGatedCombo := 1;
11381   END;
11382 
11383   BEGIN
11384 
11385     --See if we want to stop when a fatal rule error is encountered, yes by default.
11386 
11387     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11388                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11389                                 1) --default value
11390       INTO StopOnFatalRuleError
11391       FROM cz_db_settings
11392      WHERE LOWER(setting_id) = STOP_ON_ERROR_SETTING_ID
11393        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11394 
11395   EXCEPTION
11396     WHEN OTHERS THEN
11397       StopOnFatalRuleError := 1;
11398   END;
11399 
11400   BEGIN
11401 
11402     --See if we want to generate logic only for updated models, yes by default.
11403 
11404     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11405                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11406                                 1) --default value
11407       INTO GenerateUpdatedOnly
11408       FROM cz_db_settings
11409      WHERE LOWER(setting_id) = UPDATED_ONLY_SETTING_ID
11410        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11411 
11412   EXCEPTION
11413     WHEN OTHERS THEN
11414       GenerateUpdatedOnly := 1;
11415   END;
11416 
11417   --Get the logic generation run id. If a valid value has been passed as a parameter, use it,
11418   --else generate a new value.
11419 
11420   IF(thisRunId IS NULL OR thisRunId = 0)THEN
11421     SELECT cz_xfr_run_infos_s.NEXTVAL INTO thisRunId FROM DUAL;
11422   END IF;
11423 
11424   --Read the cz_effectivity_sets table into memory and create hash tables for
11425   --effectivity dates
11426 
11427   -- Bug10407496 : Selecting only effectivity sets belongs repository
11428 
11429   SELECT effectivity_set_id, effective_from, effective_until
11430   BULK COLLECT INTO gvSetId, gvEffFrom, gvEffUntil
11431     FROM cz_effectivity_sets
11432    WHERE deleted_flag = FLAG_NOT_DELETED
11433      AND EXISTS (SELECT null FROM cz_rp_entries
11434                   WHERE object_type='EFF'
11435                     AND deleted_flag = FLAG_NOT_DELETED
11436                     AND object_id = effectivity_set_id);
11437 
11438   --Add the indexing option
11439 
11440   IF(gvSetId.LAST IS NOT NULL)THEN
11441    FOR i IN gvSetId.FIRST..gvSetId.LAST LOOP
11442     gvIndexBySetId(gvSetId(i)) := i;
11443    END LOOP;
11444   END IF;
11445 
11446   --This block is introduced to implement locking.
11447 
11448   BEGIN
11449 
11450     l_locked_models.DELETE;
11451     cz_security_pvt.lock_model(1.0, inDevlProjectId, FND_API.G_TRUE, FND_API.G_TRUE, l_locked_models, l_lock_status, l_msg_count, l_msg_data);
11452 
11453     IF(l_lock_status <> FND_API.G_RET_STS_SUCCESS)THEN
11454       RAISE FAILED_TO_LOCK_MODEL;
11455     END IF;
11456 
11457     --To disable this functionality, comment out the following IF block. Previously, we
11458     --could not correctly handle accumulators and NOTTRUE operator, for which we needed
11459     --to modify a child structure file even if it was up-to-date.
11460 
11461     --Pre-populate the list of models that don't need to be regenerated because logic exists
11462     --and satisfies the 'up-to-date' criterion. Part of the fix for the bug #1941626.
11463     --For debugging purposes it may be convenient to be able to regenerate logic without any
11464     --dependency on the dates - the old way. A db setting is provided for that.
11465 
11466     IF(GenerateUpdatedOnly = 1)THEN
11467 
11468       --Have to always generate logic for the root model because the trigger updating
11469       --last_logic_update column is commented out on cz_expression_nodes, and this is
11470       --the only table Developer updates for some rule changes.
11471       --This is why we do not care about the return value and pass the margin reverse
11472       --dates.
11473 
11474       nParam := CHECK_DATES(inDevlProjectId, EpochEndDate, EpochBeginDate);
11475     END IF;
11476 
11477     globalLevel := globalLevel + 1;
11478     globalStack(globalLevel) := inDevlProjectId;
11479     globalRef(globalLevel) := inDevlProjectId;
11480     globalInstance(globalLevel) := 0;
11481 
11482     --Start off the recursion
11483 
11484     GENERATE_COMPONENT_TREE(inDevlProjectId, inDevlProjectId, NULL);
11485 
11486     --LCE header maintainance
11487 
11488     COMMIT_HEADERS;
11489 
11490   EXCEPTION
11491     WHEN FAILED_TO_LOCK_MODEL THEN
11492 
11493        FOR jmessage IN 1..l_msg_count LOOP
11494          REPORT(fnd_msg_pub.get(jmessage, FND_API.G_FALSE), 0);
11495        END LOOP;
11496 
11497        ROLLBACK_HEADERS;
11498     WHEN OTHERS THEN
11499       RAISE;
11500   END;
11501 
11502 --Handle here the exceptions that should terminate the logic tree generation process.
11503 
11504 EXCEPTION
11505   WHEN CZ_S_UNABLE_TO_CREATE_HEADER THEN
11506 --'Unable to create logic header because of %ERRORTEXT'
11507     REPORT(CZ_UTILS.GET_TEXT('CZ_G_UNABLE_TO_CREATE_HEADER', 'ERRORTEXT', errorMessage), 0);
11508     ROLLBACK_HEADERS;
11509   WHEN CZ_R_UNABLE_TO_CREATE_HEADER THEN
11510 --'Unable to create logic header because of %ERRORTEXT'
11511     REPORT(CZ_UTILS.GET_TEXT('CZ_G_UNABLE_TO_CREATE_HEADER', 'ERRORTEXT', errorMessage), 0);
11512     ROLLBACK_HEADERS;
11513   WHEN CZ_S_DEADLOOP_DETECTED THEN
11514     REPORT(errorMessage, 0);
11515     ROLLBACK_HEADERS;
11516   WHEN CZ_S_UNKNOWN_FEATURE_TYPE THEN
11517     REPORT(errorMessage, 0);
11518     ROLLBACK_HEADERS;
11519   WHEN CZ_S_UNKNOWN_NODE_TYPE THEN
11520     REPORT(errorMessage, 0);
11521     ROLLBACK_HEADERS;
11522   WHEN CZ_S_UNKNOWN_BOM_NODE_TYPE THEN
11523     REPORT(errorMessage, 0);
11524     ROLLBACK_HEADERS;
11525   WHEN CZ_S_TOO_MANY_OPTIONS THEN
11526     REPORT(errorMessage, 0);
11527     ROLLBACK_HEADERS;
11528   WHEN CZ_S_WRONG_EFFECTIVITY_SET THEN
11529     REPORT(errorMessage, 0);
11530     ROLLBACK_HEADERS;
11531   WHEN CZ_S_INCONSISTENT_QUANTITY THEN
11532     REPORT(errorMessage, 0);
11533     ROLLBACK_HEADERS;
11534   WHEN CZ_S_INCORRECT_QUANTITY THEN
11535 --'BOM item ''%ITEMNAME'' cannot have default quantity greater than 1 because it contains other trackable BOM items.'
11536     REPORT(CZ_UTILS.GET_TEXT('CZ_S_INCORRECT_QUANTITY', 'ITEMNAME', glName(nParam)), 0);
11537     ROLLBACK_HEADERS;
11538   WHEN CZ_S_TRACKABLE_CHILDREN THEN
11539 --'Invalid Model structure: ''%CHILDNAME'' is a direct child of ''%MODELNAME''. A trackable BOM item cannot be a direct child of a Container Model.'
11540     REPORT(CZ_UTILS.GET_TEXT('CZ_S_TRACKABLE_CHILDREN', 'CHILDNAME', glName(nParam), 'MODELNAME', errorMessage), 0);
11541     ROLLBACK_HEADERS;
11542   WHEN CZ_S_TRACKABLE_STANDARD THEN
11543 --'Invalid Model structure: ''%CHILDNAME'' is a direct child of ''%MODELNAME''. A trackable Standard Item cannot be
11544 -- a direct child of a non-trackable ATO or PTO BOM Model that is referenced by a Container Model.'
11545     REPORT(CZ_UTILS.GET_TEXT('CZ_S_TRACKABLE_STANDARD', 'CHILDNAME', glName(nParam), 'MODELNAME', errorMessage), 0);
11546     ROLLBACK_HEADERS;
11547   WHEN CZ_S_MULTIPLE_TRACKABLE THEN
11548 --'Invalid Model structure: Multiple references exist to the trackable instance ''%CHILDNAME''.'
11549     REPORT(CZ_UTILS.GET_TEXT('CZ_S_MULTIPLE_TRACKABLE', 'CHILDNAME', errorMessage), 0);
11550     ROLLBACK_HEADERS;
11551   WHEN CZ_S_MULTIPLE_INSTANCES THEN
11552 --'Invalid Model structure: The non-trackable Model ''%MODELNAME'' cannot have multiple instances because it is not a descendent of a trackable Model and it
11553 -- contains the trackable Model ''%CHILDNAME''. Please set both the Instances Minimum and Maximum fields for ''%MODELNAME'' to 1.'
11554     REPORT(CZ_UTILS.GET_TEXT('CZ_S_MULTIPLE_INSTANCES', 'CHILDNAME', errorMessage, 'MODELNAME', glName(nParam)), 0);
11555     ROLLBACK_HEADERS;
11556   WHEN CZ_S_CONNECT_NONTRACKABLE THEN
11557 --'Invalid Connector: Connector to non-trackable Model ''%CHILDNAME'' from the trackable Model ''%MODELNAME''. A Connector from a non-trackable Model
11558 -- to a trackable Model is not allowed in a Container Model.'
11559     REPORT(CZ_UTILS.GET_TEXT('CZ_S_CONNECT_NONTRACKABLE', 'CHILDNAME', errorMessage, 'MODELNAME', glName(nParam)), 0);
11560     ROLLBACK_HEADERS;
11561   WHEN CZ_S_CONTAINER_REFERENCE THEN
11562 --'Invalid Reference: Model ''%MODELNAME'' references the Model ''%CHILDNAME''. A Container Model cannot reference another Container Model.'
11563     REPORT(CZ_UTILS.GET_TEXT('CZ_S_CONTAINER_REFERENCE', 'CHILDNAME', errorMessage, 'MODELNAME', rootProjectName), 0);
11564     ROLLBACK_HEADERS;
11565   WHEN CZ_S_CONNECTOR_TRACKABLE THEN
11566 --'The Connector from ''%MODELNAME'' to the trackable Model ''%CHILDNAME'' is not allowed because no ancestor of ''%MODELNAME'' is trackable.'
11567     REPORT(CZ_UTILS.GET_TEXT('CZ_S_CONNECTOR_TRACKABLE', 'CHILDNAME', glName(nParam), 'MODELNAME', errorMessage), 0);
11568     ROLLBACK_HEADERS;
11569   WHEN CZ_S_INCORRECT_CONTAINER THEN
11570 --'The Reference to trackable Model ''%CHILDNAME'' in the Container Model ''%MODELNAME'' has an invalid number
11571 -- of Instances specified. Please set Minimum Instances to 0 and Maximum Instances to Null for this node,
11572 -- then regenerate the Active Model.'
11573     REPORT(CZ_UTILS.GET_TEXT('CZ_S_INCORRECT_CONTAINER', 'CHILDNAME', errorMessage, 'MODELNAME', rootProjectName), 0);
11574     ROLLBACK_HEADERS;
11575   WHEN CZ_S_NO_TRACKABLE_FLAG THEN
11576 --'Trackable status is undefined for the Model ''%CHILDNAME'' in the Container Model ''%MODELNAME''.
11577 -- Please refresh the Model by running the Refresh a Single Configuration Model concurrent program
11578 -- and then regenerate the Active Model.'
11579     REPORT(CZ_UTILS.GET_TEXT('CZ_S_NO_TRACKABLE_FLAG', 'CHILDNAME', errorMessage, 'MODELNAME', rootProjectName), 0);
11580     ROLLBACK_HEADERS;
11581   WHEN CZ_S_NO_DATA_IN_PROJECT THEN
11582 --'Project ''%PROJECTNAME'' contains no data, no logic generated'
11583     REPORT(CZ_UTILS.GET_TEXT('CZ_S_NO_DATA_IN_PROJECT', 'PROJECTNAME', errorMessage), 0);
11584     ROLLBACK_HEADERS;
11585   WHEN CZ_S_NO_SUCH_PROJECT THEN
11586 --'Project does not exist for the specified ID: %PROJECTID. No logic generated.'
11587     REPORT(CZ_UTILS.GET_TEXT('CZ_S_NO_SUCH_PROJECT', 'PROJECTID', nParam), 0);
11588     ROLLBACK_HEADERS;
11589   WHEN CZ_S_TRACKABLE_CONTAINER THEN
11590 --'Error in Model ''%PROJECTNAME'': A trackable Model cannot be a Container Model.'
11591     REPORT(CZ_UTILS.GET_TEXT('CZ_S_TRACKABLE_CONTAINER', 'PROJECTNAME', errorMessage), 0);
11592     ROLLBACK_HEADERS;
11593   WHEN CZ_LCE_MODEL_OUTOFDATE THEN
11594 --'The BOM Model ''%MODELNAME'' is out of date. Please refresh the Model by running the Refresh a Single
11595 -- Configuration Model concurrent program and then regenerate the Active Model.'
11596     REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_MODEL_OUTOFDATE', 'MODELNAME', errorMessage), 0);
11597     ROLLBACK_HEADERS;
11598   WHEN CZ_LCE_INCORRECT_BOM THEN
11599 --'Incorrect BOM Model or Option Class ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
11600 -- Only BOM Standard Items can be shippable and inventory transactable.'
11601     REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_INCORRECT_BOM', 'NODENAME', thisName, 'PARENTNAME', parentName, 'MODELNAME', errorMessage), 0);
11602     ROLLBACK_HEADERS;
11603   WHEN CZ_LCE_INCORRECT_ITEM THEN
11604 --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
11605 -- All shippable items should be inventory transactable and vice versa.'
11606     REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_INCORRECT_ITEM', 'NODENAME', thisName, 'PARENTNAME', parentName, 'MODELNAME', errorMessage), 0);
11607     ROLLBACK_HEADERS;
11608   WHEN CZ_LCE_INCORRECT_TANGIBLE THEN
11609 --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
11610 -- All shippable items should be trackable non-ATO standard items with maximum quantity 1.'
11611     REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_INCORRECT_TANGIBLE', 'NODENAME', thisName, 'PARENTNAME', parentName, 'MODELNAME', errorMessage), 0);
11612     ROLLBACK_HEADERS;
11613   WHEN CZ_LCE_INCORRECT_SHIPPABLE THEN
11614 --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
11615 -- All shippable items should be serializable trackable non-ATO standard items.'
11616     REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_INCORRECT_SHIPPABLE', 'NODENAME', thisName, 'PARENTNAME', parentName, 'MODELNAME', errorMessage), 0);
11617     ROLLBACK_HEADERS;
11618   WHEN CZ_G_INVALID_RULE_EXPLOSION THEN
11619 --'Internal data error. Unable to continue because of invalid data in rule ''%RULENAME''. Disable or delete the rule to generate logic.'
11620      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_INVALID_RULE_EXPLOSION', 'RULENAME', errorMessage);
11621     REPORT(errorMessage, 0);
11622     ROLLBACK_HEADERS;
11623   WHEN CZ_G_INVALID_MODEL_EXPLOSION THEN
11624 --'Internal data error. Unable to continue because of invalid data in model ''%MODELNAME'' - loop detected.'
11625      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_INVALID_MODEL_EXPLOSION', 'MODELNAME', errorMessage);
11626     REPORT(errorMessage, 0);
11627     ROLLBACK_HEADERS;
11628   WHEN CZ_G_INVALID_EXPLOSION_TYPE THEN
11629 --'Internal data error. Unable to continue because of invalid data in the model ''%MODELNAME'' - incorrect explosion type.'
11630      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_INVALID_EXPLOSION_TYPE', 'MODELNAME', errorMessage);
11631     REPORT(errorMessage, 0);
11632     ROLLBACK_HEADERS;
11633   WHEN OTHERS THEN
11634     IF(nDebug = 1 OR (nDebug >= 1000001 AND nDebug <= 1000011))THEN
11635 --'Unable to continue because of %ERRORTEXT. Reference explosions table may not be populated properly for model ''%MODELNAME'''
11636      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_ERROR_IN_EXPLOSION', 'ERRORTEXT', SQLERRM, 'MODELNAME', glName(glIndexByPsNodeId(inDevlProjectId)));
11637     ELSIF(nDebug >= 40 AND nDebug <= 54)THEN
11638 --'Internal data error. Unable to continue because of invalid data in rule ''%RULENAME''. Disable or delete the rule to generate logic.'
11639      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_INVALID_RULE_EXPLOSION', 'RULENAME', errorMessage);
11640     ELSIF(SUBSTR(TO_CHAR(nDebug), 1, 1) = '8')THEN
11641 --'Unable to continue because of %ERRORTEXT: (nRuleId)'
11642      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_GENERAL_ERROR', 'ERRORTEXT', SQLERRM || ': (' || errorMessage || ')');
11643     ELSE
11644 --'Unable to continue because of %ERRORTEXT'
11645      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_GENERAL_ERROR', 'ERRORTEXT', SQLERRM);
11646     END IF;
11647     REPORT(errorMessage, 0);
11648     ROLLBACK_HEADERS;
11649 END;
11650 
11651  --Bug #4587682. Restore the session's nls numeric characters.
11652 
11653  SET_NLS_CHARACTERS(StoreNlsCharacters);
11654 
11655 EXCEPTION
11656   WHEN OTHERS THEN
11657     SET_NLS_CHARACTERS(StoreNlsCharacters);
11658     RAISE;
11659 END; --GENERATE_MODEL_TREE
11660 ---------------------------------------------------------------------------------------
11661 --An additional entry point for those callers who cannot handle defaulted parameters---
11662 
11663 PROCEDURE GENERATE_LOGIC(inDevlProjectId IN NUMBER,
11664                          thisRunId       IN OUT NOCOPY NUMBER)
11665 IS
11666 
11667   l_config_engine_type   cz_devl_projects.config_engine_type%TYPE;
11668   l_fusion_debug         VARCHAR2(240);
11669 
11670 BEGIN
11671 
11672   BEGIN
11673 
11674     SELECT config_engine_type INTO l_config_engine_type
11675       FROM cz_devl_projects
11676      WHERE deleted_flag = FLAG_NOT_DELETED
11677        AND devl_project_id = inDevlProjectId;
11678 
11679   EXCEPTION
11680     WHEN NO_DATA_FOUND THEN
11681       l_config_engine_type := 'L';
11682   END;
11683 
11684   IF ( l_config_engine_type = 'F') THEN
11685 
11686     l_fusion_debug := NVL ( fnd_profile.value_wnps ('CZ_DEV_FCE_DEBUG_LOGIC'), 'N');
11687 
11688     IF ( l_fusion_debug = 'N' ) THEN
11689 
11690       cz_fce_compile.compile_logic ( inDevlProjectId,  thisRunId );
11691 
11692     ELSE
11693 
11694       cz_fce_compile.debug_logic ( inDevlProjectId,  thisRunId );
11695 
11696     END IF;
11697 
11698   ELSE
11699 
11700     GENERATE_LOGIC_(inDevlProjectId, thisRunId, 0);
11701 
11702   END IF;
11703 END;
11704 ---------------------------------------------------------------------------------------
11705 --This entry makes the logic generation work remotely in a distributed transaction,even
11706 --if the model contains property-based compatibility rules - bug #2028790.
11707 --DDL used in the property-based compatibility rules makes implicit commits and commits
11708 --are not allowed in a distributed transaction when the remote procedure has parameters
11709 --of type OUT.
11710 
11711 PROCEDURE GENERATE_LOGIC__(inDevlProjectId IN NUMBER,
11712                            thisRunId       IN NUMBER)
11713 IS
11714   outRunId  NUMBER := thisRunId;
11715 BEGIN
11716   GENERATE_LOGIC_(inDevlProjectId, outRunId, 1);
11717 END;
11718 ---------------------------------------------------------------------------------------
11719 BEGIN
11720 
11721   OperatorLiterals(OPERATOR_ADD)                := ' + ';
11722   OperatorLiterals(OPERATOR_SUB)                := ' - ';
11723   OperatorLiterals(OPERATOR_MULT)               := ' * ';
11724   OperatorLiterals(OPERATOR_DIV)                := ' / ';
11725   OperatorLiterals(OPERATOR_EQUALS)             := ' = ';
11726   OperatorLiterals(OPERATOR_NOTEQUALS)          := ' != ';
11727   OperatorLiterals(OPERATOR_GT)                 := ' > ';
11728   OperatorLiterals(OPERATOR_LT)                 := ' < ';
11729   OperatorLiterals(OPERATOR_GE)                 := ' >= ';
11730   OperatorLiterals(OPERATOR_LE)                 := ' <= ';
11731   OperatorLiterals(OPERATOR_ADD_INT)            := ' + ';
11732   OperatorLiterals(OPERATOR_SUB_INT)            := ' - ';
11733   OperatorLiterals(OPERATOR_MULT_INT)           := ' * ';
11734   OperatorLiterals(OPERATOR_EQUALS_INT)         := ' = ';
11735   OperatorLiterals(OPERATOR_NOTEQUALS_INT)      := ' != ';
11736   OperatorLiterals(OPERATOR_GT_INT)             := ' > ';
11737   OperatorLiterals(OPERATOR_LT_INT)             := ' < ';
11738   OperatorLiterals(OPERATOR_GE_INT)             := ' >= ';
11739   OperatorLiterals(OPERATOR_LE_INT)             := ' <= ';
11740   OperatorLiterals(OPERATOR_POW_INT)            := ' POW ';
11741   OperatorLiterals(OPERATOR_ROUND)              := ' ROUND ';
11742   OperatorLiterals(OPERATOR_CEILING)            := ' CEILING ';
11743   OperatorLiterals(OPERATOR_FLOOR)              := ' FLOOR ';
11744   OperatorLiterals(OPERATOR_TRUNCATE)           := ' TRUNCATE ';
11745   OperatorLiterals(OPERATOR_MIN)                := ' MIN ';
11746   OperatorLiterals(OPERATOR_MAX)                := ' MAX ';
11747   OperatorLiterals(OPERATOR_AND)                := ' AND ';
11748   OperatorLiterals(OPERATOR_OR)                 := ' OR ';
11749   OperatorLiterals(OPERATOR_NOT)                := ' NOT ';
11750   OperatorLiterals(OPERATOR_NOTTRUE)            := ' NOTTRUE ';
11751   OperatorLiterals(OPERATOR_COS)                := ' COS ';
11752   OperatorLiterals(OPERATOR_ACOS)               := ' ACOS ';
11753   OperatorLiterals(OPERATOR_COSH)               := ' COSH ';
11754   OperatorLiterals(OPERATOR_SIN)                := ' SIN ';
11755   OperatorLiterals(OPERATOR_ASIN)               := ' ASIN ';
11756   OperatorLiterals(OPERATOR_SINH)               := ' SINH ';
11757   OperatorLiterals(OPERATOR_TAN)                := ' TAN ';
11758   OperatorLiterals(OPERATOR_ATAN)               := ' ATAN ';
11759   OperatorLiterals(OPERATOR_TANH)               := ' TANH ';
11760   OperatorLiterals(OPERATOR_LOG)                := ' LOG ';
11761   OperatorLiterals(OPERATOR_LOG10)              := ' LOG10 ';
11762   OperatorLiterals(OPERATOR_EXP)                := ' EXP ';
11763   OperatorLiterals(OPERATOR_ABS)                := ' ABS ';
11764   OperatorLiterals(OPERATOR_SQRT)               := ' SQRT ';
11765   OperatorLiterals(OPERATOR_MATHDIV)            := ' DIV ';
11766   OperatorLiterals(OPERATOR_POW)                := ' POW ';
11767   OperatorLiterals(OPERATOR_ATAN2)              := ' ATAN2 ';
11768   OperatorLiterals(OPERATOR_MOD)                := ' MOD ';
11769   OperatorLiterals(OPERATOR_ROUNDTONEAREST)     := ' ROUND ';
11770   OperatorLiterals(OPERATOR_ROUNDUPTONEAREST)   := ' CEILING ';
11771   OperatorLiterals(OPERATOR_ROUNDDOWNTONEAREST) := ' FLOOR ';
11772   OperatorLiterals(OPERATOR_ALLOF)              := ' All True ';
11773   OperatorLiterals(OPERATOR_ANYOF)              := ' Any True ';
11774   OperatorLiterals(OPERATOR_NONE)               := ' ';
11775 
11776   OperatorLetters(OPERATOR_AND)                 := ' L ';
11777   OperatorLetters(OPERATOR_OR)                  := ' N ';
11778   OperatorLetters(OPERATOR_ALLOF)               := ' L ';
11779   OperatorLetters(OPERATOR_ANYOF)               := ' N ';
11780   OperatorLetters(RULE_OPERATOR_REQUIRES)       := ' R ';
11781   OperatorLetters(RULE_OPERATOR_IMPLIES)        := ' I ';
11782   OperatorLetters(RULE_OPERATOR_EXCLUDES)       := ' E ';
11783   OperatorLetters(RULE_OPERATOR_NEGATES)        := ' N ';
11784 
11785   CodeByCodeLookup(TEMPLATE_ANYTRUE)            := OPERATOR_ANYOF;
11786   CodeByCodeLookup(TEMPLATE_ALLTRUE)            := OPERATOR_ALLOF;
11787 END;