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

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