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
10package expression
11
12import (
13	"github.com/couchbase/query/value"
14)
15
16type Covers []*Cover
17
18/*
19Internal Expression to support covering indexing.
20*/
21type Cover struct {
22	ExpressionBase
23	covered Expression
24	text    string
25}
26
27func NewCover(covered Expression) *Cover {
28	switch covered := covered.(type) {
29	case *Cover:
30		return covered
31	}
32
33	rv := &Cover{
34		covered: covered,
35		text:    covered.String(),
36	}
37
38	rv.expr = rv
39	return rv
40}
41
42/*
43Visitor pattern.
44*/
45func (this *Cover) Accept(visitor Visitor) (interface{}, error) {
46	return visitor.VisitCover(this)
47}
48
49func (this *Cover) Type() value.Type {
50	return this.covered.Type()
51}
52
53func (this *Cover) Evaluate(item value.Value, context Context) (value.Value, error) {
54	var rv value.Value
55	switch item := item.(type) {
56	case value.AnnotatedValue:
57		rv = item.GetCover(this.text)
58	}
59
60	if rv == nil {
61		return value.MISSING_VALUE, nil
62	}
63
64	return rv, nil
65}
66
67func (this *Cover) Value() value.Value {
68	return this.covered.Value()
69}
70
71func (this *Cover) Static() Expression {
72	return this.covered.Static()
73}
74
75func (this *Cover) Alias() string {
76	return this.covered.Alias()
77}
78
79func (this *Cover) Indexable() bool {
80	return this.covered.Indexable()
81}
82
83func (this *Cover) PropagatesMissing() bool {
84	return this.covered.PropagatesMissing()
85}
86
87func (this *Cover) PropagatesNull() bool {
88	return this.covered.PropagatesNull()
89}
90
91func (this *Cover) EquivalentTo(other Expression) bool {
92	if this.covered.EquivalentTo(other) {
93		return true
94	}
95
96	oc, ok := other.(*Cover)
97	return ok && this.covered.EquivalentTo(oc.covered)
98}
99
100func (this *Cover) DependsOn(other Expression) bool {
101	return this.covered.DependsOn(other)
102}
103
104func (this *Cover) CoveredBy(keyspace string, exprs Expressions, options coveredOptions) Covered {
105	return this.covered.CoveredBy(keyspace, exprs, options)
106}
107
108func (this *Cover) Children() Expressions {
109	return Expressions{this.covered}
110}
111
112func (this *Cover) MapChildren(mapper Mapper) error {
113	c, err := mapper.Map(this.covered)
114	if err == nil && c != this.covered {
115		this.covered = c
116		this.text = c.String()
117	}
118
119	return err
120}
121
122func (this *Cover) Copy() Expression {
123	return NewCover(this.covered.Copy())
124}
125
126func (this *Cover) Covered() Expression {
127	return this.covered
128}
129
130func (this *Cover) Text() string {
131	return this.text
132}
133