1 /* ***********************************************************
  2    *                                                         *
  3    *                                                         *
  4    * Copyright, (C) Honeywell Information Systems Inc., 1981 *
  5    *                                                         *
  6    *                                                         *
  7    *********************************************************** */
  8 
  9 /* ******************************************************
 10    *                                                    *
 11    *                                                    *
 12    * Copyright (c) 1972 by Massachusetts Institute of   *
 13    * Technology and Honeywell Information Systems, Inc. *
 14    *                                                    *
 15    *                                                    *
 16    ****************************************************** */
 17 
 18 
 19 /****^  HISTORY COMMENTS:
 20   1) change(85-11-17,Dupuis), approve(85-12-16,MCR7314),
 21      audit(86-02-04,Brunelle), install(86-02-05,MR12.0-1013):
 22      This entry is being made to cover the change made on 85-06-14 by Thanh
 23      Nguyen. (see mrds #137)
 24   2) change(85-11-17,Dupuis), approve(85-12-16,MCR7314),
 25      audit(86-02-04,Brunelle), install(86-02-05,MR12.0-1013):
 26      This entry is being made to cover the change made on 85-10-13 by John
 27      Hergert. (see mrds #138, phx19901)
 28                                                    END HISTORY COMMENTS */
 29 
 30 
 31 mu_retrieve: proc (dbcb_ptr, area_ptr, rti_ptr, search_spec_ptr_parm,
 32           cvla_ptr_parm, tid_ptr, tuple_var_name, whole_stv_ptr,
 33           simple_typed_vector_ptr_parm, id_list_ptr_parm, code);
 34 
 35 /* NOTES:
 36 
 37    This  procedure  retrieves  the  next  tuple  within the current range which
 38    satisfies the specified constraints.
 39 
 40 */
 41 %page;
 42 /* HISTORY:
 43 
 44    78-11-01 J. A. Weeldreyer: Initially written.
 45 
 46    79-03-28 Al Kepner: Modified to return the located  tuple_id  for
 47    the restricted range case.
 48 
 49    79-05-17 Al Kepner: Modified to add entries db_on & db_off.
 50 
 51    79-06-21 Al Kepner: Partially rewritten to provide for comparison
 52    between two values from the same tuple.
 53 
 54    79-08-21 NSDavids: Comparison of  the  operands  (which  was  not
 55    always  done  correctly  if  they were of different scales and/or
 56    precisions) was replaced by a call to mu_compare_values.
 57 
 58    79-12-01 Rickie E.  Brinegar:  Modified  to  use  mrds_debug_tool
 59    switches instead of the entry points db_on & db_off.
 60 
 61    80-02-01 Jim Gray: Modified to add area_ptr parameter.
 62 
 63    80-02-15 Davids: Modified added data_ptr to the parameter list as
 64    output.  this  is  a  pointer  to  tuple.data  which is needed by
 65    mrds_dsl_search for determining the value of varying attributes.
 66 
 67    80-03-25 R. Lackey: Modified to remove calls to mdbm_util_
 68 
 69    80-05-08  Davids:  modified  assignments  of  tuple_num_atts  and
 70    tuple_nvar_atts  to  take  values from rm_rel_info.model_num_attr
 71    and  model_nvar_atts   rather   than   rm_rel_info.num_attr   and
 72    nvar_atts.  This  was  to  fix  a problem with submodels were the
 73    submodel view did not contain a varying string attribute and  the
 74    model did.
 75 
 76    80-10-30 M. Pierret: Modified to align 'match' for efficiency  of
 77    call to mu_compare_values.
 78 
 79    81-02-20 Rickie E. Brinegar: Changed calls to  mdb_display_value_
 80    to be calls to mdb_display_data_value$ptr. The latter allows more
 81    that 256 characters to be displayed.
 82 
 83    81-03-27 Jim Gray : changed dbi parameter to  dbcb_ptr,  and  for
 84    the  mu_sec_get_tuple  routines called, changed the dbi parameter
 85    to both dbcb_ptr and rmri_ptr. This is part of getting rid of the
 86    mus_ptr_man module.
 87 
 88    81-05-21   Jim   Gray   :   changed   placement   of   call    to
 89    mu_comapre_values,  so that if an error occured, the debug output
 90    about what the values were, gets  displayed.  This  was  done  to
 91    improve  the  information  in  the error message about conversion
 92    problems from mu_compare_values. Also added display of data  type
 93    for the value displayed, for the non-zero error code case.
 94 
 95    81-05-28 Jim Gray : commented out code dealing wiith foreign  key
 96    thread chasing.
 97 
 98    81-06-01 Jim Gray : changed to use new resultant structure.
 99 
100 
101    81-06-17 Jim Gray : added iocb index param to mu_sec_get_tuple$id
102    so that key retrieves do not need to use dedicated update iocb.
103 
104    81-10-19 Davids: deleted many declared but unreferenced variables
105    and also a couple of include files that were never used. modified
106    the internal routine get_comparison_value to call add_bit_offset_
107    rather  than  overlaying  a  bit  array  and  taking  the addr of
108    bit_array (offset), this because there is a pl1 bug which  causes
109    an  incorrect  addr to be returned when the code is compiled with
110    the prefix subscriptrange (see tr11784)
111 
112    82-09-03 Mike Kubicar : Converted the module to use the simple vector
113    structure instead of the tuple structure.
114 
115    82-10-26 Davids: changed the call to mu_sec_get_tuple$id to pass the
116    rtrv_info.record_collection_cursor_ptr instead of the cursor_ptr.
117 
118    82-10-28 Davids: Modified the calls to mu_sec_get_tuple$next and $id
119    to use the dbcb.select_area_ptr instead of the area_ptr which is an
120    input parameter. The select_area does not get reinitialized until the
121    selection expression changes, the area pointed to be the input param
122    gets reinitialized at every call of retrieve (or delete or modify)
123 
124    83-04-25 Mike Kubicar : There is no longer any distinction between
125    getting tuple sequentially and getting them via a key list.  Removed
126    mu_sec_get_tuple$* calls and replaced it with a single internal
127    procedure to get the next tuple via a search specification.
128 
129    83-04-28 Davids: Removed dcls for mu_sec_get_tuple$next and id.
130    added a dcl for the builtin empty.
131 
132    83-05-24 R. Harvey: Changed to use the appropriate simple_typed_vector_ptr
133    and id_list_ptr that are now passed in as arguments.
134 
135    83-05-31 Mike Kubicar : Updated to use new relation manager calling
136    sequence and search specification.
137 
138    83-08-03 Mike Kubicar : This program will no longer free the element
139    id list after returning from relation manager.  It uses the static
140    list set up by search program generation.
141 
142    84-08-07 Thanh Nguyen : Added code to check and call the user's decoded
143    procedure of an attribute (if it is required), in case of the exp_ptr
144    is null.
145 
146    85-01-15 Thanh Nguyen : Added code to check error code after calling
147    get_comparison_value and handle the case of uncessful allocation by reset
148    the work area.  Modified get_comparison_value procedure to call
149    mrds_space_allocate function instead of the standard PL/I allocate.  Added
150    two include files (mrds_space_allocate and mrds_area_initialize).
151 
152    85-01-25 Thanh Nguyen & John Hergert : Added code to check and continue
153    to get the next tuple when the get_next_tuple subroutine received the
154    mrds_error_$inconsistent_data_length.  This error is caused by the deleted
155    tuple in the share mode while getting the tuple by its tuple-id.
156 
157    85-04-14 Thanh Nguyen: Added code to detect the case of the scope that is
158    changed  from non-shared to shared mode.
159 
160    85-06-14 Thanh Nguyen: Added code to check for the scope that is changed
161    from non-shared to shared mode only if the dbcb.scopes_changed is on (This
162    flag is set by mrds_dsl_set_scope and reset by mrds_dsl_gen_srch_prog and
163    mrds_dsl_optimize
164 
165    85-10-13 John Hergert: Backed out some changes made in fix of
166    84-08-02. This was done to fix TR's phx11536 and phx19901
167 */
168 
169 /* PARAMETERS:
170    dbi -- (INPUT) data base index
171 
172    rti_ptr -- (INPUT) pointer to rtrv_info
173 
174    search_spec_ptr_parm -- (INPUT) pointer to the search spec to use for
175    the retrieval.  Note that the search spec may be changed from an
176    absolute to relative spec during this call.
177 
178    cvla_ptr_parm -- (INPUT) pointer to list of comparison values
179 
180    tid_ptr -- (INPUT) pointer to place that tuple_id of retrieved tuple
181    will be stored.
182 
183    tuple_var_name -- (INPUT) name of the tuple variable for which retrieval
184    is done (used for debugging only)
185 
186    whole_stv_ptr -- (INPUT) pointer to simple_typed_vector of whole view of
187    relation.
188 
189    simple_typed_vector_ptr -- (INPUT) pointer to newly retrieved tuple
190 
191    id_list_ptr_parm -- (INPUT) pointer to id_list structure which corresponds to
192    simple_typed_vector_ptr -> simple_typed_vector.
193 
194    code -- (OUTPUT) error code */
195 
196 /* MRDS_DEBUG_TOOL SWITCHES:
197 
198    bit 1 = display values compared.
199    bit 2 = display tuple data.
200    bits 3 through 9 = not used.
201 */
202 %page;
203           display_values_compared = substr (db_mu_retrieve, 1, 1);
204           display_tuple_data = substr (db_mu_retrieve, 2, 1);
205           cvla_ptr = cvla_ptr_parm;
206           id_list_ptr = id_list_ptr_parm;
207           simple_typed_vector_ptr = simple_typed_vector_ptr_parm;
208 
209           rmri_ptr = rtrv_info.ri_ptr;
210           k = 0;
211           ta_ptr = rtrv_info.ta_ptr;
212           ta_nids = rtrv_info.ntids;
213 
214           found = "0"b;
215           do while (^found);                                /* loop until find approp. tuple */
216 
217                call get_next_tuple (dbcb_ptr, rti_ptr,
218                     search_spec_ptr_parm, simple_typed_vector_ptr, tuple_id);
219                found = "1"b;
220 
221 
222 /* Now that we've got one, see if it matches the rest of the constraints */
223 
224                i, j = 0;
225                if cvla_ptr ^= null then do;                 /* if comparisons to be made */
226 
227                          work_area_ptr = dbcb.work_area_ptr;
228                          match = "0"b;
229                          do i = 1 to cvl_array.nlists while (^match); /* loop through and groups */
230                               cvl_ptr = cvl_array.list_ptr (i);
231                               match = "1"b;
232                               do j = 1 to comp_val_list.nvals while (match); /* loop through and group items */
233 
234                                    desc_ptr1 = addr (comp_val_list.val.desc1 (j));
235                                    desc_ptr2 = addr (comp_val_list.val.desc2 (j));
236                                    need_to_free_user_value = "0"b;
237 GET_COMPARISON_VALUE:
238                                    call get_comparison_value (
239                                         comp_val_list.val.exp_ptr (j),
240                                         null(),
241                                         comp_val_list.val.erslt_ptr (j),
242                                         comp_val_list.val.attr_ind (j),
243                                         desc_ptr1,
244                                         di_ptr,
245                                         icode);
246                                    if icode = error_table_$noalloc
247                                    then do;
248                                              call mrds_area_initialize (work_area_ptr);
249                                              go to GET_COMPARISON_VALUE;
250                                         end;
251                                    if comp_val_list.val.match_ptr (j) = null () /* compare to value from current tuple. */
252                                    then do;
253                                              call get_comparison_value (
254                                                   comp_val_list.val.exp_ptr2 (j),
255                                                   comp_val_list.val.c_ai_ptr2 (j),
256                                                   comp_val_list.val.erslt_ptr2 (j),
257                                                   comp_val_list.val.attr_ind2 (j),
258                                                   desc_ptr2,
259                                                   di_ptr2,
260                                                   icode);
261                                              if icode = error_table_$noalloc then do;
262                                                        call mrds_area_initialize (work_area_ptr);
263                                                        go to GET_COMPARISON_VALUE;
264                                                   end;
265                                         end;
266                                    else do;                 /* compare to value not from current tuple */
267                                              di_ptr2 = comp_val_list.val.match_ptr (j);
268                                         end;                /* compare to value not from current tuple */
269 
270                                    call mu_compare_values (di_ptr, desc_ptr1, di_ptr2, desc_ptr2,
271                                         comp_val_list.val.op (j), match, code);
272 
273                                    if display_values_compared | code ^= 0 then do;
274                                              if display_values_compared then
275                                                   call ioa_ ("di_ptr = ^p; di_ptr2 = ^p", di_ptr, di_ptr2);
276                                              if display_values_compared then
277                                                   call ioa_ ("Compared: ");
278                                              else call ioa_ ("Compared the data type:  ^a", mu_display_descriptor (desc_ptr1));
279                                              call mdb_display_data_value$ptr (di_ptr, desc_ptr1);
280                                              call ioa_ ("Using the comparison operator ""^a"" to:", rtrim (CVL_ops (comp_val_list.val.op (j))));
281                                              if ^display_values_compared then
282                                                   call ioa_ ("The data type:  ^a", mu_display_descriptor (desc_ptr2));
283                                              call mdb_display_data_value$ptr (di_ptr2, desc_ptr2);
284                                         end;                /* if debug_switch */
285 
286                                    if code ^= 0
287                                    then call error (code);
288                                    if need_to_free_user_value then
289                                         free value_for_user;
290                               end;                          /* comparing attr. in and group */
291                          end;                               /* comparing and group with or group */
292                          found = match;
293                     end;                                    /* if had comparisons */
294                if display_tuple_data then do;
295                          call mdb_display_tuple_$data (simple_typed_vector_ptr, rmri_ptr, iox_$user_output, icode);
296                          if icode ^= 0 then call error (icode);
297                          if found
298                          then call ioa_ ("Tuple Accepted for ""^a""", tuple_var_name);
299                          else call ioa_ ("Tuple Rejected for ""^a""", tuple_var_name);
300                     end;                                    /* if debug switch */
301           end;                                              /* search for tuple */
302 
303           code = 0;
304 
305 exit:
306           return;
307 %page;
308 get_next_tuple:
309      proc (dbcbptr, retrieve_info_ptr, search_spec_ptr,
310           simple_typed_vector_ptr, tuple_id);
311 
312 /**********
313 *
314 *   This routine will get the next tuple from a relation.  It needs to call
315 *   get_tuple_id followed by get_tuple_by_id since mrds needs both the
316 *   tuple id and the tuple in many cases.  It tries to use relation manager
317 *   as efficiently as is reasonable.  To do so, it gets as many tuple ids as
318 *   it can by one call to relation manager get_tuple_id.  It will then return
319 *   the first tuple in the list of ids by getting the tuple by id.  On
320 *   successive calls, it will use the other tuple ids in the list.  When
321 *   it has run out of tuple ids, it will get more by calling $get_tuple_id
322 *   again.  The routine effectively buffers tuple ids.  The routine uses
323 *   the following parameters:
324 *
325 *   dbcbptr  (input)  - Pointer to the dbcb
326 *   retrieve_info_ptr (input) - Pointer to the retrieve info to be used
327 *       on this retrieval.  Note that the rtrv_info structure may be
328 *       modified by this procedure.
329 *   search_spec_ptr (input) - The relation_search_specification to be used
330 *       in the search.  Note that the search spec pointed at may be modified by
331 *       this procedure.
332 *   simple_typed_vector_ptr (output) - The tuple which was retrieved.  Note
333 *       that locations pointed at by the simple typed vector structure will
334 *       be filled in with data from the database.  The simple typed vector
335 *       structure itself is not changed.  If no data is to be returned
336 *       by the procedure (i.e. only the tuple id is desired) as indicated
337 *       by a zero array extent on the id list, the contents of the structure
338 *       pointed to by this pointer is undefined.  Indeed, the pointer is not
339 *       used.
340 *   tuple (output) - The tuple id of the tuple returned.
341 *
342 *
343 *   If relation manager returns an error code, the error routine is called.
344 *   Also, if a call is to be made to $get_tuple_id and less tuple ids than
345 *   expected were returned in a prior call, then mrds_error_$no_tuple_found
346 *   is passed to the error routine.
347 *
348 **********/
349 
350 
351 /*  Parameters */
352 
353           dcl     dbcbptr                ptr;
354           dcl     retrieve_info_ptr      ptr;
355           dcl     search_spec_ptr        ptr;
356           dcl     simple_typed_vector_ptr ptr;
357           dcl     tuple_id               bit (36) aligned;
358           dcl     continue_for_next_tuple bit (1) aligned;
359 
360 /*  Local data */
361 
362           dcl     icode                  fixed bin (35);    /* Returned error code */
363 
364 
365 /* Procedure */
366 
367           continue_for_next_tuple = "1"b;
368           do while (continue_for_next_tuple);
369                continue_for_next_tuple = "0"b;
370                if dbcb.scopes_changed then do;
371                   if retrieve_info_ptr -> rtrv_info.ri_ptr -> rm_rel_info.file_type ^= 3 then
372                      /* this relation is not a temporary relation */
373                      if dbcb.non_shared_to_shared = "0"b then do;
374                          current_scope_ptr = retrieve_info_ptr -> rtrv_info.ri_ptr -> rm_rel_info.scope_flags_ptr;
375                          if (current_scope_flags.permits.read_attr |
376                              current_scope_flags.permits.delete_tuple |
377                              current_scope_flags.permits.modify_attr) then
378                             if ^current_scope_flags.prevents.modify_attr |
379                               (^current_scope_flags.prevents.append_tuple &
380                                ^current_scope_flags.prevents.delete_tuple) then
381                               if retrieve_info_ptr -> rtrv_info.maxtids ^=
382                                 mrds_data_$max_safe_tids_returned_per_call then
383                               /* Somebody just changes the scope to shared mode within the
384                               same select expression (should be -another) */
385                                 dbcb.non_shared_to_shared = "1"b;
386                     end;
387                end;
388 
389                if retrieve_info_ptr -> rtrv_info.ctid >=
390                     retrieve_info_ptr -> rtrv_info.ntids then do; /* None left from prior call or first time in routine */
391                          if retrieve_info_ptr -> rtrv_info.first_seq_io then do; /* Furst get from this tuple variable */
392                                    retrieve_info_ptr -> rtrv_info.first_seq_io = "0"b;
393                                    search_spec_ptr -> relation_search_specification.head.type =
394                                         ABSOLUTE_RELATION_SEARCH_SPECIFICATION_TYPE;
395                               end;
396                          else do;                           /* Get another set of tids */
397                                    if retrieve_info_ptr -> rtrv_info.ntids <
398                                         retrieve_info_ptr -> rtrv_info.maxtids /* Got less than we expected last time */
399                                    then call error (mrds_error_$tuple_not_found);
400                                    search_spec_ptr -> relation_search_specification.head.type =
401                                         RELATIVE_RELATION_SEARCH_SPECIFICATION_TYPE;
402                                    retrieve_info_ptr -> rtrv_info.ta_ptr -> element_id_list.number_of_elements = 0;
403                               end;
404                          call dbcbptr -> dbcb.relmgr_entries.get_tuple_id (
405                               retrieve_info_ptr -> rtrv_info.relation_cursor_ptr,
406                               search_spec_ptr, dbcbptr -> dbcb.select_area_ptr,
407                               retrieve_info_ptr -> rtrv_info.ta_ptr,
408                               icode);
409                          if icode ^= 0
410                          then call error (icode);
411                          retrieve_info_ptr -> rtrv_info.ctid = 0;
412                          retrieve_info_ptr -> rtrv_info.ntids =
413                               retrieve_info_ptr -> rtrv_info.ta_ptr -> element_id_list.number_of_elements;
414                     end;
415 
416 
417 /* Now get the next tuple in the element id list */
418 
419                retrieve_info_ptr -> rtrv_info.ctid =
420                     retrieve_info_ptr -> rtrv_info.ctid + 1;
421                tuple_id = retrieve_info_ptr -> rtrv_info.ta_ptr ->
422                     element_id_list.id (retrieve_info_ptr -> rtrv_info.ctid);
423                if id_list_ptr -> id_list.number_of_ids > 0  /* Retrieving one or more attributes of the tuple */
424                then do;
425                          call dbcbptr -> dbcb.relmgr_entries.get_tuple_by_id (
426                               retrieve_info_ptr -> rtrv_info.relation_cursor_ptr,
427                               tuple_id, id_list_ptr, dbcbptr -> dbcb.select_area_ptr,
428                               simple_typed_vector_ptr, icode);
429                          if icode = mrds_error_$inconsistent_data_length then do;
430                                    icode = 0;
431                                    continue_for_next_tuple = "1"b;
432                               end;
433                          else if icode ^= 0
434                          then call error (icode);
435                     end;
436           end;                                              /* end while */
437 
438      end get_next_tuple;
439 %page;
440 get_comparison_value: proc (exp_ptr, ai_ptr, erslt_ptr, attr_index, desc_ptr, di_ptr, icode);
441 
442 /* This routine produces a pointer to one of the values to be used in the
443    comparison.  An attribute will be check and call the decoded procedure
444    if there is a decode proc for that attribute.  An expression may be
445    evaluated if necessary. */
446 
447           dcl     exp_ptr                ptr;               /* INPUT : ptr to expression to be evaluated or null */
448           dcl     ai_ptr                 ptr;               /* INPUT : ptr to rm_attr_info, it may be null. */
449           dcl     erslt_ptr              ptr;               /* INPUT : ptr to result of expression. */
450           dcl     attr_index             fixed bin (17);    /* INPUT : attribute of interest */
451           dcl     desc_ptr               ptr;               /* INPUT : ptr to descriptor */
452           dcl     di_ptr                 ptr;               /* IN/OUT: ptr to comparison value. */
453           dcl     icode                  fixed bin (35);    /* IN/OUT: standard error code. */
454 
455           icode = 0;
456           if exp_ptr = null ()                              /* Just an attribute, no expression */
457           then do;
458                     di_ptr = whole_stv_ptr -> simple_typed_vector.dimension (attr_index).value_ptr;
459                     if ai_ptr ^= null then /* need to decode attribute */
460                          if ai_ptr -> rm_attr_info.domain_ptr -> rm_domain_info.decd_proc
461                          then do;
462                                    t_domain_ptr = ai_ptr -> rm_attr_info.domain_ptr;
463                                    user_bit_length = t_domain_ptr -> rm_domain_info.user_bit_len;
464                                    user_val_ptr = mrds_space_allocate (work_area_ptr, (user_bit_length + 35) / 36);
465                                    if user_val_ptr = null () then do;
466                                              icode = error_table_$noalloc;
467                                              return;
468                                         end;
469                                    k = k + 1;
470                                    value_for_user = "0"b;   /* clear out space */
471                                                             /* evaluate and call decoded procedure */
472                                    call mu_get_data$get_data_item (ai_ptr, work_area_ptr, di_ptr,
473                                         user_val_ptr, desc_ptr, icode);
474                                    if icode = error_table_$noalloc then
475                                         return;
476                                    di_ptr = user_val_ptr;   /* set output ptr */
477                               end;
478                end;
479           else do;                                          /* if expression */
480                     di_ptr = erslt_ptr;
481                     call mrds_dsl_eval_expr (area_ptr, exp_ptr, rmri_ptr, whole_stv_ptr, icode);
482                end;                                         /* if expression */
483           if icode ^= 0 then call error (icode);
484      end get_comparison_value;
485 %page;
486 %include mrds_space_allocate;
487 %page;
488 %include mrds_area_initialize;
489 %page;
490 error: proc (cd);
491 
492 /* Error procedure */
493 
494           dcl     cd                     fixed bin (35);
495 
496           if (cd = dm_error_$no_tuple) | (cd = dm_error_$no_tuple_id)
497           then code = mrds_error_$no_tuple;
498           else code = cd;
499           go to exit;
500 
501      end error;
502 %page;
503           dcl     cvla_ptr_parm          ptr;
504           dcl     id_list_ptr_parm       ptr parameter;
505           dcl     simple_typed_vector_ptr_parm ptr parameter;
506           dcl     search_spec_ptr_parm   ptr;
507           dcl     tuple_var_name         char (*);          /* tuple variable name for debugging */
508           dcl     user_bit_length        fixed bin;
509           dcl     value_for_user         bit (user_bit_length) based (user_val_ptr);
510           dcl     work_area_ptr          ptr;
511 
512           dcl     (i, k,                                    /* internal indexes */
513                   j)                     fixed bin;
514 
515           dcl     (code,                                    /* Output:  status code */
516                   icode)                 fixed bin (35);    /* offset of item in tuple.data */
517 
518           dcl     (area_ptr,
519                   desc_ptr1,                                /* ptr to desc for first value to be compared. */
520                   desc_ptr2,                                /* ptr to desc for second value to be compared. */
521                   di_ptr,                                   /* to data item */
522                   di_ptr2,                                  /* ptr to second comparison value */
523                   t_domain_ptr,                             /* temp ptr use to point to rm_domain_info. */
524                   tid_ptr,
525                   user_val_ptr,                             /* ptr to converted value for decoding */
526                   whole_stv_ptr)         ptr;               /* Input:  to place to store tuple id */
527 
528 
529           dcl     (display_tuple_data,                      /* flags */
530                   display_values_compared,
531                   found)                 bit (1) unaligned;
532 
533           dcl     match                  bit (1) aligned;   /* aligned for efficiency in call to mu_compare_values */
534           dcl     need_to_free_user_value bit (1) aligned;
535 
536           dcl     (addr,
537                   fixed,
538                   null,
539                   rel,
540                   rtrim,
541                   substr,
542                   unspec)                builtin;
543 
544           dcl     tuple_id               bit (36) aligned based (tid_ptr);
545 
546           dcl     CVL_ops                (1:6) char (2) int static options (constant) init (
547                                          "=",
548                                          "^=",
549                                          "<",
550                                          "<=",
551                                          ">",
552                                          ">=");
553           dcl     1 current_scope_flags aligned based (current_scope_ptr) like scope_flags;
554           dcl     current_scope_ptr      ptr;
555           dcl     dm_error_$no_tuple     fixed bin (35) ext static;
556           dcl     dm_error_$no_tuple_id  fixed bin (35) ext static;
557           dcl     mrds_data_$max_safe_tids_returned_per_call fixed bin (35) ext static;
558           dcl     mrds_error_$no_tuple   ext fixed bin (35);
559           dcl     mrds_error_$tuple_not_found fixed bin (35) ext static;
560           dcl     mrds_error_$inconsistent_data_length fixed bin (35) ext static;
561           dcl     mrds_dsl_eval_expr     entry (ptr, ptr, ptr, ptr, fixed bin (35));
562           dcl     ioa_                   entry options (variable);
563 
564           dcl     iox_$user_output       ext ptr;
565 
566           dcl     sys_info$max_seg_size  fixed bin (35) ext static;
567 
568           dcl     error_table_$noalloc   fixed bin (35) ext static;
569 
570           dcl     mdb_display_data_value$ptr entry (ptr, ptr);
571 
572           dcl     mdb_display_tuple_$data entry (ptr, ptr, ptr, fixed bin (35));
573           dcl     mu_compare_values      entry (ptr, ptr, ptr, ptr, fixed bin, bit (1) aligned, fixed bin (35));
574           dcl     mu_display_descriptor  entry (ptr) returns (char (120) varying); /* gets char form of descriptor */
575           dcl     mu_get_data$get_data_item entry (ptr, ptr, ptr, ptr, ptr, fixed bin (35));
576 %page;
577 %include dm_element_id_list;
578 %page;
579 %include dm_id_list;
580 %page;
581 %include dm_relation_spec;
582 %page;
583 %include dm_specification_head;
584 %page;
585 %include mdbm_scope_info;
586 %page;
587 %include mdbm_comp_val_list;
588 %page;
589 %include mdbm_rm_rel_info;
590 %page;
591 %include mdbm_rm_attr_info;
592 %page;
593 %include mdbm_rm_domain_info;
594 %page;
595 %include mdbm_rtrv_info;
596 %page;
597 %include mrds_debug_names;
598 %page;
599 %include mrds_dbcb;
600 %page;
601 %include vu_typed_vector;
602 
603      end mu_retrieve;