Source File
value.go
Belonging Package
github.com/freeeve/gochickpeas/gql/value
// Package value holds the GQL engine's runtime values -- what the executor// produces and expressions evaluate to. Distinct from the engine's columnar// chickpeas.Value (a 4-kind stored scalar): a runtime value can also be a// list, map, path, temporal, or a bound node/rel handle. Port of the Rust// cypher crate's Value<'g>; Go strings are immutable shared references, so// the 'g borrow lifetime disappears.package valueimport (chickpeas)// Kind discriminates a Value.type Kind uint8const (// KindNull is the absent/unknown value; the zero Value is Null.KindNull Kind = iota// KindBool is a boolean value.KindBool// KindInt is a 64-bit integer value.KindInt// KindFloat is a 64-bit float value.KindFloat// KindStr is a string value.KindStr// KindList is a list value, e.g. the right-hand side of IN [...].KindList// KindNode is a bound graph node -- RETURN n yields this.KindNode// KindRel is a bound relationship, identified by its outgoing-CSR// position (a chickpeas.RelRef.Pos).KindRel// KindPath is a path: the node sequence plus the CSR positions of the// relationships between consecutive nodes (len(rels) == len(nodes)-1).KindPath// KindMap is a map value with entries in insertion order; equality is// by content regardless of order.KindMap// KindTemporal is a date/datetime/localdatetime, epoch-millis-backed.KindTemporal// KindDuration is a duration by calendar components (months, days,// millis); equatable but not totally ordered.KindDuration)// TemporalKind says which temporal a KindTemporal value is. All are epoch// milliseconds (UTC) under the hood; the kind only affects display.// Date is midnight UTC of the day.type TemporalKind uint8const (// Date is a calendar date (midnight UTC).Date TemporalKind = iota// DateTime is a zoned datetime (treated as UTC).DateTime// LocalDateTime is a wall-clock datetime.LocalDateTime)// MapEntry is one key/value pair of a map value, in insertion order.type MapEntry struct {Key stringVal Value}// ext carries the payloads that don't fit the inline word: list elements,// map entries, path sequences, and a duration's calendar components.type ext struct {list []Valueentries []MapEntrynodes []chickpeas.NodeIDrels []uint32months int64days int64}// Value is one runtime value. The zero Value is Null. Scalars store their// payload inline (num holds the int64 bits, float bits, bool, node id, rel// position, or temporal millis); strings ride in str; lists, maps, paths,// and durations share the ext pointer.type Value struct {kind Kindaux uint8num uint64str stringext *ext}// Null is the absent/unknown value (same as the zero Value).func () Value { return Value{} }// Bool is a boolean value.func ( bool) Value {var uint64if {= 1}return Value{kind: KindBool, num: }}// Int is an integer value.func ( int64) Value { return Value{kind: KindInt, num: uint64()} }// Float is a float value.func ( float64) Value { return Value{kind: KindFloat, num: math.Float64bits()} }// Str is a string value. The string is referenced, not copied -- a property// read from the immutable snapshot shares the interner's text.func ( string) Value { return Value{kind: KindStr, str: } }// List is a list value; the slice is taken by reference, not copied.func ( []Value) Value { return Value{kind: KindList, ext: &ext{list: }} }// Node is a bound graph node.func ( chickpeas.NodeID) Value { return Value{kind: KindNode, num: uint64()} }// Rel is a bound relationship by outgoing-CSR position.func ( uint32) Value { return Value{kind: KindRel, num: uint64()} }// Path is a path value over a node sequence and the relationship positions// between consecutive nodes; both slices are taken by reference.func ( []chickpeas.NodeID, []uint32) Value {return Value{kind: KindPath, ext: &ext{nodes: , rels: }}}// Map is a map value; entries keep insertion order and are taken by// reference.func ( []MapEntry) Value { return Value{kind: KindMap, ext: &ext{entries: }} }// Temporal is an epoch-millis temporal of the given kind.func ( int64, TemporalKind) Value {return Value{kind: KindTemporal, aux: uint8(), num: uint64()}}// Duration is a duration by calendar components.func (, , int64) Value {return Value{kind: KindDuration, num: uint64(), ext: &ext{months: , days: }}}// Kind reports the value's discriminant.func ( Value) () Kind { return .kind }// IsNull reports whether the value is Null.func ( Value) () bool { return .kind == KindNull }// IsTruthy is the truthiness WHERE and the boolean operators use: only// Bool(true) is true; Null and non-booleans are not-true.func ( Value) () bool { return .kind == KindBool && .num != 0 }// AsBool returns the boolean payload; ok is false for other kinds.func ( Value) () (bool, bool) { return .num != 0, .kind == KindBool }// AsInt returns the integer payload; ok is false for other kinds.func ( Value) () (int64, bool) { return int64(.num), .kind == KindInt }// AsFloat returns the numeric payload as a float, coercing an integer; ok// is false for non-numeric kinds.func ( Value) () (float64, bool) { return .asNum() }// AsStr returns the string payload; ok is false for other kinds.func ( Value) () (string, bool) { return .str, .kind == KindStr }// AsList returns the list elements; ok is false for other kinds.func ( Value) () ([]Value, bool) {if .kind != KindList {return nil, false}return .ext.list, true}// AsNode returns the bound node id; ok is false for other kinds.func ( Value) () (chickpeas.NodeID, bool) {return chickpeas.NodeID(.num), .kind == KindNode}// AsRel returns the bound relationship's CSR position; ok is false for// other kinds.func ( Value) () (uint32, bool) { return uint32(.num), .kind == KindRel }// AsPath returns the path's node sequence and relationship positions; ok is// false for other kinds.func ( Value) () ( []chickpeas.NodeID, []uint32, bool) {if .kind != KindPath {return nil, nil, false}return .ext.nodes, .ext.rels, true}// AsMap returns the map entries in insertion order; ok is false for other// kinds.func ( Value) () ([]MapEntry, bool) {if .kind != KindMap {return nil, false}return .ext.entries, true}// AsTemporal returns the temporal's epoch millis and kind; ok is false for// other kinds.func ( Value) () ( int64, TemporalKind, bool) {return int64(.num), TemporalKind(.aux), .kind == KindTemporal}// AsDuration returns the duration's components; ok is false for other kinds.func ( Value) () (, , int64, bool) {if .kind != KindDuration {return 0, 0, 0, false}return .ext.months, .ext.days, int64(.num), true}// asNum is the shared numeric coercion: Int and Float read as float64,// everything else is non-numeric.func ( Value) () (float64, bool) {switch .kind {case KindInt:return float64(int64(.num)), truecase KindFloat:return math.Float64frombits(.num), truedefault:return 0, false}}// NumericTwin is the other numeric spelling of v that value.Compare// treats as equal: an integral float's int, an int's float. The property// index keys stored values exactly, while comparison coerces int against// float through float64 -- so an index probe for one spelling must also// probe the twin or rows whose stored type differs from the literal's// are silently lost. Bounded to |v| <= 2^53, where the int<->float// mapping is exact and bijective; beyond it no twin is reported (the// conversion rounds, so a probe would ask about a different number).func ( Value) (Value, bool) {const = int64(1) << 53if , := .AsInt(); && .Kind() == KindInt {if >= - && <= {return Float(float64()), true}return Value{}, false}if .Kind() == KindFloat {, := .AsFloat()if == float64(int64()) && >= -float64() && <= float64() {return Int(int64()), true}}return Value{}, false}
![]() |
The pages are generated with Golds v0.8.7. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |