EncodeExistsInvertedIndexSpans takes in a key prefix and returns the spans that must be scanned in the inverted index to evaluate an exists (?) predicate with the given JSON (i.e., find the objects/arrays in the index that contain the given string as a key, or *are* the given string). The spans are
( b []byte, s string, )
| 1124 | // |
| 1125 | // The input inKey is prefixed to the keys in all returned spans. |
| 1126 | func EncodeExistsInvertedIndexSpans( |
| 1127 | b []byte, s string, |
| 1128 | ) (invertedExpr inverted.Expression, err error) { |
| 1129 | b = encoding.EncodeJSONAscending(b) |
| 1130 | js := jsonString(s) |
| 1131 | // Make an inverted expression that contains both arrays containing the input |
| 1132 | // string and objects with keys that are the input string. |
| 1133 | builder := NewArrayBuilder(1) |
| 1134 | builder.Add(js) |
| 1135 | arrayKeys, err := builder.Build().encodeInvertedIndexKeys(b) |
| 1136 | if err != nil { |
| 1137 | return nil, err |
| 1138 | } |
| 1139 | scalarKeys, err := js.encodeInvertedIndexKeys(b[:len(b):len(b)]) |
| 1140 | if err != nil { |
| 1141 | return nil, err |
| 1142 | } |
| 1143 | if len(arrayKeys) != 1 || len(scalarKeys) != 1 { |
| 1144 | return nil, errors.AssertionFailedf("unexpectedly found more than 1 inverted index child in single-key array") |
| 1145 | } |
| 1146 | arrayKey := arrayKeys[0] |
| 1147 | scalarKey := scalarKeys[0] |
| 1148 | // We pass end=true so that we don't get an extra separator at the end of the |
| 1149 | // key, which would exclude keys that point to non-scalars like non-empty |
| 1150 | // arrays or non-empty objects. |
| 1151 | // However, if we don't limit the span we send, we'd also get all paths |
| 1152 | // that have keys that begin with `s`, and not just keys that exactly equal |
| 1153 | // `s`, so we have to explicitly define the span as being from `s` to the end |
| 1154 | // of the`s+sep` prefix. |
| 1155 | objectKey := encoding.EncodeJSONKeyStringAscending(b[:len(b):len(b)], s, true /* end */) |
| 1156 | objectSpan := inverted.Span{ |
| 1157 | Start: objectKey, |
| 1158 | End: keysbase.PrefixEnd(encoding.AddJSONPathSeparator(objectKey)), |
| 1159 | } |
| 1160 | return inverted.Or( |
| 1161 | inverted.Or( |
| 1162 | inverted.ExprForSpan(inverted.MakeSingleValSpan(arrayKey), true /* tight */), |
| 1163 | inverted.ExprForSpan(objectSpan, true /* tight */), |
| 1164 | ), |
| 1165 | inverted.ExprForSpan(inverted.MakeSingleValSpan(scalarKey), true /* tight */), |
| 1166 | ), nil |
| 1167 | } |
| 1168 | |
| 1169 | func (j jsonNull) encodeInvertedIndexKeys(b []byte) ([][]byte, error) { |
| 1170 | b = encoding.AddJSONPathTerminator(b) |
nothing calls this directly
no test coverage detected
searching dependent graphs…