DBA Data[Home] [Help]

PACKAGE BODY: APPS.CZ_LOGIC_GEN

Source


1 PACKAGE BODY CZ_LOGIC_GEN AS
2 /*	$Header: czlcegnb.pls 120.33.12010000.2 2008/10/21 19:31:20 asiaston 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.33.12010000.2 2008/10/21 19:31:20 asiaston 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   logicSQL  VARCHAR2(4000) := 'SELECT proj.devl_project_id, proj.last_logic_update, head.creation_date' ||
207                               '  FROM cz_devl_projects proj, cz_model_ref_expls expl, cz_lce_headers head' ||
208                               ' WHERE proj.deleted_flag = ''' || FLAG_NOT_DELETED ||
209                               ''' AND expl.deleted_flag = ''' || FLAG_NOT_DELETED ||
210                               ''' AND head.deleted_flag = ''' || FLAG_NOT_DELETED ||
211                               ''' AND expl.node_depth = 1' ||
212                               '   AND expl.model_id = :1' ||
213                               '   AND head.net_type = 1' ||
214                               '   AND proj.devl_project_id = expl.component_id' ||
215                               '   AND proj.devl_project_id = head.component_id';
216 
217   h_containerReferred  tIntegerArray_idx_vc2;
218   containerReferred    VARCHAR2(4000) :=
219 
220     'SELECT 1 FROM DUAL WHERE EXISTS' ||
221     '  (SELECT model_id FROM cz_model_ref_expls' ||
222     '    WHERE deleted_flag = ''' || FLAG_NOT_DELETED || '''' ||
223     '      AND ps_node_type IN (' || PS_NODE_TYPE_REFERENCE || ', ' || PS_NODE_TYPE_CONNECTOR || ')' ||
224     '      AND component_id = :1' ||
225     '      AND (SELECT model_type FROM cz_devl_projects' ||
226     '            WHERE devl_project_id = model_id) = ''' || MODEL_TYPE_CONTAINER_MODEL || ''')';
227 
228   GENERATION_REQUIRED         CONSTANT PLS_INTEGER := 1;
229   GENERATION_NOT_REQUIRED     CONSTANT PLS_INTEGER := 2;
230 
231   table_name_generator        PLS_INTEGER := 1;
232   table_hash_propval          tVarcharHashType;
233 ---------------------------------------------------------------------------------------
234 --Bug #5727549.
235 
236 last_id_allocated  NUMBER := NULL;
237 next_id_to_use     NUMBER := 0;
238 
239 FUNCTION next_lce_header_id RETURN NUMBER IS
240   id_to_return  NUMBER;
241 BEGIN
242   IF((last_id_allocated IS NULL) OR
243      (next_id_to_use = (NVL(last_id_allocated, 0) + CZ_SEQUENCE_INCREMENT)))THEN
244 
245     SELECT cz_lce_headers_s.NEXTVAL INTO last_id_allocated FROM DUAL;
246     next_id_to_use := last_id_allocated;
247   END IF;
248 
249   id_to_return := next_id_to_use;
250   next_id_to_use := next_id_to_use + 1;
251  RETURN id_to_return;
252 END next_lce_header_id;
253 ---------------------------------------------------------------------------------------
254 --Reporting procedure
255 
256 PROCEDURE REPORT(inMessage IN VARCHAR2, inUrgency IN PLS_INTEGER) IS
257 BEGIN
258 
259   INSERT INTO cz_db_logs (message, statuscode, caller, urgency, run_id)
260   VALUES (inMessage, nDebug, 'Logic Generator', inUrgency, thisRunId);
261 
262 EXCEPTION
263   WHEN OTHERS THEN
264     RAISE CZ_G_UNABLE_TO_REPORT_ERROR;
265 END;
266 ---------------------------------------------------------------------------------------
267 PROCEDURE SET_NLS_CHARACTERS(p_nls_characters IN VARCHAR2) IS
268 BEGIN
269   IF(NlsNumericCharacters <> StoreNlsCharacters)THEN
270 
271     EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ''' || p_nls_characters || '''';
272   END IF;
273 END;
274 ---------------------------------------------------------------------------------------
275 PROCEDURE GENERATE_COMPONENT_TREE(inComponentId         IN NUMBER,
276                                   inProjectId           IN NUMBER,
277                                   inParentLogicHeaderId IN NUMBER)
278 IS
279 
280  TYPE tNodeDepth      IS TABLE OF cz_model_ref_expls.node_depth%TYPE INDEX BY BINARY_INTEGER;
281  TYPE tNodeType       IS TABLE OF cz_model_ref_expls.ps_node_type%TYPE INDEX BY BINARY_INTEGER;
282  TYPE tVirtualFlag    IS TABLE OF cz_model_ref_expls.virtual_flag%TYPE INDEX BY BINARY_INTEGER;
283  TYPE tParentId       IS TABLE OF cz_model_ref_expls.component_id%TYPE INDEX BY BINARY_INTEGER;
284  TYPE tPsNodeId       IS TABLE OF cz_model_ref_expls.component_id%TYPE INDEX BY BINARY_INTEGER;
285  TYPE tChildModelExpl IS TABLE OF cz_model_ref_expls.child_model_expl_id%TYPE INDEX BY BINARY_INTEGER;
286  TYPE tExplNodeType   IS TABLE OF cz_model_ref_expls.expl_node_type%TYPE INDEX BY BINARY_INTEGER;
287  --kdande; Bug 6881902; 11-Mar-2008; Made the following PLSQL types local to the procedure as they are used for Bulk Collects
288  TYPE tPsNodeType     IS TABLE OF cz_ps_nodes.ps_node_type%TYPE INDEX BY BINARY_INTEGER;
289  TYPE tReferenceId    IS TABLE OF cz_ps_nodes.reference_id%TYPE INDEX BY BINARY_INTEGER;
290  TYPE tDecimalQty     IS TABLE OF cz_ps_nodes.decimal_qty_flag%TYPE INDEX BY BINARY_INTEGER;
291  TYPE tIbTrackable    IS TABLE OF cz_ps_nodes.ib_trackable%TYPE INDEX BY BINARY_INTEGER;
292  TYPE tAccumulator    IS TABLE OF cz_ps_nodes.accumulator_flag%TYPE INDEX BY BINARY_INTEGER;
293  TYPE tInstantiableFlag  IS TABLE OF cz_ps_nodes.instantiable_flag%TYPE INDEX BY BINARY_INTEGER;
294  TYPE tFeatureType       IS TABLE OF cz_ps_nodes.feature_type%TYPE INDEX BY BINARY_INTEGER;
295  TYPE tName              IS TABLE OF cz_ps_nodes.name%TYPE INDEX BY BINARY_INTEGER;
296  TYPE tInitialValue      IS TABLE OF cz_ps_nodes.initial_value%TYPE INDEX BY BINARY_INTEGER;
297  TYPE tMinimum           IS TABLE OF cz_ps_nodes.minimum%TYPE INDEX BY BINARY_INTEGER;
298  TYPE tMaximum           IS TABLE OF cz_ps_nodes.maximum%TYPE INDEX BY BINARY_INTEGER;
299  TYPE tMinimumSel        IS TABLE OF cz_ps_nodes.minimum_selected%TYPE INDEX BY BINARY_INTEGER;
300  TYPE tMaximumSel        IS TABLE OF cz_ps_nodes.maximum_selected%TYPE INDEX BY BINARY_INTEGER;
301 
302  ntPsNodeId           tPsNodeId;
303  ntItemId             tItemId;
304  ntPersistentId       tPersistentId;
305  ntPsNodeType         tPsNodeType;
306  ntInitialValue       tInitialValue;
307  ntParentId           tParentId;
308  ntMinimum            tMinimum;
309  ntMaximum            tMaximum;
310  ntVirtualFlag        tVirtualFlag;
311  ntFeatureType        tFeatureType;
312  ntName               tName;
313  ntDescriptionId      tDescriptionId;
314  ntMinimumSel         tMinimumSel;
315  ntMaximumSel         tMaximumSel;
316  ntBomRequired        tBomRequired;
317  ntReferenceId        tReferenceId;
318  dtEffFrom            tDateArray;
319  dtEffUntil           tDateArray;
320  vtUsageMask          tUsageMask;
321  ntEffSetId           tSetEffId;
322  ntDecimalQty         tDecimalQty;
323  ntIbTrackable        tIbTrackable;
324  ntAccumulator        tAccumulator;
325  ntInitialNumValue    tInitialNumValue;
326  ntInstantiableFlag   tInstantiableFlag;
327  ntShippableFlag      tShippableFlag;
328  ntTransactableFlag   tTransactableFlag;
329  ntAtoFlag            tAtoFlag;
330  ntSerializableFlag   tSerializableFlag;
331 
332  v_tNodeDepth         tNodeDepth;
333  v_tNodeType          tNodeType;
334  v_tVirtualFlag       tVirtualFlag;
335  v_tParentId          tParentId;
336  v_tPsNodeId          tPsNodeId;
337  v_tReferringId       tPsNodeId;
338  v_tChildModelExpl    tChildModelExpl;
339  v_tExplNodeType      tExplNodeType;
340  v_NodeId             tExplNodeId;
341 
342  v_IndexByNodeId      tIntegerArray_idx_vc2;
343  v_TypeByExplId       tExplNodeType;
344 
345  thisComponentExplId  cz_model_ref_expls.model_ref_expl_id%TYPE;
346  thisProjectId        cz_devl_projects.devl_project_id%TYPE;
347  thisProjectName      cz_devl_projects.name%TYPE;
348  thisProjectType      cz_devl_projects.model_type%TYPE;
349  thisRootExplIndex    PLS_INTEGER;
350 
351  nStructureHeaderId   cz_lce_headers.lce_header_id%TYPE;
352  PrevEffFrom          DATE := EpochBeginDate;
353  PrevEffUntil         DATE := EpochEndDate;
354  PrevUsageMask        cz_ps_nodes.effective_usage_mask%TYPE := AnyUsageMask;
355  CurrentEffFrom       DATE;
356  CurrentEffUntil      DATE;
357  CurrentUsageMask     cz_ps_nodes.effective_usage_mask%TYPE;
358  FeatureEffFrom       DATE;
359  FeatureEffUntil      DATE;
360  FeatureUsageMask     cz_ps_nodes.effective_usage_mask%TYPE;
361  nSequenceNbr         NUMBER := 1;
362  vLogicText           VARCHAR2(4000);
363  vLogicLine           VARCHAR2(4000);
364  vLogicName           VARCHAR2(4000);
365 
366  CurrentFromDate      VARCHAR2(25);
367  CurrentUntilDate     VARCHAR2(25);
368  localMinString       VARCHAR2(25);
369  localMaxString       VARCHAR2(25);
370 
371  CurrentlyPacking     PLS_INTEGER;
372  LastPacked           PLS_INTEGER := PACKING_GENERIC;
373  generatingFeature    PLS_INTEGER := 0;
374 
375  i                    PLS_INTEGER;
376  j                    PLS_INTEGER;
377  localCount           PLS_INTEGER;
378  optionCounter        PLS_INTEGER;
379  trackableContext     NUMBER; -- jonatara:bug7041718
380  instantiableContext  NUMBER; -- jonatara:bug7041718
381 ---------------------------------------------------------------------------------------
382  PROCEDURE PACK IS
383  BEGIN
384     IF(vLogicLine IS NOT NULL)THEN
385      IF(LENGTHB(vLogicText) + LENGTHB(vLogicLine)>2000)THEN
386 
387        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
388         (nStructureHeaderId, nSequenceNbr, vLogicText);
389        vLogicText := NULL;
390        nSequenceNbr := nSequenceNbr + 1;
391 
392        --Commit in blocks if not disabled
393 
394        IF(TwoPhaseCommit = 0)THEN
395          commit_counter := commit_counter + 1;
396          IF(commit_counter = CommitBlockSize)THEN
397           COMMIT;
398           commit_counter := 0;
399          END IF;
400        END IF;
401      END IF;
402      vLogicText := vLogicText || vLogicLine;
403      vLogicLine := NULL;
404 
405      LastPacked := PACKING_GENERIC;
406 
407     END IF;
408  END PACK;
409 ---------------------------------------------------------------------------------------
410  PROCEDURE PACK_EFFECTIVITY IS
411  BEGIN
412     IF(vLogicLine IS NOT NULL)THEN
413      IF(LENGTHB(vLogicText) + LENGTHB(vLogicLine)>2000)THEN
414 
415        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
416         (nStructureHeaderId, nSequenceNbr, vLogicText);
417        vLogicText := NULL;
418        nSequenceNbr := nSequenceNbr + 1;
419 
420        --Commit in blocks if not disabled
421 
422        IF(TwoPhaseCommit = 0)THEN
423          commit_counter := commit_counter + 1;
424          IF(commit_counter = CommitBlockSize)THEN
425           COMMIT;
426           commit_counter := 0;
427          END IF;
428        END IF;
429      END IF;
430 
431      IF(LastPacked = PACKING_EFFECTIVITY AND CurrentlyPacking = LastPacked)THEN
432 
433       --We are inserting one effectivity statement after another. Replace the last
434       --one with the current one.
435 
436       vLogicText := SUBSTR(vLogicText, 1, INSTR(vLogicText, 'EFF', -1, 1) - 1) || vLogicLine;
437 
438      ELSE
439        vLogicText := vLogicText || vLogicLine;
440      END IF;
441 
442      vLogicLine := NULL;
443      LastPacked := CurrentlyPacking;
444 
445     END IF;
446  END PACK_EFFECTIVITY;
447 ---------------------------------------------------------------------------------------
448 PROCEDURE GENERATE_EFFECTIVITY_LOGIC(inCurrentEffFrom   IN DATE,
449                                      inCurrentEffUntil  IN DATE,
450                                      inCurrentUsageMask IN VARCHAR2) IS
451 BEGIN
452   IF((inCurrentEffFrom <> PrevEffFrom) OR (inCurrentEffUntil <> PrevEffUntil) OR
453      (inCurrentUsageMask <> PrevUsageMask))THEN
454 
455        vLogicLine := LTRIM(inCurrentUsageMask, '0');
456        IF(vLogicLine IS NOT NULL) THEN
457          vLogicLine := EffUsagePrefix || vLogicLine;
458        END IF;
459 
460        IF(inCurrentEffFrom = EpochBeginDate)THEN
461          CurrentFromDate := NULL;
462        ELSE
463          CurrentFromDate := TO_CHAR(inCurrentEffFrom, EffDateFormat);
464        END IF;
465 
466        IF(inCurrentEffUntil = EpochEndDate)THEN
467          CurrentUntilDate := NULL;
468        ELSE
469          CurrentUntilDate := TO_CHAR(inCurrentEffUntil, EffDateFormat);
470        END IF;
471 
472        vLogicLine := 'EFF ' || CurrentFromDate || ', ' || CurrentUntilDate || ', ' || vLogicLine || NewLine;
473 
474        CurrentlyPacking := PACKING_EFFECTIVITY;
475        PACK_EFFECTIVITY;
476 
477        PrevEffFrom := inCurrentEffFrom;
478        PrevEffUntil := inCurrentEffUntil;
479        PrevUsageMask := inCurrentUsageMask;
480   END IF;
481 END;
482 ---------------------------------------------------------------------------------------
483 --This procedure is used for marking BOM items that are ancestors of a trackable BOM
484 --item. Such items cannot have default quantity greater than 1, and cannot be on the
485 --RHS of a numeric rule.
486 --The procedure can be called only for a BOM Option Class or Standard or a reference,
487 --so parent always exists.
488 
489 PROCEDURE PROPAGATE_TRACKABLE_ANCESTOR IS
490 
491   auxIndex  NUMBER := glIndexByPsNodeId(ntParentId(i));  --kdande; Bug 6881902; 11-Mar-2008
492 BEGIN
493   WHILE((NOT trackableAncestor.EXISTS(glPsNodeId(auxIndex))) AND
494         glPsNodeType(auxIndex) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))LOOP
495 
496     IF(glInitialValue(auxIndex) > 1)THEN
497 
498       nParam := auxIndex;
499       RAISE CZ_S_INCORRECT_QUANTITY;
500     END IF;
501 
502     trackableAncestor(glPsNodeId(auxIndex)) := 1;
503     EXIT WHEN glParentId(auxIndex) IS NULL;
504 
505     auxIndex := glIndexByPsNodeId(glParentId(auxIndex));
506   END LOOP;
507 END;
508 ---------------------------------------------------------------------------------------
509 FUNCTION IS_NODE_LOGICAL(j IN PLS_INTEGER) RETURN BOOLEAN IS
510   l_node_type  NUMBER := ntPsNodeType(j);
511 BEGIN
512   RETURN
513     l_node_type <> PS_NODE_TYPE_TOTAL AND l_node_type <> PS_NODE_TYPE_RESOURCE AND
514     (l_node_type <> PS_NODE_TYPE_FEATURE OR
515        ntFeatureType(j) IN (PS_NODE_FEATURE_TYPE_BOOLEAN, PS_NODE_FEATURE_TYPE_OPTION) OR
516          (ntFeatureType(j) = PS_NODE_FEATURE_TYPE_INTEGER AND
517           ntMinimum(j) IS NOT NULL AND ntMinimum(j) >= 0));
518 END;
519 ---------------------------------------------------------------------------------------
520 PROCEDURE GENERATE_ACCUMULATOR(j IN PLS_INTEGER) IS
521 BEGIN
522 
523   --Check if we need to create an accumulator for this node. Note that accumulator must be
524   --always effective. Part of the fix for the bug #2857955.
525 
526   IF(ntAccumulator(j) IS NOT NULL AND ntAccumulator(j) <> FLAG_NO_ACCUMULATOR)THEN
527 
528     GENERATE_EFFECTIVITY_LOGIC(EpochBeginDate, EpochEndDate, AnyUsageMask);
529     vLogicName := 'P_' || TO_CHAR(ntPersistentId(j));
530 
531     IF((NOT v_HeaderByAccId.EXISTS(ntPsNodeId(j))) AND
532        TO_NUMBER(UTL_RAW.BIT_AND(ntAccumulator(j), FLAG_ACCUMULATOR_ACC)) = TO_NUMBER(FLAG_ACCUMULATOR_ACC))THEN
533 
534       vLogicLine := 'TOTAL ' || vLogicName || '_ACC' || NewLine ||
535                     'INC ' || vLogicName || '_ACC' || ' ' || vLogicName ||
536                     OperatorLiterals(OPERATOR_ROUND) || NewLine;
537 
538       v_HeaderByAccId(ntPsNodeId(j)) := nStructureHeaderId;
539     END IF;
540 
541     IF((NOT v_HeaderByNotTrueId.EXISTS(ntPsNodeId(j))) AND
542        TO_NUMBER(UTL_RAW.BIT_AND(ntAccumulator(j), FLAG_ACCUMULATOR_NT)) = TO_NUMBER(FLAG_ACCUMULATOR_NT))THEN
543 
544       --Bug #5015333. Only node that has a 'logical' value can have this type of accumulator. Initially the
545       --accumulator_flag may have been set by a NOTTRUE operator. At this time the node had to have logical
546       --value, otherwise the rule would have been rejected by a verification (HAS_LOGICAL_VALUE function in
547       --GENERATE_NOTTRUE procedure). However later the rule may have been deleted, and the type of the node
548       --changed, so that the node does not have a 'logical' value anymore. As the accumulator_flag is still
549       --set, the code below will create a 'logical' relation that may crash the engine.
550 
551       IF(IS_NODE_LOGICAL(j))THEN
552 
553         vLogicLine := 'OBJECT ' || vLogicName || '_NT' || NewLine ||
554                       'NOTTRUE ' || vLogicName || ' ' || vLogicName || '_NT' || NewLine;
555         v_HeaderByNotTrueId(ntPsNodeId(j)) := nStructureHeaderId;
556 
557       ELSE
558 
559         --Although it is not necessary to reset the accumulator_flag here, doing so will allow to skip this
560         --verification in the future. This should not have any effect on the currency of the model's logic.
561 
562         UPDATE cz_ps_nodes SET
563              accumulator_flag = TO_CHAR(TO_NUMBER(UTL_RAW.BIT_AND(ntAccumulator(j), FLAG_ACCUMULATOR_ACC)))
564          WHERE ps_node_id = ntPsNodeId(j);
565       END IF;
566     END IF;
567 
568     PACK;
569   END IF;
570 END;
571 ---------------------------------------------------------------------------------------
572 PROCEDURE GENERATE_RULES IS
573 
574  TYPE iteratorNode       IS RECORD (node_type  NUMBER,
575                                     node_id    NUMBER,
576                                     node_value VARCHAR2(4000),
577                                     node_obj   VARCHAR2(4000),
578                                     node_id_ex NUMBER);
579  TYPE tIteratorArray     IS TABLE OF iteratorNode INDEX BY BINARY_INTEGER;
580 
581  --The cursor returns all the rules assigned in this project (model).
582 
583  CURSOR c_rules IS
584   SELECT rule_id, rule_type, antecedent_id, consequent_id, name, reason_id,
585          expr_rule_type, rule_folder_id, component_id, model_ref_expl_id,
586          effective_from, effective_until, effective_usage_mask, effectivity_set_id,
587          unsatisfied_msg_id, unsatisfied_msg_source, presentation_flag, class_name
588   FROM cz_rules
589   WHERE devl_project_id = inComponentId
590     AND deleted_flag = FLAG_NOT_DELETED
591     AND disabled_flag = FLAG_NOT_DISABLED;
592 
593  v_tExplNodeId        tExplNodeId;
594  v_tExprType          tExprType;
595  v_tExprSubtype       tExprSubtype;
596  v_tExprId            tExprId;
597  v_tExprParentId      tExprParentId;
598  v_tExprTemplateId    tExprTemplateId;
599  v_tExprParamIndex    tExprParamIndex;
600  v_tExprArgumentName  tExprArgumentName;
601  v_tExprDataType      tExprDataType;
602  v_tExpressId         tExpressId;
603  v_tExprPsNodeId      tExplNodeId;
604  v_tRealPsNodeId      tExplNodeId;
605  v_tExprDataValue     tExprDataValue;
606  v_tExprPropertyId    tExprPropertyId;
607  v_tConsequentFlag    tConsequentFlag;
608  v_tFeatureType       tDesFeatureType;
609  v_tExprDataNumValue  tExprDataNumValue;
610  v_tExprArgSignature  tExprArgSignature;
611  v_tExprParSignature  tExprParSignature;
612  v_LoadConditionId    tExplNodeId;
613  v_ExplByPsNodeId     tExplNodeId_idx_vc2; --kdande; Bug 6881902; 11-Mar-2008
614 
615  v_tArgumentName      tArgumentName;
616  v_tArgumentIndex     tArgumentIndex;
617  v_tDataType          tDataType;
618 
619  v_InstByLevel        tIntegerArray;
620  v_IndexByExprNodeId  tIntegerArray_idx_vc2;
621  v_Assignable         tIntegerArray;
622  v_Participant        tIntegerArray;
623  v_DistinctIndex      tIntegerArray;
624  v_ParticipantIndex   tIntegerArray;
625  v_RuleConnectorNet   tIntegerArray;
626  v_LevelCount         tIntegerArray;
627  v_LevelIndex         tIntegerArray;
628  v_LevelType          tIntegerArray;
629  v_MarkLoadCondition  tIntegerArray;
630  v_tIsHeaderGenerated tIntegerArray;
631  v_tSequenceNbr       tIntegerArray;
632  v_tLogicNetType      tIntegerArray;
633 
634  v_NodeLogicLevel     tIntegerArray;
635  v_NodeAssignable     tIntegerArray;
636  v_NodeInstantiable   tIntegerArray;
637  v_NodeTrackable      tIntegerArray;
638  v_IsConnectorNet     tIntegerArray;
639  v_ChildrenIndex      tIntegerArray;
640  v_NumberOfChildren   tIntegerArray;
641  v_MaxRuleExists      tIntegerArray;
642  v_ProhibitInRules    tIntegerArray;
643  v_ProhibitOptional   tIntegerArray;
644  v_ProhibitConnector  tIntegerArray;
645  v_NodeIndexPath      tIntegerArray;
646  v_NodeDownPath       tStringArray;
647  v_RelativeNodePath   tStringArray;
648  v_AssignedDownPath   tStringArray;
649  v_NodeUpPath         tStringArray;
650  v_RuleQualifiedName  tStringArray;
651  v_FuncQualifiedName  tStringArray;
652 
653  v_LoadHeaders        tHeaderId;
654  v_LoadConditions     tStringArray;
655 
656  h_EffFrom            tDateArray;
657  h_EffUntil           tDateArray;
658  h_EffUsageMask       tUsageMask;
659 
660  PrevRuleEffFrom      tDateArray;
661  PrevRuleEffUntil     tDateArray;
662  PrevRuleUsageMask    tUsageMask;
663 
664  nAntecedentId        cz_rules.antecedent_id%TYPE;
665  nConsequentId        cz_rules.consequent_id%TYPE;
666  nRuleId              cz_rules.rule_id%TYPE;
667  nRuleFolderId        cz_rules.rule_folder_id%TYPE;
668  nRuleType            cz_rules.rule_type%TYPE;
669  RuleTemplateType     cz_rules.rule_type%TYPE;
670  nRuleOperator        cz_rules.expr_rule_type%TYPE;
671  nReasonId            cz_rules.reason_id%TYPE;
672  nComponentId         cz_rules.component_id%TYPE;
673  nModelRefExplId      cz_rules.model_ref_expl_id%TYPE;
674  dEffFrom             cz_rules.effective_from%TYPE;
675  dEffUntil            cz_rules.effective_until%TYPE;
676  nRuleEffSetId        cz_rules.effectivity_set_id%TYPE;
677  nUnsatisfiedId       cz_rules.unsatisfied_msg_id%TYPE;
678  nUnsatisfiedSource   cz_rules.unsatisfied_msg_source%TYPE;
679  nPresentationFlag    cz_rules.presentation_flag%TYPE;
680  vRuleName            cz_rules.name%TYPE;
681  vUsageMask           cz_rules.effective_usage_mask%TYPE;
682  vClassName           cz_rules.class_name%TYPE;
683  MaxDepthId           cz_model_ref_expls.model_ref_expl_id%TYPE;
684  nAux                 cz_model_ref_expls.model_ref_expl_id%TYPE;
685  MaxDepthValue        cz_model_ref_expls.node_depth%TYPE;
686  baseDepthValue       cz_model_ref_expls.node_depth%TYPE;
687  nHeaderId            cz_lce_headers.lce_header_id%TYPE;
688  nPreviousHeaderId    cz_lce_headers.lce_header_id%TYPE;
689  nNewLogicFileFlag    PLS_INTEGER := 0;
690  nRuleAssignedLevel   PLS_INTEGER;
691  MaxDepthIndex        PLS_INTEGER;
692  logicNetType         PLS_INTEGER;
693  expressionSize       PLS_INTEGER;
694  expressionStart      PLS_INTEGER;
695  expressionEnd        PLS_INTEGER;
696  numericLHS           PLS_INTEGER;
697  generateCompare      PLS_INTEGER;
698  generateCollect      PLS_INTEGER;
699 
700  ConnectorIndex       PLS_INTEGER;
701  InstantiableIndex    PLS_INTEGER;
702  OptionalIndex        PLS_INTEGER;
703  AssignableIndex      PLS_INTEGER;
704  TrackableIndex       PLS_INTEGER;
705 
706  jAntecedentRoot      PLS_INTEGER;
707  jConsequentRoot      PLS_INTEGER;
708  jAntecedentRootCount PLS_INTEGER;
709  jConsequentRootCount PLS_INTEGER;
710  ListType             PLS_INTEGER;
711  nLocalDefaults       PLS_INTEGER := 0;
712  nLocalExprId         PLS_INTEGER := 1000;
713 
714  nCounter             PLS_INTEGER;
715  distinctCount        PLS_INTEGER;
716  participantCount     PLS_INTEGER;
717  localFeatureType     PLS_INTEGER;
718  localMinimum         PLS_INTEGER;
719  auxIndex             NUMBER; --kdande; Bug 6881902; 11-Mar-2008
720  auxCount             NUMBER; --kdande; Bug 6881902; 11-Mar-2008
721  localString          VARCHAR2(32000);
722  pathString           VARCHAR2(32000);
723  baseString           VARCHAR2(32000);
724  localNodeId          NUMBER;
725  localRunId           NUMBER;
726 
727  generateRound        PLS_INTEGER;
728  optimizeChain        PLS_INTEGER;
729  optimizeContribute   PLS_INTEGER;
730  optimizeTarget       VARCHAR2(4000);
731  t_prefix             VARCHAR2(128);
732 
733  returnListType       PLS_INTEGER;
734  returnStringArray    tStringArray;
735 
736  parameterScope       tIteratorArray;
737  parameterName        tStringArray;
738 
739  --This type is used when it is necessary to hash a table name by a text key.
740 
741  TYPE temp_table_hash_type IS TABLE OF VARCHAR2(30) INDEX BY VARCHAR2(4000);
742  temp_table_hash      temp_table_hash_type;
743  temp_cmpt_table_hash temp_table_hash_type;
744 
745  --Some of the variables are level specific for embedded FORALL, so we need to know the
746  --the current level. One example is the table hash key below.
747  --COMPATIBLE currently cannot be embedded, so the variable will never be greater than 1.
748 
749  forallLevel          PLS_INTEGER := 0;
750  compatLevel          PLS_INTEGER := 0;
751 
752  --This key is used to identify a temporary table constructed for an iterator and hash its
753  --name in temp_table_hash or temp_cmpt_table_hash.
754  --The format of this key is:
755  --<ps_node_id>-<model_ref_expl_id>-<property_id-1>-...-<property_id_N>
756 
757  --We need tables of keys because of the possibility of embedded FORALL - on every level
758  --the level specific key should be considered.
759  --Although currently FORALL cannot be embedded into COMPATIBLE, this may change in the
760  --future, therefore it is better to have separate keys.
761 
762  temp_table_hash_key  tStringArray;
763  temp_cmpt_hash_key   tStringArray;
764 
765  --This is a universal array accumulating all the temp tables we need to delete across
766  --all FORALL(s) and COMPATIBLE(s).
767 
768  temp_tables          tStringArray;
769 
770  --For logic and comparison rules having an unsatisified message (unsatisfied_msg_source <> 0)
771  --this string will be populated with unsatisfied_msg_id, and used as a part of GS syntax when
772  --the relation has more then one operand on either side. For all the other types of rules the
773  --string will be null.
774 
775  sUnsatisfiedId       VARCHAR2(4000);
776 ---------------------------------------------------------------------------------------
777 FUNCTION GET_PROPERTY_VALUE(p_node_id     IN cz_ps_nodes.ps_node_id%TYPE,
778                             p_property_id IN cz_properties.property_id%TYPE,
779                             p_item_id     IN cz_item_masters.item_id%TYPE,
780                             x_data_type   IN OUT NOCOPY cz_properties.data_type%TYPE)
781   RETURN VARCHAR2 IS
782     l_def_value  cz_properties.def_value%TYPE;
783     l_tab        tStringArray;
784 BEGIN
785 
786   SELECT NVL(TO_CHAR(def_num_value), def_value), data_type INTO l_def_value, x_data_type
787     FROM cz_properties
788    WHERE property_id = p_property_id
789      AND deleted_flag = FLAG_NOT_DELETED;
790 
791   SELECT NVL(TO_CHAR(data_num_value), data_value) BULK COLLECT INTO l_tab
792     FROM cz_ps_prop_vals
793    WHERE ps_node_id = p_node_id
794      AND property_id = p_property_id
795      AND deleted_flag = FLAG_NOT_DELETED;
796 
797   IF(l_tab.COUNT = 0 AND p_item_id IS NOT NULL)THEN
798 
799      SELECT NVL(TO_CHAR(property_num_value), property_value) BULK COLLECT INTO l_tab
800        FROM cz_item_property_values
801       WHERE property_id = p_property_id
802         AND item_id = p_item_id
803         AND deleted_flag = FLAG_NOT_DELETED;
804 
805      IF(l_tab.COUNT = 0)THEN
806 
807          SELECT NULL BULK COLLECT INTO l_tab
808            FROM cz_item_type_properties t, cz_item_masters m
809           WHERE m.item_id = p_item_id
810             AND m.deleted_flag = FLAG_NOT_DELETED
811             AND t.deleted_flag = FLAG_NOT_DELETED
812             AND t.property_id = p_property_id
813             AND t.item_type_id = m.item_type_id;
814      END IF;
815   END IF;
816 
817   IF(l_tab.EXISTS(1))THEN
818 
819     IF(x_data_type = DATATYPE_TRANSLATABLE_PROP)THEN
820 
821       SELECT localized_str INTO l_tab(1) FROM cz_localized_texts
822        WHERE intl_text_id = l_tab(1) AND language = USERENV('LANG');
823 
824       IF(l_tab(1) IS NULL)THEN
825 
826         SELECT localized_str INTO l_tab(1) FROM cz_localized_texts
827          WHERE intl_text_id = l_def_value AND language = USERENV('LANG');
828       END IF;
829     END IF;
830 
831      RETURN NVL(l_tab(1), l_def_value);
832   END IF;
833 
834   x_data_type := NULL;
835   RETURN NULL;
836 
837 EXCEPTION
838   WHEN NO_DATA_FOUND THEN
839     x_data_type := NULL;
840     RETURN NULL;
841 END;
842 ---------------------------------------------------------------------------------------
843 --The local procedure is required because the sequence numbers must be different
844 --Still works with global buffers and commit parameters
845 
846  PROCEDURE PACK IS
847  BEGIN
848     IF(vLogicLine IS NOT NULL)THEN
849      IF(LENGTHB(vLogicText) + LENGTHB(vLogicLine)>2000)THEN
850 
851        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
852         (nHeaderId, v_tSequenceNbr(nHeaderId), vLogicText);
853        vLogicText := NULL;
854        v_tSequenceNbr(nHeaderId) := v_tSequenceNbr(nHeaderId) + 1;
855 
856        --Commit in blocks if not disabled
857 
858        IF(TwoPhaseCommit = 0)THEN
859          commit_counter := commit_counter + 1;
860          IF(commit_counter = CommitBlockSize)THEN
861           COMMIT;
862           commit_counter := 0;
863          END IF;
864        END IF;
865      END IF;
866      vLogicText := vLogicText || vLogicLine;
867      vLogicLine := NULL;
868     END IF;
869  END PACK;
870 ---------------------------------------------------------------------------------------
871 --This function returns fully qualified rule name given rule_folder_id of a rule
872 --and puts generated names into a hash table for reuse.
873 
874 FUNCTION RULE_NAME RETURN VARCHAR2 IS
875   vQualified  VARCHAR2(4000) := '.';
876   nRuleName   PLS_INTEGER;
877 BEGIN
878   IF(nRuleFolderId IS NULL OR nRuleFolderId = -1)THEN RETURN vRuleName; END IF;
879   IF(v_RuleQualifiedName.EXISTS(nRuleFolderId))THEN RETURN v_RuleQualifiedName(nRuleFolderId) || vRuleName; END IF;
880   nRuleName := LENGTHB(vRuleName);
881   FOR folder IN (SELECT name FROM cz_rule_folders
882                   WHERE deleted_flag = FLAG_NOT_DELETED
883                     AND parent_rule_folder_id IS NOT NULL
884                   START WITH rule_folder_id = nRuleFolderId
885                     AND object_type = 'RFL'
886                 CONNECT BY PRIOR parent_rule_folder_id = rule_folder_id
887                     AND object_type = 'RFL')LOOP
888      IF(LENGTHB(folder.name) + LENGTHB(vQualified) + 1 < 2000 - nRuleName)THEN
889       vQualified := '.' || folder.name || vQualified;
890      ELSE
891       EXIT;
892      END IF;
893   END LOOP;
894   v_RuleQualifiedName(nRuleFolderId) := vQualified;
895   RETURN vQualified || vRuleName;
896 END;
897 ---------------------------------------------------------------------------------------
898 --This function returns fully qualified name of a functional companion given
899 --rule_folder_id.
900 
901 FUNCTION COMPANION_NAME(inCompanionName IN VARCHAR2, inFolderId IN NUMBER) RETURN VARCHAR2 IS
902   vQualified  VARCHAR2(4000) := '.';
903   nameLen     PLS_INTEGER;
904 BEGIN
905   IF(inFolderId IS NULL OR inFolderId = -1)THEN RETURN inCompanionName; END IF;
906   IF(v_FuncQualifiedName.EXISTS(inFolderId))THEN RETURN v_FuncQualifiedName(inFolderId) || inCompanionName; END IF;
907   nameLen := LENGTHB(inCompanionName);
908   FOR folder IN (SELECT name FROM cz_rule_folders
909                   WHERE deleted_flag = FLAG_NOT_DELETED
910                     AND parent_rule_folder_id IS NOT NULL
911                  START WITH rule_folder_id = inFolderId
912                  CONNECT BY PRIOR parent_rule_folder_id = rule_folder_id)LOOP
913      IF(LENGTHB(folder.name) + LENGTHB(vQualified) + 1 < 2000 - nameLen)THEN
914       vQualified := '.' || folder.name || vQualified;
915      ELSE
916       EXIT;
917      END IF;
918   END LOOP;
919   v_FuncQualifiedName(inFolderId) := vQualified;
920   RETURN vQualified || inCompanionName;
921 END;
922 ---------------------------------------------------------------------------------------
923 --The ps_node_id value is fixed in the memory for references to BOM. This function can
924 --be called when the original value (ps_node_id of the reference node) is required.
925 
926 FUNCTION REAL_PS_NODE_ID(j IN PLS_INTEGER) RETURN NUMBER IS
927 BEGIN
928   IF(v_tRealPsNodeId.EXISTS(j))THEN RETURN v_tRealPsNodeId(j); ELSE RETURN v_tExprPsNodeId(j); END IF;
929 END;
930 ---------------------------------------------------------------------------------------
931 FUNCTION SIGNATURE_DATA_TYPE(p_signature_id IN NUMBER) RETURN PLS_INTEGER IS
932   v_data_type  PLS_INTEGER;
933 BEGIN
934   IF(h_SignatureDataType.EXISTS(p_signature_id))THEN RETURN h_SignatureDataType(p_signature_id); END IF;
935 
936   BEGIN
937     SELECT data_type INTO v_data_type FROM cz_signatures
938      WHERE deleted_flag = FLAG_NOT_DELETED
939        AND signature_id = p_signature_id;
940 
941     h_SignatureDataType(p_signature_id) := v_data_type;
942     RETURN v_data_type;
943   EXCEPTION
944     WHEN OTHERS THEN
945       RAISE CZ_R_NO_SIGNATURE_ID;
946   END;
947 END;
948 ---------------------------------------------------------------------------------------
949 FUNCTION COMPATIBLE_DATA_TYPES(p_object_type IN PLS_INTEGER, p_subject_type PLS_INTEGER) RETURN BOOLEAN IS
950   v_null  PLS_INTEGER;
951 BEGIN
952   SELECT NULL INTO v_null FROM cz_conversion_rels_v
953    WHERE object_type = p_object_type AND subject_type = p_subject_type;
954   RETURN TRUE;
955 EXCEPTION
956   WHEN NO_DATA_FOUND THEN
957     RETURN FALSE;
958   WHEN TOO_MANY_ROWS THEN
959     RETURN TRUE;
960   WHEN OTHERS THEN
961     RETURN FALSE;
962 END;
963 ---------------------------------------------------------------------------------------
964 FUNCTION GET_ARGUMENT_INFO(p_param_index  IN NUMBER,
965                            p_signature_id IN NUMBER,
966                            x_mutable      IN OUT NOCOPY VARCHAR2,
967                            x_collection   IN OUT NOCOPY VARCHAR2)
968 RETURN NUMBER IS
969   v_data_type  cz_signature_arguments.data_type%TYPE;
970 BEGIN
971   SELECT data_type, mutable_flag, collection_flag INTO v_data_type, x_mutable, x_collection
972     FROM cz_signature_arguments
973    WHERE deleted_flag = FLAG_NOT_DELETED
974      AND argument_signature_id = p_signature_id
975      AND argument_index = p_param_index;
976   RETURN v_data_type;
977 EXCEPTION
978   WHEN OTHERS THEN
979     RETURN DATA_TYPE_VOID;
980 END;
981 ---------------------------------------------------------------------------------------
982 FUNCTION APPLICABLE_SYS_PROP(j IN PLS_INTEGER, p_ps_node_id IN NUMBER, p_rule_id IN NUMBER) RETURN BOOLEAN IS
983   v_null        PLS_INTEGER;
984   v_ps_node_id  NUMBER;
985   v_data_type   cz_signature_arguments.data_type%TYPE;
986   v_mutable     cz_signature_arguments.mutable_flag%TYPE;
987   v_collection  cz_signature_arguments.collection_flag%TYPE;
988 BEGIN
989 
990   --Some of the upgraded rules may not have param_index and param_signature_id populated. However, upgraded
991   --rules are not real statement rules, so they are not supposed to have any user error in them and in this
992   --case the verification is not required.
993 
994   IF(v_tExprParamIndex(j) IS NULL OR v_tExprParSignature(j) IS NULL)THEN RETURN TRUE; END IF;
995 
996   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;
997   v_data_type := GET_ARGUMENT_INFO(v_tExprParamIndex(j), v_tExprParSignature(j), v_mutable, v_collection);
998 
999   SELECT NULL INTO v_null
1000     FROM cz_rul_typedpsn_v psn,
1001          cz_conversion_rels_v cnv,
1002          cz_system_property_rels_v rel,
1003          cz_system_properties_v sys,
1004          cz_conversion_rels_v cnv2
1005    WHERE psn.detailed_type_id = cnv.object_type
1006      AND cnv.subject_type = rel.subject_type
1007      AND rel.object_type = sys.rule_id
1008      AND rel.rel_type_code = 'SYS'
1009      AND sys.data_type = cnv2.object_type
1010      AND psn.ps_node_id = v_ps_node_id
1011      AND sys.rule_id = p_rule_id
1012      AND sys.mutable_flag >= v_mutable
1013      AND sys.collection_flag <= v_collection
1014      AND cnv2.subject_type = v_data_type;
1015 
1016   RETURN TRUE;
1017 EXCEPTION
1018   WHEN NO_DATA_FOUND THEN
1019     RETURN FALSE;
1020   WHEN TOO_MANY_ROWS THEN
1021     RETURN TRUE;
1022   WHEN OTHERS THEN
1023     RETURN FALSE;
1024 END;
1025 ---------------------------------------------------------------------------------------
1026 FUNCTION APPLICABLE_SYS_PROP(j IN PLS_INTEGER, p_ps_node_id IN NUMBER, p_rule_name IN VARCHAR2) RETURN BOOLEAN IS
1027   v_null        PLS_INTEGER;
1028   v_ps_node_id  NUMBER;
1029   v_data_type   cz_signature_arguments.data_type%TYPE;
1030   v_mutable     cz_signature_arguments.mutable_flag%TYPE;
1031   v_collection  cz_signature_arguments.collection_flag%TYPE;
1032 BEGIN
1033 
1034   --Some of the upgraded rules may not have param_index and param_signature_id populated. However, upgraded
1035   --rules are not real statement rules, so they are not supposed to have any user error in them and in this
1036   --case the verification is not required.
1037 
1038   IF(v_tExprParamIndex(j) IS NULL OR v_tExprParSignature(j) IS NULL)THEN RETURN TRUE; END IF;
1039 
1040   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;
1041   v_data_type := GET_ARGUMENT_INFO(v_tExprParamIndex(j), v_tExprParSignature(j), v_mutable, v_collection);
1042 
1043   SELECT NULL INTO v_null
1044     FROM cz_rul_typedpsn_v psn,
1045          cz_conversion_rels_v cnv,
1046          cz_system_property_rels_v rel,
1047          cz_system_properties_v sys,
1048          cz_conversion_rels_v cnv2
1049    WHERE psn.detailed_type_id = cnv.object_type
1050      AND cnv.subject_type = rel.subject_type
1051      AND rel.object_type = sys.rule_id
1052      AND rel.rel_type_code = 'SYS'
1053      AND sys.data_type = cnv2.object_type
1054      AND psn.ps_node_id = v_ps_node_id
1055      AND UPPER(sys.name) = p_rule_name
1056      AND sys.mutable_flag >= v_mutable
1057      AND sys.collection_flag <= v_collection
1058      AND cnv2.subject_type = v_data_type;
1059 
1060   RETURN TRUE;
1061 EXCEPTION
1062   WHEN NO_DATA_FOUND THEN
1063     RETURN FALSE;
1064   WHEN TOO_MANY_ROWS THEN
1065     RETURN TRUE;
1066   WHEN OTHERS THEN
1067     RETURN FALSE;
1068 END;
1069 ---------------------------------------------------------------------------------------
1070 --Splits the CHR(7)-separated path into an array of node names.
1071 
1072 FUNCTION SPLIT_PATH(p_path IN VARCHAR2) RETURN tStringArray IS
1073 
1074   l_substr      VARCHAR2(32000) := p_path;
1075   l_index       PLS_INTEGER;
1076   l_return_tbl  tStringArray;
1077 BEGIN
1078 
1079   IF(p_path IS NULL)THEN RETURN l_return_tbl; END IF;
1080   LOOP
1081 
1082     l_index := INSTR(l_substr, FND_GLOBAL.LOCAL_CHR(7));
1083 
1084     IF(l_index > 0)THEN
1085 
1086       l_return_tbl(l_return_tbl.COUNT + 1) := SUBSTR(l_substr, 1, l_index - 1);
1087       l_substr := SUBSTR(l_substr, l_index + 1);
1088     ELSE
1089 
1090       l_return_tbl(l_return_tbl.COUNT + 1) := l_substr;
1091       EXIT;
1092     END IF;
1093   END LOOP;
1094 
1095   RETURN l_return_tbl;
1096 END;
1097 ---------------------------------------------------------------------------------------
1098 PROCEDURE RESOLVE_NODE(p_node_tbl        IN tStringArray,
1099                        p_parent_node_id  IN NUMBER,
1100                        p_parent_expl_id  IN NUMBER,
1101                        x_child_node_id   IN OUT NOCOPY NUMBER,
1102                        x_child_expl_id   IN OUT NOCOPY NUMBER) IS
1103 
1104   l_eff_from            DATE := EpochBeginDate;
1105   l_eff_until           DATE := EpochEndDate;
1106   l_index               PLS_INTEGER;
1107   l_parent_id           NUMBER;
1108 
1109   l_return_node_id_tbl  tNumberArray;
1110   l_return_expl_id_tbl  tNumberArray;
1111 
1112   FUNCTION REPORT_PATH RETURN VARCHAR2 IS
1113 
1114     l_return  VARCHAR2(32000) := NULL;
1115   BEGIN
1116 
1117     FOR i IN 1..p_node_tbl.COUNT LOOP
1118 
1119       IF(l_return IS NOT NULL)THEN l_return := l_return || '.'; END IF;
1120       l_return := l_return || p_node_tbl(i);
1121     END LOOP;
1122    RETURN l_return;
1123   END;
1124 
1125   PROCEDURE RESOLVE_CHILDREN(p_index      IN PLS_INTEGER,
1126                              p_node_id    IN NUMBER,
1127                              p_expl_id    IN NUMBER,
1128                              p_eff_from   IN DATE,
1129                              p_eff_until  IN DATE) IS
1130 
1131     t_eff_from_tbl   tDateArray;
1132     t_eff_until_tbl  tDateArray;
1133     t_node_id_tbl    tNumberArray;
1134     t_expl_id_tbl    tNumberArray;
1135     l_eff_from_tbl   tDateArray;
1136     l_eff_until_tbl  tDateArray;
1137     l_node_id_tbl    tNumberArray;
1138     l_expl_id_tbl    tNumberArray;
1139 
1140     l_counter        PLS_INTEGER := 0;
1141     l_index          PLS_INTEGER;
1142   BEGIN
1143 
1144     SELECT ps_node_id, model_ref_expl_id, effective_from, effective_until
1145       BULK COLLECT INTO l_node_id_tbl, l_expl_id_tbl, l_eff_from_tbl, l_eff_until_tbl
1146       FROM cz_explmodel_nodes_v
1147      WHERE model_id = inComponentId
1148        AND parent_psnode_expl_id = p_expl_id
1149        AND effective_parent_id = p_node_id
1150        AND suppress_flag = '0'
1151        AND name = p_node_tbl(p_index);
1152 
1153     FOR i IN 1..l_node_id_tbl.COUNT LOOP
1154 
1155       IF(p_eff_from > l_eff_from_tbl(i))THEN l_eff_from_tbl(i) := p_eff_from; END IF;
1156       IF(p_eff_until < l_eff_until_tbl(i))THEN l_eff_until_tbl(i) := p_eff_until; END IF;
1157 
1158       IF(l_eff_from_tbl(i) <= l_eff_until_tbl(i))THEN
1159 
1160         l_counter := l_counter + 1;
1161 
1162         t_eff_from_tbl(l_counter) := l_eff_from_tbl(i);
1163         t_eff_until_tbl(l_counter) := l_eff_until_tbl(i);
1164         t_node_id_tbl(l_counter) := l_node_id_tbl(i);
1165         t_expl_id_tbl(l_counter) := l_expl_id_tbl(i);
1166       END IF;
1167     END LOOP;
1168 
1169     FOR i IN 1..t_node_id_tbl.COUNT LOOP
1170 
1171       IF(p_index = p_node_tbl.COUNT)THEN
1172 
1173         l_index := l_return_node_id_tbl.COUNT + 1;
1174 
1175         l_return_node_id_tbl(l_index) := t_node_id_tbl(i);
1176         l_return_expl_id_tbl(l_index) := t_expl_id_tbl(i);
1177       ELSE
1178 
1179         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));
1180       END IF;
1181     END LOOP;
1182   END;
1183 BEGIN
1184 
1185   --Propagate effectivity from all the bom references down from the root model.
1186 
1187   FOR i IN 1..globalLevel LOOP
1188 
1189     --We need to stop on the model, in which the rule is defined.
1190 
1191     IF(globalStack(i) = inComponentId)THEN EXIT; END IF;
1192 
1193     --Account only for references to bom(s).
1194 
1195     IF(glPsNodeType(glIndexByPsNodeId(globalStack(i))) IN (PS_NODE_TYPE_BOM_MODEL,PS_NODE_TYPE_BOM_OPTIONCLASS,PS_NODE_TYPE_BOM_STANDARD))THEN
1196 
1197       l_index := glIndexByPsNodeId(globalRef(i));
1198 
1199       IF(glEffFrom(l_index) > l_eff_from)THEN l_eff_from := glEffFrom(l_index); END IF;
1200       IF(glEffUntil(l_index) < l_eff_until)THEN l_eff_until := glEffUntil(l_index); END IF;
1201     END IF;
1202   END LOOP;
1203 
1204   --Adjust effectivities for the least unambiguous parent.
1205 
1206   l_index := glIndexByPsNodeId(p_parent_node_id);
1207 
1208   IF(glEffFrom(l_index) > l_eff_from)THEN l_eff_from := glEffFrom(l_index); END IF;
1209   IF(glEffUntil(l_index) < l_eff_until)THEN l_eff_until := glEffUntil(l_index); END IF;
1210 
1211   --Finally adjust for the rule effectivity.
1212 
1213   IF(dEffFrom > l_eff_from)THEN l_eff_from := dEffFrom; END IF;
1214   IF(dEffUntil < l_eff_until)THEN l_eff_until := dEffUntil; END IF;
1215 
1216   --If effectivity range is empty, it will be impossible to resolve the node.
1217 
1218   IF(l_eff_until < l_eff_from)THEN
1219 
1220     localString := REPORT_PATH;
1221     RAISE CZ_R_INCORRECT_REFERENCE;
1222   END IF;
1223 
1224   IF(p_node_tbl.COUNT = 0)THEN
1225 
1226     x_child_node_id := p_parent_node_id;
1227     x_child_expl_id := p_parent_expl_id;
1228     RETURN;
1229   END IF;
1230 
1231   RESOLVE_CHILDREN(1, p_parent_node_id, p_parent_expl_id, l_eff_from, l_eff_until);
1232 
1233   IF(l_return_node_id_tbl.COUNT = 0)THEN
1234 
1235     localString := REPORT_PATH;
1236     RAISE CZ_R_INCORRECT_REFERENCE;
1237   ELSIF(l_return_node_id_tbl.COUNT > 1)THEN
1238 
1239     localString := REPORT_PATH;
1240     RAISE CZ_R_AMBIGUOUS_REFERENCE;
1241   ELSE
1242 
1243     x_child_node_id := l_return_node_id_tbl(1);
1244     x_child_expl_id := l_return_expl_id_tbl(1);
1245   END IF;
1246 END;
1247 ---------------------------------------------------------------------------------------
1248 --Forward declarations block.
1249 
1250 FUNCTION GENERATE_EXPRESSION(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray;
1251 FUNCTION GENERATE_REFNODE(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray;
1252 FUNCTION LOOKUP_ARGUMENT(j IN PLS_INTEGER) RETURN PLS_INTEGER;
1253 FUNCTION GENERATE_ARGUMENT(j IN PLS_INTEGER, ListType IN OUT NOCOPY PLS_INTEGER) RETURN tStringArray;
1254 ---------------------------------------------------------------------------------------
1255 FUNCTION HAS_LOGICAL_VALUE(j IN PLS_INTEGER) RETURN BOOLEAN IS
1256   NodeType     PLS_INTEGER := v_tExprType(j);
1257   PsNodeType   PLS_INTEGER;
1258   PsNodeIndex  PLS_INTEGER;
1259 BEGIN
1260 
1261   --When the validation is made from the high-level section of a logic rule, some of the participants
1262   --may still be arguments, so we need to look up the value of the argument before validating its
1263   --type. The argument in this case can be either a literal or a node (bug #3388169).
1264 
1265   IF(NodeType = EXPR_ARGUMENT)THEN
1266 
1267     PsNodeIndex := LOOKUP_ARGUMENT(j);
1268     IF(parameterScope(PsNodeIndex).node_id IS NULL)THEN RETURN FALSE; END IF;
1269 
1270     NodeType := EXPR_PSNODE;
1271     v_tExprPsNodeId(j) := parameterScope(PsNodeIndex).node_id;
1272   END IF;
1273 
1274   IF(NodeType = EXPR_NODE_TYPE_LITERAL)THEN
1275     RETURN (v_tExprDataType(j) = DATA_TYPE_BOOLEAN);
1276   ELSIF(NodeType = EXPR_PSNODE)THEN
1277     IF(v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN RETURN TRUE;
1278     ELSE
1279 
1280       PsNodeIndex := glIndexByPsNodeId(v_tExprPsNodeId(j));
1281       PsNodeType := glPsNodeType(PsNodeIndex);
1282 
1283       RETURN
1284          PsNodeType <> PS_NODE_TYPE_TOTAL
1285            AND
1286          PsNodeType <> PS_NODE_TYPE_RESOURCE
1287            AND
1288             (
1289              PsNodeType <> PS_NODE_TYPE_FEATURE
1290               OR
1291              glFeatureType(PsNodeIndex) IN (PS_NODE_FEATURE_TYPE_BOOLEAN, PS_NODE_FEATURE_TYPE_OPTION)
1292               OR
1293              (
1294                glFeatureType(PsNodeIndex) = PS_NODE_FEATURE_TYPE_INTEGER
1295                 AND
1296                glMinimum(PsNodeIndex) IS NOT NULL
1297                 AND
1298                glMinimum(PsNodeIndex) >= 0
1299              )
1300             );
1301     END IF;
1302   ELSIF(NodeType = EXPR_NODE_TYPE_OPERATOR)THEN
1303      RETURN COMPATIBLE_DATA_TYPES(SIGNATURE_DATA_TYPE(h_SignatureId(v_tExprSubtype(j))), DATA_TYPE_BOOLEAN);
1304   ELSIF(NodeType IN (EXPR_FORALL, EXPR_FORALL_DISTINCT))THEN
1305    RETURN TRUE;
1306   ELSE
1307    RETURN FALSE;
1308   END IF;
1309 END;
1310 ---------------------------------------------------------------------------------------
1311 FUNCTION HAS_OPTIONS_APPLIED(j IN PLS_INTEGER) RETURN BOOLEAN IS
1312 BEGIN
1313   RETURN (v_ChildrenIndex.EXISTS(v_tExprId(j)) AND
1314           h_SeededName.EXISTS(v_tExprSubtype(v_ChildrenIndex(v_tExprId(j)))) AND
1315           h_SeededName(v_tExprSubtype(v_ChildrenIndex(v_tExprId(j)))) = RULE_SYS_PROP_OPTIONS);
1316 END;
1317 ---------------------------------------------------------------------------------------
1318 FUNCTION GENERATE_NODE_CHILDREN(j IN PLS_INTEGER) RETURN tStringArray IS
1319  v_return  tStringArray;
1320  nChild    PLS_INTEGER;
1321  nCount    PLS_INTEGER;
1322  oper      tStringArray;
1323  ListType  PLS_INTEGER;
1324 BEGIN
1325 
1326 --nDebug := 7000005;
1327 
1328   nCount := 1;
1329   nChild := v_ChildrenIndex(v_tExprId(j));
1330 
1331 --nDebug := 7000006;
1332 
1333   WHILE(v_tExprParentId(nChild) = v_tExprId(j)) LOOP
1334 
1335 --nDebug := 7000007;
1336 
1337    oper.DELETE;
1338    oper := GENERATE_EXPRESSION(nChild, ListType);
1339 
1340    FOR i IN 1..oper.COUNT LOOP
1341 
1342     v_return(nCount) := oper(i);
1343     nCount := nCount + 1;
1344 
1345    END LOOP;
1346 
1347    nChild := nChild + 1;
1348 
1349   END LOOP;
1350 
1351 --nDebug := 7000008;
1352 
1353  RETURN v_return;
1354 END;
1355 ---------------------------------------------------------------------------------------
1356 FUNCTION GENERATE_NAME(j IN PLS_INTEGER, id IN NUMBER) RETURN VARCHAR2 IS --kdande; Bug 6881902; 11-Mar-2008
1357  v_return   VARCHAR2(4000);
1358  counter    PLS_INTEGER;
1359  val        PLS_INTEGER;
1360  delimiter  CHAR(1) := NULL;
1361  ExplId     cz_model_ref_expls.model_ref_expl_id%TYPE := v_tExplNodeId(j);
1362 BEGIN
1363 
1364  IF(NOT v_NodeUpPath.EXISTS(ExplId))THEN
1365    counter := nRuleAssignedLevel;
1366    val := v_NodeLogicLevel(ExplId);
1367    WHILE(counter > val) LOOP
1368      v_return := v_return || PATH_DELIMITER || 'parent';
1369      counter := counter - 1;
1370    END LOOP;
1371    v_NodeUpPath(ExplId) := v_return;
1372  ELSE
1373    v_return := v_NodeUpPath(ExplId);
1374  END IF;
1375 
1376  IF(v_tLogicNetType(nHeaderId) = LOGIC_NET_TYPE_NETWORK AND (NOT v_IsConnectorNet.EXISTS(ExplId)))THEN
1377 
1378    --If we are generating into a conditional net, we add an extra ^parent to the path, but only if
1379    --this is not a connector's net.
1380 
1381    v_return := PATH_DELIMITER || 'parent' || v_return;
1382  END IF;
1383 
1384  IF(v_return IS NOT NULL OR v_AssignedDownPath(ExplId) IS NOT NULL)THEN
1385    delimiter := PATH_DELIMITER;
1386  END IF;
1387 
1388  v_return := v_return || v_AssignedDownPath(ExplId) || delimiter;
1389 
1390  --The description below is only true if the reference participates in the rule as an
1391  --object, because if this is a rule against this reference's system property than we
1392  --still should generate the regular name. So, we need to make sure that we construct
1393  --the new name only if this reference participates in compatibility rules - the only
1394  --type of rules where it can participate as an object (an option). Bug #2567898.
1395 
1396  IF(nRuleType IN (RULE_TYPE_COMPAT_RULE, RULE_TYPE_COMPAT_TABLE, RULE_TYPE_DESIGNCHART_RULE) AND
1397     glPsNodeType(glIndexByPsNodeId(id)) = PS_NODE_TYPE_REFERENCE)THEN
1398 
1399    --The following comment is not exactly correct, see the above description.
1400    --The node identified by <id> is a reference. In this case we should not generate
1401    --the regular P_<id>, because such object would never exist. Instead, we generate
1402    --^N_<id>^P_<reference_id> to refer to the referenced object in the child subnet.
1403    --This fixes the base bug #2128641.
1404 
1405    IF(v_return IS NULL)THEN v_return := PATH_DELIMITER; END IF;
1406    v_return := v_return || 'N_' || TO_CHAR(glPersistentId(id)) || PATH_DELIMITER ||
1407                            'P_' || TO_CHAR(glReferenceId(id));
1408  ELSE
1409 
1410    v_return := v_return || 'P_' || TO_CHAR(glPersistentId(id));
1411  END IF;
1412 
1413  RETURN v_return;
1414 END;
1415 ---------------------------------------------------------------------------------------
1416 --Special version of GENERATE_NAME that accepts model_ref_expl_id value as a parameter
1417 --instead of extracting it from cz_expression nodes by index j.
1418 
1419 FUNCTION GENERATE_NAME_EXPL(ExplId IN PLS_INTEGER, id IN NUMBER) RETURN VARCHAR2 IS  --kdande; Bug 6881902; 11-Mar-2008
1420  v_return   VARCHAR2(4000);
1421  counter    PLS_INTEGER;
1422  val        PLS_INTEGER;
1423  delimiter  CHAR(1) := NULL;
1424 BEGIN
1425 
1426  IF(NOT v_NodeUpPath.EXISTS(ExplId))THEN
1427    counter := nRuleAssignedLevel;
1428    val := v_NodeLogicLevel(ExplId);
1429    WHILE(counter > val) LOOP
1430      v_return := v_return || PATH_DELIMITER || 'parent';
1431      counter := counter - 1;
1432    END LOOP;
1433    v_NodeUpPath(ExplId) := v_return;
1434  ELSE
1435    v_return := v_NodeUpPath(ExplId);
1436  END IF;
1437 
1438  IF(v_tLogicNetType(nHeaderId) = LOGIC_NET_TYPE_NETWORK AND (NOT v_IsConnectorNet.EXISTS(ExplId)))THEN
1439 
1440    --If we are generating into a conditional net, we add an extra ^parent to the path, but only if
1441    --this is not a connector's net.
1442 
1443    v_return := PATH_DELIMITER || 'parent' || v_return;
1444  END IF;
1445 
1446  IF(v_return IS NOT NULL OR v_AssignedDownPath(ExplId) IS NOT NULL)THEN
1447    delimiter := PATH_DELIMITER;
1448  END IF;
1449 
1450  v_return := v_return || v_AssignedDownPath(ExplId) || delimiter;
1451 
1452  --The description below is only true if the reference participates in the rule as an
1453  --object, because if this is a rule against this reference's system property than we
1454  --still should generate the regular name. So, we need to make sure that we construct
1455  --the new name only if this reference participates in compatibility rules - the only
1456  --type of rules where it can participate as an object (an option). Bug #2567898.
1457 
1458  IF(nRuleType IN (RULE_TYPE_COMPAT_RULE, RULE_TYPE_COMPAT_TABLE, RULE_TYPE_DESIGNCHART_RULE) AND
1459     glPsNodeType(glIndexByPsNodeId(id)) = PS_NODE_TYPE_REFERENCE)THEN
1460 
1461    --The following comment is not exactly correct, see the above description.
1462    --The node identified by <id> is a reference. In this case we should not generate
1463    --the regular P_<id>, because such object would never exist. Instead, we generate
1464    --^N_<id>^P_<reference_id> to refer to the referenced object in the child subnet.
1465    --This fixes the base bug #2128641.
1466 
1467    IF(v_return IS NULL)THEN v_return := PATH_DELIMITER; END IF;
1468    v_return := v_return || 'N_' || TO_CHAR(glPersistentId(id)) || PATH_DELIMITER ||
1469                            'P_' || TO_CHAR(glReferenceId(id));
1470  ELSE
1471 
1472    v_return := v_return || 'P_' || TO_CHAR(glPersistentId(id));
1473  END IF;
1474 
1475  RETURN v_return;
1476 END;
1477 ---------------------------------------------------------------------------------------
1478 FUNCTION GENERATE_NODE(j IN PLS_INTEGER) RETURN tStringArray IS
1479  v_return  tStringArray;
1480 BEGIN
1481 
1482   v_return(1) := GENERATE_NAME(j, v_tExprPsNodeId(j));
1483   RETURN v_return;
1484 
1485 END;
1486 ---------------------------------------------------------------------------------------
1487 FUNCTION ADJUSTED_EXPLOSION(p_parent_expl_id IN NUMBER, p_child_node_id IN NUMBER) RETURN NUMBER IS
1488 BEGIN
1489   FOR i IN 1..v_NodeId.COUNT LOOP
1490     IF(v_tParentId(i) = p_parent_expl_id AND v_tReferringId(i) = p_child_node_id)THEN
1491       RETURN v_NodeId(i);
1492     END IF;
1493   END LOOP;
1494 END;
1495 ---------------------------------------------------------------------------------------
1496 FUNCTION EXPAND_NODE(j IN PLS_INTEGER) RETURN tIntegerArray IS
1497   v_result       tIntegerArray;
1498   nCount         PLS_INTEGER;
1499   v_ps_node_id   NUMBER; --kdande; Bug 6881902; 11-Mar-2008
1500   v_node_type    PLS_INTEGER;
1501   v_index        PLS_INTEGER;
1502   v_start_index  PLS_INTEGER;
1503   v_end_index    PLS_INTEGER;
1504 BEGIN
1505 
1506   IF(v_tExprType(j) = EXPR_OPERATOR)THEN
1507 
1508     --The function is called on an operator node. We assume that this is OptionsOf, and so it has one
1509     --operand which represents a structure node. This structure node has its explosion populated in
1510     --cz_expression_nodes table. It is often convenient to associate this explosion also with the
1511     --operator itself. This is a fix for the bug #2232741.
1512 
1513     v_ps_node_id := v_tExprPsNodeId(v_ChildrenIndex(v_tExprId(j)));
1514     v_tExplNodeId(j) := v_tExplNodeId(v_ChildrenIndex(v_tExprId(j)));
1515 
1516   ELSIF(v_tExprType(j) = EXPR_PSNODE AND v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
1517 
1518     v_ps_node_id := v_tExprPsNodeId(j);
1519   ELSE
1520 
1521     --Left for backward compatibility.
1522 
1523     v_result(1) := v_tExprPsNodeId(j);
1524     RETURN v_result;
1525   END IF;
1526 
1527   v_index := glIndexByPsNodeId(v_ps_node_id);
1528   v_node_type := glPsNodeType(v_index);
1529   v_start_index := v_index + 1;
1530 
1531   IF(NOT glLastChildIndex.EXISTS(v_ps_node_id))THEN
1532 
1533     localString := glName(v_index);
1534     RAISE CZ_E_NO_EXPECTED_CHILDREN;
1535   END IF;
1536 
1537   v_end_index := glLastChildIndex(v_ps_node_id);
1538   nCount := 1;
1539 
1540   --If the function is called on a feature, we return options. If the function is called on a
1541   --BOM node, we return BOM children.
1542 
1543   IF(v_node_type = PS_NODE_TYPE_FEATURE)THEN
1544 
1545     FOR i IN v_start_index..v_end_index LOOP
1546 
1547       v_result(nCount) := glPsNodeId(i);
1548       v_ExplByPsNodeId(glPsNodeId(i)) := v_tExplNodeId(j);
1549       nCount := nCount + 1;
1550     END LOOP;
1551   ELSIF(v_node_type IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
1552 
1553     FOR i IN v_start_index..v_end_index LOOP
1554 
1555       IF((glPsNodeType(i) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD) OR
1556           (glPsNodeType(i) = PS_NODE_TYPE_REFERENCE AND
1557           glPsNodeType(glIndexByPsNodeId(glReferenceId(glPsNodeId(i)))) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD)))
1558           AND glParentId(i) = v_ps_node_id)THEN
1559 
1560            IF(glPsNodeType(i) = PS_NODE_TYPE_REFERENCE)THEN
1561              v_result(nCount) := glReferenceId(glPsNodeId(i));
1562              v_ExplByPsNodeId(glReferenceId(glPsNodeId(i))) := ADJUSTED_EXPLOSION(v_tExplNodeId(j), glPsNodeId(i));
1563            ELSE
1564              v_result(nCount) := glPsNodeId(i);
1565              v_ExplByPsNodeId(glPsNodeId(i)) := v_tExplNodeId(j);
1566            END IF;
1567            nCount := nCount + 1;
1568       END IF;
1569     END LOOP;
1570   END IF;
1571  RETURN v_result;
1572 END;
1573 ---------------------------------------------------------------------------------------
1574 FUNCTION GENERATE_CHILDRENOF(p_expl_id IN PLS_INTEGER, p_ps_node_id IN NUMBER) RETURN tStringArray IS  --kdande; Bug 6881902; 11-Mar-2008
1575   v_return       tStringArray;
1576   nCount         PLS_INTEGER;
1577   v_node_type    PLS_INTEGER;
1578   v_index        PLS_INTEGER;
1579   v_start_index  PLS_INTEGER;
1580   v_end_index    PLS_INTEGER;
1581 BEGIN
1582 
1583 nDebug := 7004050;
1584 
1585   --This function does basically the same as the previous one. The difference is that it can be used
1586   --only for system property, it is called on the system property node, taking the ps_node_id of the
1587   --parent as a parameter, and it returns generated names.
1588 
1589   v_index := glIndexByPsNodeId(p_ps_node_id);
1590   v_node_type := glPsNodeType(v_index);
1591   v_start_index := v_index + 1;
1592 
1593   IF(NOT glLastChildIndex.EXISTS(p_ps_node_id))THEN
1594 
1595     localString := glName(v_index);
1596     RAISE CZ_E_NO_EXPECTED_CHILDREN;
1597   END IF;
1598 
1599   v_end_index := glLastChildIndex(p_ps_node_id);
1600   nCount := 1;
1601 
1602   --If the function is called on a feature, we return options. If the function is called on a
1603   --BOM node, we return BOM children.
1604 
1605   IF(v_node_type = PS_NODE_TYPE_FEATURE)THEN
1606 
1607     FOR i IN v_start_index..v_end_index LOOP
1608 
1609       v_return(nCount) := GENERATE_NAME_EXPL(p_expl_id, glPsNodeId(i));
1610       nCount := nCount + 1;
1611     END LOOP;
1612 
1613   ELSIF(v_node_type IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
1614 
1615     FOR i IN v_start_index..v_end_index LOOP
1616       IF((glPsNodeType(i) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD) OR
1617           (glPsNodeType(i) = PS_NODE_TYPE_REFERENCE AND
1618           glPsNodeType(glIndexByPsNodeId(glReferenceId(glPsNodeId(i)))) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD)))
1619           AND glParentId(i) = p_ps_node_id)THEN
1620 
1621            IF(glPsNodeType(i) = PS_NODE_TYPE_REFERENCE)THEN
1622              v_return(nCount) := GENERATE_NAME_EXPL(ADJUSTED_EXPLOSION(p_expl_id, glPsNodeId(i)), glReferenceId(glPsNodeId(i)));
1623            ELSE
1624              v_return(nCount) := GENERATE_NAME_EXPL(p_expl_id, glPsNodeId(i));
1625            END IF;
1626            nCount := nCount + 1;
1627       END IF;
1628     END LOOP;
1629   END IF;
1630 
1631 nDebug := 7004059;
1632 
1633  RETURN v_return;
1634 END;
1635 ---------------------------------------------------------------------------------------
1636 FUNCTION GENERATE_ARITHMETIC(j IN PLS_INTEGER) RETURN tStringArray IS
1637 
1638   v_return     tStringArray;
1639   nChild       PLS_INTEGER;
1640   nCount       PLS_INTEGER;
1641   lhs          tStringArray;
1642   rhs          tStringArray;
1643   ListType     PLS_INTEGER;
1644   v_rounding   VARCHAR2(16) := ' ';
1645   v_target     VARCHAR2(4000);
1646   v_parj       PLS_INTEGER;
1647   optimizeFlag PLS_INTEGER := 0;
1648 
1649 BEGIN
1650 
1651   IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
1652    RAISE CZ_E_WRONG_ARITHMETIC_OPER;
1653   END IF;
1654 
1655   nCount := 1;
1656   nChild := v_ChildrenIndex(v_tExprId(j));
1657   IF(v_tExprParentId.EXISTS(nChild + 1) AND v_tExprParentId(nChild + 1) = v_tExprId(j))THEN
1658    nCount := 2;
1659   END IF;
1660 
1661 nDebug := 8004002;
1662 
1663   --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
1664   nLocalDefaults := nLocalDefaults + 1;
1665   v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
1666   v_target := 'TOTAL ' || v_return(1) || NewLine;
1667 
1668   --Check if this procedure has been called for generation of a direct child expression of a rounding
1669   --operator. If so, set a flag to generate an enhanced contribute relation and no temporary total.
1670   --If the rounding operator is a root operator of a numeric rule with an advanced lhs expression,
1671   --which is indicated by the optimizeChain flag, generate the optimized contribute relation.
1672 
1673   IF(v_tExprParentId(j) IS NOT NULL)THEN
1674 
1675     v_parj := v_IndexByExprNodeId(v_tExprParentId(j));
1676 
1677     IF(v_tExprType(v_parj) = EXPR_NODE_TYPE_OPERATOR AND
1678        v_tExprSubtype(v_parj) IN (OPERATOR_ROUND, OPERATOR_CEILING, OPERATOR_FLOOR, OPERATOR_TRUNCATE))THEN
1679 
1680        v_rounding := OperatorLiterals(v_tExprSubtype(v_parj));
1681        generateRound := OPTIMIZATION_COMPLETED;
1682 
1683        IF(optimizeChain = OPTIMIZATION_REQUESTED)THEN
1684 
1685          v_return(1) := optimizeTarget;
1686          v_target := NULL;
1687          optimizeChain := OPTIMIZATION_COMPLETED;
1688        END IF;
1689     END IF;
1690   ELSIF(optimizeContribute = OPTIMIZATION_REQUESTED)THEN
1691 
1692     optimizeFlag := 1;
1693     optimizeContribute := OPTIMIZATION_COMPLETED;
1694   END IF;
1695 
1696   IF(nCount = 1)THEN
1697 
1698 nDebug := 8004003;
1699 
1700     lhs := GENERATE_EXPRESSION(nChild, ListType);
1701     IF(v_tExprSubtype(j) = OPERATOR_SUB)THEN
1702 
1703       IF(optimizeFlag = 0)THEN
1704 
1705         vLogicLine := v_target || 'CONTRIBUTE ' || lhs(1) || OperatorLiterals(OPERATOR_MULT) || '-1 ' ||
1706                       v_return(1) || v_rounding || '... ' || TO_CHAR(nReasonId) || NewLine;
1707       ELSE
1708 
1709         v_return(1) := lhs(1) || OperatorLiterals(OPERATOR_MULT) || '-1 ';
1710       END IF;
1711     ELSE
1712 
1713       v_return(1) := lhs(1);
1714     END IF;
1715   ELSE
1716 
1717 nDebug := 8004004;
1718 
1719     lhs := GENERATE_EXPRESSION(nChild, ListType);
1720 
1721 nDebug := 8004005;
1722 
1723     rhs := GENERATE_EXPRESSION(nChild + 1, ListType);
1724 
1725 nDebug := 8004006;
1726 
1727     IF(optimizeFlag = 0)THEN
1728 
1729       vLogicLine := v_target || 'CONTRIBUTE ' || lhs(1) || OperatorLiterals(v_tExprSubtype(j)) ||
1730                     rhs(1) || ' ' || v_return(1) || v_rounding || '... ' || TO_CHAR(nReasonId) || NewLine;
1731     ELSE
1732 
1733       v_return(1) := lhs(1) || OperatorLiterals(v_tExprSubtype(j)) || rhs(1) || ' ';
1734     END IF;
1735   END IF;
1736 
1737  PACK;
1738  RETURN v_return;
1739 END;
1740 ---------------------------------------------------------------------------------------
1741 FUNCTION GENERATE_MATH_UNARY(j IN PLS_INTEGER) RETURN tStringArray IS
1742   v_return  tStringArray;
1743   v_result  tStringArray;
1744   nChild    PLS_INTEGER;
1745   ListType  PLS_INTEGER;
1746 BEGIN
1747 
1748 nDebug := 7000100;
1749 
1750   IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 1)THEN
1751     nParam := v_tExprSubtype(j);
1752     RAISE CZ_E_MATH_PARAMETERS;
1753   END IF;
1754 
1755   nChild := v_ChildrenIndex(v_tExprId(j));
1756 
1757 nDebug := 7000101;
1758 
1759   --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
1760   nLocalDefaults := nLocalDefaults + 1;
1761   v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
1762 
1763 nDebug := 7000102;
1764 
1765   v_result := GENERATE_EXPRESSION(nChild, ListType);
1766 
1767 nDebug := 7000103;
1768 
1769   vLogicLine := 'TOTAL ' || v_return(1) || NewLine ||
1770                 'MF ' || v_result(1) || OperatorLiterals(v_tExprSubtype(j)) ||
1771                 v_return(1) || ' ... ' || TO_CHAR(nReasonId) || NewLine;
1772   PACK;
1773 
1774  RETURN v_return;
1775 END;
1776 ---------------------------------------------------------------------------------------
1777 FUNCTION GENERATE_MATH_BINARY(j IN PLS_INTEGER) RETURN tStringArray IS
1778   v_return  tStringArray;
1779   nChild    PLS_INTEGER;
1780   lhs       tStringArray;
1781   rhs       tStringArray;
1782   ListType  PLS_INTEGER;
1783 BEGIN
1784 
1785 nDebug := 7000200;
1786 
1787   IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 2)THEN
1788     nParam := v_tExprSubtype(j);
1789     RAISE CZ_E_MATH_PARAMETERS;
1790   END IF;
1791 
1792   nChild := v_ChildrenIndex(v_tExprId(j));
1793 
1794 nDebug := 7000201;
1795 
1796   --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
1797   nLocalDefaults := nLocalDefaults + 1;
1798   v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
1799 
1800 nDebug := 7000202;
1801 
1802   lhs := GENERATE_EXPRESSION(nChild, ListType);
1803 
1804 nDebug := 7000203;
1805 
1806   rhs := GENERATE_EXPRESSION(nChild + 1, ListType);
1807 
1808   --Bug #1990405. For the pow function, the second operand must evaluate to an integer. This
1809   --requirement may be removed or modified later.
1810 
1811   IF(v_tExprSubtype(j) = OPERATOR_POW)THEN
1812 
1813     --The generated expression should be an integer constant.
1814 
1815     IF(REPLACE(TRANSLATE(rhs(1), '0123456789', '0000000000'), '0', NULL) IS NOT NULL)THEN
1816       RAISE CZ_E_INCORRECT_POWER;
1817     END IF;
1818   END IF;
1819 
1820 nDebug := 7000204;
1821 
1822   vLogicLine := 'TOTAL ' || v_return(1) || NewLine ||
1823                 'MF ' || lhs(1) || ' ' || rhs(1) || OperatorLiterals(v_tExprSubtype(j)) ||
1824                 v_return(1) || ' ... ' || TO_CHAR(nReasonId) || NewLine;
1825   PACK;
1826 
1827  RETURN v_return;
1828 END;
1829 ---------------------------------------------------------------------------------------
1830 FUNCTION GENERATE_MATH_ROUND(j IN PLS_INTEGER) RETURN tStringArray IS
1831   v_return   tStringArray;
1832   nChild     PLS_INTEGER;
1833   lhs        tStringArray;
1834   rhs        tStringArray;
1835   ListType   PLS_INTEGER;
1836   sReasonId  VARCHAR2(4000) := TO_CHAR(nReasonId);
1837 BEGIN
1838 
1839 nDebug := 7000300;
1840 
1841   IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 2)THEN
1842     nParam := v_tExprSubtype(j);
1843     RAISE CZ_E_MATH_PARAMETERS;
1844   END IF;
1845 
1846   nChild := v_ChildrenIndex(v_tExprId(j));
1847 
1848 nDebug := 7000301;
1849 
1850   --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
1851   nLocalDefaults := nLocalDefaults + 1;
1852   v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
1853 
1854 nDebug := 7000302;
1855 
1856   lhs := GENERATE_EXPRESSION(nChild, ListType);
1857 
1858 nDebug := 7000303;
1859 
1860   rhs := GENERATE_EXPRESSION(nChild + 1, ListType);
1861 
1862 nDebug := 7000304;
1863 
1864   vLogicLine := 'TOTAL ' || v_return(1) || '_1' || NewLine ||
1865                 'MF ' || lhs(1) || ' ' || rhs(1) || OperatorLiterals(OPERATOR_MATHDIV) ||
1866                 v_return(1) || '_1 ... ' || sReasonId || NewLine;
1867   PACK;
1868   vLogicLine := 'TOTAL ' || v_return(1) || '_2' || NewLine ||
1869                 'MF ' || v_return(1) || '_1' || OperatorLiterals(v_tExprSubtype(j)) ||
1870                 v_return(1) || '_2 ... ' || sReasonId || NewLine;
1871   PACK;
1872   vLogicLine := 'TOTAL ' || v_return(1) || NewLine ||
1873                 'CONTRIBUTE ' || rhs(1) || OperatorLiterals(OPERATOR_MULT) ||
1874                 v_return(1) || '_2 ' || v_return(1) || ' ... ' || sReasonId || NewLine;
1875   PACK;
1876 
1877  RETURN v_return;
1878 END;
1879 ---------------------------------------------------------------------------------------
1880 FUNCTION GENERATE_LITERAL(j IN PLS_INTEGER) RETURN tStringArray IS
1881  v_return  tStringArray;
1882 BEGIN
1883 
1884   v_return(1) := v_tExprDataValue(j);
1885 
1886   IF(v_tExprDataType(j) = DATA_TYPE_BOOLEAN)THEN
1887     IF(UPPER(v_tExprDataValue(j)) IN ('1', LOGICAL_CONSTANT_TRUE))THEN
1888 
1889       v_return(1) := ALWAYS_TRUE;
1890     ELSIF(UPPER(v_tExprDataValue(j)) IN ('0', LOGICAL_CONSTANT_FALSE))THEN
1891 
1892       v_return(1) := ALWAYS_FALSE;
1893     END IF;
1894 
1895     --Bug #4375977.
1896 
1897     IF(v_tLogicNetType(nHeaderId) = LOGIC_NET_TYPE_NETWORK AND (NOT v_IsConnectorNet.EXISTS(v_tExplNodeId(j))))THEN
1898 
1899        --If we are generating into a conditional net, we add an extra ^parent to the path, but only if
1900        --this is not a connector's net.
1901 
1902        v_return(1) := PATH_DELIMITER || 'parent' || PATH_DELIMITER || v_return(1);
1903     END IF;
1904   END IF;
1905  RETURN v_return;
1906 END;
1907 ---------------------------------------------------------------------------------------
1908 FUNCTION GENERATE_CONSTANT(j IN PLS_INTEGER) RETURN tStringArray IS
1909  v_return  tStringArray;
1910 BEGIN
1911   IF(v_tExprSubtype(j) = EXPR_SUBTYPE_CONSTANT_E)THEN
1912 
1913     IF(NOT h_HeaderEDefined.EXISTS(nHeaderId))THEN
1914       h_HeaderEDefined(nHeaderId) := 'T_' || TO_CHAR(nHeaderId) || '_E';
1915       vLogicLine := 'TOTAL ' || h_HeaderEDefined(nHeaderId) || ' ' || MATH_CONSTANT_E || NewLine;
1916       PACK;
1917     END IF;
1918     v_return(1) := h_HeaderEDefined(nHeaderId);
1919 
1920   ELSIF(v_tExprSubtype(j) = EXPR_SUBTYPE_CONSTANT_PI)THEN
1921 
1922     IF(NOT h_HeaderPiDefined.EXISTS(nHeaderId))THEN
1923       h_HeaderPiDefined(nHeaderId) := 'T_' || TO_CHAR(nHeaderId) || '_PI';
1924       vLogicLine := 'TOTAL ' || h_HeaderPiDefined(nHeaderId) || ' ' || MATH_CONSTANT_PI || NewLine;
1925       PACK;
1926     END IF;
1927     v_return(1) := h_HeaderPiDefined(nHeaderId);
1928 
1929   ELSE
1930     RAISE CZ_E_UNKNOWN_EXPR_TYPE;
1931   END IF;
1932  RETURN v_return;
1933 END;
1934 ---------------------------------------------------------------------------------------
1935 FUNCTION GENERATE_MINMAX(j IN PLS_INTEGER) RETURN tStringArray IS
1936  v_return         tStringArray;
1937  v_child          tStringArray;
1938  v_current        VARCHAR2(4000);
1939  v_oper           VARCHAR2(10) := OperatorLiterals(v_tExprSubtype(j));
1940  v_rounding       VARCHAR2(16) := ' ';
1941  v_actual         VARCHAR2(16) := ' ';
1942  v_parj           PLS_INTEGER;
1943  v_target         VARCHAR2(4000);
1944  doOptimize       PLS_INTEGER := 0;
1945  v_name           VARCHAR2(128);
1946 BEGIN
1947 
1948  nLocalDefaults := nLocalDefaults + 1;
1949  v_name := TO_CHAR(nLocalDefaults);
1950 
1951  v_child := GENERATE_NODE_CHILDREN(j);
1952  v_return(1) := t_prefix || v_name || '_1';
1953  v_target := 'TOTAL ' || v_return(1) || NewLine;
1954 
1955  IF(v_child.COUNT < 2)THEN
1956    RAISE CZ_E_WRONG_MINMAX_OPERATOR;
1957  END IF;
1958 
1959  --Check if this procedure has been called for generation of a direct child expression of a rounding
1960  --operator. If so, set a flag to generate an enhanced contribute relation and no temporary total.
1961  --If the rounding operator is a root operator of a numeric rule with an advanced lhs expression,
1962  --which is indicated by the optimizeChain flag, generate the optimized contribute relation.
1963 
1964  IF(v_tExprParentId(j) IS NOT NULL)THEN
1965 
1966    v_parj := v_IndexByExprNodeId(v_tExprParentId(j));
1967 
1968    IF(v_tExprType(v_parj) = EXPR_NODE_TYPE_OPERATOR AND
1969       v_tExprSubtype(v_parj) IN (OPERATOR_ROUND, OPERATOR_CEILING, OPERATOR_FLOOR, OPERATOR_TRUNCATE))THEN
1970 
1971       v_rounding := OperatorLiterals(v_tExprSubtype(v_parj));
1972       generateRound := OPTIMIZATION_COMPLETED;
1973 
1974       IF(optimizeChain = OPTIMIZATION_REQUESTED)THEN
1975 
1976         optimizeChain := OPTIMIZATION_COMPLETED;
1977         doOptimize := 1;
1978       END IF;
1979    END IF;
1980  END IF;
1981 
1982  --If the operator has just two operands, only one contribute relation will be generated, prepare
1983  --variables for this relation.
1984 
1985  IF(v_child.COUNT = 2)THEN
1986 
1987    v_actual := v_rounding;
1988    IF(doOptimize = 1)THEN
1989 
1990      v_target := NULL;
1991      v_return(1) := optimizeTarget;
1992    END IF;
1993  END IF;
1994 
1995  vLogicLine := v_target || 'CONTRIBUTE ' || v_child(1) || v_oper || v_child(2) || ' ' ||
1996                v_return(1) || v_actual || '... ' || TO_CHAR(nReasonId) || NewLine;
1997 
1998  PACK;
1999 
2000  v_current := v_return(1);
2001  v_actual := ' ';
2002 
2003  FOR i IN 3..v_child.COUNT LOOP
2004 
2005   v_return(1) := t_prefix || v_name || '_' || TO_CHAR(i-1);
2006   v_target := 'TOTAL ' || v_return(1) || NewLine;
2007 
2008   --If the operator has more than two operands, two or more contribute relations will be
2009   --generated. We want to modify only the last of them, so prepare the variables before
2010   --generating the last one.
2011 
2012   IF(i = v_child.COUNT)THEN
2013 
2014    v_actual := v_rounding;
2015    IF(doOptimize = 1)THEN
2016 
2017      v_target := NULL;
2018      v_return(1) := optimizeTarget;
2019    END IF;
2020   END IF;
2021 
2022   vLogicLine := v_target || 'CONTRIBUTE ' || v_child(i) || v_oper || v_current || ' ' ||
2023                 v_return(1) || v_actual || '... ' || TO_CHAR(nReasonId) || NewLine;
2024 
2025   v_current := v_return(1);
2026   PACK;
2027 
2028  END LOOP;
2029  RETURN v_return;
2030 END;
2031 ---------------------------------------------------------------------------------------
2032 FUNCTION GENERATE_OF(j IN PLS_INTEGER) RETURN tStringArray IS
2033  v_return  tStringArray;
2034  v_result  tIntegerArray;
2035  nChild    PLS_INTEGER;
2036 BEGIN
2037 
2038  IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
2039   RAISE CZ_E_WRONG_OF_OPERATOR;
2040  END IF;
2041 
2042  nChild := v_ChildrenIndex(v_tExprId(j));
2043  v_result := EXPAND_NODE(j);
2044 
2045  FOR i IN 1..v_result.COUNT LOOP
2046 
2047    v_return(i) := GENERATE_NAME_EXPL(v_ExplByPsNodeId(v_result(i)), v_result(i));
2048  END LOOP;
2049 
2050  RETURN v_return;
2051 END;
2052 ---------------------------------------------------------------------------------------
2053 FUNCTION GENERATE_NOT(j IN PLS_INTEGER) RETURN tStringArray IS
2054  v_return  tStringArray;
2055  nChild    PLS_INTEGER;
2056  oper      tStringArray;
2057  ListType  PLS_INTEGER;
2058 BEGIN
2059 
2060  IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
2061   RAISE CZ_E_WRONG_NOT_OPERATOR;
2062  END IF;
2063 
2064  nChild := v_ChildrenIndex(v_tExprId(j));
2065  IF(v_tExprParentId.EXISTS(nChild + 1) AND v_tExprParentId(nChild + 1) = v_tExprId(j))THEN
2066   RAISE CZ_E_WRONG_NOT_OPERATOR;
2067  END IF;
2068 
2069  IF(NOT HAS_LOGICAL_VALUE(nChild))THEN
2070   nParam := j;
2071   RAISE CZ_E_INVALID_OPERAND_TYPE;
2072  END IF;
2073 
2074  --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
2075  nLocalDefaults := nLocalDefaults + 1;
2076  v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2077 
2078  oper := GENERATE_EXPRESSION(nChild, ListType);
2079 
2080  vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2081                'GS N ... ' || TO_CHAR(nReasonId) || NewLine ||
2082                'GL' || OperatorLetters(OPERATOR_ANYOF) || oper(1) || NewLine ||
2083                'GR' || OperatorLetters(OPERATOR_ANYOF) || v_return(1) || NewLine;
2084  PACK;
2085 
2086  RETURN v_return;
2087 END;
2088 ---------------------------------------------------------------------------------------
2089 FUNCTION GENERATE_NOTTRUE(j IN PLS_INTEGER) RETURN tStringArray IS
2090  v_return    tStringArray;
2091  nChild      PLS_INTEGER;
2092  oper        tStringArray;
2093  ListType    PLS_INTEGER;
2094  v_NodeId    NUMBER; --kdande; Bug 6881902; 11-Mar-2008
2095  v_HeaderId  NUMBER;
2096  v_nodename  VARCHAR2(4000);
2097  v_accuname  VARCHAR2(4000);
2098  iLocal      PLS_INTEGER;
2099 BEGIN
2100 
2101  IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
2102   RAISE CZ_E_WRONG_NOTTRUE_OPERATOR;
2103  END IF;
2104 
2105  nChild := v_ChildrenIndex(v_tExprId(j));
2106  IF(v_tExprParentId.EXISTS(nChild + 1) AND v_tExprParentId(nChild + 1) = v_tExprId(j))THEN
2107   RAISE CZ_E_WRONG_NOTTRUE_OPERATOR;
2108  END IF;
2109 
2110  IF(NOT HAS_LOGICAL_VALUE(nChild))THEN
2111   nParam := j;
2112   RAISE CZ_E_INVALID_OPERAND_TYPE;
2113  END IF;
2114 
2115  --OptimizeNotTrue is a db setting which is disabled by default.
2116 
2117  IF(OptimizeNotTrue = 0 OR v_tExprType(nChild) <> EXPR_NODE_TYPE_NODE)THEN
2118 
2119    --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
2120    nLocalDefaults := nLocalDefaults + 1;
2121    v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2122 
2123    oper := GENERATE_EXPRESSION(nChild, ListType);
2124 
2125    vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2126                  'NOTTRUE ' || oper(1) || ' ' || v_return(1) || ' ... ' || TO_CHAR(nReasonId) || NewLine;
2127    PACK;
2128  ELSE
2129 
2130    v_NodeId := v_tExprPsNodeId(nChild);
2131 
2132    IF((NOT v_HeaderByNotTrueId.EXISTS(v_NodeId)) AND
2133       (glAccumulator(v_NodeId) IS NULL OR glAccumulator(v_NodeId) = FLAG_NO_ACCUMULATOR))THEN
2134 
2135      --Need to generate a new NOTTRUE relation in the node's structure file
2136 
2137      v_HeaderId := glHeaderByPsNodeId(v_NodeId);
2138      v_nodename := 'P_' || TO_CHAR(glPersistentId(v_NodeId));
2139      v_accuname := v_nodename || '_NT';
2140 
2141      --Flush off the buffer because we are about to write to another file
2142 
2143      IF(vLogicText IS NOT NULL)THEN
2144        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
2145         (nHeaderId, v_tSequenceNbr(nHeaderId), vLogicText);
2146        vLogicText := NULL;
2147        v_tSequenceNbr(nHeaderId) := v_tSequenceNbr(nHeaderId) + 1;
2148      END IF;
2149 
2150      --Fix for the bug #2398832 - we may be re-using the accumulator, so we should not
2151      --assign to it effectivities and usages of a particular node.
2152      --Do not write the effectivity dates using the actual effective date interval of
2153      --the corresponding node.
2154 
2155      --iLocal := glIndexByPsNodeId(v_NodeId);
2156      --CurrentEffFrom := glEffFrom(iLocal);
2157      --CurrentEffUntil := glEffUntil(iLocal);
2158      --CurrentUsageMask := glUsageMask(iLocal);
2159 
2160      --Instead make the accumulator always effective and universal.
2161 
2162      CurrentEffFrom := EpochBeginDate;
2163      CurrentEffUntil := EpochEndDate;
2164      CurrentUsageMask := AnyUsageMask;
2165 
2166      IF((NOT h_EffFrom.EXISTS(v_HeaderId)) OR
2167         (h_EffFrom(v_HeaderId) <> CurrentEffFrom OR h_EffUntil(v_HeaderId) <> CurrentEffUntil OR
2168          h_EffUsageMask(v_HeaderId) <> CurrentUsageMask))THEN
2169 
2170        h_EffFrom(v_HeaderId) := CurrentEffFrom;
2171        h_EffUntil(v_HeaderId) := CurrentEffUntil;
2172        h_EffUsageMask(v_HeaderId) := CurrentUsageMask;
2173 
2174        vLogicText := LTRIM(CurrentUsageMask, '0');
2175        IF(vLogicText IS NOT NULL) THEN
2176          vLogicText := EffUsagePrefix || vLogicText;
2177        END IF;
2178 
2179        IF(CurrentEffFrom = EpochBeginDate)THEN
2180          CurrentFromDate := NULL;
2181        ELSE
2182          CurrentFromDate := TO_CHAR(CurrentEffFrom, EffDateFormat);
2183        END IF;
2184 
2185        IF(CurrentEffUntil = EpochEndDate)THEN
2186          CurrentUntilDate := NULL;
2187        ELSE
2188          CurrentUntilDate := TO_CHAR(CurrentEffUntil, EffDateFormat);
2189        END IF;
2190 
2191        vLogicText := 'EFF ' || CurrentFromDate || ', ' || CurrentUntilDate || ', ' || vLogicText || NewLine;
2192      END IF;
2193 
2194      vLogicText := vLogicText || 'OBJECT ' || v_accuname || NewLine ||
2195                    'NOTTRUE ' || v_nodename || ' ' || v_accuname || ' ... ' || TO_CHAR(nReasonId) || NewLine;
2196 
2197      INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
2198       (v_HeaderId, vSeqNbrByHeader(v_HeaderId), vLogicText);
2199      vLogicText := NULL;
2200      vSeqNbrByHeader(v_HeaderId) := vSeqNbrByHeader(v_HeaderId) + 1;
2201 
2202      v_HeaderByNotTrueId(v_NodeId) := v_HeaderId;
2203 
2204      --Part of the fix for the bug #2857955. We will never be here if glAccumulator(v_NodeId) was
2205      --FLAG_ACCUMULATOR_NT because the accumulator would have already been created.
2206 
2207      UPDATE cz_ps_nodes SET
2208        accumulator_flag = DECODE(glAccumulator(v_NodeId), FLAG_ACCUMULATOR_ACC, FLAG_ACCUMULATOR_BOTH, FLAG_ACCUMULATOR_NT)
2209      WHERE ps_node_id = v_NodeId;
2210 
2211    END IF;
2212 
2213    v_return(1) := GENERATE_NAME(nChild, v_NodeId) || '_NT';
2214  END IF;
2215 
2216  RETURN v_return;
2217 END;
2218 ---------------------------------------------------------------------------------------
2219 FUNCTION COMPARE_VALUES(val1 IN VARCHAR2, val2 IN VARCHAR2, OperType IN PLS_INTEGER)
2220 RETURN BOOLEAN IS
2221   v_null  NUMBER;
2222 BEGIN
2223   IF(OperType = OPERATOR_EQUALS)THEN
2224     RETURN (val1 = val2);
2225   ELSIF(OperType = OPERATOR_NOTEQUALS)THEN
2226     RETURN (val1 <> val2);
2227   ELSIF(OperType = OPERATOR_EQUALS_INT)THEN
2228     RETURN (val1 = val2);
2229   ELSIF(OperType = OPERATOR_NOTEQUALS_INT)THEN
2230     RETURN (val1 <> val2);
2231   ELSIF(OperType = OPERATOR_GT)THEN
2232     RETURN (val1 > val2);
2233   ELSIF(OperType = OPERATOR_LT)THEN
2234     RETURN (val1 < val2);
2235   ELSIF(OperType = OPERATOR_GE)THEN
2236     RETURN (val1 >= val2);
2237   ELSIF(OperType = OPERATOR_LE)THEN
2238     RETURN (val1 <= val2);
2239   ELSIF(OperType = OPERATOR_BEGINSWITH)THEN
2240     RETURN (INSTR(val1, val2) = 1);
2241   ELSIF(OperType = OPERATOR_ENDSWITH)THEN
2242     RETURN (INSTR(val1, val2, -1) = (LENGTH(val1) - LENGTH(val2) + 1));
2243   ELSIF(OperType = OPERATOR_CONTAINS)THEN
2244     RETURN (INSTR(val1, val2) <> 0);
2245   ELSIF(OperType = OPERATOR_LIKE)THEN
2246     BEGIN
2247       SELECT NULL INTO v_null FROM DUAL WHERE val1 LIKE val2;
2248       RETURN TRUE;
2249     EXCEPTION
2250       WHEN NO_DATA_FOUND THEN
2251         RETURN FALSE;
2252     END;
2253   ELSIF(OperType = OPERATOR_MATCHES)THEN
2254     BEGIN
2255       SELECT NULL INTO v_null FROM DUAL WHERE val1 LIKE val2;
2256       RETURN TRUE;
2257     EXCEPTION
2258       WHEN NO_DATA_FOUND THEN
2259         RETURN FALSE;
2260     END;
2261   ELSIF(OperType = OPERATOR_DOESNOTBEGINWITH)THEN
2262     RETURN (INSTR(val1, val2) <> 1);
2263   ELSIF(OperType = OPERATOR_DOESNOTENDWITH)THEN
2264     RETURN (INSTR(val1, val2, -1) <> (LENGTH(val1) - LENGTH(val2) + 1));
2265   ELSIF(OperType = OPERATOR_DOESNOTCONTAIN)THEN
2266     RETURN (INSTR(val1, val2) = 0);
2267   ELSIF(OperType = OPERATOR_NOTLIKE)THEN
2268     BEGIN
2269       SELECT NULL INTO v_null FROM DUAL WHERE val1 NOT LIKE val2;
2270       RETURN TRUE;
2271     EXCEPTION
2272       WHEN NO_DATA_FOUND THEN
2273         RETURN FALSE;
2274     END;
2275   ELSE
2276     RAISE CZ_E_WRONG_COMPARISON_OPER;
2277   END IF;
2278 END;
2279 ---------------------------------------------------------------------------------------
2280 FUNCTION EXTRACT_PROPERTY_VALUE(inVal IN VARCHAR2, inType IN PLS_INTEGER)
2281 RETURN VARCHAR2 IS
2282 BEGIN
2283   IF(inType = DATATYPE_STRING)THEN
2284     RETURN SUBSTR(inVal, INSTR(inVal, PROPERTY_DELIMITER) + 1);
2285   ELSE
2286     RETURN inVal;
2287   END IF;
2288 END;
2289 ---------------------------------------------------------------------------------------
2290 FUNCTION EXTRACT_PROPERTY_VALUE(inVal IN VARCHAR2)
2291 
2292 --This simplified version is used in GENERATE_REFNODE to extract boolean property values
2293 --represented as character '0'/'1' in the database.
2294 
2295 RETURN VARCHAR2 IS
2296 BEGIN
2297     RETURN SUBSTR(inVal, INSTR(inVal, PROPERTY_DELIMITER) + 1);
2298 END;
2299 ---------------------------------------------------------------------------------------
2300 FUNCTION EXTRACT_PROPERTY_NODE(inVal IN VARCHAR2) RETURN VARCHAR2 IS
2301 BEGIN
2302   RETURN SUBSTR(inVal, 1, INSTR(inVal, PROPERTY_DELIMITER) - 1);
2303 END;
2304 ---------------------------------------------------------------------------------------
2305 FUNCTION GENERATE_CONCAT(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
2306  v_return  tStringArray;
2307  nChild    PLS_INTEGER;
2308  lhs       tStringArray;
2309  rhs       tStringArray;
2310  lListType PLS_INTEGER;
2311  rListType PLS_INTEGER;
2312  ExprId    PLS_INTEGER := v_tExprId(j);
2313 BEGIN
2314 
2315   IF(NOT v_ChildrenIndex.EXISTS(ExprId))THEN
2316    RAISE CZ_E_WRONG_COMPARISON_OPER;
2317   END IF;
2318 
2319   nChild := v_ChildrenIndex(ExprId);
2320   IF(NOT v_tExprParentId.EXISTS(nChild + 1) OR v_tExprParentId(nChild + 1) IS NULL OR
2321      v_tExprParentId(nChild + 1) <> ExprId)THEN
2322    RAISE CZ_E_WRONG_COMPARISON_OPER;
2323   END IF;
2324 
2325   lhs := GENERATE_EXPRESSION(nChild, lListType);
2326   rhs := GENERATE_EXPRESSION(nChild+1, rListType);
2327 
2328   v_return(1) := EXTRACT_PROPERTY_VALUE(lhs(1)) || EXTRACT_PROPERTY_VALUE(rhs(1));
2329   ListType := DATA_TYPE_TEXT;
2330  RETURN v_return;
2331 END;
2332 ---------------------------------------------------------------------------------------
2333 --Bug 5620750 - function to generate the new ToText operator when used outside of PBC
2334 --context.
2335 
2336 FUNCTION GENERATE_TOTEXT(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
2337  v_return  tStringArray;
2338  ExprId    PLS_INTEGER := v_tExprId(j);
2339 BEGIN
2340 
2341   IF((NOT v_ChildrenIndex.EXISTS(ExprId)) OR v_NumberOfChildren(ExprId) <> 1)THEN
2342     RAISE CZ_R_WRONG_EXPRESSION_NODE;
2343   END IF;
2344 
2345   v_return(1) := TO_CHAR(v_tExprDataNumValue(v_ChildrenIndex(ExprId)));
2346   ListType := DATA_TYPE_TEXT;
2347  RETURN v_return;
2348 END;
2349 ---------------------------------------------------------------------------------------
2350 FUNCTION GENERATE_COMPARE(j IN PLS_INTEGER) RETURN tStringArray IS
2351  v_return  tStringArray;
2352  v_left    tStringArray;
2353  nChild    PLS_INTEGER;
2354  lhs       tStringArray;
2355  rhs       tStringArray;
2356  lListType PLS_INTEGER;
2357  rListType PLS_INTEGER;
2358  OperType  PLS_INTEGER := v_tExprSubtype(j);
2359  ExprId    PLS_INTEGER := v_tExprId(j);
2360  nCount    PLS_INTEGER := 1;
2361 BEGIN
2362 
2363  IF(NOT v_ChildrenIndex.EXISTS(ExprId))THEN
2364   RAISE CZ_E_WRONG_COMPARISON_OPER;
2365  END IF;
2366 
2367  nChild := v_ChildrenIndex(ExprId);
2368  IF(NOT v_tExprParentId.EXISTS(nChild + 1) OR v_tExprParentId(nChild + 1) IS NULL OR
2369     v_tExprParentId(nChild + 1) <> ExprId)THEN
2370   RAISE CZ_E_WRONG_COMPARISON_OPER;
2371  END IF;
2372 
2373 nDebug := 8001120;
2374 
2375  --v_return(1) := 'T_' || TO_CHAR(ExprId);
2376  nLocalDefaults := nLocalDefaults + 1;
2377  v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2378 
2379 nDebug := 8001121;
2380 
2381  generateCompare := 1;
2382  lhs := GENERATE_EXPRESSION(nChild, lListType);
2383 
2384 nDebug := 8001122;
2385 
2386  rhs := GENERATE_EXPRESSION(nChild+1, rListType);
2387  generateCompare := 0;
2388 
2389   --Bug #4191838.
2390 
2391   IF(lhs.COUNT = 1 AND lListType = DATA_TYPE_TEXT AND rhs.COUNT = 1 AND rListType = DATA_TYPE_TEXT)THEN
2392 
2393      v_left(1) := 'OBJECT ' || v_return(1) || NewLine;
2394      v_left(2) := TO_CHAR(nReasonId) || NewLine ||
2395                   'GL' || OperatorLetters(OPERATOR_ALLOF) || ALWAYS_TRUE || NewLine ||
2396                   'GR' || OperatorLetters(OPERATOR_ALLOF) || v_return(1) || NewLine;
2397 
2398      IF(COMPARE_VALUES(EXTRACT_PROPERTY_VALUE(lhs(1), lListType),
2399                        EXTRACT_PROPERTY_VALUE(rhs(1), rListType), OperType))THEN
2400        vLogicLine := v_left(1) || 'GS R ... ' || v_left(2);
2401      ELSE
2402        vLogicLine := v_left(1) || 'GS E ... ' || v_left(2);
2403      END IF;
2404     PACK;
2405     RETURN v_return;
2406    END IF;
2407 
2408 nDebug := 8001123;
2409 
2410  IF(lListType = DATATYPE_STRING OR rListType = DATATYPE_STRING)THEN
2411 
2412 nDebug := 8001124;
2413 
2414   FOR ii IN 1..lhs.COUNT LOOP
2415    FOR jj IN 1..rhs.COUNT LOOP
2416 
2417     IF(COMPARE_VALUES(EXTRACT_PROPERTY_VALUE(lhs(ii), lListType),
2418                       EXTRACT_PROPERTY_VALUE(rhs(jj), rListType), OperType))THEN
2419      IF(lListType = DATATYPE_STRING AND rListType = DATATYPE_STRING)THEN
2420 
2421 nDebug := 8001125;
2422 
2423        v_left(nCount) := v_return(1) || '_' || TO_CHAR(nCount);
2424 
2425        vLogicLine := 'OBJECT ' || v_left(nCount) || NewLine ||
2426                      'GS R ' || sUnsatisfiedId || '... ' || TO_CHAR(nReasonId) || NewLine ||
2427                      'GL' || OperatorLetters(OPERATOR_ALLOF) ||
2428                       EXTRACT_PROPERTY_NODE(lhs(ii)) || ' ' || EXTRACT_PROPERTY_NODE(rhs(jj)) || NewLine ||
2429                      'GR' || OperatorLetters(OPERATOR_ALLOF) || v_left(nCount) || NewLine;
2430        PACK;
2431        nCount := nCount + 1;
2432 
2433      ELSIF(lListType = DATATYPE_STRING)THEN
2434 
2435 nDebug := 8001126;
2436 
2437        v_left(nCount) := EXTRACT_PROPERTY_NODE(lhs(ii));
2438        nCount := nCount + 1;
2439 
2440      ELSIF(rListType = DATATYPE_STRING)THEN
2441 
2442 nDebug := 8001127;
2443 
2444        v_left(nCount) := EXTRACT_PROPERTY_NODE(rhs(jj));
2445        nCount := nCount + 1;
2446 
2447      END IF;
2448     END IF;
2449    END LOOP;
2450   END LOOP;
2451 
2452 nDebug := 8001128;
2453 
2454   IF(v_left.COUNT = 0)THEN
2455 
2456     vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2457                   'GS E ...' || TO_CHAR(nReasonId) || NewLine ||
2458                   'GL' || OperatorLetters(OPERATOR_ALLOF) || ALWAYS_TRUE || NewLine ||
2459                   'GR' || OperatorLetters(OPERATOR_ALLOF) || v_return(1) || NewLine;
2460 
2461   ELSE
2462 
2463     localString := NULL;
2464     IF(v_left.COUNT > 1)THEN localString := sUnsatisfiedId; END IF;
2465 
2466     vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2467                   'GS R ' || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
2468                   'GL' || OperatorLetters(OPERATOR_ANYOF);
2469 
2470     PACK;
2471 
2472 nDebug := 8001129;
2473 
2474     FOR i IN 1..v_left.COUNT LOOP
2475 
2476       vLogicLine := v_left(i) || ' ';
2477       PACK;
2478 
2479     END LOOP;
2480 
2481     vLogicLine := NewLine || 'GR' || OperatorLetters(OPERATOR_ALLOF) || v_return(1) || NewLine;
2482 
2483 nDebug := 8001130;
2484 
2485   END IF;
2486 
2487  ELSE
2488 
2489 nDebug := 8001131;
2490 
2491    vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2492                  'COMPARE ' || lhs(1) || OperatorLiterals(OperType) ||
2493                  rhs(1) || ' ' || v_return(1) || ' ... ' || TO_CHAR(nReasonId) || NewLine;
2494  END IF;
2495 
2496  PACK;
2497 
2498  RETURN v_return;
2499 END;
2500 ---------------------------------------------------------------------------------------
2501 FUNCTION GENERATE_ANYALLOF(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
2502  v_return    tStringArray;
2503  v_child     tStringArray;
2504  v_parentid  PLS_INTEGER;
2505  v_parj      PLS_INTEGER;
2506  nChild      PLS_INTEGER;
2507 BEGIN
2508 
2509 --nDebug := 7000001;
2510 
2511  --Bug #5015333 - need a verification for the logical nature of the operands.
2512 
2513  nChild := v_ChildrenIndex(v_tExprId(j));
2514 
2515  WHILE(v_tExprParentId(nChild) = v_tExprId(j)) LOOP
2516 
2517    IF(NOT HAS_LOGICAL_VALUE(nChild))THEN
2518 
2519      nParam := j;
2520      RAISE CZ_E_INVALID_OPERAND_TYPE;
2521    END IF;
2522 
2523    nChild := nChild + 1;
2524  END LOOP;
2525 
2526  v_child := GENERATE_NODE_CHILDREN(j);
2527  v_parentid := v_tExprParentId(j);
2528 
2529  --This is important that this assignment goes after the node children generation, because the
2530  --type of the parent operator can be changed during the children generation in some cases
2531  --(see internal case #3 below).
2532 
2533  ListType := v_tExprSubtype(j);
2534 
2535  IF(OptimizeAllAnyOf = 1)THEN
2536    IF(v_parentid IS NOT NULL)THEN
2537 
2538      v_parj := v_IndexByExprNodeId(v_parentid);
2539 
2540      IF(v_tExprType(v_parj) = EXPR_NODE_TYPE_OPERATOR AND
2541         v_tExprSubtype(v_parj) IN (OPERATOR_ANYOF, OPERATOR_ALLOF))THEN
2542 
2543        IF(ListType = v_tExprSubtype(v_parj))THEN
2544 
2545          --AllOf(AllOf(...) , ...), AnyOf(AnyOf(...) , ...).
2546          --Internal case #1.
2547 
2548          return v_child;
2549        ELSIF(v_child.COUNT = 1)THEN
2550 
2551          --This operator is either AnyOf or AllOf. It is different from the parent operator which
2552          --is also AnyOf or AllOf. Therefore, this is AllOf(AnyOf(...) , ...) or
2553          --AnyOf(AllOf(...) , ...). If only one child has been generated for this operator than
2554          --we have the case of AllOf(AnyOf(1) , ...) or AnyOf(AllOf(1) , ...).
2555          --Internal case #2.
2556 
2557          return v_child;
2558 
2559        ELSIF(v_NumberOfChildren(v_parentid) = 1)THEN
2560 
2561          --We have AllOf(AnyOf(...)) or AnyOf(AllOf(...)), i. e. this AllOf or AnyOf operator is
2562          --the only child of its parent.If so, we not only carry over the children list but also
2563          --reverse the type of the parent operator.
2564          --Internal case #3.
2565 
2566          v_tExprSubtype(v_parj) := ListType;
2567          return v_child;
2568        END IF;
2569      END IF;
2570    ELSIF(nRuleType = RULE_TYPE_LOGIC_RULE)THEN
2571      IF(nRuleOperator <> RULE_OPERATOR_DEFAULTS OR j = jConsequentRoot)THEN
2572        return v_child;
2573      ELSIF(v_child.COUNT = 1)THEN
2574        return v_child;
2575      END IF;
2576    END IF;
2577  END IF;
2578 
2579 --nDebug := 7000002;
2580 
2581  --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
2582  nLocalDefaults := nLocalDefaults + 1;
2583  v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2584 
2585 --nDebug := 7000003;
2586 
2587  localString := NULL;
2588  IF(v_child.COUNT > 1)THEN localString := sUnsatisfiedId; END IF;
2589 
2590  vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2591                'GS R ' || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
2592                'GL' || OperatorLetters(ListType);
2593 
2594  PACK;
2595 
2596  IF(ChangeChildrenOrder = 1)THEN
2597    FOR i IN REVERSE 1..v_child.COUNT LOOP
2598 
2599      vLogicLine := v_child(i) || ' ';
2600      PACK;
2601 
2602    END LOOP;
2603  ELSE
2604    FOR i IN 1..v_child.COUNT LOOP
2605 
2606      vLogicLine := v_child(i) || ' ';
2607      PACK;
2608 
2609    END LOOP;
2610  END IF;
2611 
2612 --nDebug := 7000004;
2613 
2614  vLogicLine := NewLine || 'GR' || OperatorLetters(OPERATOR_ALLOF) || v_return(1) || NewLine;
2615  PACK;
2616  RETURN v_return;
2617 END;
2618 ---------------------------------------------------------------------------------------
2619 FUNCTION GENERATE_ANDOR(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
2620  v_return  tStringArray;
2621  nChild    PLS_INTEGER;
2622  lhs       tStringArray;
2623  rhs       tStringArray;
2624  lListType PLS_INTEGER;
2625  rListType PLS_INTEGER;
2626 BEGIN
2627 
2628  IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 2)THEN
2629   RAISE CZ_E_WRONG_ANDOR_OPERATOR;
2630  END IF;
2631 
2632  nChild := v_ChildrenIndex(v_tExprId(j));
2633 
2634  IF(NOT (HAS_LOGICAL_VALUE(nChild) AND HAS_LOGICAL_VALUE(nChild + 1)))THEN
2635   nParam := j;
2636   RAISE CZ_E_INVALID_OPERAND_TYPE;
2637  END IF;
2638 
2639  IF(OptimizeAllAnyOf = 1)THEN
2640    IF(v_tExprSubtype(j) = OPERATOR_AND)THEN
2641      v_tExprSubtype(j) := OPERATOR_ALLOF;
2642    ELSE
2643      v_tExprSubtype(j) := OPERATOR_ANYOF;
2644    END IF;
2645    RETURN GENERATE_ANYALLOF(j, ListType);
2646  END IF;
2647 
2648 nDebug := 8001700;
2649 
2650  --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
2651  nLocalDefaults := nLocalDefaults + 1;
2652  v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2653 
2654  lhs := GENERATE_EXPRESSION(nChild, lListType);
2655  rhs := GENERATE_EXPRESSION(nChild+1, rListType);
2656 
2657 nDebug := 8001701;
2658 
2659  vLogicLine := 'OBJECT ' || v_return(1) || NewLine ||
2660                'GS R ' || sUnsatisfiedId || '... ' || TO_CHAR(nReasonId) || NewLine ||
2661                'GL' || OperatorLetters(v_tExprSubtype(j)) || lhs(1) || ' ' || rhs(1) || NewLine ||
2662                'GR' || OperatorLetters(OPERATOR_ANYOF) || v_return(1) || NewLine;
2663  PACK;
2664 
2665 nDebug := 8001702;
2666 
2667  RETURN v_return;
2668 END;
2669 ---------------------------------------------------------------------------------------
2670 FUNCTION GENERATE_ROUND(j IN PLS_INTEGER) RETURN tStringArray IS
2671  v_return  tStringArray;
2672  nChild    PLS_INTEGER;
2673  oper      tStringArray;
2674  ListType  PLS_INTEGER;
2675 BEGIN
2676 
2677  IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
2678   RAISE CZ_E_WRONG_ROUND_OPERATOR;
2679  END IF;
2680 
2681  nChild := v_ChildrenIndex(v_tExprId(j));
2682  IF(v_tExprParentId.EXISTS(nChild + 1) AND v_tExprParentId(nChild + 1)= v_tExprId(j))THEN
2683 
2684   RAISE CZ_E_WRONG_ROUND_OPERATOR;
2685  END IF;
2686 
2687  generateRound := OPTIMIZATION_REQUESTED;
2688 
2689  oper := GENERATE_EXPRESSION(nChild, ListType);
2690 
2691  --The value may have been changed by the child expression generation. In this case we are
2692  --optimizing and do not want the increment relation to be generated at all.
2693 
2694  IF(generateRound = OPTIMIZATION_REQUESTED)THEN
2695 
2696    --v_return(1) := 'T_' || TO_CHAR(v_tExprId(j));
2697    nLocalDefaults := nLocalDefaults + 1;
2698    v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
2699 
2700    vLogicLine := 'TOTAL ' || v_return(1) || NewLine || 'INC ' || oper(1) || ' ' || v_return(1) ||
2701                  OperatorLiterals(v_tExprSubtype(j)) || '... ' || TO_CHAR(nReasonId) || NewLine;
2702    PACK;
2703    generateRound := OPTIMIZATION_COMPLETED;
2704  ELSE
2705 
2706    v_return(1) := oper(1);
2707  END IF;
2708 
2709  RETURN v_return;
2710 END;
2711 ---------------------------------------------------------------------------------------
2712 FUNCTION PROPERTY_VALUE(j IN PLS_INTEGER, iPSN IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER)
2713 RETURN VARCHAR2 IS
2714   v_return      VARCHAR2(4000);
2715   nChild        NUMBER;
2716   c_values      refCursor;
2717   optionId      cz_ps_nodes.ps_node_id%TYPE := glPsNodeId(iPSN);
2718   propertyId    cz_expression_nodes.property_id%TYPE := v_tExprPropertyId(j);
2719   itemId        cz_ps_nodes.item_id%TYPE := glItemId(iPSN);
2720   sysPropName   VARCHAR2(30);
2721 BEGIN
2722 
2723   IF(v_tExprType(j) = EXPR_SYS_PROP)THEN
2724 
2725    IF(NOT h_SeededName.EXISTS(v_tExprSubtype(j)))THEN RAISE CZ_E_BAD_PROPERTY_TYPE; END IF;
2726    sysPropName := h_SeededName(v_tExprSubtype(j));
2727 
2728    IF(sysPropName = RULE_SYS_PROP_NAME)THEN
2729 
2730 --nDebug := 8001160;
2731 
2732      v_return := glName(iPSN);
2733      ListType := DATATYPE_STRING;
2734 
2735    ELSIF(sysPropName = RULE_SYS_PROP_QUANTITY)THEN
2736 
2737      --Related bug: #2317427.
2738 
2739      v_return := GENERATE_NAME(j, optionId);
2740      ListType := DATATYPE_INTEGER;
2741 
2742    ELSIF(sysPropName = RULE_SYS_PROP_INSTANCECOUNT)THEN
2743 
2744 --nDebug := 8001161;
2745 
2746      --If it is a non-virtual component/product/reference, we add _ACTUALCOUNT to the name.
2747      --If it is a virtual component/product/reference, we return '1'.
2748      --If it is an option, we just generate the name.
2749 
2750      IF(glPsNodeType(iPSN) IN (PS_NODE_TYPE_COMPONENT,
2751                                PS_NODE_TYPE_REFERENCE,
2752                                PS_NODE_TYPE_PRODUCT))THEN
2753       IF(glVirtualFlag(iPSN) = FLAG_NON_VIRTUAL)THEN
2754        v_return := GENERATE_NAME(j, optionId)||'_ACTUALCOUNT';
2755       ELSE
2756        v_return := '1';
2757       END IF;
2758      ELSE
2759        v_return := GENERATE_NAME(j, optionId);
2760      END IF;
2761      ListType := DATATYPE_INTEGER;
2762 
2763 --nDebug := 8001162;
2764 
2765    ELSIF(sysPropName = RULE_SYS_PROP_MININSTANCE)THEN
2766 
2767 --nDebug := 8001163;
2768 
2769      v_return := GENERATE_NAME(j, optionId)||'_MIN';
2770      ListType := DATATYPE_INTEGER;
2771 
2772    ELSIF(sysPropName = RULE_SYS_PROP_MAXINSTANCE)THEN
2773 
2774 --nDebug := 8001164;
2775 
2776      v_return := GENERATE_NAME(j, optionId)||'_MAX';
2777      ListType := DATATYPE_INTEGER;
2778 
2779    ELSE
2780 
2781      RAISE CZ_E_BAD_PROPERTY_TYPE;
2782    END IF;
2783   ELSE
2784 
2785    BEGIN
2786 
2787 --nDebug := 8001165;
2788 
2789      v_return := GET_PROPERTY_VALUE(optionId, propertyId, itemId, ListType);
2790 
2791      IF(v_return IS NULL)THEN RAISE CZ_E_NULL_PROPERTY_VALUE; END IF;
2792 
2793      IF(ListType IN (DATATYPE_INTEGER, DATATYPE_FLOAT))THEN
2794 
2795        BEGIN
2796          nChild := TO_NUMBER(v_return);
2797        EXCEPTION
2798          WHEN OTHERS THEN
2799 
2800            SELECT name INTO errorMessage
2801              FROM cz_properties
2802             WHERE property_id = propertyId;
2803 
2804            localString := v_return;
2805            RAISE CZ_R_INCORRECT_DATA_TYPE;
2806        END;
2807      END IF;
2808 
2809    EXCEPTION
2810      WHEN NO_DATA_FOUND THEN
2811        RAISE CZ_E_NO_SUCH_PROPERTY;
2812      WHEN TOO_MANY_ROWS THEN
2813        RAISE CZ_E_INCORRECT_PROPERTY;
2814      WHEN OTHERS THEN
2815        RAISE;
2816    END;
2817   END IF;
2818 
2819  RETURN v_return;
2820 END;
2821 ---------------------------------------------------------------------------------------
2822 FUNCTION STATIC_SYSPROP_VALUE(p_node_id IN NUMBER, p_rule_id IN NUMBER, p_parent_up IN PLS_INTEGER)
2823 RETURN VARCHAR2 IS
2824 
2825   optionIndex  PLS_INTEGER;
2826   v_step       PLS_INTEGER := p_parent_up;
2827   sysPropName  cz_rules.name%TYPE;
2828   v_return     VARCHAR2(4000);
2829 BEGIN
2830 
2831   sysPropName := h_SeededName(p_rule_id);
2832   errorMessage := h_ReportName(p_rule_id);
2833   optionIndex := glIndexByPsNodeId(p_node_id);
2834 
2835   BEGIN
2836     WHILE(v_step > 1)LOOP
2837       optionIndex := glIndexByPsNodeId(glParentId(optionIndex));
2838       v_step := v_step - 1;
2839     END LOOP;
2840   EXCEPTION
2841     WHEN OTHERS THEN
2842       RAISE CZ_E_INCORRECT_PROPERTY;
2843   END;
2844 
2845   IF(sysPropName = RULE_SYS_PROP_NAME)THEN
2846 
2847     v_return := glName(optionIndex);
2848 
2849   ELSIF(sysPropName IN (RULE_SYS_PROP_MINVALUE, RULE_SYS_PROP_MINQUANTITY, RULE_SYS_PROP_MINSELECTED))THEN
2850 
2851     v_return := glMinimum(optionIndex);
2852 
2853   ELSIF(sysPropName IN (RULE_SYS_PROP_MAXVALUE, RULE_SYS_PROP_MAXQUANTITY, RULE_SYS_PROP_MAXSELECTED))THEN
2854 
2855     v_return := glMaximum(optionIndex);
2856 
2857   ELSIF(sysPropName = RULE_SYS_PROP_DESCRIPTION)THEN
2858 
2859     RAISE CZ_E_DESCRIPTION_IN_WHERE;
2860   ELSE
2861 
2862     RAISE CZ_E_PROPERTY_NOT_STATIC;
2863   END IF;
2864 
2865  RETURN v_return;
2866 END;
2867 ---------------------------------------------------------------------------------------
2868 FUNCTION SYSTEM_PROPERTY_VALUE(j IN PLS_INTEGER, iPSN IN tStringArray, ListType OUT NOCOPY PLS_INTEGER)
2869 RETURN tStringArray IS
2870 
2871   v_return     tStringArray;
2872   v_result     tStringArray;
2873   optionId     cz_ps_nodes.ps_node_id%TYPE;
2874   propertyId   cz_expression_nodes.property_id%TYPE := v_tExprPropertyId(j);
2875   itemId       cz_ps_nodes.item_id%TYPE;
2876   c_values     refCursor;
2877   nChild       NUMBER;
2878   optionIndex  PLS_INTEGER;
2879   sysPropName  VARCHAR2(30);
2880 BEGIN
2881 
2882 nDebug := 9001000;
2883 
2884  FOR i IN 1..iPSN.COUNT LOOP
2885 
2886    optionId := TO_NUMBER(iPSN(i));
2887    optionIndex := glIndexByPsNodeId(optionId);
2888 
2889    IF(v_tExprType(j) = EXPR_NODE_TYPE_SYSPROP)THEN
2890 
2891      sysPropName := h_SeededName(v_tExprSubtype(j));
2892 
2893      IF(sysPropName = RULE_SYS_PROP_NAME)THEN
2894 
2895        v_return(i) := glName(optionIndex);
2896        ListType := DATA_TYPE_TEXT;
2897 
2898      ELSIF(sysPropName = RULE_SYS_PROP_DESCRIPTION)THEN
2899 
2900        v_return(i) := glName(optionIndex);
2901        ListType := DATA_TYPE_TEXT;
2902 
2903      ELSIF(sysPropName = RULE_SYS_PROP_PARENT)THEN
2904 
2905        v_return(i) := TO_CHAR(glParentId(optionIndex));
2906        ListType := DATA_TYPE_NODE;
2907 
2908      ELSIF(sysPropName = RULE_SYS_PROP_OPTIONS)THEN
2909 
2910        v_result.DELETE;
2911        v_result := GENERATE_CHILDRENOF(v_tExplNodeId(j), TO_NUMBER(iPSN(i)));
2912 
2913        FOR ii IN 1..v_result.COUNT LOOP
2914          v_return(v_return.COUNT + 1) := v_result(ii);
2915        END LOOP;
2916        ListType := DATA_TYPE_NODE_COLL;
2917 
2918      ELSIF(sysPropName = RULE_SYS_PROP_MINVALUE)THEN
2919 
2920        v_return(i) := GENERATE_NAME(j, optionId)||'_MIN';
2921        ListType := DATA_TYPE_INTEGER;
2922 
2923      ELSIF(sysPropName = RULE_SYS_PROP_MAXVALUE)THEN
2924 
2925        v_return(i) := GENERATE_NAME(j, optionId)||'_MAX';
2926        ListType := DATA_TYPE_INTEGER;
2927 
2928      ELSIF(sysPropName = RULE_SYS_PROP_MINQUANTITY)THEN
2929 
2930        v_return(i) := TO_CHAR(glMinimum(optionIndex));
2931        ListType := DATA_TYPE_INTEGER;
2932 
2933      ELSIF(sysPropName = RULE_SYS_PROP_MAXQUANTITY)THEN
2934 
2935        v_return(i) := TO_CHAR(glMaximum(optionIndex));
2936        ListType := DATA_TYPE_INTEGER;
2937 
2938      ELSIF(sysPropName = RULE_SYS_PROP_MINSELECTED)THEN
2939 
2940        v_return(i) := TO_CHAR(glMinimumSel(optionIndex));
2941        ListType := DATA_TYPE_INTEGER;
2942 
2943      ELSIF(sysPropName = RULE_SYS_PROP_MAXSELECTED)THEN
2944 
2945        v_return(i) := TO_CHAR(glMaximumSel(optionIndex));
2946        ListType := DATA_TYPE_INTEGER;
2947 
2948      ELSIF(sysPropName = RULE_SYS_PROP_MININSTANCE)THEN
2949 
2950        IF(v_tExprSubtype(j) = 53)THEN
2951 
2952          --For MinInstances and MaxInstances this is a fix for the bug #3558753.
2953 
2954          --The reason we put two sets of MinInstances/MaxInstances was to support backward compatibility
2955          --of rules using those properties in the LHS. 53 and 54 are not mutable, thus they should not
2956          --be on the RHS (generic validation using the view already takes care of that). The remaining
2957          --part is to hard-code generating '0' for 53 (MinInstances) and '1' for 54 (MaxINstances).
2958          --(see also bug #4366895).
2959 
2960          v_return(i) := '0';
2961        ELSE
2962 
2963          v_return(i) := GENERATE_NAME(j, optionId)||'_MIN';
2964        END IF;
2965        ListType := DATA_TYPE_INTEGER;
2966 
2967      ELSIF(sysPropName = RULE_SYS_PROP_MAXINSTANCE)THEN
2968 
2969        IF(v_tExprSubtype(j) = 54)THEN
2970 
2971          v_return(i) := '1';
2972        ELSE
2973 
2974          v_return(i) := GENERATE_NAME(j, optionId)||'_MAX';
2975        END IF;
2976        ListType := DATA_TYPE_INTEGER;
2977 
2978      ELSIF(sysPropName = RULE_SYS_PROP_STATE)THEN
2979 
2980        v_return(i) := GENERATE_NAME(j, optionId);
2981        ListType := DATA_TYPE_BOOLEAN;
2982 
2983      ELSIF(sysPropName = RULE_SYS_PROP_VALUE)THEN
2984 
2985        v_return(i) := GENERATE_NAME(j, optionId);
2986        ListType := DATA_TYPE_VOID;
2987 
2988      ELSIF(sysPropName = RULE_SYS_PROP_QUANTITY)THEN
2989 
2990        v_return(i) := GENERATE_NAME(j, optionId);
2991        ListType := DATA_TYPE_INTEGER;
2992 
2993      ELSIF(sysPropName = RULE_SYS_PROP_INSTANCECOUNT)THEN
2994 
2995        IF(glPsNodeType(optionIndex) IN (PS_NODE_TYPE_COMPONENT,
2996                                         PS_NODE_TYPE_REFERENCE,
2997                                         PS_NODE_TYPE_PRODUCT))THEN
2998 
2999          --If it is a non-virtual component/product/reference, we add _ACTUALCOUNT to the name.
3000          --If it is a virtual component/product/reference, we return '1'.
3001          --If it is an option, we just generate the name.
3002 
3003          IF(glVirtualFlag(optionIndex) = FLAG_NON_VIRTUAL)THEN
3004            v_return(i) := GENERATE_NAME(j, optionId)||'_ACTUALCOUNT';
3005          ELSE
3006            v_return(i) := '1';
3007          END IF;
3008        ELSE
3009          v_return(i) := GENERATE_NAME(j, optionId);
3010        END IF;
3011 
3012        ListType := DATA_TYPE_INTEGER;
3013      ELSE
3014 
3015        RAISE CZ_E_NO_SUCH_PROPERTY;
3016      END IF;
3017    ELSE
3018 
3019      BEGIN
3020 
3021        itemId := glItemId(optionIndex);
3022 
3023        v_return(i) := GET_PROPERTY_VALUE(optionId, propertyId, itemId, ListType);
3024 
3025        IF(v_return(i) IS NULL)THEN RAISE CZ_E_NULL_PROPERTY_VALUE; END IF;
3026 
3027        IF(ListType IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL))THEN
3028 
3029          BEGIN
3030            nChild := TO_NUMBER(v_return(i));
3031          EXCEPTION
3032            WHEN OTHERS THEN
3033 
3034              SELECT name INTO errorMessage
3035                FROM cz_properties
3036               WHERE property_id = propertyId;
3037 
3038              localString := v_return(i);
3039              RAISE CZ_R_INCORRECT_DATA_TYPE;
3040          END;
3041        END IF;
3042 
3043      EXCEPTION
3044        WHEN NO_DATA_FOUND THEN
3045          RAISE CZ_E_NO_SUCH_PROPERTY;
3046        WHEN TOO_MANY_ROWS THEN
3047          RAISE CZ_E_INCORRECT_PROPERTY;
3048        WHEN OTHERS THEN
3049          RAISE;
3050      END;
3051    END IF;
3052  END LOOP;
3053 
3054 nDebug := 9001009;
3055 
3056  RETURN v_return;
3057 END;
3058 ---------------------------------------------------------------------------------------
3059 FUNCTION GENERATE_PROPERTY(j IN PLS_INTEGER) RETURN tStringArray IS
3060  v_return     tStringArray;
3061  ListType     PLS_INTEGER;
3062 BEGIN
3063 
3064   v_return(1) := PROPERTY_VALUE(j, glIndexByPsNodeId(v_tExprPsNodeId(j)), ListType);
3065   RETURN v_return;
3066 END;
3067 ---------------------------------------------------------------------------------------
3068 FUNCTION EXPAND_NODE_OPTIONAL(pvPsNodeId IN NUMBER) RETURN tIntegerArray IS  --kdande; Bug 6881902; 11-Mar-2008
3069  v_return     tIntegerArray;
3070  nCount       PLS_INTEGER;
3071  nStartIndex  PLS_INTEGER;
3072  nEndIndex    PLS_INTEGER;
3073  indicator    PLS_INTEGER := 0;
3074 BEGIN
3075 
3076   nStartIndex := glIndexByPsNodeId(pvPsNodeId) + 1;
3077 
3078   IF(NOT glLastChildIndex.EXISTS(pvPsNodeId))THEN
3079     localString := glName(glIndexByPsNodeId(pvPsNodeId));
3080     RAISE CZ_E_NO_EXPECTED_CHILDREN;
3081   END IF;
3082 
3083   nEndIndex := glLastChildIndex(pvPsNodeId);
3084   nCount := 1;
3085 
3086   IF(glPsNodeType(glIndexByPsNodeId(pvPsNodeId)) = PS_NODE_TYPE_FEATURE)THEN
3087 
3088     indicator := 1;
3089     FOR i IN nStartIndex..nEndIndex LOOP
3090 
3091       v_return(nCount) := i;
3092       nCount := nCount + 1;
3093 
3094     END LOOP;
3095   ELSE
3096 
3097    FOR i IN nStartIndex..nEndIndex LOOP
3098 
3099      IF(glParentId(i) = pvPsNodeId AND glBomRequired(i) = FLAG_BOM_OPTIONAL)THEN
3100 
3101        v_return(nCount) := i;
3102        nCount := nCount + 1;
3103 
3104      END IF;
3105    END LOOP;
3106   END IF;
3107 
3108  --Validate that there are any optional children, otherwise the rule has no sense so
3109  --just ignore it.
3110 
3111  IF(v_return.COUNT = 0)THEN
3112    localString := glName(glIndexByPsNodeId(pvPsNodeId));
3113    IF(indicator = 1)THEN
3114      RAISE CZ_E_NO_EXPECTED_CHILDREN;
3115    END IF;
3116    RAISE CZ_E_NO_OPTIONAL_CHILDREN;
3117  END IF;
3118 
3119  RETURN v_return;
3120 END;
3121 ---------------------------------------------------------------------------------------
3122 FUNCTION GENERATE_VAL(j IN PLS_INTEGER) RETURN tStringArray IS
3123  v_return  tStringArray;
3124  nChild    PLS_INTEGER;
3125  ListType  PLS_INTEGER;
3126  nCheck    NUMBER;
3127 BEGIN
3128 
3129  IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
3130   RAISE CZ_E_WRONG_VAL_EXPRESSION;
3131  END IF;
3132 
3133  nChild := v_ChildrenIndex(v_tExprId(j));
3134  IF(v_tExprParentId.EXISTS(nChild + 1) AND v_tExprParentId(nChild + 1) = v_tExprId(j))THEN
3135   RAISE CZ_E_WRONG_VAL_EXPRESSION;
3136  END IF;
3137 
3138  v_return := GENERATE_EXPRESSION(nChild, ListType);
3139 
3140  BEGIN
3141   nCheck := TO_NUMBER(v_return(1));
3142  EXCEPTION
3143    WHEN OTHERS THEN
3144      RAISE CZ_E_WRONG_VAL_EXPRESS_TYPE;
3145  END;
3146 
3147  RETURN v_return;
3148 END;
3149 ---------------------------------------------------------------------------------------
3150 FUNCTION GENERATE_LOGIC_SIDE(j IN PLS_INTEGER, Operator OUT NOCOPY PLS_INTEGER)
3151 RETURN tStringArray IS
3152   v_return     tStringArray;
3153   ListType     PLS_INTEGER := NEVER_EXISTS_ID;
3154 BEGIN
3155 
3156 nDebug := 8001110;
3157 
3158    --Removing the 'simple expression' branch as a part of the fix for the bug #3371279.
3159 
3160    IF(v_tExprType(j) = EXPR_OPERATOR AND NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
3161 
3162      RAISE CZ_R_INCOMPLETE_LOGIC_RULE;
3163    END IF;
3164 
3165    v_return := GENERATE_EXPRESSION(j, ListType);
3166    Operator := OPERATOR_ALLOF;
3167    IF(ListType IN (OPERATOR_ANYOF, OPERATOR_ALLOF))THEN
3168      Operator := ListType;
3169    END IF;
3170  RETURN v_return;
3171 END;
3172 ---------------------------------------------------------------------------------------
3173 PROCEDURE GENERATE_LOGIC_RULE IS
3174  defaultName  tStringArray;
3175  itemName     tStringArray;
3176  v_lefts      tStringArray;
3177  v_rights     tStringArray;
3178  LeftOp       PLS_INTEGER;
3179  RightOp      PLS_INTEGER;
3180  ListType     PLS_INTEGER;
3181  ObjectName   VARCHAR2(16);
3182 BEGIN
3183 
3184     IF(jAntecedentRoot IS NULL OR jConsequentRoot IS NULL)THEN
3185       RAISE CZ_R_INVALID_LOGIC_RULE;
3186     END IF;
3187 
3188 nDebug := 8001100;
3189 
3190     IF(nRuleOperator = RULE_OPERATOR_DEFAULTS)THEN
3191 
3192 nDebug := 8001101;
3193 
3194       defaultName := GENERATE_EXPRESSION(jAntecedentRoot, ListType);
3195       ListType := NEVER_EXISTS_ID;
3196       itemName := GENERATE_EXPRESSION(jConsequentRoot, ListType);
3197       IF(ListType NOT IN (OPERATOR_ANYOF, OPERATOR_ALLOF))THEN
3198         ListType := OPERATOR_ANYOF;
3199       END IF;
3200 
3201 nDebug := 8001102;
3202 
3203       localString := NULL;
3204       IF(itemName.COUNT > 1)THEN localString := sUnsatisfiedId; END IF;
3205 
3206       nLocalDefaults := nLocalDefaults + 1;
3207       ObjectName := 'D_' || TO_CHAR(nLocalDefaults) || '_' || TO_CHAR(MaxDepthId);
3208 
3209       vLogicLine := 'OBJECT ' || ObjectName || NewLine ||
3210         'WITH _default = ' || defaultName(1) || NewLine ||
3211         'GS R ' || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
3212         'GL' || OperatorLetters(ListType);
3213 
3214       PACK;
3215 
3216 nDebug := 8001103;
3217 
3218       FOR i IN 1..itemName.COUNT LOOP
3219 
3220         vLogicLine := itemName(i) || ' ';
3221         PACK;
3222 
3223       END LOOP;
3224 
3225       vLogicLine := NewLine || 'GR N ' || ObjectName || NewLine;
3226       PACK;
3227 
3228 nDebug := 8001104;
3229 
3230     ELSE
3231 
3232 nDebug := 8001105;
3233 
3234         v_lefts := GENERATE_LOGIC_SIDE(jAntecedentRoot, LeftOp);
3235         v_rights := GENERATE_LOGIC_SIDE(jConsequentRoot, RightOp);
3236 
3237 nDebug := 8001106;
3238 
3239         localString := NULL;
3240         IF(v_lefts.COUNT > 1 OR v_rights.COUNT > 1)THEN localString := sUnsatisfiedId; END IF;
3241 
3242         vLogicLine := 'GS' || OperatorLetters(nRuleOperator) || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
3243                       'GL' || OperatorLetters(LeftOp);
3244         PACK;
3245 
3246 nDebug := 8001107;
3247 
3248         FOR i IN 1..v_lefts.COUNT LOOP
3249 
3250           vLogicLine := v_lefts(i) || ' ';
3251           PACK;
3252 
3253         END LOOP;
3254 
3255 nDebug := 8001108;
3256 
3257         vLogicLine := NewLine || 'GR' || OperatorLetters(RightOp);
3258         PACK;
3259 
3260         FOR i IN 1..v_rights.COUNT LOOP
3261 
3262           vLogicLine := v_rights(i) || ' ';
3263           PACK;
3264 
3265         END LOOP;
3266 
3267         vLogicLine := NewLine;
3268         PACK;
3269 
3270 nDebug := 8001109;
3271 
3272     END IF;
3273 END;
3274 ---------------------------------------------------------------------------------------
3275 FUNCTION HAS_INTEGER_VALUE(j IN PLS_INTEGER) RETURN PLS_INTEGER IS
3276   NodeType     PLS_INTEGER := v_tExprType(j);
3277   FeatureType  PLS_INTEGER;
3278   SysPropType  PLS_INTEGER;
3279   PsNodeIndex  PLS_INTEGER;
3280 BEGIN
3281 
3282   IF(NodeType = EXPR_ARGUMENT)THEN
3283 
3284     PsNodeIndex := LOOKUP_ARGUMENT(j);
3285     IF(parameterScope(PsNodeIndex).node_id IS NULL)THEN RETURN GENERATE_SCOPE_ERROR; END IF;
3286 
3287     NodeType := EXPR_PSNODE;
3288     v_tExprPsNodeId(j) := parameterScope(PsNodeIndex).node_id;
3289   END IF;
3290 
3291   IF(NodeType = EXPR_PSNODE)THEN
3292 
3293     NodeType := glPsNodeType(glIndexByPsNodeId(v_tExprPsNodeId(j)));
3294     FeatureType := glFeatureType(glIndexByPsNodeId(v_tExprPsNodeId(j)));
3295     localString := glName(glIndexByPsNodeId(v_tExprPsNodeId(j)));
3296 
3297     IF(NodeType = PS_NODE_TYPE_FEATURE AND FeatureType IN
3298                  (PS_NODE_FEATURE_TYPE_OPTION, PS_NODE_FEATURE_TYPE_BOOLEAN)
3299                   AND (NOT v_ChildrenIndex.EXISTS(v_tExprId(j))))THEN
3300 
3301       IF(FeatureType = PS_NODE_FEATURE_TYPE_OPTION)THEN
3302         errorMessage := 'Option Feature';
3303       ELSE
3304         errorMessage := 'Boolean Feature';
3305       END IF;
3306       RAISE CZ_R_INCORRECT_NUMERIC_RHS;
3307     ELSIF(NodeType = PS_NODE_TYPE_COMPONENT AND (NOT v_ChildrenIndex.EXISTS(v_tExprId(j))))THEN
3308 
3309       --Bug #3800339. This is a component without a system property applied. As the data is corrupted,
3310       --it may not be possible to catch things like that by queries against the seed data.
3311 
3312       errorMessage := 'Component';
3313       RAISE CZ_R_INCORRECT_NUMERIC_RHS;
3314     END IF;
3315 
3316     IF(v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
3317       IF(v_tExprType(v_ChildrenIndex(v_tExprId(j))) = EXPR_PROP)THEN
3318 
3319         --User properties are not allowed in the consequent expression.
3320 
3321         RAISE CZ_R_INVALID_NUMERIC_RULE;
3322       END IF;
3323 
3324       SysPropType := v_tExprSubtype(v_ChildrenIndex(v_tExprId(j)));
3325       IF(NOT h_SeededName.EXISTS(SysPropType))THEN RAISE CZ_E_BAD_PROPERTY_TYPE; END IF;
3326 
3327       IF(h_SeededName(SysPropType) = RULE_SYS_PROP_SELECTION)THEN RETURN GENERATE_DYNAMIC; END IF;
3328 
3329       IF(h_SeededName(SysPropType) <> RULE_SYS_PROP_SELECTION AND
3330          (NOT APPLICABLE_SYS_PROP(j, NULL, SysPropType)))THEN
3331 
3332         localString := h_ReportName(sysPropType);
3333         auxIndex := glIndexByPsNodeId(v_tExprPsNodeId(j));
3334         RAISE CZ_R_INCOMPATIBLE_SYSPROP;
3335       ELSE
3336 
3337         --Bug #4677027. No rounding operator for contributions to any bom nodes.
3338 
3339         IF(NodeType IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN RETURN GENERATE_CONTRIBUTE; END IF;
3340 
3341         IF(COMPATIBLE_DATA_TYPES(SIGNATURE_DATA_TYPE(h_SignatureId(SysPropType)), DATATYPE_INTEGER))THEN
3342           RETURN GENERATE_INCREMENT;
3343         END IF;
3344       END IF;
3345     ELSE
3346       IF(NodeType = PS_NODE_TYPE_OPTION OR
3347          (NodeType = PS_NODE_TYPE_FEATURE AND FeatureType = PS_NODE_FEATURE_TYPE_INTEGER))THEN
3348             RETURN GENERATE_INCREMENT;
3349       END IF;
3350     END IF;
3351    RETURN GENERATE_CONTRIBUTE;
3352   ELSE
3353    RETURN GENERATE_CONTRIBUTE;
3354   END IF;
3355 END;
3356 ---------------------------------------------------------------------------------------
3357 FUNCTION GENERATE_NUMERIC_PART(j IN PLS_INTEGER, NodeId IN OUT NOCOPY NUMBER)  --kdande; Bug 6881902; 11-Mar-2008
3358 RETURN VARCHAR2 IS
3359   ExprType  PLS_INTEGER := v_tExprType(j);
3360   v_return  VARCHAR2(4000);
3361   v_propval tStringArray;
3362   ListType  PLS_INTEGER;
3363   nChild    NUMBER;
3364 BEGIN
3365   IF(ExprType IN (EXPR_PSNODE, EXPR_ARGUMENT))THEN
3366 
3367     v_propval := GENERATE_EXPRESSION(j, ListType);
3368     v_return := v_propval(1);
3369     NodeId := v_tExprPsNodeId(j);
3370 
3371   ELSIF(ExprType = EXPR_NODE_TYPE_COUNT)THEN
3372 
3373     v_return := GENERATE_NAME(j, v_tExprPsNodeId(j));
3374     NodeId := v_tExprPsNodeId(j);
3375 
3376   ELSIF(ExprType = EXPR_NODE_TYPE_LITERAL)THEN
3377 
3378     v_return := v_tExprDataValue(j);
3379     NodeId := 0;
3380 
3381   ELSIF(ExprType = EXPR_NODE_TYPE_PROP)THEN
3382 
3383     v_return := PROPERTY_VALUE(j, glIndexByPsNodeId(NodeId), ListType);
3384     NodeId := 0;
3385 
3386     BEGIN
3387      nChild := TO_NUMBER(v_return);
3388      IF(nChild = 0)THEN NodeId := -1; END IF;
3389     EXCEPTION
3390       WHEN OTHERS THEN
3391 
3392         SELECT name INTO errorMessage
3393           FROM cz_properties
3394          WHERE property_id = v_tExprPropertyId(j);
3395 
3396         RAISE CZ_R_INCORRECT_NUMERICLHS;
3397     END;
3398 
3399   ELSIF(ExprType = EXPR_NODE_TYPE_OPERATOR AND v_tExprSubtype(j) = OPERATOR_DOT)THEN
3400 
3401     nChild := v_ChildrenIndex(v_tExprId(j));
3402     v_tExplNodeId(nChild + 1) := v_tExplNodeId(nChild);
3403     v_return := PROPERTY_VALUE(nChild + 1, glIndexByPsNodeId(v_tExprPsNodeId(nChild)), ListType);
3404     NodeId := v_tExprPsNodeId(nChild);
3405 
3406   ELSE
3407 
3408     RAISE CZ_R_INVALID_NUMERIC_PART;
3409 
3410   END IF;
3411  RETURN v_return;
3412 END;
3413 ---------------------------------------------------------------------------------------
3414 FUNCTION GENERATE_BOOLEAN_PART(j IN PLS_INTEGER) RETURN VARCHAR2 IS
3415   nChild    PLS_INTEGER;
3416   v_return  VARCHAR2(4000);
3417   v_index   tIntegerArray;
3418   ExprId    PLS_INTEGER := v_tExprId(j);
3419 BEGIN
3420 
3421 nDebug := 8001001;
3422 
3423   nChild := v_ChildrenIndex(ExprId);
3424 
3425 nDebug := 8001002;
3426 
3427   nLocalDefaults := nLocalDefaults + 1;
3428   v_return := t_prefix || TO_CHAR(nLocalDefaults);
3429 
3430   vLogicLine := 'OBJECT ' || v_return || NewLine ||
3431                 'GS R ... ' || TO_CHAR(nReasonId) || NewLine ||
3432                 'GL' || OperatorLetters(v_tExprSubtype(j));
3433   PACK;
3434 
3435 nDebug := 8001004;
3436 
3437   WHILE(v_tExprParentId(nChild) = ExprId) LOOP
3438 
3439     v_index := EXPAND_NODE(nChild);
3440 
3441     FOR i IN 1..v_index.COUNT LOOP
3442 
3443       vLogicLine := GENERATE_NAME_EXPL(v_ExplByPsNodeId(v_index(i)), v_index(i)) || ' ';
3444       PACK;
3445     END LOOP;
3446 
3447     nChild := nChild + 1;
3448   END LOOP;
3449 
3450 nDebug := 8001005;
3451 
3452   vLogicLine := NewLine || 'GR' || OperatorLetters(OPERATOR_ALLOF) || v_return || NewLine;
3453   PACK;
3454 
3455 nDebug := 8001006;
3456 
3457  RETURN v_return;
3458 END;
3459 ---------------------------------------------------------------------------------------
3460 PROCEDURE GENERATE_INCREMENT_LOGIC IS
3461   v_NodeId        NUMBER; --kdande; Bug 6881902; 11-Mar-2008
3462   v_HeaderId      NUMBER;
3463   v_return        VARCHAR2(4000);
3464   v_result        tStringArray;
3465   v_index         tStringArray;
3466   v_acname        VARCHAR2(4000);
3467   v_nodename      VARCHAR2(4000);
3468   v_accuname      VARCHAR2(4000);
3469   ListType        PLS_INTEGER;
3470   sSign           VARCHAR2(8) := NULL;
3471   lhsNode         PLS_INTEGER := 0;
3472   rhsNode         PLS_INTEGER := 0;
3473   lhsName         VARCHAR2(4000);
3474   rhsName         VARCHAR2(4000);
3475   nOpNode         PLS_INTEGER;
3476   nChild          PLS_INTEGER;
3477   nGrandChild     PLS_INTEGER;
3478   nSuffix         PLS_INTEGER := 0;
3479   iLocal          PLS_INTEGER;
3480   operatorLiteral VARCHAR2(4000);
3481   v_name          VARCHAR2(128);
3482 ---------------------------------------------------------------------------------------
3483 PROCEDURE GENERATE_INCREMENT_RECORD IS
3484   v_total  VARCHAR2(4000) := NULL;
3485 BEGIN
3486 
3487   IF(v_tExprSubtype(nOpNode) = OPERATOR_DIV)THEN
3488 
3489     v_total := t_prefix || v_name || '_' || TO_CHAR(nSuffix);
3490     vLogicLine := 'TOTAL ' || v_total || NewLine ||
3491                   'CONTRIBUTE ' || lhsName || OperatorLiterals(OPERATOR_DIV) ||
3492                   rhsName || ' ' || v_total || ' ... ' || TO_CHAR(nReasonId) || NewLine;
3493     PACK;
3494   ELSIF(v_tExprSubtype(nOpNode) = OPERATOR_MATHDIV)THEN
3495 
3496     v_total := t_prefix || v_name || '_' || TO_CHAR(nSuffix);
3497     vLogicLine := 'TOTAL ' || v_total || NewLine ||
3498                   'MF ' || lhsName || ' ' || rhsName || OperatorLiterals(OPERATOR_MATHDIV) ||
3499                   v_total || ' ... ' || TO_CHAR(nReasonId) || NewLine;
3500     PACK;
3501   END IF;
3502 
3503   sSign := NULL;
3504   IF(nRuleOperator = RULE_OPERATOR_CONSUMES)THEN
3505     sSign := '-1 ';
3506   END IF;
3507 
3508   IF(v_total IS NULL)THEN
3509 
3510    vLogicLine := 'INC ' || sSign || lhsName || ' ' || rhsName || ' ' || v_acname ||
3511                  OperatorLiteral || '... ' || TO_CHAR(nReasonId) || NewLine;
3512 
3513   ELSE
3514 
3515    vLogicLine := 'INC ' || sSign || v_total || ' ' || v_acname ||
3516                  OperatorLiteral || '... ' || TO_CHAR(nReasonId) || NewLine;
3517 
3518   END IF;
3519  PACK;
3520 END;
3521 ---------------------------------------------------------------------------------------
3522 BEGIN
3523 
3524   nLocalDefaults := nLocalDefaults + 1;
3525   v_name := TO_CHAR(nLocalDefaults);
3526 
3527   --Generate the accumulator and corresponding increment relation if necessary
3528 
3529 nDebug := 8001200;
3530 
3531   v_return := GENERATE_NUMERIC_PART(jConsequentRoot, v_NodeId);
3532 
3533 nDebug := 8001201;
3534 
3535   IF(v_tExprType(jConsequentRoot) = EXPR_NODE_TYPE_OPERATOR AND
3536      v_tExprSubtype(jConsequentRoot) = OPERATOR_DOT)THEN
3537 
3538 nDebug := 8001202;
3539 
3540    nChild := v_ChildrenIndex(v_tExprId(jConsequentRoot)) + 1;
3541    v_acname := v_return;
3542 
3543    --Commenting the following block out as the fix to bug #1657701. Assuming that this code
3544    --was necessary until some fixes in participants' model_ref_expl_id population hadn't
3545    --been done, and now it's obsolete.
3546 /*
3547    IF(v_NodeId = v_tPsNodeId(v_IndexByNodeId(MaxDepthId)))THEN
3548      v_acname := PATH_DELIMITER || 'parent' || PATH_DELIMITER || v_acname;
3549    END IF;
3550 */
3551 
3552   ELSIF(v_tExprType(jConsequentRoot) = EXPR_PSNODE AND v_ChildrenIndex.EXISTS(v_tExprId(jConsequentRoot)))THEN
3553 
3554     nChild := jConsequentRoot;
3555     v_acname := v_return;
3556 
3557   ELSIF((NOT v_HeaderByAccId.EXISTS(v_NodeId)) AND
3558         (glAccumulator(v_NodeId) IS NULL OR glAccumulator(v_NodeId) = FLAG_NO_ACCUMULATOR))THEN
3559 
3560 nDebug := 8001203;
3561 
3562    v_HeaderId := glHeaderByPsNodeId(v_NodeId);
3563    v_nodename := 'P_' || TO_CHAR(glPersistentId(v_NodeId));
3564    v_accuname := v_nodename || '_ACC';
3565 
3566    --Flush off the buffer because we are about to write to another file
3567 
3568    IF(vLogicText IS NOT NULL)THEN
3569     INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
3570      (nHeaderId, v_tSequenceNbr(nHeaderId), vLogicText);
3571     vLogicText := NULL;
3572     v_tSequenceNbr(nHeaderId) := v_tSequenceNbr(nHeaderId) + 1;
3573    END IF;
3574 
3575    --Fix for the bug #2398832 - we may be re-using the accumulator, so we should not
3576    --assign to it effectivities and usages of a particular node.
3577    --Do not write the effectivity dates using the actual effective date interval of
3578    --the corresponding node.
3579 
3580    --iLocal := glIndexByPsNodeId(v_NodeId);
3581    --CurrentEffFrom := glEffFrom(iLocal);
3582    --CurrentEffUntil := glEffUntil(iLocal);
3583    --CurrentUsageMask := glUsageMask(iLocal);
3584 
3585    --Instead make the accumulator always effective and universal.
3586 
3587    CurrentEffFrom := EpochBeginDate;
3588    CurrentEffUntil := EpochEndDate;
3589    CurrentUsageMask := AnyUsageMask;
3590 
3591    IF((NOT h_EffFrom.EXISTS(v_HeaderId)) OR
3592       (h_EffFrom(v_HeaderId) <> CurrentEffFrom OR h_EffUntil(v_HeaderId) <> CurrentEffUntil OR
3593        h_EffUsageMask(v_HeaderId) <> CurrentUsageMask))THEN
3594 
3595      h_EffFrom(v_HeaderId) := CurrentEffFrom;
3596      h_EffUntil(v_HeaderId) := CurrentEffUntil;
3597      h_EffUsageMask(v_HeaderId) := CurrentUsageMask;
3598 
3599      vLogicText := LTRIM(CurrentUsageMask, '0');
3600      IF(vLogicText IS NOT NULL) THEN
3601        vLogicText := EffUsagePrefix || vLogicText;
3602      END IF;
3603 
3604      IF(CurrentEffFrom = EpochBeginDate)THEN
3605        CurrentFromDate := NULL;
3606      ELSE
3607        CurrentFromDate := TO_CHAR(CurrentEffFrom, EffDateFormat);
3608      END IF;
3609 
3610      IF(CurrentEffUntil = EpochEndDate)THEN
3611        CurrentUntilDate := NULL;
3612      ELSE
3613        CurrentUntilDate := TO_CHAR(CurrentEffUntil, EffDateFormat);
3614      END IF;
3615 
3616      vLogicText := 'EFF ' || CurrentFromDate || ', ' || CurrentUntilDate || ', ' || vLogicText || NewLine;
3617    END IF;
3618 
3619    vLogicText := vLogicText || 'TOTAL ' || v_accuname || NewLine ||
3620                  'INC ' || v_accuname || ' ' || v_nodename ||
3621                  OperatorLiterals(OPERATOR_ROUND) || '... ' || TO_CHAR(nReasonId) || NewLine;
3622 
3623    INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
3624     (v_HeaderId, vSeqNbrByHeader(v_HeaderId), vLogicText);
3625    vLogicText := NULL;
3626    vSeqNbrByHeader(v_HeaderId) := vSeqNbrByHeader(v_HeaderId) + 1;
3627 
3628    v_HeaderByAccId(v_NodeId) := v_HeaderId;
3629    v_acname := v_return || '_ACC';
3630 
3631    --Part of the fix for the bug #2857955. We will never be here if glAccumulator(v_NodeId) was
3632    --FLAG_ACCUMULATOR_ACC because the accumulator would have already been created.
3633 
3634    UPDATE cz_ps_nodes SET
3635      accumulator_flag = DECODE(glAccumulator(v_NodeId), FLAG_ACCUMULATOR_NT, FLAG_ACCUMULATOR_BOTH, FLAG_ACCUMULATOR_ACC)
3636    WHERE ps_node_id = v_NodeId;
3637 
3638   ELSE
3639 
3640 nDebug := 8001204;
3641 
3642    v_acname := v_return || '_ACC';
3643   END IF;
3644 
3645 nDebug := 8001205;
3646 
3647   --If we are here, than the RHS expression has an integer value and so the LHS expression
3648   --should have a root rounding operator. So go down one level.
3649   --However, as a fix for the bug #3558699 we now don't require the root rounding operator
3650   --if the data type of antecedent is convertible to integer. Therefore we have to be more
3651   --flexible here.
3652 
3653   IF(v_tExprType(jAntecedentRoot) <> EXPR_OPERATOR OR v_tExprSubtype(jAntecedentRoot) NOT IN
3654            (OPERATOR_ROUND, OPERATOR_CEILING, OPERATOR_FLOOR, OPERATOR_TRUNCATE, OPERATOR_NONE))THEN
3655     nOpNode := jAntecedentRoot;
3656     OperatorLiteral := OperatorLiterals(OPERATOR_NONE);
3657   ELSE
3658     nOpNode := v_ChildrenIndex(v_tExprId(jAntecedentRoot));
3659     OperatorLiteral := OperatorLiterals(v_tExprSubtype(jAntecedentRoot));
3660   END IF;
3661 
3662   IF(v_tExprType(nOpNode) = EXPR_OPERATOR AND (NOT v_ChildrenIndex.EXISTS(v_tExprId(nOpNode))))THEN
3663     RAISE CZ_R_INCOMPLETE_NUMERIC_RULE;
3664   END IF;
3665 
3666   IF(v_ChildrenIndex.EXISTS(v_tExprId(nOpNode)))THEN
3667     lhsNode := v_ChildrenIndex(v_tExprId(nOpNode));
3668     rhsNode := lhsNode + v_NumberOfChildren(v_tExprId(nOpNode)) - 1;
3669   END IF;
3670 
3671   IF(nPresentationFlag = FLAG_FREEFORM_RULE)THEN
3672 
3673     --Check if this is a simple numeric rule that has been upgraded to become a free-form rule. For such
3674     --rules we want to generate an optimized INC relation.
3675     --Bug #4047086. However, the operator can only be multiplication to be able to optimize.
3676     --Bugs #4256960, #4254591. The RHS operand must also be simple, not an operator.
3677 
3678     IF((v_tExprType(nOpNode) = EXPR_OPERATOR AND v_tExprSubtype(nOpNode) = OPERATOR_MULT) AND
3679        (v_tExprType(rhsNode) <> EXPR_OPERATOR) AND (v_tExprType(lhsNode) = EXPR_LITERAL OR
3680        (v_tExprType(lhsNode) IN (EXPR_PSNODE, EXPR_ARGUMENT) AND (NOT HAS_OPTIONS_APPLIED(lhsNode)))))THEN
3681 
3682       rhsNode := lhsNode + 1;
3683 
3684       lhsName := GENERATE_NUMERIC_PART(lhsNode, v_NodeId);
3685       rhsName := GENERATE_NUMERIC_PART(rhsNode, v_NodeId);
3686       GENERATE_INCREMENT_RECORD;
3687       RETURN;
3688     ELSE
3689 
3690 nDebug := 8001206;
3691 
3692       numericLHS := 1;
3693       v_result := GENERATE_EXPRESSION(nOpNode, ListType);
3694       IF(nRuleOperator = RULE_OPERATOR_CONSUMES)THEN
3695         sSign := '-1 ';
3696       END IF;
3697       vLogicLine := 'INC ' || sSign || v_result(1) || ' ' || v_acname ||
3698                     OperatorLiteral || '... ' || TO_CHAR(nReasonId) || NewLine;
3699       PACK;
3700       RETURN;
3701     END IF;
3702   END IF;
3703 
3704 nDebug := 8001207;
3705 
3706   FOR i IN lhsNode..rhsNode - 1 LOOP
3707     IF(v_tExprType(i) = EXPR_PSNODE AND HAS_OPTIONS_APPLIED(i))THEN
3708 
3709       v_index := GENERATE_CHILDRENOF(v_tExplNodeId(i), v_tExprPsNodeId(i));
3710 
3711       FOR ich IN 1..v_index.COUNT LOOP
3712 
3713         lhsName := v_index(ich);
3714         rhsName := GENERATE_NUMERIC_PART(rhsNode, v_NodeId);
3715         GENERATE_INCREMENT_RECORD;
3716         nSuffix := nSuffix + 1;
3717       END LOOP;
3718     ELSIF(v_tExprType(i) IN (EXPR_LITERAL, EXPR_PSNODE))THEN
3719 
3720       lhsName := GENERATE_NUMERIC_PART(i, v_NodeId);
3721       v_NodeId := v_tExprPsNodeId(i);
3722       rhsName := GENERATE_NUMERIC_PART(rhsNode, v_NodeId);
3723 
3724       GENERATE_INCREMENT_RECORD;
3725       nSuffix := nSuffix + 1;
3726     ELSE
3727 
3728       RAISE CZ_R_INVALID_NUMRULE_NODE;
3729     END IF;
3730   END LOOP;
3731 END;
3732 ---------------------------------------------------------------------------------------
3733 PROCEDURE GENERATE_CONTRIBUTE_LOGIC IS
3734   v_return     VARCHAR2(4000);
3735   v_result     tStringArray;
3736   v_index      tStringArray;
3737   ListType     PLS_INTEGER;
3738   sSign        VARCHAR2(8);
3739   lhsNode      PLS_INTEGER;
3740   rhsNode      PLS_INTEGER;
3741   lhsName      VARCHAR2(4000);
3742   rhsName      VARCHAR2(4000);
3743   nChild       PLS_INTEGER;
3744   nGrandChild  PLS_INTEGER;
3745   v_NodeId     NUMBER; --kdande; Bug 6881902; 11-Mar-2008
3746   nSuffix      PLS_INTEGER := 0;
3747   nOpNode      PLS_INTEGER := jAntecedentRoot;
3748   sOpRoot      VARCHAR2(16):= ' ';
3749   v_HeaderId   NUMBER;
3750   v_nodename   VARCHAR2(4000);
3751   v_accuname   VARCHAR2(4000);
3752   iLocal       PLS_INTEGER;
3753   v_name       VARCHAR2(128);
3754 ---------------------------------------------------------------------------------------
3755 PROCEDURE GENERATE_CONTRIBUTE_RECORD IS
3756   v_total  VARCHAR2(4000);
3757   v_local  VARCHAR2(4000) := v_return;
3758 BEGIN
3759   IF(nRuleOperator = RULE_OPERATOR_CONSUMES)THEN
3760 
3761     v_total := t_prefix || v_name || '_' || TO_CHAR(nSuffix);
3762     vLogicLine := 'TOTAL ' || v_total || NewLine ||
3763                   'CONTRIBUTE ' || v_total || OperatorLiterals(OPERATOR_MULT) ||
3764                   '-1 ' || v_local || ' ... ' || TO_CHAR(nReasonId) || NewLine;
3765     v_local := v_total;
3766     PACK;
3767   END IF;
3768 
3769   IF(v_NodeId = -1 AND v_tExprSubtype(nOpNode) = OPERATOR_MULT)THEN
3770 
3771     vLogicLine := 'CONTRIBUTE ' || lhsName || OperatorLiterals(OPERATOR_SUB) ||
3772                   lhsName || ' ' || v_local || sOpRoot || '... ' || TO_CHAR(nReasonId) || NewLine;
3773   ELSIF(v_tExprSubtype(nOpNode) = OPERATOR_MATHDIV)THEN
3774 
3775     v_total := t_prefix || v_name || '_' || TO_CHAR(nSuffix);
3776     vLogicLine := 'TOTAL ' || v_total || NewLine ||
3777                   'MF ' || lhsName || ' ' || rhsName || OperatorLiterals(OPERATOR_MATHDIV) ||
3778                   v_total || ' ... ' || TO_CHAR(nReasonId) || NewLine;
3779     PACK;
3780     vLogicLine := 'CONTRIBUTE 1 ' || v_total || ' ' || v_local || sOpRoot || '... ' || TO_CHAR(nReasonId) || NewLine;
3781   ELSE
3782 
3783     vLogicLine := 'CONTRIBUTE ' || lhsName || OperatorLiterals(v_tExprSubtype(nOpNode)) ||
3784                   rhsName || ' ' || v_local || sOpRoot || '... ' || TO_CHAR(nReasonId) || NewLine;
3785   END IF;
3786   PACK;
3787 END;
3788 ---------------------------------------------------------------------------------------
3789 BEGIN
3790 
3791   nLocalDefaults := nLocalDefaults + 1;
3792   v_name := TO_CHAR(nLocalDefaults);
3793 
3794 nDebug := 8002;
3795 
3796   v_return := GENERATE_NUMERIC_PART(jConsequentRoot, v_NodeId);
3797   optimizeChain := OPTIMIZATION_UNKNOWN;
3798   optimizeContribute := OPTIMIZATION_UNKNOWN;
3799 
3800   IF(v_tLogicNetType(nHeaderId) = LOGIC_NET_TYPE_NETWORK AND
3801      glPsNodeType(glIndexByPsNodeId(v_NodeId)) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
3802 
3803     --This is a conditional numeric rule against a BOM node. We will create an accumulator and
3804     --a 'contribute' relation from the accumulator to the BOM object, if such accumulator does
3805     --not exist. We'll need to temporarily switch context to the BOM object's structure file.
3806 
3807     IF((NOT v_HeaderByAccId.EXISTS(v_NodeId)) AND
3808        (glAccumulator(v_NodeId) IS NULL OR glAccumulator(v_NodeId) = FLAG_NO_ACCUMULATOR))THEN
3809 
3810       --Retrieve the corresponding structure file header and prepare the names.
3811 
3812       v_HeaderId := glHeaderByPsNodeId(v_NodeId);
3813       v_nodename := 'P_' || TO_CHAR(glPersistentId(v_NodeId));
3814       v_accuname := v_nodename || '_ACC';
3815 
3816       --Flush off the buffer because we are about to write to another file.
3817 
3818       IF(vLogicText IS NOT NULL)THEN
3819         INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
3820          (nHeaderId, v_tSequenceNbr(nHeaderId), vLogicText);
3821         vLogicText := NULL;
3822         v_tSequenceNbr(nHeaderId) := v_tSequenceNbr(nHeaderId) + 1;
3823       END IF;
3824 
3825       --Fix for the bug #2398832 - we may be re-using the accumulator, so we should not
3826       --assign to it effectivities and usages of a particular node.
3827       --Do not write the effectivity dates using the actual effective date interval of
3828       --the corresponding node.
3829 
3830       --iLocal := glIndexByPsNodeId(v_NodeId);
3831       --CurrentEffFrom := glEffFrom(iLocal);
3832       --CurrentEffUntil := glEffUntil(iLocal);
3833       --CurrentUsageMask := glUsageMask(iLocal);
3834 
3835       --Instead make the accumulator always effective and universal.
3836 
3837       CurrentEffFrom := EpochBeginDate;
3838       CurrentEffUntil := EpochEndDate;
3839       CurrentUsageMask := '0';
3840 
3841       IF((NOT h_EffFrom.EXISTS(v_HeaderId)) OR
3842          (h_EffFrom(v_HeaderId) <> CurrentEffFrom OR h_EffUntil(v_HeaderId) <> CurrentEffUntil OR
3843           h_EffUsageMask(v_HeaderId) <> CurrentUsageMask))THEN
3844 
3845         h_EffFrom(v_HeaderId) := CurrentEffFrom;
3846         h_EffUntil(v_HeaderId) := CurrentEffUntil;
3847         h_EffUsageMask(v_HeaderId) := CurrentUsageMask;
3848 
3849         vLogicText := LTRIM(CurrentUsageMask, '0');
3850         IF(vLogicText IS NOT NULL) THEN
3851           vLogicText := EffUsagePrefix || vLogicText;
3852         END IF;
3853 
3854         IF(CurrentEffFrom = EpochBeginDate)THEN
3855           CurrentFromDate := NULL;
3856         ELSE
3857           CurrentFromDate := TO_CHAR(CurrentEffFrom, EffDateFormat);
3858         END IF;
3859 
3860         IF(CurrentEffUntil = EpochEndDate)THEN
3861           CurrentUntilDate := NULL;
3862         ELSE
3863           CurrentUntilDate := TO_CHAR(CurrentEffUntil, EffDateFormat);
3864         END IF;
3865 
3866         vLogicText := 'EFF ' || CurrentFromDate || ', ' || CurrentUntilDate || ', ' || vLogicText || NewLine;
3867       END IF;
3868 
3869       --Write the logic record in the structure file.
3870 
3871       vLogicText := vLogicText || 'TOTAL ' || v_accuname || NewLine ||
3872                     'CONTRIBUTE 1 ' || v_accuname || ' ' || v_nodename ||
3873                     ' ... ' || TO_CHAR(nReasonId) || NewLine;
3874 
3875       INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
3876        (v_HeaderId, vSeqNbrByHeader(v_HeaderId), vLogicText);
3877 
3878       vLogicText := NULL;
3879       vSeqNbrByHeader(v_HeaderId) := vSeqNbrByHeader(v_HeaderId) + 1;
3880       v_HeaderByAccId(v_NodeId) := v_HeaderId;
3881 
3882       --This line and the ELSE branch below are to fix the bug #2702587 - we need not only create the
3883       --accumulator and a relation for it to the object but we also need to generate the rule so that
3884       --it contributes to the accumulator, not the objects.
3885 
3886       v_return := v_return || '_ACC';
3887 
3888       --Part of the fix for the bug #2857955. We will never be here if glAccumulator(v_NodeId) was
3889       --FLAG_ACCUMULATOR_ACC because the accumulator would have already been created.
3890 
3891       UPDATE cz_ps_nodes SET
3892         accumulator_flag = DECODE(glAccumulator(v_NodeId), FLAG_ACCUMULATOR_NT, FLAG_ACCUMULATOR_BOTH, FLAG_ACCUMULATOR_ACC)
3893       WHERE ps_node_id = v_NodeId;
3894 
3895     ELSE
3896 
3897       v_return := v_return || '_ACC';
3898     END IF;
3899   END IF;
3900 
3901 nDebug := 8003;
3902 
3903   IF(v_tExprSubtype(jAntecedentRoot) IN
3904       (OPERATOR_ROUND, OPERATOR_FLOOR, OPERATOR_CEILING, OPERATOR_TRUNCATE, OPERATOR_NONE))THEN
3905     nOpNode := v_ChildrenIndex(v_tExprId(jAntecedentRoot));
3906     sOpRoot := OperatorLiterals(v_tExprSubtype(jAntecedentRoot));
3907   END IF;
3908 
3909   IF(nPresentationFlag = FLAG_FREEFORM_RULE)THEN
3910 
3911 nDebug := 8004;
3912 
3913    IF(nRuleOperator = RULE_OPERATOR_CONTRIBUTES)THEN
3914 
3915      sSign := '1 ';
3916 
3917      --If this is a numeric contribute rule with a root rounding operator, set the flag and store
3918      --the target from the Motorola optimization (bug #2540163).
3919 
3920      IF(v_tExprSubtype(jAntecedentRoot) IN
3921          (OPERATOR_ROUND, OPERATOR_FLOOR, OPERATOR_CEILING, OPERATOR_TRUNCATE))THEN
3922 
3923        optimizeChain := OPTIMIZATION_REQUESTED;
3924        optimizeTarget := v_return;
3925      ELSE
3926 
3927        optimizeContribute := OPTIMIZATION_REQUESTED;
3928      END IF;
3929    ELSE
3930 
3931      sSign := '-1 ';
3932    END IF;
3933 
3934 nDebug := 8004001;
3935 
3936    numericLHS := 1;
3937    v_result := GENERATE_EXPRESSION(jAntecedentRoot, ListType);
3938 
3939    --The value may have been changed during the expression generation. If it is not 0, we still
3940    --want to generate the rule's contribute relation. However, if it is 0 than the relation has
3941    --already been generated as a part of the optimization so here we just skip it.
3942 
3943    IF(optimizeChain IN (OPTIMIZATION_REQUESTED, OPTIMIZATION_UNKNOWN))THEN
3944      IF(optimizeContribute = OPTIMIZATION_COMPLETED)THEN
3945 
3946        vLogicLine := 'CONTRIBUTE ' || v_result(1) || v_return || ' ... ' || TO_CHAR(nReasonId) || NewLine;
3947      ELSE
3948 
3949        vLogicLine := 'CONTRIBUTE ' || v_result(1) || OperatorLiterals(OPERATOR_MULT) ||
3950                      sSign || v_return || sOpRoot || '... ' || TO_CHAR(nReasonId) || NewLine;
3951      END IF;
3952 
3953      PACK;
3954      optimizeChain := OPTIMIZATION_UNKNOWN;
3955    END IF;
3956 
3957    RETURN;
3958   END IF;
3959 
3960 nDebug := 8005;
3961 
3962   lhsNode := v_ChildrenIndex(v_tExprId(nOpNode));
3963   rhsNode := lhsNode + v_NumberOfChildren(v_tExprId(nOpNode)) - 1;
3964 
3965 nDebug := 8006;
3966 
3967   FOR i IN lhsNode..rhsNode - 1 LOOP
3968 
3969     IF(v_tExprType(i) = EXPR_PSNODE AND HAS_OPTIONS_APPLIED(i))THEN
3970 
3971       v_index := GENERATE_CHILDRENOF(v_tExplNodeId(i), v_tExprPsNodeId(i));
3972 
3973       FOR ich IN 1..v_index.COUNT LOOP
3974 
3975         lhsName := v_index(ich);
3976         rhsName := GENERATE_NUMERIC_PART(rhsNode, v_NodeId);
3977 
3978         GENERATE_CONTRIBUTE_RECORD;
3979         nSuffix := nSuffix + 1;
3980       END LOOP;
3981     ELSIF(v_tExprType(i) IN (EXPR_LITERAL, EXPR_PSNODE))THEN
3982 
3983       lhsName := GENERATE_NUMERIC_PART(i, v_NodeId);
3984       v_NodeId := v_tExprPsNodeId(i);
3985       rhsName := GENERATE_NUMERIC_PART(rhsNode, v_NodeId);
3986 
3987       GENERATE_CONTRIBUTE_RECORD;
3988       nSuffix := nSuffix + 1;
3989     ELSE
3990 
3991       RAISE CZ_R_INVALID_NUMRULE_NODE;
3992     END IF;
3993   END LOOP;
3994 END;
3995 ---------------------------------------------------------------------------------------
3996 PROCEDURE GENERATE_DYNAMIC_LOGIC IS
3997   v_result        tStringArray;
3998   v_children      tIntegerArray;
3999   ListType        PLS_INTEGER;
4000   v_name          VARCHAR2(4000);
4001   v_return        VARCHAR2(4000);
4002   v_object        VARCHAR2(4000);
4003   v_index         PLS_INTEGER;
4004 BEGIN
4005 
4006   IF(v_tExprType(jConsequentRoot) = EXPR_ARGUMENT)THEN
4007 
4008    ListType := DATA_TYPE_NODE;
4009    v_result := GENERATE_ARGUMENT(jConsequentRoot, ListType);
4010   END IF;
4011 
4012   nLocalDefaults := nLocalDefaults + 1;
4013   v_return := t_prefix || TO_CHAR(nLocalDefaults);
4014   v_index := 1;
4015 
4016   v_result.DELETE;
4017   v_result := GENERATE_EXPRESSION(jAntecedentRoot, ListType);
4018   v_children := EXPAND_NODE_OPTIONAL(v_tExprPsNodeId(jConsequentRoot));
4019 
4020   FOR i IN 1..v_result.COUNT LOOP
4021     FOR ii IN 1..v_children.COUNT LOOP
4022 
4023       v_name := GENERATE_NAME_EXPL(v_tExplNodeId(jConsequentRoot), glPsNodeId(v_children(ii)));
4024       v_object := v_return || '_' || TO_CHAR(v_index);
4025 
4026       vLogicLine := 'OBJECT ' || v_object || NewLine ||
4027                     'GS I ... ' || TO_CHAR(nReasonId) || NewLine ||
4028                     'GL' || OperatorLetters(OPERATOR_ALLOF) || v_name || NewLine ||
4029                     'GR' || OperatorLetters(OPERATOR_ALLOF) || v_object || NewLine ||
4030                     'INC ' || v_result(i) || ' ' || v_object || ' ' || v_name ||
4031                     ' ... ' || TO_CHAR(nReasonId) || NewLine;
4032       PACK;
4033 
4034       v_index := v_index + 1;
4035     END LOOP;
4036   END LOOP;
4037 END GENERATE_DYNAMIC_LOGIC;
4038 ---------------------------------------------------------------------------------------
4039 PROCEDURE GENERATE_NUMERIC_RULE IS
4040 
4041   v_index  PLS_INTEGER;
4042 BEGIN
4043 
4044     IF(jAntecedentRoot IS NULL OR jConsequentRoot IS NULL)THEN
4045       RAISE CZ_R_INVALID_NUMERIC_RULE;
4046     END IF;
4047 
4048     IF(v_tExprType(jAntecedentRoot) = EXPR_OPERATOR AND (NOT v_ChildrenIndex.EXISTS(v_tExprId(jAntecedentRoot))))THEN
4049       RAISE CZ_R_INCOMPLETE_NUMERIC_RULE;
4050     END IF;
4051 
4052     IF(HAS_INTEGER_VALUE(jConsequentRoot) = GENERATE_INCREMENT)THEN
4053 
4054       --For a numeric rule, if RHS has an integer value, the antecedent root should be a rounding operator.
4055       --As a fix for the bug #3558699, we are making this check more flexible - we require the rounding
4056       --operator only if the data type of the antecedent is not convertible to integer.
4057       --As a fix for the bug #3764347, if the antecedent root is a multiply operator, we drill down into
4058       --its operands and check their data types.
4059 
4060       IF(v_tExprType(jAntecedentRoot) <> EXPR_OPERATOR OR v_tExprSubtype(jAntecedentRoot) NOT IN
4061            (OPERATOR_ROUND, OPERATOR_CEILING, OPERATOR_FLOOR, OPERATOR_TRUNCATE))THEN
4062 
4063         v_index := jAntecedentRoot;
4064         IF(v_tExprType(v_index) = EXPR_OPERATOR AND v_tExprSubtype(v_index) = OPERATOR_NONE)THEN
4065 
4066           --Bug #4180719. This is an empty operator, drill down one level.
4067 
4068           v_index:= v_ChildrenIndex(v_tExprId(v_index));
4069         END IF;
4070 
4071         IF(v_tExprType(v_index) = EXPR_OPERATOR AND v_tExprSubtype(v_index) = OPERATOR_MULT)THEN
4072 
4073           --This is a multiply operator, check the data types of the children.
4074 
4075           v_index := v_ChildrenIndex(v_tExprId(v_index));
4076 
4077           IF((NOT COMPATIBLE_DATA_TYPES(v_tExprDataType(v_index), DATA_TYPE_INTEGER)) OR
4078              (NOT COMPATIBLE_DATA_TYPES(v_tExprDataType(v_index + 1), DATA_TYPE_INTEGER)))THEN
4079 
4080             RAISE CZ_R_INVALID_NUM_SIMPLE_EXPR;
4081           END IF;
4082         ELSIF(NOT COMPATIBLE_DATA_TYPES(v_tExprDataType(v_index), DATA_TYPE_INTEGER))THEN
4083 
4084           RAISE CZ_R_INVALID_NUM_SIMPLE_EXPR;
4085         END IF;
4086       END IF;
4087 
4088       GENERATE_INCREMENT_LOGIC;
4089     ELSIF(HAS_INTEGER_VALUE(jConsequentRoot) = GENERATE_CONTRIBUTE)THEN
4090       GENERATE_CONTRIBUTE_LOGIC;
4091     ELSIF(HAS_INTEGER_VALUE(jConsequentRoot) = GENERATE_DYNAMIC)THEN
4092       GENERATE_DYNAMIC_LOGIC;
4093     ELSE
4094       RAISE CZ_R_PARAMETER_NOT_FOUND;
4095     END IF;
4096 END;
4097 ---------------------------------------------------------------------------------------
4098 PROCEDURE GENERATE_COMPARISON_RULE IS
4099  leftOper   tStringArray;
4100  rightOper  tStringArray;
4101  ListType   PLS_INTEGER;
4102  jRoot      PLS_INTEGER;
4103  jChild     PLS_INTEGER;
4104 BEGIN
4105 
4106     IF(jAntecedentRoot IS NULL OR jConsequentRoot IS NULL)THEN
4107       RAISE CZ_R_INVALID_COMPARISON_RULE;
4108     END IF;
4109 
4110     leftOper := GENERATE_EXPRESSION(jAntecedentRoot, ListType);
4111 
4112     jRoot := jConsequentRoot;
4113 
4114     IF(v_tExprType(jRoot) = EXPR_OPERATOR AND v_tExprSubtype(jRoot) IN (OPERATOR_ALLOF, OPERATOR_ANYOF) AND
4115        v_NumberOfChildren(v_tExprId(jRoot)) = 1)THEN
4116 
4117       jChild := v_ChildrenIndex(v_tExprId(jRoot));
4118       IF(v_tExprType(jChild) = EXPR_PSNODE AND (NOT v_ChildrenIndex.EXISTS(v_tExprId(jChild))))THEN
4119 
4120         jRoot := jChild;
4121       END IF;
4122     END IF;
4123 
4124     rightOper := GENERATE_EXPRESSION(jRoot, ListType);
4125 
4126     vLogicLine := 'GS' || OperatorLetters(nRuleOperator) || '... ' || TO_CHAR(nReasonId) || NewLine ||
4127                   'GL' || OperatorLetters(OPERATOR_ALLOF) || leftOper(1) || NewLine ||
4128                   'GR' || OperatorLetters(OPERATOR_ALLOF) || rightOper(1) || NewLine;
4129 
4130     PACK;
4131 END;
4132 ---------------------------------------------------------------------------------------
4133 FUNCTION GENERATE_LOGIC_TREE(j IN PLS_INTEGER) RETURN tStringArray IS
4134   v_return  tStringArray;
4135 BEGIN
4136 
4137   IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 2)THEN
4138     RAISE CZ_R_INVALID_LOGIC_RULE;
4139   END IF;
4140 
4141   nRuleOperator := v_tExprSubtype(j);
4142   jAntecedentRoot := v_ChildrenIndex(v_tExprId(j));
4143   jConsequentRoot := jAntecedentRoot + 1;
4144 
4145   v_tExprParentId(jAntecedentRoot) := NULL;
4146   v_tExprParentId(jConsequentRoot) := NULL;
4147 
4148   --High-level logic rule validation section. Should not do these validations for comparison rules.
4149   --Make sure antecedent and consequent nodes have logical value.
4150   --If this is a comparison rule with a DEFAULT operator, which was not allowed before, we will
4151   --generate this rule as a logic rule (bug #3343569).
4152 
4153   IF(RuleTemplateType = RULE_TYPE_LOGIC_RULE OR nPresentationFlag = FLAG_FREEFORM_RULE OR
4154      nRuleOperator = RULE_OPERATOR_DEFAULTS)THEN
4155 
4156     nRuleType := RULE_TYPE_LOGIC_RULE;
4157 
4158     IF(NOT HAS_LOGICAL_VALUE(jAntecedentRoot))THEN
4159       nParam := jAntecedentRoot;
4160       IF(v_tExprPsNodeId(nParam) IS NULL)THEN
4161         localString := NULL;
4162       ELSE
4163         localString := glName(glIndexByPsNodeId(v_tExprPsNodeId(nParam)));
4164       END IF;
4165 
4166       RAISE CZ_R_LOGIC_RULE_WRONG_FEAT;
4167     END IF;
4168 
4169     IF(NOT HAS_LOGICAL_VALUE(jConsequentRoot))THEN
4170       nParam := jConsequentRoot;
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     GENERATE_LOGIC_RULE;
4181 
4182   ELSIF(RuleTemplateType = RULE_TYPE_COMPARISON_RULE)THEN
4183 
4184     nRuleType := RULE_TYPE_COMPARISON_RULE;
4185     GENERATE_COMPARISON_RULE;
4186 
4187   ELSE
4188 
4189     RAISE CZ_R_UNKNOWN_RULE_TYPE;
4190   END IF;
4191  RETURN v_return;
4192 END;
4193 ---------------------------------------------------------------------------------------
4194 FUNCTION GENERATE_NUMERIC_TREE(j IN PLS_INTEGER) RETURN tStringArray IS
4195   v_return  tStringArray;
4196 BEGIN
4197 
4198   IF((NOT v_ChildrenIndex.EXISTS(v_tExprId(j))) OR v_NumberOfChildren(v_tExprId(j)) <> 2)THEN
4199     RAISE CZ_R_INVALID_NUMERIC_RULE;
4200   END IF;
4201 
4202   nRuleType := RULE_TYPE_NUMERIC_RULE;
4203 
4204   nRuleOperator := v_tExprSubtype(j);
4205   jAntecedentRoot := v_ChildrenIndex(v_tExprId(j));
4206   jConsequentRoot := jAntecedentRoot + 1;
4207 
4208   v_tExprParentId(jAntecedentRoot) := NULL;
4209   v_tExprParentId(jConsequentRoot) := NULL;
4210 
4211   --High-level numeric rule validation section.
4212   --Make sure participating features have correct types.
4213 
4214   FOR i IN expressionStart..expressionEnd LOOP
4215     IF(v_tExprPsNodeId(i) IS NOT NULL)THEN
4216 
4217       localMinimum := glIndexByPsNodeId(v_tExprPsNodeId(i));
4218 
4219       IF(glPsNodeType(localMinimum) = PS_NODE_TYPE_FEATURE AND
4220          glFeatureType(localMinimum) = PS_NODE_FEATURE_TYPE_STRING)THEN
4221 
4222          nParam := i;
4223          RAISE CZ_R_NUMERIC_RULE_WRONG_FEAT;
4224        END IF;
4225 
4226        IF(i = jConsequentRoot AND trackableAncestor.EXISTS(v_tExprPsNodeId(i)))THEN
4227 
4228           --This node is an ancestor of a BOM trackable item. It should be prohibited from
4229           --participating on the RHS of a numeric rule.
4230 
4231           nParam := glIndexByPsNodeId(v_tExprPsNodeId(i));
4232           RAISE CZ_R_TRACKABLE_ANCESTOR;
4233         END IF;
4234     END IF;
4235   END LOOP;
4236 
4237   GENERATE_NUMERIC_RULE;
4238   RETURN v_return;
4239 END;
4240 ---------------------------------------------------------------------------------------
4241 FUNCTION GENERATE_TEMPLATE_APPLICATION(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER)
4242 RETURN tStringArray IS
4243 
4244   v_return         tStringArray;
4245   h_mapExprId      tIntegerArray;
4246 
4247   jdef             PLS_INTEGER;
4248   templateStart    PLS_INTEGER;
4249   templateEnd      PLS_INTEGER;
4250   v_index          PLS_INTEGER;
4251 
4252 ---------------------------------------------------------------------------------------
4253 PROCEDURE READ_TEMPLATE(p_template_id IN NUMBER) IS
4254 
4255   --These are local arrays used only to transfer data to the relevant expression arrays.
4256 
4257   v_NodeId          tExplNodeId;
4258   v_Type            tExprType;
4259   v_Subtype         tExprSubtype;
4260   v_Id              tExprId;
4261   v_ParentId        tExprParentId;
4262   v_TemplateId      tExprTemplateId;
4263   v_ExpressId       tExpressId;
4264   v_PsNodeId        tExplNodeId;
4265   v_DataValue       tExprDataValue;
4266   v_PropertyId      tExprPropertyId;
4267   v_ArgumentIndex   tExprArgumentIndex;
4268   v_ArgumentName    tExprArgumentName;
4269   v_ConsequentFlag  tConsequentFlag;
4270   v_DataNumValue    tExprDataNumValue;
4271   v_DataType        tExprDataType;
4272 
4273 BEGIN
4274 
4275 nDebug := 8010100;
4276 
4277   IF(NOT memoryTemplateStart.EXISTS(p_template_id))THEN
4278 
4279     SELECT model_ref_expl_id, expr_type, expr_node_id, expr_parent_id, template_id,
4280            express_id, expr_subtype, ps_node_id, data_value, property_id, argument_index,
4281            argument_name, consequent_flag, data_num_value, data_type
4282     BULK COLLECT INTO v_NodeId, v_Type, v_Id, v_ParentId, v_TemplateId,
4283                       v_ExpressId, v_Subtype, v_PsNodeId, v_DataValue, v_PropertyId, v_ArgumentIndex,
4284                       v_ArgumentName, v_ConsequentFlag, v_DataNumValue, v_DataType
4285       FROM cz_expression_nodes
4286      WHERE rule_id = p_template_id
4287        AND expr_type <> EXPR_NODE_TYPE_PUNCT
4288        AND deleted_flag = FLAG_NOT_DELETED
4289      ORDER BY expr_parent_id, seq_nbr;
4290 
4291 nDebug := 8010101;
4292 
4293     IF(v_Id.COUNT = 0)THEN
4294       RAISE CZ_R_TEMPLATE_UNKNOWN;
4295     END IF;
4296 
4297     v_index := v_tTmplId.COUNT + 1;
4298     memoryTemplateStart(p_template_id) := v_index;
4299 
4300 nDebug := 8010102;
4301 
4302     FOR i IN 1..v_Id.COUNT LOOP
4303 
4304       IF(v_DataNumValue(i) IS NOT NULL)THEN v_DataValue(i) := TO_CHAR(v_DataNumValue(i)); END IF;
4305 
4306       v_tTmplNodeId(v_index)        := v_NodeId(i);
4307       v_tTmplType(v_index)          := v_Type(i);
4308       v_tTmplSubtype(v_index)       := v_Subtype(i);
4309       v_tTmplId(v_index)            := v_Id(i);
4310       v_tTmplParentId(v_index)      := v_ParentId(i);
4311       v_tTmplTemplateId(v_index)    := v_TemplateId(i);
4312       v_tTmplExpressId(v_index)     := v_ExpressId(i);
4313       v_tTmplPsNodeId(v_index)      := v_PsNodeId(i);
4314       v_tTmplPropertyId(v_index)    := v_PropertyId(i);
4315       v_tTmplArgumentIndex(v_index) := v_ArgumentIndex(i);
4316       v_tTmplArgumentName(v_index)  := v_ArgumentName(i);
4317       v_tTmplConsequent(v_index)    := v_ConsequentFlag(i);
4318       v_tTmplDataValue(v_index)     := v_DataValue(i);
4319       v_tTmplDataType(v_index)      := v_DataType(i);
4320 
4321       v_index := v_index + 1;
4322     END LOOP;
4323 
4324     memoryTemplateEnd(p_template_id) := v_tTmplId.COUNT;
4325   END IF;
4326 END;
4327 ---------------------------------------------------------------------------------------
4328 FUNCTION COPY_EXPRESSION_NODE(j_from IN PLS_INTEGER, j_parent IN PLS_INTEGER)
4329 RETURN PLS_INTEGER IS
4330   j_to  PLS_INTEGER;
4331 BEGIN
4332 
4333 nDebug := 8010105;
4334 
4335    j_to := v_tExprId.COUNT + 1;
4336    nLocalExprId := nLocalExprId + 1;
4337 
4338    v_tExprId(j_to) := nLocalExprId;
4339    v_tExprParentId(j_to) := j_parent;
4340 
4341    v_tExplNodeId(j_to)       := v_tExplNodeId(j_from);
4342    v_tExprType(j_to)         := v_tExprType(j_from);
4343    v_tExprSubtype(j_to)      := v_tExprSubtype(j_from);
4344    v_tExprTemplateId(j_to)   := v_tExprTemplateId(j_from);
4345    v_tExprParamIndex(j_to)   := v_tExprParamIndex(j_from);
4346    v_tExprParSignature(j_to) := v_tExprParSignature(j_from);
4347    v_tExpressId(j_to)        := v_tExpressId(j_from);
4348    v_tExprPsNodeId(j_to)     := v_tExprPsNodeId(j_from);
4349    v_tExprDataValue(j_to)    := v_tExprDataValue(j_from);
4350    v_tExprDataType(j_to)     := v_tExprDataType(j_from);
4351    v_tExprPropertyId(j_to)   := v_tExprPropertyId(j_from);
4352    v_tConsequentFlag(j_to)   := v_tConsequentFlag(j_from);
4353    v_tExprArgumentName(j_to) := v_tExprArgumentName(j_from);
4354 
4355 nDebug := 8010106;
4356 
4357  RETURN j_to;
4358 END;
4359 ---------------------------------------------------------------------------------------
4360 PROCEDURE COPY_EXPRESSION_TREE(j_from IN PLS_INTEGER, j_parent IN PLS_INTEGER) IS
4361   j_child     PLS_INTEGER;
4362   j_children  tIntegerArray;
4363 BEGIN
4364 
4365 nDebug := 8010107;
4366 
4367   IF(v_ChildrenIndex.EXISTS(v_tExprId(j_from)))THEN
4368 
4369     j_child := v_ChildrenIndex(v_tExprId(j_from));
4370 
4371     WHILE(v_tExprParentId(j_child) = v_tExprId(j_from))LOOP
4372 
4373       j_children(j_child) := COPY_EXPRESSION_NODE(j_child, j_parent);
4374       j_child := j_child + 1;
4375     END LOOP;
4376 
4377     j_child := v_ChildrenIndex(v_tExprId(j_from));
4378 
4379     WHILE(v_tExprParentId(j_child) = v_tExprId(j_from))LOOP
4380 
4381       COPY_EXPRESSION_TREE(j_child, j_children(j_child));
4382       j_child := j_child + 1;
4383     END LOOP;
4384   END IF;
4385 
4386 nDebug := 8010108;
4387 
4388 END;
4389 ---------------------------------------------------------------------------------------
4390 BEGIN
4391 
4392   RuleTemplateType := v_tExprSubtype(j);
4393   READ_TEMPLATE(RuleTemplateType);
4394   templateStart := v_tExprId.COUNT + 1;
4395 
4396   FOR i IN memoryTemplateStart(RuleTemplateType)..memoryTemplateEnd(RuleTemplateType) LOOP
4397 
4398     IF(v_tTmplType(i) = EXPR_ARGUMENT AND v_tTmplArgumentIndex(i) IS NOT NULL)THEN
4399 
4400 nDebug := 8010109;
4401 
4402       --This is an argument, may correspond to a collection of paramaters in the template
4403       --application.
4404 
4405       jdef := 0;
4406 
4407       FOR ii IN expressionStart..expressionEnd LOOP
4408 
4409         IF(v_tExprParamIndex(ii) = v_tTmplArgumentIndex(i))THEN
4410 
4411           jdef := 1;
4412           v_index := v_tExprId.COUNT + 1;
4413           nLocalExprId := nLocalExprId + 1;
4414 
4415           v_tExprId(v_index)           := nLocalExprId;
4416           h_mapExprId(v_tExprId(ii))   := nLocalExprId;
4417 
4418           --If this entry gets overwritten many times, it is not a problem because in this case it
4419           --will never be used.
4420 
4421           h_mapExprId(v_tTmplId(i))    := nLocalExprId;
4422 
4423           v_tExprParentId(v_index)     := v_tTmplParentId(i);
4424           v_tExplNodeId(v_index)       := v_tExplNodeId(ii);
4425           v_tExprType(v_index)         := v_tExprType(ii);
4426           v_tExprSubtype(v_index)      := v_tExprSubtype(ii);
4427           v_tExprTemplateId(v_index)   := v_tExprTemplateId(ii);
4428           v_tExpressId(v_index)        := v_tExpressId(ii);
4429           v_tExprPsNodeId(v_index)     := v_tExprPsNodeId(ii);
4430           v_tExprDataValue(v_index)    := v_tExprDataValue(ii);
4431           v_tExprDataType(v_index)     := v_tExprDataType(ii);
4432           v_tExprPropertyId(v_index)   := v_tExprPropertyId(ii);
4433           v_tConsequentFlag(v_index)   := v_tConsequentFlag(ii);
4434           v_tExprArgumentName(v_index) := v_tExprArgumentName(ii);
4435           v_tExprParamIndex(v_index)   := v_tExprParamIndex(ii);
4436           v_tExprParSignature(v_index) := v_tExprParSignature(ii);
4437 
4438           IF(v_tExprType(v_index) = EXPR_TEMPLATE)THEN v_tExprType(v_index) := EXPR_OPERATOR; END IF;
4439         END IF;
4440       END LOOP;
4441 
4442       --No parameter was found for this argument - incomplete rule.
4443 
4444       IF(jdef = 0)THEN RAISE CZ_R_INCORRECT_NODE_ID; END IF;
4445     ELSE
4446 
4447 nDebug := 8010110;
4448 
4449       --This is a regular node in the template definition, just copy.
4450 
4451       v_index := v_tExprId.COUNT + 1;
4452       nLocalExprId := nLocalExprId + 1;
4453 
4454       v_tExprId(v_index)           := nLocalExprId;
4455       h_mapExprId(v_tTmplId(i))    := nLocalExprId;
4456 
4457       v_tExprParentId(v_index)     := v_tTmplParentId(i);
4458       v_tExplNodeId(v_index)       := v_tTmplNodeId(i);
4459       v_tExprType(v_index)         := v_tTmplType(i);
4460       v_tExprSubtype(v_index)      := v_tTmplSubtype(i);
4461       v_tExprTemplateId(v_index)   := v_tTmplTemplateId(i);
4462       v_tExpressId(v_index)        := v_tTmplExpressId(i);
4463       v_tExprPsNodeId(v_index)     := v_tTmplPsNodeId(i);
4464       v_tExprDataValue(v_index)    := v_tTmplDataValue(i);
4465       v_tExprDataType(v_index)     := v_tTmplDataType(i);
4466       v_tExprPropertyId(v_index)   := v_tTmplPropertyId(i);
4467       v_tConsequentFlag(v_index)   := v_tTmplConsequent(i);
4468       v_tExprArgumentName(v_index) := v_tTmplArgumentName(i);
4469     END IF;
4470   END LOOP;
4471 
4472 nDebug := 8010111;
4473 
4474   templateEnd := v_tExprId.COUNT;
4475 
4476   FOR i IN templateStart..templateEnd LOOP
4477 
4478     IF(v_tExprParentId(i) IS NOT NULL)THEN
4479 
4480       IF(NOT h_mapExprId.EXISTS(v_tExprParentId(i)))THEN RAISE CZ_R_INCORRECT_NODE_ID; END IF;
4481       v_tExprParentId(i) := h_mapExprId(v_tExprParentId(i));
4482     END IF;
4483   END LOOP;
4484 
4485 nDebug := 8010112;
4486 
4487   FOR i IN expressionStart..expressionEnd LOOP
4488 
4489     IF(h_mapExprId.EXISTS(v_tExprId(i)))THEN
4490 
4491       COPY_EXPRESSION_TREE(i, h_mapExprId(v_tExprId(i)));
4492     END IF;
4493   END LOOP;
4494 
4495   expressionStart := templateStart;
4496   expressionEnd := v_tExprId.COUNT;
4497 
4498 nDebug := 8010114;
4499 
4500   --We need to populate all the auxiliary arrays because now this is the expression we will be
4501   --processing. We don't really have to empty these arrays.
4502 
4503   v_IndexByExprNodeId.DELETE;
4504   v_NumberOfChildren.DELETE;
4505   v_ChildrenIndex.DELETE;
4506 
4507   FOR i IN expressionStart..expressionEnd LOOP
4508 
4509     v_tExprSubtype(i) := v_tExprTemplateId(i);
4510 
4511     --Add the indexing option.
4512 
4513     v_IndexByExprNodeId(v_tExprId(i)) := i;
4514 
4515     IF(v_tExprParentId(i) IS NOT NULL)THEN
4516 
4517       IF(v_NumberOfChildren.EXISTS(v_tExprParentId(i)))THEN
4518         v_NumberOfChildren(v_tExprParentId(i)) := v_NumberOfChildren(v_tExprParentId(i)) + 1;
4519       ELSE
4520         v_NumberOfChildren(v_tExprParentId(i)) := 1;
4521       END IF;
4522 
4523       IF(NOT v_ChildrenIndex.EXISTS(v_tExprParentId(i)))THEN
4524         v_ChildrenIndex(v_tExprParentId(i)) := i;
4525       END IF;
4526 
4527     ELSE
4528 
4529       --This is the root of the exploded template application expression tree.
4530 
4531       jdef := i;
4532     END IF;
4533 
4534 nDebug := 8010115;
4535 
4536   END LOOP;
4537 
4538 nDebug := 8010116;
4539 
4540   v_return := GENERATE_EXPRESSION(jdef, ListType);
4541   RETURN v_return;
4542 END;
4543 ---------------------------------------------------------------------------------------
4544 FUNCTION LOOKUP_ARGUMENT(j IN PLS_INTEGER) RETURN PLS_INTEGER IS
4545   argIndex  PLS_INTEGER := 0;
4546 BEGIN
4547 
4548   IF(parameterScope.COUNT = 0)THEN
4549     RAISE CZ_R_EMPTY_PARAMETER_SCOPE;
4550   END IF;
4551 
4552   FOR i IN 1..parameterName.COUNT LOOP
4553     IF(parameterName(i) = v_tExprArgumentName(j))THEN argIndex := i; EXIT; END IF;
4554   END LOOP;
4555 
4556   IF(argIndex = 0)THEN
4557     RAISE CZ_R_PARAMETER_NOT_FOUND;
4558   END IF;
4559 
4560  RETURN argIndex;
4561 END;
4562 ---------------------------------------------------------------------------------------
4563 FUNCTION GENERATE_ARGUMENT(j IN PLS_INTEGER, ListType IN OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
4564   v_return  tStringArray;
4565   argIndex  PLS_INTEGER := 0;
4566 BEGIN
4567 
4568 nDebug := 7004010;
4569 
4570   --The procedure can be called with a particular ListType to get a specific field from the
4571   --parameter scope.
4572   --Call with ListType = 0 to get the data type from cz_expression_nodes.
4573   --When called with ListType NULL, generate name or return value field.
4574 
4575   --Bug #4681261 - with re-using of temporary tables, we cannot use stored generated names
4576   --anymore because these names depend not only on ps_node_id, model_ref_expl_id but also
4577   --on where the rule is assined. Therefore need to generate the name here instead of in
4578   --generate_iterator.
4579 
4580   argIndex := LOOKUP_ARGUMENT(j);
4581 
4582   v_tExprPsNodeId(j) := parameterScope(argIndex).node_id;
4583   v_tExplNodeId(j) := parameterScope(argIndex).node_id_ex;
4584 
4585   --If this is a node, generate name here.
4586 
4587   IF(v_tExprPsNodeId(j) IS NOT NULL AND v_tExplNodeId(j) IS NOT NULL AND
4588      parameterScope(argIndex).node_value IS NULL AND parameterScope(argIndex).node_obj IS NULL)THEN
4589 
4590        v_return(1) := GENERATE_NAME_EXPL(v_tExplNodeId(j), v_tExprPsNodeId(j));
4591        parameterScope(argIndex).node_value := v_return(1);
4592        parameterScope(argIndex).node_obj := v_return(1);
4593   END IF;
4594 
4595   IF(ListType = DATA_TYPE_VOID)THEN ListType := v_tExprDataType(j); END IF;
4596   IF(ListType IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL, DATA_TYPE_BOOLEAN, DATA_TYPE_TEXT))THEN
4597 
4598     v_return(1) := parameterScope(argIndex).node_value;
4599   ELSIF(ListType = DATA_TYPE_NODE)THEN
4600 
4601     v_return(1) := parameterScope(argIndex).node_id;
4602   ELSIF(ListType = DATA_TYPE_VARIANT)THEN
4603 
4604     v_return(1) := parameterScope(argIndex).node_obj;
4605   ELSE
4606 
4607     v_return(1) := parameterScope(argIndex).node_value;
4608   END IF;
4609 
4610 nDebug := 7004019;
4611 
4612   RETURN v_return;
4613 END;
4614 ---------------------------------------------------------------------------------------
4615 FUNCTION GENERATE_FORALL(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tIteratorArray;
4616 ---------------------------------------------------------------------------------------
4617 FUNCTION GENERATE_REFNODE(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
4618   v_children    tIntegerArray;
4619   v_object      VARCHAR2(128);
4620   nodeChild     PLS_INTEGER;
4621   featChild     PLS_INTEGER;
4622   featPsNodeId  NUMBER; --kdande; Bug 6881902; 11-Mar-2008
4623   LocalType     PLS_INTEGER;
4624   IsNumeric     PLS_INTEGER;
4625   IsNotZero     PLS_INTEGER;
4626   nCheck        NUMBER;
4627   countTrue     PLS_INTEGER := 0;
4628   countFalse    PLS_INTEGER := 0;
4629   v_actual      VARCHAR2(16) := ' ';
4630   v_return      tStringArray;
4631   v_propval     tStringArray;
4632   v_psnode      tStringArray;
4633   CurrentId     PLS_INTEGER;
4634   nodeId        NUMBER; --jonatara:bug7041718
4635   v_sysprop     PLS_INTEGER;
4636   v_mutable     VARCHAR2(1);
4637   v_collection  VARCHAR2(1);
4638   v_context     PLS_INTEGER;
4639 BEGIN
4640 
4641 nDebug := 7004070;
4642 
4643  CurrentId := v_tExprId(j);
4644  nodeChild := v_ChildrenIndex(CurrentId);
4645  nLocalDefaults := nLocalDefaults + 1;
4646 
4647  IF(v_tExprType(j) = EXPR_ARGUMENT)THEN
4648 
4649    --This is an argument, we assume that it is of type 'node'.
4650 
4651    LocalType := DATA_TYPE_NODE;
4652    v_return := GENERATE_ARGUMENT(j, LocalType);
4653 
4654  ELSE
4655 
4656    --It's not an argument, so it's a ps_node.
4657 
4658    v_return(1) := TO_CHAR(v_tExprPsNodeId(j));
4659  END IF;
4660 
4661  nodeId := v_return(1);
4662 
4663  WHILE(v_tExprParentId.EXISTS(nodeChild) AND v_tExprParentId(nodeChild) = CurrentId)LOOP
4664    IF(v_tExplNodeId(nodeChild) IS NULL OR v_tExplNodeId(nodeChild) = -1 OR
4665 
4666       --Bug #3821827, caused by a corruption, when the explosion_id value was neither NULL or -1,
4667       --but was just some incorrect value when it is expected to be NULL.
4668 
4669       (NOT v_NodeLogicLevel.EXISTS(v_tExplNodeId(nodeChild))))THEN
4670 
4671      v_tExplNodeId(nodeChild) := v_ExplByPsNodeId(nodeId);
4672    END IF;
4673 
4674    IF(h_SeededName.EXISTS(v_tExprSubtype(nodeChild)) AND h_SeededName(v_tExprSubtype(nodeChild)) = RULE_SYS_PROP_SELECTION)THEN
4675 
4676      featChild := v_ChildrenIndex(CurrentId);
4677      featPsNodeId := v_return(1);
4678      v_children := EXPAND_NODE_OPTIONAL(featPsNodeId);
4679      v_sysprop := nodeChild + 1;
4680      LocalType := DATA_TYPE_VOID;
4681      v_context := 1;
4682 
4683      IF(v_tExprParentId.EXISTS(v_sysprop) AND v_tExprParentId(v_sysprop) = CurrentId)THEN
4684 
4685        --The system property was explicitly specified.
4686 
4687 nDebug := 7004073;
4688 
4689        IF(v_tExprType(v_sysprop) = EXPR_NODE_TYPE_SYSPROP)THEN
4690          IF(NOT h_SeededName.EXISTS(v_tExprSubtype(v_sysprop)))THEN RAISE CZ_E_BAD_PROPERTY_TYPE; END IF;
4691 
4692          IF(NOT APPLICABLE_SYS_PROP(j, glPsNodeId(v_children(1)), v_tExprSubtype(v_sysprop)))THEN
4693 
4694            auxIndex := v_children(1);
4695            localString := h_ReportName(v_tExprSubtype(v_sysprop));
4696            RAISE CZ_R_INCOMPATIBLE_SYSPROP;
4697          END IF;
4698        END IF;
4699 
4700        v_tExplNodeId(v_sysprop) := v_ExplByPsNodeId(nodeId);
4701        v_context := 0;
4702      ELSE
4703 
4704        --This is Node.Selection(), the actual system property is not specified. It can be either .State()
4705        --or .Quantity() depending on the context.
4706 
4707        IF(COMPATIBLE_DATA_TYPES(GET_ARGUMENT_INFO(v_tExprParamIndex(j), v_tExprParSignature(j),
4708                                                   v_mutable, v_collection), DATA_TYPE_BOOLEAN))THEN
4709          --The context is boolean.
4710 
4711 nDebug := 7004071;
4712 
4713          IF(NOT APPLICABLE_SYS_PROP(j, NULL, RULE_SYS_PROP_STATE))THEN
4714 
4715            auxIndex := glIndexByPsNodeId(nodeId);
4716            localString := 'State';
4717            RAISE CZ_R_INCOMPATIBLE_SYSPROP;
4718          END IF;
4719 
4720          ListType := DATA_TYPE_BOOLEAN;
4721          v_return.DELETE;
4722          v_return(1) := GENERATE_NAME(j, nodeId);
4723 
4724          --This is Feature.Selection().State(), which in a boolean context is equivalent to Feature.
4725 
4726          EXIT;
4727        ELSE
4728 
4729          --The context is numeric.
4730 
4731 nDebug := 7004072;
4732 
4733          IF(NOT APPLICABLE_SYS_PROP(j, glPsNodeId(v_children(1)), RULE_SYS_PROP_QUANTITY))THEN
4734 
4735            auxIndex := v_children(1);
4736            localString := 'Quantity';
4737            RAISE CZ_R_INCOMPATIBLE_SYSPROP;
4738          END IF;
4739 
4740          LocalType := DATA_TYPE_DECIMAL;
4741        END IF;
4742      END IF;
4743 
4744      v_return.DELETE;
4745 
4746      IF(nRuleType = RULE_TYPE_NUMERIC_RULE AND v_context = 0 AND
4747         v_tExprType(v_sysprop) = EXPR_NODE_TYPE_SYSPROP AND
4748         h_SeededName(v_tExprSubtype(v_sysprop)) = RULE_SYS_PROP_STATE)THEN
4749 
4750        --This is Node.Selection().State() in a numeric rule, State() was explicitly specified.
4751        --Bugs #4198455, #4366598.
4752 
4753        v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
4754        vLogicLine := 'OBJECT ' || v_return(1) || NewLine;
4755        PACK;
4756 
4757        FOR i IN 1..v_children.COUNT LOOP
4758 
4759          vLogicLine := 'OBJECT ' || v_return(1) || '_' || TO_CHAR(i) || NewLine ||
4760                        'GS I ... ' || TO_CHAR(nReasonId) || NewLine ||
4761                        'GL' || OperatorLetters(OPERATOR_ANYOF) || GENERATE_NAME(j, glPsNodeId(v_children(i))) || NewLine ||
4762                        'GR' || OperatorLetters(OPERATOR_ANYOF) || v_return(1) || '_' || TO_CHAR(i) || NewLine;
4763          PACK;
4764 
4765          vLogicLine := 'INC ' || v_return(1) || '_' || TO_CHAR(i) || ' ' || v_return(1) ||
4766                           OperatorLiterals(OPERATOR_ROUND) || '... ' || TO_CHAR(nReasonId) || NewLine;
4767          PACK;
4768        END LOOP;
4769 
4770        RETURN v_return;
4771      END IF;
4772 
4773      FOR i IN 1..v_children.COUNT LOOP
4774 
4775        v_propval(1) := TO_CHAR(glPsNodeId(v_children(i)));
4776 
4777        IF(v_context = 1)THEN v_propval(1) := GENERATE_NAME(j, glPsNodeId(v_children(i)));
4778        ELSE v_propval := SYSTEM_PROPERTY_VALUE(v_sysprop, v_propval, LocalType); END IF;
4779        ListType := LocalType;
4780 
4781        BEGIN
4782          nCheck := TO_NUMBER(v_propval(1));
4783          IsNumeric := 1;
4784          IsNotZero := 1;
4785          IF(nCheck = 0)THEN
4786            IsNotZero := 0;
4787          END IF;
4788        EXCEPTION
4789          WHEN OTHERS THEN
4790            IsNumeric := 0;
4791            IsNotZero := 1;
4792        END;
4793 
4794        IF(LocalType IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL))THEN
4795 
4796          v_object := t_prefix || TO_CHAR(nLocalDefaults) || '_' || TO_CHAR(i);
4797 
4798          IF(IsNumeric = 1)THEN
4799 
4800             --If a number, we have to GATE it throught the real option. We will do
4801             --it even if the property value is 0 for consistency.
4802 
4803             vLogicLine := 'OBJECT ' || v_object || NewLine ||
4804                           'GS I ... ' || TO_CHAR(nReasonId) || NewLine ||
4805                           'GL' || OperatorLetters(OPERATOR_ANYOF) || GENERATE_NAME(featChild, glPsNodeId(v_children(i))) || NewLine ||
4806                           'GR' || OperatorLetters(OPERATOR_ANYOF) || v_object || NewLine;
4807          ELSE
4808 
4809             --If the property value is not numeric, then it is a "P_" name returned
4810             --as a result of Feat.#Selection.Count. In this case we have to GATE it
4811             --by making an INC from the real option. This prevents from propagating
4812             --when the option is FALSE.
4813 
4814             vLogicLine := 'OBJECT ' || v_object || NewLine ||
4815                           'INC ' || GENERATE_NAME(featChild, glPsNodeId(v_children(i))) || ' ' || v_object ||
4816                           OperatorLiterals(OPERATOR_NONE) ||
4817                           '... ' || TO_CHAR(nReasonId) || NewLine;
4818          END IF;
4819 
4820          PACK;
4821 
4822          IF(NOT v_return.EXISTS(1))THEN
4823 
4824            v_return(1) := t_prefix || TO_CHAR(nLocalDefaults);
4825            vLogicLine := 'TOTAL ' || v_return(1) || NewLine;
4826            PACK;
4827          END IF;
4828 
4829          --In any case we multiply the property count (a number if it's .property or
4830          --the actual option if it is .#Count) by the intermediate object (the gate)
4831          --which is only true if the option is true. That way if no options selected
4832          --the result will be UNKNOWN.
4833 
4834          IF(IsNumeric = 0)THEN
4835 
4836            --If the property is not numeric then we multiply by 1 because it is the
4837            --count of the option.
4838 
4839            vLogicLine := 'CONTRIBUTE ' || v_object || OperatorLiterals(OPERATOR_MULT) ||
4840                          '1 ' || v_return(1) || v_actual || '... ' || TO_CHAR(nReasonId) || NewLine;
4841 
4842          ELSIF(IsNotZero = 1)THEN
4843 
4844            --If the property is not zero we have to multiply the gate by the property.
4845 
4846            vLogicLine := 'CONTRIBUTE ' || v_object || OperatorLiterals(OPERATOR_MULT) ||
4847                          v_propval(1) || ' ' || v_return(1) || v_actual || '... ' || TO_CHAR(nReasonId) || NewLine;
4848 
4849          ELSE
4850 
4851            --If the property value is 0, we will subtract the gate from the gate. This
4852            --is required in order to propagate 0 only if the option is selected. If we
4853            --used "gate * 0" it would always propagate 0, even if the gate is UNKNOWN,
4854            --and we don't want that to happen.
4855 
4856            vLogicLine := 'CONTRIBUTE ' || v_object || OperatorLiterals(OPERATOR_SUB) ||
4857                          v_object || ' ' || v_return(1) || v_actual || '... ' || TO_CHAR(nReasonId) || NewLine;
4858 
4859          END IF;
4860          PACK;
4861 
4862        ELSE
4863 
4864          IF(LocalType <> DATA_TYPE_TEXT OR generateCompare = 1)THEN
4865 
4866             v_return(i) := GENERATE_NAME(featChild, glPsNodeId(v_children(i))) || PROPERTY_DELIMITER || v_propval(1);
4867          ELSE
4868            --The expression contained a Text property which is only allowed in a comparison expression.
4869            --A Text property is not allowed in the context of your expression. Rule '%RULENAME' in
4870            --Model '%MODELNAME' ignored.
4871 
4872             RAISE CZ_R_PROPERTY_NOT_ALLOWED;
4873          END IF;
4874        END IF;
4875      END LOOP;
4876 
4877      IF(LocalType = DATA_TYPE_BOOLEAN)THEN
4878 
4879        --The code inside this block has been changed as a fix for bug #1862896.
4880        --Start with creating gating objects and INC relations for all the extracted
4881        --options.
4882 
4883        FOR i IN 1..v_return.COUNT LOOP
4884 
4885          v_object := t_prefix || TO_CHAR(nLocalDefaults) || '_' || TO_CHAR(i);
4886          vLogicLine := 'OBJECT ' || v_object || NewLine ||
4887                        'INC ' || EXTRACT_PROPERTY_NODE(v_return(i)) || ' ' || v_object ||
4888                        OperatorLiterals(OPERATOR_ROUND) || '... ' || TO_CHAR(nReasonId) || NewLine;
4889 
4890          --We are going to calculate the counts of true/false options in order to decide whether
4891          --we need to include the unsatisfied message id in the following GS relations. First we
4892          --overwrite the concatenated name/property value string in v_return to be just property
4893          --value as we don't use the concatenated format of v_return in this branch anymore.
4894 
4895          v_return(i) := EXTRACT_PROPERTY_VALUE(v_return(i));
4896          IF(v_return(i) = BOOLEAN_TRUE_REPRESENTATION)THEN countTrue := countTrue + 1;
4897          ELSIF(v_return(i) = BOOLEAN_FALSE_REPRESENTATION)THEN countFalse := countFalse + 1;
4898          END IF;
4899 
4900          PACK;
4901        END LOOP;
4902 
4903        --This is the resulting object that will be returned. Any of the TRUE gating
4904        --objects requires this object, any of the FALSE gating objects negates it.
4905 
4906        v_object := t_prefix || TO_CHAR(nLocalDefaults);
4907        vLogicLine := 'OBJECT ' || v_object || NewLine;
4908 
4909        IF(countTrue > 0)THEN
4910 
4911          localString := NULL;
4912          IF(countTrue > 1)THEN localString := sUnsatisfiedId; END IF;
4913 
4914          vLogicLine := vLogicLine || 'GS R ' || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
4915                      'GL' || OperatorLetters(OPERATOR_ANYOF);
4916          PACK;
4917 
4918 nDebug := 8001156;
4919 
4920          --Generate the list of all the TRUE gating objects.
4921 
4922          FOR i IN 1..v_return.COUNT LOOP
4923 
4924            IF(v_return(i) = BOOLEAN_TRUE_REPRESENTATION)THEN
4925              vLogicLine := v_object || '_' || TO_CHAR(i) || ' ';
4926              PACK;
4927            END IF;
4928          END LOOP;
4929 
4930          vLogicLine := NewLine || 'GR' || OperatorLetters(OPERATOR_ANYOF) || v_object || NewLine;
4931        END IF;
4932 
4933        IF(countFalse > 0)THEN
4934 
4935          localString := NULL;
4936          IF(countFalse > 1)THEN localString := sUnsatisfiedId; END IF;
4937 
4938          vLogicLine := vLogicLine || 'GS N ' || localString || '... ' || TO_CHAR(nReasonId) || NewLine ||
4939                        'GL' || OperatorLetters(OPERATOR_ANYOF);
4940          PACK;
4941 
4942 nDebug := 8001157;
4943 
4944          --Generate the list of all the FALSE gating objects.
4945 
4946          FOR i IN 1..v_return.COUNT LOOP
4947 
4948            IF(v_return(i) = BOOLEAN_FALSE_REPRESENTATION)THEN
4949              vLogicLine := v_object || '_' || TO_CHAR(i) || ' ';
4950              PACK;
4951            END IF;
4952          END LOOP;
4953 
4954          vLogicLine := NewLine || 'GR' || OperatorLetters(OPERATOR_ANYOF) || v_object || NewLine;
4955        END IF;
4956        PACK;
4957 
4958        v_return.DELETE;
4959        v_return(1) := v_object;
4960 
4961      END IF;
4962 
4963      --We don't need to move on as we already processed the following expression node(s).
4964 
4965      EXIT;
4966    ELSE
4967 
4968      IF(v_tExprType(nodeChild) = EXPR_NODE_TYPE_SYSPROP)THEN
4969        IF(NOT h_SeededName.EXISTS(v_tExprSubtype(nodeChild)))THEN RAISE CZ_E_BAD_PROPERTY_TYPE; END IF;
4970 
4971        IF(NOT APPLICABLE_SYS_PROP(j, NULL, v_tExprSubtype(nodeChild)))THEN
4972 
4973          auxIndex := glIndexByPsNodeId(nodeId);
4974          localString := h_ReportName(v_tExprSubtype(nodeChild));
4975          RAISE CZ_R_INCOMPATIBLE_SYSPROP;
4976        END IF;
4977      END IF;
4978 
4979      v_propval := SYSTEM_PROPERTY_VALUE(nodeChild, v_return, ListType);
4980 
4981      IF(ListType = DATA_TYPE_TEXT)THEN
4982 
4983        --This is a direct user or system property of DATA_TYPE_TEXT. Currently we don't allow
4984        --any operations to work with strings other than the comparison operators, therefore we
4985        --are going from here back to the GENERATE_COMPARE procedure , which expects the output
4986        --to be a combination of the node's P_ name and the property value.
4987 
4988        --This whole IF block is a part of the fix for the bug #1706286.
4989 
4990        IF(generateCompare = 1)THEN
4991 
4992          FOR i IN 1..v_propval.COUNT LOOP
4993 
4994            v_return(i) := GENERATE_NAME(v_ChildrenIndex(CurrentId), v_return(i)) || PROPERTY_DELIMITER || v_propval(i);
4995          END LOOP;
4996        ELSIF(generateCollect = 1)THEN
4997 
4998          --Exclusion from the above comment: we can be generating the COLLECT expression. Such expression
4999          --can contain references to text properties to be used for comparison in the WHERE clause, but
5000          --at this time we do not know that they will be used in comparison. We need to just return the
5001          --value of the property.
5002 
5003          v_return := v_propval;
5004        ELSE
5005          --The expression contained a Text property which is only allowed in a comparison expression.
5006          --A Text property is not allowed in the context of your expression. Rule '%RULENAME' in
5007          --Model '%MODELNAME' ignored.
5008 
5009          RAISE CZ_R_PROPERTY_NOT_ALLOWED;
5010        END IF;
5011      ELSIF(ListType = DATA_TYPE_BOOLEAN AND v_tExprType(nodeChild) = EXPR_PROP)THEN
5012 
5013        --For boolean user properties we replace the 0/1 values with corresponding object names.
5014        --Bug #3371279.
5015 
5016        FOR i IN 1..v_propval.COUNT LOOP
5017          IF(v_propval(i) = BOOLEAN_TRUE_REPRESENTATION)THEN v_return(i) := ALWAYS_TRUE;
5018          ELSE v_return(i) := ALWAYS_FALSE; END IF;
5019        END LOOP;
5020      ELSE
5021 
5022        v_return := v_propval;
5023      END IF;
5024    END IF;
5025 
5026    nodeChild := nodeChild + 1;
5027  END LOOP;
5028 
5029 nDebug := 7004080;
5030 
5031  RETURN v_return;
5032 END;
5033 ---------------------------------------------------------------------------------------
5034 FUNCTION GENERATE_ITERATOR(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tIteratorArray IS
5035 
5036   v_return  tIteratorArray;
5037   v_iterin  tIteratorArray;
5038   nChild    PLS_INTEGER;
5039   nCount    PLS_INTEGER;
5040   nGrand    PLS_INTEGER;
5041   nType     PLS_INTEGER;
5042   v_result  tIntegerArray;
5043   v_record  tStringArray;
5044   nodeName  VARCHAR2(4000);
5045 
5046 BEGIN
5047 
5048 nDebug := 7004000;
5049 
5050   nChild := v_ChildrenIndex(v_tExprId(j));
5051 
5052   WHILE(v_tExprParentId(nChild) = v_tExprId(j))LOOP
5053 
5054     v_result.DELETE;
5055     v_record.DELETE;
5056     v_iterin.DELETE;
5057 
5058     nCount := v_return.COUNT + 1;
5059 
5060     IF(v_tExprType(nChild) = EXPR_PSNODE)THEN
5061       IF(v_ChildrenIndex.EXISTS(v_tExprId(nChild)))THEN
5062         IF(HAS_OPTIONS_APPLIED(nChild))THEN
5063 
5064           IF(v_NumberOfChildren(v_tExprId(j)) = 1)THEN
5065 
5066             temp_table_hash_key(forallLevel) := TO_CHAR(v_tExprPsNodeId(nChild)) || '-' || TO_CHAR(v_tExplNodeId(nChild));
5067             temp_cmpt_hash_key(compatLevel) := temp_table_hash_key(forallLevel);
5068           END IF;
5069 
5070           v_result := EXPAND_NODE(nChild);
5071 
5072           FOR i IN 1..v_result.COUNT LOOP
5073 
5074             --Bug #4681261 - with re-using of temporary tables, we cannot use stored generated names
5075             --anymore because these names depend not only on ps_node_id, model_ref_expl_id but also
5076             --on where the rule is assined. Name will be generated in generate_argument.
5077             --nodeName := GENERATE_NAME_EXPL(v_ExplByPsNodeId(v_result(i)), v_result(i));
5078 
5079             v_return(nCount).node_type := DATA_TYPE_NODE;
5080             v_return(nCount).node_value := NULL;
5081             v_return(nCount).node_id := v_result(i);
5082             v_return(nCount).node_obj := NULL;
5083             v_return(nCount).node_id_ex := v_ExplByPsNodeId(v_result(i));
5084 
5085             nCount := nCount + 1;
5086           END LOOP;
5087         ELSE
5088 
5089           v_record := GENERATE_REFNODE(nChild, ListType);
5090 
5091           FOR i IN 1..v_record.COUNT LOOP
5092 
5093             v_return(nCount).node_type := ListType;
5094             v_return(nCount).node_value := v_record(i);
5095             v_return(nCount).node_id := NULL;
5096             v_return(nCount).node_obj := v_record(i);
5097 
5098             nCount := nCount + 1;
5099           END LOOP;
5100         END IF;
5101       ELSE
5102 
5103         --Bug #4681261 - with re-using of temporary tables, we cannot use stored generated names
5104         --anymore because these names depend not only on ps_node_id, model_ref_expl_id but also
5105         --on where the rule is assined. Name will be generated in generate_argument.
5106         --nodeName := GENERATE_NAME(nChild, v_tExprPsNodeId(nChild));
5107 
5108         v_return(nCount).node_type := DATA_TYPE_NODE;
5109         v_return(nCount).node_value := NULL;
5110         v_return(nCount).node_id := v_tExprPsNodeId(nChild);
5111         v_return(nCount).node_obj := NULL;
5112         v_return(nCount).node_id_ex := v_tExplNodeId(nChild);
5113       END IF;
5114     ELSIF(v_tExprType(nChild) = EXPR_LITERAL)THEN
5115 
5116       v_return(nCount).node_type := v_tExprDataType(nChild);
5117       v_return(nCount).node_value := v_tExprDataValue(nChild);
5118       v_return(nCount).node_id := NULL;
5119       v_return(nCount).node_obj := NULL;
5120 
5121     ELSIF(v_tExprType(nChild) = EXPR_OPERATOR AND v_tExprSubtype(nChild) = OPERATOR_OPTIONSOF)THEN
5122 
5123       nGrand := v_ChildrenIndex(v_tExprId(nChild));
5124 
5125       IF(v_NumberOfChildren(v_tExprId(j)) = 1)THEN
5126 
5127         temp_table_hash_key(forallLevel) := TO_CHAR(v_tExprPsNodeId(nGrand)) || '-' || TO_CHAR(v_tExplNodeId(nGrand));
5128         temp_cmpt_hash_key(compatLevel) := temp_table_hash_key(forallLevel);
5129       END IF;
5130 
5131       v_result := EXPAND_NODE(nChild);
5132 
5133       FOR i IN 1..v_result.COUNT LOOP
5134 
5135         --Bug #4681261 - with re-using of temporary tables, we cannot use stored generated names
5136         --anymore because these names depend not only on ps_node_id, model_ref_expl_id but also
5137         --on where the rule is assined. Name will be generated in generate_argument.
5138         --nodeName := GENERATE_NAME_EXPL(v_ExplByPsNodeId(v_result(i)), v_result(i));
5139 
5140         v_return(nCount).node_type := DATA_TYPE_NODE;
5141         v_return(nCount).node_value := NULL;
5142         v_return(nCount).node_id := v_result(i);
5143         v_return(nCount).node_obj := NULL;
5144         v_return(nCount).node_id_ex := v_ExplByPsNodeId(v_result(i));
5145 
5146         nCount := nCount + 1;
5147       END LOOP;
5148 
5149     ELSIF(v_tExprType(nChild) IN (EXPR_FORALL, EXPR_FORALL_DISTINCT))THEN
5150 
5151       v_iterin := GENERATE_FORALL(nChild, ListType);
5152 
5153       FOR i IN 1..v_iterin.COUNT LOOP
5154 
5155         v_return(nCount) := v_iterin(i);
5156         nCount := nCount + 1;
5157       END LOOP;
5158     ELSE
5159 
5160       v_record := GENERATE_EXPRESSION(nChild, ListType);
5161 
5162       IF(v_tExprPsNodeId(nChild) IS NOT NULL)THEN
5163 
5164          nType := v_tExprType(nChild);
5165          v_tExprType(nChild) := EXPR_PSNODE;
5166 
5167          v_iterin := GENERATE_ITERATOR(j, ListType);
5168          v_tExprType(nChild) := nType;
5169 
5170          FOR i IN 1..v_iterin.COUNT LOOP
5171 
5172            v_return(nCount) := v_iterin(i);
5173            nCount := nCount + 1;
5174          END LOOP;
5175 
5176       ELSE
5177 
5178          FOR i IN 1..v_record.COUNT LOOP
5179 
5180            v_return(nCount).node_type := DATA_TYPE_VARIANT;
5181            v_return(nCount).node_value := v_record(i);
5182 
5183            --If it's a 'P_' object, the node_id should still be populated, otherwise it will be impossible
5184            --to use properties of this objects.
5185 
5186            v_return(nCount).node_id := NULL;
5187            v_return(nCount).node_obj := v_record(i);
5188 
5189            nCount := nCount + 1;
5190          END LOOP;
5191       END IF;
5192     END IF;
5193 
5194     nChild := nChild + 1;
5195   END LOOP;
5196 
5197 nDebug := 7004009;
5198 
5199   RETURN v_return;
5200 END;
5201 ---------------------------------------------------------------------------------------
5202 FUNCTION EXTRACT_PROPERTY_INFO(j IN PLS_INTEGER, PropName OUT NOCOPY VARCHAR2,
5203                                DataType OUT NOCOPY PLS_INTEGER,
5204                                PropertyType OUT NOCOPY PLS_INTEGER)
5205 RETURN PLS_INTEGER IS
5206   propChild   PLS_INTEGER := v_ChildrenIndex(v_tExprId(j));
5207   propertyId  PLS_INTEGER;
5208   tempVal NUMBER := -1;
5209 BEGIN
5210 
5211 nDebug := 7004040;
5212 
5213   PropertyType := 0;
5214 
5215   WHILE(v_tExprParentId(propChild) = v_tExprId(j) AND
5216         v_tExprPropertyId(propChild) IS NULL AND v_tExprType(propChild) NOT IN
5217         (EXPR_NODE_TYPE_SYSPROP, EXPR_LITERAL))LOOP
5218        propChild := propChild + 1;
5219   END LOOP;
5220 
5221 nDebug := 7004042;
5222 
5223   IF(v_tExprParentId(propChild) = v_tExprId(j))THEN
5224     BEGIN
5225       IF(v_tExprPropertyId(propChild) IS NOT NULL)THEN
5226 
5227         SELECT data_type, name INTO DataType, PropName
5228           FROM cz_properties
5229            WHERE deleted_flag = FLAG_NOT_DELETED
5230              AND property_id = v_tExprPropertyId(propChild);
5231 nDebug := 7004043;
5232 
5233         RETURN v_tExprPropertyId(propChild);
5234 
5235       ELSIF(v_tExprType(propChild) = EXPR_LITERAL)THEN
5236 
5237         SELECT property_id, data_type, name INTO propertyId, DataType, PropName
5238           FROM cz_properties
5239          WHERE deleted_flag = FLAG_NOT_DELETED
5240            AND name = v_tExprDataValue(propChild);
5241 
5242         RETURN propertyId;
5243       ELSE
5244 
5245         PropertyType := 1;
5246         WHILE(v_tExprParentId(propChild) = v_tExprId(j) AND
5247               h_SeededName(v_tExprSubtype(propChild)) = RULE_SYS_PROP_PARENT)LOOP
5248 
5249           propChild := propChild + 1;
5250           PropertyType := PropertyType + 1;
5251         END LOOP;
5252         IF(v_tExprParentId(propChild) = v_tExprId(j))THEN
5253 
5254           SELECT data_type, name INTO DataType, PropName
5255             FROM cz_system_properties_v
5256            WHERE rule_id = v_tExprSubtype(propChild);
5257 
5258           RETURN v_tExprSubtype(propChild);
5259         ELSE
5260           RAISE CZ_E_INCORRECT_PROPERTY;
5261         END IF;
5262       END IF;
5263     EXCEPTION
5264       WHEN OTHERS THEN
5265         RAISE CZ_E_INCORRECT_PROPERTY;
5266     END;
5267   ELSE
5268     RAISE CZ_E_INCORRECT_PROPERTY;
5269   END IF;
5270 nDebug := 7004049;
5271 END;
5272 ---------------------------------------------------------------------------------------
5273 FUNCTION GENERATE_FORALL_(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tIteratorArray IS
5274 
5275   iteratorIndex    tIntegerArray;
5276   iterator         tIteratorArray;
5277   whereIndex       PLS_INTEGER := 0;
5278   expressionIndex  PLS_INTEGER := 0;
5279   nChild           PLS_INTEGER;
5280   nCount           PLS_INTEGER;
5281   v_property_id    tIntegerArray;
5282   v_data_type      tIntegerArray;
5283   v_prop_name      tStringArray;
5284   v_return         tIteratorArray;
5285   v_express        tStringArray;
5286   SQLCreate        VARCHAR2(8000);
5287   SQLInsert        VARCHAR2(8000);
5288   SQLValues        VARCHAR2(8000);
5289   SQLSelect        VARCHAR2(8000);
5290   SQLFrom          VARCHAR2(8000);
5291   SQLWhere         VARCHAR2(8000) := NULL;
5292   tableName        VARCHAR2(4000);
5293   tableAlias       VARCHAR2(4000);
5294   nodeId           NUMBER; --jonatara:bug7041718
5295   itemId           PLS_INTEGER;
5296   propertyId       PLS_INTEGER;
5297   c_values         refCursor;
5298   v_cursor         NUMBER;
5299   propertyVal      VARCHAR2(4000);
5300   localNumber      NUMBER;
5301   localString      VARCHAR2(4000);
5302   bindValue        tStringArray;
5303   v_flag           tIntegerArray;
5304   v_stack_start    PLS_INTEGER;
5305   v_stack_end      PLS_INTEGER;
5306   v_value_exists   PLS_INTEGER := 0;
5307 
5308   bind_node_id     DBMS_SQL.NUMBER_TABLE;
5309   bind_node_id_ex  DBMS_SQL.NUMBER_TABLE;
5310   bind_node_type   DBMS_SQL.NUMBER_TABLE;
5311   bind_node_value  DBMS_SQL.VARCHAR2_TABLE;
5312   bind_node_obj    DBMS_SQL.VARCHAR2_TABLE;
5313 
5314   TYPE bind_value_table IS TABLE OF DBMS_SQL.VARCHAR2_TABLE INDEX BY BINARY_INTEGER;
5315   bind_values      bind_value_table;
5316   arg_table_name   temp_table_hash_type;
5317   hash_propval_key VARCHAR2(4000);
5318 ---------------------------------------------------------------------------------------
5319 PROCEDURE EXPLORE_WHERE(j IN PLS_INTEGER, v_argument IN VARCHAR2) IS
5320   nChild      PLS_INTEGER;
5321   nCount      PLS_INTEGER;
5322   propertyId  PLS_INTEGER;
5323   dataType    PLS_INTEGER;
5324   propType    PLS_INTEGER;
5325   propName    cz_properties.name%TYPE;
5326 BEGIN
5327 
5328 nDebug := 7004020;
5329 
5330   nChild := v_ChildrenIndex(v_tExprId(j));
5331 
5332   WHILE(v_tExprParentId(nChild) = v_tExprId(j))LOOP
5333 
5334     nCount := v_property_id.COUNT + 1;
5335 
5336     IF(v_ChildrenIndex.EXISTS(v_tExprId(nChild)))THEN
5337       IF(v_tExprType(nChild) = EXPR_ARGUMENT AND v_tExprArgumentName(nChild) = v_argument)THEN
5338 
5339         propertyId := EXTRACT_PROPERTY_INFO(nChild, propName, dataType, propType);
5340 
5341 	nDebug := 7004021;
5342 
5343         IF(NOT v_flag.EXISTS(propertyId))THEN
5344 
5345           v_property_id(nCount) := propertyId;
5346           v_data_type(nCount) := dataType;
5347           v_prop_name(nCount) := propName;
5348           v_flag(propertyId) := propType;
5349         END IF;
5350       ELSE
5351 
5352         EXPLORE_WHERE(nChild, v_argument);
5353       END IF;
5354     END IF;
5355     nChild := nChild + 1;
5356   END LOOP;
5357 
5358 nDebug := 7004029;
5359 END;
5360 ---------------------------------------------------------------------------------------
5361 --This function finds every reference to iterators in the FORALL WHERE clause, replaces
5362 --arguments with <table_alias>.value string and reference nodes with <table_alias>.i_<property_id>
5363 --string. It returns the generated SQL WHERE clause of the SELECT statement. All the literal
5364 --values are collected in an array for later binding.
5365 
5366 FUNCTION EXAMINE_WHERE_CLAUSE(j IN PLS_INTEGER) RETURN VARCHAR2 IS
5367   argChild         PLS_INTEGER;
5368   propType         PLS_INTEGER;
5369   jChild           PLS_INTEGER;
5370   isLocal          PLS_INTEGER := 0;
5371   LocalType        PLS_INTEGER := DATA_TYPE_VOID;
5372   propName         cz_properties.name%TYPE;
5373   v_extern         tStringArray;
5374   v_quotes         VARCHAR2(2);
5375 BEGIN
5376 
5377 nDebug := 7004030;
5378 
5379   IF(v_tExprType(j) = EXPR_ARGUMENT)THEN
5380 
5381     --This is an argument. First of all, find out if it corresponds to one of the local iterators - only
5382     --in this case there will be a temporary table with the corresponding name. Otherwise, it can be an
5383     --external argument from an upper level FORALL. In this case we have to get the value from the
5384     --parameter scope and use it as a literal in the generated WHERE clause.
5385 
5386     FOR i IN 1..iteratorIndex.COUNT LOOP
5387 
5388       IF(v_tExprArgumentName(iteratorIndex(i)) = v_tExprArgumentName(j))THEN isLocal := 1; END IF;
5389     END LOOP;
5390 
5391     IF(isLocal = 1)THEN
5392 
5393       --This is an argument that corresponds to a local iterator.
5394 
5395       IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
5396 
5397         --Add <table_name>.value to the WHERE clause being generated.
5398 
5399         RETURN arg_table_name(v_tExprArgumentName(j)) || '.node_value';
5400       ELSE
5401 
5402         --Add <table_name>.i_<property_id> to the WHERE clause being generated.
5403         RETURN arg_table_name(v_tExprArgumentName(j)) || '.i_' ||
5404                TO_CHAR(EXTRACT_PROPERTY_INFO(j, propName, jChild, propType));
5405       END IF;
5406     ELSE
5407 
5408       --This is an external argument, must be in the parameter scope.
5409       --We assume that it is of type 'node'.
5410 
5411       v_extern := GENERATE_ARGUMENT(j, LocalType);
5412       IF(LocalType = DATA_TYPE_TEXT)THEN v_quotes := ''''; END IF;
5413 
5414       IF(v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
5415 
5416         RETURN v_quotes || PROPERTY_VALUE(v_ChildrenIndex(v_tExprId(j)), glIndexByPsNodeId(v_tExprPsNodeId(j)), LocalType) || v_quotes;
5417       ELSE
5418 
5419         RETURN v_quotes || v_extern(1) || v_quotes;
5420       END IF;
5421     END IF;
5422   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_NODE AND v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
5423 
5424     --Nodes can participate in the WHERE clause only with a property applied.
5425     --Bug #4648386.
5426 
5427     v_extern(1) := EXTRACT_PROPERTY_INFO(j, propName, jChild, propType);
5428     nDebug := 7004032;
5429     IF(jChild IN (DATATYPE_TRANSLATABLE_PROP, DATA_TYPE_TEXT))THEN v_quotes := ''''; END IF;
5430 
5431     IF(propType = 0)THEN
5432 
5433       RETURN v_quotes || PROPERTY_VALUE(v_ChildrenIndex(v_tExprId(j)), glIndexByPsNodeId(v_tExprPsNodeId(j)), LocalType) || v_quotes;
5434     ELSE
5435 
5436       RETURN v_quotes || STATIC_SYSPROP_VALUE(v_tExprPsNodeId(j), v_tExprPropertyId(j), propType) || v_quotes;
5437     END IF;
5438   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_LITERAL)THEN
5439 
5440     bindValue(bindValue.COUNT + 1) := v_tExprDataValue(j);
5441     RETURN ':x' || TO_CHAR(bindValue.COUNT);
5442 
5443   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_OPERATOR)THEN
5444 
5445     jChild := v_ChildrenIndex(v_tExprId(j));
5446 
5447     IF(v_tExprSubtype(j) = OPERATOR_TOTEXT)THEN
5448 
5449         --Added for the bug #5620750. Just need ignore the ToText operator to continue using
5450         --default type conversion.
5451 
5452         RETURN EXAMINE_WHERE_CLAUSE(jChild);
5453     END IF;
5454 
5455     IF(v_tExprParentId.EXISTS(jChild + 1) AND v_tExprParentId(jChild + 1)= v_tExprId(j))THEN
5456 
5457       IF(v_tExprSubtype(j) IN (OPERATOR_EQUALS,
5458                                OPERATOR_NOTEQUALS,
5459                                OPERATOR_EQUALS_INT,
5460                                OPERATOR_NOTEQUALS_INT,
5461                                OPERATOR_GT,
5462                                OPERATOR_LT,
5463                                OPERATOR_GE,
5464                                OPERATOR_LE,
5465                                OPERATOR_AND,
5466                                OPERATOR_OR))THEN
5467 
5468         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || OperatorLiterals(v_tExprSubtype(j)) ||
5469                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5470 
5471       ELSIF(v_tExprSubtype(j) = OPERATOR_CONCAT)THEN
5472 
5473         RETURN EXAMINE_WHERE_CLAUSE(jChild) || ' || ' || EXAMINE_WHERE_CLAUSE(jChild + 1);
5474 
5475       ELSIF(v_tExprSubtype(j) = OPERATOR_BEGINSWITH)THEN
5476 
5477         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
5478                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
5479 
5480       ELSIF(v_tExprSubtype(j) = OPERATOR_ENDSWITH)THEN
5481 
5482         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ''%'' || ' ||
5483                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5484 
5485       ELSIF(v_tExprSubtype(j) = OPERATOR_CONTAINS)THEN
5486 
5487         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ''%'' || ' ||
5488                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
5489 
5490       ELSIF(v_tExprSubtype(j) = OPERATOR_LIKE)THEN
5491 
5492         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
5493                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5494 
5495       ELSIF(v_tExprSubtype(j) = OPERATOR_MATCHES)THEN
5496 
5497         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
5498                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5499 
5500       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTBEGINWITH)THEN
5501 
5502         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ' ||
5503                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
5504 
5505       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTENDWITH)THEN
5506 
5507         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ''%'' || ' ||
5508                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5509 
5510       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTCONTAIN)THEN
5511 
5512         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ''%'' || ' ||
5513                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
5514 
5515       ELSIF(v_tExprSubtype(j) = OPERATOR_NOTLIKE)THEN
5516 
5517         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ' ||
5518                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
5519 
5520       ELSE
5521 
5522         RAISE CZ_E_UKNOWN_OPER_IN_COMPAT;
5523       END IF;
5524 
5525     ELSIF(v_tExprSubtype(j) = OPERATOR_NOT)THEN
5526 
5527       RETURN '(NOT ' || EXAMINE_WHERE_CLAUSE(jChild) || ')';
5528 
5529     ELSE
5530 
5531       RAISE CZ_E_WRONG_OPER_IN_COMPAT;
5532     END IF;
5533   ELSE
5534 
5535     RAISE CZ_R_WRONG_COMPAT_EXPRESSION;
5536   END IF;
5537 END;
5538 ---------------------------------------------------------------------------------------
5539 BEGIN
5540 
5541 nDebug := 7004100;
5542 
5543   nChild := v_ChildrenIndex(v_tExprId(j));
5544 
5545   WHILE(v_tExprParentId(nChild) = v_tExprId(j)) LOOP
5546     IF(v_tExprType(nChild) = EXPR_ITERATOR)THEN
5547 
5548       iteratorIndex(iteratorIndex.COUNT + 1) := nChild;
5549     ELSIF(v_tExprType(nChild) = EXPR_WHERE)THEN
5550 
5551       whereIndex := nChild;
5552     ELSE
5553 
5554       expressionIndex := nChild;
5555     END IF;
5556 
5557     nChild := nChild + 1;
5558   END LOOP;
5559 
5560   v_stack_start := parameterScope.COUNT + 1;
5561   v_stack_end := v_stack_start + iteratorIndex.COUNT - 1;
5562 
5563 nDebug := 7004101;
5564 
5565   FOR i IN 1..iteratorIndex.COUNT LOOP
5566 
5567     bind_node_id.DELETE;
5568     bind_node_id_ex.DELETE;
5569     bind_node_type.DELETE;
5570     bind_node_value.DELETE;
5571     bind_node_obj.DELETE;
5572     bind_values.DELETE;
5573 
5574     v_property_id.DELETE;
5575     v_data_type.DELETE;
5576     v_prop_name.DELETE;
5577     v_flag.DELETE;
5578 
5579     temp_table_hash_key(forallLevel) := NULL;
5580     tableAlias := 'T' || TO_CHAR(i);
5581 
5582     iterator.DELETE;
5583     iterator := GENERATE_ITERATOR(iteratorIndex(i), ListType);
5584 
5585     IF(whereIndex <> 0)THEN
5586       EXPLORE_WHERE(whereIndex, v_tExprArgumentName(iteratorIndex(i)));
5587     END IF;
5588 
5589     IF(temp_table_hash_key(forallLevel) IS NOT NULL)THEN
5590       FOR ii IN 1..v_property_id.COUNT LOOP
5591         temp_table_hash_key(forallLevel) := temp_table_hash_key(forallLevel) || '-' || TO_CHAR(v_property_id(ii));
5592       END LOOP;
5593     END IF;
5594 
5595 nDebug := 7004102;
5596 
5597     IF(temp_table_hash_key(forallLevel) IS NOT NULL AND temp_table_hash.EXISTS(temp_table_hash_key(forallLevel)))THEN
5598 
5599       tableName := temp_table_hash(temp_table_hash_key(forallLevel));
5600       arg_table_name(v_tExprArgumentName(iteratorIndex(i))) := tableAlias;
5601 
5602       IF(SQLSelect IS NULL)THEN SQLSelect := 'SELECT '; ELSE SQLSelect := SQLSelect || ', '; END IF;
5603       SQLSelect := SQLSelect || tableAlias || '.node_type, ' ||
5604                                 tableAlias || '.node_id, ' ||
5605                                 tableAlias || '.node_value, ' ||
5606                                 tableAlias || '.node_obj, ' ||
5607                                 tableAlias || '.node_id_ex';
5608       IF(SQLFrom IS NULL)THEN SQLFrom := ' FROM '; ELSE SQLFrom := SQLFrom || ', '; END IF;
5609       SQLFrom := SQLFrom || tableName || ' ' || tableAlias;
5610 
5611     ELSE
5612 
5613     tableName := 'G_' || TO_CHAR(table_name_generator);
5614     table_name_generator := table_name_generator + 1;
5615     arg_table_name(v_tExprArgumentName(iteratorIndex(i))) := tableAlias;
5616 
5617     IF(SQLSelect IS NULL)THEN SQLSelect := 'SELECT '; ELSE SQLSelect := SQLSelect || ', '; END IF;
5618     SQLSelect := SQLSelect || tableAlias || '.node_type, ' ||
5619                               tableAlias || '.node_id, ' ||
5620                               tableAlias || '.node_value, ' ||
5621                               tableAlias || '.node_obj, ' ||
5622                               tableAlias || '.node_id_ex';
5623     IF(SQLFrom IS NULL)THEN SQLFrom := ' FROM '; ELSE SQLFrom := SQLFrom || ', '; END IF;
5624     SQLFrom := SQLFrom || tableName || ' ' || tableAlias;
5625 
5626     SQLCreate := 'CREATE GLOBAL TEMPORARY TABLE ' || tableName ||
5627                  '(node_type NUMBER, node_id NUMBER, node_value VARCHAR2(' || TO_CHAR(MAXIMUM_INDEX_LENGTH) ||
5628                  '), node_obj VARCHAR2(' || TO_CHAR(MAXIMUM_INDEX_LENGTH) || '), node_id_ex NUMBER';
5629 
5630     FOR ii IN 1..v_property_id.COUNT LOOP
5631 
5632       SQLCreate := SQLCreate || ', i_' || TO_CHAR(v_property_id(ii));
5633 
5634       IF(v_data_type(ii) IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL))THEN
5635 
5636         SQLCreate := SQLCreate || ' NUMBER';
5637       ELSE
5638 
5639         SQLCreate := SQLCreate || ' VARCHAR2(' || TO_CHAR(MAXIMUM_INDEX_LENGTH) || ')';
5640       END IF;
5641     END LOOP;
5642 
5643     SQLCreate := SQLCreate || ') ON COMMIT PRESERVE ROWS';
5644 
5645 nDebug := 7004103;
5646 
5647     BEGIN
5648       EXECUTE IMMEDIATE SQLCreate;
5649     EXCEPTION
5650       WHEN OTHERS THEN
5651 
5652         --If the table already exists, truncate it, drop and try to create again.
5653 
5654         IF(SQLCODE = ORACLE_OBJECT_ALREADY_EXISTS)THEN
5655           EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || tableName;
5656           EXECUTE IMMEDIATE 'DROP TABLE ' || tableName;
5657           EXECUTE IMMEDIATE SQLCreate;
5658         ELSE
5659           RAISE;
5660         END IF;
5661     END;
5662 
5663     --The table is created, add its name to the delete list.
5664 
5665     temp_tables(temp_tables.COUNT + 1) := tableName;
5666 
5667 nDebug := 7004104;
5668 
5669     SQLInsert := 'INSERT INTO ' || tableName || '(node_type, node_id, node_value, node_obj, node_id_ex';
5670     SQLValues := ' VALUES (:y1, :y2, :y3, :y4, :y5';
5671 
5672     FOR ii IN 1..v_property_id.COUNT LOOP
5673 
5674       BEGIN
5675 
5676         EXECUTE IMMEDIATE 'CREATE INDEX ' || tableName || '_I' || TO_CHAR(ii) || ' ON ' || tableName ||
5677                           '(i_' || v_property_id(ii) || ')';
5678       EXCEPTION
5679         WHEN OTHERS THEN
5680           IF(SQLCODE <> ORACLE_OBJECT_ALREADY_EXISTS)THEN RAISE; END IF;
5681       END;
5682 
5683       SQLInsert := SQLInsert || ', i_' || TO_CHAR(v_property_id(ii));
5684       SQLValues := SQLValues || ', :x' || TO_CHAR(ii);
5685     END LOOP;
5686 
5687     SQLInsert := SQLInsert || ')';
5688     SQLValues := SQLValues || ')';
5689 
5690 nDebug := 7004105;
5691 
5692     FOR ii IN 1..iterator.COUNT LOOP
5693 
5694       IF(LENGTH(iterator(ii).node_value) > MAXIMUM_INDEX_LENGTH OR
5695          LENGTH(iterator(ii).node_obj) > MAXIMUM_INDEX_LENGTH)THEN
5696 
5697         --Bug #3416994. This structure is internally generated, so we give the 'internal error' message.
5698         RAISE CZ_R_TYPE_NO_PROPERTY;
5699       END IF;
5700 
5701       bind_node_id(ii) := iterator(ii).node_id;
5702       bind_node_id_ex(ii) := iterator(ii).node_id_ex;
5703       bind_node_value(ii) := iterator(ii).node_value;
5704       bind_node_obj(ii) := iterator(ii).node_obj;
5705       bind_node_type(ii) := iterator(ii).node_type;
5706 
5707       IF(v_property_id.COUNT > 0)THEN
5708 
5709         --This is only valid if there are properties.
5710 
5711         IF(iterator(ii).node_id IS NULL)THEN RAISE CZ_R_TYPE_NO_PROPERTY; END IF;
5712 
5713         nodeId := glPsNodeId(glIndexByPsNodeId(iterator(ii).node_id));
5714         itemId := glItemId(glIndexByPsNodeId(iterator(ii).node_id));
5715       END IF;
5716 
5717       --Get the property values and insert the data.
5718 
5719       FOR jj IN 1..v_property_id.COUNT LOOP
5720 
5721         propertyId := v_property_id(jj);
5722         hash_propval_key := TO_CHAR(nodeId) || '-' || TO_CHAR(itemId) || '-' ||
5723                             TO_CHAR(propertyId) || '-' || TO_CHAR(v_flag(propertyId));
5724 
5725         IF(NOT table_hash_propval.EXISTS(hash_propval_key))THEN
5726 
5727           IF(v_flag(propertyId) = 0)THEN
5728 
5729             --User property.
5730 
5731             propertyVal := GET_PROPERTY_VALUE(nodeId, propertyId, itemId, localNumber);
5732 
5733             --Bug #4554100.
5734 
5735             IF(localNumber IS NULL)THEN
5736 
5737                errorMessage := v_prop_name(jj);
5738                auxIndex := glIndexByPsNodeId(iterator(ii).node_id);
5739                IF(glParentId(auxIndex) IS NULL)THEN nParam := auxIndex; ELSE
5740                nParam := glIndexByPsNodeId(glParentId(auxIndex)); END IF;
5741                RAISE CZ_R_OPTION_NO_PROPERTY;
5742             END IF;
5743           ELSE
5744 
5745             --System property.
5746 
5747             propertyVal := STATIC_SYSPROP_VALUE(nodeId, propertyId, v_flag(v_property_id(jj)));
5748           END IF;
5749 
5750           IF(LENGTH(propertyVal) > MAXIMUM_INDEX_LENGTH)THEN
5751 
5752             --Bug #3416994.
5753 
5754             errorMessage := v_prop_name(jj);
5755             auxIndex := glIndexByPsNodeId(iterator(ii).node_id);
5756             IF(glParentId(auxIndex) IS NULL)THEN nParam := auxIndex; ELSE
5757             nParam := glIndexByPsNodeId(glParentId(auxIndex)); END IF;
5758             RAISE CZ_R_LONG_PROPERTY_VALUE;
5759           END IF;
5760 
5761           bind_values(jj)(ii) := propertyVal;
5762           table_hash_propval(hash_propval_key) := propertyVal;
5763         ELSE
5764           bind_values(jj)(ii) := table_hash_propval(hash_propval_key);
5765         END IF;
5766       END LOOP;
5767     END LOOP;
5768 
5769 nDebug := 7004106;
5770 
5771     v_cursor := DBMS_SQL.OPEN_CURSOR;
5772     DBMS_SQL.PARSE(v_cursor, SQLInsert || SQLValues, DBMS_SQL.NATIVE);
5773 
5774     DBMS_SQL.BIND_ARRAY(v_cursor, ':y1', bind_node_type);
5775     DBMS_SQL.BIND_ARRAY(v_cursor, ':y2', bind_node_id);
5776     DBMS_SQL.BIND_ARRAY(v_cursor, ':y3', bind_node_value);
5777     DBMS_SQL.BIND_ARRAY(v_cursor, ':y4', bind_node_obj);
5778     DBMS_SQL.BIND_ARRAY(v_cursor, ':y5', bind_node_id_ex);
5779 
5780     FOR ii IN 1..v_property_id.COUNT LOOP
5781       DBMS_SQL.BIND_ARRAY(v_cursor, ':x' || TO_CHAR(ii), bind_values(ii));
5782     END LOOP;
5783 
5784     localNumber := DBMS_SQL.EXECUTE(v_cursor);
5785     DBMS_SQL.CLOSE_CURSOR(v_cursor);
5786 
5787 nDebug := 7004107;
5788 
5789     EXECUTE IMMEDIATE 'ANALYZE TABLE ' || tableName || ' COMPUTE STATISTICS';
5790 
5791     --The table is created and populated, add its name to the hash for re-use if it is eligible.
5792 
5793     IF(temp_table_hash_key(forallLevel) IS NOT NULL)THEN temp_table_hash(temp_table_hash_key(forallLevel)) := tableName; END IF;
5794     END IF;
5795   END LOOP;
5796 
5797   --Generate the WHERE clause and run the query with bind variables. For every row returned,
5798   --generate the expression and return the object.
5799   --To do this, add GENERATE_ARGUMENT to the GENERATE_EXPRESSION.
5800 
5801 nDebug := 7004108;
5802 
5803   IF(whereIndex <> 0)THEN
5804 
5805     SQLWhere := ' WHERE ' || EXAMINE_WHERE_CLAUSE(v_ChildrenIndex(v_tExprId(whereIndex)));
5806   END IF;
5807 
5808   v_cursor := DBMS_SQL.OPEN_CURSOR;
5809   DBMS_SQL.PARSE(v_cursor, SQLSelect || SQLFrom || SQLWhere, DBMS_SQL.NATIVE);
5810 
5811   FOR i IN 1..bindValue.COUNT LOOP
5812     DBMS_SQL.BIND_VARIABLE(v_cursor, ':x' || TO_CHAR(i), bindValue(i));
5813   END LOOP;
5814 
5815   FOR i IN 1..iteratorIndex.COUNT LOOP
5816 
5817     DBMS_SQL.DEFINE_COLUMN(v_cursor, 5 * (i - 1) + 1, localNumber);
5818     DBMS_SQL.DEFINE_COLUMN(v_cursor, 5 * (i - 1) + 2, localNumber);
5819     DBMS_SQL.DEFINE_COLUMN(v_cursor, 5 * (i - 1) + 3, localString, 2000);
5820     DBMS_SQL.DEFINE_COLUMN(v_cursor, 5 * (i - 1) + 4, localString, 2000);
5821     DBMS_SQL.DEFINE_COLUMN(v_cursor, 5 * (i - 1) + 5, localNumber);
5822   END LOOP;
5823 
5824 nDebug := 7004109;
5825 
5826   localNumber := DBMS_SQL.EXECUTE(v_cursor);
5827 
5828   --For every returned row, store the values in the parameter scope, from where GENERATE_EXPRESSION
5829   --will be retrieving it when generating an argument.
5830 
5831   FOR i IN 1..iteratorIndex.COUNT LOOP
5832 
5833     parameterName(v_stack_start + i - 1) := v_tExprArgumentName(iteratorIndex(i));
5834   END LOOP;
5835 
5836   WHILE(DBMS_SQL.FETCH_ROWS(v_cursor) > 0)LOOP
5837 
5838     FOR i IN 1..iteratorIndex.COUNT LOOP
5839 
5840       DBMS_SQL.COLUMN_VALUE(v_cursor, 5 * (i - 1) + 1, parameterScope(v_stack_start + i - 1).node_type);
5841       DBMS_SQL.COLUMN_VALUE(v_cursor, 5 * (i - 1) + 2, parameterScope(v_stack_start + i - 1).node_id);
5842       DBMS_SQL.COLUMN_VALUE(v_cursor, 5 * (i - 1) + 3, parameterScope(v_stack_start + i - 1).node_value);
5843       DBMS_SQL.COLUMN_VALUE(v_cursor, 5 * (i - 1) + 4, parameterScope(v_stack_start + i - 1).node_obj);
5844       DBMS_SQL.COLUMN_VALUE(v_cursor, 5 * (i - 1) + 5, parameterScope(v_stack_start + i - 1).node_id_ex);
5845     END LOOP;
5846 
5847     IF(expressionIndex <> 0 AND v_ChildrenIndex.EXISTS(v_tExprId(expressionIndex)))THEN
5848 
5849       --Bug #5497235. This is a FORALL with an expression, need to generate the expression.
5850 
5851       generateCollect := 1;
5852 
5853       v_express := GENERATE_EXPRESSION(expressionIndex, ListType);
5854       generateCollect := 0;
5855 
5856       nCount := v_return.COUNT + 1;
5857 
5858       FOR i IN 1..v_express.COUNT LOOP
5859 
5860         IF(v_tExprType(j) = EXPR_FORALL_DISTINCT)THEN
5861 
5862           --For COLLECT DISTINCT we need to leave only distinct values in the results.
5863 
5864           v_value_exists := 0;
5865 
5866           FOR ii IN 1..nCount - 1 LOOP
5867             IF(v_return(ii).node_value = v_express(i))THEN v_value_exists := 1; EXIT; END IF;
5868           END LOOP;
5869         END IF;
5870 
5871         IF(v_value_exists = 0)THEN
5872 
5873           v_return(nCount).node_obj := v_express(i);
5874           v_return(nCount).node_value := v_express(i);
5875           v_return(nCount).node_id := NULL;
5876           v_return(nCount).node_type := DATA_TYPE_VARIANT;
5877           nCount := nCount + 1;
5878         END IF;
5879       END LOOP;
5880 
5881     ELSE
5882 
5883       --Bug #5497235. This is a COLLECT because there is no expression or the expression is just an argument.
5884       --In this case we need a direct copy of the parameter scope.
5885 
5886       nCount := v_return.COUNT + 1;
5887 
5888       /* Changing this for loop from 1..parameterscope.count to the below as part of the fix for the bug : 6355526*/
5889 
5890       FOR i IN v_stack_start..v_stack_end LOOP
5891 
5892 
5893         v_return(nCount).node_id := parameterScope(i).node_id;
5894         v_return(nCount).node_type := parameterScope(i).node_type;
5895         v_return(nCount).node_value := parameterScope(i).node_value;
5896         v_return(nCount).node_obj := parameterScope(i).node_obj;
5897         v_return(nCount).node_id_ex := parameterScope(i).node_id_ex;
5898         nCount := nCount + 1;
5899       END LOOP;
5900     END IF;
5901   END LOOP;
5902 
5903   parameterScope.DELETE(v_stack_start, v_stack_end);
5904   parameterName.DELETE(v_stack_start, v_stack_end);
5905 
5906 nDebug := 7004110;
5907 
5908   DBMS_SQL.CLOSE_CURSOR(v_cursor);
5909 
5910   IF(v_tExprParentId(j) IS NOT NULL AND v_return.COUNT = 0)THEN
5911 
5912     --The FORALL or COLLECT did not yield any rows while it is not the root operator.
5913     --Need a new message to report this.
5914 
5915     RAISE CZ_R_COMPAT_NO_COMBINATIONS;
5916   END IF;
5917 
5918  RETURN v_return;
5919 END;
5920 ---------------------------------------------------------------------------------------
5921 --This function is introduced to support the level of embedding.
5922 
5923 FUNCTION GENERATE_FORALL(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tIteratorArray IS
5924   v_return  tIteratorArray;
5925 BEGIN
5926   forallLevel := forallLevel + 1;
5927   v_return := GENERATE_FORALL_(j, ListType);
5928   forallLevel := forallLevel - 1;
5929  RETURN v_return;
5930 EXCEPTION
5931   WHEN OTHERS THEN
5932     forallLevel := forallLevel - 1;
5933     RAISE;
5934 END;
5935 ---------------------------------------------------------------------------------------
5936 FUNCTION GENERATE_COMPATIBLE_(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
5937 
5938   iteratorIndex    tIntegerArray;
5939   iterator         tIteratorArray;
5940   whereIndex       PLS_INTEGER := 0;
5941   featureIndex     PLS_INTEGER;
5942   nChild           NUMBER; -- jonatara:bug7041718
5943   nCounter         NUMBER; -- jonatara:bug7041718
5944   v_property_id    tIntegerArray;
5945   v_data_type      tIntegerArray;
5946   v_prop_name      tStringArray;
5947   v_return         tStringArray;
5948   SQLCreate        VARCHAR2(8000);
5949   SQLInsert        VARCHAR2(8000);
5950   SQLValues        VARCHAR2(8000);
5951   SQLSelect        VARCHAR2(8000);
5952   SQLFrom          VARCHAR2(8000);
5953   SQLWhere         VARCHAR2(8000) := NULL;
5954   tableName        VARCHAR2(4000);
5955   tableAlias       VARCHAR2(4000);
5956   nodeId           NUMBER; -- jonatara:bug7041718
5957   itemId           PLS_INTEGER;
5958   propertyId       PLS_INTEGER;
5959   c_values         refCursor;
5960   v_cursor         NUMBER;
5961   propertyVal      VARCHAR2(4000);
5962   localNumber      NUMBER;
5963   localString      VARCHAR2(4000);
5964   bindValue        tStringArray;
5965   typeCheck        NUMBER;
5966   v_tOptionId      DBMS_SQL.NUMBER_TABLE;
5967   v_tFeatureId     tExplNodeId;
5968   v_BackIndex      tIntegerArray;
5969   v_tExplId        tExplNodeId;
5970   rowThreshold     PLS_INTEGER := 0;
5971   v_OptionExists   tIntegerArray_idx_vc2; --kdande; Bug 6881902; 11-Mar-2008
5972   v_OptionsChain   tIntegerArray;
5973   v_FeatureIndex   tIntegerArray;
5974   v_ItemIndex      tIntegerArray;
5975   chainIndex       PLS_INTEGER := 1;
5976   currentIndex     PLS_INTEGER;
5977   itemIndex        PLS_INTEGER;
5978   itemCount        PLS_INTEGER := 1;
5979   v_RowLines       tStringArray;
5980   v_ItemLines      tStringArray;
5981   ExcludesRequired PLS_INTEGER;
5982   v_flag           tIntegerArray;
5983 
5984   bind_node_id     DBMS_SQL.NUMBER_TABLE;
5985 
5986   TYPE bind_value_table IS TABLE OF DBMS_SQL.VARCHAR2_TABLE INDEX BY BINARY_INTEGER;
5987   bind_values      bind_value_table;
5988   arg_table_name   temp_table_hash_type;
5989 
5990   h_OptionExplId   table_of_tNumberArray_idx_vc2;-- jonatara:bug7041718
5991   hash_propval_key VARCHAR2(4000);
5992 ---------------------------------------------------------------------------------------
5993 PROCEDURE EXPLORE_WHERE(j IN PLS_INTEGER, v_argument IN VARCHAR2) IS
5994   nChild      PLS_INTEGER;
5995   nCount      PLS_INTEGER;
5996   propertyId  PLS_INTEGER;
5997   dataType    PLS_INTEGER;
5998   propType    PLS_INTEGER;
5999   propName    cz_properties.name%TYPE;
6000 BEGIN
6001 
6002 nDebug := 7005020;
6003 
6004   nChild := v_ChildrenIndex(v_tExprId(j));
6005 
6006   WHILE(v_tExprParentId(nChild) = v_tExprId(j))LOOP
6007 
6008     nCount := v_property_id.COUNT + 1;
6009 
6010     IF(v_ChildrenIndex.EXISTS(v_tExprId(nChild)))THEN
6011       IF(v_tExprType(nChild) = EXPR_ARGUMENT AND v_tExprArgumentName(nChild) = v_argument)THEN
6012 
6013         propertyId := EXTRACT_PROPERTY_INFO(nChild, propName, dataType, propType);
6014 	nDebug := 7005021;
6015         IF(NOT v_flag.EXISTS(propertyId))THEN
6016 
6017           v_property_id(nCount) := propertyId;
6018           v_data_type(nCount) := dataType;
6019           v_prop_name(nCount) := propName;
6020           v_flag(propertyId) := propType;
6021         END IF;
6022       ELSE
6023 
6024         EXPLORE_WHERE(nChild, v_argument);
6025       END IF;
6026     END IF;
6027     nChild := nChild + 1;
6028   END LOOP;
6029 
6030 nDebug := 7005029;
6031 END;
6032 ---------------------------------------------------------------------------------------
6033 --This function finds every reference to iterators in the FORALL WHERE clause, replaces
6034 --arguments with 'G_<argument_name>.value' string and reference nodes with
6035 --'G_<argument_name>.i_<property_id>' string. It returns the generated SQL
6036 --WHERE clause of the SELECT statement.
6037 --All the literal values are collected in an array for later binding.
6038 
6039 FUNCTION EXAMINE_WHERE_CLAUSE(j IN PLS_INTEGER) RETURN VARCHAR2 IS
6040   argChild         PLS_INTEGER;
6041   propType         PLS_INTEGER;
6042   jChild           PLS_INTEGER;
6043   propName         cz_properties.name%TYPE;
6044   LocalType        PLS_INTEGER := DATA_TYPE_VOID;
6045   v_extern         tStringArray;
6046   v_quotes         VARCHAR2(2);
6047 BEGIN
6048 
6049 nDebug := 7005030;
6050 
6051   IF(v_tExprType(j) = EXPR_ARGUMENT)THEN
6052     IF(NOT v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
6053 
6054       --Add <table_name>.value to the WHERE clause being generated.
6055 
6056       RETURN arg_table_name(v_tExprArgumentName(j)) || '.node_value';
6057     ELSE
6058 
6059       --Add <table_name>.i_<property_id> to the WHERE clause being generated.
6060       RETURN arg_table_name(v_tExprArgumentName(j)) || '.i_' ||
6061              TO_CHAR(EXTRACT_PROPERTY_INFO(j, propName, jChild, propType));
6062     END IF;
6063   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_NODE AND v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
6064 
6065     --Nodes can participate in the WHERE clause only with a property applied.
6066     --Bug #4648386.
6067 
6068     v_extern(1) := EXTRACT_PROPERTY_INFO(j, propName, jChild, propType);
6069 
6070     nDebug := 7005032;
6071 
6072     IF(jChild IN (DATATYPE_TRANSLATABLE_PROP, DATA_TYPE_TEXT))THEN v_quotes := ''''; END IF;
6073 
6074     IF(propType = 0)THEN
6075 
6076       RETURN v_quotes || PROPERTY_VALUE(v_ChildrenIndex(v_tExprId(j)), glIndexByPsNodeId(v_tExprPsNodeId(j)), LocalType) || v_quotes;
6077     ELSE
6078 
6079       RETURN v_quotes || STATIC_SYSPROP_VALUE(v_tExprPsNodeId(j), v_tExprPropertyId(j), propType) || v_quotes;
6080     END IF;
6081   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_LITERAL)THEN
6082 
6083     bindValue(bindValue.COUNT + 1) := v_tExprDataValue(j);
6084     RETURN ':x' || TO_CHAR(bindValue.COUNT);
6085 
6086   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_OPERATOR)THEN
6087 
6088     jChild := v_ChildrenIndex(v_tExprId(j));
6089 
6090     IF(v_tExprSubtype(j) = OPERATOR_TOTEXT)THEN
6091 
6092         --Added for the bug #5620750. Just need to ignore the ToText operator to preserve the
6093         --default type conversion.
6094 
6095         RETURN EXAMINE_WHERE_CLAUSE(jChild);
6096     END IF;
6097 
6098     IF(v_tExprParentId.EXISTS(jChild + 1) AND v_tExprParentId(jChild + 1)= v_tExprId(j))THEN
6099 
6100       IF(v_tExprSubtype(j) IN (OPERATOR_EQUALS,
6101                                OPERATOR_NOTEQUALS,
6102                                OPERATOR_EQUALS_INT,
6103                                OPERATOR_NOTEQUALS_INT,
6104                                OPERATOR_GT,
6105                                OPERATOR_LT,
6106                                OPERATOR_GE,
6107                                OPERATOR_LE,
6108                                OPERATOR_AND,
6109                                OPERATOR_OR))THEN
6110 
6111         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || OperatorLiterals(v_tExprSubtype(j)) ||
6112                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6113 
6114       ELSIF(v_tExprSubtype(j) = OPERATOR_CONCAT)THEN
6115 
6116         RETURN EXAMINE_WHERE_CLAUSE(jChild) || ' || ' || EXAMINE_WHERE_CLAUSE(jChild + 1);
6117 
6118       ELSIF(v_tExprSubtype(j) = OPERATOR_BEGINSWITH)THEN
6119 
6120         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
6121                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
6122 
6123       ELSIF(v_tExprSubtype(j) = OPERATOR_ENDSWITH)THEN
6124 
6125         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ''%'' || ' ||
6126                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6127 
6128       ELSIF(v_tExprSubtype(j) = OPERATOR_CONTAINS)THEN
6129 
6130         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ''%'' || ' ||
6131                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
6132 
6133       ELSIF(v_tExprSubtype(j) = OPERATOR_LIKE)THEN
6134 
6135         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
6136                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6137 
6138       ELSIF(v_tExprSubtype(j) = OPERATOR_MATCHES)THEN
6139 
6140         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' LIKE ' ||
6141                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6142 
6143       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTBEGINWITH)THEN
6144 
6145         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ' ||
6146                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
6147 
6148       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTENDWITH)THEN
6149 
6150         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ''%'' || ' ||
6151                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6152 
6153       ELSIF(v_tExprSubtype(j) = OPERATOR_DOESNOTCONTAIN)THEN
6154 
6155         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ''%'' || ' ||
6156                EXAMINE_WHERE_CLAUSE(jChild + 1) || ' || ''%'')';
6157 
6158       ELSIF(v_tExprSubtype(j) = OPERATOR_NOTLIKE)THEN
6159 
6160         RETURN '(' || EXAMINE_WHERE_CLAUSE(jChild) || ' NOT LIKE ' ||
6161                EXAMINE_WHERE_CLAUSE(jChild + 1) || ')';
6162 
6163       ELSE
6164 
6165         RAISE CZ_E_UKNOWN_OPER_IN_COMPAT;
6166       END IF;
6167 
6168     ELSIF(v_tExprSubtype(j) = OPERATOR_NOT)THEN
6169 
6170       RETURN '(NOT ' || EXAMINE_WHERE_CLAUSE(jChild) || ')';
6171 
6172     ELSE
6173 
6174       RAISE CZ_E_WRONG_OPER_IN_COMPAT;
6175     END IF;
6176   ELSE
6177 
6178     RAISE CZ_R_WRONG_COMPAT_EXPRESSION;
6179   END IF;
6180 END;
6181 ---------------------------------------------------------------------------------------
6182 PROCEDURE GET_ITEM_INDEX(OptionId IN NUMBER, ColumnIndex IN PLS_INTEGER) IS  --kdande; Bug 6881902; 11-Mar-2008
6183 BEGIN
6184 
6185  IF(NOT v_OptionExists.EXISTS(OptionId))THEN
6186    v_OptionExists(OptionId) := chainIndex;
6187  ELSE
6188    currentIndex := v_OptionExists(OptionId);
6189    LOOP
6190 
6191     IF(v_FeatureIndex(currentIndex) = ColumnIndex)THEN
6192       itemIndex := v_ItemIndex(currentIndex);
6193       RETURN;
6194     END IF;
6195 
6196     EXIT WHEN v_OptionsChain(currentIndex) IS NULL;
6197     currentIndex := v_OptionsChain(currentIndex);
6198    END LOOP;
6199 
6200    v_OptionsChain(currentIndex) := chainIndex;
6201  END IF;
6202 
6203   --Bug #4546828. Use the hashed explosion id for each option.
6204 
6205   v_ItemLines(itemCount) := GENERATE_NAME_EXPL(h_OptionExplId(ColumnIndex)(OptionId), OptionId) || ' ' || TO_CHAR(ColumnIndex - 1);
6206 
6207   v_OptionsChain(chainIndex) := NULL;
6208   v_FeatureIndex(chainIndex) := ColumnIndex;
6209   v_ItemIndex(chainIndex) := itemCount;
6210   itemIndex := itemCount;
6211   itemCount := itemCount + 1;
6212   chainIndex := chainIndex + 1;
6213 END;
6214 ---------------------------------------------------------------------------------------
6215 PROCEDURE GENERATE_STANDARD_PBC IS
6216 BEGIN
6217   v_cursor := DBMS_SQL.OPEN_CURSOR;
6218   DBMS_SQL.PARSE(v_cursor, SQLSelect || SQLFrom || SQLWhere, DBMS_SQL.NATIVE);
6219 
6220   FOR i IN 1..bindValue.COUNT LOOP
6221     DBMS_SQL.BIND_VARIABLE(v_cursor, ':x' || TO_CHAR(i), bindValue(i));
6222   END LOOP;
6223 
6224 nDebug := 7005109;
6225 
6226   localNumber := DBMS_SQL.EXECUTE(v_cursor);
6227 
6228   LOOP
6229 
6230     FOR i IN 1..iteratorIndex.COUNT LOOP
6231       DBMS_SQL.DEFINE_ARRAY(v_cursor, i, v_tOptionId, DBMS_SQL_MAX_BUFFER_SIZE, 1);
6232     END LOOP;
6233 
6234     localNumber := DBMS_SQL.FETCH_ROWS(v_cursor);
6235 
6236     FOR i IN 1..v_tFeatureId.COUNT LOOP
6237 
6238       DBMS_SQL.COLUMN_VALUE(v_cursor, i, v_tOptionId);
6239 
6240       FOR n IN 1..localNumber LOOP
6241 
6242         GET_ITEM_INDEX(v_tOptionId(n), i);
6243 
6244         --Fix for the bug #2256166: changed n to rowThreshold + n in the EXISTS operator.
6245 
6246         IF(v_RowLines.EXISTS(rowThreshold + n))THEN
6247           v_RowLines(rowThreshold + n) := v_RowLines(rowThreshold + n) || ' ' || TO_CHAR(itemIndex - 1);
6248         ELSE
6249           v_RowLines(rowThreshold + n) := ' ' || TO_CHAR(itemIndex - 1);
6250         END IF;
6251       END LOOP;
6252     END LOOP;
6253     EXIT WHEN localNumber <> DBMS_SQL_MAX_BUFFER_SIZE;
6254     rowThreshold := rowThreshold + DBMS_SQL_MAX_BUFFER_SIZE;
6255   END LOOP;
6256 
6257 nDebug := 7005110;
6258 
6259   DBMS_SQL.CLOSE_CURSOR(v_cursor);
6260 
6261   --If there's no valid combinations, report the rule and ignore it.
6262 
6263   IF(v_RowLines.COUNT = 0)THEN
6264     RAISE CZ_R_COMPAT_NO_COMBINATIONS;
6265   END IF;
6266 
6267   --Generate the combo structure
6268 
6269   vLogicLine := 'OBJECT P_R' || TO_CHAR(nRuleId) || '_' || TO_CHAR(v_tExprId(j)) || NewLine ||
6270                 'COMBO P_R' || TO_CHAR(nRuleId) || '_' || TO_CHAR(v_tExprId(j)) || ' ' ||
6271                 TO_CHAR(v_ItemLines.COUNT) || ' ' || TO_CHAR(v_RowLines.COUNT) || ' ' ||
6272                 TO_CHAR(v_tFeatureId.COUNT) || ' ... ' || TO_CHAR(nReasonId) || NewLine;
6273   PACK;
6274 
6275   FOR i IN 1..v_ItemLines.COUNT LOOP
6276 
6277     vLogicLine := 'CI ' || TO_CHAR(i - 1) || ' ' || v_ItemLines(i) || NewLine;
6278     PACK;
6279   END LOOP;
6280 
6281   FOR i IN 1..v_tFeatureId.COUNT LOOP
6282 
6283     IF(GenerateGatedCombo = 0)THEN
6284 
6285       --Use intermediate variable instead of using NVL because this is faster
6286 
6287       localNumber := glIndexByPsNodeId(v_tFeatureId(i));
6288       localString := TO_CHAR(glMaximum(localNumber));
6289 
6290       --If it's a BOM item, we use maximum_selected instead of maximum
6291 
6292       IF(glPsNodeType(localNumber) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
6293         localString := TO_CHAR(glMaximumSel(localNumber));
6294       END IF;
6295 
6296       IF(localString IS NULL)THEN localString := '-1'; END IF;
6297       vLogicLine := ' O';
6298     ELSE
6299 
6300       --Generate gated combinations: maximum is always -1, the 'G' argument is followed
6301       --by the feature name.
6302 
6303       localString := '-1';
6304       vLogicLine := ' G ' || GENERATE_NAME(v_BackIndex(i), v_tFeatureId(i));
6305     END IF;
6306 
6307     vLogicLine := 'CC ' || TO_CHAR(i - 1) || ' 0 ' || localString || vLogicLine || NewLine;
6308     PACK;
6309   END LOOP;
6310 
6311   FOR i IN 1..v_RowLines.COUNT LOOP
6312 
6313     vLogicLine := 'CR ' || TO_CHAR(i - 1) || v_RowLines(i) || NewLine;
6314     PACK;
6315   END LOOP;
6316 
6317   vLogicLine := 'COMBO_END' || NewLine;
6318   PACK;
6319 
6320   --Generate the exclude relations if necessary.
6321   --The code is re-written as part of the fix for the bug #4546828 to use the new hash table.
6322 
6323   FOR i IN 1..v_tFeatureId.COUNT LOOP
6324 
6325     --We will use this array in the local context now
6326 
6327     v_OptionExists.DELETE;
6328 
6329     FOR n IN 1..v_ItemLines.COUNT LOOP
6330 
6331      itemIndex := INSTR(v_ItemLines(n), ' ', -1) + 1;
6332 
6333      IF(TO_NUMBER(SUBSTR(v_ItemLines(n), itemIndex)) = i - 1)THEN
6334 
6335        currentIndex := INSTR(v_ItemLines(n), '_', -1) + 1;
6336        v_OptionExists(TO_NUMBER(SUBSTR(v_ItemLines(n), currentIndex, itemIndex - currentIndex - 1))) := 1;
6337      END IF;
6338     END LOOP;
6339 
6340     ExcludesRequired := 0;
6341     nChild := h_OptionExplId(i).FIRST;
6342     nCounter := nChild;
6343 
6344     WHILE(nChild IS NOT NULL) LOOP
6345       IF(NOT v_OptionExists.EXISTS(glPersistentId(nChild)))THEN
6346          ExcludesRequired := 1;
6347          EXIT;
6348       END IF;
6349       nChild := h_OptionExplId(i).NEXT(nChild);
6350     END LOOP;
6351 
6352     IF(ExcludesRequired = 1)THEN
6353 
6354      nChild := nCounter;
6355 
6356      vLogicLine := 'GS E ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N ';
6357      PACK;
6358 
6359      WHILE(nChild IS NOT NULL) LOOP
6360        IF(NOT v_OptionExists.EXISTS(glPersistentId(nChild)))THEN
6361          vLogicLine := GENERATE_NAME_EXPL(h_OptionExplId(i)(nChild), nChild) || ' ';
6362          PACK;
6363        END IF;
6364        nChild := h_OptionExplId(i).NEXT(nChild);
6365      END LOOP;
6366 
6367      vLogicLine := NewLine || 'GR L ';
6368      PACK;
6369 
6370      FOR n IN 1..v_tFeatureId.COUNT LOOP
6371        IF(n <> i)THEN
6372          vLogicLine := GENERATE_NAME(v_BackIndex(n), v_tFeatureId(n)) || ' ';
6373          PACK;
6374        END IF;
6375      END LOOP;
6376 
6377      vLogicLine := NewLine;
6378      PACK;
6379     END IF; --Excludes required
6380   END LOOP;
6381 END GENERATE_STANDARD_PBC;
6382 ---------------------------------------------------------------------------------------
6383 PROCEDURE GENERATE_OPTIMIZED_PBC IS
6384 
6385   TYPE tVarcharTable IS TABLE OF VARCHAR2(32000) INDEX BY VARCHAR2(32000);
6386 
6387   v_options              SYSTEM.cz_lce_compat_tab_type := SYSTEM.cz_lce_compat_tab_type();
6388   a_min                  PLS_INTEGER;
6389   b_min                  PLS_INTEGER;
6390   a_object_name          VARCHAR2(4000);
6391   b_object_name          VARCHAR2(4000);
6392   v_option_a             DBMS_SQL.NUMBER_TABLE;
6393   v_option_b             DBMS_SQL.NUMBER_TABLE;
6394   current_option         NUMBER;
6395   v_bitpos_a             tIntegerArray_idx_vc2; --jonatara:bug7041718
6396   v_bitpos_b             tIntegerArray_idx_vc2;
6397   v_bitinv_a             tIntegerArray;
6398   v_bitinv_b             tIntegerArray;
6399   v_mask                 VARCHAR2(32000);
6400   v_group                VARCHAR2(32000);
6401   v_rel                  VARCHAR2(1);
6402   v_group_by_set_mask_a  tVarcharTable;
6403   v_group_by_set_mask_b  tVarcharTable;
6404 /*-------------------------------------------------------------------------------------
6405   CREATE OR REPLACE TYPE cz_lce_compat_rec_type IS OBJECT (option_a NUMBER, option_b NUMBER);
6406   CREATE OR REPLACE TYPE cz_lce_compat_tab_type IS TABLE OF cz_lce_compat_rec_type;
6407 ---------------------------------------------------------------------------------------*/
6408   FUNCTION get_feature_minimum(p_feature_id IN NUMBER) RETURN PLS_INTEGER IS
6409     v_idx  NUMBER; --kdande; Bug 6881902; 11-Mar-2008
6410     v_min  NUMBER; --kdande; Bug 6881902; 11-Mar-2008
6411   BEGIN
6412       v_idx := glIndexByPsNodeId(p_feature_id);
6413       v_min := glMinimum(v_idx);
6414 
6415       IF(glPsNodeType(v_idx) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
6416         v_min := glMinimumSel(v_idx);
6417       END IF;
6418     if(v_min IS NULL OR v_min < 1)THEN RETURN 0; END IF;
6419    RETURN 1;
6420   END;
6421 ---------------------------------------------------------------------------------------
6422 PROCEDURE init_set_mask(p_size IN PLS_INTEGER) IS
6423 BEGIN
6424   v_mask := '0';
6425   v_mask := RPAD(v_mask, p_size, '0');
6426 END;
6427 ---------------------------------------------------------------------------------------
6428 PROCEDURE set_mask(p_bitpos IN PLS_INTEGER) IS
6429 BEGIN
6430   v_mask := SUBSTR(v_mask, 1, p_bitpos - 1) || '1' || SUBSTR(v_mask, p_bitpos + 1);
6431 END;
6432 ---------------------------------------------------------------------------------------
6433 PROCEDURE init_group_mask_a(p_key IN VARCHAR2) IS
6434 BEGIN
6435   v_group_by_set_mask_a(p_key) := '0';
6436   v_group_by_set_mask_a(p_key) := RPAD(v_group_by_set_mask_a(p_key), v_bitpos_a.COUNT, '0');
6437 END;
6438 ---------------------------------------------------------------------------------------
6439 PROCEDURE set_group_mask_a(p_key IN VARCHAR2, p_bitpos IN PLS_INTEGER) IS
6440 BEGIN
6441   v_group_by_set_mask_a(p_key) := SUBSTR(v_group_by_set_mask_a(p_key), 1, p_bitpos - 1)
6442                         || '1' || SUBSTR(v_group_by_set_mask_a(p_key), p_bitpos + 1);
6443 END;
6444 ---------------------------------------------------------------------------------------
6445 PROCEDURE init_group_mask_b(p_key IN VARCHAR2) IS
6446 BEGIN
6447   v_group_by_set_mask_b(p_key) := '0';
6448   v_group_by_set_mask_b(p_key) := RPAD(v_group_by_set_mask_b(p_key), v_bitpos_b.COUNT, '0');
6449 END;
6450 ---------------------------------------------------------------------------------------
6451 PROCEDURE set_group_mask_b(p_key IN VARCHAR2, p_bitpos IN PLS_INTEGER) IS
6452 BEGIN
6453   v_group_by_set_mask_b(p_key) := SUBSTR(v_group_by_set_mask_b(p_key), 1, p_bitpos - 1)
6454                         || '1' || SUBSTR(v_group_by_set_mask_b(p_key), p_bitpos + 1);
6455 END;
6456 ---------------------------------------------------------------------------------------
6457 FUNCTION in_mask(p_bitpos IN PLS_INTEGER) RETURN BOOLEAN IS
6458 BEGIN
6459   RETURN (SUBSTR(v_mask, p_bitpos, 1) = '1');
6460 END;
6461 ---------------------------------------------------------------------------------------
6462 FUNCTION in_group(p_bitpos IN PLS_INTEGER) RETURN BOOLEAN IS
6463 BEGIN
6464   RETURN (SUBSTR(v_group, p_bitpos, 1) = '1');
6465 END;
6466 ---------------------------------------------------------------------------------------
6467 BEGIN
6468 nDebug := 8000000;
6469   v_cursor := DBMS_SQL.OPEN_CURSOR;
6470   DBMS_SQL.PARSE(v_cursor, SQLSelect || SQLFrom || SQLWhere, DBMS_SQL.NATIVE);
6471 
6472   FOR i IN 1..bindValue.COUNT LOOP
6473     DBMS_SQL.BIND_VARIABLE(v_cursor, ':x' || TO_CHAR(i), bindValue(i));
6474   END LOOP;
6475 
6476   localNumber := DBMS_SQL.EXECUTE(v_cursor);
6477 nDebug := 8000001;
6478   LOOP
6479 
6480     DBMS_SQL.DEFINE_ARRAY(v_cursor, 1, v_option_a, DBMS_SQL_MAX_BUFFER_SIZE, 1);
6481     DBMS_SQL.DEFINE_ARRAY(v_cursor, 2, v_option_b, DBMS_SQL_MAX_BUFFER_SIZE, 1);
6482 
6483     localNumber := DBMS_SQL.FETCH_ROWS(v_cursor);
6484 
6485     DBMS_SQL.COLUMN_VALUE(v_cursor, 1, v_option_a);
6486     DBMS_SQL.COLUMN_VALUE(v_cursor, 2, v_option_b);
6487 nDebug := 8000002;
6488     FOR i IN 1..localNumber LOOP
6489       v_options.EXTEND();
6490       v_options(rowThreshold + i) := SYSTEM.cz_lce_compat_rec_type(v_option_a(i), v_option_b(i));
6491 nDebug := 8000003;
6492       --These arrays store 'bit positions' for every a or b option. Later they will be used in construction
6493       --of the 'bit masks' for compatibility groups and sets.
6494       --The 'inv' arrays allow to quickly get an option_id by its bit position.
6495 
6496       IF(NOT v_bitpos_a.EXISTS(v_option_a(i)))THEN
6497 
6498          v_bitpos_a(v_option_a(i)) := v_bitpos_a.COUNT + 1;
6499          v_bitinv_a(v_bitpos_a(v_option_a(i))) := v_option_a(i);
6500       END IF;
6501       IF(NOT v_bitpos_b.EXISTS(v_option_b(i)))THEN
6502 
6503          v_bitpos_b(v_option_b(i)) := v_bitpos_b.COUNT + 1;
6504          v_bitinv_b(v_bitpos_b(v_option_b(i))) := v_option_b(i);
6505       END IF;
6506     END LOOP;
6507 
6508     v_option_a.DELETE;
6509     v_option_b.DELETE;
6510 
6511     EXIT WHEN localNumber <> DBMS_SQL_MAX_BUFFER_SIZE;
6512     rowThreshold := rowThreshold + DBMS_SQL_MAX_BUFFER_SIZE;
6513   END LOOP;
6514 nDebug := 8000005;
6515   DBMS_SQL.CLOSE_CURSOR(v_cursor);
6516 
6517   --If there's no valid combinations, report the rule and ignore it.
6518 
6519   IF(v_options.COUNT = 0)THEN
6520     RAISE CZ_R_COMPAT_NO_COMBINATIONS;
6521   END IF;
6522 
6523   IF (v_options.COUNT = (featOptionsCount(v_tFeatureId(1)) * featOptionsCount(v_tFeatureId(2)))) THEN
6524 
6525      --This is a two-column pbc rule, and the number of valid combinations is equal to the
6526      --number of possible combinations. The rule can be ignored.
6527 
6528      RETURN;
6529   END IF;
6530 
6531   a_min := get_feature_minimum(v_tFeatureId(1));
6532   b_min := get_feature_minimum(v_tFeatureId(2));
6533 
6534   --Generate the main relations.
6535 
6536   IF(a_min = 0)THEN
6537 
6538     --We need a temporary object to represent Not(A).
6539 
6540     nLocalDefaults := nLocalDefaults + 1;
6541     a_object_name := t_prefix || TO_CHAR(nLocalDefaults);
6542 
6543     vLogicLine := 'OBJECT ' || a_object_name || NewLine ||
6544                   'GS N ... ' || TO_CHAR(nReasonId) || NewLine ||
6545                   'GL' || OperatorLetters(OPERATOR_ANYOF) || GENERATE_NAME(v_BackIndex(1), v_tFeatureId(1)) || NewLine ||
6546                   'GR' || OperatorLetters(OPERATOR_ANYOF) || a_object_name || NewLine;
6547     PACK;
6548     a_object_name := a_object_name || ' ';
6549   END IF;
6550 
6551   IF(b_min = 0)THEN
6552 
6553     --We need a temporary object to represent Not(B).
6554 
6555     nLocalDefaults := nLocalDefaults + 1;
6556     b_object_name := t_prefix || TO_CHAR(nLocalDefaults);
6557 
6558     vLogicLine := 'OBJECT ' || b_object_name || NewLine ||
6559                   'GS N ... ' || TO_CHAR(nReasonId) || NewLine ||
6560                   'GL' || OperatorLetters(OPERATOR_ANYOF) || GENERATE_NAME(v_BackIndex(2), v_tFeatureId(2)) || NewLine ||
6561                   'GR' || OperatorLetters(OPERATOR_ANYOF) || b_object_name || NewLine;
6562     PACK;
6563     b_object_name := b_object_name || ' ';
6564   END IF;
6565 
6566   current_option := -1;
6567 nDebug := 8000010;
6568   FOR a IN (SELECT option_a, option_b FROM TABLE(v_options) ORDER BY option_a) LOOP
6569 
6570     IF(a.option_a <> current_option)THEN
6571 
6572       IF(current_option <> -1)THEN
6573 
6574         --We just moved to the next option. current_option is still the previous option for
6575         --which the generating of the compatible set mask is completed, and the actual mask
6576         --is still in v_mask.
6577         --Here either add the options to an existing compatibility group mask, or create a
6578         --new compatibility group mask.
6579 
6580         IF(NOT v_group_by_set_mask_a.EXISTS(v_mask))THEN init_group_mask_a(v_mask); END IF;
6581         set_group_mask_a(v_mask, v_bitpos_a(current_option));
6582       END IF;
6583 
6584       current_option := a.option_a;
6585       init_set_mask(v_bitpos_b.COUNT);
6586     END IF;
6587 
6588     set_mask(v_bitpos_b(a.option_b));
6589   END LOOP;
6590 
6591   --Need to repeat that for the last option.
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 
6596   current_option := -1;
6597 
6598   FOR b IN (SELECT option_a, option_b FROM TABLE(v_options) ORDER BY option_b) LOOP
6599 
6600     IF(b.option_b <> current_option)THEN
6601 
6602       IF(current_option <> -1)THEN
6603 
6604         IF(NOT v_group_by_set_mask_b.EXISTS(v_mask))THEN init_group_mask_b(v_mask); END IF;
6605         set_group_mask_b(v_mask, v_bitpos_b(current_option));
6606       END IF;
6607 
6608       current_option := b.option_b;
6609       init_set_mask(v_bitpos_a.COUNT);
6610     END IF;
6611 
6612     set_mask(v_bitpos_a(b.option_a));
6613   END LOOP;
6614 
6615   --Need to repeat that for the last option.
6616 nDebug := 8000015;
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 
6620   --The tables of compatibility group masks hashed by compatibility set masks have been built
6621   --for both sides. Now we can use them to generate the relations.
6622 
6623   v_mask := v_group_by_set_mask_a.FIRST;
6624 
6625   WHILE(v_mask IS NOT NULL)LOOP
6626 
6627     v_group := v_group_by_set_mask_a(v_mask);
6628     v_rel := 'I';
6629 
6630     IF(a_min = 1 AND b_min = 1 AND
6631        v_group_by_set_mask_b.EXISTS(v_group) AND v_group_by_set_mask_b(v_group) = v_mask)THEN
6632 
6633       --This is A Implies B, B Implies A. A Requires relation will be generated between v_group and
6634       --v_mask and v_group_by_set_mask_b(v_group) will be deleted so that it will not be processed
6635       --by the cycle on the other side.
6636 
6637       v_rel := 'R';
6638       v_group_by_set_mask_b.DELETE(v_group);
6639     END IF;
6640 
6641     --Generate an Implies or Requires relation between AnyTrue(v_group) and AnyTrue(v_mask)
6642 
6643     vLogicLine := 'GS ' || v_rel || ' ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N '; PACK;
6644 
6645     FOR i IN 1..v_bitpos_a.COUNT LOOP
6646       IF(in_group(i))THEN
6647         vLogicLine := GENERATE_NAME(v_BackIndex(1), v_bitinv_a(i)) || ' '; PACK;
6648       END IF;
6649     END LOOP;
6650 
6651     vLogicLine := NewLine || 'GR N ' || b_object_name; PACK;
6652 nDebug := 8000020;
6653     FOR i IN 1..v_bitpos_b.COUNT LOOP
6654       IF(in_mask(i))THEN
6655         vLogicLine := GENERATE_NAME(v_BackIndex(2), v_bitinv_b(i)) || ' '; PACK;
6656       END IF;
6657     END LOOP;
6658 
6659     vLogicLine := NewLine;
6660     PACK;
6661     v_mask := v_group_by_set_mask_a.NEXT(v_mask);
6662   END LOOP;
6663 
6664   v_mask := v_group_by_set_mask_b.FIRST;
6665 
6666   WHILE(v_mask IS NOT NULL)LOOP
6667 
6668     v_group := v_group_by_set_mask_b(v_mask);
6669     v_rel := 'I';
6670 
6671     IF(a_min = 1 AND b_min = 1 AND
6672        v_group_by_set_mask_a.EXISTS(v_group) AND v_group_by_set_mask_a(v_group) = v_mask)THEN
6673 
6674       --This is B Implies A, A Implies B. A Requires relation will be generated between v_group and
6675       --v_mask. We don't need to delete anything from the other side.
6676 
6677       v_rel := 'R';
6678     END IF;
6679 
6680     --Generate an Implies or Requires relation between AnyTrue(v_group) and AnyTrue(v_mask)
6681 
6682     vLogicLine := 'GS ' || v_rel || ' ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N '; PACK;
6683 nDebug := 8000025;
6684     FOR i IN 1..v_bitpos_b.COUNT LOOP
6685       IF(in_group(i))THEN
6686         vLogicLine := GENERATE_NAME(v_BackIndex(2), v_bitinv_b(i)) || ' '; PACK;
6687       END IF;
6688     END LOOP;
6689 
6690     vLogicLine := NewLine || 'GR N ' || a_object_name; PACK;
6691 
6692     FOR i IN 1..v_bitpos_a.COUNT LOOP
6693       IF(in_mask(i))THEN
6694         vLogicLine := GENERATE_NAME(v_BackIndex(1), v_bitinv_a(i)) || ' '; PACK;
6695       END IF;
6696     END LOOP;
6697 
6698     vLogicLine := NewLine;
6699     PACK;
6700     v_mask := v_group_by_set_mask_b.NEXT(v_mask);
6701   END LOOP;
6702 
6703   -- The following block can be optimized by splitting into two (for a and b), and
6704   -- 1) using featOptionsCount table and compare it to v_bitpos_a(b).COUNT to find out if excludes
6705   --    are required instead of cycling through the feature options;
6706   -- 2) using v_bitpos_a(b) instead of v_OptionExists thus avoiding populating this table.
6707 
6708   v_OptionExists.DELETE;
6709 
6710   --Hash all the options of both features that are compatible. If an option is not in the hash,
6711   --exclude relation will be generated later.
6712 nDebug := 8000030;
6713   FOR i IN 1..v_options.COUNT LOOP
6714     v_OptionExists(v_options(i).option_a) := 1;
6715     v_OptionExists(v_options(i).option_b) := 1;
6716   END LOOP;
6717 
6718   --Generate the exclude relations if necessary.
6719   --The code is re-written as part of the fix for the bug #4546828 to use the new hash table.
6720 
6721   FOR i IN 1..v_tFeatureId.COUNT LOOP
6722 
6723     ExcludesRequired := 0;
6724     nChild := h_OptionExplId(i).FIRST;
6725     nCounter := nChild;
6726 
6727     WHILE(nChild IS NOT NULL) LOOP
6728       IF(NOT v_OptionExists.EXISTS(nChild))THEN
6729          ExcludesRequired := 1;
6730          EXIT;
6731       END IF;
6732       nChild := h_OptionExplId(i).NEXT(nChild);
6733     END LOOP;
6734 
6735     IF(ExcludesRequired = 1)THEN
6736 
6737      nChild := nCounter;
6738 nDebug := 8000040;
6739      vLogicLine := 'GS E ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N ';
6740      PACK;
6741 
6742      WHILE(nChild IS NOT NULL) LOOP
6743        IF(NOT v_OptionExists.EXISTS(nChild))THEN
6744          vLogicLine := GENERATE_NAME_EXPL(h_OptionExplId(i)(nChild), nChild) || ' ';
6745          PACK;
6746        END IF;
6747        nChild := h_OptionExplId(i).NEXT(nChild);
6748      END LOOP;
6749 
6750      vLogicLine := NewLine || 'GR L ';
6751      PACK;
6752 
6753      FOR n IN 1..v_tFeatureId.COUNT LOOP
6754        IF(n <> i)THEN
6755          vLogicLine := GENERATE_NAME(v_BackIndex(n), v_tFeatureId(n)) || ' ';
6756          PACK;
6757        END IF;
6758      END LOOP;
6759 
6760      vLogicLine := NewLine;
6761      PACK;
6762     END IF; --Excludes required
6763   END LOOP;
6764 END GENERATE_OPTIMIZED_PBC;
6765 ---------------------------------------------------------------------------------------
6766 BEGIN
6767 
6768   --High-level property-based compatibility rule validation section
6769   --Make sure the rule has at least 2 participant features
6770 
6771   IF(participantCount < 2)THEN
6772     RAISE CZ_R_COMPAT_SINGLE_FEATURE;
6773   END IF;
6774 
6775 nDebug := 7005100;
6776 
6777   nChild := v_ChildrenIndex(v_tExprId(j));
6778   nCounter := 1;
6779 
6780   WHILE(v_tExprParentId(nChild) = v_tExprId(j)) LOOP
6781     IF(v_tExprType(nChild) = EXPR_ITERATOR)THEN
6782 
6783       iteratorIndex(nCounter) := nChild;
6784       featureIndex := v_ChildrenIndex(v_tExprId(nChild));
6785 
6786       v_tFeatureId(nCounter) := v_tExprPsNodeId(featureIndex);
6787       v_tExplId(nCounter) := v_tExplNodeId(featureIndex);
6788       v_BackIndex(nCounter) := featureIndex;
6789 
6790       nCounter := nCounter + 1;
6791 
6792     ELSIF(v_tExprType(nChild) = EXPR_WHERE)THEN
6793 
6794       whereIndex := nChild;
6795     END IF;
6796 
6797     nChild := nChild + 1;
6798   END LOOP;
6799 
6800 nDebug := 7005101;
6801 
6802   FOR i IN 1..iteratorIndex.COUNT LOOP
6803 
6804     bind_node_id.DELETE;
6805     bind_values.DELETE;
6806 
6807     v_property_id.DELETE;
6808     v_data_type.DELETE;
6809     v_prop_name.DELETE;
6810     v_flag.DELETE;
6811 
6812     temp_cmpt_hash_key(compatLevel) := NULL;
6813     tableAlias := 'C' || TO_CHAR(i);
6814 
6815     iterator.DELETE;
6816     iterator := GENERATE_ITERATOR(iteratorIndex(i), ListType);
6817 
6818     IF(whereIndex <> 0)THEN
6819       EXPLORE_WHERE(whereIndex, v_tExprArgumentName(iteratorIndex(i)));
6820     END IF;
6821 
6822     IF(temp_cmpt_hash_key(compatLevel) IS NOT NULL)THEN
6823       FOR ii IN 1..v_property_id.COUNT LOOP
6824         temp_cmpt_hash_key(compatLevel) := temp_cmpt_hash_key(compatLevel) || '-' || TO_CHAR(v_property_id(ii));
6825       END LOOP;
6826     END IF;
6827 
6828 nDebug := 7005102;
6829 
6830     IF(temp_cmpt_hash_key(compatLevel) IS NOT NULL AND temp_cmpt_table_hash.EXISTS(temp_cmpt_hash_key(compatLevel)))THEN
6831 
6832       tableName := temp_cmpt_table_hash(temp_cmpt_hash_key(compatLevel));
6833       arg_table_name(v_tExprArgumentName(iteratorIndex(i))) := tableAlias;
6834 
6835       IF(SQLSelect IS NULL)THEN SQLSelect := 'SELECT '; ELSE SQLSelect := SQLSelect || ', '; END IF;
6836       SQLSelect := SQLSelect || tableAlias || '.node_id';
6837       IF(SQLFrom IS NULL)THEN SQLFrom := ' FROM '; ELSE SQLFrom := SQLFrom || ', '; END IF;
6838       SQLFrom := SQLFrom || tableName || ' ' || tableAlias;
6839 
6840       FOR ii IN 1..iterator.COUNT LOOP
6841         h_OptionExplId(i)(iterator(ii).node_id) := iterator(ii).node_id_ex;
6842       END LOOP;
6843     ELSE
6844 
6845     tableName := 'G_' || TO_CHAR(table_name_generator);
6846     table_name_generator := table_name_generator + 1;
6847     arg_table_name(v_tExprArgumentName(iteratorIndex(i))) := tableAlias;
6848 
6849     IF(SQLSelect IS NULL)THEN SQLSelect := 'SELECT '; ELSE SQLSelect := SQLSelect || ', '; END IF;
6850     SQLSelect := SQLSelect || tableAlias || '.node_id';
6851     IF(SQLFrom IS NULL)THEN SQLFrom := ' FROM '; ELSE SQLFrom := SQLFrom || ', '; END IF;
6852     SQLFrom := SQLFrom || tableName || ' ' || tableAlias;
6853 
6854     SQLCreate := 'CREATE GLOBAL TEMPORARY TABLE ' || tableName || '(node_id NUMBER ';
6855 
6856     FOR ii IN 1..v_property_id.COUNT LOOP
6857 
6858       SQLCreate := SQLCreate || ', i_' || TO_CHAR(v_property_id(ii));
6859 
6860       IF(v_data_type(ii) IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL))THEN
6861 
6862         SQLCreate := SQLCreate || ' NUMBER';
6863       ELSE
6864 
6865         SQLCreate := SQLCreate || ' VARCHAR2(' || TO_CHAR(MAXIMUM_INDEX_LENGTH) || ')';
6866       END IF;
6867     END LOOP;
6868 
6869     SQLCreate := SQLCreate || ') ON COMMIT PRESERVE ROWS';
6870 
6871 nDebug := 7005103;
6872 
6873     BEGIN
6874       EXECUTE IMMEDIATE SQLCreate;
6875     EXCEPTION
6876       WHEN OTHERS THEN
6877 
6878         --If the table already exists, truncate it, drop and try to create again.
6879 
6880         IF(SQLCODE = ORACLE_OBJECT_ALREADY_EXISTS)THEN
6881           EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || tableName;
6882           EXECUTE IMMEDIATE 'DROP TABLE ' || tableName;
6883           EXECUTE IMMEDIATE SQLCreate;
6884         ELSE
6885           RAISE;
6886         END IF;
6887     END;
6888 
6889     --The table is created, add its name to the delete list.
6890 
6891     temp_tables(temp_tables.COUNT + 1) := tableName;
6892 
6893 nDebug := 7005104;
6894 
6895     SQLInsert := 'INSERT INTO ' || tableName || '(node_id';
6896     SQLValues := ' VALUES (:y1';
6897 
6898     FOR ii IN 1..v_property_id.COUNT LOOP
6899 
6900       BEGIN
6901 
6902         EXECUTE IMMEDIATE 'CREATE INDEX ' || tableName || '_I' || TO_CHAR(ii) || ' ON ' || tableName ||
6903                           '(i_' || v_property_id(ii) || ')';
6904       EXCEPTION
6905         WHEN OTHERS THEN
6906           IF(SQLCODE <> ORACLE_OBJECT_ALREADY_EXISTS)THEN RAISE; END IF;
6907       END;
6908 
6909       SQLInsert := SQLInsert || ', i_' || TO_CHAR(v_property_id(ii));
6910       SQLValues := SQLValues || ', :x' || TO_CHAR(ii);
6911     END LOOP;
6912 
6913     SQLInsert := SQLInsert || ')';
6914     SQLValues := SQLValues || ')';
6915 
6916 nDebug := 7005105;
6917 
6918     FOR ii IN 1..iterator.COUNT LOOP
6919 
6920       bind_node_id(ii) := iterator(ii).node_id;
6921 
6922       IF(v_property_id.COUNT > 0)THEN
6923 
6924         --This is only valid if there are properties.
6925 
6926         IF(iterator(ii).node_id IS NULL)THEN RAISE CZ_R_TYPE_NO_PROPERTY; END IF;
6927 
6928         nodeId := glPsNodeId(glIndexByPsNodeId(iterator(ii).node_id));
6929         itemId := glItemId(glIndexByPsNodeId(iterator(ii).node_id));
6930       END IF;
6931 
6932       --Get the property values and insert the data.
6933 
6934 nDebug := 7005106;
6935 
6936       FOR jj IN 1..v_property_id.COUNT LOOP
6937 
6938         propertyId := v_property_id(jj);
6939         hash_propval_key := TO_CHAR(nodeId) || '-' || TO_CHAR(itemId) || '-' ||
6940                             TO_CHAR(propertyId) || '-' || TO_CHAR(v_flag(propertyId));
6941 
6942         IF(NOT table_hash_propval.EXISTS(hash_propval_key))THEN
6943 
6944           IF(v_flag(propertyId) = 0)THEN
6945 
6946             --User property.
6947 
6948             propertyVal := NULL;
6949             localNumber := NULL;
6950             propertyVal := GET_PROPERTY_VALUE(nodeId, propertyId, itemId, localNumber);
6951           ELSE
6952 
6953             --System property.
6954 
6955             localNumber := 1;
6956             propertyVal := STATIC_SYSPROP_VALUE(nodeId, propertyId, v_flag(v_property_id(jj)));
6957           END IF;
6958 
6959           --Bug #3829438. Second and third columns of the cursor are not null, so localNumber can be NULL
6960           --only if no rows are fetched.
6961 
6962           IF(localNumber IS NOT NULL)THEN
6963             IF(v_data_type(jj) IN (DATATYPE_INTEGER, DATATYPE_FLOAT))THEN
6964 
6965               --If the property has numeric type, but the data is corrupted and the value
6966               --cannot be actually converted to a number, the generated SQL statement may
6967               --produce incomprehensive syntax errors, like 'too many columns'. To avoid
6968               --this verify the value.
6969 
6970               BEGIN
6971                 typeCheck := TO_NUMBER(propertyVal);
6972               EXCEPTION
6973                 WHEN OTHERS THEN
6974                   errorMessage := v_prop_name(jj);
6975                   localString := propertyVal;
6976                   RAISE CZ_R_INCORRECT_DATA_TYPE;
6977               END;
6978             ELSIF(LENGTH(propertyVal) > MAXIMUM_INDEX_LENGTH)THEN
6979 
6980                errorMessage := v_prop_name(jj);
6981                nParam := glIndexByPsNodeId(v_tFeatureId(i));
6982                auxIndex := glIndexByPsNodeId(iterator(ii).node_id);
6983                RAISE CZ_R_LONG_PROPERTY_VALUE;
6984             END IF;
6985           ELSE
6986             errorMessage := v_prop_name(jj);
6987             nParam := glIndexByPsNodeId(v_tFeatureId(i));
6988             auxIndex := glIndexByPsNodeId(iterator(ii).node_id);
6989             RAISE CZ_R_OPTION_NO_PROPERTY;
6990           END IF;
6991 
6992           bind_values(jj)(ii) := propertyVal;
6993           table_hash_propval(hash_propval_key) := propertyVal;
6994         ELSE
6995           bind_values(jj)(ii) := table_hash_propval(hash_propval_key);
6996         END IF;
6997       END LOOP;
6998 
6999       --Bug #4546828.
7000       --In a BOM model, options can really be references to other BOM models, therefore each option
7001       --can have its own explosion id, which should be used to generate correct logic name.
7002       --Hash the explosion id(s) here in a two-dimensional table (iterator, option_id).
7003       --Here we are supposed to hash all eligible options of the parent (the eligibility determined
7004       --by EXPAND_NODE inside the GENERATE_ITERATOR). For example, if a BOM model has BOM standard
7005       --items and a non-BOM feature, only the bom items are eligible. Therefore, this table will be
7006       --used later when generating exclusions.
7007 
7008       h_OptionExplId(i)(nodeId) := iterator(ii).node_id_ex;
7009     END LOOP;
7010 
7011 nDebug := 7005107;
7012 
7013     v_cursor := DBMS_SQL.OPEN_CURSOR;
7014     DBMS_SQL.PARSE(v_cursor, SQLInsert || SQLValues, DBMS_SQL.NATIVE);
7015 
7016     DBMS_SQL.BIND_ARRAY(v_cursor, ':y1', bind_node_id);
7017 
7018     FOR ii IN 1..v_property_id.COUNT LOOP
7019       DBMS_SQL.BIND_ARRAY(v_cursor, ':x' || TO_CHAR(ii), bind_values(ii));
7020     END LOOP;
7021 
7022     localNumber := DBMS_SQL.EXECUTE(v_cursor);
7023     DBMS_SQL.CLOSE_CURSOR(v_cursor);
7024 
7025     EXECUTE IMMEDIATE 'ANALYZE TABLE ' || tableName || ' COMPUTE STATISTICS';
7026 
7027     --The table is created and populated, add its name to the hash for re-use if it is eligible.
7028 
7029     IF(temp_cmpt_hash_key(compatLevel) IS NOT NULL)THEN temp_cmpt_table_hash(temp_cmpt_hash_key(compatLevel)) := tableName; END IF;
7030     END IF;
7031   END LOOP;
7032 
7033   --Generate the WHERE clause and run the query with bind variables. For every row returned,
7034   --generate the expression and return the object.
7035   --To do this, add GENERATE_ARGUMENT to the GENERATE_EXPRESSION.
7036 
7037 nDebug := 7005108;
7038 
7039   IF(whereIndex <> 0)THEN
7040     SQLWhere := ' WHERE ' || EXAMINE_WHERE_CLAUSE(v_ChildrenIndex(v_tExprId(whereIndex)));
7041   END IF;
7042 
7043   IF(v_tFeatureId.COUNT = 2)THEN
7044     GENERATE_OPTIMIZED_PBC;
7045   ELSE
7046 
7047     GENERATE_STANDARD_PBC;
7048   END IF;
7049 
7050  RETURN v_return;
7051 END;
7052 ---------------------------------------------------------------------------------------
7053 --This function is introduced to support the level of embedding.
7054 
7055 FUNCTION GENERATE_COMPATIBLE(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
7056   v_return  tStringArray;
7057 BEGIN
7058   compatLevel := compatLevel + 1;
7059   v_return := GENERATE_COMPATIBLE_(j, ListType);
7060   compatLevel := compatLevel - 1;
7061  RETURN v_return;
7062 EXCEPTION
7063   WHEN OTHERS THEN
7064     compatLevel := compatLevel - 1;
7065     RAISE;
7066 END;
7067 ---------------------------------------------------------------------------------------
7068 FUNCTION GENERATE_EXPRESSION(j IN PLS_INTEGER, ListType OUT NOCOPY PLS_INTEGER) RETURN tStringArray IS
7069  v_return  tStringArray;
7070  v_result  tIteratorArray;
7071 BEGIN
7072 
7073   ListType := DATATYPE_GENERIC;
7074 
7075   IF(v_tExprType(j) = EXPR_NODE_TYPE_NODE)THEN
7076 
7077     IF(v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
7078 
7079       RETURN GENERATE_REFNODE(j, ListType);
7080     ELSE
7081 
7082       RETURN GENERATE_NODE(j);
7083     END IF;
7084 
7085   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_FEATPROP)THEN
7086 
7087     RETURN GENERATE_PROPERTY(j);
7088 
7089   ELSIF(v_tExprType(j) = EXPR_PROP)THEN
7090 
7091     v_return(1) := PROPERTY_VALUE(j, glIndexByPsNodeId(v_tExprPsNodeId(j - 1)), ListType);
7092 
7093   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_OPERATOR)THEN
7094 
7095     IF(v_tExprSubtype(j) IN (OPERATOR_ADD,
7096                              OPERATOR_SUB,
7097                              OPERATOR_MULT,
7098                              OPERATOR_DIV,
7099                              OPERATOR_ADD_INT,
7100                              OPERATOR_SUB_INT,
7101                              OPERATOR_MULT_INT))THEN
7102       RETURN GENERATE_ARITHMETIC(j);
7103 
7104     ELSIF(v_tExprSubtype(j) IN (OPERATOR_COS,
7105                                 OPERATOR_ACOS,
7106                                 OPERATOR_COSH,
7107                                 OPERATOR_SIN,
7108                                 OPERATOR_ASIN,
7109                                 OPERATOR_SINH,
7110                                 OPERATOR_TAN,
7111                                 OPERATOR_ATAN,
7112                                 OPERATOR_TANH,
7113                                 OPERATOR_LOG,
7114                                 OPERATOR_LOG10,
7115                                 OPERATOR_EXP,
7116                                 OPERATOR_ABS,
7117                                 OPERATOR_SQRT))THEN
7118       RETURN GENERATE_MATH_UNARY(j);
7119 
7120     ELSIF(v_tExprSubtype(j) IN (OPERATOR_MATHDIV,
7121                                 OPERATOR_POW,
7122                                 OPERATOR_POW_INT,
7123                                 OPERATOR_ATAN2,
7124                                 OPERATOR_MOD))THEN
7125       RETURN GENERATE_MATH_BINARY(j);
7126 
7127     ELSIF(v_tExprSubtype(j) IN (OPERATOR_ROUNDTONEAREST,
7128                                 OPERATOR_ROUNDUPTONEAREST,
7129                                 OPERATOR_ROUNDDOWNTONEAREST))THEN
7130       RETURN GENERATE_MATH_ROUND(j);
7131 
7132     ELSIF(v_tExprSubtype(j) IN (OPERATOR_CEILING,
7133                                 OPERATOR_FLOOR,
7134                                 OPERATOR_ROUND,
7135                                 OPERATOR_TRUNCATE))THEN
7136       RETURN GENERATE_ROUND(j);
7137 
7138     ELSIF(v_tExprSubtype(j) IN (OPERATOR_AND,
7139                                 OPERATOR_OR))THEN
7140       RETURN GENERATE_ANDOR(j, ListType);
7141 
7142     ELSIF(v_tExprSubtype(j) IN (OPERATOR_ANYOF,
7143                                 OPERATOR_ALLOF))THEN
7144       RETURN GENERATE_ANYALLOF(j, ListType);
7145 
7146     ELSIF(v_tExprSubtype(j) = OPERATOR_NOT)THEN
7147       RETURN GENERATE_NOT(j);
7148 
7149     ELSIF(v_tExprSubtype(j) = OPERATOR_NOTTRUE)THEN
7150       RETURN GENERATE_NOTTRUE(j);
7151 
7152     ELSIF(v_tExprSubtype(j) IN (OPERATOR_EQUALS,
7153                                 OPERATOR_NOTEQUALS,
7154                                 OPERATOR_GT,
7155                                 OPERATOR_LT,
7156                                 OPERATOR_GE,
7157                                 OPERATOR_LE,
7158                                 OPERATOR_EQUALS_INT,
7159                                 OPERATOR_NOTEQUALS_INT,
7160                                 OPERATOR_GT_INT,
7161                                 OPERATOR_LT_INT,
7162                                 OPERATOR_GE_INT,
7163                                 OPERATOR_LE_INT,
7164                                 OPERATOR_BEGINSWITH,
7165                                 OPERATOR_ENDSWITH,
7166                                 OPERATOR_CONTAINS,
7167                                 OPERATOR_LIKE,
7168                                 OPERATOR_MATCHES,
7169                                 OPERATOR_DOESNOTBEGINWITH,
7170                                 OPERATOR_DOESNOTENDWITH,
7171                                 OPERATOR_DOESNOTCONTAIN,
7172                                 OPERATOR_NOTLIKE))THEN
7173       RETURN GENERATE_COMPARE(j);
7174 
7175     ELSIF(v_tExprSubtype(j) = OPERATOR_CONCAT)THEN
7176       RETURN GENERATE_CONCAT(j, ListType);
7177 
7178     ELSIF(v_tExprSubtype(j) = OPERATOR_TOTEXT)THEN
7179 
7180       --Bug 5620750 - recognize and handle the new ToText operator when used outside of PBC
7181       --context.
7182 
7183       RETURN GENERATE_TOTEXT(j, ListType);
7184 
7185     ELSIF(v_tExprSubtype(j) = OPERATOR_OPTIONSOF)THEN
7186       RETURN GENERATE_OF(j);
7187 
7188     ELSIF(v_tExprSubtype(j) IN (OPERATOR_MIN,
7189                                 OPERATOR_MAX))THEN
7190       RETURN GENERATE_MINMAX(j);
7191 
7192     ELSIF(v_tExprSubtype(j) IN (OPERATOR_VAL))THEN
7193       RETURN GENERATE_VAL(j);
7194 
7195     ELSIF(v_tExprSubtype(j) IN (RULE_OPERATOR_REQUIRES,
7196                                 RULE_OPERATOR_IMPLIES,
7197                                 RULE_OPERATOR_EXCLUDES,
7198                                 RULE_OPERATOR_NEGATES,
7199                                 RULE_OPERATOR_DEFAULTS))THEN
7200       RETURN GENERATE_LOGIC_TREE(j);
7201 
7202     ELSIF(v_tExprSubtype(j) IN (RULE_OPERATOR_CONTRIBUTES,
7203                                 RULE_OPERATOR_CONSUMES))THEN
7204       RETURN GENERATE_NUMERIC_TREE(j);
7205 
7206     ELSE
7207 
7208       --This is not a built-in operator (primitive template), so generate it as a template application.
7209       --Right now there is no reason to report it as unknown.
7210 
7211       RETURN GENERATE_TEMPLATE_APPLICATION (j, ListType);
7212 
7213       --nParam := v_tExprSubtype(j);
7214       --RAISE CZ_E_UNKNOWN_OPERATOR_TYPE;
7215     END IF;
7216 
7217   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_LITERAL)THEN
7218 
7219     RETURN GENERATE_LITERAL(j);
7220 
7221   ELSIF(v_tExprType(j) = EXPR_NODE_TYPE_CONSTANT)THEN
7222 
7223     RETURN GENERATE_CONSTANT(j);
7224 
7225   ELSIF(v_tExprType(j) IN (EXPR_FORALL, EXPR_FORALL_DISTINCT))THEN
7226 
7227     v_result := GENERATE_FORALL(j, ListType);
7228 
7229     FOR i IN 1..v_result.COUNT LOOP
7230          v_return(i) := v_result(i).node_obj;
7231 	 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
7232 		v_return(i) := GENERATE_NAME_EXPL(v_result(i).node_id_ex, v_result(i).node_id);
7233          END IF;
7234     END LOOP;
7235 
7236   ELSIF(v_tExprType(j) = EXPR_COMPATIBLE)THEN
7237 
7238     RETURN GENERATE_COMPATIBLE(j, ListType);
7239 
7240   ELSIF(v_tExprType(j) = EXPR_ARGUMENT)THEN
7241 
7242     IF(v_ChildrenIndex.EXISTS(v_tExprId(j)))THEN
7243 
7244       RETURN GENERATE_REFNODE(j, ListType);
7245     ELSE
7246 
7247       ListType := DATA_TYPE_VOID;
7248       RETURN GENERATE_ARGUMENT(j, ListType);
7249     END IF;
7250 
7251   ELSE
7252 
7253     RAISE CZ_E_UNKNOWN_EXPR_TYPE;
7254   END IF;
7255  RETURN v_return;
7256 END;
7257 ---------------------------------------------------------------------------------------
7258 PROCEDURE GENERATE_COMPATIBILITY_TABLE IS
7259   v_tOptionId       tOptionId;
7260   v_OptionExists    tIntegerArray_idx_vc2; --kdande; Bug 6881902; 11-Mar-2008
7261   v_RowLines        tStringArray;
7262   v_ItemLines       tStringArray;
7263   itemIndex         PLS_INTEGER;
7264   itemCount         PLS_INTEGER := 1;
7265   nChild            PLS_INTEGER;
7266   nCounter          PLS_INTEGER;
7267   ExcludesRequired  PLS_INTEGER;
7268   PrimaryCount      PLS_INTEGER;
7269   localString       VARCHAR2(25);
7270   localNumber       PLS_INTEGER;
7271 BEGIN
7272 
7273 nDebug := 5000001;
7274 
7275   FOR i IN 1..v_tExprPsNodeId.COUNT LOOP
7276 
7277     v_tOptionId.DELETE;
7278     v_OptionExists.DELETE;
7279 
7280 nDebug := 5000002;
7281 
7282     SELECT secondary_opt_id BULK COLLECT INTO v_tOptionId
7283     FROM cz_des_chart_cells
7284     WHERE deleted_flag = FLAG_NOT_DELETED
7285       AND rule_id = nRuleId
7286       AND secondary_feature_id = v_tExprPsNodeId(i)
7287       AND secondary_feat_expl_id = v_tExplNodeId(i);
7288 
7289     IF(v_tOptionId.COUNT = 0)THEN
7290       RAISE CZ_R_EMPTY_COMPAT_RULE;
7291     ELSIF(i = 1)THEN
7292       PrimaryCount := v_tOptionId.COUNT;
7293     ELSE
7294       IF(v_tOptionId.COUNT <> PrimaryCount)THEN
7295         RAISE CZ_R_WRONG_COMPAT_TABLE;
7296       END IF;
7297     END IF;
7298 
7299 nDebug := 5000003;
7300 
7301     FOR n IN 1..v_tOptionId.COUNT LOOP
7302 
7303       --Make sure the option exists
7304 
7305       IF(NOT glIndexByPsNodeId.EXISTS(v_tOptionId(n)))THEN
7306         RAISE CZ_R_INCORRECT_NODE_ID;
7307       END IF;
7308 
7309       IF(NOT v_OptionExists.EXISTS(v_tOptionId(n)))THEN
7310 
7311 nDebug := 5000004;
7312 
7313        v_ItemLines(itemCount) := GENERATE_NAME(i, v_tOptionId(n)) || ' ' || TO_CHAR(i - 1);
7314        v_OptionExists(v_tOptionId(n)) := itemCount;
7315        itemCount := itemCount + 1;
7316 
7317       END IF;
7318 
7319 nDebug := 5000005;
7320 
7321       itemIndex := v_OptionExists(v_tOptionId(n));
7322 
7323       IF(v_RowLines.EXISTS(n))THEN
7324         v_RowLines(n) := v_RowLines(n) || ' ' || TO_CHAR(itemIndex - 1);
7325       ELSE
7326         v_RowLines(n) := ' ' || TO_CHAR(itemIndex - 1);
7327       END IF;
7328 
7329     END LOOP;
7330 
7331 nDebug := 5000006;
7332 
7333     nChild := glIndexByPsNodeId(v_tExprPsNodeId(i)) + 1;
7334     nCounter := nChild;
7335     ExcludesRequired := 0;
7336 
7337 nDebug := 5000007;
7338 
7339     WHILE(glParentId.EXISTS(nChild) AND glParentId(nChild) = v_tExprPsNodeId(i))LOOP
7340      IF(NOT v_OptionExists.EXISTS(glPsNodeId(nChild)))THEN
7341        ExcludesRequired := 1;
7342        EXIT;
7343      END IF;
7344      nChild := nChild + 1;
7345     END LOOP;
7346 
7347 nDebug := 5000008;
7348 
7349     IF(ExcludesRequired = 1)THEN
7350 
7351      nChild := nCounter;
7352 
7353      vLogicLine := 'GS E ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N ';
7354      PACK;
7355 
7356      WHILE(glParentId.EXISTS(nChild) AND glParentId(nChild) = v_tExprPsNodeId(i))LOOP
7357       IF(NOT v_OptionExists.EXISTS(glPsNodeId(nChild)))THEN
7358         vLogicLine := GENERATE_NAME(i, glPsNodeId(nChild)) || ' ';
7359         PACK;
7360       END IF;
7361       nChild := nChild + 1;
7362      END LOOP;
7363 
7364 nDebug := 5000009;
7365 
7366      vLogicLine := NewLine || 'GR L ';
7367      PACK;
7368 
7369      FOR n IN 1..v_tExprPsNodeId.COUNT LOOP
7370        IF(n <> i)THEN
7371          vLogicLine := GENERATE_NAME(n, v_tExprPsNodeId(n)) || ' ';
7372          PACK;
7373        END IF;
7374      END LOOP;
7375 
7376 nDebug := 5000010;
7377 
7378      vLogicLine := NewLine;
7379      PACK;
7380     END IF; --Excludes required
7381   END LOOP;
7382 
7383 nDebug := 5000011;
7384 
7385   vLogicLine := 'OBJECT P_R' || TO_CHAR(nRuleId) || NewLine ||
7386                 'COMBO P_R' || TO_CHAR(nRuleId) || ' ' || TO_CHAR(v_ItemLines.COUNT) || ' ' ||
7387                 TO_CHAR(v_RowLines.COUNT) || ' ' || TO_CHAR(v_tExprPsNodeId.COUNT) || ' ... ' ||
7388                 TO_CHAR(nReasonId) || NewLine;
7389   PACK;
7390 
7391 nDebug := 5000012;
7392 
7393   FOR i IN 1..v_ItemLines.COUNT LOOP
7394 
7395     vLogicLine := 'CI ' || TO_CHAR(i - 1) || ' ' || v_ItemLines(i) || NewLine;
7396     PACK;
7397 
7398   END LOOP;
7399 
7400 nDebug := 5000013;
7401 
7402   FOR i IN 1..v_tExprPsNodeId.COUNT LOOP
7403 
7404     IF(GenerateGatedCombo = 0)THEN
7405 
7406       --Use intermediate variable instead of using NVL because this is faster
7407 
7408       localNumber := glIndexByPsNodeId(v_tExprPsNodeId(i));
7409       localString := TO_CHAR(glMaximum(localNumber));
7410 
7411       --If it's a BOM item, we use maximum_selected instead of maximum
7412 
7413       IF(glPsNodeType(localNumber) IN (PS_NODE_TYPE_BOM_MODEL,PS_NODE_TYPE_BOM_OPTIONCLASS,PS_NODE_TYPE_BOM_STANDARD))THEN
7414        localString := TO_CHAR(glMaximumSel(localNumber));
7415       END IF;
7416 
7417       IF(localString IS NULL)THEN localString := '-1'; END IF;
7418       vLogicLine := ' O';
7419     ELSE
7420 
7421       --Generate gated combinations: maximum is always -1, the 'G' argument is followed
7422       --by the feature name.
7423 
7424       localString := '-1';
7425       vLogicLine := ' G ' || GENERATE_NAME(i, v_tExprPsNodeId(i));
7426     END IF;
7427 
7428     vLogicLine := 'CC ' || TO_CHAR(i - 1) || ' 0 ' || localString || vLogicLine || NewLine;
7429     PACK;
7430 
7431   END LOOP;
7432 
7433 nDebug := 5000014;
7434 
7435   FOR i IN 1..v_RowLines.COUNT LOOP
7436 
7437     vLogicLine := 'CR ' || TO_CHAR(i - 1) || v_RowLines(i) || NewLine;
7438     PACK;
7439 
7440   END LOOP;
7441 
7442 nDebug := 5000015;
7443 
7444   vLogicLine := 'COMBO_END' || NewLine;
7445   PACK;
7446 
7447 END;
7448 ---------------------------------------------------------------------------------------
7449 PROCEDURE GENERATE_DESIGNCHART_RULE IS
7450   vGridColumns      tPsNodeId;
7451   vBackIndex        tIntegerArray;
7452   nIndex            PLS_INTEGER;
7453 ---------------------------------------------------------------------------------------
7454 PROCEDURE GENERATE_COMPAT_TEMPLATE(inSuffix IN PLS_INTEGER) IS
7455   v_tOptionId         tOptionId;
7456   v_tPrimaryOptId     tOptionId;
7457   v_tPrimaryId        tOptionId;
7458   v_OptionExists      tIntegerArray_idx_vc2; --kdande; Bug 6881902; 11-Mar-2008
7459   v_OptionsUsed       tIntegerArray;
7460   v_StartOptionsUsed  tIntegerArray;
7461   v_EndOptionsUsed    tIntegerArray;
7462   v_ExcludesRequired  tIntegerArray;
7463   v_RowLinesIndex     tIntegerArray;
7464   v_RowLines          tStringArray;
7465   v_tailRowLines      tStringArray;
7466   v_ItemLines         tStringArray;
7467   itemIndex           PLS_INTEGER;
7468   itemCount           PLS_INTEGER := 1;
7469   startCount          PLS_INTEGER;
7470   nChild              PLS_INTEGER;
7471   localString         VARCHAR2(25);
7472   localNumber         PLS_INTEGER;
7473 ---------------------------------------------------------------------------------------
7474 FUNCTION OPTION_EXISTS(nIndex IN PLS_INTEGER) RETURN PLS_INTEGER IS
7475 BEGIN
7476   FOR j IN v_StartOptionsUsed(nIndex)..v_EndOptionsUsed(nIndex) LOOP
7477    IF(v_OptionsUsed(j) = glPsNodeId(nChild))THEN RETURN 1; END IF;
7478   END LOOP;
7479  RETURN 0;
7480 END;
7481 ---------------------------------------------------------------------------------------
7482 --This procedure implements a version of QuickSort algorythm which sorts not the array
7483 --itself, but the array of pointers instead
7484 
7485 PROCEDURE SORT_ARRAY_INDEX(indexStart IN PLS_INTEGER, indexEnd IN PLS_INTEGER) IS
7486   localStart  PLS_INTEGER;
7487   localEnd    PLS_INTEGER;
7488   localSwap   PLS_INTEGER;
7489   RowLine     VARCHAR2(4000);
7490 BEGIN
7491 
7492   IF(indexStart >= indexEnd)THEN RETURN; END IF;
7493 
7494   localStart := indexStart;
7495   localEnd := indexEnd;
7496   RowLine := v_tailRowLines(v_RowLinesIndex((localStart + localEnd) / 2));
7497 
7498   WHILE(localStart < localEnd)LOOP
7499 
7500     WHILE(localStart < localEnd AND v_tailRowLines(v_RowLinesIndex(localStart)) < RowLine) LOOP
7501       localStart := localStart + 1;
7502     END LOOP;
7503 
7504     WHILE(localStart < localEnd AND v_tailRowLines(v_RowLinesIndex(localEnd)) > RowLine) LOOP
7505       localEnd := localEnd - 1;
7506     END LOOP;
7507 
7508     IF(localStart < localEnd)THEN
7509       localSwap := v_RowLinesIndex(localStart);
7510       v_RowLinesIndex(localStart) := v_RowLinesIndex(localEnd);
7511       v_RowLinesIndex(localEnd) := localSwap;
7512     END IF;
7513 
7514     localStart := localStart + 1;
7515     localEnd := localEnd - 1;
7516 
7517   END LOOP;
7518 
7519   IF(localEnd < localStart)THEN
7520     localSwap := localEnd;
7521     localEnd := localStart;
7522     localStart := localSwap;
7523   END IF;
7524 
7525   SORT_ARRAY_INDEX(indexStart, localStart);
7526   IF(localStart = indexStart)THEN localStart := localStart + 1; END IF;
7527   SORT_ARRAY_INDEX(localStart, indexEnd);
7528 END;
7529 ---------------------------------------------------------------------------------------
7530 BEGIN
7531 
7532 nDebug := 5000200;
7533 
7534   FOR i IN 1..vGridColumns.COUNT LOOP --Validation and initial data for features
7535 
7536 nDebug := 5000201;
7537 
7538     IF(i = 1)THEN
7539 
7540       --Read the list of participating options of the primary feature. Make a copy of the list
7541       --for the rule verification purposes (bug #2257421).
7542 
7543        SELECT primary_opt_id, primary_opt_id BULK COLLECT INTO v_tOptionId, v_tPrimaryOptId
7544        FROM cz_des_chart_cells
7545        WHERE rule_id = nRuleId
7546          AND secondary_feature_id = vGridColumns(2)
7547          AND secondary_feat_expl_id = v_tExplNodeId(vBackIndex(2))
7548          AND deleted_flag = FLAG_NOT_DELETED
7549        ORDER BY 1, 2;
7550 
7551        IF(v_tOptionId.COUNT = 0)THEN
7552 
7553        --The previous query returned no rows. That means that there're no selections made for
7554        --any of the primary feature options. It's OK if we are processing an optional table,
7555        --but for the defining table we raise an exception.
7556 
7557          IF(inSuffix = 0)THEN --we are processing the defining table
7558            RAISE CZ_R_NO_DEFINING_SELECTION;
7559          END IF;
7560 
7561        --This is an optional table with no selections - don't generate the COMBO, just generate
7562        --an EXCLUDE relation and exit the procedure.
7563 
7564          vLogicLine := 'GS E ... ' || TO_CHAR(nReasonId) || NewLine ||
7565                        'GL N ' || GENERATE_NAME(vBackIndex(1), vGridColumns(1)) || NewLine ||
7566                        'GR L ' || GENERATE_NAME(vBackIndex(2), vGridColumns(2)) || NewLine;
7567          PACK;
7568          RETURN;
7569 
7570        END IF;
7571 
7572     ELSE
7573 
7574 nDebug := 5000202;
7575 
7576       v_tOptionId.DELETE;
7577       v_tPrimaryId.DELETE;
7578       v_OptionExists.DELETE;
7579 
7580       --Read the list of participating options of defining or optional feature.
7581 
7582       SELECT secondary_opt_id, primary_opt_id BULK COLLECT INTO v_tOptionId, v_tPrimaryId
7583       FROM cz_des_chart_cells
7584       WHERE rule_id = nRuleId
7585         AND secondary_feature_id = vGridColumns(i)
7586         AND secondary_feat_expl_id = v_tExplNodeId(vBackIndex(i))
7587         AND deleted_flag = FLAG_NOT_DELETED
7588       ORDER BY primary_opt_id;
7589 
7590       FOR n IN 1..v_tOptionId.COUNT LOOP
7591 
7592         IF(NOT glIndexByPsNodeId.EXISTS(v_tPrimaryId(n)))THEN
7593 
7594           BEGIN
7595             SELECT name INTO errorMessage FROM cz_ps_nodes
7596              WHERE ps_node_id = v_tPrimaryId(n);
7597           EXCEPTION
7598             WHEN OTHERS THEN
7599               errorMessage := 'Unknown';
7600           END;
7601 
7602           RAISE CZ_R_DELETED_OPTION;
7603         END IF;
7604 
7605         --Bug #2257421. The list of corresponding primary options which participate in the rule should be
7606         --equal for all defining features.
7607         --v_tPrimaryOptId - the ordered list of primary options checked for the first defining feature.
7608         --v_tPrimaryId - the ordered list of primary options checked for the current feature.
7609 
7610         IF((NOT v_tPrimaryOptId.EXISTS(n)) OR (v_tPrimaryOptId(n) > v_tPrimaryId(n)))THEN
7611 
7612            --Too many selections made.
7613 
7614            auxCount := glIndexByPsNodeId(vGridColumns(1));
7615            auxIndex := glIndexByPsNodeId(v_tPrimaryId(n));
7616            RAISE CZ_R_INCOMPLETE_DES_CHART;
7617 
7618         ELSIF(v_tPrimaryOptId(n) < v_tPrimaryId(n))THEN
7619 
7620            --Too few selections made.
7621 
7622            auxCount := glIndexByPsNodeId(vGridColumns(1));
7623            auxIndex := glIndexByPsNodeId(v_tPrimaryOptId(n));
7624            RAISE CZ_R_INCOMPLETE_DES_CHART;
7625         END IF;
7626       END LOOP;
7627 
7628       IF(v_tPrimaryOptId.EXISTS(v_tOptionId.COUNT + 1))THEN
7629 
7630            --Too few selections made.
7631 
7632            auxCount := glIndexByPsNodeId(vGridColumns(1));
7633            auxIndex := glIndexByPsNodeId(v_tPrimaryOptId(v_tOptionId.COUNT + 1));
7634            RAISE CZ_R_INCOMPLETE_DES_CHART;
7635       END IF;
7636     END IF;
7637 
7638     startCount := itemCount;
7639 
7640     FOR n IN 1..v_tOptionId.COUNT LOOP
7641 
7642       --Make sure the option exists.
7643 
7644       IF(NOT glIndexByPsNodeId.EXISTS(v_tOptionId(n)))THEN
7645 
7646         BEGIN
7647           SELECT name INTO errorMessage FROM cz_ps_nodes
7648            WHERE ps_node_id = v_tOptionId(n);
7649         EXCEPTION
7650           WHEN OTHERS THEN
7651             errorMessage := 'Unknown';
7652         END;
7653 
7654         RAISE CZ_R_DELETED_OPTION;
7655       END IF;
7656 
7657       IF(NOT v_OptionExists.EXISTS(v_tOptionId(n)))THEN
7658 
7659 nDebug := 5000203;
7660 
7661        v_ItemLines(itemCount) := GENERATE_NAME(vBackIndex(i), v_tOptionId(n)) || ' ' || TO_CHAR(i - 1);
7662        v_OptionsUsed(itemCount) := v_tOptionId(n);
7663        v_OptionExists(v_tOptionId(n)) := itemCount;
7664        itemCount := itemCount + 1;
7665 
7666       END IF;
7667 
7668 nDebug := 5000204;
7669 
7670       itemIndex := v_OptionExists(v_tOptionId(n));
7671       v_RowLinesIndex(n) := n;
7672 
7673       IF(v_RowLines.EXISTS(n))THEN
7674         v_RowLines(n) := v_RowLines(n) || ' ' || TO_CHAR(itemIndex - 1);
7675       ELSE
7676         v_RowLines(n) := ' ' || TO_CHAR(itemIndex - 1);
7677       END IF;
7678 
7679     END LOOP;
7680 
7681     v_ExcludesRequired(i) := 0;
7682 
7683 nDebug := 5000205;
7684 
7685     IF(featOptionsCount(vGridColumns(i)) <> itemCount - startCount)THEN
7686 
7687       v_StartOptionsUsed(i) := startCount;
7688       v_EndOptionsUsed(i) := itemCount - 1;
7689       v_ExcludesRequired(i) := 1;
7690 
7691     END IF;
7692   END LOOP; --Validation and initial data for features
7693 
7694   --Design chart rule specific validation - uniqueness of every column in the chart table.
7695   --At the current step this requirement is equivalent to the requirement of no duplicate
7696   --elements in v_RowLines table. We use the modified QuickSort algorythm to sort out the
7697   --table and then check for duplicate values in one pass.
7698 
7699   IF(inSuffix = 0)THEN --This is the defining table
7700 
7701    --We need a substring of the row starting with the 4th character
7702 
7703    FOR i IN 1..v_RowLines.COUNT LOOP
7704     v_tailRowLines(i) := SUBSTR(v_RowLines(i),4);
7705    END LOOP;
7706 
7707    SORT_ARRAY_INDEX(1, v_tailRowLines.COUNT);
7708    FOR i IN 2..v_tailRowLines.COUNT LOOP
7709     IF(v_tailRowLines(v_RowLinesIndex(i)) = v_tailRowLines(v_RowLinesIndex(i - 1)))THEN
7710 
7711       --Duplicate combination of defining options for a primary option
7712       RAISE CZ_R_DUPLICATE_COMBINATION;
7713 
7714     END IF;
7715    END LOOP;
7716   END IF; --This is the defining table
7717 
7718 nDebug := 5000206;
7719 
7720   FOR i IN 1..vGridColumns.COUNT LOOP
7721 
7722 nDebug := 5000207;
7723 
7724     IF(v_ExcludesRequired(i) = 1)THEN
7725 
7726      nChild := glIndexByPsNodeId(vGridColumns(i)) + 1;
7727 
7728      vLogicLine := 'GS E ... ' || TO_CHAR(nReasonId) || NewLine || 'GL N ';
7729      PACK;
7730 
7731 nDebug := 5000208;
7732 
7733      WHILE(glParentId.EXISTS(nChild) AND glParentId(nChild) = vGridColumns(i))LOOP
7734       IF(OPTION_EXISTS(i) = 0)THEN
7735         vLogicLine := GENERATE_NAME(vBackIndex(i), glPsNodeId(nChild)) || ' ';
7736         PACK;
7737       END IF;
7738       nChild := nChild + 1;
7739      END LOOP;
7740 
7741      vLogicLine := NewLine || 'GR L ';
7742      PACK;
7743 
7744 nDebug := 5000209;
7745 
7746      FOR n IN 1..vGridColumns.COUNT LOOP
7747        IF(n <> i)THEN
7748          vLogicLine := GENERATE_NAME(vBackIndex(n), vGridColumns(n)) || ' ';
7749          PACK;
7750        END IF;
7751      END LOOP;
7752 
7753      vLogicLine := NewLine;
7754      PACK;
7755     END IF; --Excludes required
7756   END LOOP;
7757 
7758 nDebug := 5000210;
7759 
7760   vLogicLine := 'OBJECT P_R' || TO_CHAR(nRuleId) || '_' || TO_CHAR(inSuffix) || NewLine ||
7761                 'COMBO P_R' || TO_CHAR(nRuleId) || '_' || TO_CHAR(inSuffix) || ' ' || TO_CHAR(v_ItemLines.COUNT) || ' ' ||
7762                 TO_CHAR(v_RowLines.COUNT) || ' ' || TO_CHAR(vGridColumns.COUNT) || ' ... ' ||
7763                 TO_CHAR(nReasonId) || NewLine;
7764   PACK;
7765 
7766 nDebug := 5000211;
7767 
7768   FOR i IN 1..v_ItemLines.COUNT LOOP
7769 
7770     vLogicLine := 'CI ' || TO_CHAR(i - 1) || ' ' || v_ItemLines(i) || NewLine;
7771     PACK;
7772 
7773   END LOOP;
7774 
7775 nDebug := 5000212;
7776 
7777   FOR i IN 1..vGridColumns.COUNT LOOP
7778 
7779     IF(GenerateGatedCombo = 0)THEN
7780 
7781       IF(inSuffix = 0 OR i = 1)THEN
7782 
7783         --This is the defining table or the primary feature in an optional table.
7784         --In this case we currently use actual feature's maximum value for the column
7785         --(or maximum_selected for BOM).
7786 
7787         --Use intermediate variable instead of using NVL because this is faster
7788 
7789         localNumber := glIndexByPsNodeId(vGridColumns(i));
7790         localString := TO_CHAR(glMaximum(localNumber));
7791 
7792         --If it's a BOM item, we use maximum_selected instead of maximum
7793 
7794         IF(glPsNodeType(localNumber) IN (PS_NODE_TYPE_BOM_MODEL,PS_NODE_TYPE_BOM_OPTIONCLASS,PS_NODE_TYPE_BOM_STANDARD))THEN
7795          localString := TO_CHAR(glMaximumSel(localNumber));
7796         END IF;
7797 
7798         IF(localString IS NULL)THEN localString := '-1'; END IF;
7799 
7800       ELSE
7801         --For optional features in optional tables we always use '-1' for columns' maximum value.
7802 
7803         localString := '-1';
7804       END IF;
7805 
7806       vLogicLine := ' O';
7807     ELSE
7808 
7809       --Generate gated combinations: maximum is always -1, the 'G' argument is followed
7810       --by the feature name.
7811 
7812       localString := '-1';
7813       vLogicLine := ' G ' || GENERATE_NAME(vBackIndex(i), vGridColumns(i));
7814     END IF;
7815 
7816     vLogicLine := 'CC ' || TO_CHAR(i - 1) || ' 0 ' || localString || vLogicLine || NewLine;
7817     PACK;
7818 
7819   END LOOP;
7820 
7821 nDebug := 5000213;
7822 
7823   FOR i IN 1..v_RowLines.COUNT LOOP
7824 
7825     vLogicLine := 'CR ' || TO_CHAR(i - 1) || v_RowLines(i) || NewLine;
7826     PACK;
7827 
7828   END LOOP;
7829 
7830 nDebug := 5000214;
7831 
7832   vLogicLine := 'COMBO_END' || NewLine;
7833   PACK;
7834 END;
7835 ---------------------------------------------------------------------------------------
7836 BEGIN
7837 
7838   --Generate the defining table
7839 
7840   nIndex := 2;
7841 
7842   FOR i IN expressionStart..expressionEnd LOOP
7843 
7844     IF(v_tFeatureType(i) = FEATURE_TYPE_DEFINING)THEN
7845       vGridColumns(nIndex) := v_tExprPsNodeId(i);
7846       vBackIndex(nIndex) := i;
7847       nIndex := nIndex + 1;
7848     ELSIF(v_tFeatureType(i) = FEATURE_TYPE_PRIMARY)THEN
7849       vGridColumns(1) := v_tExprPsNodeId(i);
7850       vBackIndex(1) := i;
7851     END IF;
7852 
7853   END LOOP;
7854 
7855   IF(vGridColumns.COUNT = 0)THEN
7856     RAISE CZ_R_NO_PRIMARY_FEATURE;
7857   ELSIF(vGridColumns.COUNT > 1)THEN
7858     GENERATE_COMPAT_TEMPLATE(0);
7859     vGridColumns.DELETE(2, vGridColumns.COUNT);
7860     vBackIndex.DELETE(2, vBackIndex.COUNT);
7861   END IF;
7862 
7863   --Generate all the optional tables
7864 
7865   nIndex := 1;
7866 
7867   FOR i IN expressionStart..expressionEnd LOOP
7868 
7869     IF(v_tFeatureType(i) = FEATURE_TYPE_OPTIONAL)THEN
7870       vGridColumns(2) := v_tExprPsNodeId(i);
7871       vBackIndex(2) := i;
7872       GENERATE_COMPAT_TEMPLATE(nIndex);
7873       nIndex := nIndex + 1;
7874     END IF;
7875 
7876   END LOOP;
7877 END;
7878 ---------------------------------------------------------------------------------------
7879 BEGIN --GENERATE_RULES
7880 
7881 nDebug := 0;
7882 
7883   IF(t_RuleId.COUNT = 0)THEN
7884 
7885     --This should be done only once during the generation session. The data is static and common
7886     --to all models.
7887 
7888     SELECT rule_id, signature_id, name BULK COLLECT INTO t_RuleId, t_SignatureId, t_RuleName
7889       FROM cz_rules
7890      WHERE devl_project_id = 0
7891        AND seeded_flag = FLAG_SEEDED
7892        AND deleted_flag = FLAG_NOT_DELETED
7893        AND disabled_flag = FLAG_NOT_DISABLED;
7894 
7895     --Make the table of names hashed by rule_id.
7896 
7897     FOR i IN 1..t_RuleId.COUNT LOOP
7898 
7899       h_SeededName(t_RuleId(i)) := UPPER(t_RuleName(i));
7900       h_ReportName(t_RuleId(i)) := t_RuleName(i);
7901       h_SignatureId(t_RuleId(i)) := t_SignatureId(i);
7902     END LOOP;
7903   END IF;
7904 
7905 nDebug := 1;
7906 
7907   --Make a quick and simple verification of all functional companions defined in this
7908   --project. All other rule related instances that do not reside in cz_rules can also
7909   --be processed in this section.
7910   --Added as a fix for the bug #2200481.
7911 
7912   --Restoring this block in 11.5.10+, bug #3989382.
7913 
7914   FOR c_func IN (SELECT component_id, model_ref_expl_id, program_string, name, rule_folder_id
7915                    FROM cz_func_comp_specs
7916                   WHERE devl_project_id = inComponentId
7917                     AND deleted_flag = FLAG_NOT_DELETED) LOOP
7918 
7919     IF(c_func.component_id IS NULL)THEN
7920 
7921       --'Incomplete data: No base component specified for functional companion ''%COMPANION'' in model ''%MODELNAME''.'
7922       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);
7923 
7924     ELSIF(c_func.program_string IS NULL)THEN
7925 
7926       --'Incomplete data: No program string specified for functional companion ''%COMPANION'' in model ''%MODELNAME''.'
7927       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);
7928 
7929     ELSIF(NOT glIndexByPsNodeId.EXISTS(c_func.component_id))THEN
7930 
7931       --'Internal data error. Incorrect product structure data for functional companion ''%COMPANION'' in model ''%MODELNAME''.'
7932       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);
7933 
7934     ELSIF(c_func.model_ref_expl_id IS NULL OR (NOT v_IndexByNodeId.EXISTS(c_func.model_ref_expl_id)))THEN
7935 
7936       --'Internal data error. Incorrect explosion data for functional companion ''%COMPANION'' in model ''%MODELNAME''.'
7937       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);
7938     END IF;
7939   END LOOP;
7940 
7941   --Calculate downpathes for all explosion nodes here
7942 
7943 nDebug := 1000007;
7944 
7945   FOR i IN 1..v_NodeId.COUNT LOOP
7946 
7947 nDebug := 1000002;
7948 
7949    --Unconditionally create rule files for all the non-virtual components of the
7950    --model primary structure and all first-level reference nodes and put the INC
7951    --relation there.
7952 
7953     IF(v_tVirtualFlag(i) = FLAG_NON_VIRTUAL AND v_tNodeDepth(i) > 0 AND
7954        (v_tChildModelExpl(i) IS NULL OR
7955         (v_tNodeType(i) = PS_NODE_TYPE_REFERENCE AND
7956          v_tChildModelExpl(v_IndexByNodeId(v_tParentId(i))) IS NULL)
7957        ))THEN
7958 
7959 nDebug := 1000003;
7960 
7961      nHeaderId := next_lce_header_id;
7962 
7963      BEGIN
7964 
7965 nDebug := 1000004;
7966 
7967       --Insert the rule net logic header record into the table.
7968 
7969       INSERT INTO cz_lce_headers
7970        (lce_header_id, gen_version, gen_header, component_id, net_type,
7971         devl_project_id, model_ref_expl_id, nbr_required_expls, deleted_flag)
7972       VALUES
7973        (nHeaderId, VersionString, GenHeader, v_tPsNodeId(i), LOGIC_NET_TYPE_MANDATORY,
7974         thisProjectId, v_NodeId(i), 1, FLAG_PENDING);
7975 
7976       INSERT INTO cz_lce_load_specs
7977        (attachment_expl_id, lce_header_id, required_expl_id, attachment_comp_id,
7978         model_id, net_type, deleted_flag)
7979       VALUES
7980        (v_NodeId(i), nHeaderId, v_NodeId(i), v_tPsNodeId(i), thisProjectId,
7981         LOGIC_NET_TYPE_MANDATORY, FLAG_PENDING);
7982 
7983       EXCEPTION
7984         WHEN OTHERS THEN
7985           errorMessage := SQLERRM;
7986           RAISE CZ_R_UNABLE_TO_CREATE_HEADER;
7987       END;
7988 
7989 nDebug := 1000005;
7990 
7991       NewHeaders(counterNewHeaders) := nHeaderId;
7992       NewHeadersComponents(counterNewHeaders) := v_tPsNodeId(i);
7993       NewHeadersExplosions(counterNewHeaders) := v_NodeId(i);
7994       counterNewHeaders := counterNewHeaders + 1;
7995 
7996 nDebug := 1000006;
7997 
7998       --Use intermediate variable instead of using NVL because this is faster
7999 
8000       IF(v_tReferringId(i) IS NOT NULL)THEN
8001        localString := TO_CHAR(glPersistentId(v_tReferringId(i)));
8002       ELSE
8003        localString := TO_CHAR(glPersistentId(v_tPsNodeId(i)));
8004       END IF;
8005 
8006       vLogicLine := 'CONTROL NOSPEC' || NewLine || 'VERSION 3 3' || NewLine || NewLine ||
8007                     'REM -- Rules file for component: ' || TO_CHAR(v_tPsNodeId(i)) ||
8008                     ', explosion node: ' || TO_CHAR(v_NodeId(i)) || NewLine || NewLine ||
8009                     'EFF , , ' || NewLine || NewLine ||
8010                     'INC 1 ' || PATH_DELIMITER || 'parent' || PATH_DELIMITER || 'P_' ||
8011                     localString || '_ACTUALCOUNT round' || NewLine;
8012 
8013       INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES (nHeaderId, 1, vLogicLine);
8014 
8015       v_tIsHeaderGenerated(v_NodeId(i)) := nHeaderId;
8016       v_tSequenceNbr(nHeaderId) := 2;
8017       v_tLogicNetType(nHeaderId) := LOGIC_NET_TYPE_MANDATORY;
8018 
8019       --This variable is not supposed to be used as an accumulator for logic text. Instead,  it
8020       --is used as a buffer every time to store a piece of text to be accumulated in vLogicText
8021       --(see PACK procedure). Therefore, it should be safe to null it out here even if it's not
8022       --necessary.
8023 
8024       vLogicLine := NULL;
8025     END IF;
8026 
8027 nDebug := 1000008;
8028 
8029     --Here we will construct model level downpaths, which do not depend on a particular rule,
8030     --but only on explosion id within the model's explosion tree. When a particular rule is
8031     --assigned, downpaths of its participants may be prepended with segments including all A
8032     --type nodes from assignee to assignable. This corrected downpaths are always used when
8033     --generating names of the rule's participants.
8034 
8035     nAux := v_NodeId(i);
8036     auxIndex := v_tNodeDepth(i) + 1;
8037 
8038     IF(NOT v_NodeDownPath.EXISTS(nAux))THEN
8039 
8040 nDebug := 1000009;
8041 
8042       v_NodeDownPath(nAux) := ''; --start building the downpath
8043       v_NodeIndexPath.DELETE; --reset the table
8044 
8045       --These all are index values in v_NodeIndexPath.
8046 
8047       ConnectorIndex := 0;
8048       InstantiableIndex := auxIndex;
8049       OptionalIndex := auxIndex;
8050       TrackableIndex := auxIndex;
8051       nCounter := 1;
8052       auxCount := 0;
8053 
8054       --Go all the way up from the explosion id and find the deepest D node and the
8055       --shallowest connector, and also the deepest optional node.
8056       --We are interested in the shallowest reference to a trackable model as well.
8057       --It will be used only if the root model is marked as a network container. If
8058       --there is no such reference above the explosion node the root node is used.
8059 
8060       WHILE(nAux IS NOT NULL) LOOP
8061 
8062         localCount := v_IndexByNodeId(nAux);
8063 
8064         --Detect infinite loops which may be caused by data corruption.
8065 
8066         auxCount := auxCount + 1;
8067         IF(auxCount > LOOP_DETECTED_LOOPS_NUMBER)THEN
8068 
8069           errorMessage := glName(glIndexByPsNodeId(inProjectId));
8070           RAISE CZ_G_INVALID_MODEL_EXPLOSION;
8071         END IF;
8072 
8073         --The next IF statement has been added as a fix for the bug #2802049. In case of circular
8074         --connectors it is possible that the explosion table of the second level-referenced model
8075         --contains pointers to ps node structure of the parent model that hasn't been read yet.
8076         --As in this case we do not need to generate downpaths, we can just ignore such pointers.
8077 
8078         IF(NOT glIndexByPsNodeId.EXISTS(NVL(v_tReferringId(localCount), v_tPsNodeId(localCount))))THEN
8079 
8080           auxCount := -1;
8081           EXIT;
8082         END IF;
8083 
8084         IF(v_TypeByExplId(nAux) = EXPL_NODE_TYPE_CONNECTOR)THEN
8085 
8086           ConnectorIndex := nCounter;
8087         ELSIF(v_TypeByExplId(nAux) = EXPL_NODE_TYPE_OPTIONAL AND OptionalIndex = auxIndex)THEN
8088 
8089           OptionalIndex := nCounter;
8090         ELSIF(v_TypeByExplId(nAux) = EXPL_NODE_TYPE_INSTANTIABLE)THEN
8091 
8092           IF(InstantiableIndex = auxIndex)THEN InstantiableIndex := nCounter; END IF;
8093 
8094           IF(v_tNodeType(localCount) = PS_NODE_TYPE_REFERENCE AND
8095              glIbTrackable(v_tPsNodeId(localCount)) = FLAG_IB_TRACKABLE)THEN
8096 
8097              TrackableIndex := nCounter;
8098           END IF;
8099         END IF;
8100 
8101        v_NodeIndexPath(nCounter) := localCount;
8102        nCounter := nCounter + 1;
8103 
8104        nAux := v_tParentId(localCount);
8105       END LOOP;
8106 
8107       IF(auxCount = -1)THEN
8108 
8109         --This is the 'circular connectors' case, we don't need any downpath.
8110         NULL;
8111 
8112       ELSIF(InstantiableIndex < ConnectorIndex)THEN
8113 
8114         --There are D nodes under connectors on the path - this explosion cannot participate
8115         --in any rule because it would be impossible to assign such a rule. No downpath.
8116         --For reporting purposes store the cz_ps_nodes indexes of the instantiable component
8117         --and the connector, corresponding exception/message is CZ_R_UNASSIGNABLE_RULE.
8118 
8119         v_ProhibitInRules(v_NodeId(i)) := glIndexByPsNodeId(v_tPsNodeId(v_NodeIndexPath(InstantiableIndex)));
8120         v_ProhibitConnector(v_NodeId(i)) := glIndexByPsNodeId(v_tReferringId(v_NodeIndexPath(ConnectorIndex)));
8121 
8122       ELSIF(OptionalIndex < ConnectorIndex)THEN
8123 
8124         --There are A nodes under connectors on the path - this explosion cannot participate
8125         --in any rule - bug #2217450. No downpath.
8126         --For reporting purposes store the cz_ps_nodes indexes of the optional component
8127         --and the connector, corresponding exception/message is CZ_R_OPTIONAL_INSIDE.
8128 
8129         v_ProhibitOptional(v_NodeId(i)) := glIndexByPsNodeId(v_tPsNodeId(v_NodeIndexPath(OptionalIndex)));
8130         v_ProhibitConnector(v_NodeId(i)) := glIndexByPsNodeId(v_tReferringId(v_NodeIndexPath(ConnectorIndex)));
8131 
8132       ELSE
8133 
8134 nDebug := 1000010;
8135 
8136         AssignableIndex := InstantiableIndex;
8137 
8138         --Find the deepest A node between the deepest D node and the shallowest connector.
8139         --This node is the assignable for the explosion id (can be the D node itself).
8140 
8141         FOR n IN ConnectorIndex + 1..InstantiableIndex LOOP
8142           IF(v_tExplNodeType(v_NodeIndexPath(n)) = EXPL_NODE_TYPE_OPTIONAL)THEN
8143 
8144             AssignableIndex := n;
8145             EXIT;
8146           END IF;
8147         END LOOP;
8148 
8149         v_NodeLogicLevel(v_NodeId(i)) := v_tNodeDepth(v_NodeIndexPath(AssignableIndex));
8150 
8151         --Store the main index of the assignable of the explosion node.
8152 
8153         v_NodeAssignable(v_NodeId(i)) := v_NodeIndexPath(AssignableIndex);
8154 
8155         --Store the main index of the deepest instantiable component above the explosion
8156         --node (may be the node itself if it is instantiable, or the root node if there
8157         --is no instantiable components on the way up from the explosion node).
8158 
8159         v_NodeInstantiable(v_NodeId(i)) := v_NodeIndexPath(InstantiableIndex);
8160 
8161         --Store the main index of the shallowest reference to a trackable model.
8162 
8163         v_NodeTrackable(v_NodeId(i)) := v_NodeIndexPath(TrackableIndex);
8164 
8165 nDebug := 1000011;
8166 
8167         --Finally, construct the downpath from the assignable to the explosion id.
8168 
8169         FOR n IN 1..AssignableIndex - 1 LOOP
8170           IF(v_tExplNodeType(v_NodeIndexPath(n)) IN (EXPL_NODE_TYPE_OPTIONAL, EXPL_NODE_TYPE_MANDATORY))THEN
8171 
8172            --This is a mandatory reference or optional component, add N_<persistent_node_id>
8173            --to the path.
8174 
8175            v_NodeDownPath(v_NodeId(i)) := PATH_DELIMITER || 'N_' ||
8176              TO_CHAR(glPersistentId(NVL(v_tReferringId(v_NodeIndexPath(n)), v_tPsNodeId(v_NodeIndexPath(n))))) ||
8177              v_NodeDownPath(v_NodeId(i));
8178 
8179           ELSIF(v_tExplNodeType(v_NodeIndexPath(n)) = EXPL_NODE_TYPE_CONNECTOR)THEN
8180 
8181            --This is a connector, add C_<model_ref_expl_id> to the path.
8182 
8183            v_NodeDownPath(v_NodeId(i)) := PATH_DELIMITER || 'C_' ||
8184              TO_CHAR(v_NodeId(v_NodeIndexPath(n))) || v_NodeDownPath(v_NodeId(i));
8185 
8186            --We will stop here, we do not want anything above the deepest connector to be reflected
8187            --in the path. Set a flag for this explosion because we do not want to prepend downpaths
8188            --for these explosions after the rule is assigned either. Actually, not just a flag, but
8189            --store the connector itself (main index) which may be useful for reporting purposes.
8190 
8191            v_IsConnectorNet(v_NodeId(i)) := v_NodeIndexPath(n);
8192            EXIT;
8193           END IF;
8194         END LOOP;
8195       END IF;
8196     END IF;
8197   END LOOP;
8198 
8199 nDebug := 2;
8200 
8201   OPEN c_rules;
8202   LOOP
8203   BEGIN
8204 
8205     --To generate effectivity information for the first rule. Uses the fact that
8206     --effective mask can not be null.
8207 
8208     vUsageMask := NULL;
8209 
8210     FETCH c_rules INTO
8211      nRuleId, nRuleType, nAntecedentId, nConsequentId, vRuleName, nReasonId, nRuleOperator,
8212      nRuleFolderId, nComponentId, nModelRefExplId, dEffFrom, dEffUntil, vUsageMask,
8213      nRuleEffSetId, nUnsatisfiedId, nUnsatisfiedSource, nPresentationFlag, vClassName;
8214     EXIT WHEN c_rules%NOTFOUND;
8215 
8216    --Do nothing for those rules.
8217 
8218    IF(nRuleType NOT IN (RULE_TYPE_FUNC_COMP, RULE_TYPE_RULE_FOLDER, RULE_TYPE_BINDING_RULE,
8219                         RULE_TYPE_RULE_SYS_PROP, RULE_TYPE_JAVA_SYS_PROP,
8220                         RULE_TYPE_CAPTION_RULE, RULE_TYPE_DISPLAY_CONDITION))THEN
8221 
8222     v_tExplNodeId.DELETE;
8223     v_tExprType.DELETE;
8224     v_tExprSubtype.DELETE;
8225     v_tExprId.DELETE;
8226     v_tExprParentId.DELETE;
8227     v_tExprTemplateId.DELETE;
8228     v_tExpressId.DELETE;
8229     v_tExprPsNodeId.DELETE;
8230     v_tRealPsNodeId.DELETE;
8231     v_tExprDataValue.DELETE;
8232     v_tExprPropertyId.DELETE;
8233     v_tConsequentFlag.DELETE;
8234     v_tExprParamIndex.DELETE;
8235     v_tExprArgumentName.DELETE;
8236     v_tExprDataType.DELETE;
8237     v_tExprDataNumValue.DELETE;
8238     v_tExprArgSignature.DELETE;
8239     v_tExprParSignature.DELETE;
8240     v_tArgumentIndex.DELETE;
8241     v_tDataType.DELETE;
8242     v_tArgumentName.DELETE;
8243     v_InstByLevel.DELETE;
8244     v_Assignable.DELETE;
8245     v_Participant.DELETE;
8246     v_DistinctIndex.DELETE;
8247     v_ParticipantIndex.DELETE;
8248     v_RuleConnectorNet.DELETE;
8249     v_LevelCount.DELETE;
8250     v_LevelIndex.DELETE;
8251     v_LevelType.DELETE;
8252     v_MarkLoadCondition.DELETE;
8253     v_LoadConditionId.DELETE;
8254     v_ChildrenIndex.DELETE;
8255     v_NodeUpPath.DELETE;
8256     v_IndexByExprNodeId.DELETE;
8257     v_NumberOfChildren.DELETE;
8258     v_ExplByPsNodeId.DELETE;
8259     v_RelativeNodePath.DELETE;
8260     parameterScope.DELETE;
8261     parameterName.DELETE;
8262 
8263     jAntecedentRoot  := NULL;
8264     jConsequentRoot  := NULL;
8265     sUnsatisfiedId   := NULL;
8266     RuleTemplateType := RULE_TYPE_UNKNOWN;
8267     numericLHS       := 0;
8268     generateCompare  := 0;
8269     t_prefix         := 'T' || TO_CHAR(nRuleId) || '_';
8270 
8271     --We need to reset the assigned down paths for every rule. Bug #3431166.
8272 
8273     FOR i IN 1..v_NodeId.COUNT LOOP
8274 
8275       --Make a copy that will be used as a rule-specific downpath which may have to be prepended
8276       --after the rule is assigned. It is this copy that will be used for name generation.
8277 
8278       v_AssignedDownPath(v_NodeId(i)) := v_NodeDownPath(v_NodeId(i));
8279     END LOOP;
8280 
8281     --Bug #3180819.
8282 
8283     IF(nPresentationFlag IS NULL)THEN nPresentationFlag := FLAG_FREEFORM_RULE; END IF;
8284 
8285 nDebug := 3;
8286 
8287     --Get the rule participants, differently for different types of rules
8288 
8289     IF(nRuleType = RULE_TYPE_JAVA_METHOD)THEN
8290 
8291       --This is a CX. Call the CX validation procedure and continue with rules.
8292 
8293       localRunId := thisRunId;
8294       cz_developer_utils_pvt.verify_special_rule(nRuleId, vRuleName, localRunId);
8295       RAISE CZ_LCE_CONTINUE;
8296 
8297     ELSIF(nRuleType IN (RULE_TYPE_TEMPLATE, RULE_TYPE_EXPRESSION))THEN
8298 
8299       --Set the unsatisfied message id string.
8300 
8301       IF(nUnsatisfiedSource <> UNSATISFIED_TYPE_NONE)THEN
8302 
8303         sUnsatisfiedId := TO_CHAR(nUnsatisfiedId);
8304         IF(sUnsatisfiedId IS NOT NULL)THEN sUnsatisfiedId := sUnsatisfiedId || ' '; END IF;
8305       END IF;
8306 
8307       SELECT model_ref_expl_id, expr_type, expr_node_id, expr_parent_id, template_id,
8308              express_id, expr_subtype, ps_node_id, data_value, property_id, consequent_flag,
8309              param_index, argument_name, data_type, data_num_value, param_signature_id,
8310              relative_node_path
8311       BULK COLLECT INTO v_tExplNodeId, v_tExprType, v_tExprId, v_tExprParentId, v_tExprTemplateId,
8312                         v_tExpressId, v_tExprSubtype, v_tExprPsNodeId, v_tExprDataValue,
8313                         v_tExprPropertyId, v_tConsequentFlag, v_tExprParamIndex, v_tExprArgumentName,
8314                         v_tExprDataType, v_tExprDataNumValue, v_tExprParSignature,
8315                         v_RelativeNodePath
8316        FROM cz_expression_nodes
8317       WHERE rule_id = nRuleId
8318         AND expr_type <> EXPR_NODE_TYPE_PUNCT
8319         AND deleted_flag = FLAG_NOT_DELETED
8320       ORDER BY expr_parent_id, seq_nbr;
8321 
8322      --Determine the size of the expression for all eventual purposes.
8323 
8324      expressionSize := v_tExprType.COUNT;
8325 
8326      IF(expressionSize = 0)THEN
8327        RAISE CZ_R_NO_PARTICIPANTS;
8328      END IF;
8329 
8330      expressionStart := 1;
8331      expressionEnd := expressionSize;
8332 
8333      FOR i IN expressionStart..expressionEnd LOOP
8334 
8335        IF(v_tExprDataNumValue(i) IS NOT NULL)THEN v_tExprDataValue(i) := TO_CHAR(v_tExprDataNumValue(i)); END IF;
8336 
8337        --Bug #3800352. Resolve the codes by names and emulate regular node types.
8338 
8339        IF(v_tExprType(i) IN (EXPR_PROPERTYBYNAME, EXPR_OPERATORBYNAME, EXPR_JAVAPROPERTYBYNAME))THEN
8340 
8341          FOR n IN 1..t_RuleId.COUNT LOOP
8342 
8343            IF(t_RuleName(n) = v_tExprArgumentName(i))THEN v_tExprTemplateId(i) := t_RuleId(n); EXIT; END IF;
8344          END LOOP;
8345 
8346          IF(v_tExprType(i) = EXPR_PROPERTYBYNAME)THEN
8347 
8348            v_tExprType(i) := EXPR_SYS_PROP;
8349          ELSIF(v_tExprType(i) = EXPR_OPERATORBYNAME)THEN
8350 
8351            v_tExprType(i) := EXPR_OPERATOR;
8352          ELSIF(v_tExprType(i) = EXPR_JAVAPROPERTYBYNAME)THEN
8353 
8354            v_tExprType(i) := EXPR_JAVA_PROPERTY;
8355          END IF;
8356        END IF;
8357 
8358        --Populate the expression node subtype from template_id for all expression nodes for backward
8359        --compatibility.
8360 
8361        v_tExprSubtype(i) := v_tExprTemplateId(i);
8362 
8363        --Use the code lookup to fix irregularities in new codes. May become unnecessary when real
8364        --metadata lookup is implemented.
8365 
8366        IF(CodeByCodeLookup.EXISTS(v_tExprTemplateId(i)))THEN
8367 
8368          v_tExprSubtype(i) := CodeByCodeLookup(v_tExprTemplateId(i));
8369          v_tExprTemplateId(i) := v_tExprSubtype(i);
8370        END IF;
8371 
8372        IF(v_tExprParentId(i) IS NOT NULL)THEN
8373 
8374          IF(v_NumberOfChildren.EXISTS(v_tExprParentId(i)))THEN
8375            v_NumberOfChildren(v_tExprParentId(i)) := v_NumberOfChildren(v_tExprParentId(i)) + 1;
8376          ELSE
8377            v_NumberOfChildren(v_tExprParentId(i)) := 1;
8378          END IF;
8379 
8380          IF(NOT v_ChildrenIndex.EXISTS(v_tExprParentId(i)))THEN
8381            v_ChildrenIndex(v_tExprParentId(i)) := i;
8382          END IF;
8383        END IF;
8384 
8385        --If this rule is against max of some component, mark this component as having such a rule.
8386        --Later we will generate INC for this component's actual max.
8387 
8388        IF(v_tExprType(i) = EXPR_SYS_PROP AND h_SeededName.EXISTS(v_tExprSubtype(i)) AND
8389           h_SeededName(v_tExprSubtype(i)) = RULE_SYS_PROP_MAXINSTANCE AND
8390           v_tConsequentFlag(i) = FLAG_IS_CONSEQUENT)THEN
8391 
8392           v_MaxRuleExists(v_tExplNodeId(i)) := 1;
8393        END IF;
8394 
8395        --Add the indexing option.
8396 
8397        v_IndexByExprNodeId(v_tExprId(i)) := i;
8398      END LOOP;
8399 
8400     ELSIF(nRuleType = RULE_TYPE_COMPAT_TABLE)THEN
8401 
8402      --Read all the features
8403 
8404      SELECT model_ref_expl_id, feature_id, EXPR_NODE_TYPE_NODE
8405      BULK COLLECT INTO v_tExplNodeId, v_tExprPsNodeId, v_tExprType
8406      FROM cz_des_chart_features
8407      WHERE rule_id = nRuleId
8408        AND deleted_flag = FLAG_NOT_DELETED;
8409 
8410 nDebug := 32;
8411 
8412      --Determine the size of the expression for all eventual purposes.
8413 
8414      expressionSize := v_tExprType.COUNT;
8415 
8416      IF(expressionSize < 2)THEN
8417        RAISE CZ_R_NO_PARTICIPANTS;
8418      END IF;
8419 
8420      expressionStart := 1;
8421      expressionEnd := expressionSize;
8422 
8423     ELSIF(nRuleType = RULE_TYPE_DESIGNCHART_RULE)THEN
8424 
8425      --Read all the features
8426 
8427      SELECT model_ref_expl_id, feature_id, feature_type, EXPR_NODE_TYPE_NODE
8428      BULK COLLECT INTO v_tExplNodeId, v_tExprPsNodeId, v_tFeatureType, v_tExprType
8429      FROM cz_des_chart_features
8430      WHERE rule_id = nRuleId
8431        AND deleted_flag = FLAG_NOT_DELETED;
8432 
8433 nDebug := 34;
8434 
8435      --Determine the size of the expression for all eventual purposes.
8436 
8437      expressionSize := v_tExprType.COUNT;
8438 
8439      IF(expressionSize < 2)THEN
8440        RAISE CZ_R_NO_PARTICIPANTS;
8441      END IF;
8442 
8443      expressionStart := 1;
8444      expressionEnd := expressionSize;
8445 
8446     ELSE
8447 
8448      --Unknown rule type. Do nothing for those rules, just go to the next rule.
8449 
8450      RAISE CZ_LCE_CONTINUE;
8451     END IF;
8452 
8453     --General rule data validation section - all rule types----------------------------Start
8454 
8455     FOR i IN expressionStart..expressionEnd LOOP
8456 
8457       IF(v_tExprPsNodeId(i) IS NOT NULL)THEN
8458         IF(NOT glIndexByPsNodeId.EXISTS(v_tExprPsNodeId(i)))THEN
8459 
8460 nDebug := 35;
8461 
8462      --Every participating node must actually exist in the product structure.
8463 
8464           RAISE CZ_R_WRONG_EXPRESSION_NODE;
8465 
8466         ELSIF(glPsNodeType(glIndexByPsNodeId(v_tExprPsNodeId(i))) = PS_NODE_TYPE_FEATURE AND
8467               glFeatureType(glIndexByPsNodeId(v_tExprPsNodeId(i))) = PS_NODE_FEATURE_TYPE_STRING)THEN
8468 
8469      --A text feature cannot participate in any kind of rules.
8470 
8471           localString := glName(glIndexByPsNodeId(v_tExprPsNodeId(i)));
8472           RAISE CZ_R_INCORRECT_FEATURE_TYPE;
8473 
8474         ELSIF(glPsNodeType(glIndexByPsNodeId(v_tExprPsNodeId(i))) = PS_NODE_TYPE_CONNECTOR)THEN
8475 
8476      --A connector cannot participate in any kind of rules.
8477 
8478           RAISE CZ_R_CONNECTOR_RULE;
8479         END IF;
8480 
8481         IF(v_tExplNodeId(i) IS NULL)THEN
8482 
8483 nDebug := 36;
8484 
8485     --Every not null ps_node_id should have a not null assosiated model_ref_expl_id (data corruption).
8486 
8487           RAISE CZ_G_INVALID_RULE_EXPLOSION;
8488 
8489         ELSIF(NOT v_IndexByNodeId.EXISTS(v_tExplNodeId(i)))THEN
8490 
8491 nDebug := 37;
8492 
8493     --All the participants' model_ref_expl_id must be in the current model's explosion table (data corruption).
8494 
8495           RAISE CZ_G_INVALID_RULE_EXPLOSION;
8496 
8497         END IF;
8498       END IF;
8499 
8500 nDebug := 38;
8501 
8502       IF(v_tExprType(i) IN (EXPR_NODE_TYPE_NODE, EXPR_PSNODEBYNAME))THEN
8503        IF(v_tExprPsNodeId(i) IS NULL)THEN
8504 
8505 nDebug := 381;
8506 
8507       --Every node type node must have assosiated ps_node_id.
8508 
8509         RAISE CZ_R_INCORRECT_NODE_ID;
8510        END IF;
8511       ELSIF(v_tExprType(i) = EXPR_NODE_TYPE_LITERAL)THEN
8512        IF(v_tExprDataValue(i) IS NULL)THEN
8513 
8514 nDebug := 382;
8515 
8516       --Every literal must have not null value.
8517 
8518         RAISE CZ_R_LITERAL_NO_VALUE;
8519        END IF;
8520       ELSIF(v_tExprType(i) = EXPR_NODE_TYPE_FEATPROP)THEN
8521        IF(v_tExprPsNodeId(i) IS NULL)THEN
8522 
8523 nDebug := 383;
8524 
8525       --Every feature property node must have assosiated ps_node_id.
8526 
8527         RAISE CZ_R_INCORRECT_NODE_ID;
8528        ELSIF(v_tExprPropertyId(i) IS NULL)THEN
8529 
8530 nDebug := 384;
8531 
8532       --Every feature property node must have assosiated property_id.
8533 
8534         RAISE CZ_R_FEATURE_NO_PROPERTY;
8535        END IF;
8536       END IF;
8537 
8538       --Bug #4760372.
8539 
8540       IF(v_tExprType(i) = EXPR_PSNODEBYNAME)THEN
8541 
8542         --This will resolve the path if possible, populate ps_node_id and model_ref_expl_id with
8543         --resolved values and change the type of the expression node.
8544 
8545         RESOLVE_NODE(SPLIT_PATH(v_RelativeNodePath(i)), v_tExprPsNodeId(i), v_tExplNodeId(i), v_tExprPsNodeId(i), v_tExplNodeId(i));
8546         v_tExprType(i) := EXPR_NODE_TYPE_NODE;
8547       END IF;
8548     END LOOP;
8549     --General rule data validation section-----------------------------------------------End
8550 
8551 nDebug := 41;
8552 
8553     nCounter := 0;
8554     distinctCount := 0;
8555     participantCount := 0;
8556     MaxDepthValue := 0;
8557     MaxDepthIndex := thisRootExplIndex;
8558 
8559     FOR i IN expressionStart..expressionEnd LOOP
8560      IF(v_tExprPsNodeId(i) IS NOT NULL)THEN
8561 
8562       participantCount := participantCount + 1;
8563       auxIndex := glIndexByPsNodeId(v_tExprPsNodeId(i));
8564 
8565       --Soft fix the explosion nodes whenever necessary:
8566 
8567       --When a rule has a reference node as a participant,Developer would put the explosion id
8568       --of the reference node itself instead of the explosion id of its parent. This should be
8569       --fixed in some cases (see below).
8570       --If a participant is a component, then it's the component's MIN,MAX or COUNT and actual
8571       --participant should be it's parent. However,it can also be features of the component or
8572       --some other (new) operator. That's why we make sure that the parent of the component is
8573       --the operator DOT and, in addition, the component is non-virtual.
8574 
8575       --Later remark:
8576       --A reference, as well as a component, should be fixed only when they are in combination
8577       --with system property. So, it's not enough to check that the parent operator is DOT, we
8578       --also have to make sure that the another operand is EXPR_SYS_PROP with MIN,MAX or COUNT
8579       --subtype.
8580 
8581       IF(glPsNodeType(auxIndex) = PS_NODE_TYPE_REFERENCE OR
8582          (glPsNodeType(auxIndex) = PS_NODE_TYPE_COMPONENT AND glVirtualFlag(auxIndex) = FLAG_NON_VIRTUAL))THEN
8583 
8584          IF((v_ChildrenIndex.EXISTS(v_tExprId(i)) AND v_tExprType(v_ChildrenIndex(v_tExprId(i))) = EXPR_SYS_PROP AND
8585              h_SeededName.EXISTS(v_tExprSubtype(v_ChildrenIndex(v_tExprId(i)))) AND
8586              h_SeededName(v_tExprSubtype(v_ChildrenIndex(v_tExprId(i)))) IN (RULE_SYS_PROP_MININSTANCE, RULE_SYS_PROP_MAXINSTANCE, RULE_SYS_PROP_INSTANCECOUNT))
8587          )THEN
8588 
8589            --SYS_PROP_COUNT has been removed from the above condition as a part of the fix for the
8590            --bug #2317427 - we do not want to fix explosion if it is a reference to a BOM ATO. For
8591            --such a reference SYS_PROP_COUNT means #Quantity.
8592 
8593            --If this is a reference to a trackable model in a network container model, then this
8594            --rule is against its #Min or #Max, not #Quantity, and so it should be prohibited.
8595            --This exception does not just ignore the rule, it stops the generation.
8596 
8597            IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL AND glIbTrackable(v_tExprPsNodeId(i)) = FLAG_IB_TRACKABLE)THEN
8598 
8599              nParam := auxIndex;
8600              RAISE CZ_R_AGAINST_TRACKABLE;
8601            END IF;
8602 
8603            v_tExplNodeId(i) := v_tParentId(v_IndexByNodeId(v_tExplNodeId(i)));
8604 
8605          ELSIF(glPsNodeType(auxIndex) = PS_NODE_TYPE_REFERENCE)THEN
8606 
8607            --If we are here, than this is a reference to a BOM model, because it should be prohibited
8608            --for a reference to a component to participate with anything other than it's MIN or MAX.
8609            --We will fix the corresponding PS_NODE_ID value to be not the reference node's PS_NODE_ID
8610            --but the PS_NODE_ID of the referenced BOM model. This is necessary to generate the correct
8611            --object name.
8612            --In some cases we still need to use the real reference's ps_node_id.
8613 
8614            v_tRealPsNodeId(i) := v_tExprPsNodeId(i);
8615            v_tExprPsNodeId(i) := glReferenceId(v_tExprPsNodeId(i));
8616          END IF;
8617       END IF;
8618 
8619 nDebug := 42;
8620 
8621       --Select a participant and get its explosion id.
8622 
8623       nAux := v_tExplNodeId(i);
8624 
8625       IF(NOT v_Participant.EXISTS(nAux))THEN
8626 
8627 nDebug := 43;
8628 
8629         IF(v_ProhibitInRules.EXISTS(nAux))THEN
8630 
8631           --This explosion node has D nodes under connectors on the way up in the explosion table.
8632           --It will be impossible to assign this rule, so just stop here.
8633 
8634           localString := glName(glIndexByPsNodeId(v_tExprPsNodeId(i)));
8635           auxIndex := v_ProhibitInRules(nAux);
8636           auxCount := v_ProhibitConnector(nAux);
8637           RAISE CZ_R_UNASSIGNABLE_RULE;
8638 
8639         ELSIF(v_ProhibitOptional.EXISTS(nAux))THEN
8640 
8641           --This explosion node has A nodes under connectors on the way up in the explosion table.
8642           --Stop here - bug #2217450.
8643 
8644           localString := glName(glIndexByPsNodeId(v_tExprPsNodeId(i)));
8645           auxIndex := v_ProhibitOptional(nAux);
8646           auxCount := v_ProhibitConnector(nAux);
8647           RAISE CZ_R_OPTIONAL_INSIDE;
8648         END IF;
8649 
8650         --Add to the list of indexes of distinct participants' explosions.
8651 
8652         v_Participant(nAux) := 1;
8653         distinctCount := distinctCount + 1;
8654         v_ParticipantIndex(distinctCount) := v_IndexByNodeId(nAux);
8655 
8656         --The node is not prohibited from participating in rules, so both assignable exists and
8657         --corresponding deepest instantiable node is defined.
8658 
8659         auxIndex := v_NodeInstantiable(nAux);
8660         auxCount := v_NodeAssignable(nAux);
8661 
8662         --We mark the potential assignables to reflect the fact that the associated participant
8663         --belongs to a connector net. We need a separate table because this information is rule
8664         --specific while v_IsConnectorNet stores the explosion-specific information. A node can
8665         --be assignable for a connector's net participant in one rule but not in another.
8666 
8667         IF(v_IsConnectorNet.EXISTS(nAux))THEN
8668 
8669           v_RuleConnectorNet(auxIndex) := 1;
8670           v_RuleConnectorNet(auxCount) := 1;
8671         END IF;
8672 
8673         --Select and store all the distinct assignables for all the current rule's participants.
8674         --Main indexes are stored in v_DistinctIndex. Also find the deepest D node among all of
8675         --participants here. MaxDepthValue is initialized to the root (0), so that if there are
8676         --no D nodes, the root node will act as one.
8677 
8678 nDebug := 44;
8679 
8680         IF(NOT v_Assignable.EXISTS(auxIndex))THEN
8681 
8682           v_Assignable(auxIndex) := 1;
8683           nCounter := nCounter + 1;
8684           v_DistinctIndex(nCounter) := auxIndex;
8685 
8686           IF(v_tNodeDepth(auxIndex) > MaxDepthValue)THEN
8687 
8688              MaxDepthValue := v_tNodeDepth(auxIndex);
8689              MaxDepthIndex := auxIndex;
8690           END IF;
8691         END IF;
8692 
8693         IF(NOT v_Assignable.EXISTS(auxCount))THEN
8694 
8695           v_Assignable(auxCount) := 1;
8696           nCounter := nCounter + 1;
8697           v_DistinctIndex(nCounter) := auxCount;
8698         END IF;
8699       END IF; --This is a distinct participant.
8700 
8701       v_ExplByPsNodeId(v_tExprPsNodeId(i)) := v_tExplNodeId(i);
8702 
8703      END IF; --This is a participant.
8704     END LOOP;
8705 
8706 nDebug := 45;
8707 
8708     --Now populate the <index in memory>(NODE_DEPTH) table for assignables of any type which
8709     --are above the deepest D component. They should form a chain, without duplicates on the
8710     --same level. Here we verify that there are no two components on the same level. This is
8711     --necessary but not sufficient for the rule to be valid.
8712 
8713     FOR i IN 1..v_DistinctIndex.COUNT LOOP
8714 
8715       auxIndex := v_DistinctIndex(i);
8716 
8717       IF(v_tNodeDepth(auxIndex) <= MaxDepthValue)THEN
8718         IF(v_InstByLevel.EXISTS(v_tNodeDepth(auxIndex)))THEN
8719 
8720           --There is already a node on this level. Two or more non-virtual components on the
8721           --same level are prohibited.
8722 
8723           auxCount := glIndexByPsNodeId(v_tPsNodeId(auxIndex));
8724           auxIndex := glIndexByPsNodeId(v_tPsNodeId(v_InstByLevel(v_tNodeDepth(auxIndex))));
8725           RAISE CZ_R_CONFLICTING_NODES;
8726         ELSE
8727 
8728           --This level is now occupied by a node with memory index auxIndex.
8729 
8730           v_InstByLevel(v_tNodeDepth(auxIndex)) := auxIndex;
8731         END IF;
8732       END IF;
8733     END LOOP;
8734 
8735 nDebug := 46;
8736 
8737     --Now we make sure that if we move up from the deepest D assignable, we will step over
8738     --all other assignable which are above this D, so they all form a chain.
8739     --We start with the deepest D component and move up to its parent and so on thus going
8740     --through every level in the hierarchy. On every level, if an assignable exists there,
8741     --we make sure that this node is what we expect - the parent we just moved up to.
8742 
8743     nCounter := 0;
8744     auxIndex := MaxDepthIndex;
8745 
8746     LOOP
8747       IF(v_InstByLevel.EXISTS(v_tNodeDepth(auxIndex)))THEN
8748          IF(v_InstByLevel(v_tNodeDepth(auxIndex)) <> auxIndex)THEN
8749 
8750            --Incorrect node on the level. The rule goes across non-virual boundaries.
8751 
8752            auxCount := glIndexByPsNodeId(v_tPsNodeId(v_InstByLevel(v_tNodeDepth(auxIndex))));
8753            auxIndex := glIndexByPsNodeId(v_tPsNodeId(MaxDepthIndex));
8754            RAISE CZ_R_INCORRECT_NODE_LEVEL;
8755          END IF;
8756          nCounter := nCounter + 1;
8757       END IF;
8758 
8759       EXIT WHEN nCounter = v_InstByLevel.COUNT OR v_tParentId(auxIndex) IS NULL;
8760       auxIndex := v_IndexByNodeId(v_tParentId(auxIndex));
8761     END LOOP;
8762 
8763 nDebug := 47;
8764 
8765     --We verified that on the way up from the deepest D node we pass ONLY through eligible
8766     --assignables. Now lets see if we passed through ALL of them.
8767 
8768     IF(nCounter <> v_InstByLevel.COUNT)THEN
8769 
8770       --Not all the assignables have been passed on the way up. The rule goes across
8771       --non-virual boundaries.
8772 
8773       RAISE CZ_R_INVALID_RULE;
8774     END IF;
8775 
8776     --So, there exists the deepest type D assignable (it can be the root node) and we verified
8777     --that above it there is no non-virtual boundaries crossing. However, if there are A type
8778     --assignables beneath that D node, we want to assign the rule to the least common ancestor.
8779     --Or there may be not assignables but just regular A nodes between assignables and D.
8780 
8781     --First of all, let us see if there are connector's nets attached to the deepest component
8782     --among the rule participants, because if there are, then the rule will be assigned to the
8783     --deepst D already found and there's no need to work with A type components. Example:
8784 
8785     --  M
8786     --  |_D
8787     --    |_A0
8788     --    | |_A
8789     --    | | |_F2
8790     --    | |_A
8791     --    |   |_F3
8792     --    |
8793     --    |_Connector->M1-F4
8794 
8795     --For both rules relating either (F2, F3) or (F2, F3, F4), D is the deepest D node. However,
8796     --the first rule should be assigned to A0 while the second rule should be assigned to D.
8797     --Reference bug #2188507.
8798 
8799     --We also identify possible connector's nets attached to a node above the deepest D node.
8800     --Such explosions will have assignables above the deepest D and so may have passed all the
8801     --tests above, but a rule may still cross non-virual boundaries. Example:
8802 
8803     --  M
8804     --  |_D
8805     --  | |_A
8806     --  |   |_F2
8807     --  |
8808     --  |___Connector->M1-F4
8809 
8810     --F4 has M as its assignable, and although M and D form a good chain, an (F2, F4) rule is
8811     --prohibited.
8812     --Reference bug #2190399.
8813 
8814     --This block can be optimized to use v_RuleConnectorNet table which was introduced later.
8815 
8816     auxCount := 0;
8817 
8818     FOR i IN 1..v_ParticipantIndex.COUNT LOOP
8819 
8820       nAux := v_NodeId(v_ParticipantIndex(i));
8821 
8822       IF(v_IsConnectorNet.EXISTS(nAux))THEN
8823         IF(v_tNodeDepth(v_NodeAssignable(nAux)) < MaxDepthValue)THEN
8824 
8825           --This is a connector's net attached to a node above the deepest D assignable, report
8826           --the rule.
8827 
8828           auxCount := glIndexByPsNodeId(v_tReferringId(v_IsConnectorNet(nAux)));
8829           auxIndex := glIndexByPsNodeId(v_tPsNodeId(MaxDepthIndex));
8830           RAISE CZ_R_CONNECTOR_ASIDE;
8831         ELSIF(v_NodeAssignable(nAux) = MaxDepthIndex)THEN
8832 
8833           --This is a connector's net attached to the D, so the rule will be assigned to the D.
8834 
8835           auxCount := 1;
8836 
8837           --Just one attached net is enough, but we cannot exit here because we need to examine
8838           --all other participants on account of connector's nets attached above the D node
8839           --(the previous IF does that).
8840         END IF;
8841       END IF;
8842     END LOOP;
8843 
8844     IF(auxCount = 0)THEN
8845 
8846       --We know that the rule can be assigned somewhere under the deepest D node. It can be
8847       --one of the A type nodes under the deepest D, assignable or not. We start from every
8848       --assignable A node underneath the deepest D and go up all the way to the D. If we do
8849       --not end up on the deepest D, the rule crosses non-virtual boundaries and is invalid.
8850 
8851       --On the way up we collect the following information:
8852 
8853       --  for every level the number of distinct components of any type on this level
8854       --  (v_LevelCount);
8855       --  index of the first of such components (v_LevelIndex);
8856       --  type of the first of such components (v_LevelType);
8857 
8858 nDebug := 48;
8859 
8860       nCounter := MaxDepthValue;
8861 
8862       FOR i IN 1..v_DistinctIndex.COUNT LOOP
8863 
8864         auxIndex := v_DistinctIndex(i);
8865         nAux := v_tNodeDepth(auxIndex);
8866 
8867         IF(v_tExplNodeType(auxIndex) = EXPL_NODE_TYPE_OPTIONAL AND nAux > MaxDepthValue)THEN
8868 
8869            IF(nCounter < nAux)THEN nCounter := nAux; END IF;
8870 
8871            FOR n IN REVERSE MaxDepthValue + 1..nAux LOOP
8872 
8873              IF(NOT v_LevelCount.EXISTS(nAux))THEN
8874 
8875                v_LevelCount(nAux) := 1;
8876                v_LevelIndex(nAux) := auxIndex;
8877                v_LevelType(nAux) := v_tExplNodeType(auxIndex);
8878              END IF;
8879 
8880              IF(auxIndex <> v_LevelIndex(nAux))THEN
8881 
8882                v_LevelCount(nAux) := v_LevelCount(nAux) + 1;
8883              END IF;
8884 
8885              auxIndex := v_IndexByNodeId(v_tParentId(auxIndex));
8886              nAux := nAux - 1;
8887            END LOOP;
8888 
8889            IF(auxIndex <> MaxDepthIndex)THEN
8890 
8891              --The way up from the A node doesn't pass through the D node on level MaxDepthValue.
8892              --Crossing of non-virtual boundaries detected.
8893 
8894              auxCount := glIndexByPsNodeId(v_tPsNodeId(v_DistinctIndex(i)));
8895              auxIndex := glIndexByPsNodeId(v_tPsNodeId(MaxDepthIndex));
8896              RAISE CZ_R_OPTIONAL_ASIDE;
8897            END IF;
8898         END IF;
8899       END LOOP;
8900 
8901 nDebug := 49;
8902 
8903       --We want to find the deepest A component we can assign the rule to. So we move from the
8904       --top down shifting MaxDepthIndex with every A component we find. When we hit a fork, we
8905       --stop.
8906 
8907       FOR i IN MaxDepthValue + 1..nCounter LOOP
8908 
8909         IF(v_LevelCount(i) = 1 AND v_LevelType(i) = EXPL_NODE_TYPE_OPTIONAL)THEN
8910 
8911           MaxDepthIndex := v_LevelIndex(i);
8912         END IF;
8913 
8914         --We stop when we hit a fork or when we see that there is a connector net attached to
8915         --the optional component which is another kind of fork. Example:
8916 
8917         --  A1
8918         --  |_A2
8919         --    |_A3
8920         --    | |_A4
8921         --    |
8922         --    |_Connector->participant
8923 
8924         --We don't want to go below A2.
8925 
8926         IF(v_LevelCount(i) > 1 OR v_RuleConnectorNet.EXISTS(v_LevelIndex(i))) THEN
8927 
8928           EXIT;
8929         END IF;
8930       END LOOP;
8931     END IF;  --We finished processing the tree of A nodes beneath the deepest D node which
8932              --may have resulted in assigning the rule to an A node under the deepest D.
8933 
8934     --If this rule is defined in a network container model, it can't have participants across
8935     --instantiable references to trackable models. We have already calculated indexes of such
8936     --references for every explosion. The requirement above means that, if one of the indexes
8937     --belongs to a non-trackable model, then all the indexes should belong to a non-trackable
8938     --model.
8939 
8940     IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
8941 
8942       localCount := 0;
8943 
8944       FOR i IN 1..v_ParticipantIndex.COUNT LOOP
8945 
8946         IF(glIbTrackable(v_tPsNodeId(v_NodeTrackable(v_NodeId(v_ParticipantIndex(i))))) = FLAG_NOT_IB_TRACKABLE)
8947         THEN localCount := localCount + 1; END IF;
8948       END LOOP;
8949 
8950       IF(localCount > 0 AND localCount < v_ParticipantIndex.COUNT)THEN
8951 
8952         RAISE CZ_R_ACROSS_TRACKABLE;
8953       END IF;
8954     END IF;
8955 
8956 nDebug := 490;
8957 
8958     --The rule is assigned to this component (identified by model_ref_expl_id). This variable
8959     --is used mostly for identification of rule logic files, but also in rule generation code.
8960 
8961     MaxDepthId := v_NodeId(MaxDepthIndex);
8962     MaxDepthValue := v_tNodeDepth(MaxDepthIndex);
8963 
8964 nDebug := 50;
8965 
8966     --We need to prepend downpaths for all the distinct participating explosions. If the
8967     --assignable of an explosion id is deeper than the rule's assignee, we are going to
8968     --prepend the downpath with all optional (type A) components or mandatory references
8969     --on the way down from the assignee to the assignable. We do not need to change the
8970     --node's logic level.
8971     --We do not prepend downpaths for explosions corresponding to connectors.
8972 
8973     FOR i IN 1..v_ParticipantIndex.COUNT LOOP
8974 
8975       nAux := v_NodeId(v_ParticipantIndex(i));
8976 
8977       IF(NOT v_IsConnectorNet.EXISTS(nAux))THEN
8978 
8979         auxIndex := v_NodeAssignable(nAux);
8980 
8981         WHILE(v_tNodeDepth(auxIndex) > MaxDepthValue)LOOP
8982           IF(v_tExplNodeType(auxIndex) IN (EXPL_NODE_TYPE_OPTIONAL, EXPL_NODE_TYPE_MANDATORY))THEN
8983 
8984             v_AssignedDownPath(nAux) := PATH_DELIMITER || 'N_' ||
8985                 TO_CHAR(glPersistentId(NVL(v_tReferringId(auxIndex), v_tPsNodeId(auxIndex)))) ||
8986                                         v_AssignedDownPath(nAux);
8987           END IF;
8988 
8989           auxIndex := v_IndexByNodeId(v_tParentId(auxIndex));
8990         END LOOP;
8991       END IF;
8992     END LOOP;
8993 
8994 nDebug := 51;
8995 
8996     --Now we can go ahead and collect the load conditions for this rule. Those would be all
8997     --type A (optional) and C (connector) descendants of the rule assignee. To collect them
8998     --we need to go up from each (distinct) rule participant's explosion id (index).
8999     --There may also be no load conditions at all and then this is the 'standard' rule file
9000     --identified by explosion id of the assignee as a load condition (NET_TYPE = 2).
9001 
9002     FOR i IN 1..v_ParticipantIndex.COUNT LOOP
9003 
9004       auxIndex := v_ParticipantIndex(i);
9005 
9006       WHILE(v_tNodeDepth(auxIndex) > MaxDepthValue AND v_tParentId(auxIndex) IS NOT NULL) LOOP
9007 
9008         IF(v_tExplNodeType(auxIndex) IN (EXPL_NODE_TYPE_OPTIONAL, EXPL_NODE_TYPE_CONNECTOR))THEN
9009 
9010           --It is enough to just mark the index as a load condition.
9011 
9012           v_MarkLoadCondition(auxIndex) := 1;
9013         END IF;
9014 
9015         auxIndex := v_IndexByNodeId(v_tParentId(auxIndex));
9016       END LOOP;
9017     END LOOP;
9018 
9019 nDebug := 52;
9020 
9021     nHeaderId := NEVER_EXISTS_ID;
9022 
9023     IF(v_MarkLoadCondition.COUNT = 0)THEN
9024 
9025       --This is going to be a mandatory (standard) rule file.
9026 
9027       logicNetType := LOGIC_NET_TYPE_MANDATORY;
9028       v_LoadConditionId(1) := MaxDepthId;
9029       IF(v_tIsHeaderGenerated.EXISTS(MaxDepthId))THEN
9030 
9031         nHeaderId := v_tIsHeaderGenerated(MaxDepthId);
9032       END IF;
9033     ELSE
9034 
9035       --There are load conditions, so this is going to be a network logic file.
9036 
9037       logicNetType := LOGIC_NET_TYPE_NETWORK;
9038 
9039 nDebug := 53;
9040 
9041       --Generate the load condition string. Note that with the algorithm used condition nodes
9042       --are ordered, otherwise it would make no sense.
9043       --There is currently no check for not to exceed the length of the localString.
9044 
9045       localString := NULL;
9046       nCounter := 0;
9047 
9048       FOR i IN 1..v_NodeId.COUNT LOOP
9049         IF(v_MarkLoadCondition.EXISTS(i))THEN
9050 
9051           nCounter := nCounter + 1;
9052           v_LoadConditionId(nCounter) := v_NodeId(i);
9053           localString := localString || ':' || TO_CHAR(v_NodeId(i));
9054         END IF;
9055       END LOOP;
9056 
9057 nDebug := 54;
9058 
9059       nCounter := 0;
9060 
9061       FOR i IN 1..v_LoadConditions.COUNT LOOP
9062         IF(localString = v_LoadConditions(i))THEN
9063 
9064           --Load condition found, fetch the corresponding header and exit the loop.
9065 
9066           nHeaderId := v_LoadHeaders(i);
9067           nCounter := 1;
9068           EXIT;
9069         END IF;
9070       END LOOP;
9071 
9072       IF(nCounter = 0)THEN
9073 
9074         --A new load condition, add it to the table. Corresponding header will be
9075         --generated and added later.
9076 
9077         v_LoadConditions(v_LoadConditions.COUNT + 1) := localString;
9078       END IF;
9079     END IF;
9080 
9081     nCounter := v_LoadConditionId.COUNT;
9082 
9083 nDebug := 7;
9084 
9085     --Generate a new logic header if necessary.
9086 
9087     IF(nHeaderId = NEVER_EXISTS_ID)THEN
9088 
9089       nHeaderId := next_lce_header_id;
9090 
9091       BEGIN
9092 
9093         --Insert the rule net logic header record into the table.
9094 
9095         INSERT INTO cz_lce_headers
9096          (lce_header_id, gen_version, gen_header, component_id, net_type,
9097           devl_project_id, model_ref_expl_id, nbr_required_expls, deleted_flag)
9098         VALUES
9099          (nHeaderId, VersionString, GenHeader, v_tPsNodeId(v_IndexByNodeId(MaxDepthId)),
9100           logicNetType, thisProjectId, MaxDepthId, nCounter, FLAG_PENDING);
9101 
9102         FOR i IN 1..nCounter LOOP
9103 
9104           nAux := v_LoadConditionId(i);
9105 
9106           --The following statement populates the new ALIAS_NAME column introduced as a fix
9107           --for the bug #2214414. The column is populated with C_<model_ref_expl_id> for
9108           --connector conditions and with NULL for other conditions (optional components).
9109 
9110           INSERT INTO cz_lce_load_specs
9111            (attachment_expl_id, lce_header_id, required_expl_id, attachment_comp_id,
9112             model_id, net_type, deleted_flag, alias_name)
9113           VALUES
9114            (MaxDepthId, nHeaderId, nAux, v_tPsNodeId(v_IndexByNodeId(MaxDepthId)),
9115             thisProjectId, logicNetType, FLAG_PENDING,
9116             DECODE(v_tExplNodeType(v_IndexByNodeId(nAux)), EXPL_NODE_TYPE_CONNECTOR, 'C_' || nAux, NULL));
9117         END LOOP;
9118 
9119       EXCEPTION
9120         WHEN OTHERS THEN
9121           errorMessage := SQLERRM;
9122           RAISE CZ_R_UNABLE_TO_CREATE_HEADER;
9123       END;
9124 
9125       NewHeaders(counterNewHeaders) := nHeaderId;
9126       NewHeadersComponents(counterNewHeaders) := v_tPsNodeId(v_IndexByNodeId(MaxDepthId));
9127       NewHeadersExplosions(counterNewHeaders) := MaxDepthId;
9128       counterNewHeaders := counterNewHeaders + 1;
9129 
9130       IF(logicNetType = LOGIC_NET_TYPE_MANDATORY)THEN
9131 
9132         v_tIsHeaderGenerated(MaxDepthId) := nHeaderId;
9133       ELSE
9134 
9135         v_LoadHeaders(v_LoadHeaders.COUNT + 1) := nHeaderId;
9136       END IF;
9137 
9138       v_tSequenceNbr(nHeaderId) := 1;
9139       v_tLogicNetType(nHeaderId) := logicNetType;
9140       nNewLogicFileFlag := 1;
9141     END IF;
9142 
9143     nRuleAssignedLevel := v_tNodeDepth(v_IndexByNodeId(MaxDepthId));
9144 
9145     --If the logic file has changed then we need to flush off the buffer
9146 
9147     IF(nHeaderId <> nPreviousHeaderId)THEN
9148 
9149      IF(vLogicText IS NOT NULL)THEN
9150        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
9151         (nPreviousHeaderId, v_tSequenceNbr(nPreviousHeaderId), vLogicText);
9152        vLogicText := NULL;
9153        v_tSequenceNbr(nPreviousHeaderId) := v_tSequenceNbr(nPreviousHeaderId) + 1;
9154      END IF;
9155 
9156     END IF;
9157 
9158     nPreviousHeaderId := nHeaderId;
9159 
9160     IF(nNewLogicFileFlag = 1)THEN
9161 
9162       --This is a new logic file, put the header lines in
9163 
9164       vLogicLine := 'CONTROL NOSPEC' || NewLine || 'VERSION 3 3' || NewLine || NewLine ||
9165                     'REM -- Rules file for component: ' || TO_CHAR(v_tPsNodeId(v_IndexByNodeId(MaxDepthId))) ||
9166                     ', explosion node: ' || TO_CHAR(MaxDepthId) || NewLine || NewLine;
9167       PACK;
9168       nNewLogicFileFlag := 0;
9169 
9170     END IF;
9171 
9172 nDebug := 8;
9173 
9174    --Prepare the effective date interval.
9175    --First get the effective date interval either from an effectivity set or
9176    --from the local values.
9177 
9178    IF(nRuleEffSetId IS NOT NULL)THEN
9179     IF(gvIndexBySetId.EXISTS(nRuleEffSetId))THEN
9180 
9181 nDebug := 8000100;
9182 
9183      CurrentEffFrom := gvEffFrom(gvIndexBySetId(nRuleEffSetId));
9184      CurrentEffUntil := gvEffUntil(gvIndexBySetId(nRuleEffSetId));
9185     ELSE
9186       --This is a fatal error - data corruption
9187       RAISE CZ_R_WRONG_EFFECTIVITY_SET;
9188     END IF;
9189    ELSE
9190      CurrentEffFrom := dEffFrom;
9191      CurrentEffUntil := dEffUntil;
9192    END IF;
9193 
9194 nDebug := 8000101;
9195 
9196    --Make sure effective dates are not null. Usage mask is not null anyway.
9197 
9198    IF(CurrentEffFrom IS NULL)THEN CurrentEffFrom := EpochBeginDate; END IF;
9199    IF(CurrentEffUntil IS NULL)THEN CurrentEffUntil := EpochEndDate; END IF;
9200 
9201    dEffFrom := CurrentEffFrom;
9202    dEffUntil := CurrentEffUntil;
9203 
9204    IF((NOT PrevRuleEffFrom.EXISTS(nHeaderId)) OR
9205       (CurrentEffFrom <> PrevRuleEffFrom(nHeaderId)) OR (CurrentEffUntil <> PrevRuleEffUntil(nHeaderId)) OR
9206       (vUsageMask <> PrevRuleUsageMask(nHeaderId)))THEN
9207 
9208         vLogicLine := LTRIM(vUsageMask, '0');
9209         IF(vLogicLine IS NOT NULL) THEN
9210           vLogicLine := EffUsagePrefix || vLogicLine;
9211         END IF;
9212 
9213         IF(CurrentEffFrom = EpochBeginDate)THEN
9214           CurrentFromDate := NULL;
9215         ELSE
9216           CurrentFromDate := TO_CHAR(CurrentEffFrom, EffDateFormat);
9217         END IF;
9218 
9219         IF(CurrentEffUntil = EpochEndDate)THEN
9220           CurrentUntilDate := NULL;
9221         ELSE
9222           CurrentUntilDate := TO_CHAR(CurrentEffUntil, EffDateFormat);
9223         END IF;
9224 
9225         vLogicLine := 'EFF ' || CurrentFromDate || ', ' || CurrentUntilDate || ', ' || vLogicLine || NewLine;
9226         PACK;
9227 
9228         PrevRuleEffFrom(nHeaderId) := CurrentEffFrom;
9229         PrevRuleEffUntil(nHeaderId) := CurrentEffUntil;
9230         PrevRuleUsageMask(nHeaderId) := vUsageMask;
9231    END IF;
9232 
9233 nDebug := 8000102;
9234 
9235    --Expression generation
9236 
9237    IF(nRuleType IN (RULE_TYPE_TEMPLATE, RULE_TYPE_EXPRESSION))THEN
9238 
9239     FOR i IN expressionStart..expressionEnd LOOP
9240       IF(v_tExprParentId(i) IS NULL)THEN
9241 
9242         --Because of the ordering by expr_parent_id, all the expression tree roots will be at the end
9243         --after all their children. As soon as we hit the first of them we can start generating.
9244         --The construction of children lookup arrays has been moved directly after reading the
9245         --expression tree.
9246 
9247         --Bugs #5160714, #5184017. Reset optimization and other parameters per rule. It is not enough
9248         --to do it once after for each rule record because rule text may consist of several rules.
9249         --These parameter are not used for other rule types.
9250 
9251         optimizeChain      := OPTIMIZATION_UNKNOWN;
9252         optimizeContribute := OPTIMIZATION_UNKNOWN;
9253         jAntecedentRoot  := NULL;
9254         jConsequentRoot  := NULL;
9255         RuleTemplateType := RULE_TYPE_UNKNOWN;
9256         numericLHS       := 0;
9257         generateCompare  := 0;
9258 
9259         returnStringArray := GENERATE_EXPRESSION(i, returnListType);
9260       END IF;
9261     END LOOP;
9262    ELSIF(nRuleType = RULE_TYPE_COMPAT_TABLE)THEN
9263 
9264      GENERATE_COMPATIBILITY_TABLE;
9265    ELSIF(nRuleType = RULE_TYPE_DESIGNCHART_RULE)THEN
9266 
9267      GENERATE_DESIGNCHART_RULE;
9268    END IF; --End expression and rule generation
9269    END IF; --Not a rule folder or functional companion
9270 
9271   --This block handles the exceptions during a rule generation. Every such exception
9272   --will stop generation only for the particular rule if not re-raised here.
9273 
9274   EXCEPTION
9275      WHEN CZ_R_UNKNOWN_RULE_TYPE THEN
9276 --'Unknown rule type, rule ''%RULENAME'' ignored'
9277        REPORT(CZ_UTILS.GET_TEXT('CZ_R_UNKNOWN_RULE_TYPE', 'RULENAME', RULE_NAME), 1);
9278        PACK;
9279      WHEN CZ_R_INVALID_RULE THEN
9280 --'Rule ''%RULENAME'' cannot be generated because it relates an incorrect combination of components. Rule ignored.'
9281        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_RULE', 'RULENAME', RULE_NAME), 1);
9282        PACK;
9283      WHEN CZ_R_UNASSIGNABLE_RULE THEN
9284 --'Rule ''%RULENAME'' cannot be generated because the node ''%NODENAME'' is a descendant of the multiply
9285 -- instantiable component ''%COMPONENT'' inside the connected model ''%CONNECTOR'', and therefore cannot
9286 -- participate in rules. Rule ignored.'
9287        REPORT(CZ_UTILS.GET_TEXT('CZ_R_UNASSIGNABLE_RULE', 'NODENAME', localString, 'COMPONENT', glName(auxIndex), 'CONNECTOR', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9288        PACK;
9289      WHEN CZ_R_OPTIONAL_INSIDE THEN
9290 --'Rule ''%RULENAME'' cannot be generated because the node ''%NODENAME'' is a descendant of the optional
9291 -- component ''%COMPONENT'' inside the connected model ''%CONNECTOR'', and therefore cannot  participate
9292 -- in rules. Rule ignored.'
9293        REPORT(CZ_UTILS.GET_TEXT('CZ_R_OPTIONAL_INSIDE', 'NODENAME', localString, 'COMPONENT', glName(auxIndex), 'CONNECTOR', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9294        PACK;
9295      WHEN CZ_R_OPTIONAL_ASIDE THEN
9296 --'Rule ''%RULENAME'' cannot be generated because it relates the multiply instantiable component ''%COMPONENT1''
9297 -- with the optional component ''%COMPONENT2''. Rule ignored.'
9298        REPORT(CZ_UTILS.GET_TEXT('CZ_R_OPTIONAL_ASIDE', 'COMPONENT1', glName(auxIndex), 'COMPONENT2', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9299        PACK;
9300      WHEN CZ_R_CONNECTOR_ASIDE THEN
9301 --'Rule ''%RULENAME'' cannot be generated because it relates the multiply instantiable component ''%COMPONENT''
9302 -- with the connected model ''%CONNECTOR''. Rule ignored.'
9303        REPORT(CZ_UTILS.GET_TEXT('CZ_R_CONNECTOR_ASIDE', 'COMPONENT', glName(auxIndex), 'CONNECTOR', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9304        PACK;
9305      WHEN CZ_R_CONFLICTING_NODES THEN
9306 --'Logic cannot be generated for Rule ''%RULENAME''. This is because the rule participants are descendants of
9307 -- Components ''%COMPONENT1'' and ''%COMPONENT2'' that can be instantiated multiple times. Rule ignored.'
9308        REPORT(CZ_UTILS.GET_TEXT('CZ_R_CONFLICTING_NODES', 'COMPONENT1', glName(auxIndex), 'COMPONENT2', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9309        PACK;
9310      WHEN CZ_R_INCORRECT_NODE_LEVEL THEN
9311 --'Rule ''%RULENAME'' cannot be generated because it relates the multiply instantiable component ''%COMPONENT1'' with the component ''%COMPONENT2''.
9312 -- Rule ignored.'
9313        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_NODE_LEVEL', 'COMPONENT1', glName(auxIndex), 'COMPONENT2', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9314        PACK;
9315      WHEN CZ_R_ACROSS_TRACKABLE THEN
9316 --'Logic cannot be generated for rule ''%RULENAME'' because it relates a trackable instantiable Model with
9317 -- non-trackable items inside the Container Model ''%PROJECTNAME''. Rule ignored.'
9318        REPORT(CZ_UTILS.GET_TEXT('CZ_R_ACROSS_TRACKABLE', 'PROJECTNAME', rootProjectName, 'RULENAME', RULE_NAME), 1);
9319        PACK;
9320      WHEN CZ_R_CONNECTOR_RULE THEN
9321 --'Rule ''%RULENAME'' in the Model ''%MODELNAME'' is invalid. Connectors cannot participate in rules.'
9322        REPORT(CZ_UTILS.GET_TEXT('CZ_R_CONNECTOR_RULE', 'MODELNAME', thisProjectName, 'RULENAME', RULE_NAME), 1);
9323        PACK;
9324      WHEN CZ_R_INVALID_LOGIC_RULE THEN
9325 --'Invalid logic rule, rule ''%RULENAME'' ignored'
9326        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_LOGIC_RULE', 'RULENAME', RULE_NAME), 1);
9327        PACK;
9328      WHEN CZ_R_INCOMPLETE_LOGIC_RULE THEN
9329 --'Incomplete logic rule, rule ''%RULENAME'' ignored'
9330        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCOMPLETE_LOGIC_RULE', 'RULENAME', RULE_NAME), 1);
9331        PACK;
9332      WHEN CZ_R_LOGIC_RULE_WRONG_FEAT THEN
9333 --'Incorrect feature type in logic rule, feature ''%FEATNAME'', rule ''%RULENAME'' ignored'
9334        REPORT(CZ_UTILS.GET_TEXT('CZ_R_LOGIC_RULE_WRONG_FEAT', 'FEATNAME', localString, 'RULENAME', RULE_NAME), 1);
9335        PACK;
9336      WHEN CZ_R_NUMERIC_RULE_WRONG_FEAT THEN
9337 --'Incorrect feature type in numeric rule, feature ''%FEATNAME'', rule ''%RULENAME'' ignored'
9338        REPORT(CZ_UTILS.GET_TEXT('CZ_R_NUMERIC_RULE_WRONG_FEAT', 'FEATNAME', localString, 'RULENAME', RULE_NAME), 1);
9339        PACK;
9340      WHEN CZ_R_INCORRECT_FEATURE_TYPE THEN
9341 --'Text features are not allowed to participate in rules, feature ''%FEATNAME'', rule ''%RULENAME'' ignored.'
9342        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_FEATURE_TYPE', 'FEATNAME', localString, 'RULENAME', RULE_NAME), 1);
9343        PACK;
9344      WHEN CZ_R_INVALID_NUMERIC_RULE THEN
9345 --'Invalid numeric rule, rule ''%RULENAME'' ignored'
9346        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_NUMERIC_RULE', 'RULENAME', RULE_NAME), 1);
9347        PACK;
9348      WHEN CZ_R_INCORRECT_NUMERIC_RHS THEN
9349 --'The node ''%NODENAME'' in the Model ''%MODELNAME'' is a(n) ''%NODETYPE''. This type of node cannot be
9350 -- a participant on the B side of a Numeric rule. Rule ''%RULENAME'' ignored.'
9351        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_NUMERIC_RHS', 'NODENAME', localString, 'MODELNAME', thisProjectName, 'NODETYPE', errorMessage, 'RULENAME', RULE_NAME), 1);
9352        PACK;
9353      WHEN CZ_R_INCOMPATIBLE_SYSPROP THEN
9354 --'The Property ''%PROPERTYNAME'' is invalid for the node ''%NODENAME''. Rule ''%RULENAME'' in Model ''%MODELNAME'' ignored.'
9355        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCOMPATIBLE_SYSPROP', 'PROPERTYNAME', localString, 'NODENAME', glName(auxIndex), 'MODELNAME', thisProjectName, 'RULENAME', RULE_NAME), 1);
9356        PACK;
9357      WHEN CZ_R_INVALID_COMPARISON_RULE THEN
9358 --'Invalid comparison rule, rule ''%RULENAME'' ignored'
9359        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_COMPARISON_RULE', 'RULENAME', RULE_NAME), 1);
9360        PACK;
9361      WHEN CZ_R_INVALID_NUMERIC_PART THEN
9362 --'Invalid numeric part, rule ''%RULENAME'' ignored'
9363        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_NUMERIC_PART', 'RULENAME', RULE_NAME), 1);
9364        PACK;
9365      WHEN CZ_R_INCOMPLETE_NUMERIC_RULE THEN
9366 --'Incomplete numeric rule, rule ''%RULENAME'' ignored'
9367        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCOMPLETE_NUMERIC_RULE', 'RULENAME', RULE_NAME), 1);
9368        PACK;
9369      WHEN CZ_R_INVALID_NUMRULE_NODE THEN
9370 --'Invalid numeric rule node, rule ''%RULENAME'' ignored'
9371        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_NUMRULE_NODE', 'RULENAME', RULE_NAME), 1);
9372        PACK;
9373      WHEN CZ_R_INVALID_NUM_SIMPLE_EXPR THEN
9374 --'The left-hand side expression must have a root rounding operator, rule ''%RULENAME'' ignored'
9375        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INVALID_NUM_SIMPLE_EXPR', 'RULENAME', RULE_NAME), 1);
9376        PACK;
9377      WHEN CZ_E_UNKNOWN_EXPR_TYPE THEN
9378 --'Unknown expression type, rule ''%RULENAME'' ignored'
9379        REPORT(CZ_UTILS.GET_TEXT('CZ_E_UNKNOWN_EXPR_TYPE', 'RULENAME', RULE_NAME), 1);
9380        PACK;
9381      WHEN CZ_E_WRONG_ARITHMETIC_OPER THEN
9382 --'Incorrect arithmetic operator, rule ''%RULENAME'' ignored'
9383        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_ARITHMETIC_OPER', 'RULENAME', RULE_NAME), 1);
9384        PACK;
9385      WHEN CZ_E_WRONG_COMPARISON_OPER THEN
9386 --'Incorrect comparison operator, rule ''%RULENAME'' ignored'
9387        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_COMPARISON_OPER', 'RULENAME', RULE_NAME), 1);
9388        PACK;
9389      WHEN CZ_E_WRONG_ROUND_OPERATOR THEN
9390 --'Incorrect ROUND operator, rule ''%RULENAME'' ignored'
9391        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_ROUND_OPERATOR', 'RULENAME', RULE_NAME), 1);
9392        PACK;
9393      WHEN CZ_E_WRONG_ANDOR_OPERATOR THEN
9394 --'Incorrect AND/OR operator, rule ''%RULENAME'' ignored'
9395        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_ANDOR_OPERATOR', 'RULENAME', RULE_NAME), 1);
9396        PACK;
9397      WHEN CZ_E_WRONG_NOT_OPERATOR THEN
9398 --'Incorrect NOT operator, rule ''%RULENAME'' ignored'
9399        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_NOT_OPERATOR', 'RULENAME', RULE_NAME), 1);
9400        PACK;
9401      WHEN CZ_E_WRONG_NOTTRUE_OPERATOR THEN
9402 --'Incorrect NOTTRUE operator, rule ''%RULENAME'' ignored'
9403        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_NOTTRUE_OPERATOR', 'RULENAME', RULE_NAME), 1);
9404        PACK;
9405      WHEN CZ_E_WRONG_VAL_EXPRESSION THEN
9406 --'Incorrect VAL expression, rule ''%RULENAME'' ignored'
9407        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_VAL_EXPRESSION', 'RULENAME', RULE_NAME), 1);
9408        PACK;
9409      WHEN CZ_E_WRONG_VAL_EXPRESS_TYPE THEN
9410 --'Incorrect VAL expression type, rule ''%RULENAME'' ignored'
9411        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_VAL_EXPRESS_TYPE', 'RULENAME', RULE_NAME), 1);
9412        PACK;
9413      WHEN CZ_E_WRONG_MINMAX_OPERATOR THEN
9414 --'Incorrect MIN/MAX operator, rule ''%RULENAME'' ignored'
9415        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_MINMAX_OPERATOR', 'RULENAME', RULE_NAME), 1);
9416        PACK;
9417      WHEN CZ_E_WRONG_OF_OPERATOR THEN
9418 --'Incorrect OF operator, rule ''%RULENAME'' ignored'
9419        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_OF_OPERATOR', 'RULENAME', RULE_NAME), 1);
9420        PACK;
9421      WHEN CZ_E_WRONG_DOT_OPERATOR THEN
9422 --'Incorrect DOT operator, rule ''%RULENAME'' ignored'
9423        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_DOT_OPERATOR', 'RULENAME', RULE_NAME), 1);
9424        PACK;
9425      WHEN CZ_E_DOT_TYPE_MISMATCH THEN
9426 --'DOT type mismatch, rule ''%RULENAME'' ignored'
9427        REPORT(CZ_UTILS.GET_TEXT('CZ_E_DOT_TYPE_MISMATCH', 'RULENAME', RULE_NAME), 1);
9428        PACK;
9429      WHEN CZ_E_BAD_PROPERTY_TYPE THEN
9430 --'Bad property type, rule ''%RULENAME'' ignored'
9431        REPORT(CZ_UTILS.GET_TEXT('CZ_E_BAD_PROPERTY_TYPE', 'RULENAME', RULE_NAME), 1);
9432        PACK;
9433      WHEN CZ_E_NO_SUCH_PROPERTY THEN
9434 --'No such property, rule ''%RULENAME'' ignored'
9435        REPORT(CZ_UTILS.GET_TEXT('CZ_E_NO_SUCH_PROPERTY', 'RULENAME', RULE_NAME), 1);
9436        PACK;
9437      WHEN CZ_E_NULL_PROPERTY_VALUE THEN
9438 --'Null property value, rule ''%RULENAME'' ignored'
9439        REPORT(CZ_UTILS.GET_TEXT('CZ_E_NULL_PROPERTY_VALUE', 'RULENAME', RULE_NAME), 1);
9440        PACK;
9441      WHEN CZ_E_INCORRECT_PROPERTY THEN
9442 --'Unable to identify property value, rule ''%RULENAME'' ignored'
9443        REPORT(CZ_UTILS.GET_TEXT('CZ_E_INCORRECT_PROPERTY', 'RULENAME', RULE_NAME), 1);
9444        PACK;
9445      WHEN CZ_E_UNKNOWN_OPERATOR_TYPE THEN
9446 --'Unknown operator type, type %OPERTYPE, rule ''%RULENAME'' ignored'
9447        REPORT(CZ_UTILS.GET_TEXT('CZ_E_UNKNOWN_OPERATOR_TYPE', 'OPERTYPE', TO_CHAR(nParam), 'RULENAME', RULE_NAME), 1);
9448        PACK;
9449      WHEN CZ_E_INVALID_OPERAND_TYPE THEN
9450 --'Invalid operand type, operator ''%OPERNAME'', rule ''%RULENAME'' ignored'
9451        REPORT(CZ_UTILS.GET_TEXT('CZ_E_INVALID_OPERAND_TYPE', 'OPERNAME', LTRIM(RTRIM(OperatorLiterals(v_tExprSubtype(nParam)))), 'RULENAME', RULE_NAME), 1);
9452        PACK;
9453      WHEN CZ_E_MATH_PARAMETERS THEN
9454 --'Incorrect number of parameters to mathematical function %FUNCTION, rule ''%RULENAME'' ignored'
9455        REPORT(CZ_UTILS.GET_TEXT('CZ_E_MATH_PARAMETERS', 'RULENAME', RULE_NAME, 'FUNCTION', LTRIM(RTRIM(OperatorLiterals(nParam)))), 1);
9456        PACK;
9457      WHEN CZ_E_INCORRECT_POWER THEN
9458 --'Exponent value of a POW function could not be resolved to a constant integer, rule ''%RULENAME'' ignored'
9459        REPORT(CZ_UTILS.GET_TEXT('CZ_E_INCORRECT_POWER', 'RULENAME', RULE_NAME), 1);
9460        PACK;
9461      WHEN CZ_R_UNABLE_TO_CREATE_TABLE THEN
9462 --'Unable to create a temporary table for property-based compatibility rule, rule ''%RULENAME'' ignored, error: %ERRORTEXT'
9463        REPORT(CZ_UTILS.GET_TEXT('CZ_R_UNABLE_TO_CREATE_TABLE', 'RULENAME', RULE_NAME, 'ERRORTEXT', errorMessage), 1);
9464        PACK;
9465      WHEN CZ_R_WRONG_COMPAT_EXPRESSION THEN
9466 --'Incorrect compatibility expression, rule ''%RULENAME'' ignored'
9467        REPORT(CZ_UTILS.GET_TEXT('CZ_R_WRONG_COMPAT_EXPRESSION', 'RULENAME', RULE_NAME), 1);
9468        PACK;
9469      WHEN CZ_E_WRONG_OPER_IN_COMPAT THEN
9470 --'Incorrect operator in compatibility rule, rule ''%RULENAME'' ignored'
9471        REPORT(CZ_UTILS.GET_TEXT('CZ_E_WRONG_OPER_IN_COMPAT', 'RULENAME', RULE_NAME), 1);
9472        PACK;
9473      WHEN CZ_E_UKNOWN_OPER_IN_COMPAT THEN
9474 --'Unknown operator in compatibility rule, rule ''%RULENAME'' ignored'
9475        REPORT(CZ_UTILS.GET_TEXT('CZ_E_UKNOWN_OPER_IN_COMPAT', 'RULENAME', RULE_NAME), 1);
9476        PACK;
9477      WHEN CZ_R_COMPAT_NO_COMBINATIONS THEN
9478 --'No valid combinations, rule ''%RULENAME'' ignored'
9479        REPORT(CZ_UTILS.GET_TEXT('CZ_R_COMPAT_NO_COMBINATIONS', 'RULENAME', RULE_NAME), 1);
9480        PACK;
9481      WHEN CZ_R_WRONG_EXPRESSION_NODE THEN
9482 --'Incorrect node in expression, rule ''%RULENAME'' ignored'
9483        REPORT(CZ_UTILS.GET_TEXT('CZ_R_WRONG_EXPRESSION_NODE', 'RULENAME', RULE_NAME), 1);
9484        PACK;
9485      WHEN CZ_R_NO_DEFINING_SELECTION THEN
9486 --'No selection made between primary and defining feature in design chart rule, rule ''%RULENAME'' ignored'
9487        REPORT(CZ_UTILS.GET_TEXT('CZ_R_NO_DEFINING_SELECTION', 'RULENAME', RULE_NAME), 1);
9488        PACK;
9489      WHEN CZ_R_NO_PRIMARY_FEATURE THEN
9490 --'No primary feature in design chart rule, rule ''%RULENAME'' ignored'
9491        REPORT(CZ_UTILS.GET_TEXT('CZ_R_NO_PRIMARY_FEATURE', 'RULENAME', RULE_NAME), 1);
9492        PACK;
9493      WHEN CZ_R_DELETED_OPTION THEN
9494 --'The Model structure has changed and the Design Chart rule ''%RULENAME'' now contains deleted node ''%NODENAME''.
9495 -- The rule will be ignored.'
9496        REPORT(CZ_UTILS.GET_TEXT('CZ_R_DELETED_OPTION', 'RULENAME', RULE_NAME, 'NODENAME', errorMessage), 1);
9497        PACK;
9498      WHEN CZ_R_WRONG_DESIGNCHART_RULE THEN
9499 --'No one-to-one correspondence between options of primary and defining feature in design chart rule, rule ''%RULENAME'' ignored'
9500        REPORT(CZ_UTILS.GET_TEXT('CZ_R_WRONG_DESIGNCHART_RULE', 'RULENAME', RULE_NAME), 1);
9501        PACK;
9502      WHEN CZ_R_DUPLICATE_COMBINATION THEN
9503 --'Not unique combination of defining feature options for a primary option in design chart rule, rule ''%RULENAME'' ignored'
9504        REPORT(CZ_UTILS.GET_TEXT('CZ_R_DUPLICATE_COMBINATION', 'RULENAME', RULE_NAME), 1);
9505        PACK;
9506      WHEN CZ_R_INCOMPLETE_DES_CHART THEN
9507 --'Incorrect number of compatibility selections made for the option ''%OPTIONNAME'' of the Primary Feature ''%FEATURENAME''
9508 -- in Design Chart ''%RULENAME''. Rule ignored.'
9509        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCOMPLETE_DES_CHART', 'OPTIONNAME', glName(auxIndex), 'FEATURENAME', glName(auxCount), 'RULENAME', RULE_NAME), 1);
9510        PACK;
9511      WHEN CZ_R_EMPTY_COMPAT_RULE THEN
9512 --'Empty compatibility rule, rule ''%RULENAME'' ignored'
9513        REPORT(CZ_UTILS.GET_TEXT('CZ_R_EMPTY_COMPAT_RULE', 'RULENAME', RULE_NAME), 1);
9514        PACK;
9515      WHEN CZ_R_COMPAT_SINGLE_FEATURE THEN
9516 --'Compatibility rule must have at least two participating features, rule ''%RULENAME'' ignored'
9517        REPORT(CZ_UTILS.GET_TEXT('CZ_R_COMPAT_SINGLE_FEATURE', 'RULENAME', RULE_NAME), 1);
9518        PACK;
9519      WHEN CZ_R_COMPAT_RULE_NO_PROPERTY THEN
9520 --'Incomplete compatibility rule, no property defined for feature ''%FEATNAME'', rule ''%RULENAME'' ignored'
9521        REPORT(CZ_UTILS.GET_TEXT('CZ_R_COMPAT_RULE_NO_PROPERTY', 'FEATNAME', glName(glIndexByPsNodeId(v_tExprPsNodeId(nParam))), 'RULENAME', RULE_NAME), 1);
9522        PACK;
9523      WHEN CZ_R_OPTION_NO_PROPERTY THEN
9524 --'Property value for ''%PROPERTYNAME'' is not defined for item ''%ITEMNAME'' with parent ''%PARENTNAME'' in model ''%MODELNAME''. Rule ''%RULENAME'' ignored.'
9525        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);
9526        PACK;
9527      WHEN CZ_R_LONG_PROPERTY_VALUE THEN
9528 --'Value of the Property ''%PROPERTYNAME'' is too long for item ''%ITEMNAME'' with parent ''%PARENTNAME'' in model ''%MODELNAME''. Rule ''%RULENAME'' ignored.'
9529        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);
9530        PACK;
9531      WHEN CZ_R_INCORRECT_DATA_TYPE THEN
9532 --'Incorrect data: integer or decimal property ''%PROPERTYNAME'' has a text value of ''%VALUE''. Rule ''%RULENAME'' in model ''%MODELNAME'' ignored.'
9533        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_DATA_TYPE', 'PROPERTYNAME', errorMessage, 'VALUE', localString, 'MODELNAME', glName(glIndexByPsNodeId(inProjectId)), 'RULENAME', RULE_NAME), 1);
9534        PACK;
9535      WHEN CZ_R_INCORRECT_NUMERICLHS THEN
9536 --'''%PROPERTYNAME'' is invalid in the Numeric rule ''%RULENAME'' in Model ''%MODELNAME''. Text and Boolean Properties
9537 -- cannot be participants on the left-hand side of a Numeric rule. Rule ignored.'
9538        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_NUMERICLHS', 'PROPERTYNAME', errorMessage, 'MODELNAME', glName(glIndexByPsNodeId(inProjectId)), 'RULENAME', RULE_NAME), 1);
9539        PACK;
9540      WHEN CZ_R_PROPERTY_NOT_ALLOWED THEN
9541 --'The expression contained a Text property which is only allowed in a comparison expression. A Text property is not
9542 -- allowed in the context of your expression. Rule ''%RULENAME'' in Model ''%MODELNAME'' ignored.'
9543        REPORT(CZ_UTILS.GET_TEXT('CZ_R_PROPERTY_NOT_ALLOWED', 'MODELNAME', glName(glIndexByPsNodeId(inProjectId)), 'RULENAME', RULE_NAME), 1);
9544        PACK;
9545      WHEN CZ_R_VIRTUAL_COMPONENT THEN
9546 --'The system property ''%PROPERTYNAME'' is not allowed because ''%NODENAME'' is required. Refer to Oracle Configurator
9547 -- Developer documentation for details. Rule ''%RULENAME'' ignored.'
9548        REPORT(CZ_UTILS.GET_TEXT('CZ_R_VIRTUAL_COMPONENT', 'PROPERTYNAME', localString, 'NODENAME', glName(nParam), 'RULENAME', RULE_NAME), 1);
9549        PACK;
9550      WHEN CZ_R_WRONG_COMPAT_TABLE THEN
9551 --'Incorrect explicit compatibility table, rule ''%RULENAME'' ignored'
9552        REPORT(CZ_UTILS.GET_TEXT('CZ_R_WRONG_COMPAT_TABLE', 'RULENAME', RULE_NAME), 1);
9553        PACK;
9554      WHEN CZ_R_NO_PARTICIPANTS THEN
9555 --'Incomplete rule - no participants, rule ''%RULENAME'' ignored'
9556        REPORT(CZ_UTILS.GET_TEXT('CZ_R_NO_PARTICIPANTS', 'RULENAME', RULE_NAME), 1);
9557        PACK;
9558      WHEN CZ_R_NO_COMPONENT_ID THEN
9559 --'No ps_node_id defined for none of the rule participants, rule ''%RULENAME'' ignored'
9560        REPORT(CZ_UTILS.GET_TEXT('CZ_R_NO_COMPONENT_ID', 'RULENAME', RULE_NAME), 1);
9561        PACK;
9562      WHEN CZ_R_RULE_WRONG_EXPRESSION THEN
9563 --'Invalid expression specified, rule ''%RULENAME'' ignored'
9564        REPORT(CZ_UTILS.GET_TEXT('CZ_R_RULE_WRONG_EXPRESSION', 'RULENAME', RULE_NAME), 1);
9565        PACK;
9566      WHEN CZ_R_WRONG_EFFECTIVITY_SET THEN
9567 --'Invalid effectivity set assosiated with rule ''%RULENAME'', rule ignored'
9568        REPORT(CZ_UTILS.GET_TEXT('CZ_R_WRONG_EFFECTIVITY_SET', 'RULENAME', RULE_NAME), 1);
9569        PACK;
9570      WHEN CZ_R_LITERAL_NO_VALUE THEN
9571 --'No literal value specified in rule ''%RULENAME'', rule ignored'
9572        REPORT(CZ_UTILS.GET_TEXT('CZ_R_LITERAL_NO_VALUE', 'RULENAME', RULE_NAME), 1);
9573        PACK;
9574      WHEN CZ_R_INCORRECT_NODE_ID THEN
9575 --'Incomplete or invalid data in rule ''%RULENAME'', rule ignored'
9576        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_NODE_ID', 'RULENAME', RULE_NAME), 1);
9577        PACK;
9578      WHEN CZ_R_FEATURE_NO_PROPERTY THEN
9579 --'Invalid property or no property specified in rule ''%RULENAME'', rule ignored'
9580        REPORT(CZ_UTILS.GET_TEXT('CZ_R_FEATURE_NO_PROPERTY', 'RULENAME', RULE_NAME), 1);
9581        PACK;
9582      WHEN CZ_R_INCORRECT_REFERENCE THEN
9583 --'The reference %PATH is invalid. At least one node does not exist in the Model or is not effective when the rule is effective.
9584 -- Rule ''%RULENAME'' ignored.'
9585        REPORT(CZ_UTILS.GET_TEXT('CZ_R_INCORRECT_REFERENCE', 'PATH', localString, 'RULENAME', RULE_NAME), 1);
9586        PACK;
9587      WHEN CZ_R_AMBIGUOUS_REFERENCE THEN
9588 --'Unable to resolve Model node reference %PATH because it is ambiguous. Rule ''%RULENAME'' ignored.'
9589        REPORT(CZ_UTILS.GET_TEXT('CZ_R_AMBIGUOUS_REFERENCE', 'PATH', localString, 'RULENAME', RULE_NAME), 1);
9590        PACK;
9591      WHEN CZ_E_NO_EXPECTED_CHILDREN THEN
9592 --'Node ''%NODENAME'' has no children, rule ''%RULENAME'' ignored'
9593        REPORT(CZ_UTILS.GET_TEXT('CZ_E_NO_EXPECTED_CHILDREN', 'NODENAME', localString, 'RULENAME', RULE_NAME), 1);
9594        PACK;
9595      WHEN CZ_E_NO_OPTIONAL_CHILDREN THEN
9596 --'All children of the BOM node ''%NODENAME'' are required when parent is selected, no optional children, rule ''%RULENAME'' ignored'
9597        REPORT(CZ_UTILS.GET_TEXT('CZ_E_NO_OPTIONAL_CHILDREN', 'NODENAME', localString, 'RULENAME', RULE_NAME), 1);
9598        PACK;
9599      WHEN CZ_R_TRACKABLE_ANCESTOR THEN
9600 --'BOM item ''%ITEMNAME'' cannot participate in the Numeric rule ''%RULENAME'' because it contains other trackable BOM items.'
9601        REPORT(CZ_UTILS.GET_TEXT('CZ_R_TRACKABLE_ANCESTOR', 'ITEMNAME', glName(nParam), 'RULENAME', RULE_NAME), 1);
9602        PACK;
9603      WHEN CZ_R_AGAINST_TRACKABLE THEN
9604 --'Numeric rule ''%RULENAME'' is invalid. In a Container Model, a Numeric rule cannot contribute to or consume
9605 -- from how many instances of a trackable Model are allowed at runtime.'
9606        REPORT(CZ_UTILS.GET_TEXT('CZ_R_AGAINST_TRACKABLE', 'RULENAME', RULE_NAME), 1);
9607        PACK;
9608 --'Only nontranslatable System Properties are allowed in the WHERE clause of a COMPATIBLE or FORALL operator.
9609 -- The System Property ''%PROPERTYNAME'' can be translated, therefore it is invalid in this context. Rule ''%RULENAME''
9610 -- in the Model ''%MODELNAME'' will be ignored.'
9611      WHEN CZ_E_DESCRIPTION_IN_WHERE THEN
9612        REPORT(CZ_UTILS.GET_TEXT('CZ_E_DESCRIPTION_IN_WHERE', 'PROPERTYNAME', errorMessage,'MODELNAME', thisProjectName, 'RULENAME', RULE_NAME), 1);
9613        PACK;
9614 --'Only static System Properties are allowed in the WHERE clause of a COMPATIBLE or FORALL operator. The value of the
9615 -- System Property ''%PROPERTYNAME'' can change at runtime, therefore it is invalid in this context. Rule ''%RULENAME''
9616 -- in the Model ''%MODELNAME'' will be ignored.'
9617      WHEN CZ_E_PROPERTY_NOT_STATIC THEN
9618        REPORT(CZ_UTILS.GET_TEXT('CZ_E_PROPERTY_NOT_STATIC', 'PROPERTYNAME', errorMessage,'MODELNAME', thisProjectName, 'RULENAME', RULE_NAME), 1);
9619        PACK;
9620      WHEN CZ_R_TEMPLATE_UNKNOWN OR CZ_R_EMPTY_PARAMETER_SCOPE OR CZ_R_PARAMETER_NOT_FOUND OR
9621           CZ_R_TYPE_NO_PROPERTY OR CZ_R_NO_SIGNATURE_ID THEN
9622 --'Unable to generate rule ''%RULENAME'', internal data error.'
9623        REPORT(CZ_UTILS.GET_TEXT('CZ_G_INTERNAL_RULE_ERROR', 'RULENAME', RULE_NAME), 1);
9624        PACK;
9625      WHEN CZ_G_INVALID_RULE_EXPLOSION THEN
9626 --This is fatal: model_ref_expl_id of one of the participants references an explosion table
9627 --other than the current model table
9628        errorMessage := RULE_NAME;
9629        IF(StopOnFatalRuleError = 1)THEN
9630          IF(c_rules%ISOPEN)THEN CLOSE c_rules; END IF;
9631          RAISE;
9632        ELSE
9633 --'Unable to generate rule ''%RULENAME'', internal data error.'
9634          REPORT(CZ_UTILS.GET_TEXT('CZ_G_INTERNAL_RULE_ERROR', 'RULENAME', errorMessage), 1);
9635          PACK;
9636        END IF;
9637      WHEN CZ_R_UNABLE_TO_CREATE_HEADER THEN
9638 
9639          --This is supposed to be a definitely fatal error, so raise the exception.
9640 
9641          IF(c_rules%ISOPEN)THEN CLOSE c_rules; END IF;
9642          RAISE;
9643      WHEN CZ_LCE_CONTINUE THEN
9644 --This exception is used to immediately move to the next loop, not an error.
9645        NULL;
9646      WHEN OTHERS THEN
9647        IF(nDebug >= 40 AND nDebug <= 54)THEN
9648          errorMessage := RULE_NAME;
9649        ELSIF(SUBSTR(TO_CHAR(nDebug), 1, 1) = '8')THEN
9650          errorMessage := TO_CHAR(nRuleId);
9651        END IF;
9652 
9653        --When the first data corruption-type error for a rule is encountered, logic gen stops.
9654        --However, it may be convenient for debugging purposes to be able to report all of such
9655        --rules. So, check the db setting here.
9656 
9657        IF(StopOnFatalRuleError = 1)THEN
9658          IF(c_rules%ISOPEN)THEN CLOSE c_rules; END IF;
9659          RAISE;
9660        ELSE
9661 --'Unable to generate rule ''%RULENAME'', internal error %ERRORTEXT'
9662          REPORT(CZ_UTILS.GET_TEXT('CZ_G_GENERAL_RULE_ERROR', 'RULENAME', RULE_NAME, 'ERRORTEXT', SQLERRM), 1);
9663          PACK;
9664        END IF;
9665   END;
9666   END LOOP;
9667   CLOSE c_rules;
9668 
9669   --Now generate the INC relations into the root rule file for the non-virtual components
9670   --that have rules against their max.
9671 
9672   IF(v_MaxRuleExists.COUNT > 0)THEN
9673     IF(v_tIsHeaderGenerated.EXISTS(thisComponentExplId))THEN
9674 
9675       --Use this header to generate the rule into
9676 
9677       nHeaderId := v_tIsHeaderGenerated(thisComponentExplId);
9678 
9679     ELSE
9680 
9681       nHeaderId := next_lce_header_id;
9682 
9683       BEGIN
9684 
9685         --Insert the rule net logic header record into the table
9686 
9687         INSERT INTO cz_lce_headers
9688          (lce_header_id, gen_version, gen_header, component_id, net_type,
9689           devl_project_id, model_ref_expl_id, nbr_required_expls, deleted_flag)
9690         VALUES
9691          (nHeaderId, VersionString, GenHeader, inComponentId, LOGIC_NET_TYPE_MANDATORY,
9692           thisProjectId, thisComponentExplId, 1, FLAG_PENDING);
9693 
9694         INSERT INTO cz_lce_load_specs
9695          (attachment_expl_id, lce_header_id, required_expl_id, attachment_comp_id,
9696           model_id, net_type, deleted_flag)
9697         VALUES
9698          (thisComponentExplId, nHeaderId, thisComponentExplId, inComponentId,
9699           thisProjectId, LOGIC_NET_TYPE_MANDATORY, FLAG_PENDING);
9700 
9701       EXCEPTION
9702         WHEN OTHERS THEN
9703           errorMessage := SQLERRM;
9704           RAISE CZ_R_UNABLE_TO_CREATE_HEADER;
9705       END;
9706 
9707       NewHeaders(counterNewHeaders) := nHeaderId;
9708       NewHeadersComponents(counterNewHeaders) := inComponentId;
9709       NewHeadersExplosions(counterNewHeaders) := thisComponentExplId;
9710       counterNewHeaders := counterNewHeaders + 1;
9711 
9712       v_tIsHeaderGenerated(thisComponentExplId) := nHeaderId;
9713       v_tSequenceNbr(nHeaderId) := 1;
9714       v_tLogicNetType(nHeaderId) := LOGIC_NET_TYPE_MANDATORY;
9715       nNewLogicFileFlag := 1;
9716 
9717     END IF;
9718 
9719     --If the logic file has changed then we need to flush off the buffer
9720 
9721     IF(nHeaderId <> nPreviousHeaderId)THEN
9722 
9723      IF(vLogicText IS NOT NULL)THEN
9724        INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
9725         (nPreviousHeaderId, v_tSequenceNbr(nPreviousHeaderId), vLogicText);
9726        vLogicText := NULL;
9727        v_tSequenceNbr(nPreviousHeaderId) := v_tSequenceNbr(nPreviousHeaderId) + 1;
9728      END IF;
9729 
9730     END IF;
9731 
9732     IF(nNewLogicFileFlag = 1)THEN
9733 
9734       --This is a new logic file, put the header lines in
9735 
9736       vLogicLine := 'CONTROL NOSPEC' || NewLine || 'VERSION 3 3' || NewLine || NewLine ||
9737                     'REM -- Rules file for component: ' || TO_CHAR(inComponentId) ||
9738                     ', explosion node: ' || TO_CHAR(thisComponentExplId) || NewLine || NewLine ||
9739                     'EFF , , ' || NewLine || NewLine;
9740       PACK;
9741     END IF;
9742 
9743     FOR i IN 1..v_NodeId.COUNT LOOP
9744      IF(v_MaxRuleExists.EXISTS(v_NodeId(i)) AND v_tVirtualFlag(i) = FLAG_NON_VIRTUAL AND
9745         v_tNodeDepth(i) > 0)THEN
9746 
9747        --Use intermediate variable instead of using NVL because this is faster
9748 
9749        IF(v_tReferringId(i) IS NOT NULL)THEN
9750         localString := TO_CHAR(glPersistentId(v_tReferringId(i)));
9751        ELSE
9752         localString := TO_CHAR(glPersistentId(v_tPsNodeId(i)));
9753        END IF;
9754 
9755        vLogicLine := 'INC 1 P_' || localString || '_MAX round' || NewLine;
9756        PACK;
9757 
9758      END IF;
9759     END LOOP;
9760 
9761   END IF;
9762 
9763 nDebug := 9;
9764 
9765   --Flush off the buffer after rules generation
9766 
9767   IF(vLogicText IS NOT NULL)THEN
9768     INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
9769      (nHeaderId, v_tSequenceNbr(nHeaderId), vLogicText);
9770     vLogicText := NULL;
9771     v_tSequenceNbr(nHeaderId) := v_tSequenceNbr(nHeaderId) + 1;
9772   END IF;
9773 
9774   FOR i IN 1..temp_tables.COUNT LOOP
9775     BEGIN
9776       EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || temp_tables(i);
9777       EXECUTE IMMEDIATE 'DROP TABLE ' || temp_tables(i);
9778     EXCEPTION
9779       WHEN OTHERS THEN
9780         IF(SQLCODE <> ORACLE_OBJECT_IN_USE)THEN RAISE; END IF;
9781     END;
9782   END LOOP;
9783 
9784   IF(TwoPhaseCommit = 0)THEN COMMIT; END IF;
9785 
9786 EXCEPTION
9787   WHEN OTHERS THEN
9788     FOR i IN 1..temp_tables.COUNT LOOP
9789       BEGIN
9790         EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || temp_tables(i);
9791         EXECUTE IMMEDIATE 'DROP TABLE ' || temp_tables(i);
9792       EXCEPTION
9793         WHEN OTHERS THEN
9794           NULL;
9795       END;
9796     END LOOP;
9797     RAISE;
9798 END; --GENERATE_RULES
9799 ---------------------------------------------------------------------------------------
9800 BEGIN --GENERATE_COMPONENT_TREE - Product Structure Generation
9801 
9802   --Generate next lce_header_id for this LCE file. This is the structure net for a model or
9803   --non-virtual component.
9804 
9805 nDebug := 1110000;
9806 
9807   IF(inParentLogicHeaderId IS NULL)THEN
9808 
9809     --If this is the root model, read and store its name and type for later use.
9810 
9811     BEGIN
9812 
9813       SELECT name, model_type INTO thisProjectName, thisProjectType
9814         FROM cz_devl_projects
9815        WHERE devl_project_id = inComponentId;
9816     EXCEPTION
9817       WHEN OTHERS THEN
9818         nParam := inComponentId;
9819         RAISE CZ_S_NO_SUCH_PROJECT;
9820     END;
9821 
9822     IF(inComponentId = inDevlProjectId)THEN
9823 
9824       --Store the name and type of the root project for which the logic generation was
9825       --originally started.
9826 
9827       rootProjectName := thisProjectName;
9828       rootProjectType := thisProjectType;
9829     ELSIF(thisProjectType = MODEL_TYPE_CONTAINER_MODEL AND rootProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
9830 
9831       --Container cannot be referenced or connected to.
9832 
9833       errorMessage := thisProjectName;
9834       RAISE CZ_S_CONTAINER_REFERENCE;
9835     END IF;
9836   END IF;
9837 
9838   IF(NOT IsLogicGenerated.EXISTS(inComponentId))THEN
9839 
9840     --Read the explosions table here. It will be extensively used in rule generation. For the
9841     --structure generation, there is really no need in this table, except that now we want to
9842     --put reasonable values into CZ_LCE_HEADERS.MODEL_REF_EXPL_ID even for structure files as
9843     --this column is being made not nullable in 18.
9844 
9845     IF(inParentLogicHeaderId IS NULL)THEN
9846 
9847       --If this is the root model, read the table and populate project's id and explosion id
9848       --variables, and hash tables.
9849 
9850       SELECT model_ref_expl_id, parent_expl_node_id, node_depth,
9851              ps_node_type, virtual_flag, component_id, referring_node_id,
9852              child_model_expl_id, expl_node_type
9853       BULK COLLECT INTO v_NodeId, v_tParentId, v_tNodeDepth,
9854                         v_tNodeType, v_tVirtualFlag, v_tPsNodeId, v_tReferringId,
9855                         v_tChildModelExpl, v_tExplNodeType
9856       FROM cz_model_ref_expls
9857       WHERE model_id = inComponentId AND deleted_flag = FLAG_NOT_DELETED;
9858 
9859       FOR i IN 1..v_NodeId.COUNT LOOP
9860 
9861 nDebug := 1110010;
9862 
9863         IF(v_tVirtualFlag(i) = FLAG_NON_VIRTUAL AND v_tExplNodeType(i) = EXPL_NODE_TYPE_MANDATORY)THEN
9864 
9865           --This is introduced as a remedy to a well-known type of data corruption occured during
9866           --the development process. May be removed later on when the data become stable.
9867 
9868           errorMessage := thisProjectName;
9869           RAISE CZ_G_INVALID_EXPLOSION_TYPE;
9870         END IF;
9871 
9872 nDebug := 1110001;
9873 
9874         --Add another indexing option - by model_ref_expl_id
9875 
9876         v_IndexByNodeId(v_NodeId(i)) := i;
9877 
9878         --Store the explosion id and the index of the root node - the project node itself.
9879 
9880         IF(v_tNodeDepth(i) = 0)THEN
9881           thisComponentExplId := v_NodeId(i);
9882           thisRootExplIndex := i;
9883         END IF;
9884 
9885         --Create the EXPL_NODE_TYPE(MODEL_REF_EXPL_ID) hash table. Other explosion columns
9886         --are currently indexed through v_IndexByNodeId. Using direct hash may provide for
9887         --some performance improvement.
9888 
9889         v_TypeByExplId(v_NodeId(i)) := v_tExplNodeType(i);
9890 
9891         --Build the MODEL_REF_EXPL_ID(COMPONENT_ID) hash table for all the components
9892         --inside this project (not inside referenced projects). All such components
9893         --have CHILD_MODEL_EXPL_ID null. We need this table to populate MODEL_REF_EXPL_ID
9894         --in CZ_LCE_HEADERS records for structure file of this component.
9895 
9896         IF(v_tChildModelExpl(i) IS NULL)THEN
9897           v_NodeIdByComponent(v_tPsNodeId(i)) := v_NodeId(i);
9898         END IF;
9899       END LOOP;
9900     ELSE
9901 
9902 nDebug := 1110002;
9903 
9904       --This is a non-virtual component inside this project, so the value in the
9905       --hash table exists.
9906       --We do not have to populate thisRootExplIndex, because it is used only in
9907       --rule generation and this will not be called for a non-root component.
9908       --Have to populate the other two variables though as they are used here in
9909       --the structure generation.
9910 
9911       thisComponentExplId := v_NodeIdByComponent(inComponentId);
9912     END IF;
9913 
9914     thisProjectId := inProjectId;
9915 
9916     --Generate next lce_header_id for this LCE file. This is the structure net for a model or
9917     --non-virtual component.
9918 
9919     nStructureHeaderId := next_lce_header_id;
9920 
9921     BEGIN
9922 
9923      --Insert the structure logic header record into the table.
9924 
9925      INSERT INTO cz_lce_headers
9926       (lce_header_id, gen_version, gen_header, component_id, net_type,
9927        devl_project_id, model_ref_expl_id, nbr_required_expls, deleted_flag)
9928      VALUES
9929       (nStructureHeaderId, VersionString, GenHeader, inComponentId, LOGIC_NET_TYPE_STRUCTURE,
9930        thisProjectId, thisComponentExplId, 1, FLAG_PENDING);
9931 
9932      --Insert the structure load conditions record for this component.
9933 
9934      INSERT INTO cz_lce_load_specs
9935       (attachment_expl_id, lce_header_id, required_expl_id, attachment_comp_id,
9936        model_id, net_type, deleted_flag)
9937      VALUES
9938       (thisComponentExplId, nStructureHeaderId, thisComponentExplId, inComponentId,
9939        thisProjectId, LOGIC_NET_TYPE_STRUCTURE, FLAG_PENDING);
9940 
9941     EXCEPTION
9942       WHEN OTHERS THEN
9943         errorMessage := SQLERRM;
9944         RAISE CZ_S_UNABLE_TO_CREATE_HEADER;
9945     END;
9946 
9947     NewHeaders(counterNewHeaders) := nStructureHeaderId;
9948     NewHeadersComponents(counterNewHeaders) := inComponentId;
9949     NewHeadersExplosions(counterNewHeaders) := thisComponentExplId;
9950     counterNewHeaders := counterNewHeaders + 1;
9951 
9952   ELSIF(IsLogicGenerated(inComponentId) = 0)THEN
9953 
9954     --The flag may be set by two reasons: the model was considered up-to-date or the model has already been
9955     --processed in this session. Only in the first case a header should exist in the database and we need
9956     --to load it into memory. In the second case it should be in the memory and may not exist in the database.
9957     --Bug #3150226.
9958 
9959 nDebug := 1110003;
9960 
9961     SELECT head.lce_header_id, max(text.seq_nbr) INTO nStructureHeaderId, nSequenceNbr
9962       FROM cz_lce_headers head, cz_lce_texts text
9963      WHERE head.deleted_flag = FLAG_NOT_DELETED
9964        AND head.net_type = LOGIC_NET_TYPE_STRUCTURE
9965        AND head.component_id = inComponentId
9966        AND head.lce_header_id = text.lce_header_id
9967      GROUP BY head.lce_header_id;
9968 
9969     vSeqNbrByHeader(nStructureHeaderId) := nSequenceNbr + 1;
9970   END IF;
9971 
9972 nDebug := 1110004;
9973 
9974   vLogicText := 'CONTROL NOSPEC' || NewLine || 'VERSION 3 3' || NewLine ||
9975                 'SETDEFAULTDELTA F' || NewLine || 'EFF , , ' || NewLine || NewLine ||
9976                 'REM -- Structure file for component: ' || TO_CHAR(inComponentId) || NewLine || NewLine ||
9977                 'OBJECT _ALWAYS_TRUE' || NewLine || 'MINMAX 1 1 _ALWAYS_TRUE' || NewLine ||
9978                 'OBJECT _ALWAYS_FALSE' || NewLine ||
9979                 'GS N' || NewLine || 'GL L _ALWAYS_TRUE' || NewLine || 'GR L _ALWAYS_FALSE' || NewLine;
9980 
9981 nDebug := 1110005;
9982 
9983   --This SELECT statement reads the whole 'virtual' tree under a non-virtual component which also
9984   --includes the non-virtual component itself. Non-virtual components underneath are included in
9985   --order to recurse, and this function will be called for every non-virtual component underneath.
9986   --The resulting order provided by this statement is used later when generating list of options
9987   --for an option feature.
9988 
9989   SELECT ps_node_id, parent_id, item_id, minimum, maximum, name, intl_text_id, minimum_selected,
9990          maximum_selected, ps_node_type, initial_value, virtual_flag, feature_type, bom_required_flag,
9991          reference_id, persistent_node_id, effective_from, effective_until, effective_usage_mask,
9992          effectivity_set_id, decimal_qty_flag, ib_trackable, accumulator_flag, initial_num_value,
9993          instantiable_flag, shippable_item_flag, inventory_transactable_flag, assemble_to_order_flag,
9994          serializable_item_flag
9995   BULK COLLECT INTO
9996          ntPsNodeId, ntParentId, ntItemId, ntMinimum, ntMaximum, ntName, ntDescriptionId, ntMinimumSel,
9997          ntMaximumSel, ntPsNodeType, ntInitialValue, ntVirtualFlag, ntFeatureType, ntBomRequired,
9998          ntReferenceId, ntPersistentId, dtEffFrom, dtEffUntil, vtUsageMask,
9999          ntEffSetId, ntDecimalQty, ntIbTrackable, ntAccumulator, ntInitialNumValue,
10000          ntInstantiableFlag, ntShippableFlag, ntTransactableFlag, ntAtoFlag, ntSerializableFlag
10001   FROM cz_ps_nodes
10002   WHERE deleted_flag = FLAG_NOT_DELETED
10003   START WITH ps_node_id = inComponentId
10004   CONNECT BY PRIOR ps_node_id = parent_id
10005       AND (PRIOR virtual_flag IS NULL OR PRIOR virtual_flag = FLAG_VIRTUAL OR
10006            PRIOR ps_node_id = inComponentId);
10007 
10008 nDebug := 1110006;
10009 
10010   --Make sure there is some data returned
10011 
10012   IF(ntPsNodeId.LAST IS NOT NULL)THEN
10013 
10014 nDebug := 1110007;
10015 
10016   --Having this dummy boundary node eliminates the necessity of potentially time
10017   --consuming boundary checks during the option feature options' list generation
10018 
10019   ntParentId(ntPsNodeId.LAST + 1) := NEVER_EXISTS_ID;
10020 
10021   --Prepare to start the main cycle
10022 
10023   i := ntPsNodeId.FIRST;
10024 
10025   WHILE(i <= ntPsNodeId.LAST) LOOP --Start the main structure generating cycle
10026    BEGIN
10027 
10028     CurrentlyPacking := PACKING_GENERIC;
10029 
10030    --Populate the 'global' arrays - required for rules generation
10031 
10032 nDebug := 1110010;
10033 
10034     IF(NOT glIndexByPsNodeId.EXISTS(ntPsNodeId(i)))THEN
10035 
10036      IF(ntInitialNumValue(i) IS NOT NULL)THEN ntInitialValue(i) := TO_CHAR(ntInitialNumValue(i)); END IF;
10037 
10038      glPsNodeId(globalCount) := ntPsNodeId(i);
10039      glItemId(globalCount) := ntItemId(i);
10040      glPsNodeType(globalCount) := ntPsNodeType(i);
10041      glParentId(globalCount) := ntParentId(i);
10042      glFeatureType(globalCount) := ntFeatureType(i);
10043      glName(globalCount) := ntName(i);
10044      glBomRequired(globalCount) := ntBomRequired(i);
10045      glMinimum(globalCount) := ntMinimum(i);
10046      glMaximum(globalCount) := ntMaximum(i);
10047      glMinimumSel(globalCount) := ntMinimumSel(i);
10048      glMaximumSel(globalCount) := ntMaximumSel(i);
10049      glVirtualFlag(globalCount) := ntVirtualFlag(i);
10050      glInitialValue(globalCount) := ntInitialValue(i);
10051 
10052    --Indexing by ps_node_id, will be used in expressions generation to get back to
10053    --the structure.
10054 
10055      glIndexByPsNodeId(ntPsNodeId(i)) := globalCount;
10056 
10057    --These global arrays will be indexed differently because we only need to get
10058    --persistent_node_id or reference_id by ps_node_id. Probably, good indexing
10059    --option for some of the other global arrays, too.
10060 
10061      glPersistentId(ntPsNodeId(i)) := ntPersistentId(i);
10062      glReferenceId(ntPsNodeId(i)) := ntReferenceId(i);
10063      glDecimalQty(ntPsNodeId(i)) := ntDecimalQty(i);
10064      glIbTrackable(ntPsNodeId(i)) := ntIbTrackable(i);
10065      glAccumulator(ntPsNodeId(i)) := ntAccumulator(i);
10066      glInstantiableFlag(ntPsNodeId(i)) := ntInstantiableFlag(i);
10067 
10068    --Children of any node start right after the node. But then, the children list may
10069    --not be dense, because children may have their own children. So in order to find
10070    --all the children of a node we need to search the whole structure after the node.
10071    --Here we store the last child's index so that we need to search not the whole
10072    --structure up to the end but up to this last child's index.
10073 
10074 nDebug := 1110011;
10075 
10076      IF(ntParentId(i) IS NOT NULL)THEN
10077       glLastChildIndex(ntParentId(i)) := globalCount;
10078 
10079       --This array is used in design chart rules generation and contains the number of children
10080       --of a node. We actually use it only for features and BOM option classes.
10081 
10082       IF(NOT featOptionsCount.EXISTS(ntParentId(i)))THEN featOptionsCount(ntParentId(i)) := 0; END IF;
10083       featOptionsCount(ntParentId(i)) := featOptionsCount(ntParentId(i)) + 1;
10084      END IF;
10085 
10086      IF(ntPsNodeType(i) = PS_NODE_TYPE_BOM_STANDARD AND ntIbTrackable(i) = FLAG_IB_TRACKABLE AND
10087         thisProjectType IN (MODEL_TYPE_PTO_MODEL, MODEL_TYPE_ATO_MODEL) AND
10088         glPsNodeType(glIndexByPsNodeId(ntParentId(i))) = PS_NODE_TYPE_BOM_MODEL AND
10089         glIbTrackable(ntParentId(i)) = FLAG_NOT_IB_TRACKABLE) THEN
10090 
10091        --A trackable BOM Standard item cannot be a direct child of a non-trackable
10092        --ATO/PTO Model if this model is references from any Network Container model.
10093        --Re: bug #3644036.
10094 
10095        IF(NOT h_containerReferred.EXISTS(ntParentId(i)))THEN
10096 
10097          BEGIN
10098 
10099            EXECUTE IMMEDIATE containerReferred INTO h_containerReferred(ntParentId(i)) USING ntParentId(i);
10100 
10101          EXCEPTION
10102            WHEN NO_DATA_FOUND THEN
10103              h_containerReferred(ntParentId(i)) := 0;
10104          END;
10105        END IF;
10106 
10107        IF(h_containerReferred(ntParentId(i)) = 1)THEN
10108 
10109          errorMessage := thisProjectName;
10110          nParam := glIndexByPsNodeId(ntPsNodeId(i));
10111          RAISE CZ_S_TRACKABLE_STANDARD;
10112        END IF;
10113      END IF;
10114 
10115    --Prepare the actual effective date interval for populating global effectivity dates.
10116    --First get the nominal effective date interval either from an effectivity set or
10117    --from the local values.
10118 
10119      IF(ntEffSetId(i) IS NOT NULL)THEN
10120       IF(gvIndexBySetId.EXISTS(ntEffSetId(i)))THEN
10121        CurrentEffFrom := gvEffFrom(gvIndexBySetId(ntEffSetId(i)));
10122        CurrentEffUntil := gvEffUntil(gvIndexBySetId(ntEffSetId(i)));
10123       ELSE
10124         --This is a fatal error - data corruption.
10125         --'Invalid effectivity set associated with node ''%NODENAME'''
10126         errorMessage := CZ_UTILS.GET_TEXT('CZ_S_WRONG_EFFECTIVITY_SET', 'NODENAME', ntName(i));
10127         RAISE CZ_S_WRONG_EFFECTIVITY_SET;
10128       END IF;
10129      ELSE
10130        CurrentEffFrom := dtEffFrom(i);
10131        CurrentEffUntil := dtEffUntil(i);
10132      END IF;
10133      CurrentUsageMask := vtUsageMask(i);
10134 
10135    --Make sure effective dates are not null, so that actual effective date interval
10136    --will have no null bounds too. Usage mask is not null anyway.
10137 
10138      IF(CurrentEffFrom IS NULL)THEN CurrentEffFrom := EpochBeginDate; END IF;
10139      IF(CurrentEffUntil IS NULL)THEN CurrentEffUntil := EpochEndDate; END IF;
10140 
10141    --If this is not a model or a root component, adjust the effectivity dates by
10142    --intersecting with parent's actual effectivity dates, which have already been
10143    --calculated because of the hierarchichal order of the query.
10144    --Actual effective date interval is the intersection of parent's actual effective
10145    --date interval with child's nominal effective date interval. Again, no nulls.
10146 
10147      IF(ntParentId(i) IS NOT NULL)THEN
10148 
10149        localCount := glIndexByPsNodeId(ntParentId(i));
10150        IF(glEffFrom(localCount) > CurrentEffFrom)THEN CurrentEffFrom := glEffFrom(localCount); END IF;
10151        IF(glEffUntil(localCount) < CurrentEffUntil)THEN CurrentEffUntil := glEffUntil(localcount); END IF;
10152 
10153        --Adjust usage mask here. CurrentUsageMask is now OR-ed with glUsageMask(localCount)
10154        CurrentUsageMask := RAWTOHEX(UTL_RAW.BIT_OR(HEXTORAW(LPAD(CurrentUsageMask,16,'0')),HEXTORAW(glUsageMask(localCount))));
10155 
10156      END IF;
10157 
10158    --From now on the local variables (dtEff) or effectivity set, if defined, will contain
10159    --the nominal effective date interval while the global variables (glEff) will contain
10160    --the actual (intersected with parent) effective date interval.
10161    --The same is true for the usage mask nominal/actual values.
10162 
10163      glEffFrom(globalCount) := CurrentEffFrom;
10164      glEffUntil(globalCount) := CurrentEffUntil;
10165      glUsageMask(globalCount) := CurrentUsageMask;
10166 
10167      glHeaderByPsNodeId(ntPsNodeId(i)) := nStructureHeaderId;
10168      globalCount := globalCount + 1;
10169 
10170     ELSE
10171 
10172      localCount := glIndexByPsNodeId(ntPsNodeId(i));
10173      CurrentEffFrom := glEffFrom(localCount);
10174      CurrentEffUntil := glEffUntil(localCount);
10175      CurrentUsageMask := glUsageMask(localCount);
10176 
10177     END IF;
10178 
10179 nDebug := 1110012;
10180 
10181     IF(isLogicGenerated.EXISTS(inComponentId))THEN
10182 
10183       --We need to call the procedure for any non-virtual component (bug #2065239) and for any
10184       --component and reference.
10185 
10186       IF(ntPsNodeType(i) IN (PS_NODE_TYPE_REFERENCE, PS_NODE_TYPE_CONNECTOR))THEN
10187 
10188         --Check for circularity.
10189 
10190         localCount := 0;
10191 
10192         FOR n IN 1..globalLevel LOOP
10193          IF(globalStack(n) = ntReferenceId(i))THEN
10194 
10195            --Circularity detected.
10196 
10197            localCount := 1;
10198            EXIT;
10199          END IF;
10200         END LOOP;
10201 
10202         IF(localCount = 0)THEN
10203 
10204           globalLevel := globalLevel + 1;
10205           globalStack(globalLevel) := ntReferenceId(i);
10206           globalRef(globalLevel) := ntPsNodeId(i);
10207 
10208           IF(ntPsNodeType(i) = PS_NODE_TYPE_REFERENCE)THEN
10209 
10210             localMinString := TO_CHAR(ntMinimum(i));
10211             IF(localMinString IS NULL)THEN localMinString := '0'; END IF;
10212             localMaxString := TO_CHAR(ntMaximum(i));
10213             IF(localMaxString IS NULL)THEN localMaxString := '-1'; END IF;
10214 
10215             --Store the information on the instantiability of the reference on the stack.
10216 
10217             IF(localMinString = '1' AND localMaxString = '1')THEN
10218               globalInstance(globalLevel) := 0;
10219             ELSE
10220               globalInstance(globalLevel) := 1;
10221             END IF;
10222           ELSE
10223             --This is a connector and instantiability is not defined, but we need a value on
10224             --the stack.
10225 
10226             globalInstance(globalLevel) := 0;
10227           END IF;
10228 
10229           GENERATE_COMPONENT_TREE(ntReferenceId(i), ntReferenceId(i), NULL);
10230           globalLevel := globalLevel - 1;
10231 
10232           --Bug #5003285. Need to move the propagation of trackable flag into this branch which
10233           --executes even if child model is up-to-date.
10234 
10235           IF(ntPsNodeType(i) = PS_NODE_TYPE_REFERENCE AND rootProjectType = MODEL_TYPE_CONTAINER_MODEL AND
10236 
10237             --All the following verifications are to be made only if the referenced model is
10238             --a BOM Model - bug #2509208.
10239 
10240             glPsNodeType(glIndexByPsNodeId(ntReferenceId(i))) IN
10241               (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
10242 
10243             --If the referenced model is trackable it may be a trackable leaf. However, if its
10244             --trackableAncestor flag exists, it has trackable children. In any case we need to
10245             --mark all of its ancestors and make sure their quantities are not greater than 1,
10246             --because the root is a container model here.
10247 
10248             IF(glIbTrackable(ntReferenceId(i)) = FLAG_IB_TRACKABLE OR
10249                trackableAncestor.EXISTS(ntReferenceId(i)))THEN
10250 
10251                trackableAncestor(ntPsNodeId(i)) := 1;
10252                PROPAGATE_TRACKABLE_ANCESTOR;
10253             END IF;
10254           END IF;
10255         END IF;
10256 
10257       ELSIF(ntVirtualFlag(i) = FLAG_NON_VIRTUAL AND
10258             ntPsNodeType(i) IN (PS_NODE_TYPE_COMPONENT, PS_NODE_TYPE_PRODUCT) AND
10259             ntPsNodeId(i) <> inComponentId)THEN
10260 
10261         --We emulate the component as a model with generated logic because we do not want to
10262         --generate anything but still want to follow everything underneath this component.
10263 
10264         IsLogicGenerated(ntPsNodeId(i)) := 1;
10265 
10266         --We can pass logic header as NULL because it will never be actually used.
10267 
10268         GENERATE_COMPONENT_TREE(ntPsNodeId(i), inProjectId, 0);
10269       END IF;
10270 
10271       --Bug #5003285. Need to move the propagation of trackable flag into this branch which
10272       --executes even if child model is up-to-date.
10273 
10274       IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL AND
10275          ntPsNodeType(i) IN (PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD) AND
10276          glIbTrackable(ntPsNodeId(i)) = FLAG_IB_TRACKABLE)THEN
10277 
10278          PROPAGATE_TRACKABLE_ANCESTOR;
10279 
10280          --If the item is tangible, we should prohibit not only its ancestors but also itself
10281          --from being on the RHS of numeric rules - TSO with Equipment.
10282 
10283          IF(ntShippableFlag(i) = '1')THEN trackableAncestor(ntPsNodeId(i)) := 2; END IF;
10284       END IF;
10285 
10286     --If no logic already exists, generate the structure.
10287 
10288     ELSE
10289 
10290     GENERATE_EFFECTIVITY_LOGIC(CurrentEffFrom, CurrentEffUntil, CurrentUsageMask);
10291 
10292     IF(ntPsNodeType(i) = PS_NODE_TYPE_OPTION)THEN
10293 
10294       --We are in a feature's options. The important assumption here is that a feature
10295       --can have only options as it's children,so feature's children list is dense and
10296       --all the feature's children should be processed, and this list starts here.
10297       --In other words, we assume that as soon as we encountered the first option of a
10298       --feature, we will be dealing only with options of this feature until we process
10299       --all of them.
10300 
10301       /*--The restriction is removed (bug #1746927)-----------------------------------
10302         --First make sure that there aren't too many options.
10303       IF(optionCounter > MAX_NUMBER_OF_OPTIONS)THEN
10304         --This will be fatal and terminate the logic generation
10305         --'Option feature has more than maximum allowed number of options, feature ''%FEATNAME'''
10306         errorMessage := CZ_UTILS.GET_TEXT('CZ_S_TOO_MANY_OPTIONS', 'FEATNAME', ntName(i));
10307         RAISE CZ_S_TOO_MANY_OPTIONS;
10308       END IF;
10309       ------------------------------------------------------------------------------*/
10310 
10311       optionCounter := optionCounter + 1;
10312 
10313       --Generate the option: OBJECT P_<OptID> R
10314       vLogicLine := 'OBJECT P_' || TO_CHAR(ntPersistentId(i)) || ' R' || NewLine;
10315 
10316       --If this is the last option, we will generate the feature right here
10317 
10318       IF(ntParentId(i + 1) <> ntParentId(i))THEN
10319 
10320         --Done with options, ready to generate the feature, put in the stored
10321         --effectivity information.
10322 
10323         PACK;
10324         GENERATE_EFFECTIVITY_LOGIC(FeatureEffFrom, FeatureEffUntil, FeatureUsageMask);
10325 
10326         --This is the feature index
10327 
10328         j := i - optionCounter;
10329 
10330         --Generate the feature itself. Local variables here are inherited from the feature
10331         --generation section.
10332         --But before that adjust the minimum number of selected children to the actual number
10333         --of options - bug #2233795.
10334 
10335         IF(ntMinimum(j) IS NOT NULL AND ntMinimum(j) > optionCounter)THEN
10336 
10337           localMinString := TO_CHAR(optionCounter);
10338         END IF;
10339 
10340         vLogicLine := 'SGN P_' || TO_CHAR(ntPersistentId(j)) || ' R ' || localMinString || ' ' ||
10341         localMaxString || ' _';
10342 
10343 nDebug := 1110028;
10344 
10345         --Generate the list of options for the feature
10346 
10347         WHILE(j < i)LOOP
10348 
10349          j := j + 1;
10350 
10351          --This call is necessary here for wrapping
10352 
10353          PACK;
10354          vLogicLine := ' P_' || TO_CHAR(ntPersistentId(j));
10355 
10356 nDebug := 1110029;
10357 
10358         END LOOP;
10359 
10360         --We must put [new line] after the list of options
10361 
10362         vLogicLine := vLogicLine || NewLine;
10363         j := i - optionCounter;
10364 
10365         PACK;
10366         GENERATE_ACCUMULATOR(j);
10367         generatingFeature := 0;
10368 
10369         --Minimum number of selected options greater than the actual number of options.
10370         --The feature is already generated and now will be reported.
10371 
10372         IF(ntMinimum(j) IS NOT NULL AND ntMinimum(j) > optionCounter)THEN
10373 
10374          RAISE CZ_S_ILLEGAL_OPTION_FEATURE;
10375         END IF;
10376 
10377       END IF;
10378 
10379     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_TOTAL OR
10380        ntPsNodeType(i) = PS_NODE_TYPE_RESOURCE)THEN
10381 
10382 nDebug := 1110014;
10383 
10384     --This is a total or resource: TOTAL P_<Tot/ResID> R [tot/res initial value]
10385 
10386      vLogicLine := 'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || ' R ' ||
10387                    ntInitialValue(i) || NewLine;
10388     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_FEATURE)THEN
10389 
10390 nDebug := 1110015;
10391 
10392     --This is a feature, so consider different subtypes
10393 
10394      IF(ntFeatureType(i) IS NULL OR ntFeatureType(i) = PS_NODE_FEATURE_TYPE_INTEGER)THEN
10395 
10396 nDebug := 1110016;
10397 
10398      --This is an integer feature: real integer or count
10399 
10400       IF(ntMinimum(i) IS NULL OR ntMinimum(i) < 0)THEN
10401 
10402 nDebug := 1110017;
10403 
10404       --This is a real integer feature: TOTAL P_<FeatID> R [initial_value]
10405 
10406        vLogicLine := 'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || ' R ' ||
10407                      ntInitialValue(i) || NewLine;
10408       ELSE
10409 
10410 nDebug := 1110018;
10411 
10412       --This is a count feature: OBJECT P_<FeatID> R [initial_value]
10413 
10414 /* This is rolled back as a fix for the bug #1994924.
10415 
10416        --If initial value is not specified and minimum value is greater than 0, we
10417        --define the initial value to be equal to the minimum value. Bug #1834581.
10418 
10419        IF(ntInitialValue(i) IS NULL)THEN
10420          ntInitialValue(i) := ntMinimum(i);
10421        END IF;
10422 */
10423        vLogicLine := 'OBJECT P_' || TO_CHAR(ntPersistentId(i)) || ' R ' ||
10424                      ntInitialValue(i) || NewLine;
10425       END IF;
10426      ELSIF(ntFeatureType(i) = PS_NODE_FEATURE_TYPE_FLOAT)THEN
10427 
10428 nDebug := 1110019;
10429 
10430      --This is a decimal feature: TOTAL P_<FeatID> R [initial_value]
10431 
10432 /* This is rolled back as a fix for the bug #1994924.
10433 
10434       --If initial value is not specified and minimum value is specified and is greater than 0,
10435       --we define the initial value to be equal to the minimum value. Bug #1834581.
10436 
10437       IF(ntInitialValue(i) IS NULL AND ntMinimum(i) > 0)THEN
10438         ntInitialValue(i) := ntMinimum(i);
10439       END IF;
10440 */
10441       vLogicLine := 'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || ' R ' ||
10442                     ntInitialValue(i) || NewLine;
10443      ELSIF(ntFeatureType(i) = PS_NODE_FEATURE_TYPE_BOOLEAN)THEN
10444 
10445 nDebug := 1110020;
10446 
10447      --This is a boolean feature
10448 
10449       vLogicLine := 'OBJECT P_' || TO_CHAR(ntPersistentId(i)) || ' R' || NewLine;
10450       IF(ntInitialValue(i) IS NOT NULL)THEN
10451        IF(ntInitialValue(i) = '1')THEN
10452 
10453 nDebug := 1110021;
10454 
10455        --Initial value is 'True', create a default rule from an always true object
10456        --toward this one
10457 
10458         vLogicLine := vLogicLine || 'OBJECT D_' || TO_CHAR(ntPersistentId(i)) || '_IV' || NewLine ||
10459           'WITH _default = _ALWAYS_TRUE' || NewLine ||
10460           'GS R ... ' || TO_CHAR(ntDescriptionId(i)) || NewLine ||
10461           'GL N D_' || TO_CHAR(ntPersistentId(i)) || '_IV' || NewLine ||
10462           'GR N P_' || TO_CHAR(ntPersistentId(i)) || NewLine;
10463 
10464 --        vLogicLine := vLogicLine || 'WITH _default = _ALWAYS_TRUE' || NewLine;
10465 
10466        ELSIF(ntInitialValue(i) = '0')THEN
10467 
10468 nDebug := 1110022;
10469 
10470        --Initial value is 'False', create a temporary object and an additional
10471        --'negates' relation
10472 
10473         vLogicLine := vLogicLine || 'OBJECT D_' || TO_CHAR(ntPersistentId(i)) || '_IV' || NewLine ||
10474           'WITH _default = _ALWAYS_TRUE' || NewLine ||
10475           'GS N ... ' || TO_CHAR(ntDescriptionId(i)) || NewLine ||
10476           'GL N D_' || TO_CHAR(ntPersistentId(i)) || '_IV' || NewLine ||
10477           'GR N P_' || TO_CHAR(ntPersistentId(i)) || NewLine;
10478 
10479        ELSE
10480 
10481         RAISE CZ_S_BAD_BOOLEAN_FEAT_VALUE;
10482 
10483        END IF;
10484       END IF;
10485 
10486      ELSIF(ntFeatureType(i) = PS_NODE_FEATURE_TYPE_STRING)THEN
10487 
10488 nDebug := 1110023;
10489 
10490        NULL;
10491 
10492 /* Do not need to generate anything for text features.
10493 
10494      --This is a text feature
10495 
10496       vLogicLine := 'TEXT P_' || TO_CHAR(ntPersistentId(i)) || ' R "' ||
10497                   ntInitialValue(i) || '"' || NewLine;
10498 */
10499      ELSIF(ntFeatureType(i) = PS_NODE_FEATURE_TYPE_OPTION)THEN
10500 
10501       --Set the options counter
10502 
10503       optionCounter := 0;
10504 
10505       --Prepare Min, Max values for later use
10506       --Use intermediate variable instead of using NVL because this is faster
10507       --This values will be used also when generating the last option of the feature
10508 
10509       localMinString := TO_CHAR(ntMinimum(i));
10510       IF(localMinString IS NULL)THEN localMinString := '0'; END IF;
10511       localMaxString := TO_CHAR(ntMaximum(i));
10512       IF(localMaxString IS NULL)THEN localMaxString := '-1'; END IF;
10513 
10514       --Save feature's effective intervals and usage mask for feature generating type
10515 
10516       FeatureEffFrom := CurrentEffFrom;
10517       FeatureEffUntil := CurrentEffUntil;
10518       FeatureUsageMask := CurrentUsageMask;
10519 
10520 nDebug := 1110024;
10521 
10522       --Check if there are any children, report if not
10523 
10524       IF(ntParentId(i + 1) <> ntPsNodeId(i))THEN
10525 
10526         --No options, still want to generate the feature even with empty options list
10527 
10528         vLogicLine := 'SGN P_' || TO_CHAR(ntPersistentId(i)) || ' R ' || localMinString || ' ' ||
10529         localMaxString || ' _' || NewLine;
10530 
10531         --No children, report the feature
10532         RAISE CZ_S_FEATURE_NO_CHILDREN;
10533       END IF;
10534 
10535       --Now proceed with the cycle. As options of the feature directly follows it in memory,
10536       --we will be generating them right away. After the last option, the feature itself will
10537       --be generated (see options generating code).
10538 
10539       generatingFeature := 1;
10540 
10541 nDebug := 1110027;
10542 
10543      ELSE
10544 
10545        --'Unknown feature type, feature ''%FEATNAME'''
10546        errorMessage := CZ_UTILS.GET_TEXT('CZ_S_UNKNOWN_FEATURE_TYPE', 'FEATNAME', ntName(i));
10547        RAISE CZ_S_UNKNOWN_FEATURE_TYPE;
10548      END IF;
10549     ELSIF(ntPsNodeType(i) IN (PS_NODE_TYPE_COMPONENT, PS_NODE_TYPE_PRODUCT) AND
10550           ntVirtualFlag(i) = FLAG_NON_VIRTUAL)THEN
10551 
10552 nDebug := 1110030;
10553 
10554      --We don't want to go into an infinite cycle - don't call the procedure for the current
10555      --root component
10556 
10557      IF(ntPsNodeId(i) <> inComponentId)THEN
10558 
10559       --This is another non-virtual component. Call this function for it - recursion
10560       --Use intermediate variable instead of using NVL because this is faster
10561 
10562       localMinString := TO_CHAR(ntMinimum(i));
10563       IF(localMinString IS NULL)THEN localMinString := '0'; END IF;
10564       localMaxString := TO_CHAR(ntMaximum(i));
10565       IF(localMaxString IS NULL)THEN localMaxString := '-1'; END IF;
10566 
10567       vLogicLine := 'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_MIN R ' || localMinString || NewLine ||
10568                     'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_MAX R ' || localMaxString || NewLine ||
10569                     'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_ACTUALCOUNT R 0' || NewLine;
10570 
10571       GENERATE_COMPONENT_TREE(ntPsNodeId(i), inProjectId, nStructureHeaderId);
10572      END IF;
10573 
10574     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_REFERENCE)THEN
10575 
10576 nDebug := 1110031;
10577 
10578      --Check for circularity.
10579 
10580      localCount := 0;
10581      trackableContext := 0;
10582      instantiableContext := 0;
10583 
10584      FOR n IN 1..globalLevel LOOP
10585 
10586       IF(globalStack(n) = ntReferenceId(i))THEN
10587 
10588         --Circularity detected.
10589 
10590         localCount := 1;
10591         EXIT;
10592       END IF;
10593 
10594       IF(glIbTrackable(globalStack(n)) = FLAG_IB_TRACKABLE)THEN
10595 
10596         trackableContext := globalStack(n);
10597       END IF;
10598 
10599       IF(globalInstance(n) = 1)THEN
10600 
10601         instantiableContext := globalStack(n);
10602       END IF;
10603      END LOOP;
10604 
10605      localMinString := TO_CHAR(ntMinimum(i));
10606      IF(localMinString IS NULL)THEN localMinString := '0'; END IF;
10607      localMaxString := TO_CHAR(ntMaximum(i));
10608      IF(localMaxString IS NULL)THEN localMaxString := '-1'; END IF;
10609 
10610      IF(ntVirtualFlag(i) = FLAG_NON_VIRTUAL)THEN
10611 
10612        vLogicLine := 'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_MIN R ' || localMinString || NewLine ||
10613                      'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_MAX R ' || localMaxString || NewLine ||
10614                      'TOTAL P_' || TO_CHAR(ntPersistentId(i)) || '_ACTUALCOUNT R 0' || NewLine;
10615      END IF;
10616 
10617      IF(localCount = 0)THEN
10618 
10619        --Follow the reference, doesn't affect the current LCE file.
10620        --Use intermediate variable instead of using NVL because this is faster.
10621        --Maintain the stack of references - needed to be able to detect dead-loops.
10622 
10623        globalLevel := globalLevel + 1;
10624        globalStack(globalLevel) := ntReferenceId(i);
10625        globalRef(globalLevel) := ntPsNodeId(i);
10626 
10627        --Store the information on the instantiability of the reference on the stack.
10628 
10629        IF(localMinString = '1' AND localMaxString = '1')THEN
10630          globalInstance(globalLevel) := 0;
10631        ELSE
10632          globalInstance(globalLevel) := 1;
10633        END IF;
10634 
10635        GENERATE_COMPONENT_TREE(ntReferenceId(i), ntReferenceId(i), NULL);
10636        globalLevel := globalLevel - 1;
10637 
10638        IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL AND
10639 
10640           --All the following verifications are to be made only if the referenced model is
10641           --a BOM Model - bug #2509208.
10642 
10643           glPsNodeType(glIndexByPsNodeId(ntReferenceId(i))) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
10644 
10645          errorMessage := glName(glIndexByPsNodeId(ntReferenceId(i)));
10646 
10647          --If this is a network container model, every reference to a trackable model should
10648          --have exactly minimum = 0 and maximum = -1. This validation must be made after the
10649          --referenced model is processed so that its IB_TRACKABLE flag has become available.
10650          --IB_TRACKABLE flag for the instantiably referenced model should not be null.
10651 
10652          IF(glIbTrackable(ntReferenceId(i)) IS NULL)THEN
10653 
10654            RAISE CZ_S_NO_TRACKABLE_FLAG;
10655 
10656          ELSIF(trackableContext = 0 AND glIbTrackable(ntReferenceId(i)) = FLAG_IB_TRACKABLE)THEN
10657 
10658            --This is a trackable instance model, make additional verifications.
10659 
10660            IF(instanceModel.EXISTS(ntReferenceId(i)) AND
10661               (globalLevel > 1 OR instanceModel(ntReferenceId(i)) > 1))THEN
10662 
10663              --Multiple occurrences of a trackable instance model. We allow them only if all
10664              --of them are immediate children of the container model, because they may have
10665              --different effectivity ranges.
10666 
10667              nParam := glIndexByPsNodeId(globalStack(globalLevel - 1));
10668              RAISE CZ_S_MULTIPLE_TRACKABLE;
10669 
10670            ELSIF(instantiableContext > 0)THEN
10671 
10672              --One of the ancestors of the trackable instance model is multiply instantiable.
10673 
10674              nParam := glIndexByPsNodeId(instantiableContext);
10675              RAISE CZ_S_MULTIPLE_INSTANCES;
10676 
10677            ELSIF(localMinString <> '0' OR localMaxString <> '-1')THEN
10678 
10679              --Incorrect instance numbers for a reference to a trackable instance model.
10680 
10681              RAISE CZ_S_INCORRECT_CONTAINER;
10682 
10683            ELSE
10684 
10685              instanceModel(ntReferenceId(i)) := globalLevel;
10686            END IF;
10687          END IF;
10688 
10689          --If the referenced model is trackable it may be a trackable leaf. However, if its
10690          --trackableAncestor flag exists, it has trackable children. In any case we need to
10691          --mark all of its ancestors and make sure their quantities are not greater than 1,
10692          --because the root is a container model here.
10693 
10694          IF(glIbTrackable(ntReferenceId(i)) = FLAG_IB_TRACKABLE OR
10695             trackableAncestor.EXISTS(ntReferenceId(i)))THEN
10696 
10697            trackableAncestor(ntPsNodeId(i)) := 1;
10698            PROPAGATE_TRACKABLE_ANCESTOR;
10699          END IF;
10700        END IF;
10701      END IF;
10702 
10703     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_CONNECTOR)THEN
10704 
10705      --Go and generate the connection target. At least we need to have its structure in
10706      --memory, but there is also a versioning problem.
10707      --Check for circularity.
10708 
10709      localCount := 0;
10710      trackableContext := 0;
10711 
10712      FOR n IN 1..globalLevel LOOP
10713       IF(globalStack(n) = ntReferenceId(i))THEN
10714 
10715         --Circularity detected.
10716 
10717         localCount := 1;
10718         EXIT;
10719       END IF;
10720 
10721       IF(glIbTrackable(globalStack(n)) = FLAG_IB_TRACKABLE)THEN
10722 
10723         trackableContext := globalStack(n);
10724       END IF;
10725      END LOOP;
10726 
10727      IF(localCount = 0)THEN
10728 
10729        globalLevel := globalLevel + 1;
10730        globalStack(globalLevel) := ntReferenceId(i);
10731        globalRef(globalLevel) := ntPsNodeId(i);
10732 
10733        --This is a connector and instantiability is not defined, but we need a value on
10734        --the stack.
10735 
10736        globalInstance(globalLevel) := 0;
10737 
10738        GENERATE_COMPONENT_TREE(ntReferenceId(i), ntReferenceId(i), NULL);
10739        globalLevel := globalLevel - 1;
10740 
10741        IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
10742 
10743          --Definition: trackable instance model is a trackable model that has no trackable
10744          --ancestors. In a container model no connectors to trackable instance models are
10745          --allowed. In other words, any connector to a trackable model in a container model
10746          --should be inside a trackable child of the container model.
10747 
10748          IF(glIbTrackable(ntReferenceId(i)) = FLAG_IB_TRACKABLE AND trackableContext = 0)THEN
10749 
10750            errorMessage := thisProjectName;
10751            nParam := glIndexByPsNodeId(ntReferenceId(i));
10752            RAISE CZ_S_CONNECTOR_TRACKABLE;
10753          END IF;
10754 
10755          --Inside a trackable model no connector to a non-trackable model is allowed on any
10756          --level in a container model.
10757 
10758          IF((glIbTrackable(ntReferenceId(i)) IS NULL OR glIbTrackable(ntReferenceId(i)) <> FLAG_IB_TRACKABLE) AND
10759             trackableContext > 0)THEN
10760 
10761            errorMessage := glName(glIndexByPsNodeId(ntReferenceId(i)));
10762            nParam := glIndexByPsNodeId(trackableContext);
10763            RAISE CZ_S_CONNECT_NONTRACKABLE;
10764          END IF;
10765        END IF;
10766      END IF;
10767 
10768     ELSIF(ntPsNodeType(i) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
10769 
10770 nDebug := 1110032;
10771 
10772     --Run the TSO with Equipment validations before generating logic.
10773 
10774     IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL OR
10775        thisProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
10776 
10777       errorMessage := thisProjectName;
10778       thisName := ntName(i);
10779       parentName := '';
10780       IF(ntParentId(i) IS NOT NULL)THEN parentName := glName(glIndexByPsNodeId(ntParentId(i))); END IF;
10781 
10782       IF(ntShippableFlag(i) IS NULL OR ntTransactableFlag(i) IS NULL OR
10783          ntAtoFlag(i) IS NULL OR ntSerializableFlag(i) IS NULL) THEN
10784 
10785        --'The BOM Model ''%MODELNAME'' is out of date. Please refresh the Model by running the Refresh a Single
10786        -- Configuration Model concurrent program and then regenerate the Active Model.'
10787 
10788        RAISE CZ_LCE_MODEL_OUTOFDATE;
10789       END IF; --The new flags are null, need to refresh.
10790 
10791       IF((ntPsNodeType(i) IN (PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_MODEL)) AND
10792          (ntShippableFlag(i) = '1' OR ntTransactableFlag(i) = '1'))THEN
10793 
10794        --'Incorrect BOM Model or Option Class ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
10795        -- Only BOM Standard Items can be shippable and inventory transactable.'
10796 
10797        RAISE CZ_LCE_INCORRECT_BOM;
10798       END IF; --Flags are set for a non-Standard item node.
10799 
10800       IF(ntPsNodeType(i) = PS_NODE_TYPE_BOM_STANDARD)THEN
10801         IF(ntShippableFlag(i) <> ntTransactableFlag(i))THEN
10802 
10803           --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
10804           -- All shippable items should be inventory transactable and vice versa.'
10805 
10806           RAISE CZ_LCE_INCORRECT_ITEM;
10807         END IF; -- ntShippableFlag <> ntTransactableFlag.
10808 
10809         IF(ntShippableFlag(i) = '1' AND ((ntAtoFlag(i) <> '0') OR (NVL(ntIbTrackable(i), '0') <> '1')))THEN
10810 
10811        --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
10812        -- All shippable items should be trackable non-ATO standard items with maximum quantity 1.'
10813 
10814           RAISE CZ_LCE_INCORRECT_TANGIBLE;
10815         END IF; --ntShippableFlag = '1'.
10816 
10817         IF(ntShippableFlag(i) = '1' AND ntSerializableFlag(i) = '0')THEN
10818 
10819           --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
10820           -- All shippable items should be serializable trackable non-ATO standard items.'
10821 
10822           RAISE CZ_LCE_INCORRECT_SHIPPABLE;
10823         END IF; --ntShippableFlag = '1' AND ntSerializableFlag = '0';
10824       END IF; --Standard Item.
10825     END IF; --MACD Container.
10826 
10827 nDebug := 1110033;
10828 
10829      --Generate header.
10830 
10831      vLogicLine := 'BOM P_' || TO_CHAR(ntPersistentId(i)) || ' R ';
10832 
10833      --BOM modifier.
10834 
10835      IF(ntPsNodeType(i) = PS_NODE_TYPE_BOM_STANDARD)THEN
10836        vLogicLine := vLogicLine || 'S';
10837      ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_BOM_OPTIONCLASS)THEN
10838        vLogicLine := vLogicLine || 'O';
10839      ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_BOM_MODEL)THEN
10840        vLogicLine := vLogicLine || 'M';
10841 
10842        --This is a BOM model, it can be only the root model, so that thisProjectType and
10843        --thisProjectName are currently referring to it.
10844 
10845        IF(ntIbTrackable(i) = FLAG_IB_TRACKABLE AND thisProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
10846 
10847          --A network container model should not be trackable.
10848 
10849          errorMessage := thisProjectName;
10850          RAISE CZ_S_TRACKABLE_CONTAINER;
10851        END IF;
10852      ELSE
10853 
10854        --'Unknown BOM node type, node ''%NODENAME'''
10855        errorMessage := CZ_UTILS.GET_TEXT('CZ_S_UNKNOWN_BOM_NODE_TYPE', 'NODENAME', ntName(i));
10856        RAISE CZ_S_UNKNOWN_BOM_NODE_TYPE;
10857      END IF;
10858 
10859      IF(ntPsNodeType(i) IN (PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD) AND
10860         glIbTrackable(ntPsNodeId(i)) = FLAG_IB_TRACKABLE)THEN
10861 
10862        --Trackable Standard Items/Option Classes are not allowed as immediate children of a
10863        --network container model.
10864 
10865        IF(thisProjectType = MODEL_TYPE_CONTAINER_MODEL AND
10866           glPsNodeType(glIndexByPsNodeId(ntParentId(i))) = PS_NODE_TYPE_BOM_MODEL)THEN
10867 
10868          errorMessage := thisProjectName;
10869          nParam := glIndexByPsNodeId(ntPsNodeId(i));
10870          RAISE CZ_S_TRACKABLE_CHILDREN;
10871        END IF;
10872 
10873        --As this is a trackable Standard Item or Option Class we need to mark all of its
10874        --ancestors and make sure their quantities are not greater than 1, if the root is
10875        --a container model.
10876 
10877        IF(rootProjectType = MODEL_TYPE_CONTAINER_MODEL)THEN
10878 
10879          PROPAGATE_TRACKABLE_ANCESTOR;
10880 
10881          --If the item is tangible, we should prohibit not only its ancestors but also itself
10882          --from being on the RHS of numeric rules - TSO with Equipment.
10883 
10884          IF(ntShippableFlag(i) = '1')THEN trackableAncestor(ntPsNodeId(i)) := 2; END IF;
10885        END IF;
10886      END IF;
10887 
10888      --Add the decimal quantity modifier if necessary
10889 
10890      IF(ntDecimalQty(i) = FLAG_DECIMAL_QTY)THEN
10891       vLogicLine := vLogicLine || 'D';
10892      END IF;
10893 
10894 nDebug := 1110034;
10895 
10896      --BOM required flag + minimum which is always 0
10897 
10898      IF(ntBomRequired(i) = FLAG_BOM_REQUIRED)THEN
10899       vLogicLine := vLogicLine || ' RC 0 ';
10900      ELSE
10901       vLogicLine := vLogicLine || ' NRC 0 ';
10902      END IF;
10903 
10904 nDebug := 1110035;
10905 
10906      --Maximum selected
10907 
10908      IF(ntMaximumSel(i) IS NOT NULL)THEN
10909       vLogicLine := vLogicLine || TO_CHAR(ntMaximumSel(i)) || ' ';
10910      ELSE
10911       vLogicLine := vLogicLine || '-1 ';
10912      END IF;
10913 
10914 nDebug := 1110036;
10915 
10916      --Parent 'logic' name if any
10917 
10918      IF(ntParentId(i) IS NOT NULL AND
10919         glPsNodeType(glIndexByPsNodeId(ntParentId(i))) IN (PS_NODE_TYPE_BOM_MODEL, PS_NODE_TYPE_BOM_OPTIONCLASS, PS_NODE_TYPE_BOM_STANDARD))THEN
10920 
10921       --Fix for the bug #1745394. If a BOM parent is of decimal quantity and it's child is of
10922       --integer quantity, fatal error will be raised.
10923 
10924       IF(glDecimalQty(ntParentId(i)) = FLAG_DECIMAL_QTY AND ntDecimalQty(i) = FLAG_INTEGER_QTY)THEN
10925 
10926        --'Node ''%CHILDNAME'' must allow decimal quantity since its parent ''%PARENTNAME'' allows decimal quantity'
10927        errorMessage := CZ_UTILS.GET_TEXT('CZ_S_INCONSISTENT_QUANTITY', 'CHILDNAME', ntName(i),
10928                                                                        'PARENTNAME', glName(glIndexByPsNodeId(ntParentId(i))));
10929         RAISE CZ_S_INCONSISTENT_QUANTITY;
10930       END IF;
10931 
10932       vLogicLine := vLogicLine || 'P_' || TO_CHAR(glPersistentId(ntParentId(i))) || ' ';
10933      END IF;
10934 
10935 nDebug := 1110037;
10936 
10937      --Default quantity. If initial_value is not null and can't be converted to
10938      --a number the VALUE_ERROR exception will be raised. We catch this one and
10939      --re-raise our own exception for better reporting.
10940 
10941      BEGIN
10942       IF(ntInitialValue(i) IS NOT NULL AND TO_NUMBER(ntInitialValue(i)) > 0)THEN
10943        vLogicLine := vLogicLine || ntInitialValue(i) || ' ... ' || ntDescriptionId(i) || NewLine;
10944       ELSE
10945        vLogicLine := vLogicLine || '0' || ' ... ' || ntDescriptionId(i) || NewLine;
10946       END IF;
10947      EXCEPTION
10948        WHEN VALUE_ERROR THEN
10949          RAISE CZ_S_WRONG_INITIAL_VALUE;
10950      END;
10951 
10952     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_FEATUREGROUP)THEN
10953 
10954      NULL;
10955 
10956     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_COMPONENT)THEN
10957 
10958      NULL;
10959 
10960     ELSIF(ntPsNodeType(i) = PS_NODE_TYPE_PRODUCT)THEN
10961 
10962      NULL;
10963 
10964     ELSE
10965 
10966      --'Unknown node type, node ''%NODENAME'''
10967      errorMessage := CZ_UTILS.GET_TEXT('CZ_S_UNKNOWN_NODE_TYPE', 'NODENAME', ntName(i));
10968      RAISE CZ_S_UNKNOWN_NODE_TYPE;
10969     END IF;
10970     END IF; --End of the IF block of 'if logic does not already exist' inside the main loop
10971 
10972   --This exception handler may be used to catch the 'logic item'-level exceptions
10973   --that shouldn't stop the process. If an exception is re-raised here it becomes
10974   --a fatal exception (warning vs. errors).
10975 
10976    EXCEPTION
10977      WHEN CZ_S_BAD_BOOLEAN_FEAT_VALUE THEN
10978 --'Bad boolean feature value, feature ''%FEATNAME'''
10979        REPORT(CZ_UTILS.GET_TEXT('CZ_S_BAD_BOOLEAN_FEAT_VALUE', 'FEATNAME', ntName(i)), 1);
10980      WHEN CZ_S_FEATURE_NO_CHILDREN THEN
10981 --'Option feature has no children, feature ''%FEATNAME'''
10982        REPORT(CZ_UTILS.GET_TEXT('CZ_S_FEATURE_NO_CHILDREN', 'FEATNAME', ntName(i)), 1);
10983      WHEN CZ_S_ILLEGAL_OPTION_FEATURE THEN
10984 --'Feature ''%FEATNAME'' has no options or fewer options than its minimum count, feature ''%FEATNAME'''
10985        REPORT(CZ_UTILS.GET_TEXT('CZ_S_ILLEGAL_OPTION_FEATURE', 'FEATNAME', ntName(j)), 1);
10986      WHEN CZ_S_WRONG_INITIAL_VALUE THEN
10987 --'Initial value of BOM node is not null and can not be converted to number, node ''%NODENAME'''
10988        REPORT(CZ_UTILS.GET_TEXT('CZ_S_WRONG_INITIAL_VALUE', 'NODENAME', ntName(i)), 1);
10989 
10990   --Fatal exceptions section. Exceptions are re-raised to be reported at the higher level.
10991 
10992      WHEN CZ_S_DEADLOOP_DETECTED THEN --Currently never thrown.
10993 --As per bug #3593513, when thrown should probably be moved to the place where thrown. Otherwise going up from
10994 --the recursion overwites the message substituting incorrect names.
10995 
10996 --'An infinite loop detected: models ''%MODELNAME'' and ''%CHILDNAME'' reference each other'
10997        errorMessage := CZ_UTILS.GET_TEXT('CZ_S_DEADLOOP_DETECTED', 'MODELNAME', glName(glIndexByPsNodeId(globalStack(globalLevel))),
10998                                                                    'CHILDNAME', glName(glIndexByPsNodeId(globalStack(nParam))));
10999        RAISE;
11000    END;
11001 
11002    --This procedure implements wrapping. A call to it is included in options list generation
11003    --for an option feature above
11004 
11005    PACK;
11006 
11007 nDebug := 1110040;
11008 
11009    IF(NOT IsLogicGenerated.EXISTS(inComponentId))THEN
11010 
11011      --generatingFeature is set to 1 when we step over an option feature with actual options. It will
11012      --be unset when we finally generate the feature after all of its options. But while generating
11013      --the options we want to call this procedure for every of them. This is why we check the type
11014      --and if it is an option, call the procedure even though the flag is set.
11015 
11016      IF(generatingFeature = 0 OR ntPsNodeType(i) = PS_NODE_TYPE_OPTION)THEN GENERATE_ACCUMULATOR(i); END IF;
11017    END IF;
11018 
11019    --Increase the main cycle counter
11020 
11021    i := i + 1;
11022 
11023   END LOOP; --End of the main structure generation cycle
11024 
11025 nDebug := 1110038;
11026 
11027   ELSE --IF 'there is some data returned'
11028 
11029     --The project is empty, stop here.
11030 
11031     errorMessage := thisProjectName;
11032     RAISE CZ_S_NO_DATA_IN_PROJECT;
11033 
11034   END IF; --Ends the ELSE block of IF 'there is some data returned'
11035 
11036   IF(NOT IsLogicGenerated.EXISTS(inComponentId))THEN
11037 
11038    --Flush the buffer
11039 
11040    IF(vLogicText IS NOT NULL)THEN
11041     INSERT INTO cz_lce_texts (lce_header_id, seq_nbr, lce_text) VALUES
11042      (nStructureHeaderId, nSequenceNbr, vLogicText);
11043     vLogicText := NULL;
11044    END IF;
11045 
11046    --Remember the next sequence number for this logic file. Will be used in
11047    --numeric rules generation for accumulators.
11048 
11049    vSeqNbrByHeader(nStructureHeaderId) := nSequenceNbr + 1;
11050 
11051    IF(TwoPhaseCommit = 0)THEN COMMIT; END IF;
11052   END IF;
11053 
11054 nDebug := 1110039;
11055 
11056   --If a model, generate rules and set the logic generated flag.
11057 
11058   IF(inParentLogicHeaderId IS NULL)THEN
11059 
11060     --Generate model's rules and expressions if necessary
11061 
11062     IF(NOT IsLogicGenerated.EXISTS(inComponentId))THEN
11063       GENERATE_RULES;
11064       IsLogicGenerated(inComponentId) := 1;
11065     END IF;
11066   END IF;
11067 END; --GENERATE_COMPONENT_TREE
11068 ---------------------------------------------------------------------------------------
11069 PROCEDURE COMMIT_HEADERS IS
11070   localOldHeaders  tIntegerArray;
11071   nCount           PLS_INTEGER := 1;
11072   localComponent   NUMBER := NULL; --kdande; Bug 6881902; 11-Mar-2008
11073 BEGIN
11074 
11075    FOR i IN 1..NewHeaders.COUNT LOOP
11076     IF(((NOT IsLogicGenerated.EXISTS(NewHeadersComponents(i))) OR IsLogicGenerated(NewHeadersComponents(i)) = 1) AND
11077        (localComponent IS NULL OR NewHeadersComponents(i) <> localComponent))THEN
11078 
11079       localOldHeaders.DELETE;
11080 
11081       SELECT lce_header_id BULK COLLECT INTO localOldHeaders FROM cz_lce_headers
11082        WHERE deleted_flag = FLAG_NOT_DELETED
11083          AND devl_project_id = NewHeadersComponents(i);
11084 
11085       FOR j IN 1..localOldHeaders.COUNT LOOP
11086         OldHeaders(nCount) := localOldHeaders(j);
11087         nCount := nCount + 1;
11088       END LOOP;
11089 
11090       localComponent := NewHeadersComponents(i);
11091     END IF;
11092    END LOOP;
11093 
11094    FORALL i IN 1..OldHeaders.COUNT
11095     UPDATE cz_lce_headers SET deleted_flag = FLAG_DELETED
11096      WHERE lce_header_id = OldHeaders(i);
11097 
11098    FORALL i IN 1..OldHeaders.COUNT
11099     UPDATE cz_lce_load_specs SET deleted_flag = FLAG_DELETED
11100      WHERE lce_header_id = OldHeaders(i);
11101 
11102    FORALL i IN 1..NewHeaders.COUNT
11103     UPDATE cz_lce_headers SET deleted_flag = FLAG_NOT_DELETED
11104      WHERE lce_header_id = NewHeaders(i);
11105 
11106    FORALL i IN 1..NewHeaders.COUNT
11107     UPDATE cz_lce_load_specs SET deleted_flag = FLAG_NOT_DELETED
11108      WHERE lce_header_id = NewHeaders(i);
11109 
11110    cz_security_pvt.unlock_model(1.0, FND_API.G_TRUE, l_locked_models, l_lock_status, l_msg_count, l_msg_data);
11111 
11112    IF(l_lock_status <> FND_API.G_RET_STS_SUCCESS)THEN
11113      FOR jmessage IN 1..l_msg_count LOOP
11114        REPORT(fnd_msg_pub.get(jmessage, FND_API.G_FALSE), 0);
11115      END LOOP;
11116    END IF;
11117 
11118    IF(TwoPhaseCommit = 0)THEN COMMIT; END IF;
11119 END;
11120 ---------------------------------------------------------------------------------------
11121 PROCEDURE ROLLBACK_HEADERS IS
11122 BEGIN
11123 
11124    FORALL i IN 1..NewHeaders.COUNT
11125     UPDATE cz_lce_headers SET deleted_flag = FLAG_DELETED
11126      WHERE lce_header_id = NewHeaders(i);
11127 
11128    FORALL i IN 1..NewHeaders.COUNT
11129     UPDATE cz_lce_load_specs SET deleted_flag = FLAG_DELETED
11130      WHERE lce_header_id = NewHeaders(i);
11131 
11132    IF(OldHeaders.COUNT > 0)THEN
11133 
11134      FORALL i IN 1..OldHeaders.COUNT
11135       UPDATE cz_lce_headers SET deleted_flag = FLAG_NOT_DELETED
11136        WHERE lce_header_id = OldHeaders(i);
11137 
11138      FORALL i IN 1..OldHeaders.COUNT
11139       UPDATE cz_lce_load_specs SET deleted_flag = FLAG_NOT_DELETED
11140        WHERE lce_header_id = OldHeaders(i);
11141    END IF;
11142 
11143    cz_security_pvt.unlock_model(1.0, FND_API.G_TRUE, l_locked_models, l_lock_status, l_msg_count, l_msg_data);
11144 
11145    IF(l_lock_status <> FND_API.G_RET_STS_SUCCESS)THEN
11146      FOR jmessage IN 1..l_msg_count LOOP
11147        REPORT(fnd_msg_pub.get(jmessage, FND_API.G_FALSE), 0);
11148      END LOOP;
11149    END IF;
11150 
11151    IF(TwoPhaseCommit = 0)THEN COMMIT; END IF;
11152 
11153 EXCEPTION
11154   WHEN OTHERS THEN
11155 --'Fatal error. Logic header maintainance not completed. Unable to rollback changes because of %ERRORTEXT'
11156     REPORT(CZ_UTILS.GET_TEXT('CZ_G_UNABLE_TO_ROLLBACK', 'ERRORTEXT', SQLERRM), 0);
11157 END;
11158 ---------------------------------------------------------------------------------------
11159 FUNCTION CHECK_DATES(inModelId IN NUMBER, inLogicUpdate IN DATE, inHeaderCreated IN DATE)
11160 RETURN PLS_INTEGER IS
11161 
11162   c_model             refCursor;
11163   childFlag           PLS_INTEGER;
11164   thisFlag            PLS_INTEGER := GENERATION_NOT_REQUIRED;
11165   childModelId        cz_devl_projects.devl_project_id%TYPE;
11166   childLogicUpdate    cz_devl_projects.last_logic_update%TYPE;
11167   childHeaderCreated  cz_lce_headers.creation_date%TYPE;
11168 
11169 BEGIN
11170 
11171   IF(NOT modelChecked.EXISTS(inModelId))THEN
11172 
11173     modelChecked(inModelId) := 1;
11174 
11175     OPEN c_model FOR logicSQL USING inModelId;
11176     LOOP
11177       FETCH c_model INTO childModelId, childLogicUpdate, childHeaderCreated;
11178       EXIT WHEN c_model%NOTFOUND;
11179 
11180       childFlag := CHECK_DATES(childModelId, childLogicUpdate, childHeaderCreated);
11181 
11182       IF(thisFlag = GENERATION_NOT_REQUIRED AND
11183          (childFlag = GENERATION_REQUIRED OR inHeaderCreated < childLogicUpdate))THEN
11184         thisFlag := GENERATION_REQUIRED;
11185       END IF;
11186     END LOOP;
11187     CLOSE c_model;
11188   END IF;
11189 
11190   IF(thisFlag = GENERATION_NOT_REQUIRED AND inHeaderCreated < inLogicUpdate)THEN
11191     thisFlag := GENERATION_REQUIRED;
11192   END IF;
11193 
11194   IF(thisFlag = GENERATION_NOT_REQUIRED)THEN
11195     IsLogicGenerated(inModelId) := 0;
11196   END IF;
11197  RETURN thisFlag;
11198 END;
11199 ---------------------------------------------------------------------------------------
11200 BEGIN --GENERATE_LOGIC_
11201 
11202     --Bug #4587682. Save current nls numeric characters and set the standard characters.
11203 
11204     SELECT value INTO StoreNlsCharacters FROM NLS_SESSION_PARAMETERS
11205      WHERE UPPER(parameter) = 'NLS_NUMERIC_CHARACTERS';
11206 
11207     SET_NLS_CHARACTERS(NlsNumericCharacters);
11208 
11209 BEGIN
11210 
11211   --Database settings processing section
11212 
11213   BEGIN
11214 
11215     --Get the commit block size - the number of records inserted into cz_lce_texts
11216     --after which the transaction is commited, if commit is not disabled at all by
11217     --TwoPhaseCommit parameter set to 1.
11218 
11219     SELECT TO_NUMBER(value) INTO CommitBlockSize
11220       FROM cz_db_settings
11221      WHERE LOWER(setting_id) = COMMIT_BLOCK_SETTING_ID
11222        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11223 
11224     IF(CommitBlockSize <= 0) THEN CommitBlockSize := DEFAULT_COMMIT_BLOCK_SIZE; END IF;
11225 
11226   EXCEPTION
11227     WHEN OTHERS THEN
11228       CommitBlockSize := DEFAULT_COMMIT_BLOCK_SIZE;
11229   END;
11230 
11231 /*  Making the optimizations unconditional, cz_db_settings ignored.
11232   BEGIN
11233 
11234     --Get the NotTrue optimization flag, no optimization by default.
11235 
11236     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11237                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11238                                 0) --default value
11239       INTO OptimizeNotTrue
11240       FROM cz_db_settings
11241      WHERE LOWER(setting_id) = OPTIMIZE_NOTTRUE_SETTING_ID
11242        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11243 
11244   EXCEPTION
11245     WHEN OTHERS THEN
11246       OptimizeNotTrue := 0;
11247   END;
11248 
11249   BEGIN
11250 
11251     --Get the AllOf/AnyOf optimization flag, no optimization by default.
11252 
11253     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11254                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11255                                 0) --default value
11256       INTO OptimizeAllAnyOf
11257       FROM cz_db_settings
11258      WHERE LOWER(setting_id) = OPTIMIZE_ALLANYOF_SETTING_ID
11259        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11260 
11261   EXCEPTION
11262     WHEN OTHERS THEN
11263       OptimizeAllAnyOf := 0;
11264   END;
11265 
11266   BEGIN
11267 
11268     --Get the Change Children Order flag, no change by default.
11269     --Currently will change children order when generating AllOf/AnyOf.
11270 
11271     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11272                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11273                                 0) --default value
11274       INTO ChangeChildrenOrder
11275       FROM cz_db_settings
11276      WHERE LOWER(setting_id) = CHILDREN_ORDER_SETTING_ID
11277        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11278 
11279   EXCEPTION
11280     WHEN OTHERS THEN
11281       ChangeChildrenOrder := 0;
11282   END;
11283 */
11284 
11285   --Enable all three optimizations here ignoring cz_db_settings.
11286 
11287   OptimizeNotTrue := 1;
11288   OptimizeAllAnyOf := 1;
11289   ChangeChildrenOrder := 1;
11290 
11291   BEGIN
11292 
11293     --See if we want to generate gated combinations, yes by default.
11294 
11295     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11296                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11297                                 1) --default value
11298       INTO GenerateGatedCombo
11299       FROM cz_db_settings
11300      WHERE LOWER(setting_id) = GATED_COMBO_SETTING_ID
11301        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11302 
11303   EXCEPTION
11304     WHEN OTHERS THEN
11305       GenerateGatedCombo := 1;
11306   END;
11307 
11308   BEGIN
11309 
11310     --See if we want to stop when a fatal rule error is encountered, yes by default.
11311 
11312     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11313                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11314                                 1) --default value
11315       INTO StopOnFatalRuleError
11316       FROM cz_db_settings
11317      WHERE LOWER(setting_id) = STOP_ON_ERROR_SETTING_ID
11318        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11319 
11320   EXCEPTION
11321     WHEN OTHERS THEN
11322       StopOnFatalRuleError := 1;
11323   END;
11324 
11325   BEGIN
11326 
11327     --See if we want to generate logic only for updated models, yes by default.
11328 
11329     SELECT DECODE(LOWER(value), '1', 1, 'on',  1, 'y', 1, 'yes', 1,'true',  1, 'enable',  1,
11330                                 '0', 0, 'off', 0, 'n', 0, 'no',  0,'false', 0, 'disable', 0,
11331                                 1) --default value
11332       INTO GenerateUpdatedOnly
11333       FROM cz_db_settings
11334      WHERE LOWER(setting_id) = UPDATED_ONLY_SETTING_ID
11335        AND LOWER(section_name) = DBSETTINGS_SECTION_NAME;
11336 
11337   EXCEPTION
11338     WHEN OTHERS THEN
11339       GenerateUpdatedOnly := 1;
11340   END;
11341 
11342   --Get the logic generation run id. If a valid value has been passed as a parameter, use it,
11343   --else generate a new value.
11344 
11345   IF(thisRunId IS NULL OR thisRunId = 0)THEN
11346     SELECT cz_xfr_run_infos_s.NEXTVAL INTO thisRunId FROM DUAL;
11347   END IF;
11348 
11349   --Read the cz_effectivity_sets table into memory and create hash tables for
11350   --effectivity dates
11351 
11352   SELECT effectivity_set_id, effective_from, effective_until
11353   BULK COLLECT INTO gvSetId, gvEffFrom, gvEffUntil
11354     FROM cz_effectivity_sets
11355    WHERE deleted_flag = FLAG_NOT_DELETED;
11356 
11357   --Add the indexing option
11358 
11359   IF(gvSetId.LAST IS NOT NULL)THEN
11360    FOR i IN gvSetId.FIRST..gvSetId.LAST LOOP
11361     gvIndexBySetId(gvSetId(i)) := i;
11362    END LOOP;
11363   END IF;
11364 
11365   --This block is introduced to implement locking.
11366 
11367   BEGIN
11368 
11369     l_locked_models.DELETE;
11370     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);
11371 
11372     IF(l_lock_status <> FND_API.G_RET_STS_SUCCESS)THEN
11373       RAISE FAILED_TO_LOCK_MODEL;
11374     END IF;
11375 
11376     --To disable this functionality, comment out the following IF block. Previously, we
11377     --could not correctly handle accumulators and NOTTRUE operator, for which we needed
11378     --to modify a child structure file even if it was up-to-date.
11379 
11380     --Pre-populate the list of models that don't need to be regenerated because logic exists
11381     --and satisfies the 'up-to-date' criterion. Part of the fix for the bug #1941626.
11382     --For debugging purposes it may be convenient to be able to regenerate logic without any
11383     --dependency on the dates - the old way. A db setting is provided for that.
11384 
11385     IF(GenerateUpdatedOnly = 1)THEN
11386 
11387       --Have to always generate logic for the root model because the trigger updating
11388       --last_logic_update column is commented out on cz_expression_nodes, and this is
11389       --the only table Developer updates for some rule changes.
11390       --This is why we do not care about the return value and pass the margin reverse
11391       --dates.
11392 
11393       nParam := CHECK_DATES(inDevlProjectId, EpochEndDate, EpochBeginDate);
11394     END IF;
11395 
11396     globalLevel := globalLevel + 1;
11397     globalStack(globalLevel) := inDevlProjectId;
11398     globalRef(globalLevel) := inDevlProjectId;
11399     globalInstance(globalLevel) := 0;
11400 
11401     --Start off the recursion
11402 
11403     GENERATE_COMPONENT_TREE(inDevlProjectId, inDevlProjectId, NULL);
11404 
11405     --LCE header maintainance
11406 
11407     COMMIT_HEADERS;
11408 
11409   EXCEPTION
11410     WHEN FAILED_TO_LOCK_MODEL THEN
11411 
11412        FOR jmessage IN 1..l_msg_count LOOP
11413          REPORT(fnd_msg_pub.get(jmessage, FND_API.G_FALSE), 0);
11414        END LOOP;
11415 
11416        ROLLBACK_HEADERS;
11417     WHEN OTHERS THEN
11418       RAISE;
11419   END;
11420 
11421 --Handle here the exceptions that should terminate the logic tree generation process.
11422 
11423 EXCEPTION
11424   WHEN CZ_S_UNABLE_TO_CREATE_HEADER THEN
11425 --'Unable to create logic header because of %ERRORTEXT'
11426     REPORT(CZ_UTILS.GET_TEXT('CZ_G_UNABLE_TO_CREATE_HEADER', 'ERRORTEXT', errorMessage), 0);
11427     ROLLBACK_HEADERS;
11428   WHEN CZ_R_UNABLE_TO_CREATE_HEADER THEN
11429 --'Unable to create logic header because of %ERRORTEXT'
11430     REPORT(CZ_UTILS.GET_TEXT('CZ_G_UNABLE_TO_CREATE_HEADER', 'ERRORTEXT', errorMessage), 0);
11431     ROLLBACK_HEADERS;
11432   WHEN CZ_S_DEADLOOP_DETECTED THEN
11433     REPORT(errorMessage, 0);
11434     ROLLBACK_HEADERS;
11435   WHEN CZ_S_UNKNOWN_FEATURE_TYPE THEN
11436     REPORT(errorMessage, 0);
11437     ROLLBACK_HEADERS;
11438   WHEN CZ_S_UNKNOWN_NODE_TYPE THEN
11439     REPORT(errorMessage, 0);
11440     ROLLBACK_HEADERS;
11441   WHEN CZ_S_UNKNOWN_BOM_NODE_TYPE THEN
11442     REPORT(errorMessage, 0);
11443     ROLLBACK_HEADERS;
11444   WHEN CZ_S_TOO_MANY_OPTIONS THEN
11445     REPORT(errorMessage, 0);
11446     ROLLBACK_HEADERS;
11447   WHEN CZ_S_WRONG_EFFECTIVITY_SET THEN
11448     REPORT(errorMessage, 0);
11449     ROLLBACK_HEADERS;
11450   WHEN CZ_S_INCONSISTENT_QUANTITY THEN
11451     REPORT(errorMessage, 0);
11452     ROLLBACK_HEADERS;
11453   WHEN CZ_S_INCORRECT_QUANTITY THEN
11454 --'BOM item ''%ITEMNAME'' cannot have default quantity greater than 1 because it contains other trackable BOM items.'
11455     REPORT(CZ_UTILS.GET_TEXT('CZ_S_INCORRECT_QUANTITY', 'ITEMNAME', glName(nParam)), 0);
11456     ROLLBACK_HEADERS;
11457   WHEN CZ_S_TRACKABLE_CHILDREN THEN
11458 --'Invalid Model structure: ''%CHILDNAME'' is a direct child of ''%MODELNAME''. A trackable BOM item cannot be a direct child of a Container Model.'
11459     REPORT(CZ_UTILS.GET_TEXT('CZ_S_TRACKABLE_CHILDREN', 'CHILDNAME', glName(nParam), 'MODELNAME', errorMessage), 0);
11460     ROLLBACK_HEADERS;
11461   WHEN CZ_S_TRACKABLE_STANDARD THEN
11462 --'Invalid Model structure: ''%CHILDNAME'' is a direct child of ''%MODELNAME''. A trackable Standard Item cannot be
11463 -- a direct child of a non-trackable ATO or PTO BOM Model that is referenced by a Container Model.'
11464     REPORT(CZ_UTILS.GET_TEXT('CZ_S_TRACKABLE_STANDARD', 'CHILDNAME', glName(nParam), 'MODELNAME', errorMessage), 0);
11465     ROLLBACK_HEADERS;
11466   WHEN CZ_S_MULTIPLE_TRACKABLE THEN
11467 --'Invalid Model structure: Multiple references exist to the trackable instance ''%CHILDNAME''.'
11468     REPORT(CZ_UTILS.GET_TEXT('CZ_S_MULTIPLE_TRACKABLE', 'CHILDNAME', errorMessage), 0);
11469     ROLLBACK_HEADERS;
11470   WHEN CZ_S_MULTIPLE_INSTANCES THEN
11471 --'Invalid Model structure: The non-trackable Model ''%MODELNAME'' cannot have multiple instances because it is not a descendent of a trackable Model and it
11472 -- contains the trackable Model ''%CHILDNAME''. Please set both the Instances Minimum and Maximum fields for ''%MODELNAME'' to 1.'
11473     REPORT(CZ_UTILS.GET_TEXT('CZ_S_MULTIPLE_INSTANCES', 'CHILDNAME', errorMessage, 'MODELNAME', glName(nParam)), 0);
11474     ROLLBACK_HEADERS;
11475   WHEN CZ_S_CONNECT_NONTRACKABLE THEN
11476 --'Invalid Connector: Connector to non-trackable Model ''%CHILDNAME'' from the trackable Model ''%MODELNAME''. A Connector from a non-trackable Model
11477 -- to a trackable Model is not allowed in a Container Model.'
11478     REPORT(CZ_UTILS.GET_TEXT('CZ_S_CONNECT_NONTRACKABLE', 'CHILDNAME', errorMessage, 'MODELNAME', glName(nParam)), 0);
11479     ROLLBACK_HEADERS;
11480   WHEN CZ_S_CONTAINER_REFERENCE THEN
11481 --'Invalid Reference: Model ''%MODELNAME'' references the Model ''%CHILDNAME''. A Container Model cannot reference another Container Model.'
11482     REPORT(CZ_UTILS.GET_TEXT('CZ_S_CONTAINER_REFERENCE', 'CHILDNAME', errorMessage, 'MODELNAME', rootProjectName), 0);
11483     ROLLBACK_HEADERS;
11484   WHEN CZ_S_CONNECTOR_TRACKABLE THEN
11485 --'The Connector from ''%MODELNAME'' to the trackable Model ''%CHILDNAME'' is not allowed because no ancestor of ''%MODELNAME'' is trackable.'
11486     REPORT(CZ_UTILS.GET_TEXT('CZ_S_CONNECTOR_TRACKABLE', 'CHILDNAME', glName(nParam), 'MODELNAME', errorMessage), 0);
11487     ROLLBACK_HEADERS;
11488   WHEN CZ_S_INCORRECT_CONTAINER THEN
11489 --'The Reference to trackable Model ''%CHILDNAME'' in the Container Model ''%MODELNAME'' has an invalid number
11490 -- of Instances specified. Please set Minimum Instances to 0 and Maximum Instances to Null for this node,
11491 -- then regenerate the Active Model.'
11492     REPORT(CZ_UTILS.GET_TEXT('CZ_S_INCORRECT_CONTAINER', 'CHILDNAME', errorMessage, 'MODELNAME', rootProjectName), 0);
11493     ROLLBACK_HEADERS;
11494   WHEN CZ_S_NO_TRACKABLE_FLAG THEN
11495 --'Trackable status is undefined for the Model ''%CHILDNAME'' in the Container Model ''%MODELNAME''.
11496 -- Please refresh the Model by running the Refresh a Single Configuration Model concurrent program
11497 -- and then regenerate the Active Model.'
11498     REPORT(CZ_UTILS.GET_TEXT('CZ_S_NO_TRACKABLE_FLAG', 'CHILDNAME', errorMessage, 'MODELNAME', rootProjectName), 0);
11499     ROLLBACK_HEADERS;
11500   WHEN CZ_S_NO_DATA_IN_PROJECT THEN
11501 --'Project ''%PROJECTNAME'' contains no data, no logic generated'
11502     REPORT(CZ_UTILS.GET_TEXT('CZ_S_NO_DATA_IN_PROJECT', 'PROJECTNAME', errorMessage), 0);
11503     ROLLBACK_HEADERS;
11504   WHEN CZ_S_NO_SUCH_PROJECT THEN
11505 --'Project does not exist for the specified ID: %PROJECTID. No logic generated.'
11506     REPORT(CZ_UTILS.GET_TEXT('CZ_S_NO_SUCH_PROJECT', 'PROJECTID', nParam), 0);
11507     ROLLBACK_HEADERS;
11508   WHEN CZ_S_TRACKABLE_CONTAINER THEN
11509 --'Error in Model ''%PROJECTNAME'': A trackable Model cannot be a Container Model.'
11510     REPORT(CZ_UTILS.GET_TEXT('CZ_S_TRACKABLE_CONTAINER', 'PROJECTNAME', errorMessage), 0);
11511     ROLLBACK_HEADERS;
11512   WHEN CZ_LCE_MODEL_OUTOFDATE THEN
11513 --'The BOM Model ''%MODELNAME'' is out of date. Please refresh the Model by running the Refresh a Single
11514 -- Configuration Model concurrent program and then regenerate the Active Model.'
11515     REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_MODEL_OUTOFDATE', 'MODELNAME', errorMessage), 0);
11516     ROLLBACK_HEADERS;
11517   WHEN CZ_LCE_INCORRECT_BOM THEN
11518 --'Incorrect BOM Model or Option Class ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
11519 -- Only BOM Standard Items can be shippable and inventory transactable.'
11520     REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_INCORRECT_BOM', 'NODENAME', thisName, 'PARENTNAME', parentName, 'MODELNAME', errorMessage), 0);
11521     ROLLBACK_HEADERS;
11522   WHEN CZ_LCE_INCORRECT_ITEM THEN
11523 --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
11524 -- All shippable items should be inventory transactable and vice versa.'
11525     REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_INCORRECT_ITEM', 'NODENAME', thisName, 'PARENTNAME', parentName, 'MODELNAME', errorMessage), 0);
11526     ROLLBACK_HEADERS;
11527   WHEN CZ_LCE_INCORRECT_TANGIBLE THEN
11528 --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
11529 -- All shippable items should be trackable non-ATO standard items with maximum quantity 1.'
11530     REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_INCORRECT_TANGIBLE', 'NODENAME', thisName, 'PARENTNAME', parentName, 'MODELNAME', errorMessage), 0);
11531     ROLLBACK_HEADERS;
11532   WHEN CZ_LCE_INCORRECT_SHIPPABLE THEN
11533 --'Incorrect BOM Standard Item ''%NODENAME'' with parent ''%PARENTNAME'' in BOM Model ''%MODELNAME''.
11534 -- All shippable items should be serializable trackable non-ATO standard items.'
11535     REPORT(CZ_UTILS.GET_TEXT('CZ_LCE_INCORRECT_SHIPPABLE', 'NODENAME', thisName, 'PARENTNAME', parentName, 'MODELNAME', errorMessage), 0);
11536     ROLLBACK_HEADERS;
11537   WHEN CZ_G_INVALID_RULE_EXPLOSION THEN
11538 --'Internal data error. Unable to continue because of invalid data in rule ''%RULENAME''. Disable or delete the rule to generate logic.'
11539      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_INVALID_RULE_EXPLOSION', 'RULENAME', errorMessage);
11540     REPORT(errorMessage, 0);
11541     ROLLBACK_HEADERS;
11542   WHEN CZ_G_INVALID_MODEL_EXPLOSION THEN
11543 --'Internal data error. Unable to continue because of invalid data in model ''%MODELNAME'' - loop detected.'
11544      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_INVALID_MODEL_EXPLOSION', 'MODELNAME', errorMessage);
11545     REPORT(errorMessage, 0);
11546     ROLLBACK_HEADERS;
11547   WHEN CZ_G_INVALID_EXPLOSION_TYPE THEN
11548 --'Internal data error. Unable to continue because of invalid data in the model ''%MODELNAME'' - incorrect explosion type.'
11549      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_INVALID_EXPLOSION_TYPE', 'MODELNAME', errorMessage);
11550     REPORT(errorMessage, 0);
11551     ROLLBACK_HEADERS;
11552   WHEN OTHERS THEN
11553     IF(nDebug = 1 OR (nDebug >= 1000001 AND nDebug <= 1000011))THEN
11554 --'Unable to continue because of %ERRORTEXT. Reference explosions table may not be populated properly for model ''%MODELNAME'''
11555      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_ERROR_IN_EXPLOSION', 'ERRORTEXT', SQLERRM, 'MODELNAME', glName(glIndexByPsNodeId(inDevlProjectId)));
11556     ELSIF(nDebug >= 40 AND nDebug <= 54)THEN
11557 --'Internal data error. Unable to continue because of invalid data in rule ''%RULENAME''. Disable or delete the rule to generate logic.'
11558      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_INVALID_RULE_EXPLOSION', 'RULENAME', errorMessage);
11559     ELSIF(SUBSTR(TO_CHAR(nDebug), 1, 1) = '8')THEN
11560 --'Unable to continue because of %ERRORTEXT: (nRuleId)'
11561      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_GENERAL_ERROR', 'ERRORTEXT', SQLERRM || ': (' || errorMessage || ')');
11562     ELSE
11563 --'Unable to continue because of %ERRORTEXT'
11564      errorMessage := CZ_UTILS.GET_TEXT('CZ_G_GENERAL_ERROR', 'ERRORTEXT', SQLERRM);
11565     END IF;
11566     REPORT(errorMessage, 0);
11567     ROLLBACK_HEADERS;
11568 END;
11569 
11570  --Bug #4587682. Restore the session's nls numeric characters.
11571 
11572  SET_NLS_CHARACTERS(StoreNlsCharacters);
11573 
11574 EXCEPTION
11575   WHEN OTHERS THEN
11576     SET_NLS_CHARACTERS(StoreNlsCharacters);
11577     RAISE;
11578 END; --GENERATE_MODEL_TREE
11579 ---------------------------------------------------------------------------------------
11580 --An additional entry point for those callers who cannot handle defaulted parameters---
11581 
11582 PROCEDURE GENERATE_LOGIC(inDevlProjectId IN NUMBER,
11583                          thisRunId       IN OUT NOCOPY NUMBER)
11584 IS
11585 
11586   l_config_engine_type   cz_devl_projects.config_engine_type%TYPE;
11587   l_fusion_debug         VARCHAR2(240);
11588 
11589 BEGIN
11590 
11591   BEGIN
11592 
11593     SELECT config_engine_type INTO l_config_engine_type
11594       FROM cz_devl_projects
11595      WHERE deleted_flag = FLAG_NOT_DELETED
11596        AND devl_project_id = inDevlProjectId;
11597 
11598   EXCEPTION
11599     WHEN NO_DATA_FOUND THEN
11600       l_config_engine_type := 'L';
11601   END;
11602 
11603   IF ( l_config_engine_type = 'F') THEN
11604 
11605     l_fusion_debug := NVL ( fnd_profile.value_wnps ('CZ_DEV_FCE_DEBUG_LOGIC'), 'N');
11606 
11607     IF ( l_fusion_debug = 'N' ) THEN
11608 
11609       cz_fce_compile.compile_logic ( inDevlProjectId,  thisRunId );
11610 
11611     ELSE
11612 
11613       cz_fce_compile.debug_logic ( inDevlProjectId,  thisRunId );
11614 
11615     END IF;
11616 
11617   ELSE
11618 
11619     GENERATE_LOGIC_(inDevlProjectId, thisRunId, 0);
11620 
11621   END IF;
11622 END;
11623 ---------------------------------------------------------------------------------------
11624 --This entry makes the logic generation work remotely in a distributed transaction,even
11625 --if the model contains property-based compatibility rules - bug #2028790.
11626 --DDL used in the property-based compatibility rules makes implicit commits and commits
11627 --are not allowed in a distributed transaction when the remote procedure has parameters
11628 --of type OUT.
11629 
11630 PROCEDURE GENERATE_LOGIC__(inDevlProjectId IN NUMBER,
11631                            thisRunId       IN NUMBER)
11632 IS
11633   outRunId  NUMBER := thisRunId;
11634 BEGIN
11635   GENERATE_LOGIC_(inDevlProjectId, outRunId, 1);
11636 END;
11637 ---------------------------------------------------------------------------------------
11638 BEGIN
11639 
11640   OperatorLiterals(OPERATOR_ADD)                := ' + ';
11641   OperatorLiterals(OPERATOR_SUB)                := ' - ';
11642   OperatorLiterals(OPERATOR_MULT)               := ' * ';
11643   OperatorLiterals(OPERATOR_DIV)                := ' / ';
11644   OperatorLiterals(OPERATOR_EQUALS)             := ' = ';
11645   OperatorLiterals(OPERATOR_NOTEQUALS)          := ' != ';
11646   OperatorLiterals(OPERATOR_GT)                 := ' > ';
11647   OperatorLiterals(OPERATOR_LT)                 := ' < ';
11648   OperatorLiterals(OPERATOR_GE)                 := ' >= ';
11649   OperatorLiterals(OPERATOR_LE)                 := ' <= ';
11650   OperatorLiterals(OPERATOR_ADD_INT)            := ' + ';
11651   OperatorLiterals(OPERATOR_SUB_INT)            := ' - ';
11652   OperatorLiterals(OPERATOR_MULT_INT)           := ' * ';
11653   OperatorLiterals(OPERATOR_EQUALS_INT)         := ' = ';
11654   OperatorLiterals(OPERATOR_NOTEQUALS_INT)      := ' != ';
11655   OperatorLiterals(OPERATOR_GT_INT)             := ' > ';
11656   OperatorLiterals(OPERATOR_LT_INT)             := ' < ';
11657   OperatorLiterals(OPERATOR_GE_INT)             := ' >= ';
11658   OperatorLiterals(OPERATOR_LE_INT)             := ' <= ';
11659   OperatorLiterals(OPERATOR_POW_INT)            := ' POW ';
11660   OperatorLiterals(OPERATOR_ROUND)              := ' ROUND ';
11661   OperatorLiterals(OPERATOR_CEILING)            := ' CEILING ';
11662   OperatorLiterals(OPERATOR_FLOOR)              := ' FLOOR ';
11663   OperatorLiterals(OPERATOR_TRUNCATE)           := ' TRUNCATE ';
11664   OperatorLiterals(OPERATOR_MIN)                := ' MIN ';
11665   OperatorLiterals(OPERATOR_MAX)                := ' MAX ';
11666   OperatorLiterals(OPERATOR_AND)                := ' AND ';
11667   OperatorLiterals(OPERATOR_OR)                 := ' OR ';
11668   OperatorLiterals(OPERATOR_NOT)                := ' NOT ';
11669   OperatorLiterals(OPERATOR_NOTTRUE)            := ' NOTTRUE ';
11670   OperatorLiterals(OPERATOR_COS)                := ' COS ';
11671   OperatorLiterals(OPERATOR_ACOS)               := ' ACOS ';
11672   OperatorLiterals(OPERATOR_COSH)               := ' COSH ';
11673   OperatorLiterals(OPERATOR_SIN)                := ' SIN ';
11674   OperatorLiterals(OPERATOR_ASIN)               := ' ASIN ';
11675   OperatorLiterals(OPERATOR_SINH)               := ' SINH ';
11676   OperatorLiterals(OPERATOR_TAN)                := ' TAN ';
11677   OperatorLiterals(OPERATOR_ATAN)               := ' ATAN ';
11678   OperatorLiterals(OPERATOR_TANH)               := ' TANH ';
11679   OperatorLiterals(OPERATOR_LOG)                := ' LOG ';
11680   OperatorLiterals(OPERATOR_LOG10)              := ' LOG10 ';
11681   OperatorLiterals(OPERATOR_EXP)                := ' EXP ';
11682   OperatorLiterals(OPERATOR_ABS)                := ' ABS ';
11683   OperatorLiterals(OPERATOR_SQRT)               := ' SQRT ';
11684   OperatorLiterals(OPERATOR_MATHDIV)            := ' DIV ';
11685   OperatorLiterals(OPERATOR_POW)                := ' POW ';
11686   OperatorLiterals(OPERATOR_ATAN2)              := ' ATAN2 ';
11687   OperatorLiterals(OPERATOR_MOD)                := ' MOD ';
11688   OperatorLiterals(OPERATOR_ROUNDTONEAREST)     := ' ROUND ';
11689   OperatorLiterals(OPERATOR_ROUNDUPTONEAREST)   := ' CEILING ';
11690   OperatorLiterals(OPERATOR_ROUNDDOWNTONEAREST) := ' FLOOR ';
11691   OperatorLiterals(OPERATOR_ALLOF)              := ' All True ';
11692   OperatorLiterals(OPERATOR_ANYOF)              := ' Any True ';
11693   OperatorLiterals(OPERATOR_NONE)               := ' ';
11694 
11695   OperatorLetters(OPERATOR_AND)                 := ' L ';
11696   OperatorLetters(OPERATOR_OR)                  := ' N ';
11697   OperatorLetters(OPERATOR_ALLOF)               := ' L ';
11698   OperatorLetters(OPERATOR_ANYOF)               := ' N ';
11699   OperatorLetters(RULE_OPERATOR_REQUIRES)       := ' R ';
11700   OperatorLetters(RULE_OPERATOR_IMPLIES)        := ' I ';
11701   OperatorLetters(RULE_OPERATOR_EXCLUDES)       := ' E ';
11702   OperatorLetters(RULE_OPERATOR_NEGATES)        := ' N ';
11703 
11704   CodeByCodeLookup(TEMPLATE_ANYTRUE)            := OPERATOR_ANYOF;
11705   CodeByCodeLookup(TEMPLATE_ALLTRUE)            := OPERATOR_ALLOF;
11706 END;