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) }
func (this *builder) buildJoinScan(keyspace datastore.Keyspace, node *algebra.KeyspaceTerm, op string) ( datastore.Index, expression.Covers, error) { indexes, err := allIndexes(keyspace) if err != nil { return nil, nil, err } var pred expression.Expression pred = expression.NewIsNotNull(node.Keys().Copy()) dnf := NewDNF() pred, err = dnf.Map(pred) if err != nil { return nil, nil, err } subset := pred if this.where != nil { subset = expression.NewAnd(subset, this.where.Copy()) subset, err = dnf.Map(subset) if err != nil { return nil, nil, err } } formalizer := expression.NewFormalizer() formalizer.Keyspace = node.Alias() primaryKey := expression.Expressions{ expression.NewField( expression.NewMeta(expression.NewConstant(node.Alias())), expression.NewFieldName("id", false)), } sargables, err := sargableIndexes(indexes, pred, subset, primaryKey, dnf, formalizer) if err != nil { return nil, nil, err } minimals, err := minimalIndexes(sargables, pred) if err != nil { return nil, nil, err } if len(minimals) == 0 { return nil, nil, errors.NewNoIndexJoinError(node.Alias(), op) } return this.buildCoveringJoinScan(minimals, node, op) }