-- File DBModelSystemImpl.mesa
-- Contents: Initialization of and operations on system tuples
-- Last modified by:
--  Eric Bier on: 18-Aug-81 14:48:57
--  Rick Cattell on: April 12, 1983 10:33 am
--  Willie-Sue on June 25, 1982 9:26 am


DIRECTORY
  DBStorage,
  DBTuplesConcrete,
  DBEnvironment,
  DB,
  DBModel,
  DBModelPrivate,
  Inline USING [LowHalf],
  Rope USING [ROPE, Concat];


DBModelSystemImpl: CEDAR PROGRAM
  IMPORTS DBStorage, DBModel, DBModelPrivate, Inline, Rope
  EXPORTS DB, DBModelPrivate, DBEnvironment =
   
BEGIN OPEN DBStorage, DB, DBModelPrivate, DBModel; 

ROPE: TYPE = Rope.ROPE;


-- Error and Fatal signals, exported to both DB and DBEnvironment:

Error: PUBLIC SIGNAL[code: DBEnvironment.ErrorCode] = CODE; 

Aborted: PUBLIC ERROR [trans: REF ANY] = CODE; 

Fatal: PUBLIC ERROR[code: DBEnvironment.FatalCode] = CODE;

InternalError: PUBLIC SIGNAL = CODE; 


-- Opaque type objects: exported (from DBTuplesConcrete) to DBModel

TupleObject: PUBLIC TYPE = DBTuplesConcrete.TupleObject;
EntityObject: PUBLIC TYPE = TupleObject;
RelshipObject: PUBLIC TYPE = TupleObject;

EntitySetObject: PUBLIC TYPE = DBTuplesConcrete.EntitySetObject;
RelshipSetObject: PUBLIC TYPE = DBTuplesConcrete.RelshipSetObject;

-- REFS to opaque type objects

Tuple, TupleSet, Index, IndexFactor: TYPE = REF TupleObject;
Domain, Relation, Entity, Attribute, Property, DataType: PUBLIC TYPE = REF EntityObject;
Relship: PUBLIC TYPE = REF RelshipObject;

EntitySet: PUBLIC TYPE = REF EntitySetObject;
RelshipSet: PUBLIC TYPE = REF RelshipSetObject;

SystemATuple: TYPE = REF attribute TupleObject;
SystemTSTuple: TYPE = REF tupleSet TupleObject;
SystemETuple: TYPE = REF entity TupleObject;

T2SAT: PROC[t: TupleHandle] RETURNS [SystemATuple] =
  BEGIN RETURN [NARROW[t]] END;
  
T2STT: PROC[t: TupleHandle] RETURNS [SystemTSTuple] =
  INLINE BEGIN RETURN [NARROW[t]] END;
  
T2SET: PROC[t: TupleHandle] RETURNS [SystemETuple] =
  INLINE BEGIN RETURN [NARROW[t]] END;


-- Value Types

AnyDomainType,
BoolType,
IntType,
RecordType,
TimeType,
StringType: PUBLIC DataType;


-- The System tuple abstraction
  
systemTupleVec: PUBLIC REF STSVecType ← NEW[STSVecType← ALL[NIL]];
attributeIDCount: LONG CARDINAL← 0;
  -- used in DefineSystemTupleSet and DefineSystemAttribute.
  
-- The system-defined domains, relations, and attributes: grouped by domains

-- Items declared to be Properties are attributes with no relation; we don't need the relation
-- because it is an internal private binary surrogate relation.  The [binary] relations that the 
-- client may access require both attributes and the relation entity itself, so that the client
-- may perform RelationSubset and do a GetP in both directions.

DomainDomain: PUBLIC Domain; -- one element per client-defined domain
  
  dHandleProp: PUBLIC Property;  -- the storage level tupleset handle
  dIndexProp: PUBLIC Property;  -- the storage level index handle for this domain

  dSubType: PUBLIC Relation; -- one element per direct sub-super type relationship
    dSubTypeOf: PUBLIC Attribute; -- domain: the super-type
    dSubTypeIs: PUBLIC Attribute; -- domain: the sub-type

