mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-31 15:06:26 +00:00
wip
This commit is contained in:
parent
9af6c63774
commit
401e79e0d8
5 changed files with 34 additions and 13 deletions
|
@ -19,6 +19,8 @@ according to [these docs](https://docs.victoriametrics.com/victorialogs/quicksta
|
||||||
|
|
||||||
## tip
|
## tip
|
||||||
|
|
||||||
|
* FEATURE: allow [`head` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#limit-pipe) without number. For example, `error | head`. In this case 10 last values are returned as `head` Unix command does by default.
|
||||||
|
|
||||||
## [v0.12.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v0.12.1-victorialogs)
|
## [v0.12.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v0.12.1-victorialogs)
|
||||||
|
|
||||||
Released at 2024-05-26
|
Released at 2024-05-26
|
||||||
|
|
|
@ -1463,6 +1463,12 @@ _time:5m | limit 100
|
||||||
|
|
||||||
`head` keyword can be used instead of `limit` for convenience. For example, `_time:5m | head 100` is equivalent to `_time:5m | limit 100`.
|
`head` keyword can be used instead of `limit` for convenience. For example, `_time:5m | head 100` is equivalent to `_time:5m | limit 100`.
|
||||||
|
|
||||||
|
The `N` in `head N` can be omitted - in this case up to 10 matching logs are returned:
|
||||||
|
|
||||||
|
```logsql
|
||||||
|
error | head
|
||||||
|
```
|
||||||
|
|
||||||
By default rows are selected in arbitrary order because of performance reasons, so the query above can return different sets of logs every time it is executed.
|
By default rows are selected in arbitrary order because of performance reasons, so the query above can return different sets of logs every time it is executed.
|
||||||
[`sort` pipe](#sort-pipe) can be used for making sure the logs are in the same order before applying `limit ...` to them.
|
[`sort` pipe](#sort-pipe) can be used for making sure the logs are in the same order before applying `limit ...` to them.
|
||||||
|
|
||||||
|
|
|
@ -869,8 +869,10 @@ func TestParseQuerySuccess(t *testing.T) {
|
||||||
f(`* | DELETE foo, bar`, `* | delete foo, bar`)
|
f(`* | DELETE foo, bar`, `* | delete foo, bar`)
|
||||||
|
|
||||||
// limit and head pipe
|
// limit and head pipe
|
||||||
f(`foo | limit 10`, `foo | limit 10`)
|
f(`foo | limit`, `foo | limit 10`)
|
||||||
f(`foo | head 10`, `foo | limit 10`)
|
f(`foo | head`, `foo | limit 10`)
|
||||||
|
f(`foo | limit 20`, `foo | limit 20`)
|
||||||
|
f(`foo | head 20`, `foo | limit 20`)
|
||||||
f(`foo | HEAD 1_123_432`, `foo | limit 1123432`)
|
f(`foo | HEAD 1_123_432`, `foo | limit 1123432`)
|
||||||
f(`foo | head 10K`, `foo | limit 10000`)
|
f(`foo | head 10K`, `foo | limit 10000`)
|
||||||
|
|
||||||
|
@ -1313,10 +1315,6 @@ func TestParseQueryFailure(t *testing.T) {
|
||||||
f(`foo | delete foo,`)
|
f(`foo | delete foo,`)
|
||||||
f(`foo | delete foo,,`)
|
f(`foo | delete foo,,`)
|
||||||
|
|
||||||
// missing limit and head pipe value
|
|
||||||
f(`foo | limit`)
|
|
||||||
f(`foo | head`)
|
|
||||||
|
|
||||||
// invalid limit pipe value
|
// invalid limit pipe value
|
||||||
f(`foo | limit bar`)
|
f(`foo | limit bar`)
|
||||||
f(`foo | limit -123`)
|
f(`foo | limit -123`)
|
||||||
|
|
|
@ -88,15 +88,20 @@ func parsePipeLimit(lex *lexer) (*pipeLimit, error) {
|
||||||
if !lex.isKeyword("limit", "head") {
|
if !lex.isKeyword("limit", "head") {
|
||||||
return nil, fmt.Errorf("expecting 'limit' or 'head'; got %q", lex.token)
|
return nil, fmt.Errorf("expecting 'limit' or 'head'; got %q", lex.token)
|
||||||
}
|
}
|
||||||
|
lex.nextToken()
|
||||||
|
|
||||||
lex.nextToken()
|
limit := uint64(10)
|
||||||
n, err := parseUint(lex.token)
|
if !lex.isKeyword("|", ")", "") {
|
||||||
if err != nil {
|
n, err := parseUint(lex.token)
|
||||||
return nil, fmt.Errorf("cannot parse rows limit from %q: %w", lex.token, err)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot parse rows limit from %q: %w", lex.token, err)
|
||||||
|
}
|
||||||
|
lex.nextToken()
|
||||||
|
limit = n
|
||||||
}
|
}
|
||||||
lex.nextToken()
|
|
||||||
pl := &pipeLimit{
|
pl := &pipeLimit{
|
||||||
limit: n,
|
limit: limit,
|
||||||
}
|
}
|
||||||
return pl, nil
|
return pl, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ func TestParsePipeLimitFailure(t *testing.T) {
|
||||||
expectParsePipeFailure(t, pipeStr)
|
expectParsePipeFailure(t, pipeStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
f(`limit`)
|
|
||||||
f(`limit -10`)
|
f(`limit -10`)
|
||||||
f(`limit foo`)
|
f(`limit foo`)
|
||||||
}
|
}
|
||||||
|
@ -30,6 +29,17 @@ func TestPipeLimit(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
expectPipeResults(t, pipeStr, rows, rowsExpected)
|
expectPipeResults(t, pipeStr, rows, rowsExpected)
|
||||||
}
|
}
|
||||||
|
f("limit", [][]Field{
|
||||||
|
{
|
||||||
|
{"_msg", `{"foo":"bar"}`},
|
||||||
|
{"a", `test`},
|
||||||
|
},
|
||||||
|
}, [][]Field{
|
||||||
|
{
|
||||||
|
{"_msg", `{"foo":"bar"}`},
|
||||||
|
{"a", `test`},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
f("limit 100", [][]Field{
|
f("limit 100", [][]Field{
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue