Beispiel #1
0
func (this *builder) buildCoveringJoinScan(secondaries map[datastore.Index]*indexEntry,
	node *algebra.KeyspaceTerm, op string) (datastore.Index, expression.Covers, error) {
	if this.cover == nil {
		for index, _ := range secondaries {
			return index, nil, nil
		}
	}

	alias := node.Alias()
	exprs := this.cover.Expressions()

outer:
	for index, entry := range secondaries {
		for _, expr := range exprs {
			if !expr.CoveredBy(alias, entry.keys) {
				continue outer
			}
		}

		covers := make(expression.Covers, len(entry.keys))
		for i, key := range entry.keys {
			covers[i] = expression.NewCover(key)
		}

		return index, covers, nil
	}

	for index, _ := range secondaries {
		return index, nil, nil
	}

	return nil, nil, errors.NewNoIndexJoinError(node.Alias(), op)
}
Beispiel #2
0
func (this *builder) buildCoveringScan(secondaries map[datastore.Index]*indexEntry,
	node *algebra.KeyspaceTerm, limit expression.Expression) (*plan.IndexScan, error) {
	if this.cover == nil {
		return nil, nil
	}

	exprs := this.cover.Expressions()

outer:
	for index, entry := range secondaries {
		for _, expr := range exprs {
			if !expr.CoveredBy(entry.keys) {
				continue outer
			}
		}

		covered := make([]*expression.Cover, len(entry.keys))
		for i, key := range entry.keys {
			covered[i] = expression.NewCover(key)
		}

		scan := plan.NewIndexScan(index, node, entry.spans, false, limit, covered)
		this.coveringScan = scan
		return scan, nil
	}

	return nil, nil
}
Beispiel #3
0
func (this *IndexScan) UnmarshalJSON(body []byte) error {
	var _unmarshalled struct {
		_         string              `json:"#operator"`
		Index     string              `json:"index"`
		Namespace string              `json:"namespace"`
		Keyspace  string              `json:"keyspace"`
		Using     datastore.IndexType `json:"using"`
		Spans     Spans               `json:"spans"`
		Distinct  bool                `json:"distinct"`
		Limit     string              `json:"limit"`
		Covers    []string            `json:"covers"`
	}

	err := json.Unmarshal(body, &_unmarshalled)
	if err != nil {
		return err
	}

	k, err := datastore.GetKeyspace(_unmarshalled.Namespace, _unmarshalled.Keyspace)
	if err != nil {
		return err
	}

	this.term = algebra.NewKeyspaceTerm(
		_unmarshalled.Namespace, _unmarshalled.Keyspace,
		nil, "", nil, nil)

	this.spans = _unmarshalled.Spans
	this.distinct = _unmarshalled.Distinct

	if _unmarshalled.Limit != "" {
		this.limit, err = parser.Parse(_unmarshalled.Limit)
		if err != nil {
			return err
		}
	}

	if _unmarshalled.Covers != nil {
		this.covers = make(expression.Covers, len(_unmarshalled.Covers))
		for i, c := range _unmarshalled.Covers {
			expr, err := parser.Parse(c)
			if err != nil {
				return err
			}

			this.covers[i] = expression.NewCover(expr)
		}
	}

	indexer, err := k.Indexer(_unmarshalled.Using)
	if err != nil {
		return err
	}

	this.index, err = indexer.IndexByName(_unmarshalled.Index)
	return err
}
Beispiel #4
0
func (this *builder) buildCoveringScan(secondaries map[datastore.Index]*indexEntry,
	node *algebra.KeyspaceTerm, limit expression.Expression) (plan.Operator, error) {
	if this.cover == nil {
		return nil, nil
	}

	alias := node.Alias()
	exprs := this.cover.Expressions()
	id := expression.NewField(
		expression.NewMeta(expression.NewIdentifier(node.Alias())),
		expression.NewFieldName("id", false))

outer:
	for index, entry := range secondaries {
		keys := entry.keys
		if !index.IsPrimary() {
			// Matches execution.spanScan.RunOnce()
			keys = append(keys, id)
		}

		// Use the first available covering index
		for _, expr := range exprs {
			if !expr.CoveredBy(alias, keys) {
				continue outer
			}
		}

		covers := make(expression.Covers, 0, len(keys))
		for _, key := range keys {
			covers = append(covers, expression.NewCover(key))
		}

		scan := plan.NewIndexScan(index, node, entry.spans, false, limit, covers)
		this.coveringScan = scan

		if len(entry.spans) > 1 {
			// Use UnionScan to de-dup multiple spans
			return plan.NewUnionScan(scan), nil
		}

		return scan, nil
	}

	return nil, nil
}
Beispiel #5
0
func (this *IndexNest) UnmarshalJSON(body []byte) error {
	var _unmarshalled struct {
		_     string `json:"#operator"`
		Names string `json:"namespace"`
		Keys  string `json:"keyspace"`
		On    string `json:"on_key"`
		Outer bool   `json:"outer"`
		As    string `json:"as"`
		For   string `json:"for"`
		Scan  struct {
			Index  string              `json:"index"`
			Using  datastore.IndexType `json:"using"`
			Covers []string            `json:"covers"`
		} `json:"scan"`
	}

	err := json.Unmarshal(body, &_unmarshalled)
	if err != nil {
		return err
	}

	var keys_expr expression.Expression
	if _unmarshalled.On != "" {
		keys_expr, err = parser.Parse(_unmarshalled.On)
		if err != nil {
			return err
		}
	}

	this.outer = _unmarshalled.Outer
	this.keyFor = _unmarshalled.For
	this.idExpr = expression.NewField(
		expression.NewMeta(expression.NewIdentifier(this.keyFor)),
		expression.NewFieldName("id", false))
	this.term = algebra.NewKeyspaceTerm(_unmarshalled.Names, _unmarshalled.Keys,
		nil, _unmarshalled.As, keys_expr, nil)
	this.keyspace, err = datastore.GetKeyspace(_unmarshalled.Names, _unmarshalled.Keys)
	if err != nil {
		return err
	}

	indexer, err := this.keyspace.Indexer(_unmarshalled.Scan.Using)
	if err != nil {
		return err
	}

	this.index, err = indexer.IndexByName(_unmarshalled.Scan.Index)
	if err != nil {
		return err
	}

	if _unmarshalled.Scan.Covers != nil {
		this.covers = make(expression.Covers, len(_unmarshalled.Scan.Covers))
		for i, c := range _unmarshalled.Scan.Covers {
			expr, err := parser.Parse(c)
			if err != nil {
				return err
			}

			this.covers[i] = expression.NewCover(expr)
		}
	}

	return nil
}