@@ -186,17 +186,18 @@ Any references to a type ID in the body of a typedef are encoded as a `uvarint`.
186186A record typedef creates a new type ID equal to the next stream type ID
187187with the following structure:
188188```
189- --------------------------------------------------------
190- |0x00|<nfields>|<name1><type-id-1><name2><type-id-2>...|
191- --------------------------------------------------------
189+ ----------------------------------------------------------------------
190+ |0x00|<nfields>|<name1><opt-1>< type-id-1><name2><opt-2 ><type-id-2>...|
191+ ----------------------------------------------------------------------
192192```
193193Record types consist of an ordered set of fields where each field consists of
194194a name and its type. Unlike JSON, the ordering of the fields is significant
195195and must be preserved through any APIs that consume, process, and emit BSUP records.
196196
197197A record type is encoded as a count of fields, i.e., ` <nfields> ` from above,
198198followed by the field definitions,
199- where a field definition is a field name followed by a type ID, i.e.,
199+ where a field definition is a field name, followed by its optionality coded
200+ as a single byte, followed by a type ID, i.e.,
200201` <name1> ` followed by ` <type-id-1> ` etc. as indicated above.
201202
202203The field names in a record must be unique.
@@ -215,6 +216,9 @@ string data.
215216> even if the field names available to the dot operator are restricted
216217> by language syntax for identifiers.
217218
219+ The optionality byte indicates "optional" for the value 1 and mandatory for
220+ the value 0.
221+
218222The type ID follows the field name and is encoded as a ` uvarint ` .
219223
220224#### 2.1.2 Array Typedef
@@ -336,14 +340,10 @@ whereby the inner loop need not consult and interpret the type ID of each elemen
336340
337341#### 2.2.1 Tag-Encoding of Values
338342
339- Each value is prefixed with a "tag" that defines:
340- * whether it is the null value, and
341- * its encoded length in bytes.
343+ Each value is prefixed with a length "tag" indicating its encoded length in bytes.
342344
343- The tag is 0 for the null value and ` length+1 ` for non-null values where
344- ` length ` is the encoded length of the value. Note that this encoding
345- differentiates between a null value and a zero-length value. Many data types
346- have a meaningful interpretation of a zero-length value, for example, an
345+ Zero-length values are possible as many data types
346+ have a meaningful empty interpretation, for example, an
347347empty array, the empty record, etc.
348348
349349The tag itself is encoded as a ` uvarint ` .
@@ -368,18 +368,19 @@ tend to be zero-filled for small integers.
368368
369369#### 2.2.3 Tag-Encoded Body of Complex Values
370370
371- The body of a length-N container comprises zero or more tag-encoded values,
371+ The body of a length-N container for a complex value
372+ comprises zero or more tag-encoded values,
372373where the values are encoded as follows:
373374
374- | Type | Value |
375- | ----------| -----------------------------------------|
376- | ` array ` | concatenation of elements |
377- | ` set ` | normalized concatenation of elements |
378- | ` record ` | concatenation of elements |
379- | ` map ` | concatenation of key and value elements |
380- | ` union ` | concatenation of tag and value |
381- | ` enum ` | position of enum element |
382- | ` error ` | wrapped element |
375+ | Type | Value |
376+ | ----------| ------------------------------------------- |
377+ | ` array ` | concatenation of elements |
378+ | ` set ` | normalized concatenation of elements |
379+ | ` record ` | option bits and concatenation of elements |
380+ | ` map ` | concatenation of key and value elements |
381+ | ` union ` | concatenation of tag and value |
382+ | ` enum ` | position of enum element |
383+ | ` error ` | wrapped element |
383384
384385Since N, the byte length of any of these container values, is known,
385386there is no need to encode a count of the
@@ -390,6 +391,17 @@ For sets, the concatenation of elements must be normalized so that the
390391sequence of bytes encoding each element's tag-counted value is
391392lexicographically greater than that of the preceding element.
392393
394+ For records, when its type has optional fields,
395+ a bit vector of length NF is encoded as a tag-encoded value of
396+ floor((NF+7)/8) bytes to indicate the omission of an optional value
397+ where NF is the number of optional fields in the record.
398+ The field order of optional fields determines their position
399+ in the bit vector with bit numbers 0-7 (least significant to most significant)
400+ in the first byte, number 8-15 in the second byte, and so forth.
401+ Following the option bits is a concatenation
402+ of elements comprising the mandatory values and the optional values that are present
403+ all in field order.
404+
393405A union value is encoded as a container with two elements. The first
394406element, called the tag, is the ` uvarint ` encoding of the
395407positional index determining the type of the value in reference to the
@@ -546,11 +558,12 @@ complex type it represents as described below.
546558
547559A record type value has the form:
548560```
549- --------------------------------------------------
550- |30|<nfields>|<name1><typeval><name2><typeval>...|
551- --------------------------------------------------
561+ ---------------------------------------------------------
562+ |30|<nfields>|<opts>|< name1><typeval><name2><typeval>...|
563+ ---------------------------------------------------------
552564```
553565where ` <nfields> ` is the number of fields in the record encoded as a ` uvarint ` ,
566+ ` <opts> ` is a bit vector of length ` <nfields> ` indicating which fields are optional,
554567` <name1> ` etc. are the field names encoded as in the
555568record typedef, and each ` <typeval> ` is a recursive encoding of a type value.
556569
0 commit comments