* Support searching by metadata.label fields:
* Add labels when adding/replacing objects.
* Add labels to the query language
* Add a unit test for label tests.
* Stick with terse in-place table alias names rather than interpolate descriptive named constants.
Also: Move all the label operations from store to listoption_indexer.
* Run go generate after refactoring label handling.
* Move label handling out of store.go and into the listoption indexer.
* Fix the number of args in the mocked calls to creating the indices tables.
- tx.Exec takes only one argument.
* Split 'ListOptionIndexer.afterUpsert' into two funcs with more descriptive names.
* Split the 'afterX' methods into two parts, with better names.
* Refactor the query-generator into its own method.
* Split 'ListByOptions' into two functions to simplify testing.
* Add tests for converting other ops to sql stmts, fixing breakage.
* Add more tests, fix NOT-EXISTS for labels.
* Code quality changes:
- Fixed rendering NOT-EXISTS queries.
- Wrap query error in a 'db.QueryError' object.
- Use consistent error message when failing to get a unstructured object.
- Don't include ORDER-BY clauses in COUNT queries.
- Don't bother pulling the various fields out of the `queryInfo` struct
- Pull the count queryInfo parts out only when needed.
* Simplify the way the final queryInfo struct is built.
In particular, don't clear the count query values if no
count query needs to be made -- just leave the default struct
values, and the query executor won't run a count-query.
* No need to map nil to an empty array when there's no count query.
* Process comparisons in the query strings.
* Allow exist-tests on filters only on labels.
* Fix the labels-not-exists (and not-equals) sql expressions.
Conceptually it's simpler to do a '<key> NOT IN (SELECT o1.key...)' to find the rows that don't have the target label.
* Use 'LEFT OUTER JOIN' on label tables only where necessary.
For example, if the test is to find all rows where `metadata.labels.animal = "cows"`,
we can ignore any rows that don't have associated labels, because they will never match.
* LABEL <label> NOT IN (...) tests also succeed where the <label> isn't present.
* Add unit tests on multiple filters with only positive-tests on labels.
There are negative tests on non-label fields -- the goal here is
to verify that we never do an OUTER JOIN when we don't need one.
* Always LEFT-OUTER-JOIN when testing labels.
* Two simplifications when querying on labels:
- Always LEFT-OUTER-JOIN to retain fields that have no associated labels (for negative operators)
- Always SELECT-DISTINCT in case some results return duplicate entries.
And always SELECT DISTINCT when
* Fix multiple filters involving label tests.
When we have multiple filter sub-queries, these get ANDed together.
But we need to do a self-join for each instance of a label-type filter.
Added unit tests to verify that this is what we're generating.