RelationDomain: PUBLIC Domain; -- one element per client-defined relation
  
  rHandleProp: PUBLIC Property;  -- the storage level tupleset handle
  r1to1Prop: PUBLIC Property;  -- TRUE iff this relation is a surrogate relation

AttributeDomain: PUBLIC Domain; -- one element per client-defined attribute

  aHandleProp: PUBLIC Property;  -- the storage level handle for this field
  aTypeCodeProp: PUBLIC Property;  -- tid of the type entity, or zero if domain-valued
  aTypeEntityProp: PUBLIC Property;  -- the domain this attribute refs, or NIL if datum-valued
  
  aRelation: PUBLIC Relation; -- one element per client-defined attribute
    aRelationOf: PUBLIC Attribute; -- the attribute
    aRelationIs: PUBLIC Attribute; -- relation of the attribute

  aType: PUBLIC Relation; -- one element per client-defined attribute
    aTypeOf: PUBLIC Attribute; -- the attribute
    aTypeIs: PUBLIC Attribute; -- domain or datatype of the attribute

  aUniqueness: PUBLIC Relation; -- one element per client-defined attribute
    aUniquenessOf: PUBLIC Attribute; -- the attribute
    aUniquenessIs: PUBLIC Attribute; -- INT corresponding to its uniqueness

  aLength: PUBLIC Relation; -- one element per client-defined attribute
    aLengthOf: PUBLIC Attribute; -- the attribute
    aLengthIs: PUBLIC Attribute;  -- INT corresponding to attribute's length

  aLink: PUBLIC Relation; -- one element per client-defined attribute
    aLinkOf: PUBLIC Attribute; -- the attribute
    aLinkIs: PUBLIC Attribute;  -- INT corresponding to its LinkType.

  aDomain: PUBLIC Relation; -- exported to DBModelPrivate: one elt per client-defined attribute
    aDomainOf: PUBLIC Attribute; -- the attribute
    aDomainIs: PUBLIC Attribute;  -- non-NIL only if this is the first (targetted) attribute of
                                         -- a surrogate relation, equals domain where actually
                                         -- stored (i.e., equals aTypeEntityProp when non-NIL)

  aUnlinked: PUBLIC Relation; -- exported to DBModelPrivate: one elt per client-defined attribute
    aUnlinkedOf: PUBLIC Attribute; -- the attribute
    aUnlinkedIs: PUBLIC Attribute;  -- non-NIL only if this attribute is NOT linked, in which
                                         -- case it equals aTypeProp (i.e., the domain referenced)

DataTypeDomain: PUBLIC Domain;  -- StringType, BoolType, etc. are of this domain

IndexDomain: PUBLIC Domain;  -- one element per client-defined index
  iHandleProp: PUBLIC Property;  -- index handle, set by storage level

IndexFactorDomain: PUBLIC Domain;  -- one element per attribute in an index

  ifIndex: PUBLIC Relation;  -- one element per attribute in an index (an "index factor")
    ifIndexOf: PUBLIC Attribute;  -- the index factor
    ifIndexIs: PUBLIC Attribute;  -- the index this index factor belongs to

  ifOrdinalPosition: PUBLIC Relation; -- one element per index factor
    ifOrdinalPositionOf: PUBLIC Attribute;  -- the index factor
    ifOrdinalPositionIs: PUBLIC Attribute;  -- the position of this index factor in the ordering

  ifAttribute: PUBLIC Relation; -- one element per index factor
    ifAttributeOf: PUBLIC Attribute;  -- the index factor
    ifAttributeIs: PUBLIC Attribute;  -- the attribute this index factor indexes


-- Other global variables, exported to DBModelPrivate:

defaultDomainIndex, defaultRelationIndex: PUBLIC DBStorage.IndexHandle;
defaultNameHandle, attributeNameHandle, tupleSetNameHandle: PUBLIC DBStorage.FieldHandle;
defaultNameAttribute: PUBLIC Attribute;

