Skip to content

Commit f182be0

Browse files
committed
Added UNION [ ALL ]. Simplified Index API.
1 parent 55edbb6 commit f182be0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+298
-403
lines changed

algebra/aggregate.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ func (this *aggregateBase) EquivalentTo(other expression.Expression) bool {
5252
}
5353

5454
func (this *aggregateBase) Dependencies() expression.Expressions {
55-
return nil
55+
if this.parameter != nil {
56+
return expression.Expressions{this.parameter}
57+
} else {
58+
return nil
59+
}
5660
}
5761

5862
func (this *aggregateBase) Alias() string {
@@ -67,6 +71,14 @@ func (this *aggregateBase) Fold() expression.Expression {
6771
return this
6872
}
6973

74+
func (this *aggregateBase) SubsetOf(other expression.Expression) bool {
75+
return false
76+
}
77+
78+
func (this *aggregateBase) Spans(index expression.Index) expression.Spans {
79+
return nil
80+
}
81+
7082
func (this *aggregateBase) Parameter() expression.Expression {
7183
return this.parameter
7284
}

catalog/index.go

+9-54
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,16 @@ const (
2525

2626
// Index is the base type for all indexes.
2727
type Index interface {
28+
expression.Index
2829
BucketId() string
2930
Id() string
3031
Name() string
3132
Type() IndexType
32-
Equal() expression.CompositeExpression
33-
Range() expression.CompositeExpression
3433
Drop() err.Error // PrimaryIndexes cannot be dropped
34+
Statistics(span *expression.Span) (Statistics, err.Error)
35+
Scan(span *expression.Span, conn *IndexConnection)
36+
CandidateMins(span *expression.Span, conn *IndexConnection) // Anywhere from single min value to Scan()
37+
CandidateMaxes(span *expression.Span, conn *IndexConnection) // Anywhere from single max value to Scan()
3538
}
3639

3740
type IndexEntry struct {
@@ -44,65 +47,17 @@ type StopChannel chan bool
4447

4548
// PrimaryIndex represents primary key indexes.
4649
type PrimaryIndex interface {
47-
EqualIndex
48-
PrimaryScan(conn *IndexConnection)
49-
}
50-
51-
// EqualIndexes support equality matching.
52-
type EqualIndex interface {
5350
Index
54-
EqualScan(equal value.CompositeValue, conn *IndexConnection)
55-
EqualCount(equal value.CompositeValue) (int64, err.Error)
56-
}
57-
58-
// Inclusion controls how the boundary values of a range are treated.
59-
type RangeInclusion int
60-
61-
const (
62-
NEITHER RangeInclusion = iota
63-
LOW
64-
HIGH
65-
BOTH
66-
)
67-
68-
type Ranges []*Range
69-
70-
type Range struct {
71-
Low value.CompositeValue
72-
High value.CompositeValue
73-
Inclusion RangeInclusion
74-
}
75-
76-
// RangeIndexes support unrestricted range queries.
77-
type RangeIndex interface {
78-
Index
79-
RangeStats(ranje *Range) (RangeStatistics, err.Error)
80-
RangeScan(ranje *Range, conn *IndexConnection)
81-
RangeCandidateMins(ranje *Range, conn *IndexConnection) // Anywhere from single Min value to RangeScan()
82-
RangeCandidateMaxes(ranje *Range, conn *IndexConnection) // Anywhere from single Max value to RangeScan()
83-
}
84-
85-
type Dual struct {
86-
Equal value.CompositeValue
87-
Range
88-
}
89-
90-
// DualIndexes support restricted range queries.
91-
type DualIndex interface {
92-
Index
93-
DualStats(dual *Dual) (RangeStatistics, err.Error)
94-
DualScan(dual *Dual, conn *IndexConnection)
95-
DualCandidateMins(dual *Dual, conn *IndexConnection) // Anywhere from single Min value to DualScan()
96-
DualCandidateMaxes(dual *Dual, conn *IndexConnection) // Anywhere from single Max value to DualScan()
51+
PrimaryScan(conn *IndexConnection)
9752
}
9853

99-
// RangeStatistics captures statistics for an index range.
100-
type RangeStatistics interface {
54+
// Statistics captures statistics for an index span.
55+
type Statistics interface {
10156
Count() (int64, err.Error)
10257
Min() (value.Value, err.Error)
10358
Max() (value.Value, err.Error)
10459
DistinctCount(int64, err.Error)
105-
Bins() ([]RangeStatistics, err.Error)
60+
Bins() ([]Statistics, err.Error)
10661
}
10762

10863
type IndexConnection struct {
0 Bytes

docs/diagram/alias.png

0 Bytes

docs/diagram/arithmetic-term.png

0 Bytes

docs/diagram/array-expr.png

0 Bytes

docs/diagram/array.png

0 Bytes

docs/diagram/block-comment.png

0 Bytes

docs/diagram/case-expr.png

0 Bytes

docs/diagram/char.png

0 Bytes

docs/diagram/chars.png

0 Bytes

docs/diagram/collection-cond.png

0 Bytes

docs/diagram/collection-expr.png

0 Bytes

docs/diagram/collection-xform.png

0 Bytes

docs/diagram/comparison-term.png

0 Bytes

docs/diagram/concatenation-term.png

0 Bytes

docs/diagram/cond.png

0 Bytes

docs/diagram/digit.png

0 Bytes

docs/diagram/digits.png

0 Bytes

docs/diagram/e.png

0 Bytes

docs/diagram/elements.png

0 Bytes

docs/diagram/escaped-identifier.png

0 Bytes

docs/diagram/exists-expr.png

0 Bytes

docs/diagram/exp.png

0 Bytes

docs/diagram/expr.png

0 Bytes

docs/diagram/first-expr.png

0 Bytes

docs/diagram/frac.png

0 Bytes

docs/diagram/from-clause.png

0 Bytes

docs/diagram/from-path.png

0 Bytes

docs/diagram/from-select-core.png

0 Bytes

docs/diagram/from-term.png

0 Bytes

docs/diagram/function-call.png

0 Bytes

docs/diagram/function-name.png

0 Bytes

docs/diagram/group-by-clause.png

0 Bytes

docs/diagram/having-clause.png

0 Bytes

docs/diagram/hex-digit.png

0 Bytes

docs/diagram/identifier.png

0 Bytes

docs/diagram/in-expr.png

0 Bytes

docs/diagram/int.png

0 Bytes

docs/diagram/join-clause.png

0 Bytes

docs/diagram/join-type.png

0 Bytes

docs/diagram/keys-clause.png

0 Bytes

docs/diagram/let-clause.png

0 Bytes

docs/diagram/letting-clause.png

0 Bytes

docs/diagram/limit-clause.png

0 Bytes

docs/diagram/line-comment.png

0 Bytes

docs/diagram/literal-value.png

0 Bytes

docs/diagram/logical-term.png

0 Bytes

docs/diagram/members.png

0 Bytes

docs/diagram/nest-clause.png

0 Bytes

docs/diagram/nested-expr.png

0 Bytes

docs/diagram/non-zero-digit.png

0 Bytes

docs/diagram/number.png

0 Bytes

docs/diagram/object.png

0 Bytes

docs/diagram/offset-clause.png

0 Bytes

docs/diagram/order-by-clause.png

0 Bytes

docs/diagram/ordering-term.png

0 Bytes

docs/diagram/pair.png

0 Bytes

docs/diagram/path.png

0 Bytes

docs/diagram/pool-name.png

0 Bytes

docs/diagram/result-expr.png

0 Bytes

docs/diagram/searched-case-expr.png

0 Bytes

docs/diagram/select-clause.png

0 Bytes

docs/diagram/select-core.png

0 Bytes

docs/diagram/select-from-core.png

0 Bytes

docs/diagram/select.png

2.89 KB

docs/diagram/simple-case-expr.png

0 Bytes

docs/diagram/string.png

0 Bytes

docs/diagram/subquery-expr.png

0 Bytes

docs/diagram/uint.png

0 Bytes

docs/diagram/unescaped-identifier.png

0 Bytes

docs/diagram/unnest-clause.png

0 Bytes

docs/diagram/variable.png

0 Bytes

docs/diagram/where-clause.png

0 Bytes

docs/n1ql-select.ebnf

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/*
66
* select statement
77
*/
8-
select ::= select-core order-by-clause? limit-clause? offset-clause?
8+
select ::= select-core ('UNION' 'ALL'? select-core)* order-by-clause? limit-clause? offset-clause?
99
select-core ::= select-from-core | from-select-core
1010
select-from-core ::= select-clause from-clause? let-clause? where-clause? group-by-clause?
1111
from-select-core ::= from-clause let-clause? where-clause? group-by-clause? select-clause

docs/n1ql-select.md

+13

execute/all.go

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright (c) 2014 Couchbase, Inc.
2+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3+
// except in compliance with the License. You may obtain a copy of the License at
4+
// http://www.apache.org/licenses/LICENSE-2.0
5+
// Unless required by applicable law or agreed to in writing, software distributed under the
6+
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
7+
// either express or implied. See the License for the specific language governing permissions
8+
// and limitations under the License.
9+
10+
package execute
11+
12+
import (
13+
"github.com/couchbaselabs/query/value"
14+
)
15+
16+
type All struct {
17+
base
18+
children []Operator
19+
childChannel StopChannel
20+
}
21+
22+
func NewAll(children []Operator) *All {
23+
rv := &All{
24+
base: newBase(),
25+
children: children,
26+
childChannel: make(StopChannel, len(children)),
27+
}
28+
29+
rv.output = rv
30+
return rv
31+
}
32+
33+
func (this *All) Accept(visitor Visitor) (interface{}, error) {
34+
return visitor.VisitAll(this)
35+
}
36+
37+
func (this *All) Copy() Operator {
38+
rv := &All{
39+
base: this.base.copy(),
40+
childChannel: make(StopChannel, len(this.children)),
41+
}
42+
43+
children := make([]Operator, len(this.children))
44+
for i, c := range this.children {
45+
children[i] = c.Copy()
46+
}
47+
48+
rv.children = children
49+
return rv
50+
}
51+
52+
func (this *All) RunOnce(context *Context, parent value.Value) {
53+
this.once.Do(func() {
54+
defer close(this.itemChannel) // Broadcast that I have stopped
55+
defer this.notify() // Notify that I have stopped
56+
57+
n := len(this.children)
58+
59+
// Run children in parallel
60+
for _, child := range this.children {
61+
child.SetOutput(this.output)
62+
go child.RunOnce(context, parent)
63+
}
64+
65+
for n > 0 {
66+
select {
67+
case <-this.childChannel: // Never closed
68+
// Wait for all children
69+
n--
70+
case <-this.stopChannel: // Never closed
71+
this.notifyStop()
72+
for _, child := range this.children {
73+
select {
74+
case child.StopChannel() <- false:
75+
default:
76+
}
77+
}
78+
}
79+
}
80+
})
81+
}
82+
83+
func (this *All) ChildChannel() StopChannel {
84+
return this.childChannel
85+
}

execute/builder.go

+17-10
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,8 @@ func (this *Builder) VisitParentScan(plan *plan.ParentScan) (interface{}, error)
4444
return NewParentScan(), nil
4545
}
4646

47-
func (this *Builder) VisitEqualScan(plan *plan.EqualScan) (interface{}, error) {
48-
return NewEqualScan(plan), nil
49-
}
50-
51-
func (this *Builder) VisitRangeScan(plan *plan.RangeScan) (interface{}, error) {
52-
return NewRangeScan(plan), nil
53-
}
54-
55-
func (this *Builder) VisitDualScan(plan *plan.DualScan) (interface{}, error) {
56-
return NewDualScan(plan), nil
47+
func (this *Builder) VisitIndexScan(plan *plan.IndexScan) (interface{}, error) {
48+
return NewIndexScan(plan), nil
5749
}
5850

5951
func (this *Builder) VisitKeyScan(plan *plan.KeyScan) (interface{}, error) {
@@ -142,6 +134,21 @@ func (this *Builder) VisitDistinct(plan *plan.Distinct) (interface{}, error) {
142134
return NewDistinct(), nil
143135
}
144136

137+
// Union [ All ]
138+
func (this *Builder) VisitAll(plan *plan.All) (interface{}, error) {
139+
children := make([]Operator, len(plan.Children()))
140+
for i, child := range plan.Children() {
141+
c, e := child.Accept(this)
142+
if e != nil {
143+
return nil, e
144+
}
145+
146+
children[i] = c.(Operator)
147+
}
148+
149+
return NewAll(children), nil
150+
}
151+
145152
// Order
146153
func (this *Builder) VisitOrder(plan *plan.Order) (interface{}, error) {
147154
return NewOrder(plan), nil

execute/parallel.go

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
package execute
1111

1212
import (
13-
_ "fmt"
1413
"runtime"
1514

1615
"github.com/couchbaselabs/query/value"

0 commit comments

Comments
 (0)