vendor: Update everything
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4620
This commit is contained in:
2
vendor/github.com/cznic/ql/btree.go
generated
vendored
2
vendor/github.com/cznic/ql/btree.go
generated
vendored
@@ -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{}) {
|
||||
|
||||
21
vendor/github.com/cznic/ql/builtin.go
generated
vendored
21
vendor/github.com/cznic/ql/builtin.go
generated
vendored
@@ -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
21
vendor/github.com/cznic/ql/doc.go
generated
vendored
@@ -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
48
vendor/github.com/cznic/ql/driver.go
generated
vendored
@@ -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
140
vendor/github.com/cznic/ql/driver1.8.go
generated
vendored
Normal 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
43
vendor/github.com/cznic/ql/expr.go
generated
vendored
@@ -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
154
vendor/github.com/cznic/ql/lexer.go
generated
vendored
Normal 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
11
vendor/github.com/cznic/ql/mem.go
generated
vendored
@@ -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
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
35
vendor/github.com/cznic/ql/plan.go
generated
vendored
@@ -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
124
vendor/github.com/cznic/ql/ql.go
generated
vendored
@@ -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
194
vendor/github.com/cznic/ql/ql/main.go
generated
vendored
@@ -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
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
53
vendor/github.com/cznic/ql/stmt.go
generated
vendored
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
12
vendor/github.com/cznic/ql/storage.go
generated
vendored
12
vendor/github.com/cznic/ql/storage.go
generated
vendored
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user