DefaultNameSize: CARDINAL = 20;

-- The following shouldn't go into DB because they might get used before initialized
minfString: PUBLIC ROPE ← ""; -- less than any other string
infString: PUBLIC ROPE ← "\177"; -- greater than any other string



InitializeSystemTuples: PUBLIC PROC = TRUSTED
  BEGIN dNameProp, rNameProp, aNameProp: Domain; -- only need temporarily
  
   DBStorage.SetSystemTupleTable[systemTupleVec];
  
   -- Define the system domains
   DomainDomain← DefineSystemDomain[DomainTSID, "Domain"];
   RelationDomain← DefineSystemDomain[RelationTSID, "Relation"];
   AttributeDomain← DefineSystemDomain[AttributeTSID, "Attribute"];
   DataTypeDomain← DefineSystemDomain[DataTypeTSID, "DataType"];
   IndexDomain← DefineSystemDomain[IndexTSID, "Index"];
   IndexFactorDomain← DefineSystemDomain[IndexFactorTSID, "IndexFactor"];

   -- Define the DataType entities
   StringType← DefineSystemEntity[StringTypeID, DataTypeDomain, "StringType"];
   IntType← DefineSystemEntity[IntTypeID, DataTypeDomain, "IntType"];
   TimeType← DefineSystemEntity[TimeTypeID, DataTypeDomain, "TimeType"];
   BoolType← DefineSystemEntity[BoolTypeID, DataTypeDomain, "BoolType"];
   RecordType← DefineSystemEntity[RecordTypeID, DataTypeDomain, "RecordType"];
   AnyDomainType← DefineSystemEntity[AnyDomainTypeID, DataTypeDomain, "AnyDomainType"];

   FakeTheNameHandle[]; -- must call after StringType defined but before any real entities

   -- Define (private) properties of domain, relation, attribute, and index entities

   dHandleProp← DefinePrivateProperty[
     DomainDomain, "dHandleProp", RecordType, DBStorage.TuplesetObjectSize];
     -- dHandle must be first field for proper storage level operation!
   dNameProp← DefinePrivateProperty[DomainDomain, "dName", StringType, DefaultNameSize];
     tupleSetNameHandle← T2SAT[dNameProp].vHandle;
   dIndexProp← DefinePrivateProperty[DomainDomain, "dIndexProp", IndexDomain];

   rHandleProp← DefinePrivateProperty[
     RelationDomain, "rHandleProp", RecordType, DBStorage.TuplesetObjectSize];
     -- rHandle must be first field for proper DBStorage operation!
   rNameProp← DefinePrivateProperty[
     RelationDomain, "rNameProp", StringType, DefaultNameSize];
     -- don't need handle because assume identical pos&size as tupleChangeNameHandle above
   r1to1Prop← DefinePrivateProperty[RelationDomain, "r1to1", BoolType];
 
   aHandleProp← DefinePrivateProperty[
     AttributeDomain, "aHandleProp", RecordType, DBStorage.FieldObjectSize];
     -- handle need not be first field, but make it that way anyway like other system tuples 
   aNameProp← DefinePrivateProperty[AttributeDomain, "aName", StringType];
   attributeNameHandle← T2SAT[aNameProp].vHandle;
   aTypeCodeProp← DefinePrivateProperty[
     AttributeDomain, "aTypeCodeProp", IntType];
   aTypeEntityProp← DefinePrivateProperty[
     AttributeDomain, "aTypeEntityProp", DomainDomain];

   iHandleProp← DefinePrivateProperty[
     IndexDomain, "iHandleProp", RecordType, DBStorage.IndexObjectSize];
     -- iHandle must be first field of Index entity for proper DBStorage operation!

   -- Define the system relations and their attributes
   
   FakeTheTypeAndLinkRelations[];
   [aRelation, aRelationOf, aRelationIs]← DefineSystemBinary[
     id: aRelationTSID, name: "aRelation", of: AttributeDomain, is: RelationDomain];
   [aUniqueness, aUniquenessOf, aUniquenessIs]← DefineSystemBinary[
     id: aUniquenessTSID, name: "aUniqueness", of: AttributeDomain, is: IntType];
   [aLength, aLengthOf, aLengthIs]← DefineSystemBinary[
     id: aLengthTSID, name: "aLength", of: AttributeDomain, is: IntType];
   [aDomain, aDomainOf, aDomainIs]← DefineSystemBinary[
     id: aDomainTSID, name: "aDomain", of: AttributeDomain, is: DomainDomain];
   [aUnlinked, aUnlinkedOf, aUnlinkedIs]← DefineSystemBinary[
     id: aUnlinkedTSID, name: "aUnlinked", of: AttributeDomain, is: DomainDomain];
   [ifIndex, ifIndexOf, ifIndexIs]← DefineSystemBinary[
     id: ifIndexTSID, name: "ifIndex", of: IndexFactorDomain, is: IndexDomain];
   [ifOrdinalPosition, ifOrdinalPositionOf, ifOrdinalPositionIs]← DefineSystemBinary[
     id: ifOrdinalPositionTSID, name: "ifOrdinalPosition", of: IndexFactorDomain, is: IntType];
   [ifAttribute, ifAttributeOf, ifAttributeIs]← DefineSystemBinary[
     id: ifAttributeTSID, name: "ifAttribute", of: IndexFactorDomain, is: AttributeDomain];
   [dSubType, dSubTypeOf, dSubTypeIs]← DefineSystemBinary[
     id: dSubTypeTSID, name: "dSubType", of: DomainDomain, is: DomainDomain, is1to1: FALSE];

  END;

