Index - ObjectVision/GeoDMS GitHub Wiki

Relational functions index

syntax

  • index(a)

definition

index(a) results in an index attribute based on the sort order of the values in attribute a.

If two values are identical in attribute a, the first occurring value receives the lowest index number.

applies to

  • attribute a with Numeric, Point, uint2, uint4, bool or string value type

examples

1. defining the index

attribute<Region> indexTemp (Region) := index(Temperature);
Temperature indexTemp
12 2
11 5
null 1
11 3
14 0
null 4
14 6

domain Region, nr of rows = 7

2. using the index to sort an attribute:

attribute<degrees> Temperature_sorted (Region) := Temperature[indexTemp];
Temperature indexTemp Temperature_sorted
12 2 null
11 5 null
null 1 11
11 3 11
14 0 12
null 4 14
14 6 14

domain Region, nr of rows = 7

3. using index and unique to make a new sorted domain:

unit<uint32> Region: nrofrows = 7
{
   attribute<degrees> Temperature :[12,11,null,11,14,null,14];
   attribute<.>       indexTemp   := index(Temperature);
}

unit<uint32> Region_sorted := unique(Region/indexTemp)
{
   attribute<float32> Temperature := (Region/Temperature[Region/indexTemp])[values];
}
Values Temperature
0 null
1 null
2 11
3 11
4 12
5 14
6 14

domain Region_sorted, nr of rows = 7

sorted tables with attributes

Since GeoDMS 20.18.0, the standard prelude supplies sort_index_raw, sort_index, sort_index_spec, and sort_index_with_attr. sort_index_raw accepts one or more attributes and returns the stable lexicographic permutation attribute; the first argument is the primary criterion. Equal values retain their earlier order, so later criteria can be sorted first and their order survives within equal leading criteria.

The signatures below use ...rest for zero or more additional sort attributes on the same domain; the prelude provides separate one-criterion and multiple-criterion variants:

sort_index_raw(attribute<V> value (D); ...rest) -> attribute<D> (D)
sort_index(attribute<V> value (D); ...rest) -> unit<D>
sort_index_spec(parameter<string> specString; container attrContainer;
                attribute<V> value (D); ...rest) -> unit<D>
sort_index_with_attr(container src; attribute<V> value (D); ...rest) -> unit<D>

Thus sort_index_raw returns only the permutation on the existing domain, whereas each of the other three functions returns a new domain unit. sort_index and the two collecting variants put an org_rel attribute directly beneath that returned unit.

sort_index applies that permutation to create a fresh domain and exposes the permutation as its org_rel back to the original domain:

unit<uint32> Trips_order := sort_index(
    Trips/trip_id,
    Trips/departure_time
);

sort_index_with_attr creates a new sorted domain and collects the source unit's own attributes onto it, without following a referred-item chain:

unit<uint32> Trips_sorted := sort_index_with_attr(
    Trips,
    Trips/trip_id,
    Trips/departure_time
);

Attribute collection is deliberately opt-in. It scans every matching sub-item, which can add unintended update dependencies or expose a recursion that plain sort_index does not have. Prefer sort_index when only the new domain and org_rel are needed.

The attributes are available directly as Trips_sorted/trip_id, Trips_sorted/departure_time, and so on. Trips_sorted/org_rel relates each sorted row to its original row. Use sort_index_spec when collection-scope words are needed:

unit<uint32> Trips_sorted := sort_index_spec(
    'ref;sub',
    Trips,
    Trips/trip_id,
    Trips/departure_time
);

ref follows the attribute container's referred-item chain and sub mirrors attributes from sub-containers. Both broaden the catch-all scan and should therefore be used only when those extra dependencies are intended. The implementation uses table_spec to combine the sorting domain, its org_rel, and the collected attributes without modifying the source unit.

⚠️ **GitHub.com Fallback** ⚠️