When doing tests, we create a ton of one-off clusters. This
turns out to be expensive and slow. Fixing it is surprisingly hard.
Fundamentally: If we're sharing clusters, we need to use different
indexes for each test, to avoid clashes. This changes index names.
As a side-effect, this reorders many partition-based things, like
the order keys are returned in. Thus, to fix this, we change a lot
of tests to no longer depend on the *order* in which strings are
returned.
Having done that, we can also discard the ModHasher behavior, since
that only existed to allow us to reliably predict partitioning.
The basic design is as follows: Instead of a cluster being a
[]*Command, a "shareable" cluster is now a []*Command plus some
flags, and a "cluster" is a pointer to a possibly-shared cluster,
plus a link to the specific test using this specific cluster,
and correspondingly, its test name suitably coerced to be a valid
index name prefix.
The "test.Cluster" object now has methods to allow retrieving an
index name, and also implemnts fmt.Formatter to let you use,
e.g., `%i` with it in Sprintf to get "the index name, plus an i".
(This works for everything but %p and %T.)
This allows us to consistently rework all the many things that
use index names in a persistent way.
We also have `MustUnshared` and `MustRunUnsharedCluster` methods
which allow us to specify that a given test needs its own cluster
for some reason. For instance, the tests that want to run backups
need their own isolated cluster, and the tests that want to close
or reopen nodes need their own cluster because a reopened cluster
won't have working GRPC for some reason.
On "closing" a shared cluster (actually the test-specific wrapper
that reflects a given sharing), we delete any indexes starting with
that test's index name prefix. Otherwise, the huge pile of open
indexes prevents `go test -race` from working on MacOS, where we
run out of address space too quickly.
This is fairly enormous but most of the individual changes are
fairly trivial things like replacing the string "i" with "c.Idx()".
We also tweaked a test that failed for me a couple of times to
not depend on sort order.
The "field/view will just synthesize a tx" behavior is awful and
also hides a number of fundamental flaws. We distinguish between
"we really do mean to work on a single shard here" and "we intend
to work on the whole field or view", and the latter now take
Qcx instead of Tx.
This eliminates a lot of very weird cases where we checked for
nil Tx and synthesized them, and also gets us away from
field and view taking Tx parameters when no possible Tx
can be constructed which is valid, because Tx are inherently
shard-specific at this time.
* squashed 45 commits into one :)
* tlt/sql experiment (#2035)
* Move PlanOperator to sql3/planner/types package
includes:
type PlanOperatorColumn struct
type PlanOperator interface
* Remove planner dependencies from pilosa package
The goal after this is to prevent the planner package (which doesn't exist yet)
from being imported by the pilosa package; we just want it injected into the server
in server/server.go. This is because the planner package uses pilosa types, so we need
to avoid circular dependencies.
Added ExecutionPlannerFn
Make public: pilosa.ExecOptions
Added a pilosa.Executor interface
Added a planner.types.CompilePlanner interface
Isolated the planner calls to:
- Executor.Execute()
- *API.[method]()
* Move executionplanner files into the sql3/planner package.
This required a bit of gymnastics, and there are some things around
FieldOptions which need to be addressed soon.
* Remove the hacky FieldOptions stuff I added earlier
This implementation just uses the pilosa.FieldOption functional options
provided by the API (as opposed to trying to build a FieldOptions
object.
It also changes field types to constants. These are private for now, but
if we need to make them public, we should put them in the planner/types
package.
* Implement the "scale" value from Decimal(scale)
Also, precision and scale were currently reversed in the parser. This
fixes that.
* Modify the parser to handle CACHETYPE <type> SIZE <size>
It's a little odd to me that the cache type values are Tokens, but I
guess it's ok. One thing to keep in mind is that FeatureBase expects
lowercase values, so this commit changes the parser to set the value to
the lowercase version of the type.
* Fix the /sql2 tests
This entailed a combination of commenting out or t.Skip()-ing tests
which covered code in the parser that has been commented out or removed
as not currently supported in sql3.
It also adds some coverage for the sql.Contraint stringers.
* Prevent JSON sql results from containing closing commas
This commit just re-works the existing output code to avoid inserting
closing commas (which results in invalid JSON).
* Enhance the CREATE TABLE test coverage.
In particular, ensure that the fields which get created in FeatureBase
are what we expect based on the fields defined in the CREATE TABLE
statement.
This also ensures that the TIMEQUANTUM and CACHETYPE contraints are not
provided for the same field (since those constraints are not supported
together).
* Adjust the EBNF file to indicate SIZE contraint is optional
A CACHETYPE can be provided without a SIZE. This change indicates that
SIZE is optional.
* Remove `executionplanner_` from file names (#2040)
* implementation of ALTER TABLE (sans column RENAME)
* refactored expression analysis; added more robust type checking; all unary and bin ops function on ints
* added type support for expressions; full bin/unary op support; added cast; more literal support
* cast int to all other types
* all literals (except idset, stringset & timestamp) make it thru; cast to all types with int as source now works
* implemented LIKE/NOT LIKE
* Implemented IS [NOT] NULL
* Move sql2 files into sql3/parser package (#2045)
* Move sql2 files into sql3/parser package
This also removes the sql2 package.
* Fix tests which were typing _id fields as INT intead of ID
* implemented BETWEEN, NOT BETWEEN
* Add featurebase/error package (#2046)
* Add featurebase/error package
I copied the `dax/errors` package which I am starting to use in the DAX
prototype into `featurebase/errors` in order to start using it with the
sql3 package. It's basically a wrapper around `github.com/pkg/errors`,
but it uses a customer coded error.
The sql package can define its own errors based on the
`featurebase/errors` types. Then do things like `Wrap()` and `Is()`.
* Address the linter complaints: shadowed variables, unreachable code
* implemented IN & NOT IN with expression lists
* first cut of CASE
* Fixed some errors from rebase
* updated bnf; removed unused code; tightened up error handling
* first crack at basic CLI for SQL3
Use: `featurebase cli`
Still lots to do here, but for example:
> select count(*) from tremor
+--------------+
| COUNT |
+--------------+
| 1.158321e+06 |
+--------------+
* Iterate on the CLI (#2057)
Handle the errors.
Add an "exit" command.
Add some general formatting and white space.
Add termination character: ";" (semicolon)
This commit allows a user to provide multiple or partial SQL statements.
Example of multiple statements:
```
show tables; select * from foo;
```
Example of partial (multi-line) statements:
```
select *
from foo;
```
Don't uppercase the header values
* error refactoring; first cut of TOP; remove unused code; use log.Printf instead of fmt.Printf
* fixed a bug with QualifiedRef from refactoring; added bones of INSERT; removal of unused code; tightened up errors more; fixed failing tests
* single value list for INSERT
* Update bnf per discussion with Travis; INSERT now doing the requisite stuff
* Pat's eyes went square - nothing wrong with TOP, Pat needed to learn arrays again.
* improved some errors; fixed tests to suit
* send warnings back in the api; update CLI to display warnings
* start warning on stuff not implemented so we don't get bugged about it
* Tlt/sql experiment (#2063)
* Expresssion -> Expression
* Add SQL planner test
- adds a test to which it is easier to add tables and SQL statments
- un-exports all of the expression types
- removes the planner pointer from the expression types (it can be added
back later if need be)
* Fix where clause on a string field
Prior to this commit, the binary expression for a where clause on a
string field was building the call by providing a range operator which
is typically used for BSI fields. This changes it to use the call.Args
for string values.
* Update planner tests to handle multiple sql for the same results
* Reorganize SQL tests
Introduce a test/helpers package and move shared MustQueryRows into that
package.
* Add a compatibility map for field types. (#2064)
This is primarily to address the fact that ID fields were previously
incompatible with INT literals.
We should probably consider introducing a custom type for FieldType
which can be used to define compatibilities.
* significantly refactored type checking
* Handle nil (NULL) values in the sql CLI. (#2067)
go-pretty panics if the interface{} field value is nil. This replaces
nil values with a "NULL" string.
* Squash some commits
fixed a still failing test
added line, col to all error messages
refactored source handling to enable table aliases
fixed some copypasta per review
warnings for order by & topn; implemented select as a source
starting to handle in (select...); added stub for optimizer
JSON-encode the sql error and warning strings (#2069)
Error strings with unencoded characters (like double quotes) were
resulting in invalid json.
got insert working; added symbol table; added concrete optimizer; added nascent NestedLoopsOperator; rewrite "where foo in (select..." as inner join
* all about the sets (#2085)
* implemented setcontains()
* implemented set literal; insert set column values; setcontains/all/any both in expr eval and pql filters
* Convert test to use latest framework. (#2086)
* fixed some comments
* removed refactored tests
Co-authored-by: Travis Turner <travis@pilosa.com>
* Add support for Decimal fields to the sql test. (#2090)
* dates (#2094)
* return dates as strings in output; tightened up decimal type checking
* return dates as strings in output; tightened up decimal type checking
* fixed failing tests after decimal changes
* can now insert decimal values
* implemented insert for timestamp data type; implemented current_date, current_timestamp constants
* fixed some failing tests
* handle date literals from strings in insert statements
* changes from feedback
* Fix pointer method error
* sql3 API interface (#2110)
* Introduce API-related interfaces: SchemaAPI, ComputeAPI
The sql3 code was relying on the pointer: *pilosa.API in order to call
API methods directly on the local node. If we want to import and use the
sql3 package in another service (the DAX queryer, for example), we need
to be able to use an implementation of an interface for those API method
calls.
This commit introduces two interfaces, both automatically implemented by
pilosa.API:
- SchemaAPI
- ComputeAPI
* Convert sql3 code to use IndexInfo instead of Index
The sql3 code was relying on a *pilosa.Index and its methods to get
general information like index and field name, type, etc. This commit
converts everything to use a *pilosa.IndexInfo instead.
This allows us to modify the SchemaAPI interface to also return
IndexInfo instead of Index, which will be a lot easier to implement in a
non-pilosa package (like DAX); creating a *pilosa.Index requires
providing things like data directory paths and holders, which are not
necessary for these use cases.
* Unary and Binary Ops R US plus CAST (#2111)
* implemented string literal for timestamp epoch
* fixed failing test
* fixed the failing test again
* refactored tests; implemented unary op tests for all datatypes; implemented binop tests for int/int, int/id, int/decimal & ID/int
* implemented all binary ops for INT & all other types, ID & all other types
* implemented binary ops for DECIMAL types & all other types
* added STRING & BOOL to various tests; implemented all remaining binOp tests
* fix up some stuff after rebasing
* refactored test defs into multiple files; implemented CAST for every datatype
* added tests for like/not like
* addressed review feedback
* addressed type review feedback
* tightened up IS [NOT] NULL behavior plus tests (#2118)
* tightened up IS [NOT] NULL behavior plus tests
* BETWEEN/NOT BETWEEN with all data types
* addressed review feedback
* Handle negative integers in column min/max constraints (#2120)
This commit parses the min/max contraint as an expression, as opposed to
an int literal, so that negative values are treated as Unary
expressions.
There currently isn't support for min/max constraints on `decimal`
fiels, so for now this change only expects +/- integer values.
* Implement the CREATE TABLE keypartitions logic (#2123)
* Execution time, IN/NOT IN & multiple aggregates (#2124)
* added display of execution time
* IN/NOT IN tests for all data types
* fixed date parsing
* removed duplicative tests
* refactoring aggregates
* suport multiple aggregates
* Address review feedback
* final round of feedback
* Add method SchemaAPI.CreateIndexAndFields() (#2127)
In order to support a CREATE TABLE statement as a single command, this
commit alters the SchemaAPI interface to contain a single method which
handles both the index and its fields. It also updates the sql3 code to
use this interface instead of CreateIndex() and CreateField()
indepedently.
* Symbol Handling (Again) (#2129)
* Refactored symbol handling in the planner; re-instated the select as source tests
* removed commented out code
* addressing review feedback
* Move hard-coded _id field out of planner and into interface implementation (#2130)
This commit moves the hard-coded addition of the `_id` field from the
planner to the SchemaAPI.IndexInfo() implementation method.
NOTE: If anything was expecting SchemaAPI.Schema() to also return the
`_id` field as part of its field list in each table, then it would not
be there because the `_id` field is only added in the IndexInfo() method
for now. Currently that's not a problem because nothing is expecting the
`_id` field for `Schema()`.
* Multiple aggregates, all aggregates stand alone and in GROUP BY (#2132)
* handle multiple aggregates in group by queries
* added handling for avg() aggregate both stand alone and in group by
* tightened up sum & avg outside of group by
* added min, max & percentile
* added warnings
* Make MaterializedRowSet implement the PlanOperator interface. (#2133)
This commit refactors the PQLMultiGroupByOperator to have a PlanOperator
as its output. Then, when it initializes, it sets up a
MaterializedRowSet and populates that with the values from the multiple
group by operations.
* added explicit min/max pql operators
* saved a file I forgot to save
* per review
* Un-indent some if/else nesting (#2136)
Co-authored-by: Travis Turner <travis@pilosa.com>
* Add optional `name` argument to test structs.
This commit adds the `name` argument to `tableTest` and `sqlTest` so
that a test can be optionally named. This allows a developer to more
easily run/identify a particular test by name.
* Inbuilt functions (redux) (#2141)
* set functions type parameter type checking
* implemented datepart
* include SQL3 type in SHOW COLUMNS output
* fixed select as source; failing SHOW COLUMNS test
* select in select list
* dump output columns; handle optimization for select list subqueries
* make it an error to return multiple rows for a select list subquery
* added description
* contants and test coverage for datepart function
* SQL3 Refactor-palooza (#2182)
* removed unneeded IsAggregate()
* first cut of working nested loops operator aka INNER JOIN
* remove selectListItemPlanExpression
* added some warnings
* all the tests are passing again!
* addressed some linter complaints
* added basic order by
* bug fixes; added 'or replace'/'replace' to insert
* for insert references should return appropriately
* added back ability to use subquery singleton expressions
* removed dead code; fixed test
* json-able plan, Schema() plus refactoring
* fixed dumb code
* add some tests for time quantum behavior
* Code cleanup during review. Also fixed INSERT to keyed table bug.
This commit contains a lot of minor adjustments made during code review.
It also contains a bug fix that was preventing INSERT into a keyed table
(i.e. _id type STRING) from working.
Co-authored-by: Travis Turner <travis@molecula.com>
* Fix expected min/max on timestamp column test (decimal field)
I don't know why this changed, but presumably something to do with
decimal related work that happened on master.
* Fix compile problem after rebase
* review feedback
Co-authored-by: Matthew Jaffee <jaffee@pilosa.com>
Co-authored-by: Travis Turner <travis@pilosa.com>
Co-authored-by: Travis Turner <travis@molecula.com>
Co-authored-by: Fletcher Haynes <fletcher@capitalprawn.com>
* FB-1251: Add ability to sort Extract queries by some field
There is a sort call which takes a row call and the field, and
based on the field type, the corresponding rows are read. both key and
value are stored in RowKV{}. The value is stored since its required to
merge data from shards. values are sorted in each shard and these sorted
listes are merged in the reduce.
sort-desc flag is sent to comparator to decide the sorting order. ok
flag is added to the compare function to track any error in the
sort.Slice anonymous function
Sorting over set field was removed, since there would be multiple values
for each ids and there would be no right sorting order there.
previously we allowed users to specify a granularity for timestamp
e.g. seconds, milli, micro, nano
however we converted everything to nano before we stored it.
This reduced the allowed range for all time units to what
was allowed by timestamp. For example, with second granularity
you can represent billions of years within the capacity of
int64 but with nano its somewhere b/w 100-200 years.
So now, for timeunits of seconds, milli, and micro the range
is year 0001 - 9999. These limits come from what Go
supports.
So this uses unit specific function to translate
timestamps to values and vice versa to increase
the time range.
In the process of increasing the range for timestamp and subsequent
testing, I found and addressed a few bugs:
- min/max queries were not using timestamp specific comparators so
added that.
- Values from Import/ingest come to FB as relative values to epoch
whereas other BSI fields come as actual values and then
becomes relative to their respective bases within FB. so some
specific handling of that was added.
- However! Set queries use timestamp strings which are, of course,
the actual value they designate. So they have to become
relative.
- When bitdepth is 0, Min/maxUnsigned functions did not run
resulting in a count of 0 when there
was an actual value that was 0.
Also, this removes (now) dead code and updates/adds tests.
The root problem this is attempting to address is sporadic
weird cases in which etcd mistakenly thinks it's down even when
it's up. I am not confident that this is addressed, but there's
a reasonable chance that it is, and I can't trigger it at the
moment, but it was always sporadic, so that doesn't prove much.
There's a lot going on here, and it comes into roughly three
categories.
First: Dropping unused/unneeded code. There's a lot of leftover
bits from the initial development and refactoring of this.
Second: Unifying and shuffling some of the design. We had
multiple interfaces which are functionally impossible to
usefully implement separately, so they're combined together,
and in some cases, moved.
Third: Streamlining logic and simplifying design choices.
This is combined into one commit because the changes are
thoroughly entertwined with each other and you can't usefully
break most of them out.
Also, a bunch of test coverage for most of these changes.
Big changes:
We merge the topology and disco packages. The topology and disco
packages being separate creates a complicated tangle of problems
and dependencies. The fundamental problem, approximately, is that
topology.Node has to track disco.NodeState.
There's three core interfaces interacting here:
topology.Noder (maintains list of nodes)
disco.Stator (maintains the state of a node)
disco.Metadator (stores, possibly retrieves, node metadata)
But the node state mantained by the Noder *is* the set of node
metadata, plus state updates produced by Stators. The only actual
non-trivial and usable implementation of these interfaces is a single
thing which implements all three, and in which the implementations
share a single backend data source which they are all modifying.
But you can't move Noder into disco, because Noder has to refer
to topology.Node, but topology.Node refers to disco.
Solution: First, merge these two packages. Second, merge these
three interfaces, to provide a single interface which is more
clear about the fact that (metadator.)SetMetadata() and
(stator.)Started() are both changing the output we'll get from
(noder.)Nodes().
We rework the node state tracking.
We have this nodeStates map which is almost unused. Really, we
don't need it at all. Every node's state is either its last heartbeat
state or "Unknown", so we simplify this a bit. Also, we ensure that
the populateNodeStates function itself is yielding the sorted nodes
list, so we don't have to be as worried about possible later lookups
of sortedNodes happening outside a lock. We also add diagnostics
for deleting nodes from the metadata list (this should never happen),
and try to track heartbeat state more closely.
This is *probably* what fixes the underlying reported problem,
if anything did.
Still an open issue: Make heartbeat state changes aware of when
they're talking about *this* node and possibly not try to
mark it down? Except this may have a flaw: That would result in
each node disagreeing with other nodes in etcd about the state
of that node in the failure cases, and undermine the point of
using etcd to keep these states consistent.
We reduce the number of contexts and cancelfuncs in the etcd wrapper.
We create a shared context for the non-etcd.embed children of our
etcd wrapper, the heartbeat/keepalive and the node watcher, so we
can cancel that one context and cancel all of those at once, so
we don't need to separately track a function to call to cancel
the watch, AND be closing another channel. Also, our shutdown
now propagates automatically to the various etcd API calls we've
made for things like the node watcher and keepalive calls.
We still need to watch that channel in watchNodesOnce, though,
because apparently the watch doesn't yield an error even if the
context calling it is canceled. Whee.
This should reduce the risk of ending up in an inconsistent state,
and also the Close() function is probably idempotent now.
Smaller changes:
* Remove config-generators that existed to generate etcd
configs but were used only for tests that no longer exist
or make sense.
* Move the logic to generate etcd configs into the etcd
package, instead of the "testing" subpackage. This allows
us to write a self-contained config generator for
clusters where the nodes know about each other, but do
this just with etcd, not with full featurebase servers.
* Move the thing generating `fake:%d` socket names into
the etcd package, which is the only place we use it.
Also simplify it slightly.
* Don't panic on invalid URLs, report errors from them.
* At least try to use etcd's config.Validate functionality.
It's underdocumented, so we're not sure what it will report,
but at least if it does we'll get reports from it and
know what they are?
* Try to handle CompactRevision errors from watches more
correctly -- after a CompactRevision, any future attempt
to watch from a lower revision will necessarily fail, so
we adjust our target revision up. We don't have good
testing for this.
* Drop the Metadata() method (that used to be in Metadator)
because nothing ever used it and it didn't make much sense
to try.
* Convert SetMetadata from taking an arbitrary json blob
to taking the only data that would ever be valid since
we always use it to extract node information anyway.
* Drop several unused functions, unexport things only used
internally.
* Replace Started() with SetState("STARTED"), allowing us
to write tests that mess with states. We weren't really thinking
carefully about state transitions sometimes and now it's much
easier to do that thinking.
* Stop leaving stray localhost:2380 and localhost:2379 in
our embed config. We still sometimes see peer requests from
those and I honestly don't know why, but at least it should
be rarer.
Changes to row queries with from/to options return an error if field is not a timestamp field
logic couldn't be made earlier in call stack because other queries process from/to time differently.
This PR reverts the timestamp work.
The timestamp work requires changes to FB and IDK; and there are
circular dependencies between tests in either repo preventing merging
of either. The work here is pretty stable, but required bypassing
the smoketest. Meanwhile, I found some additional things in IDK that
need addressing which means I merged this work in pre-maturely. Once
I get that worked out, I'll re-commit these commits.
This reverts following commits related to timestamp work:
bypass of smoke test b/c of circular dep with IDK: 0676790
update codec to reflect changes to timstamp range: bd5dc76
fix few bugs regarding timestamp: 33fce8a
increase time range for timestamp by using specified granularity: 5939923.
In the process of increasing the range for timestamp and subsequent
testing, I found and addressed a few bugs:
- min/max queries were not using timestamp specific comparators so
added that.
- Values from Import/ingest come to FB as relative values to epoch
whereas other BSI fields come as actual values and then
becomes relative to their respective bases within FB. so some
specific handling of that was added.
- However! Set queries use timestamp strings which are, of course,
the actual value they designate. So they have to become
relative.
- When bitdepth is 0, Min/maxUnsigned functions did not run
resulting in a count of 0 when there
was an actual value that was 0.
Also, this removes (now) dead code and updates/adds tests.
previously we allowed users to specify a granularity for timestamp
e.g. seconds, milli, micro, nano
however we converted everything to nano before we stored it.
This reduced the allowed range for all time units to what
was allowed by timestamp. For example, with second granularity
you can represent billions of years within the capacity of
int64 but with nano its somewhere b/w 100-200 years.
So now, for timeunits of seconds, milli, and micro the range
is year 0001 - 9999. These limits come from what Go
supports.
So this uses unit specific function to translate
timestamps to values and vice versa to increase
the time range.
* Revert "make pql.Decimal.Value a private big.Int field"
This reverts commit eab6174388.
* Revert "pql.Decimal for DecimalVal in ValCount&GroupCount"
This reverts commit a0c9eec410.
* Revert "Add AddDecimal support to pql"
This reverts commit 50787fd37a.
This is fairly experimental, but basically, we make a fragment-level
op which, given a []uint64, can produce a union of all those rows in
the fragment, with a single scan through the fragment and not needing
a ton of additional space to reify all the rows at once.
Now with the Repair calls happening in the Results assembly rather than
on the intermediate data.
This ensures that we can't overflow when adding `pql.Decimal`s together. The
only place we can possibly overflow is when converting pql.Decimal to an Int64,
but that is a risk we have to take. Also, the only place we do this is in our
ToRowser. We could maybe change that to strings, so the presentation of data
doesn't indicate an overflow, but that is a later decision to make. It will
also involve fixing the generate-proto-grpc make command, because that's broken
rn.
This way we can avoid annoying floating point rounding errors.
Check out FB-1359 for an example:
```
--- FAIL: TestExecutor_GroupByStrings (0.55s)
--- FAIL: TestExecutor_GroupByStrings/3 (0.00s)
executor_test.go:5433: unexpected result at 0:
got:{Group:[generals.1.r1] Count:5 Agg:2775
DecimalAgg:27.749999999999996}
want:{Group:[generals.1.r1] Count:5 Agg:2775 DecimalAgg:27.75}
```
* ugly first cut at supportings Rows(in=[...])
need tests, better handling of various combinations of arguments and
error cases
* explicitly error when other arguments passed with 'in' to Rows
* first cut at supporting Rows(in=[...])
'in' is explicitly not supported with any other arguments (except the
field of course), and will error. It works both as a standalone Rows
call and in GroupBy.
* bitmapfilter require ordered rowids
* remove log message
Co-authored-by: Todd Gruben <todd@molecula.com>
* add bsi base back to int value
* test bsi base/min/max for IntFields
motivated by bsi base not being added back to values
in extract calls when min was a positive integer.
we have an issue where nodes get into UNKNOWN state rather frequently
during periods of high load when they aren't actually down. We want to
allow queries in this situation rather than giving a "shard
unavailable" message.
We default to the jmp-hash method which we had previously, and allow a
user to set the "modulus" option which uses a simple mod operation to
ensure an even spread of partitions across nodes.
I think that ideally we would have new indexes uses modulus and
existing indexes use jmp-hash which implies supporting this
configuration on a per-index basis.
If we don't do per index, we should probably run the whole test suite
both ways.
This uses the shiny new ApplyRewriter logic for ClearRecords,
mostly to verify that ApplyRewriter works at all.
This also implies separating the cache update code out from
importPositions so it can be used also by this.
We also use fragment.ClearRecords instead of the different clearFragment
code in executor. The clearFragment implementation did not update TopN
caches and the like. Standardize it on the clearRecords implementation
which does.
Because the ToRowser interface was not implemented for DistinctTimestamp, there was
a error when using the GRPC endpoint to call Distinct(All(), field=ts). Implementing
the ToRowser interface for DistinctTimestamp solves that problem.
Related to SUP-210: WebUI, Python - Distinct() does not work for Timestamp field
If you're wondering how something that simple gets a commit
message this long, sit down, because you are in for a ride.
The Row, Rows, TopK, and GroupBy(Rows...) commands had three
different sets of semantics for from/to ranges. We unify these.
Sounds easy, right?
The original purpose of this was to address a bug in GroupBy
where, if you had multiple queries only one of which used time,
we could end up silently returning no results because we tried to
do a time query against a non-time field. This was easy to
fix; just move a boolean flag from outside a loop to inside
the loop so it resets to false on each pass.
In the process of trying to test that, I discovered that
specifying `from=...` without `to=...` in a Rows in a GroupBy
didn't work. Searching around, I discovered that we had three
different answers:
GroupBy, TopK: unspecified 'to=' is 0
Row: unspecified to is tomorrow
Rows: unspecified to is the max time quantum in the field
(A time value of 0 is apparently interpreted as January 1st,
0001.) Note that "GroupBy" is really referring to a Rows()
command in a GroupBy, it's just that this uses completely different
code (because it has to be computing rows potentially matching or
restricted to a filter, or provide the rows it generated so
they can be used to filter something else).
So we fixed that, and made a field method for finding the min/max
values (as done in a Rows command that *isn't* in a GroupBy),
and tried to use that with viewsByTimeRange. Then I tried to write
documentation for this, but the documentation was unclear, and
I tried to clear it up. Which caused me to discover that these
four different places ALSO differed in when or whether they'd
replace a broad query with "just the standard view".
So. Round two of the fix: We create a `field.viewsByTimeRange`,
which tries to fall back to a standard view when one exists
and the specified range covers everything, and treats zero
values as non-restrictive, but also picks a narrow range that
is actually related to the range of dates in the field. This
matters because viewsByTimeRange generates the entire set of
views it would need *even if those views don't exist*.
We drop one test that was testing Rows specifically to verify
that, if you omitted To, we acted as though you'd specified a date
two days in the future. That behavior is not now intended, so
we drop the test that tries to verify it.
Thing that might make this better: Figuring out a way to generate the
list of views more cheaply. Right now, we're redoing all the view
computation, including producing a sorted list of view names, for
every shard. This is excessive, but hard to fix.
In particular, there is no trivial way to generate a sorting such
that you can take slices of it and have them be the right slices,
because we want to skip smaller time quanta when an entire larger
parent quantum is included. e.g., if we're including all of
April 2022, we don't want to include any of the days for April of
2022, but if we're doing up through April 15th, we want to include
the first 15 days of April, but NOT include the whole-month quantum.
And so on. Fixing this cleanly is hard and would require a
significant design effort.
Check if queries that have a 'like' argument are applied to keyed
fields. If not, log that the user is trying to use 'like' on an
unsupported field type (as opposed to reporting that there
are no results.)
When deletion is started, _exists field is updated with row+1.
After deletion is completed, we delete _exists=row+1.
If _exists>=1, then deletion was not completed.
Updated go version in docker to match other requirements.
Removed duplicate error check for grpc.