FakeTheNameHandle: PROC =
  -- Sets up fake relation so that defaultNameHandle will work.
  -- Must be called after StringType defined. 
  BEGIN
  fakeReln: TupleSet← DefineSystemTupleSet[DummyID, "fakeReln", FALSE, FALSE];
  defaultNameAttribute← DefineSystemField[fakeReln, "defaultNameAttribute", StringType];
  defaultNameHandle← T2SAT[defaultNameAttribute].vHandle;
  END;

FakeTheTypeAndLinkRelations: PROC =
  -- The aType and aLink relations are tricky, to achieve better performance than the
  -- obvious implementation.  They are actually defined on two underlying properties,
  -- the aTypeCodeProp and the aTypeEntityProp, which are surrogate attributes of the
  -- attribute entities.  When we do operations on aType or aLink, we must trap them,
  -- interpreting aTypeCodeProp and aTypeEntityProp as follows:
  --  (1) If aTypeEntityProp=NIL, then we have a non-entity-valued attribute, and the
  --      aTypeCodeProp is the tid of the system DataType entity (e.g., StringType, IntType).
  --  (2) If aTypeEntityProp#NIL, then it references the domain that is the type of the
  --      attribute, and aTypeCodeProp= 0 or -1 depending on whether it is linked or not linked. 
  -- Operations fetching or setting aType and aLink are trapped in the low-level procedures
  -- GetValFromHandle and SetValFromHandle, so that they do not need to be checked
  -- separately in GetF, SurrogateGetF, GetP, SetF, etc.  The low level procedures have
  -- only the handle for the attribute available, not the attribute itself; they thus must
  -- do equality comparison to the aTypeIs.vHandle or aLinkIs.vHandle; so the handle is needed
  -- merely for its unique pointer value, not for the DBStorage.FieldHandleObject it points to. 
  BEGIN
  aType← DefineSystemTupleSet[
    id: aTypeTSID, name: "aType", isDomain: FALSE, is1to1: TRUE];
  aTypeOf← DefineSystemFieldObject[aType, "aTypeOf", AttributeDomain];
  aTypeIs← DefineSystemField[aType, "aTypeIs", DataTypeDomain];
  T2SAT[aTypeIs].vHandle← T2SAT[aTypeEntityProp].vHandle; -- so group scans work on type
  T2SAT[aTypeOf].vRelation← T2SAT[aTypeIs].vRelation← aType;
  T2STT[aType].vAttributes← LIST[aTypeOf, aTypeIs];
  aLink← DefineSystemTupleSet[
    id: aLinkTSID, name: "aLink", isDomain: FALSE, is1to1: TRUE];
  aLinkOf← DefineSystemFieldObject[aLink, "aLinkOf", AttributeDomain];
  aLinkIs← DefineSystemField[aLink, "aLinkIs", IntType];
  T2STT[aLink].vAttributes← LIST[aLinkOf, aLinkIs];
  T2SAT[aLinkOf].vRelation← T2SAT[aLinkIs].vRelation← aLink;
  END;
    
