This avoids wracking up huge numbers of login tokens for the test
user. It would be nice to have these automatically cleaned up, but this
will do for now.
This reverts commit f91d870778.
It turns out that while we did implement "storing EJSON in MongoDB", the
technique we chose is very flaky. Some MongoDB commands (insert,
updates that don't increase the doc size?) let you store fields with
non-starting $, and others (update that does increase the doc size?)
don't.
Specifically, this ensures that with sort specifier {'a.x': 1, 'a.y': 1},
{a: [{x: 0, y: 4}]} sorts before {a: [{x: 0, y: 5}, {x: 1, y: 3}]} by
ensuring that the latter only has sort keys [0,5] and [1,3], and not
[0,3].
It does this by ensuring that the different fields used to generate a
sort key are only matched up if they use the same "path" (series of
array indices used during lookup). This is a little stronger than what
MongoDB does: MongoDB lets you do {'a.x': 1, 'a.y.z': 1} where 'a' and
'a.y' are both arrays, and our new rule requires all fields to have
either the exact same set of arrays or to use no arrays at all.
(MongoDB does still have some constraints; eg, with sort key {a: 1,
b:1}, a and b cannot both be arrays. Basically, there may be at most
one "outermost" array across all the fields; and so on recursively, sort
of.
The previously failing test passes now.
This rewrites the sorter to generate "keys" for each doc and find the
lexicographically minimum "key", rather than to look at each sort key
field separately.
This commit doesn't actually change the semantics (and the failing test
still fails) because the key generator actually still computes the full
cartesian product of all keys, rather than only using fields that are
next to each other in arrays.
This 'x' thing is a bit of a hack. The idea is that there are two
consumers of arrayIndices. One is '$', which only looks at the first
index. The other is (soon) sort ken generators, which cares if indices
are explicit or implicit, but doesn't really need to "parse"
arrayIndices; it just will use them to associate branches from different
lookup functions with the matching arrayIndices. 'x' is a simple way to
accomplish this, though I could have made the values of arrayIndices be
objects too.