Multics Technical Bulletin                        MTB-547, Rev. 1
  DM: Record Manager Functional Spec

  To:       Distribution

  From:     Lindsey Spratt and Matt Pierret

  Date:     04/18/84

  Subject:  Data Management: Record Manager Functional Specification

  1 ABSTRACT

       This document describes the operations of the record manager
  which  will  be used  by  the relation  and index  managers.  The
  record  manager  implements  a  collection  of  fixed-format (all
  records having the same  set of fields), variable-length records.
  Methods  of accessing  data are  described, including  the use of
  search specifications, cursors and record identifiers.

  Comments should be sent to the author:

  via Multics Mail:
     Spratt.Multics on either MIT Multics or System M.

  via US Mail:
     Lindsey Spratt
     Honeywell Information Systems, inc.
     4 Cambridge Center
     Cambridge, Massachusetts 02142

  via telephone:
     (HVN) 261-9321, or
     (617) 492-9321

  _________________________________________________________________

  Multics  project  internal  working  documentation.   Not  to  be
  reproduced or distributed outside the Multics project without the
  consent of the author or the author's management.



                            CONTENTS

                                                         Page

                 1 Abstract . . . . . . . . . . . . . .     i
                 2 Introduction . . . . . . . . . . . .     1
                 3 Significant Changes Contained in
                  Revision 1  . . . . . . . . . . . . .     1
                 4 Storing Records  . . . . . . . . . .     2
                 5 Cursors  . . . . . . . . . . . . . .     3
                 6 Vectors  . . . . . . . . . . . . . .     3
                 7 Description of the Operations  . . .     4
                    record_manager_ . . . . . . . . . .     4
                       $copy_cursor (unimplemented) . .     5
                       $create_collection . . . . . . .     6
                       $create_cursor . . . . . . . . .     7
                       $delete_record_by_id . . . . . .     8
                       $delete_records_by_id_list . . .     9
                       $delete_records_by_spec  . . . .    10
                       $destroy_collection  . . . . . .    11
                       $destroy_cursor  . . . . . . . .    12
                       $get_field_info  . . . . . . . .    13
                       $get_record_by_id  . . . . . . .    14
                       $get_record_ids_by_interval  . .    15
                       $get_record_ids_by_spec  . . . .    16
                       $get_record_count  . . . . . . .    17
                       $get_record_count_by_interval  .    18
                       $get_records_and_ids_by_spec . .    19
                       $get_records_and_ids_by_interval    20
                       $get_records_by_id_list  . . . .    22
                       $get_records_by_interval . . . .    23
                       $get_records_by_spec . . . . . .    25
                       $modify_record_by_id . . . . . .    26
                       $modify_records_by_id_list . . .    27
                       $modify_records_by_spec  . . . .    28
                       $position_cursor . . . . . . . .    29
                       $put_record_by_id  . . . . . . .    30
                       $put_records_by_id . . . . . . .    32
                       $put_records_by_spec
                        (unimplemented) . . . . . . . .    34
                 Appendix A - Specification Structures     35
                    The specification_head structure  .    35
                    The subset_specification structure     35
                    The search_specification structure     36
                    The numeric_specification structure    39



                         CONTENTS (cont)

                                                         Page

                 Appendix B - Information Structures  .    41
                    The typed_vector structure  . . . .    41
                    The typed_vector_array structure  .    42
                    The element_id_list structure . . .    43
                    The id_list structure . . . . . . .    43
                    The interval_list structure . . . .    44

  Multics Technical Bulletin                        MTB-547, Rev. 1
  DM: Record Manager Functional Spec

  2 INTRODUCTION

       The record manager supports the organization of records in a
  collection.    Records   are    multiple-field,   fixed   format,
  varying-length  records.  That  is, many  fields are  allowed per
  record, and the fields may be  of varying length, but all records
  must  have the  same set  of fields  (fixed format).   The record
  manager  may be  used with  an index  manager or  alone.  Records
  which  are  related,  as  specified   by  the  caller,  are  kept
  physically "close" together if possible.

       Record identifiers are not  guaranteed to be unchanging from
  transaction to transaction, but can  be guaranteed to be constant
  for the  duration of a transaction.   Identifiers can change when
  doing a cleanup of the record collection.

       Records  are  threaded  together  in  an  explicitly defined
  order,  making  it possible  to use  the record  manager directly
  without the aid  of an index.  This should  save on call overhead
  and I/Os  when walking through the  entire collection of records.
  In general however,  it is expected that the  record manager will
  be used in concert with an index.

  3 SIGNIFICANT CHANGES CONTAINED IN REVISION 1                     |

       Changes  made  to this  MTB  for Revision  1  are extensive. |
  Therefore, no change bar indicators will appear.                  |

       The name  of the subroutine interface  to the Record Manager |
  has been changed from  rcdmgr_ to record_manager_.  The following |
  entry points have been added:                                     |

       delete_records_by_id_list                                    |
       get_field_info                                               |
       get_record_ids_by_interval                                   |
       get_record_count_by_interval                                 |
       get_records_and_ids_by_spec                                  |
       get_records_and_ids_by_interval                              |
       get_records_by_id_list                                       |
       get_records_by_interval                                      |
       modify_records_by_id_list                                    |
       put_records_by_id                                            |

      The following entry points have been renamed:                 |

          old_name                   new_name                       |

       delete_record_by_spec         delete_records_by_spec         |
       get_id                        get_record_ids_by_spec         |


  MTB-547, Rev. 1                        Multics Technical Bulletin
                                 DM: Record Manager Functional Spec

|      get_record_by_spec            get_records_by_spec
|      modify_record_by_spec         modify_records_by_spec
|      put_record_by_spec            put_records_by_spec

|      The calculate_storage entry point has been deleted.

|      The  argument  names have  been named  so that  entry points
| which pass the same arguments now call them by the same names.