DefineSystemDomain: PROC [id: LONG CARDINAL, name: ROPE] RETURNS [Domain] =
  INLINE {RETURN[DefineSystemTupleSet[id, name, TRUE, FALSE]]};

DefineSystemBinary: PROC [
  id: LONG CARDINAL, name: ROPE, of: DataType, is: DataType, is1to1: BOOL← TRUE]
  RETURNS [r: Relation, rOf, rIs: Attribute] =
  -- Defines a binary system relation and attributes with types specified by of and is.
  -- The system relation entity is given the tuple id specified, and attributes are allocated ids.
  -- The attributes types are "of" and "is" respectively.  The relation is given the specified name,
  -- and the attributes are given the specified name postfixed by the strings "Of" and "Is".
  -- If is1to1=TRUE, then relation is a "surrogate" relation, and the values are actually stored
  -- as fields of the domain type of "of".
  BEGIN
  r← DefineSystemTupleSet[id, name, FALSE, is1to1];
  IF is1to1 THEN
    -- The "is" attribute is actually a field of of's domain, not of the relation
    BEGIN
    rOf← DefineSystemFieldObject[of, Rope.Concat[name, "Of"], of];
    rIs← DefineSystemField[of, Rope.Concat[name, "Is"], is, DefaultNameLength];
    END
  ELSE
    -- Normal attributes: fields of r.
    BEGIN
    rOf← DefineSystemField[r, Rope.Concat[name, "Of"], of];
    rIs← DefineSystemField[r, Rope.Concat[name, "Is"], is, DefaultNameLength];
    END;
  T2STT[r].vAttributes← LIST[rOf, rIs];
  T2SAT[rOf].vRelation← T2SAT[rIs].vRelation← r;
  END;

DefineSystemTupleSet: PROC[id: LONG CARDINAL, name: ROPE, isDomain: BOOL, is1to1: BOOL] RETURNS[TupleSet] = TRUSTED
  -- Defines a system domain or relation, according to the value of isDomain.  
  BEGIN t: SystemTSTuple;
  IF id>MaxVTID THEN ERROR InternalError;
  t← T2STT[DBStorage.ConsSystemTupleObject[tupleSet]];
  t.tid← id;
  t.vTuple← DBStorage.CreateSystemTupleset[id]; -- SLevel tuple representing this abstraction
  t.vName← name;    -- name of this tupleset.
  t.vR1to1← is1to1;
  t.vIsDomain← isDomain;
  systemTupleVec[Inline.LowHalf[id]]← t;
  RETURN[t]
  END;
  
DefineSystemField: PROC[
  ts: TupleSet, name: ROPE, type: DataType, length: CARDINAL← 0] RETURNS[Attribute] = TRUSTED
  -- Used as a subroutine to DefineSystemBinary and DefinePrivateProperty, to define a
  -- field of domain or relation ts with the given name, type, and length if applicable.
  BEGIN
  f: Attribute← DefineSystemFieldObject[ts, name, type];
  -- add a field to ts to hold values of this type:
  T2SAT[f].vHandle← DBStorage.AddSystemField[T2STT[ts].vTuple, MakeFD[type, length,, f]];
  RETURN[f]
  END;

