vendor: Update everything

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4620
This commit is contained in:
Jakob Borg
2017-12-29 11:38:00 +00:00
parent 1296a22069
commit c24bf7ea55
1070 changed files with 294926 additions and 488191 deletions

41
vendor/github.com/cznic/b/btree.go generated vendored
View File

@@ -301,7 +301,6 @@ func (t *Tree) Delete(k interface{} /*K*/) (ok bool) {
pi = i + 1
p = x
q = x.x[pi].ch
ok = false
continue
case *d:
t.extract(x, i)
@@ -547,12 +546,13 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
if ok {
switch x := q.(type) {
case *x:
i++
if x.c > 2*kx {
x, i = t.splitX(p, x, pi, i)
}
pi = i + 1
pi = i
p = x
q = x.x[i+1].ch
q = x.x[i].ch
continue
case *d:
x.d[i].v = v
@@ -614,12 +614,13 @@ func (t *Tree) Put(k interface{} /*K*/, upd func(oldV interface{} /*V*/, exists
if ok {
switch x := q.(type) {
case *x:
i++
if x.c > 2*kx {
x, i = t.splitX(p, x, pi, i)
}
pi = i + 1
pi = i
p = x
q = x.x[i+1].ch
q = x.x[i].ch
continue
case *d:
oldV = x.d[i].v
@@ -701,36 +702,20 @@ func (t *Tree) splitX(p *x, q *x, pi int, i int) (*x, int) {
r.c = kx
if pi >= 0 {
p.insert(pi, q.x[kx].k, r)
q.x[kx].k = zk
for i := range q.x[kx+1:] {
q.x[kx+i+1] = zxe
}
switch {
case i < kx:
return q, i
case i == kx:
return p, pi
default: // i > kx
return r, i - kx - 1
}
} else {
t.r = newX(q).insert(0, q.x[kx].k, r)
}
nr := newX(q).insert(0, q.x[kx].k, r)
t.r = nr
q.x[kx].k = zk
for i := range q.x[kx+1:] {
q.x[kx+i+1] = zxe
}
switch {
case i < kx:
return q, i
case i == kx:
return nr, 0
default: // i > kx
return r, i - kx - 1
if i > kx {
q = r
i -= kx + 1
}
return q, i
}
func (t *Tree) underflow(p *x, q *d, pi int) {

View File

@@ -76,7 +76,7 @@ type (
//
// However, once an Enumerator returns io.EOF to signal "no more
// items", it does no more attempt to "resync" on tree mutation(s). In
// other words, io.EOF from an Enumaretor is "sticky" (idempotent).
// other words, io.EOF from an Enumerator is "sticky" (idempotent).
Enumerator struct {
err error
hit bool
@@ -450,7 +450,7 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) {
t.ver++
l, r := p.siblings(pi)
if l != nil && l.c < 2*kd {
if l != nil && l.c < 2*kd && i != 0 {
l.mvL(q, 1)
t.insert(q, i-1, k, v)
p.x[pi-1].k = q.d[0].k
@@ -473,9 +473,9 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) {
t.split(p, q, pi, i, k, v)
}
// Seek returns an Enumerator positioned on a an item such that k >= item's
// key. ok reports if k == item.key The Enumerator's position is possibly
// after the last item in the tree.
// Seek returns an Enumerator positioned on an item such that k >= item's key.
// ok reports if k == item.key The Enumerator's position is possibly after the
// last item in the tree.
func (t *Tree) Seek(k int) (e *Enumerator, ok bool) {
q := t.r
if q == nil {
@@ -547,12 +547,13 @@ func (t *Tree) Set(k int, v int) {
if ok {
switch x := q.(type) {
case *x:
i++
if x.c > 2*kx {
x, i = t.splitX(p, x, pi, i)
}
pi = i + 1
pi = i
p = x
q = x.x[i+1].ch
q = x.x[i].ch
continue
case *d:
x.d[i].v = v
@@ -614,12 +615,13 @@ func (t *Tree) Put(k int, upd func(oldV int, exists bool) (newV int, write bool)
if ok {
switch x := q.(type) {
case *x:
i++
if x.c > 2*kx {
x, i = t.splitX(p, x, pi, i)
}
pi = i + 1
pi = i
p = x
q = x.x[i+1].ch
q = x.x[i].ch
continue
case *d:
oldV = x.d[i].v
@@ -701,36 +703,20 @@ func (t *Tree) splitX(p *x, q *x, pi int, i int) (*x, int) {
r.c = kx
if pi >= 0 {
p.insert(pi, q.x[kx].k, r)
q.x[kx].k = zk
for i := range q.x[kx+1:] {
q.x[kx+i+1] = zxe
}
switch {
case i < kx:
return q, i
case i == kx:
return p, pi
default: // i > kx
return r, i - kx - 1
}
} else {
t.r = newX(q).insert(0, q.x[kx].k, r)
}
nr := newX(q).insert(0, q.x[kx].k, r)
t.r = nr
q.x[kx].k = zk
for i := range q.x[kx+1:] {
q.x[kx+i+1] = zxe
}
switch {
case i < kx:
return q, i
case i == kx:
return nr, 0
default: // i > kx
return r, i - kx - 1
if i > kx {
q = r
i -= kx + 1
}
return q, i
}
func (t *Tree) underflow(p *x, q *d, pi int) {
@@ -826,13 +812,7 @@ func (e *Enumerator) Next() (k int, v int, err error) {
}
if e.ver != e.t.ver {
f, hit := e.t.Seek(e.k)
if !e.hit && hit {
if err = f.next(); err != nil {
return
}
}
f, _ := e.t.Seek(e.k)
*e = *f
f.Close()
}
@@ -849,7 +829,7 @@ func (e *Enumerator) Next() (k int, v int, err error) {
i := e.q.d[e.i]
k, v = i.k, i.v
e.k, e.hit = k, false
e.k, e.hit = k, true
e.next()
return
}
@@ -880,13 +860,7 @@ func (e *Enumerator) Prev() (k int, v int, err error) {
}
if e.ver != e.t.ver {
f, hit := e.t.Seek(e.k)
if !e.hit && hit {
if err = f.prev(); err != nil {
return
}
}
f, _ := e.t.Seek(e.k)
*e = *f
f.Close()
}
@@ -895,15 +869,22 @@ func (e *Enumerator) Prev() (k int, v int, err error) {
return
}
if !e.hit {
// move to previous because Seek overshoots if there's no hit
if err = e.prev(); err != nil {
return
}
}
if e.i >= e.q.c {
if err = e.next(); err != nil {
if err = e.prev(); err != nil {
return
}
}
i := e.q.d[e.i]
k, v = i.k, i.v
e.k, e.hit = k, false
e.k, e.hit = k, true
e.prev()
return
}

View File

@@ -190,7 +190,9 @@ func TempFile(dir, prefix, suffix string) (f *os.File, err error) {
f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if os.IsExist(err) {
if nconflict++; nconflict > 10 {
randmu.Lock()
rand = reseed()
randmu.Unlock()
}
continue
}

27
vendor/github.com/cznic/golex/lex/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,27 @@
Copyright (c) 2014 The golex Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the names of the authors nor the names of the
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

410
vendor/github.com/cznic/golex/lex/api.go generated vendored Normal file
View File

@@ -0,0 +1,410 @@
// Copyright (c) 2015 The golex Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lex
import (
"bytes"
"fmt"
"go/token"
"io"
"os"
)
// BOM handling modes which can be set by the BOMMode Option. Default is BOMIgnoreFirst.
const (
BOMError = iota // BOM is an error anywhere.
BOMIgnoreFirst // Skip BOM if at beginning, report as error if anywhere else.
BOMPassAll // No special handling of BOM.
BOMPassFirst // No special handling of BOM if at beginning, report as error if anywhere else.
)
const (
NonASCII = 0x80 // DefaultRuneClass returns NonASCII for non ASCII runes.
RuneEOF = -1 // Distinct from any valid Unicode rune value.
)
// DefaultRuneClass returns the character class of r. If r is an ASCII code
// then its class equals the ASCII code. Any other rune is of class NonASCII.
//
// DefaultRuneClass is the default implementation Lexer will use to convert
// runes (21 bit entities) to scanner classes (8 bit entities).
//
// Non ASCII aware lexical analyzers will typically use their own
// categorization function. To assign such custom function use the RuneClass
// option.
func DefaultRuneClass(r rune) int {
if r >= 0 && r < 0x80 {
return int(r)
}
return NonASCII
}
// Char represents a rune and its position.
type Char struct {
Rune rune
pos int32
}
// NewChar returns a new Char value.
func NewChar(pos token.Pos, r rune) Char { return Char{pos: int32(pos), Rune: r} }
// IsValid reports whether c is not a zero Char.
func (c Char) IsValid() bool { return c.Pos().IsValid() }
// Pos returns the token.Pos associated with c.
func (c Char) Pos() token.Pos { return token.Pos(c.pos) }
// CharReader is a RuneReader providing additionally explicit position
// information by returning a Char instead of a rune as its first result.
type CharReader interface {
ReadChar() (c Char, size int, err error)
}
// Lexer suports golex[0] generated lexical analyzers.
type Lexer struct {
File *token.File // The *token.File passed to New.
First Char // First remembers the lookahead char when Rule0 was invoked.
Last Char // Last remembers the last Char returned by Next.
Prev Char // Prev remembers the Char previous to Last.
bomMode int // See the BOM* constants.
bytesBuf bytes.Buffer // Used by TokenBytes.
charSrc CharReader // Lexer alternative input.
classf func(rune) int //
errorf func(token.Pos, string) //
lookahead Char // Lookahead if non zero.
mark int // Longest match marker.
off int // Used for File.AddLine.
src io.RuneReader // Lexer input.
tokenBuf []Char // Lexeme collector.
ungetBuf []Char // Unget buffer.
}
// New returns a new *Lexer. The result can be amended using opts.
//
// Non Unicode Input
//
// To consume sources in other encodings and still have exact position
// information, pass an io.RuneReader which returns the next input character
// reencoded as an Unicode rune but returns the size (number of bytes used to
// encode it) of the original character, not the size of its UTF-8
// representation after converted to an Unicode rune. Size is the second
// returned value of io.RuneReader.ReadRune method[4].
//
// When src optionally implements CharReader its ReadChar method is used
// instead of io.ReadRune.
func New(file *token.File, src io.RuneReader, opts ...Option) (*Lexer, error) {
r := &Lexer{
File: file,
bomMode: BOMIgnoreFirst,
classf: DefaultRuneClass,
src: src,
}
if x, ok := src.(CharReader); ok {
r.charSrc = x
}
r.errorf = r.defaultErrorf
for _, o := range opts {
if err := o(r); err != nil {
return nil, err
}
}
return r, nil
}
// Abort handles the situation when the scanner does not successfully recognize
// any token or when an attempt to find the longest match "overruns" from an
// accepting state only to never reach an accepting state again. In the first
// case the scanner was never in an accepting state since last call to Rule0
// and then (true, previousLookahead rune) is returned, effectively consuming a
// single Char token, avoiding scanner stall. Otherwise there was at least one
// accepting scanner state marked using Mark. In this case Abort rollbacks the
// lexer state to the marked state and returns (false, 0). The scanner must
// then execute a prescribed goto statement. For example:
//
// %yyc c
// %yyn c = l.Next()
// %yym l.Mark()
//
// %{
// package foo
//
// import (...)
//
// type lexer struct {
// *lex.Lexer
// ...
// }
//
// func newLexer(...) *lexer {
// return &lexer{
// lex.NewLexer(...),
// ...
// }
// }
//
// func (l *lexer) scan() int {
// c := l.Enter()
// %}
//
// ... more lex defintions
//
// %%
//
// c = l.Rule0()
//
// ... lex rules
//
// %%
//
// if c, ok := l.Abort(); ok {
// return c
// }
//
// goto yyAction
// }
func (l *Lexer) Abort() (int, bool) {
if l.mark >= 0 {
if len(l.tokenBuf) > l.mark {
l.Unget(l.lookahead)
for i := len(l.tokenBuf) - 1; i >= l.mark; i-- {
l.Unget(l.tokenBuf[i])
}
}
l.tokenBuf = l.tokenBuf[:l.mark]
return 0, false
}
switch n := len(l.tokenBuf); n {
case 0: // [] z
c := l.lookahead
l.Next()
return int(c.Rune), true
case 1: // [a] z
return int(l.tokenBuf[0].Rune), true
default: // [a, b, ...], z
c := l.tokenBuf[0] // a
l.Unget(l.lookahead) // z
for i := n - 1; i > 1; i-- {
l.Unget(l.tokenBuf[i]) // ...
}
l.lookahead = l.tokenBuf[1] // b
l.tokenBuf = l.tokenBuf[:1]
return int(c.Rune), true
}
}
func (l *Lexer) class() int { return l.classf(l.lookahead.Rune) }
func (l *Lexer) defaultErrorf(pos token.Pos, msg string) {
l.Error(fmt.Sprintf("%v: %v", l.File.Position(pos), msg))
}
// Enter ensures the lexer has a valid lookahead Char and returns its class.
// Typical use in an .l file
//
// func (l *lexer) scan() lex.Char {
// c := l.Enter()
// ...
func (l *Lexer) Enter() int {
if !l.lookahead.IsValid() {
l.Next()
}
return l.class()
}
// Error Implements yyLexer[2] by printing the msg to stderr.
func (l *Lexer) Error(msg string) {
fmt.Fprintf(os.Stderr, "%s\n", msg)
}
// Lookahead returns the current lookahead.
func (l *Lexer) Lookahead() Char {
if !l.lookahead.IsValid() {
l.Next()
}
return l.lookahead
}
// Mark records the current state of scanner as accepting. It implements the
// golex macro %yym. Typical usage in an .l file:
//
// %yym l.Mark()
func (l *Lexer) Mark() { l.mark = len(l.tokenBuf) }
func (l *Lexer) next() int {
const bom = '\ufeff'
if c := l.lookahead; c.IsValid() {
l.tokenBuf = append(l.tokenBuf, c)
}
if n := len(l.ungetBuf); n != 0 {
l.lookahead = l.ungetBuf[n-1]
l.ungetBuf = l.ungetBuf[:n-1]
return l.class()
}
if l.src == nil {
return RuneEOF
}
var r rune
var sz int
var err error
var pos token.Pos
var c Char
again:
off0 := l.off
switch cs := l.charSrc; {
case cs != nil:
c, sz, err = cs.ReadChar()
r = c.Rune
pos = c.Pos()
default:
r, sz, err = l.src.ReadRune()
pos = l.File.Pos(l.off)
}
l.off += sz
if err != nil {
l.src = nil
r = RuneEOF
if err != io.EOF {
l.errorf(pos, err.Error())
}
}
if r == bom {
switch l.bomMode {
default:
fallthrough
case BOMIgnoreFirst:
if off0 != 0 {
l.errorf(pos, "unicode (UTF-8) BOM in middle of file")
}
goto again
case BOMPassAll:
// nop
case BOMPassFirst:
if off0 != 0 {
l.errorf(pos, "unicode (UTF-8) BOM in middle of file")
goto again
}
case BOMError:
switch {
case off0 == 0:
l.errorf(pos, "unicode (UTF-8) BOM at beginnig of file")
default:
l.errorf(pos, "unicode (UTF-8) BOM in middle of file")
}
goto again
}
}
l.lookahead = NewChar(pos, r)
if r == '\n' {
l.File.AddLine(l.off)
}
return l.class()
}
// Next advances the scanner for one rune and returns the respective character
// class of the new lookahead. Typical usage in an .l file:
//
// %yyn c = l.Next()
func (l *Lexer) Next() int {
l.Prev = l.Last
r := l.next()
l.Last = l.lookahead
return r
}
// Offset returns the current reading offset of the lexer's source.
func (l *Lexer) Offset() int { return l.off }
// Rule0 initializes the scanner state before the attempt to recognize a token
// starts. The token collecting buffer is cleared. Rule0 records the current
// lookahead in l.First and returns its class. Typical usage in an .l file:
//
// ... lex definitions
//
// %%
//
// c := l.Rule0()
//
// first-pattern-regexp
func (l *Lexer) Rule0() int {
if !l.lookahead.IsValid() {
l.Next()
}
l.First = l.lookahead
l.mark = -1
if len(l.tokenBuf) > 1<<18 { //DONE constant tuned
l.tokenBuf = nil
} else {
l.tokenBuf = l.tokenBuf[:0]
}
return l.class()
}
// Token returns the currently collected token chars. The result is R/O.
func (l *Lexer) Token() []Char { return l.tokenBuf }
// TokenBytes returns the UTF-8 encoding of Token. If builder is not nil then
// it's called instead to build the encoded token byte value into the buffer
// passed to it.
//
// The Result is R/O.
func (l *Lexer) TokenBytes(builder func(*bytes.Buffer)) []byte {
if len(l.bytesBuf.Bytes()) < 1<<18 { //DONE constant tuned
l.bytesBuf.Reset()
} else {
l.bytesBuf = bytes.Buffer{}
}
switch {
case builder != nil:
builder(&l.bytesBuf)
default:
for _, c := range l.Token() {
l.bytesBuf.WriteRune(c.Rune)
}
}
return l.bytesBuf.Bytes()
}
// Unget unreads all chars in c.
func (l *Lexer) Unget(c ...Char) {
l.ungetBuf = append(l.ungetBuf, c...)
l.lookahead = Char{} // Must invalidate lookahead.
}
// Option is a function which can be passed as an optional argument to New.
type Option func(*Lexer) error
// BOMMode option selects how the lexer handles BOMs. See the BOM* constants for details.
func BOMMode(mode int) Option {
return func(l *Lexer) error {
l.bomMode = mode
return nil
}
}
// ErrorFunc option sets a function called when an, for example I/O error,
// occurs. The default is to call Error with the position and message already
// formated as a string.
func ErrorFunc(f func(token.Pos, string)) Option {
return func(l *Lexer) error {
l.errorf = f
return nil
}
}
// RuneClass option sets the function used to convert runes to character
// classes.
func RuneClass(f func(rune) int) Option {
return func(l *Lexer) error {
l.classf = f
return nil
}
}

40
vendor/github.com/cznic/golex/lex/doc.go generated vendored Normal file
View File

@@ -0,0 +1,40 @@
// Copyright (c) 2015 The golex Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package lex is a Unicode-friendly run time library for golex[0] generated
// lexical analyzers[1].
//
// Changelog
//
// 2015-04-08: Initial release.
//
// Character classes
//
// Golex internally handles only 8 bit "characters". Many Unicode-aware
// tokenizers do not actually need to recognize every Unicode rune, but only
// some particular partitions/subsets. Like, for example, a particular Unicode
// category, say upper case letters: Lu.
//
// The idea is to convert all runes in a particular set as a single 8 bit
// character allocated outside the ASCII range of codes. The token value, a
// string of runes and their exact positions is collected as usual (see the
// Token and TokenBytes method), but the tokenizer DFA is simpler (and thus
// smaller and perhaps also faster) when this technique is used. In the example
// program (see below), recognizing (and skipping) white space, integer
// literals, one keyword and Go identifiers requires only an 8 state DFA[5].
//
// To provide the conversion from runes to character classes, "install" your
// converting function using the RuneClass option.
//
// References
//
// -
//
// [0]: http://godoc.org/github.com/cznic/golex
// [1]: http://en.wikipedia.org/wiki/Lexical_analysis
// [2]: http://golang.org/cmd/yacc/
// [3]: https://github.com/cznic/golex/blob/master/lex/example.l
// [4]: http://golang.org/pkg/io/#RuneReader
// [5]: https://github.com/cznic/golex/blob/master/lex/dfa
package lex

View File

@@ -124,11 +124,23 @@ func (f *mem) Truncate(size int64) (err error) {
}
first := size >> f.pgBits
if size&int64(f.pgMask) != 0 {
if po := size & int64(f.pgMask); po != 0 {
if p := f.m[first]; p != nil {
b := (*p)[po:]
for i := range b {
b[i] = 0
}
}
first++
}
last := f.size >> f.pgBits
if f.size&int64(f.pgMask) != 0 {
if po := f.size & int64(f.pgMask); po != 0 {
if p := f.m[last]; p != nil {
b := (*p)[po:]
for i := range b {
b[i] = 0
}
}
last++
}
for ; first <= last; first++ {
@@ -143,6 +155,10 @@ func (f *mem) Truncate(size int64) (err error) {
}
func (f *mem) WriteAt(b []byte, off int64) (n int, err error) {
if len(b) == 0 {
return 0, nil
}
pi := off >> f.pgBits
po := int(off) & f.pgMask
n = len(b)
@@ -319,11 +335,23 @@ func (f *file) Truncate(size int64) (err error) {
}
first := size >> f.pgBits
if size&int64(f.pgMask) != 0 {
if po := size & int64(f.pgMask); po != 0 {
if p := f.m[first]; p != nil {
b := p[po:]
for i := range b {
b[i] = 0
}
}
first++
}
last := f.size >> f.pgBits
if f.size&int64(f.pgMask) != 0 {
if po := f.size & int64(f.pgMask); po != 0 {
if p := f.m[last]; p != nil {
b := p[po:]
for i := range b {
b[i] = 0
}
}
last++
}
for ; first <= last; first++ {
@@ -349,6 +377,10 @@ func (f *file) Truncate(size int64) (err error) {
}
func (f *file) WriteAt(b []byte, off int64) (n int, err error) {
if len(b) == 0 {
return 0, nil
}
pi := off >> f.pgBits
po := int(off) & f.pgMask
n = len(b)

View File

@@ -7,6 +7,13 @@
//
// Release history and compatibility issues
//
// 2017-10-14: New variadic functions for Max/Min. Ex:
// func MaxVal(val int, vals ...int) int {
// func MinVal(val int, vals ...int) int {
// func MaxByteVal(val byte, vals ...byte) byte {
// func MinByteVal(val byte, vals ...byte) byte {
// ...
//
// 2016-10-10: New functions QuadPolyDiscriminant and QuadPolyFactors.
//
// 2013-12-13: The following functions have been REMOVED
@@ -631,6 +638,33 @@ func Min(a, b int) int {
return b
}
// MaxVal returns the largest argument passed.
func MaxVal(val int, vals ...int) int {
res := val
for _, v := range vals {
if v > res {
res = v
}
}
return res
}
// MinVal returns the smallest argument passed.
func MinVal(val int, vals ...int) int {
res := val
for _, v := range vals {
if v < res {
res = v
}
}
return res
}
// Clamp returns a value restricted between lo and hi.
func Clamp(v, lo, hi int) int {
return Min(Max(v, lo), hi)
}
// UMax returns the larger of a and b.
func UMax(a, b uint) uint {
if a > b {
@@ -649,6 +683,33 @@ func UMin(a, b uint) uint {
return b
}
// UMaxVal returns the largest argument passed.
func UMaxVal(val uint, vals ...uint) uint {
res := val
for _, v := range vals {
if v > res {
res = v
}
}
return res
}
// UMinVal returns the smallest argument passed.
func UMinVal(val uint, vals ...uint) uint {
res := val
for _, v := range vals {
if v < res {
res = v
}
}
return res
}
// UClamp returns a value restricted between lo and hi.
func UClamp(v, lo, hi uint) uint {
return UMin(UMax(v, lo), hi)
}
// MaxByte returns the larger of a and b.
func MaxByte(a, b byte) byte {
if a > b {
@@ -667,6 +728,33 @@ func MinByte(a, b byte) byte {
return b
}
// MaxByteVal returns the largest argument passed.
func MaxByteVal(val byte, vals ...byte) byte {
res := val
for _, v := range vals {
if v > res {
res = v
}
}
return res
}
// MinByteVal returns the smallest argument passed.
func MinByteVal(val byte, vals ...byte) byte {
res := val
for _, v := range vals {
if v < res {
res = v
}
}
return res
}
// ClampByte returns a value restricted between lo and hi.
func ClampByte(v, lo, hi byte) byte {
return MinByte(MaxByte(v, lo), hi)
}
// MaxInt8 returns the larger of a and b.
func MaxInt8(a, b int8) int8 {
if a > b {
@@ -685,6 +773,33 @@ func MinInt8(a, b int8) int8 {
return b
}
// MaxInt8Val returns the largest argument passed.
func MaxInt8Val(val int8, vals ...int8) int8 {
res := val
for _, v := range vals {
if v > res {
res = v
}
}
return res
}
// MinInt8Val returns the smallest argument passed.
func MinInt8Val(val int8, vals ...int8) int8 {
res := val
for _, v := range vals {
if v < res {
res = v
}
}
return res
}
// ClampInt8 returns a value restricted between lo and hi.
func ClampInt8(v, lo, hi int8) int8 {
return MinInt8(MaxInt8(v, lo), hi)
}
// MaxUint16 returns the larger of a and b.
func MaxUint16(a, b uint16) uint16 {
if a > b {
@@ -703,6 +818,33 @@ func MinUint16(a, b uint16) uint16 {
return b
}
// MaxUint16Val returns the largest argument passed.
func MaxUint16Val(val uint16, vals ...uint16) uint16 {
res := val
for _, v := range vals {
if v > res {
res = v
}
}
return res
}
// MinUint16Val returns the smallest argument passed.
func MinUint16Val(val uint16, vals ...uint16) uint16 {
res := val
for _, v := range vals {
if v < res {
res = v
}
}
return res
}
// ClampUint16 returns a value restricted between lo and hi.
func ClampUint16(v, lo, hi uint16) uint16 {
return MinUint16(MaxUint16(v, lo), hi)
}
// MaxInt16 returns the larger of a and b.
func MaxInt16(a, b int16) int16 {
if a > b {
@@ -721,6 +863,33 @@ func MinInt16(a, b int16) int16 {
return b
}
// MaxInt16Val returns the largest argument passed.
func MaxInt16Val(val int16, vals ...int16) int16 {
res := val
for _, v := range vals {
if v > res {
res = v
}
}
return res
}
// MinInt16Val returns the smallest argument passed.
func MinInt16Val(val int16, vals ...int16) int16 {
res := val
for _, v := range vals {
if v < res {
res = v
}
}
return res
}
// ClampInt16 returns a value restricted between lo and hi.
func ClampInt16(v, lo, hi int16) int16 {
return MinInt16(MaxInt16(v, lo), hi)
}
// MaxUint32 returns the larger of a and b.
func MaxUint32(a, b uint32) uint32 {
if a > b {
@@ -739,6 +908,33 @@ func MinUint32(a, b uint32) uint32 {
return b
}
// MaxUint32Val returns the largest argument passed.
func MaxUint32Val(val uint32, vals ...uint32) uint32 {
res := val
for _, v := range vals {
if v > res {
res = v
}
}
return res
}
// MinUint32Val returns the smallest argument passed.
func MinUint32Val(val uint32, vals ...uint32) uint32 {
res := val
for _, v := range vals {
if v < res {
res = v
}
}
return res
}
// ClampUint32 returns a value restricted between lo and hi.
func ClampUint32(v, lo, hi uint32) uint32 {
return MinUint32(MaxUint32(v, lo), hi)
}
// MaxInt32 returns the larger of a and b.
func MaxInt32(a, b int32) int32 {
if a > b {
@@ -757,6 +953,33 @@ func MinInt32(a, b int32) int32 {
return b
}
// MaxInt32Val returns the largest argument passed.
func MaxInt32Val(val int32, vals ...int32) int32 {
res := val
for _, v := range vals {
if v > res {
res = v
}
}
return res
}
// MinInt32Val returns the smallest argument passed.
func MinInt32Val(val int32, vals ...int32) int32 {
res := val
for _, v := range vals {
if v < res {
res = v
}
}
return res
}
// ClampInt32 returns a value restricted between lo and hi.
func ClampInt32(v, lo, hi int32) int32 {
return MinInt32(MaxInt32(v, lo), hi)
}
// MaxUint64 returns the larger of a and b.
func MaxUint64(a, b uint64) uint64 {
if a > b {
@@ -775,6 +998,33 @@ func MinUint64(a, b uint64) uint64 {
return b
}
// MaxUint64Val returns the largest argument passed.
func MaxUint64Val(val uint64, vals ...uint64) uint64 {
res := val
for _, v := range vals {
if v > res {
res = v
}
}
return res
}
// MinUint64Val returns the smallest argument passed.
func MinUint64Val(val uint64, vals ...uint64) uint64 {
res := val
for _, v := range vals {
if v < res {
res = v
}
}
return res
}
// ClampUint64 returns a value restricted between lo and hi.
func ClampUint64(v, lo, hi uint64) uint64 {
return MinUint64(MaxUint64(v, lo), hi)
}
// MaxInt64 returns the larger of a and b.
func MaxInt64(a, b int64) int64 {
if a > b {
@@ -793,6 +1043,33 @@ func MinInt64(a, b int64) int64 {
return b
}
// MaxInt64Val returns the largest argument passed.
func MaxInt64Val(val int64, vals ...int64) int64 {
res := val
for _, v := range vals {
if v > res {
res = v
}
}
return res
}
// MinInt64Val returns the smallest argument passed.
func MinInt64Val(val int64, vals ...int64) int64 {
res := val
for _, v := range vals {
if v < res {
res = v
}
}
return res
}
// ClampInt64 returns a value restricted between lo and hi.
func ClampInt64(v, lo, hi int64) int64 {
return MinInt64(MaxInt64(v, lo), hi)
}
// ToBase produces n in base b. For example
//
// ToBase(2047, 22) -> [1, 5, 4]

View File

@@ -146,7 +146,7 @@ It is conjectured that every odd d ∊ N divides infinitely many Mersenne number
The returned n should be the exponent of smallest such Mn.
NOTE: The computation of n from a given d performs roughly in O(n). It is
thus highly recomended to use the 'max' argument to limit the "searched"
thus highly recommended to use the 'max' argument to limit the "searched"
exponent upper bound as appropriate. Otherwise the computation can take a long
time as a large factor can be a divisor of a Mn with exponent above the uint32
limits.

View File

@@ -270,7 +270,6 @@ func (t *tree) extract(q *d, i int) { // (r []interface{}) {
}
q.d[q.c] = zde // GC
t.c--
return
}
func (t *tree) find(q interface{}, k []interface{}) (i int, ok bool) {
@@ -491,7 +490,6 @@ func (t *tree) Set(k []interface{}, v []interface{}) {
z := t.insert(&d{}, 0, k, v)
t.r, t.first, t.last = z, z, z
return
}
func (t *tree) split(p *x, q *d, pi, i int, k []interface{}, v []interface{}) {

View File

@@ -53,6 +53,7 @@ var builtin = map[string]struct {
"second": {builtinSecond, 1, 1, true, false},
"seconds": {builtinSeconds, 1, 1, true, false},
"since": {builtinSince, 1, 1, false, false},
"sleep": {builtinSleep, 1, 1, false, false},
"sum": {builtinSum, 1, 1, false, true},
"timeIn": {builtinTimeIn, 2, 2, true, false},
"weekday": {builtinWeekday, 1, 1, true, false},
@@ -873,6 +874,26 @@ func builtinSince(arg []interface{}, ctx map[interface{}]interface{}) (v interfa
}
}
func builtinSleep(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
switch x := arg[0].(type) {
case nil:
return nil, nil
case time.Duration:
time.Sleep(x)
return nil, nil
case idealInt:
v := time.Second * time.Duration(int64(x))
time.Sleep(v)
return nil, nil
case int64:
v := time.Second * time.Duration(x)
time.Sleep(v)
return nil, nil
default:
return nil, invArg(x, "sleep")
}
}
func builtinSum(arg []interface{}, ctx map[interface{}]interface{}) (v interface{}, err error) {
if _, ok := ctx["$agg0"]; ok {
return

21
vendor/github.com/cznic/ql/doc.go generated vendored
View File

@@ -213,12 +213,14 @@
// newline = . // the Unicode code point U+000A
// unicode_char = . // an arbitrary Unicode code point except newline
// ascii_letter = "a" … "z" | "A" … "Z" .
// unicode_letter = . // Unicode category L.
// unicode_digit = . // Unocode category D.
//
// Letters and digits
//
// The underscore character _ (U+005F) is considered a letter.
//
// letter = ascii_letter | "_" .
// letter = ascii_letter | unicode_letter | "_" .
// decimal_digit = "0" … "9" .
// octal_digit = "0" … "7" .
// hex_digit = "0" … "9" | "A" … "F" | "a" … "f" .
@@ -262,7 +264,7 @@
// identifier is a sequence of one or more letters and digits. The first
// character in an identifier must be a letter.
//
// identifier = letter { letter | decimal_digit } .
// identifier = letter { letter | decimal_digit | unicode_digit } .
//
// For example
//
@@ -1089,7 +1091,7 @@
//
// - Rational values are comparable and ordered, in the usual way.
//
// - String values are comparable and ordered, lexically byte-wise.
// - String and Blob values are comparable and ordered, lexically byte-wise.
//
// - Time values are comparable and ordered.
//
@@ -1738,7 +1740,7 @@
// The result can be filtered using a WhereClause and orderd by the OrderBy
// clause.
//
// SelectStmt = "SELECT" [ "DISTINCT" ] ( "*" | FieldList ) "FROM" RecordSetList
// SelectStmt = "SELECT" [ "DISTINCT" ] ( "*" | FieldList ) [ "FROM" RecordSetList ]
// [ JoinClause ] [ WhereClause ] [ GroupByClause ] [ OrderBy ] [ Limit ] [ Offset ].
//
// JoinClause = ( "LEFT" | "RIGHT" | "FULL" ) [ "OUTER" ] "JOIN" RecordSet "ON" Expression .
@@ -1878,7 +1880,16 @@
// It is an error if the expression evaluates to a non null value of non bool
// type.
//
// WhereClause = "WHERE" Expression .
// Another form of the WHERE clause is an existence predicate of a
// parenthesized select statement. The EXISTS form evaluates to true if the
// parenthesized SELECT statement produces a non empty record set. The NOT
// EXISTS form evaluates to true if the parenthesized SELECT statement produces
// an empty record set. The parenthesized SELECT statement is evaluated only
// once (TODO issue #159).
//
// WhereClause = "WHERE" Expression
// | "WHERE" "EXISTS" "(" SelectStmt ")"
// | "WHERE" "NOT" "EXISTS" "(" SelectStmt ")" .
//
// Recordset grouping
//

48
vendor/github.com/cznic/ql/driver.go generated vendored
View File

@@ -375,10 +375,8 @@ func driverQuery(db *driverDB, ctx *TCtx, list List, args []driver.Value) (drive
switch n := len(rss); n {
case 0:
return nil, errNoResult
case 1:
return newdriverRows(rss[len(rss)-1]), nil
default:
return nil, fmt.Errorf("query produced %d result sets, expected only one", n)
return newDriverMultiRows(rss), nil
}
}
@@ -469,7 +467,7 @@ func (r *driverRows) Next(dest []driver.Value) error {
switch v := xi.(type) {
case nil, int64, float64, bool, []byte, time.Time:
dest[i] = v
case complex64, complex128, *big.Int, *big.Rat:
case complex64, complex128, *big.Int, *big.Rat, idealComplex:
var buf bytes.Buffer
fmt.Fprintf(&buf, "%v", v)
dest[i] = buf.Bytes()
@@ -495,6 +493,12 @@ func (r *driverRows) Next(dest []driver.Value) error {
dest[i] = int64(v)
case string:
dest[i] = []byte(v)
case idealInt:
dest[i] = int64(v)
case idealUint:
dest[i] = int64(v)
case idealFloat:
dest[i] = float64(v)
default:
return fmt.Errorf("internal error 004")
}
@@ -508,6 +512,42 @@ func (r *driverRows) Next(dest []driver.Value) error {
}
}
type driverMultiRows struct {
rs []Recordset
pos int
active *driverRows
}
func newDriverMultiRows(rs []Recordset) *driverMultiRows {
return &driverMultiRows{
rs: rs,
active: newdriverRows(rs[0]),
}
}
func (r *driverMultiRows) Columns() []string {
return r.active.Columns()
}
func (r *driverMultiRows) Close() error {
return r.active.Close()
}
func (r *driverMultiRows) HasNextResultSet() bool {
return r.pos+1 < len(r.rs)
}
func (r *driverMultiRows) NextResultSet() error {
if r.HasNextResultSet() {
r.active.Close()
r.pos++
r.active = newdriverRows(r.rs[r.pos])
return nil
}
return io.EOF
}
func (r *driverMultiRows) Next(dest []driver.Value) error {
return r.active.Next(dest)
}
// driverStmt is a prepared statement. It is bound to a driverConn and not used
// by multiple goroutines concurrently.
type driverStmt struct {

140
vendor/github.com/cznic/ql/driver1.8.go generated vendored Normal file
View File

@@ -0,0 +1,140 @@
// +build go1.8
package ql
import (
"context"
"database/sql/driver"
"fmt"
"strconv"
"strings"
)
const prefix = "$"
func (c *driverConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
query, vals, err := replaceNamed(query, args)
if err != nil {
return nil, err
}
return c.Exec(query, vals)
}
func replaceNamed(query string, args []driver.NamedValue) (string, []driver.Value, error) {
toks, err := tokenize(query)
if err != nil {
return "", nil, err
}
a := make([]driver.Value, len(args))
m := map[string]int{}
for _, v := range args {
m[v.Name] = v.Ordinal
a[v.Ordinal-1] = v.Value
}
for i, v := range toks {
if len(v) > 1 && strings.HasPrefix(v, prefix) {
if v[1] >= '1' && v[1] <= '9' {
continue
}
nm := v[1:]
k, ok := m[nm]
if !ok {
return query, nil, fmt.Errorf("unknown named parameter %s", nm)
}
toks[i] = fmt.Sprintf("$%d", k)
}
}
return strings.Join(toks, " "), a, nil
}
func (c *driverConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
query, vals, err := replaceNamed(query, args)
if err != nil {
return nil, err
}
return c.Query(query, vals)
}
func (c *driverConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
query, err := filterNamedArgs(query)
if err != nil {
return nil, err
}
return c.Prepare(query)
}
func filterNamedArgs(query string) (string, error) {
toks, err := tokenize(query)
if err != nil {
return "", err
}
n := 0
for _, v := range toks {
if len(v) > 1 && strings.HasPrefix(v, prefix) && v[1] >= '1' && v[1] <= '9' {
m, err := strconv.ParseUint(v[1:], 10, 31)
if err != nil {
return "", err
}
if int(m) > n {
n = int(m)
}
}
}
for i, v := range toks {
if len(v) > 1 && strings.HasPrefix(v, prefix) {
if v[1] >= '1' && v[1] <= '9' {
continue
}
n++
toks[i] = fmt.Sprintf("$%d", n)
}
}
return strings.Join(toks, " "), nil
}
func (s *driverStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
a := make([]driver.Value, len(args))
for k, v := range args {
a[k] = v.Value
}
return s.Exec(a)
}
func (s *driverStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
a := make([]driver.Value, len(args))
for k, v := range args {
a[k] = v.Value
}
return s.Query(a)
}
func tokenize(s string) (r []string, _ error) {
lx, err := newLexer(s)
if err != nil {
return nil, err
}
var lval yySymType
for lx.Lex(&lval) != 0 {
s := string(lx.TokenBytes(nil))
if s != "" {
switch s[len(s)-1] {
case '"':
s = "\"" + s
case '`':
s = "`" + s
}
}
r = append(r, s)
}
return r, nil
}

43
vendor/github.com/cznic/ql/expr.go generated vendored
View File

@@ -5,6 +5,7 @@
package ql
import (
"bytes"
"fmt"
"math/big"
"regexp"
@@ -779,6 +780,13 @@ func (o *binaryOperation) eval(execCtx *execCtx, ctx map[interface{}]interface{}
default:
return invOp2(x, y, op)
}
case []byte:
switch y := b.(type) {
case []byte:
return bytes.Equal(x, y), nil
default:
return invOp2(x, y, op)
}
default:
return invOp2(a, b, op)
}
@@ -930,6 +938,13 @@ func (o *binaryOperation) eval(execCtx *execCtx, ctx map[interface{}]interface{}
default:
return invOp2(x, y, op)
}
case []byte:
switch y := b.(type) {
case []byte:
return bytes.Compare(x, y) < 0, nil
default:
return invOp2(x, y, op)
}
default:
return invOp2(a, b, op)
}
@@ -1081,6 +1096,13 @@ func (o *binaryOperation) eval(execCtx *execCtx, ctx map[interface{}]interface{}
default:
return invOp2(x, y, op)
}
case []byte:
switch y := b.(type) {
case []byte:
return bytes.Compare(x, y) <= 0, nil
default:
return invOp2(x, y, op)
}
default:
return invOp2(a, b, op)
}
@@ -1232,6 +1254,13 @@ func (o *binaryOperation) eval(execCtx *execCtx, ctx map[interface{}]interface{}
default:
return invOp2(x, y, op)
}
case []byte:
switch y := b.(type) {
case []byte:
return bytes.Compare(x, y) >= 0, nil
default:
return invOp2(x, y, op)
}
default:
return invOp2(a, b, op)
}
@@ -1403,6 +1432,13 @@ func (o *binaryOperation) eval(execCtx *execCtx, ctx map[interface{}]interface{}
default:
return invOp2(x, y, op)
}
case []byte:
switch y := b.(type) {
case []byte:
return !bytes.Equal(x, y), nil
default:
return invOp2(x, y, op)
}
default:
return invOp2(a, b, op)
}
@@ -1574,6 +1610,13 @@ func (o *binaryOperation) eval(execCtx *execCtx, ctx map[interface{}]interface{}
default:
return invOp2(x, y, op)
}
case []byte:
switch y := b.(type) {
case []byte:
return bytes.Equal(x, y), nil
default:
return invOp2(x, y, op)
}
default:
return invOp2(a, b, op)
}

154
vendor/github.com/cznic/ql/lexer.go generated vendored Normal file
View File

@@ -0,0 +1,154 @@
// Copyright 2017 The ql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ql
import (
"fmt"
"go/scanner"
"go/token"
"math"
"strconv"
"strings"
"unicode"
"github.com/cznic/golex/lex"
)
const (
ccEOF = iota + 0x80
ccLetter
ccDigit
ccOther
)
func runeClass(r rune) int {
switch {
case r == lex.RuneEOF:
return ccEOF
case r < 0x80:
return int(r)
case unicode.IsLetter(r):
return ccLetter
case unicode.IsDigit(r):
return ccDigit
default:
return ccOther
}
}
type lexer struct {
*lex.Lexer
agg []bool
col int
errs scanner.ErrorList
expr expression
file *token.File
inj int
line int
list []stmt
params int
root bool
sc int
}
func newLexer(src string) (*lexer, error) {
fset := token.NewFileSet()
file := fset.AddFile("", -1, len(src))
l := &lexer{
file: file,
}
l0, err := lex.New(
file,
strings.NewReader(src),
lex.ErrorFunc(func(pos token.Pos, msg string) {
l.errPos(pos, msg)
}),
lex.RuneClass(runeClass),
lex.BOMMode(lex.BOMIgnoreFirst),
)
if err != nil {
return nil, err
}
l.Lexer = l0
return l, nil
}
func (l *lexer) errPos(pos token.Pos, format string, arg ...interface{}) {
l.errs.Add(l.file.Position(pos), fmt.Sprintf(format, arg...))
}
func (l *lexer) err(s string, arg ...interface{}) {
l.errPos(l.Last.Pos(), s, arg...)
}
// Implements yyLexer.
func (l *lexer) Error(s string) {
l.err(s)
}
func (l *lexer) int(lval *yySymType, im bool) int {
val := l.TokenBytes(nil)
if im {
val = val[:len(val)-1]
}
n, err := strconv.ParseUint(string(val), 0, 64)
if err != nil {
l.err("integer literal: %v", err)
return int(unicode.ReplacementChar)
}
if im {
lval.item = idealComplex(complex(0, float64(n)))
return imaginaryLit
}
switch {
case n < math.MaxInt64:
lval.item = idealInt(n)
default:
lval.item = idealUint(n)
}
return intLit
}
func (l *lexer) float(lval *yySymType, im bool) int {
val := l.TokenBytes(nil)
if im {
val = val[:len(val)-1]
}
n, err := strconv.ParseFloat(string(val), 64)
if err != nil {
l.err("float literal: %v", err)
return int(unicode.ReplacementChar)
}
if im {
lval.item = idealComplex(complex(0, n))
return imaginaryLit
}
lval.item = idealFloat(n)
return floatLit
}
func (l *lexer) str(lval *yySymType, pref string) int {
val := l.TokenBytes(nil)
l.sc = 0
s := pref + string(val)
s, err := strconv.Unquote(s)
if err != nil {
l.err("string literal: %v", err)
return int(unicode.ReplacementChar)
}
lval.item = s
return stringLit
}
func (l *lexer) npos() (line, col int) {
pos := l.file.Position(l.Last.Pos())
return pos.Line, pos.Column
}

11
vendor/github.com/cznic/ql/mem.go generated vendored
View File

@@ -11,6 +11,7 @@ import (
"fmt"
"io"
"math/big"
"sync"
"time"
)
@@ -247,6 +248,7 @@ type mem struct {
recycler []int
tnl int
rollback *undos
mu sync.RWMutex
}
func newMemStorage() (s *mem, err error) {
@@ -278,10 +280,13 @@ func (s *mem) newUndo(tag int, h int64, data []interface{}) {
func (s *mem) Acid() bool { return false }
func (s *mem) Close() (err error) {
s.mu.Lock()
defer s.mu.Unlock()
if s.tnl != 0 {
return fmt.Errorf("cannot close DB while open transaction exist")
}
*s = mem{}
s.data, s.recycler, s.rollback = nil, nil, nil
s.id, s.tnl = 0, 0
return
}
@@ -453,6 +458,8 @@ func (s *mem) Create(data ...interface{}) (h int64, err error) {
}
func (s *mem) Read(dst []interface{}, h int64, cols ...*col) (data []interface{}, err error) {
s.mu.RLock()
defer s.mu.RUnlock()
if i := int(h); i != 0 && i < len(s.data) {
d := s.clone(s.data[h]...)
if cols == nil {
@@ -822,7 +829,6 @@ func (t *xtree) extract(q *xd, i int) { // (r int64) {
}
q.xd[q.c] = zxde // GC
t.c--
return
}
func (t *xtree) find(q interface{}, k indexKey) (i int, ok bool) {
@@ -1043,7 +1049,6 @@ func (t *xtree) Set(k indexKey, v int) {
z := t.insert(&xd{}, 0, k, v)
t.r, t.first, t.last = z, z, z
return
}
func (t *xtree) split(p *xx, q *xd, pi, i int, k indexKey, v int) {

2059
vendor/github.com/cznic/ql/parser.go generated vendored

File diff suppressed because it is too large Load Diff

35
vendor/github.com/cznic/ql/plan.go generated vendored
View File

@@ -49,6 +49,7 @@ var (
_ plan = (*selectFieldsDefaultPlan)(nil)
_ plan = (*selectFieldsGroupPlan)(nil)
_ plan = (*selectIndexDefaultPlan)(nil)
_ plan = (*selectDummyPlan)(nil)
_ plan = (*sysColumnDefaultPlan)(nil)
_ plan = (*sysIndexDefaultPlan)(nil)
_ plan = (*sysTableDefaultPlan)(nil)
@@ -1379,9 +1380,7 @@ func (r *explainDefaultPlan) do(ctx *execCtx, f func(id interface{}, data []inte
return nil
}
func (r *explainDefaultPlan) explain(w strutil.Formatter) {
return
}
func (r *explainDefaultPlan) explain(w strutil.Formatter) {}
func (r *explainDefaultPlan) fieldNames() []string {
return []string{""}
@@ -2798,3 +2797,33 @@ func (r *fullJoinDefaultPlan) do(ctx *execCtx, f func(id interface{}, data []int
}
}
}
type selectDummyPlan struct {
flds []*fld
}
func (r *selectDummyPlan) hasID() bool { return true }
func (r *selectDummyPlan) explain(w strutil.Formatter) {
w.Format("┌Selects values from dummy table\n└Output field names %v\n", qnames(r.fieldNames()))
}
func (r *selectDummyPlan) fieldNames() []string { return make([]string, len(r.flds)) }
func (r *selectDummyPlan) filter(expr expression) (plan, []string, error) {
return nil, nil, nil
}
func (r *selectDummyPlan) do(ctx *execCtx, f func(id interface{}, data []interface{}) (bool, error)) (err error) {
m := map[interface{}]interface{}{}
data := []interface{}{}
for _, v := range r.flds {
rst, err := v.expr.eval(ctx, m)
if err != nil {
return err
}
data = append(data, rst)
}
_, err = f(nil, data)
return
}

124
vendor/github.com/cznic/ql/ql.go generated vendored
View File

@@ -330,8 +330,21 @@ func (r *orderByRset) plan(ctx *execCtx) (plan, error) {
}
type whereRset struct {
expr expression
src plan
expr expression
src plan
sel *selectStmt
exists bool
}
func (r *whereRset) String() string {
if r.sel != nil {
s := ""
if !r.exists {
s += " NOT "
}
return fmt.Sprintf("%s EXISTS ( %s )", s, strings.TrimSuffix(r.sel.String(), ";"))
}
return r.expr.String()
}
func (r *whereRset) planBinOp(x *binaryOperation) (plan, error) {
@@ -514,6 +527,44 @@ func (r *whereRset) planUnaryOp(x *unaryOperation) (plan, error) {
}
func (r *whereRset) plan(ctx *execCtx) (plan, error) {
o := r.src
if r.sel != nil {
var exists bool
ctx.mu.RLock()
m, ok := ctx.cache[r.sel]
ctx.mu.RUnlock()
if ok {
exists = m.(bool)
} else {
p, err := r.sel.plan(ctx)
if err != nil {
return nil, err
}
err = p.do(ctx, func(i interface{}, data []interface{}) (bool, error) {
if len(data) > 0 {
exists = true
}
return false, nil
})
if err != nil {
return nil, err
}
ctx.mu.Lock()
ctx.cache[r.sel] = true
ctx.mu.Unlock()
}
if r.exists == exists {
return o, nil
}
return &nullPlan{fields: o.fieldNames()}, nil
}
return r.planExpr(ctx)
}
func (r *whereRset) planExpr(ctx *execCtx) (plan, error) {
if r.expr == nil {
return &nullPlan{}, nil
}
expr, err := r.expr.clone(ctx.arg)
if err != nil {
return nil, err
@@ -567,6 +618,10 @@ type selectRset struct {
}
func (r *selectRset) plan(ctx *execCtx) (plan, error) {
if r.src == nil {
return nil, nil
}
var flds2 []*fld
if len(r.flds) != 0 {
m := map[string]struct{}{}
@@ -703,8 +758,7 @@ func findCol(cols []*col, name string) (c *col) {
}
func (f *col) clone() *col {
var r col
r = *f
r := *f
r.constraint = f.constraint.clone()
if f.dflt != nil {
r.dflt, _ = r.dflt.clone(nil)
@@ -795,7 +849,7 @@ func newDB(store storage) (db *DB, err error) {
return
}
ctx := &execCtx{db: db0}
ctx := newExecCtx(db0, nil)
for _, t := range db0.root.tables {
if err := t.constraintsAndDefaults(ctx); err != nil {
return nil, err
@@ -893,7 +947,7 @@ func newDB(store storage) (db *DB, err error) {
func (db *DB) deleteIndex2ByIndexName(nm string) error {
for _, s := range deleteIndex2ByIndexName.l {
if _, err := s.exec(&execCtx{db: db, arg: []interface{}{nm}}); err != nil {
if _, err := s.exec(newExecCtx(db, []interface{}{nm})); err != nil {
return err
}
}
@@ -902,7 +956,7 @@ func (db *DB) deleteIndex2ByIndexName(nm string) error {
func (db *DB) deleteIndex2ByTableName(nm string) error {
for _, s := range deleteIndex2ByTableName.l {
if _, err := s.exec(&execCtx{db: db, arg: []interface{}{nm}}); err != nil {
if _, err := s.exec(newExecCtx(db, []interface{}{nm})); err != nil {
return err
}
}
@@ -931,7 +985,7 @@ func (db *DB) createIndex2() error {
expr := "id()"
if i != 0 {
expr = t.cols[i-1].name
expr = t.cols0[i-1].name
}
if err := db.insertIndex2(t.name, index.name, []string{expr}, index.unique, true, index.xroot); err != nil {
@@ -1036,29 +1090,41 @@ func (db *DB) run(ctx *TCtx, ql string, arg ...interface{}) (rs []Recordset, ind
//
// Compile is safe for concurrent use by multiple goroutines.
func Compile(src string) (List, error) {
l := newLexer(src)
l, err := newLexer(src)
if err != nil {
return List{}, err
}
if yyParse(l) != 0 {
return List{}, l.errs[0]
return List{}, l.errs
}
return List{l.list, l.params}, nil
}
func compileExpr(src string) (expression, error) {
l := newLexer(src)
l, err := newLexer(src)
if err != nil {
return nil, err
}
l.inj = parseExpression
if yyParse(l) != 0 {
return nil, l.errs[0]
return nil, l.errs
}
return l.expr, nil
}
func compile(src string) (List, error) {
l := newLexer(src)
l, err := newLexer(src)
if err != nil {
return List{}, err
}
l.root = true
if yyParse(l) != 0 {
return List{}, l.errs[0]
return List{}, l.errs
}
return List{l.list, l.params}, nil
@@ -1263,7 +1329,7 @@ func (db *DB) run1(pc *TCtx, s stmt, arg ...interface{}) (rs Recordset, tnla, tn
db.rwmu.RLock() // can safely grab before Unlock
db.muUnlock()
defer db.rwmu.RUnlock()
rs, err = s.exec(&execCtx{db, arg}) // R/O tctx
rs, err = s.exec(newExecCtx(db, arg)) // R/O tctx
return rs, tnla, tnlb, err
}
default: // case true:
@@ -1345,7 +1411,7 @@ func (db *DB) run1(pc *TCtx, s stmt, arg ...interface{}) (rs Recordset, tnla, tn
db.muUnlock() // must Unlock before RLock
db.rwmu.RLock()
defer db.rwmu.RUnlock()
rs, err = s.exec(&execCtx{db, arg})
rs, err = s.exec(newExecCtx(db, arg))
return rs, tnla, tnlb, err
}
@@ -1355,7 +1421,7 @@ func (db *DB) run1(pc *TCtx, s stmt, arg ...interface{}) (rs Recordset, tnla, tn
return nil, tnla, tnlb, fmt.Errorf("invalid passed transaction context")
}
rs, err = s.exec(&execCtx{db, arg})
rs, err = s.exec(newExecCtx(db, arg))
return rs, tnla, tnlb, err
}
}
@@ -1523,13 +1589,13 @@ func (db *DB) info() (r *DbInfo, err error) {
ti := TableInfo{Name: nm}
m := map[string]*ColumnInfo{}
if hasColumn2 {
rs, err := selectColumn2.l[0].exec(&execCtx{db: db, arg: []interface{}{nm}})
rs, err := selectColumn2.l[0].exec(newExecCtx(db, []interface{}{nm}))
if err != nil {
return nil, err
}
if err := rs.(recordset).do(
&execCtx{db: db, arg: []interface{}{nm}},
newExecCtx(db, []interface{}{nm}),
func(id interface{}, data []interface{}) (bool, error) {
ci := &ColumnInfo{NotNull: data[1].(bool), Constraint: data[2].(string), Default: data[3].(string)}
m[data[0].(string)] = ci
@@ -1609,7 +1675,15 @@ type joinRset struct {
on expression
}
func (r *joinRset) isZero() bool {
return len(r.sources) == 0 && r.typ == 0 && r.on == nil
}
func (r *joinRset) String() string {
if r.isZero() {
return ""
}
a := make([]string, len(r.sources))
for i, pair0 := range r.sources {
pair := pair0.([]interface{})
@@ -1652,6 +1726,9 @@ func (r *joinRset) String() string {
}
func (r *joinRset) plan(ctx *execCtx) (plan, error) {
if r.isZero() {
return nil, nil
}
rsets := make([]plan, len(r.sources))
names := make([]string, len(r.sources))
var err error
@@ -1699,19 +1776,18 @@ func (r *joinRset) plan(ctx *execCtx) (plan, error) {
if f != "" && nm != "" {
f = fmt.Sprintf("%s.%s", nm, f)
}
if nm == "" {
f = ""
}
fields = append(fields, f)
}
}
rsets[i] = q
}
if len(rsets) == 1 {
switch len(rsets) {
case 0:
return nil, nil
case 1:
return rsets[0], nil
}
right := len(rsets[len(rsets)-1].fieldNames())
switch r.typ {
case crossJoin:

194
vendor/github.com/cznic/ql/ql/main.go generated vendored
View File

@@ -58,6 +58,7 @@ import (
"log"
"os"
"regexp"
"runtime"
"sort"
"strings"
"time"
@@ -84,22 +85,66 @@ func main() {
}
}
func do() (err error) {
oDB := flag.String("db", "ql.db", "The DB file to open. It'll be created if missing.")
oFlds := flag.Bool("fld", false, "Show recordset's field names.")
oSchema := flag.String("schema", "", "If non empty, show the CREATE statements of matching tables and exit.")
oTables := flag.String("tables", "", "If non empty, list matching table names and exit.")
oTime := flag.Bool("t", false, "Measure and report time to execute the statement(s) including DB create/open/close.")
type config struct {
db string
flds bool
schema string
tables string
time bool
help bool
interactive bool
}
func (c *config) parse() {
db := flag.String("db", "ql.db", "The DB file to open. It'll be created if missing.")
flds := flag.Bool("fld", false, "Show recordset's field names.")
schema := flag.String("schema", "", "If non empty, show the CREATE statements of matching tables and exit.")
tables := flag.String("tables", "", "If non empty, list matching table names and exit.")
time := flag.Bool("t", false, "Measure and report time to execute the statement(s) including DB create/open/close.")
help := flag.Bool("h", false, "Shows this help text.")
interactive := flag.Bool("i", false, "runs in interactive mode")
flag.Parse()
c.flds = *flds
c.db = *db
c.schema = *schema
c.tables = *tables
c.time = *time
c.help = *help
c.interactive = *interactive
}
t0 := time.Now()
if *oTime {
defer func() {
fmt.Fprintf(os.Stderr, "%s\n", time.Since(t0))
}()
func do() (err error) {
cfg := &config{}
cfg.parse()
if cfg.help {
flag.PrintDefaults()
return nil
}
if flag.NArg() == 0 && !cfg.interactive {
db, err := ql.OpenFile(*oDB, &ql.Options{CanCreate: true})
// Somehow we expect input to the ql tool.
// This will block trying to read input from stdin
b, err := ioutil.ReadAll(os.Stdin)
if err != nil || len(b) == 0 {
flag.PrintDefaults()
return nil
}
db, err := ql.OpenFile(cfg.db, &ql.Options{CanCreate: true})
if err != nil {
return err
}
defer func() {
ec := db.Close()
switch {
case ec != nil && err != nil:
log.Println(ec)
case ec != nil:
err = ec
}
}()
return run(cfg, bufio.NewWriter(os.Stdout), string(b), db)
}
db, err := ql.OpenFile(cfg.db, &ql.Options{CanCreate: true})
if err != nil {
return err
}
@@ -113,8 +158,85 @@ func do() (err error) {
err = ec
}
}()
r := bufio.NewReader(os.Stdin)
o := bufio.NewWriter(os.Stdout)
if cfg.interactive {
for {
o.WriteString("ql> ")
o.Flush()
src, err := readSrc(cfg.interactive, r)
if err != nil {
return err
}
err = run(cfg, o, src, db)
if err != nil {
fmt.Fprintln(o, err)
o.Flush()
}
}
return nil
}
src, err := readSrc(cfg.interactive, r)
if err != nil {
return err
}
return run(cfg, o, src, db)
}
if pat := *oSchema; pat != "" {
func readSrc(i bool, in *bufio.Reader) (string, error) {
if i {
return in.ReadString('\n')
}
var src string
switch n := flag.NArg(); n {
case 0:
b, err := ioutil.ReadAll(in)
if err != nil {
return "", err
}
src = string(b)
default:
a := make([]string, n)
for i := range a {
a[i] = flag.Arg(i)
}
src = strings.Join(a, " ")
}
return src, nil
}
func run(cfg *config, o *bufio.Writer, src string, db *ql.DB) (err error) {
defer o.Flush()
if cfg.interactive {
src = strings.TrimSpace(src)
if strings.HasPrefix(src, "\\") ||
strings.HasPrefix(src, ".") {
switch src {
case "\\clear", ".clear":
switch runtime.GOOS {
case "darwin", "linux":
fmt.Fprintln(o, "\033[H\033[2J")
default:
fmt.Fprintln(o, "clear not supported in this system")
}
return nil
case "\\q", "\\exit", ".q", ".exit":
// we make sure to close the database before exiting
db.Close()
os.Exit(1)
}
}
}
t0 := time.Now()
if cfg.time {
defer func() {
fmt.Fprintf(os.Stderr, "%s\n", time.Since(t0))
}()
}
if pat := cfg.schema; pat != "" {
re, err := regexp.Compile(pat)
if err != nil {
return err
@@ -139,12 +261,12 @@ func do() (err error) {
}
sort.Strings(r)
if len(r) != 0 {
fmt.Println(strings.Join(r, "\n"))
fmt.Fprintln(o, strings.Join(r, "\n"))
}
return nil
}
if pat := *oTables; pat != "" {
if pat := cfg.tables; pat != "" {
re, err := regexp.Compile(pat)
if err != nil {
return err
@@ -165,29 +287,18 @@ func do() (err error) {
}
sort.Strings(r)
if len(r) != 0 {
fmt.Println(strings.Join(r, "\n"))
fmt.Fprintln(o, strings.Join(r, "\n"))
}
return nil
}
var src string
switch n := flag.NArg(); n {
case 0:
b, err := ioutil.ReadAll(bufio.NewReader(os.Stdin))
if err != nil {
return err
}
src = strings.TrimSpace(src)
src = string(b)
default:
a := make([]string, n)
for i := range a {
a[i] = flag.Arg(i)
}
src = strings.Join(a, " ")
commit := "COMMIT;"
if !strings.HasSuffix(src, ";") {
commit = "; " + commit
}
src = "BEGIN TRANSACTION; " + src + "; COMMIT;"
src = "BEGIN TRANSACTION; " + src + commit
l, err := ql.Compile(src)
if err != nil {
log.Println(src)
@@ -206,14 +317,21 @@ func do() (err error) {
switch {
case l.IsExplainStmt():
return rs[len(rs)-1].Do(*oFlds, func(data []interface{}) (bool, error) {
fmt.Println(data[0])
return rs[len(rs)-1].Do(cfg.flds, func(data []interface{}) (bool, error) {
fmt.Fprintln(o, data[0])
return true, nil
})
default:
return rs[len(rs)-1].Do(*oFlds, func(data []interface{}) (bool, error) {
fmt.Println(str(data))
return true, nil
})
for _, rst := range rs {
err = rst.Do(cfg.flds, func(data []interface{}) (bool, error) {
fmt.Fprintln(o, str(data))
return true, nil
})
o.Flush()
if err != nil {
return
}
}
return
}
}

4862
vendor/github.com/cznic/ql/scanner.go generated vendored

File diff suppressed because it is too large Load Diff

53
vendor/github.com/cznic/ql/stmt.go generated vendored
View File

@@ -9,6 +9,8 @@ import (
"fmt"
"strings"
"sync"
"github.com/cznic/strutil"
)
@@ -121,8 +123,18 @@ type stmt interface {
}
type execCtx struct { //LATER +shared temp
db *DB
arg []interface{}
db *DB
arg []interface{}
cache map[interface{}]interface{}
mu sync.RWMutex
}
func newExecCtx(db *DB, arg []interface{}) *execCtx {
return &execCtx{
db: db,
arg: arg,
cache: make(map[interface{}]interface{}),
}
}
type explainStmt struct {
@@ -571,7 +583,7 @@ func (s *alterTableDropColumnStmt) exec(ctx *execCtx) (Recordset, error) {
}
if _, ok := ctx.db.root.tables["__Column2"]; ok {
if _, err := deleteColumn2.l[0].exec(&execCtx{db: ctx.db, arg: []interface{}{s.tableName, c.name}}); err != nil {
if _, err := deleteColumn2.l[0].exec(newExecCtx(ctx.db, []interface{}{s.tableName, c.name})); err != nil {
return nil, err
}
}
@@ -680,7 +692,7 @@ func (s *alterTableAddStmt) exec(ctx *execCtx) (Recordset, error) {
if c.constraint != nil || c.dflt != nil {
for _, s := range createColumn2.l {
_, err := s.exec(&execCtx{db: ctx.db})
_, err := s.exec(newExecCtx(ctx.db, nil))
if err != nil {
return nil, err
}
@@ -693,7 +705,7 @@ func (s *alterTableAddStmt) exec(ctx *execCtx) (Recordset, error) {
if e := c.dflt; e != nil {
d = e.String()
}
if _, err := insertColumn2.l[0].exec(&execCtx{db: ctx.db, arg: []interface{}{s.tableName, c.name, notNull, co, d}}); err != nil {
if _, err := insertColumn2.l[0].exec(newExecCtx(ctx.db, []interface{}{s.tableName, c.name, notNull, co, d})); err != nil {
return nil, err
}
}
@@ -750,11 +762,16 @@ func (s *selectStmt) String() string {
}
b.WriteString(" " + strings.Join(a, ", "))
}
b.WriteString(" FROM ")
b.WriteString(s.from.String())
if s.from != nil {
if !s.from.isZero() {
b.WriteString(" FROM ")
b.WriteString(s.from.String())
}
}
if s.where != nil {
b.WriteString(" WHERE ")
b.WriteString(s.where.expr.String())
b.WriteString(s.where.String())
}
if s.group != nil {
b.WriteString(" GROUP BY ")
@@ -777,13 +794,19 @@ func (s *selectStmt) String() string {
}
func (s *selectStmt) plan(ctx *execCtx) (plan, error) { //LATER overlapping goroutines/pipelines
r, err := s.from.plan(ctx)
if err != nil {
return nil, err
var r plan
var err error
if s.from != nil {
r, err = s.from.plan(ctx)
if err != nil {
return nil, err
}
}
if r == nil {
return &selectDummyPlan{flds: s.flds}, nil
}
if w := s.where; w != nil {
if r, err = (&whereRset{expr: w.expr, src: r}).plan(ctx); err != nil {
if r, err = (&whereRset{expr: w.expr, src: r, sel: w.sel, exists: w.exists}).plan(ctx); err != nil {
return nil, err
}
}
@@ -1234,7 +1257,7 @@ func (s *createTableStmt) exec(ctx *execCtx) (_ Recordset, err error) {
if c.constraint != nil || c.dflt != nil {
if mustCreateColumn2 {
for _, stmt := range createColumn2.l {
_, err := stmt.exec(&execCtx{db: ctx.db})
_, err := stmt.exec(newExecCtx(ctx.db, nil))
if err != nil {
return nil, err
}
@@ -1250,7 +1273,7 @@ func (s *createTableStmt) exec(ctx *execCtx) (_ Recordset, err error) {
if e := c.dflt; e != nil {
d = e.String()
}
if _, err := insertColumn2.l[0].exec(&execCtx{db: ctx.db, arg: []interface{}{s.tableName, c.name, notNull, co, d}}); err != nil {
if _, err := insertColumn2.l[0].exec(newExecCtx(ctx.db, []interface{}{s.tableName, c.name, notNull, co, d})); err != nil {
return nil, err
}
}

View File

@@ -153,7 +153,7 @@ func (t *table) constraintsAndDefaults(ctx *execCtx) error {
constraints := make([]*constraint, len(cols))
defaults := make([]expression, len(cols))
arg := []interface{}{t.name}
rs, err := selectColumn2.l[0].exec(&execCtx{db: ctx.db, arg: arg})
rs, err := selectColumn2.l[0].exec(newExecCtx(ctx.db, arg))
if err != nil {
return err
}
@@ -161,7 +161,7 @@ func (t *table) constraintsAndDefaults(ctx *execCtx) error {
var rows [][]interface{}
ok = false
if err := rs.(recordset).do(
&execCtx{db: ctx.db, arg: arg},
newExecCtx(ctx.db, arg),
func(id interface{}, data []interface{}) (more bool, err error) {
rows = append(rows, data)
return true, nil
@@ -330,7 +330,7 @@ func (t *table) findIndexByColName(name string) (*col, *indexedCol) {
continue
}
if c := t.cols[i-1]; c.name == name {
if c := t.cols0[i-1]; c.name == name {
return c, v
}
}
@@ -784,7 +784,11 @@ func (t *table) row(ctx *execCtx, h int64) (int64, []interface{}, error) {
return -1, nil, err
}
return rec[1].(int64), rec[2:], nil
id := rec[1].(int64)
for i, c := range t.cols {
rec[i] = rec[c.index+2]
}
return id, rec[:len(t.cols)], nil
}
// storage fields

View File

@@ -397,7 +397,7 @@ func (d *GoDict) S(id int) (s string, ok bool) {
// to a string slice over an unreferenced biger underlying string keeps the biger one
// in memory anyway - it can't be GCed.
func StrPack(s string) string {
return string([]byte(s))
return string([]byte(s)) // T(U(T)) intentional.
}
// JoinFields returns strings in flds joined by sep. Flds may contain arbitrary
@@ -665,6 +665,19 @@ func Gopath() string {
}
}
// Homepath returns the user's home directory path.
func Homepath() string {
// go1.8: https://github.com/golang/go/blob/74628a8b9f102bddd5078ee426efe0fd57033115/doc/code.html#L122
switch runtime.GOOS {
case "plan9":
return os.Getenv("home")
case "windows":
return os.Getenv("USERPROFILE")
default:
return os.Getenv("HOME")
}
}
// ImportPath returns the import path of the caller or an error, if any.
func ImportPath() (string, error) {
_, file, _, ok := runtime.Caller(1)