|      The  descriptions   of  the  specification   structures  and
| information  structures used  by this subroutine  have been moved
| into Appendix  A, and their  descriptions updated to  reflect the
| currently     installed     code.      Descriptions     of    the
| simple_typed_vector, general_typed_vector, and typed_vector_array
| structures have been provided.

  4 STORING RECORDS

       Records of  a collection are chained  together, allowing the
  record manager to access the  records in some order.  When adding
  a  record to  this chain  (i.e.  storing  a record)  the user may
  specify  where  in the  chain  the record  should go.   With this
  technique, the user can maintain a meaningful ordering of his/her
  records.  The user also has the  option to not care about how the
  records  are ordered,  and store them  randomly.  Whether records
  are stored randomly or in some meaningful order, they are chained
  together.

       Records  which  are  chained  near  each  other  are  stored
  physically  close  to  each   other,  if  possible.   Performance
  enhancements  can  be  realised,  in  terms  of  number  of  I/Os
  generated, under  certain common circumstances if  the user takes
  advantage  this physical  closeness.  For  instance, if  the user
  knows that the  records will very often be  searched according to
  constraints over a particular field or set of fields, storing the
  records in the order of the values of that field or set of fields
  would make searching more  efficient.  Those searches, which were
  already identified to be the  common case, would require only one
  I/O  for several  records, rather  than the  likely I/O  for each
  record if stored randomly.

       An alternative gain would result  if the user could identify
  sets  of records  within a collection  which would  very often be
  accessed together, i.e.  if one of the records is accessed, there
  is a high probability that the other records of the set will also
  be accessed  very soon.  The  user could then  have those records
  stored near each other, to reduce on the number of I/Os generated
  in this type of search.


  Multics Technical Bulletin                        MTB-547, Rev. 1
  DM: Record Manager Functional Spec

       As  keeping records  in some meaningful  order requires some
  effort  on the  part of  the user, the  user can  opt for storing
  records  without specifying  where the  records should  go.  With
  this random storage, records are  still chained together to allow
  for searches over  the collection, but all records  are stored at
  the  end of  the collection both  physically and in  the chain of
  records.

  5 CURSORS

       Cursors  are  used  to  maintain  a  position  in  a  record
  collection.   Record manager  cursors contain  an indicaton  of a
  position in a  collection, as well as such  needed information as
  the  file  opening identifier  and the  identifier of  the record
  collection.  Users of the record manager never manipulate or even
  see cursors  directly.  Users pass pointers  to cursors to record
  manager routines which are responsible for manipulating the value
  of the cursor.  All operations which access the record collection
  expect a cursor as an input argument, even if the position is not
  used, because  the cursor determines the  file opening and record
  collection identifiers.

  6 VECTORS

       The  record  and index  managers use  a common  structure to
  return records and  keys.  Record and key values  are referred to
  generically as  vectors.  Vectors are  returned to the  caller in
  vector  arrays.  These  vector arrays  have built  in information
  about the format  of the data, how to display  and sort the data,
  and how to convert the  data into a character representation.  As
  a  result,  tools for  displaying  and editing  vectors  need not
  continually reference header information.

       Just as a record is composed of fields, a vector is composed
  of dimensions.  In  this paper, the terms vector  and record, and
  dimension  and  field  are  used  interchangeably.   For  a  more
  complete description  of vectors and vector  arrays and the tools
  used to  manipulate them, see  "The Data Vector -  A General Data
  Management Tool", MTB-999.


  MTB-547, Rev. 1                        Multics Technical Bulletin
                                 DM: Record Manager Functional Spec

  7 DESCRIPTION OF THE OPERATIONS

  Name:  record_manager_

       The record_manager_  subroutine manages records  in a record
  collection.   The  records may  have  multiple fields  of varying
  length and mixed data types.  All  records must have the same set
  of fields.

       Positioning in  record collections is  done with the  aid of
  search  specifications  -- structures  which describe  records or
  record positions.  A specification  can be numeric positioning or
  search on  values.  It can  be absolute, done by  starting at the
  beginning or end of the index, or relative, done by starting at a
  position specified by a cursor.

       See  Appendix  A  for  a  description  of  the specification
  structures.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$copy_cursor (unimplemented)

       Makes  a  copy of  a cursor.   The new  cursor has  the same
  position as the template cursor from which it was copied.

  Usage

       dcl record_manager_$copy_cursor (unimplemented) entry (ptr,
            ptr, ptr, fixed bin(35));

       call record_manager_$copy_cursor (unimplemented)
            (input_cursor_ptr, work_area_ptr, output_cursor_ptr,
            code);
  where:

         input_cursor_ptr             (Input)
              is a pointer to the cursor to be copied.

         work_area_ptr                (Input)
              is a pointer  to the area in which  the new cursor is
              to be allocated.

         output_cursor_ptr            (Output)
              is a pointer to the new cursor.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$create_collection

       Creates an  empty record collection  in the given  file with
  the specified fields.  An  identifier is assigned for referencing
  this  collection, or  rather the  header of  the collection.  The
  header is filled with information about the format of the records
  and the location of the first control interval of the collection.

  Usage

       dcl record_manager_$create_collection entry (bit(36)
            aligned, ptr, ptr, ptr, bit(36) aligned, fixed
            bin(35));

       call record_manager_$create_collection (file_opening_id,
            typed_vector_array_ptr, cism_info_ptr, esm_info_ptr,
            record_collection_id, code);
  where:

         file_opening_id              (Input)
              is the opening identifier of the file of interest.

         typed_vector_array_ptr       (Input)
              is a  pointer to a  typed_vector_array structure, the
              dimension table of which is used to define the fields
              of  the colleciton.   In operations  where the fields
              are referred to, either explicitly or implicitly, the
              array index  of the field  in the dimension  table is
              its identifier.

         cism_info_ptr                (Input)
              is a pointer to a structure which defines the Control
              Interval   Storage   Method.   Currently,   only  the
              Unblocked CISM  is supported.  The  structure used is
              unblocked_cism_info,            declared           in
              dm_cm_cism_info.incl.pl1.

         esm_info_ptr                 (Input)
              is a pointer to a structure which defines the Element
              Storage  Method.   Currently, only  the Basic  ESM is
              supported.   The  structure  used  is basic_esm_info,
              declared in dm_cm_esm_info.incl.pl1.

         record_collection_id         (Output)
              is a record collection  identifier which serves as an
              index to the record collection's header.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$create_cursor

       Allocates  a  cursor structure  in  the provided  work area.
  This cursor is  tailored for the record collection  with which it
  is to be  used.  Its initial position is at  the beginning of the
  collection.

  Usage

       dcl record_manager_$create_cursor entry (bit(36) aligned,
            bit(36) aligned, ptr, ptr, fixed bin(35));

       call record_manager_$create_cursor (file_opening_id,
            record_collection_id, work_area_ptr, record_cursor_ptr,
            code);
  where:

         file_opening_id              (Input)
              is the  opening identifier of  the file in  which the
              record collection resides.

         record_collection_id         (Input)
              is a record collection identifier.

         work_area_ptr                (Input)
              is a pl1 area defined by the caller.

         record_cursor_ptr            (Output)
              is a pointer  to a data structure used  to identify a
              position  in  a  record_collection.   It  is  managed
              entirely by the record  manager.  The cursor contains
              the  file_opening_id,  the  record_collection_id, the
              work_area_ptr (to  facilitate freeing), the  value of
              the  record which  is the  current position,  and the
              "address"  of   the  record  which   is  the  current
              position.   The address  is to  provide swift access,
              the  value  is to  verify that  the address  is still
              valid.  The address and  value (the current position)
              are  "undefined"  when  the  cursor  is  created.  It
              becomes "defined" when given as input to any absolute
              positioning     operation    (modify_records_by_spec,
              delete_records_by_spec,          get_records_by_spec,
              get_record_id, or position_cursor  with an "absolute"
              specification).

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$delete_record_by_id

       Deletes the record specified by record_id.

  Usage

       dcl record_manager_$delete_record_by_id entry (bit(36)
            aligned, ptr, fixed bin(35));

       call record_manager_$delete_record_by_id (record_id,
            record_cursor_ptr, code);
  where:

         record_id                    (Input)
              is the identifier of the record to delete.

         record_cursor_ptr            (Input)
              is a pointer to a record cursor.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$delete_records_by_id_list

       Deletes  the records  specified by  the record_id_list.  The
  cursor  is  positioned to  the record  following the  last record
  deleted.

  Usage

       dcl record_manager_$delete_records_by_id_list entry (ptr,
            ptr, fixed bin(35), fixed bin(35));

       call record_manager_$delete_records_by_id_list
            (element_id_list_ptr, record_cursor_ptr,
            number_of_records_processed, code);
  where:

         element_id_list_ptr          (Input)
              is   a  pointer   to  an   element_id_list  structure
              containing the identifiers of the records to delete.

         record_cursor_ptr            (Input)
              is a pointer to a record cursor.

         number_of_records_processed  (Output)
              is the number of records deleted.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$delete_records_by_spec

       Deletes the records identified by the search specification.

  Usage

       dcl record_manager_$delete_records_by_spec entry (ptr, ptr,
            fixed bin(35), fixed bin(35));

       call record_manager_$delete_records_by_spec
            (specification_ptr, record_cursor_ptr,
            number_of_records_processed, code);
  where:

         specification_ptr            (Input)
              is   a   pointer   to   a   search_specification   or
              numeric_specification structure.

         record_cursor_ptr            (Input)
              is a pointer to a record cursor.  After the deletion,
              the  cursor is  set to the  position of  what was the
              "next" record, or to  a special value indicating that
              the end of the collection has been reached.

         number_of_records_processed  (Output)
              is the number of records which were deleted.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$destroy_collection

       Destroys  a   record  collection,  freeing   its  associated
  storage.   Record collection  identifiers may  be re-used  by the
  "create_collection" operation.

  Usage

       dcl record_manager_$destroy_collection entry (bit(36)
            aligned, bit(36) aligned, fixed bin(35));

       call record_manager_$destroy_collection (file_opening_id,
            record_collection_id, code);
  where:

         file_opening_id              (Input)
              if the  opening identifier of  the file in  which the
              record collection resides.

         record_collection_id         (Input)
              is  the  identifier of  the  record collection  to be
              destroyed.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$destroy_cursor

       Destroys a cursor, freeing its storage.

  Usage

       dcl record_manager_$destroy_cursor entry (ptr, fixed
            bin(35));

       call record_manager_$destroy_cursor (record_cursor_ptr,
            code);
  where:

         record_cursor_ptr            (Input)
              is a pointer to the record cursor to be destroyed.

         code                         (Output)
              is standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$get_field_info

            Returns information  about the fields  of the specified
  record.

  Usage

       dcl record_manager_$get_field_info entry (bit(36) aligned,
            bit(36) aligned, ptr, ptr, fixed bin(35));

       call record_manager_$get_field_info (file_opening_id,
            record_collection_id, work_area_ptr,
            typed_vector_array_ptr, code);
  where:

         file_opening_id              (Input)
              is the  opening identifier of  the file in  which the
              record collection resides.

         record_collection_id         (Input)
              is the identifier of the record collection.

         work_area_ptr                (Input)
              is a pointer  to a pl1 area defined  by the caller in
              which to return the array of information.

         typed_vector_array_ptr       (Output)
              is a pointer to  a typed_vector_array structure which
              contains the field information.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$get_record_by_id

       Gets  the  desired  fields   of  the  record  identified  by
  record_id.

  Usage

       dcl record_manager_$get_record_by_id entry (bit(36) aligned,
            ptr, ptr, ptr, ptr, fixed bin(35));

       call record_manager_$get_record_by_id (record_id,
            id_list_ptr, work_area_ptr, record_cursor_ptr,
            simple_typed_vector_ptr, code);
  where:

         record_id                    (Input)
              is the identifier of the desired record.

         id_list_ptr                  (Input)
              is a  pointer to an id_list  structure containing the
              identifiers of the fields to be retrieved.

         work_area_ptr                (Input)
              is a pointer  to a pl1 area defined  by the caller in
              which to place the retrieved records.

         record_cursor_ptr            (Input)
              is a pointer to a record cursor.

         simple_typed_vector_ptr      (Output)
              is  a  pointer  to  a  simple_typed_vector  structure
              containing the retrieved record.

         code                         (Output)
              is standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$get_record_ids_by_interval

       This  entry returns  the record  identifiers of  the records
  specified.  Selection is based on three things:  a list of record
  identifiers,   a   search_specification,  and   an  interval_list
  structure.

  Usage

       dcl record_manager_$get_record_ids_by_interval entry (ptr,
            ptr, ptr, ptr, ptr, ptr, fixed bin(35));

       call record_manager_$get_record_ids_by_interval
            (input_element_id_list_ptr, search_specification_ptr,
            interval_list_ptr, work_area_ptr, record_cursor_ptr,
            output_element_id_list_ptr, code);
  where:

         input_element_id_list_ptr    (Input)
              is   a  pointer   to  an   element_id_list  structure
              containing  the  ids  of  the  records  to  which the
              search_specification and interval are to be applied.

         search_specification_ptr     (Input)
              is a pointer to  a search_specification to be applied
              to the  records listed in  the record element_id_list
              structure.

         interval_list_ptr            (Input)
              is  a  pointer  to  an  interval_list  structure.  It
              identifies records satisfying  the constraints in the
              and_group which pertain to  the fields present in the
              index.

         work_area_ptr                (Input)
              is a  pointer to a  freeing area in  which the output
              typed_vector_array is to be allocated.

         record_cursor_ptr            (Input)
              is  a pointer  to a  record cursor.   The position is
              left unchanged by this operation.

         output_element_id_list_ptr   (Output)
              is  a pointer  to an  element_id_list structure which
              contains  the  record  identifiers  of  the  selected
              records.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$get_record_ids_by_spec

       Gets  the  identifiers  of  the  records  identified  by the
  specification.

  Usage

       dcl record_manager_$get_record_ids_by_spec entry (ptr, ptr,
            ptr, ptr, fixed bin(35));

       call record_manager_$get_record_ids_by_spec
            (specification_ptr, work_area_ptr, record_cursor_ptr,
            element_id_list_ptr, code);
  where:

         specification_ptr            (Input)
              is   a   pointer   to   a   search_specification   or
              numeric_specification structure.

         work_area_ptr                (Input)
              is a pointer  to a pl1 area defined  by the caller in
              which to place the returned identifiers.

         record_cursor_ptr            (Input)
              is  a   pointer  to  a  record   cursor.   After  the
              operation, the  cursor is set to  the position of the
              record corresponding to the last id retrieved.

         element_id_list_ptr          (Output)
              is   a  pointer   to  an   element_id_list  structure
              containing the record identifiers selected.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$get_record_count

       Returns the count of records  in the collection that satisfy
  the search specification.

  Usage

       dcl record_manager_$get_record_count entry (ptr, ptr, fixed
            bin(35), fixed bin(35));

       call record_manager_$get_record_count (specification_ptr,
            record_cursor_ptr, number_of_records_processed, code);
  where:

         specification_ptr            (Input)
              is   a   pointer   to   a   search_specification   or
              numeric_specification structure.

         record_cursor_ptr            (Input)
              is a pointer to a record cursor.  The position is not
              changed.

         number_of_records_processed  (Output)
              is the number of records selected.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$get_record_count_by_interval

       This  entry  returns  the  count  of  records  that  meet  a
  selection  criteria  based on  a  list of  record  identifiers, a
  search specification, and an interval list structure.

  Usage

       dcl record_manager_$get_record_count_by_interval entry (ptr,
            ptr, ptr, ptr, ptr, fixed bin(35), fixed bin(35));

       call record_manager_$get_record_count_by_interval
            (input_elment_id_list_ptr, search_specification_ptr,
            interval_list_ptr, work_area_ptr, record_cursor_ptr,
            record_count, code);
  where:

         input_element_id_list_ptr    (Input)
              is   a  pointer   to  an   element_id_list  structure
              containing  the  ids  of  the  records  to  which the
              search_specification and interval are to be applied.

         search_specification_ptr     (Input)
              is a pointer to  a search_specification to be applied
              to   the  records   listed  in   the  element_id_list
              structure.

         interval_list_ptr            (Input)
              is  a  pointer  to  an  interval_list  structure.  It
              identifies records satisfying  the constraints in the
              and_group which pertain to  the fields present in the
              index.

         work_area_ptr                (Input)
              is a  pointer to a  freeing area in  which the output
              typed_vector_array is to be allocated.

         record_cursor_ptr            (Input)
              is  a pointer  to a  record cursor.   The position is
              left unchanged by this operation.

         record_count                 (Output)
              is  a count  of the number  of records  in the record
              element_id_list  which  satisfied the  constraints of
              the  search_specification  applied   in  the  fashion
              specified by the interval_list.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$get_records_and_ids_by_spec

       This entry  returns a set  of records and  their identifiers
  that meet the search specification.

  Usage

       dcl record_manager_$get_records_and_ids_by_spec entry (ptr,
            ptr, ptr, ptr, ptr, ptr, fixed bin(35));

       call record_manager_$get_records_and_ids_by_spec
            (specification_ptr, id_list_ptr, work_area_ptr,
            record_cursor_ptr, element_id_list_ptr,
            typed_vector_array_ptr, code);
  where:

         specification_ptr            (Input)
              is   a   pointer   to   a   search_specification   or
              numeric_specification structure.

         id_list_ptr                  (Input)
              is a  pointer to an id_list  structure containing the
              field identifiers of the fields to be returned.

         work_area_ptr                (Input)
              is a  pointer to a  freeing area in  which the output
              typed_vector_array is to be allocated.

         record_cursor_ptr            (Input)
              is  a pointer  to a  record cursor.   The position is
              left unchanged by this operation.

         element_id_list_ptr          (Output)
              is  a pointer  to an  element_id_list structure which
              contains  the  record  identifiers  of  the  selected
              records.

         typed_vector_array_ptr       (Output)
              is a pointer to  a typed_vector_array structure which
              contains the selected records.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$get_records_and_ids_by_interval

       This entry  returns a set  of records and  their identifiers
  that meet a selection criteria based  on three things:  a list of
  record identifiers, a  search_specification, and an interval_list
  structure.

  Usage

       dcl record_manager_$get_records_and_ids_by_interval entry
            (ptr, ptr, ptr, ptr, ptr, fixed bin(35), ptr, ptr, ptr,
            fixed bin(35));

       call record_manager_$get_records_and_ids_by_interval
            (input_element_id_list_ptr, id_list_ptr,
            search_specification_ptr, interval_list_ptr,
            work_area_ptr, typed_vector_array_version,
            record_cursor_ptr, output_element_id_list_ptr,
            typed_vector_array_ptr, code);
  where:

         input_element_id_list_ptr    (Input)
              is   a  pointer   to  an   element_id_list  structure
              containing  the  ids  of  the  records  to  which the
              search_specification and interval are to be applied.

         id_list_ptr                  (Input)
              is a  pointer to an id_list  structure containing the
              field identifiers of the fields to be returned.

         search_specification_ptr     (Input)
              is a pointer to  a search_specification to be applied
              to  the records  listed in  the input_element_id_list
              structure.

         interval_list_ptr            (Input)
              is  a  pointer  to  an  interval_list  structure.  It
              identifies records satisfying  the constraints in the
              and_group which pertain to  the fields present in the
              index.

         work_area_ptr                (Input)
              is a  pointer to a  freeing area in  which the output
              typed_vector_array is to be allocated.

         typed_vector_array_version   (Input)
              is the version of the typed_vector_array structure to
              use.        The        current       version       is
              TYPED_VERSION_ARRAY_VERSION_2.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

         record_cursor_ptr            (Input)
              is  a pointer  to a  record cursor.   The position is
              left unchanged by this operation.

         output_element_id_list_ptr   (Output)
              is  a pointer  to an  element_id_list structure which
              contains  the  record  identifiers  of  the  selected
              records.

         typed_vector_array_ptr       (Output)
              is a pointer to  a typed_vector_array structure which
              contains the selected records.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$get_records_by_id_list

       Gets the desired fields of  all of the records identified by
  the record id list.

  Usage

       dcl record_manager_$get_records_by_id_list entry (ptr, ptr,
            ptr, ptr, ptr, fixed bin(35));

       call record_manager_$get_records_by_id_list
            (element_id_list_ptr, id_list_ptr, work_area_ptr,
            record_cursor_ptr, typed_vector_array_ptr, code);
  where:

         element_id_list_ptr          (Input)
              is  a   pointer  to  an   element_id_list  structure,
              containing the  record identifiers of  each record to
              get.    A  scalar   can  be  provided;   it  will  be
              interpreted as an array of one element.

         id_list_ptr                  (Input)
              is a  pointer to an id_list  structure containing the
              identifiers of the fields to be retrieved.

         work_area_ptr                (Input)
              is a pointer  to a pl1 area defined  by the caller in
              which to place the retrieved records.

         record_cursor_ptr            (Input)
              is a pointer to a record cursor.

         typed_vector_array_ptr       (Output)
              is  a  pointer   to  a  typed_vector_array  structure
              containing the retrieved records.

         code                         (Output)
              is standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$get_records_by_interval

       This entry  retrieves a set  of records identified  by three
  things:   a list  of record  identifiers, a search_specification,
  and an interval_list structure.   Each "interval" of the interval
  list  identifies  a span  of  record identifiers  in the  list of
  record   identifiers  and   one  or  more   and_groups  from  the
  search_specification.   All of  the records in  an interval which
  satisfy  one  or  more  of the  and_groups  associated  with that
  interval  are  returned.   This  entry is  primarily  for  use in
  conjunction with the index_manager_.

  Usage

       dcl record_manager_$get_records_by_interval entry (ptr, ptr,
            ptr, ptr, ptr, fixed bin(35), ptr, ptr, fixed bin(35));

       call record_manager_$get_records_by_interval
            (element_id_list_ptr, id_list_ptr,
            search_specification_ptr, interval_list_ptr,
            work_area_ptr, typed_vector_array_version,
            record_cursor_ptr, typed_vector_array_ptr, code);
  where:

         element_id_list_ptr          (Input)
              is   a  pointer   to  an   element_id_list  structure
              containing  the  ids  of  the  records  to  which the
              search_specification and interval are to be applied.

         id_list_ptr                  (Input)
              is a  pointer to an id_list  structure containing the
              field identifiers of the fields to be returned.

         search_specification_ptr     (Input)
              is a pointer to  a search_specification to be applied
              to   the  records   listed  in   the  element_id_list
              structure.

         interval_list_ptr            (Input)
              is  a  pointer  to  an  interval_list  structure.  It
              identifies records satisfying  the constraints in the
              and_group which pertain to  the fields present in the
              index.

         work_area_ptr                (Input)
              is a  pointer to a  freeing area in  which the output
              typed_vector_array is to be allocated.

         typed_vector_array_version   (Input)

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

              is the version of the typed_vector_array structure to
              use.        The        current       version       is
              TYPED_VERSION_ARRAY_VERSION_2.

         record_cursor_ptr            (Input)
              is  a pointer  to a  record cursor.   The position is
              left unchanged by this operation.

         typed_vector_array_ptr       (Output)
              is a  pointer to a  typed_vector_array which contains
              the results of the search.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$get_records_by_spec

       Gets  the desired  fields of  the records  identified by the
  search specification.

  Usage

       dcl record_manager_$get_records_by_spec entry (ptr, ptr,
            ptr, ptr, ptr, fixed bin(35));

       call record_manager_$get_records_by_spec (specification_ptr,
            id_list_ptr, work_area_ptr, record_cursor_ptr,
            typed_vector_array_ptr, code);
  where:

         specification_ptr            (Input)
              is   a   pointer   to   a   search_specification   or
              numeric_specification structure.

         id_list_ptr                  (Input)
              is  a  pointer  to an  id_list  structure, containing
              identifiers of the fields to be returned.

         work_area_ptr                (Input)
              is a pl1 area defined by the caller, in which storage
              for the retrieved records is allocated.  The area can
              be  of  any type,  but  if the  caller expects  to be
              handling  large amounts  of data, the  area should be
              extensible.   For  efficiency   reasons,  the  caller
              should set  the zero_on_alloc and  zero_on_free flags
              off if dealing with large amounts of data.

         record_cursor_ptr            (Input)
              is  a   pointer  to  a  record   cursor.   After  the
              operation, the  cursor is set to  the position of the
              last record retrieved.

         typed_vector_array_ptr       (Output)
              is a  pointer to a  structure containing an  array of
              pointers  to simple_typed_vector  structures, each of
              which holds  a record value retrieved,  now placed in
              the storage allocated in work_area.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$modify_record_by_id

       Modifies the  fields specified to  have the values  given in
  the general_typed_vector, for the record identified by record_id.

  Usage

       dcl record_manager_$modify_record_by_id entry (bit(36)
            aligned, ptr, ptr, fixed bin(35));

       call record_manager_$modify_record_by_id (record_id,
            general_typed_vector_ptr, record_cursor_ptr, code);
  where:

         record_id                    (Input)
              is the identifier of the record to be modified.

         general_typed_vector_ptr     (Input)
              is  a  pointer  to  a  general_typed_vector structure
              containing  the  new  values  of  the  fields  to  be
              modified.

         record_cursor_ptr            (Input)
              is a pointer to a record cursor.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$modify_records_by_id_list

       Modifies the  specified fields to  have the values  given in
  the  general_typed_vector, for  all of the  records identified by
  the record_id_list.

  Usage

       dcl record_manager_$modify_records_by_id_list entry (ptr,
            ptr, ptr, fixed bin(35), fixed bin(35));

       call record_manager_$modify_records_by_id_list
            (element_id_list_ptr, general_typed_vector_ptr,
            record_cursor_ptr, number_of_records_processed, code);
  where:

         element_id_list_ptr          (Input)
              is  a   pointer  to  an   element_id_list  structure,
              identifying each record to be modified.  A scalar may
              be passed by value rather  than an array, and it will
              be interpreted as an array of one element.

         general_typed_vector_ptr     (Input)
              is a pointer to a general_typed_vector containing the
              new values of the fields to be modified.

         record_cursor_ptr            (Input)
              is  a  pointer to  a  record cursor.   The  cursor is
              positioned to the last record modified.

         number_of_records_processed  (Output)
              is the number of records modified.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$modify_records_by_spec

       Modifies the  specified fields to  have the values  given in
  the  general_typed_vector  structure,  for  all  of  the  records
  identified by the search specification.

  Usage

       dcl record_manager_$modify_records_by_spec entry (ptr, ptr,
            ptr, fixed bin(35), fixed bin(35));

       call record_manager_$modify_records_by_spec
            (specification_ptr, general_typed_vector_ptr,
            record_cursor_ptr, number_of_records_processed, code);
  where:

         specification_ptr            (Input)
              is   a   pointer   to   a   search_specification   or
              numeric_specification structure.

         general_typed_vector_ptr     (Input)
              is  a  pointer to  a  general_typed_vector structure.
              The  dimension   id  identifies  the   fields  to  be
              modified, and the dimension value is the value to set
              the   field   to.   Modifications   must   involve  a
              replacement of the entire field at this time.

         record_cursor_ptr            (Input)
              is  a   pointer  to  a  record   cursor.   After  the
              modification,  the cursor  is set to  the position of
              the last record modified.

         number_of_records_modified   (Output)
              is the number of records which were modified.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$position_cursor

       Sets the value of the cursor to be the given position in the
  specified collection.  If the  specification identifies more than
  one record, the cursor points at the first of these.

  Usage

       dcl record_manager_$position_cursor entry (ptr, ptr, fixed
            bin(35));

       call record_manager_$position_cursor (specification_ptr,
            record_cursor_ptr, code);
  where:

         specification_ptr            (Input)
              is   a   pointer   to   a   search_specification   or
              numeric_specification structure.

         record_cursor_ptr            (Input)
              is a pointer to the record cursor to be positioned.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$put_record_by_id

       Puts a  record into the record  collection.  If possible, it
  is  put  in  the  same control  interval  as  the  related record
  specified by the caller.

  Usage

       dcl record_manager_$put_record_by_id entry (bit(36) aligned,
            ptr, fixed bin(35), ptr, bit(36) aligned, fixed
            bin(35));

       call record_manager_$put_record_by_id (related_record_id,
            simple_typed_vector_ptr, minimum_free_space,
            record_cursor_ptr, record_id, code);
  where:

         related_record_id            (Input)
              is  the  identifier  of  the record  which  is  to be
              previous  to the  record being "put",  referred to as
              the    related    record.     If    the    value   of
              related_record_id  is  "0"b, the  new record  will be
              inserted randomly.

         simple_typed_vector_ptr      (Input)
              is a pointer to a simple_typed_vector structure which
              is used to represent the value of the record.

         minimum_free_space           (Input)
              is the minimum  amount of space in bits  that must be
              left free in the control interval in which the record
              is  put.  Normally  this value  is zero,  meaning the
              control interval can be  packed full.  At times, such
              as during  loading a file or  garbage collecting, the
              caller may wish to leave some space free to allow for
              growth of records and insertion of new records.

         record_cursor_ptr            (Input)
              is  a  pointer  to  a structure  which  maintains the
              current position  in the record  collection.  It also
              contains  the file  opening id  and record collection
              id.   After  the  put  operation, it  is  set  to the
              position of the newly put record.

         record_id                    (Output)
              is the identifier of the record that was put into the
              collection.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$put_records_by_id

       Puts  a  set  of  records into  the  record  collection.  If
  possible,  they  are  put in  the  same control  interval  as the
  related record specified by the caller.

  Usage

       dcl record_manager_$put_records_by_id entry (bit(36)
            aligned, ptr, fixed bin(35), ptr, bit(36) aligned,
            fixed bin(35));

       call record_manager_$put_records_by_id (related_record_id,
            typed_vector_array_ptr, minimum_free_space,
            record_cursor_ptr, element_id_list_ptr, code);
  where:

         related_record_id            (Input)
              is  the  identifier  of  the record  which  is  to be
              previous to  the records being "put",  referred to as
              the related record.  If the records are threaded, the
              related record  is previous to  the first of  the new
              records  in the  chain of records  in the collection,
              and  the  record  manager  will try  to  put  the new
              records in  the same control interval  as the related
              record.  Otherwise,  in either the  following control
              interval or  a newly allocated  control interval.  If
              the  value  of  related_record_id  is  "0"b,  the new
              records will be inserted randomly.

         typed_vector_array_ptr       (Input)
              is a pointer to  a typed_vector_array structure which
              is used to represent the values of the records.

         minimum_free_space           (Input)
              is the minimum  amount of space in bits  that must be
              left  free  in  each  control interval  in  which the
              records  are  put.   Normally  this  value  is  zero,
              meaning the control interval  can be packed full.  At
              times,  such  as  during  loading a  file  or garbage
              collecting, the  caller may wish to  leave some space
              free to allow for growth  of records and insertion of
              new records.

         record_cursor_ptr            (Input)
              is  a  pointer  to  a structure  which  maintains the
              current position  in the record  collection.  It also
              contains  the file  opening id  and record collection
              id.   It is  set to the  position of  the last record

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

              put.

         element_id_list_ptr          (Output)
              is   a  pointer   to  an   element_id_list  structure
              containing the record ids of the newly put records.

         code                         (Output)
              is a standard system status code.

  _______________                                   _______________

  record_manager_                                   record_manager_
  _______________                                   _______________

  Entry:  record_manager_$put_records_by_spec (unimplemented)

       Puts a  given set of  records into the  record collection at
  the location indicated by the specification.

  Usage

       dcl record_manager_$put_records_by_spec (unimplemented)
            entry (ptr, ptr, fixed bin(35), ptr, ptr, fixed
            bin(35));

       call record_manager_$put_records_by_spec (unimplemented)
            (specification_ptr, typed_vector_array_ptr,
            minimum_free_space, record_cursor_ptr,
            element_id_list_ptr, code);
  where:

         specification_ptr            (Input)
              is   a   pointer   to   a   search_specification   or
              numeric_specification structure.

         typed_vector_array_ptr       (Input)
              is  a  pointer  to  a  typed_vector_array  structure,
              containing     an     array     of     pointers    to
              simple_typed_vectors  which  are  used  to  represent
              record values.

         minimum_free_space           (Input)
              is the minimum amount of free space in bits that must
              be left in each control interval in which records are
              put.

         record_cursor_ptr            (Input)
              is  a  pointer  to  a structure  which  maintains the
              current position  in the record  collection.  It also
              contains  the file  opening id  and record collection
              id.   After  the  put  operation, it  is  set  to the
              position of  the newly put record.   If more than one
              record is put, it is set  to the position of the last
              record.

         element_id_list_ptr          (Output)
              is  a   pointer  to  an   element_id_list  structure,
              containing an  array of identifiers of  the newly put
              records.

         code                         (Output)
              is a standard system status code.



                Appendix A - Specification Structures

  The specification_head structure

  The  following  structure  is  used in  specifying  keys.   It is
  declared in the dm_specification_head.incl.pl1 include file:

       dcl 1 specification_head         based (sh_ptr) aligned,
             2 version                  fixed bin(35),
             2 type                     fixed bin(17) unal,
             2 pad                      bit(18) unal,
             2 subset_specification_ptr ptr;

  where:

         version
              is the version of the structure.  The current version
              is a static variable named SPECIFICATION_VERSION_4.

         type
              is  the type  of the  specification.  There  are four
              types    for   record_manager_;    absolute   numeric
              positioning,  relative numeric  positioning, absolute
              (from the  "root") searching, and  relative (from the
              current  position indicated  by a  cursor) searching.
              These       constants       are       defined      in
              dm_specification_head.incl.pl1.

         pad
              must be "0"b.

         subset_specification_ptr
              is  a  pointer to  a  subset_specification structure.
              This structure is used  to constrain selected keys to
              either be members of a subset  or not be members of a
              subset.   (See  below for  the documentation  of this
              structure.)
      Any of  the following structures  can be used  for specifying
  positions, each of which use specification_head as a header.

  The subset_specification structure

      Following  is  the structure  to  specify subset  indices and
  their  relation to  a specification of  keys.  It  is declared in
  dm_subset_specification.incl.pl1.



       dcl 1 subset_specification based (subset_specification_ptr),
             2 version            char (8),
             2 number_of_subsets  fixed bin,
             2 subset             (ss_number_of_subsets refer
                                  (subset_specification
                                   .number_of_subsets)),
                3 id_list_ptr      ptr,
                3 is_member        bit(1) unaligned,
                3 pad              bit(35) unaligned,
                3 cursor_ptr       ptr;

  where:

         version
              is  the  version of  the  structure.  The  version is
              given    by    the     internal    static    constant
              SUBSET_SPECIFICATION_VERSION_1.

         number_of_subsets
              is  the  number  of  subsets  used  in  defining  the
              specification.  Subsets may be used in either numeric
              or value, and absolute or relative positioning.

         subset.id_list_ptr
              is a pointer to a id_list structure which defines the
              relationship of the fields of the subset index to the
              index   being   searched.    id_list.id(I)   is   the
              identifier of  the field in the  index being searched
              which is associated with the I'th field of the subset
              index.

         subset.is_member
              if on,  indicates that keys  which this specification
              identifies  must  be  found  in this  subset.   For a
              subset to have a (source  index) key as a member, the
              subset index must contain as  a key the data which is
              found  in  the attendant  data  fields of  the source
              index  key.   This  is  a special  case  of  the more
              general  subset "membership"  definition which allows
              the caller to  define the way in which  data from the
              source index  is to match  data in the  subset index.
              This special case is useful for the relation manager.

         subset.pad
              must be "0"b.

         subset.cursor_ptr
              is a pointer to a cursor for the subset index.



  The search_specification structure

       This  structure  is  used  when   a  search  for  keys  with
  particular   values   is  to   be  done.    It  is   declared  in
  dm_specification.incl.pl1.

       dcl 1 search_specification    based (ss_ptr),
             2 head                  like specification_head,
             2 maximum_number_of_constraints,
                                     fixed bin(17) unal,
             2 range,                unal,

            3 type                   fixed bin(17),
               3 size                fixed bin(17),
             2 number_of_and_groups  fixed bin(17) unal,
             2 and_group             (ss_number_of_and_groups refer
                                     (search_specification
                                      .number_of_and_groups)),
             2 number_of_constraints fixed bin(17) unal,
               3 constraint          (ss_maximum_number_of_constraints
                                     (refer search_specification
                                      .maximum_number_of_constraints)),
                 4 field_id          fixed bin(17) unal,
                 4 operator_code     fixed bin(17) unal,
                 4 value_field_id    fixed bin(17) unal,
                 4 pad               bit(18) unal,
                 4 value_ptr         ptr unal;

  where:

         maximum_number_of_constraints
              is the number of field specifications to be allocated
              for each and_group.

         range.type
              is the type of range of the specified keys desired:
                 0 - all
                 1 - top
                 2 - bottom
              Constants   for   these   values   are   defined   in
              dm_range_constants.incl.pl1.

         range.size
              is the size  of the range.  If the  type is "all" (or
              0), then the  size is ignored.  If the  type is "top"
              and the value  of size is N, then  the highest N keys
              of the  keys selected are  returned.  In the  case of
              "bottom", the lowest N keys  of the keys selected are
              returned.

         number_of_and_groups
              is   the   number   of   and_groups   used   in   the
              search_specification.  The elements satisfied by each



              and_group are joined by  union to obtain the complete
              set to satisfy the search_specification.

         and_group.number_of_constraints
              is the number of constraints actually in use for this
              and_group.  Each constraint of  the and_group must be
              satisfied in order  for an element to be  a member of
              the and_group.

         and_group.constraint.field_id
              is the id for the field being constrained.

         and_group.constraint.operator_code
              is  the relationship  the value  of the  desired keys
              must have to the  value specified in this constraint.
              The operator codes can be  dealt with as either fixed
              binary  number  or as  a  bit string  (which  must be
              converted to a fixed binary number).  When considered
              as a  bit string the  meaning of the  bits are "or"ed
              together.    The  right-most   bits  are   given  the
              following meaning:

                 "00001"b - = (equals)
                 "00010"b - > (greater than)
                 "00100"b - ^ (not)
                 "01000"b - regular expression match
                 "10000"b - field may be absent.

              An "absent" field always compares to false for any of
              the other  four comparisons.  If  this bit is  on, an
              "absent"  field will  compare "true"  and a "present"
              field will compare false.

              Some combinations of operators "bits" are not defined
              to have any meaning, e.g.  "regular expression match"
              or'ed with  "greater than".  The  complete definition
              of the meanings  of all of the combinations  of the 5
              right-most operator bits follows:

                 1 - "00001"b - =
                 2 - "00010"b - >
                 3 - "00011"b - >=
                 4 - "00100"b - ^
                 5 - "00101"b - ^= (><)
                 6 - "00110"b - ^> (<=)
                 7 - "00111"b - ^>= (<)
                 8 - "01000"b - regular expression match
                 9 through 15 - undefined
                 16 - "10000"b - field is absent from key
                 17 - "10001"b - field is absent or =
                 18 - "10010"b - field is absent or >
                 19 - "10011"b - field is absent or >=
                 20 - "10100"b - field is not absent



                 21 - "10101"b - field is absent or ^> (<=)
                 22 - "10110"b - field is absent or  ^=
                 23 - "10111"b - undefined
                 24 - "11000"b - if field is present, regular expression match
                 25 through 31 - undefined

         and_group.constraint.value_field_id
              specifies intra-key/record compares.

         and_group.constraint.pad
              must be "0"b.

         and_group.constraint.value_ptr
              is  a pointer  to the value  to be  compared with the
              values in the database.   The value must be allocated
              according to the DM data types.

  The numeric_specification structure

       This  structure  is  used  when a  search  for  keys  with a
  particular  numeric position  is to be  done.  It  is declared in
  dm_specification.incl.pl1.

       dcl 1 numeric_specification based (nss_ptr),
             2 head                like specification_head,
             2 range_size          fixed bin(35) aligned,
             2 position_number     fixed bin(17) unal,
             2 pad                 bit(18) unal;

  where:

         range_size
              is the  number of keys  to be returned  including the
              key  identified  by position_number,  below.   If the
              range_size  is negative,  it indicates  that the keys
              desired  precede   the  specified  key.    If  it  is
              positive,  the keys  are to  be the  ones immediately
              following the specified key.

         position_number
              is interpreted according to  the absolute or relative
              nature of the specification.   If absolute, it is the
              position_number'th  key  of  the index  to  which the
              position is  moved.  If position_number  is negative,
              the keys  are counted backwards  from the end  of the
              index  for position_number  keys.  If position_number
              is  positive, the  keys are counted  forward from the
              beginning of the index.  If  the type is relative, it
              is  the  position_number'th   key  from  the  current
              position  to   which  the  position   is  moved.   If
              position_number  is negative,  the position  is moved
              backwards  from  the  current   position;  if  it  is



              positive,  it  is  moved  forwards  from  the current
              position.

              If position_number moves the cursor beyond the index,
              i.e.  it is  either too large or too  small, then the
              cursor is moved to the  beginning or end of the index
              as appropriate and error_table_$beginning_of_index or
              error_table_$end_of_index is returned.

         pad
              must be "0"b.



                 Appendix B - Information Structures

  The typed_vector structure

       There   are   two   formats   for   the   typed_vector,  the
  simple_typed_vector  and  the   general_typed_vector.   Both  are
  defined in vu_typed_vector.incl.pl1.   In the simple_typed_vector
  there is  only a pointer  for each dimension  value, no dimension
  identifier  is  provided.   It  can  be  used  when  all  of  the
  dimensions   in   a   typed_vector_array  are   present   in  the
  typed_vector.  The dimensions would be assumed to be in the order
  defined by the dimension_table of the typed_vector_array.

       In  the  general_typed_vector,  any  subset  of  the defined
  dimensions  may  be  present, hence  the  dimension.identifier is
  required.

       dcl 1 simple_typed_vector    based (simple_typed_vector_ptr),
             2 type                 fixed bin (17) unal,
             2 number_of_dimensions fixed bin (17) unal,
             2 dimension            (stv_number_of_dimensions refer
                                    (simple_typed_vector
                                    .number_of_dimensions)),
               3 value_ptr          ptr unal;

       dcl 1 general_typed_vector   based (general_typed_vector_ptr),
             2 type                 fixed bin (17) unal,
             2 number_of_dimensions fixed bin (17) unal,
             2 dimension            (gtv_number_of_dimensions refer
                                    (general_typed_vector
                                    .number_of_dimensions)),
               3 identifier         fixed bin (17) unal,
               3 pad                bit (18) unal,
               3 value_ptr          ptr unal;

  where:

         type
              indicates  the  type  of  the  vector  structure.   2
              indicates  the  general_typed_vector and  3 indicates
              the simple_typed_vector structure.

         number_of_dimensions
              is the number of dimensions present in the vector.

         dimension.identifier
              is   the   index  in   the  dimension_table   of  the
              typed_vector_array of the dimension.

         dimension.pad
              must be "0"b.



         dimension.value_ptr
              is a pointer to the value of the dimension.

  The typed_vector_array structure

       The         typed_vector_array         structure         (in
  vu_typed_vector_array.incl.pl1) is:

       dcl 1 typed_vector_array       based (typed_vector_array_ptr)
                                      aligned,
             2 version                fixed bin (35),
             2 number_of_dimensions   fixed bin (17),
             2 number_of_vectors      fixed bin (17),
             2 number_of_vector_slots fixed bin (17),
             2 maximum_dimension_name_length
                                      fixed bin (17),
             2 dimension_table        (tva_number_of_dimensions
                                      refer (typed_vector_array
                                      .number_of_dimensions)),
               3 name                 char (
                                      tva_maximum_dimension_name_length
                                      refer (typed_vector_array
                                      .maximum_dimension_name_length))
                                      varying,
               3 descriptor_ptr       ptr,
               3 cv_to_print          entry (ptr, ptr, ptr, fixed bin(35),
                                      char(*) varying, fixed bin(35)),
               3 cv_to_typed          entry (ptr, ptr, ptr, ptr,
                                      fixed bin(35)),
             2 vector_slot            (tva_number_of_vector_slots
                                      refer (typed_vector_array
                                      .number_of_vector_slots)) ptr;

  where:

         version
              is   the   version  of   this   structure,  currently
              TYPED_VECTOR_ARRAY_VERSION_2.

         number_of_dimensions
              is the number of dimensions in the dimension table.

         maximum_dimension_name_length
              is the maximum length of  any of the dimensions named
              in the dimension table.

         number_of_vectors
              is the number of vector  slots actually used to point
              at vectors.

         number_of_vector_slots
              is the number of vector slots allocated.



         dimension_table.name
              is the name of the dimension.

         dimension_table.descriptor_ptr
              is   a   pointer  to   standard  Multics   data  type
              descriptor.

         dimension_table.cv_to_print
              is an entry for converting  from typed format data to
              print format.

         dimension_table.cv_to_typed
              is an entry for converting  from print format data to
              typed.

         vector_slot
              is a pointer to a typed_vector structure.

  The element_id_list structure

       Contains  an array  of "bit(36)  aligned" identifiers  to be
  used  as record  ids, tuple  ids, key  ids, or  element ids.  Its
  declaration    follows,    and    it     can    be    found    in
  dm_element_id_list.incl.pl1.

       dcl 1 element_id_list    aligned based (element_id_list_ptr),
             2 version          fixed bin(35),
             2 number_of_ids    fixed bin(17),
             2 id               (eil_number_of_ids refer
                                (element_id_list.number_of_ids))
                                bit(36) aligned;
  where:

         version
              is   the   version   of   the   structure,  currently
              ELEMENT_ID_LIST_VERSION_1.

         number_of_ids
              is the number of identifiers.

         id
              is an array of element identifiers.

  The id_list structure

       The id_list  structure contains an array  of "fixed bin(17)"
  identifiers,  which are  used to identify  attributes and fields.
  The declaration follows, and it is found in dm_id_list.incl.pl1.



       dcl 1 id_list          aligned based (id_list_ptr),
             2 version        fixed bin(35),
             2 number_of_ids  fixed bin(17),
             2 id             (il_number_of_ids refer
                              (id_list.number_of_ids))
                              fixed bin(17);

  where:

         version
              is the version of the structure, ID_LIST_VERSION_1.

         number_of_ids
              is the number of identifiers.

         id
              is  an   array  of  identifiers,   used  to  identify
              attributes and fields.

  The interval_list structure

       The      interval_list      structure,      declared      in
  dm_interval_list.incl.pl1,   is  used   in  conjunction   with  a
  search_specification  to identify  partially processed and_groups
  with which records were found to satisfy those constraints in the
  and_group  which  pertain to  the  fields present  in  the index.
  Constraints for  fields not present  in the index  have field_ids
  less than zero.

       dcl 1 interval_list             based (interval_list_ptr),
             2 version                 fixed bin(35),
             2 number_of_intervals     fixed bin(17) unal,
             2 pad                     bit(18) unal,
             2 interval                (intl_number_of_intervals
                                       refer (interval_list
                                       .number_of_intervals)),
               3 low_vector_idx        fixed bin(35),
               3 high_vector_idx       fixed bin(35),
               3 and_group_id_list_ptr ptr;

  where:

         version
              is   the  current   version.   It  must   be  set  to
              INTERVAL_LIST_VERSION_1.

         number_of_intervals
              is the number of intervals  in the interval list.  It
              is set by the refer option at allocation time.

         pad
              must be "0"b.



         interval.low_vector_idx
              is the  index into the  associated typed_vector_array
              of the first record of the interval.

         interval.high_vector_idx
              is the  index into the  associated typed_vector_array
              of the last record of the interval.

         and_group_id_list_ptr
              is  a pointer  to an id_list  structure (declared int
              dm_id_list.incl.pl1) which contains a  list of ids of
              the  and_groups  to be  applied  to this  interval of
              records.   These and_group  ids are  indices into the
              and_group      array      of      the      associated
              search_specification.