DefineSystemFieldObject: PROC[
  ts: TupleSet, name: ROPE, type: DataType] RETURNS[Attribute] = TRUSTED
  -- Used as a subroutine to DefineSystemField and DefineSystemBinary.
  -- Defines the storage level object for a system field, though doesn't actually create the field.
  BEGIN
  t: SystemATuple← T2SAT[DBStorage.ConsSystemTupleObject[attribute]];
  t.tid← FirstAttributeID + attributeIDCount;
  t.vType← type; -- what type this attribute can point to
  t.vName← name; -- attribute name
  attributeIDCount← attributeIDCount+1;
  IF FirstAttributeID+attributeIDCount>MaxVTID THEN SIGNAL InternalError;
  systemTupleVec[Inline.LowHalf[attributeIDCount+FirstAttributeID-1]]← t;
  RETURN[t]
  END;
 
DefineSystemEntity: PROC[
  id: LONG CARDINAL, d: Domain, name: ROPE] RETURNS [Entity] = TRUSTED
  -- Use only for DataTypes; creates a system entity object.
  BEGIN
  e: SystemETuple← T2SET[DBStorage.ConsSystemTupleObject[entity]];
  e.tid← id;
  e.vName← name;
  e.vParent← d;
  systemTupleVec[Inline.LowHalf[id]]← e;
  RETURN[e]
  END;
    
DefinePrivateProperty: PROC [
  d: Domain, name: ROPE, type: DataType, length: INT← 0] RETURNS [Property] =
  -- Adds an "invisible" new system relation which is actually a surrogate relation stored
  -- as a field of the domain d.  We use this instead of DefineSystemBinary when the client
  -- doesn't actually need access to the relation, so we can just define the field alone.
  -- This proc turns out to be implemented by calling DefineSystemField, but is logically
  -- quite different since we are defining an "attribute" of a domain, not a relation.  We fake
  -- the call by pretending the domain is a relation (they are both TupleSets, the same type).
  -- We add the fake attribute to the vAttributes list on the domain, so it can be used to
  -- optimize SafeGetP and other operations.
  BEGIN fakeAttribute: Attribute;
  fakeAttribute← DefineSystemField[d, name, type, length];
  T2STT[d].vAttributes← CONS[fakeAttribute, T2STT[d].vAttributes];
  T2SAT[fakeAttribute].vRelation← d;
  RETURN[fakeAttribute]
  END;
 

-- Operations on system tuples

SystemDomainSubset: PUBLIC PROC[
  d: Domain, lowName, highName: ROPE, segment: Segment] RETURNS [es: EntitySet] = TRUSTED
  -- Domain d must be DomainDomain or RelationDomain.  We implement an index scan on the
  -- domain or relation index in the given segment, with names in the given range.
  -- Note that there is no tuple set scan possible through domains or relations, because
  -- the storage level provides no links through the system tuples. 
  -- Scans on the AttributeDomain, IndexDomain, and IndexFactorDomain are not currently
  -- implemented.  They must be accessed via system relations instead.
  -- If segment=NIL, all segments are searched, by creating a recursive "segment" EntitySet.
  -- Otherwise just the given segment is searched.
  BEGIN
  MakeIndexScan: PROC[indexToScan: DBStorage.IndexHandle] RETURNS[EntitySet] = TRUSTED
    BEGIN
    tsScan: DBStorage.IndexScanHandle;
    [lowName, highName]← NCodeAndDefaultLimits[lowName, highName];
    tsScan← DBStorage.OpenScanIndex[indexToScan, [lowName, highName, TRUE, TRUE], First ];
    RETURN[NEW[EntitySetObject[index] ← [index[tsScan]]]];
    END;
  IF segment=NIL THEN
    es← NEW[EntitySetObject[segment] ← [segment[
      remainingSegments: DBModel.QGetSegments[],
      domain: d,
      lowName: lowName,
      highName: highName,
      currentEntitySet: NIL]]]
  ELSE SELECT d FROM
    DomainDomain =>
      es← MakeIndexScan[GetDomainIndex[segment]];
    RelationDomain =>
      es← MakeIndexScan[GetRelationIndex[segment]];
    ENDCASE => {SIGNAL Error[NotImplemented]; RETURN[NIL]};
  END;
 
SystemGetP: PUBLIC PROC [e: Entity, aIs: Attribute] RETURNS [v: Value] = TRUSTED
  -- Fetches properties of system entities.  Need only work with single-valued properties.
  -- System entities are not defined to have the following properties:
  --  dHandleProp, dIndexProp dSubTypeOf, dSubTypeIs, rHandleProp
  --  aTypeCodeProp, aTypeEntityProp, aRelationIs. 
  BEGIN
  WITH e↑ SELECT FROM
    e1: TupleObject[tupleSet] =>  -- e is one of the five system domains
      SELECT aIs FROM
        r1to1Prop => v← NEW[BOOL← e1.vR1to1];
        ENDCASE => SIGNAL Error[NotImplemented];
    e1: TupleObject[attribute] =>   -- e is one of the system attributes
      SELECT aIs FROM
        aHandleProp => v← NEW[POINTER TO UNSPECIFIED← e1.vHandle];
        aTypeIs => v← e1.vType;
        aRelationIs => v← e1.vRelation;
        aLinkIs => v← NEW[BOOL← TRUE];
        ENDCASE => SIGNAL Error[NotImplemented];
     ENDCASE => SIGNAL Error[NotImplemented]; -- No other kinds implemented
   RETURN[v]
   END;
 
SystemGetName: PUBLIC PROC [e: Entity] RETURNS [ROPE] =
  BEGIN
  WITH e↑ SELECT FROM
    e1: TupleObject[tupleSet] =>
      RETURN[e1.vName];
    e1: TupleObject[attribute] => 
      RETURN[e1.vName];
    e1: TupleObject[entity] => 
      RETURN[e1.vName];
    ENDCASE => SIGNAL Error[NotImplemented]; 
  RETURN[NIL]
  END;

NCodeAndDefaultLimits: PROC [low, high: ROPE] RETURNS [newLow, newHigh: ROPE] = TRUSTED
  -- Used by DomainSubset and RelationSubset to default limits on an index search.  The
  -- rules are: (1) if both high and low limits are NIL, the whole index is searched.
  -- (2) if just the high limit is NIL, it defaults to the low limit, (3) any any case, we
  -- must call NCode to convert to all upper case.
  BEGIN
  IF high=NIL THEN 
    IF low=NIL THEN {low← minfString; high← infString}
    ELSE {low← NCode[low]; high← low}
  ELSE
   {low← NCode[low]; high← NCode[high]};
  RETURN[low, high]
  END;
 
  
 
END.



Last edited by:

Cattell on 19-Dec-81  9:31:31: Changed iTupleSetProp and ifXXXProps to have underlying attributes.  Bug had arisen when attempted to do GroupScan on iTupleSetProp, because there was no underlying attribute and therefore no unique fieldID to do the groupscan upon (a random memory location had been used).  Decided to disallow entity-reffing fields without explicit underlying attributes so this won't happen (so DefineSystemProperty only works with simple-valued attributes).

Cattell on 19-Dec-81  9:31:31: Changed aType* stuff around; may have to do more on this.

Cattell on 29-Dec-81 16:09:49: Almost completely rewrote SystemDomainSubset: handle more special cases and do so correctly.

Cattell on April 28, 1982 9:42 am: Added call to NCode in SystemDomainSubset and DesiredPropValue, so upper-case-only works.

Cattell on August 2, 1982 11:16 pm: SubType relation attributes should be DomainDomain type, not AnyDomainType.

Cattell on November 4, 1982 11:24 am: Conversion to new property scheme.  This involves complete rework of system relations and domains, and the procedures used to initialize them.  SystemRelationSubset and SystemGetP also rewritten.

Cattell on December 17, 1982 5:18 pm: Converstion to new segment scheme, new Error scheme.