Example #1
0
func minimalIndexes(sargables map[datastore.Index]*indexEntry, pred expression.Expression) (
	map[datastore.Index]*indexEntry, error) {
	for s, se := range sargables {
		for t, te := range sargables {
			if t == s {
				continue
			}

			if narrowerOrEquivalent(se, te) {
				delete(sargables, t)
			}
		}
	}

	minimals := make(map[datastore.Index]*indexEntry, len(sargables))
	for s, se := range sargables {
		spans, err := SargFor(pred, se.sargKeys, len(se.keys))
		if err != nil || len(spans) == 0 {
			logging.Errorp("Sargable index not sarged", logging.Pair{"pred", pred},
				logging.Pair{"sarg_keys", se.sargKeys}, logging.Pair{"error", err})
			return nil, errors.NewPlanError(nil, fmt.Sprintf("Sargable index not sarged; pred=%v, sarg_keys=%v, error=%v",
				pred.String(), se.sargKeys.String(), err))
			return nil, err
		}

		se.spans = spans
		minimals[s] = se
	}

	return minimals, nil
}
Example #2
0
func (this *Server) getPrepared(request Request, namespace string) (*plan.Prepared, errors.Error) {
	prepared := request.Prepared()
	if prepared == nil {
		parse := time.Now()
		stmt, err := n1ql.ParseStatement(request.Statement())
		if err != nil {
			return nil, errors.NewParseSyntaxError(err, "")
		}

		prep := time.Now()
		prepared, err = planner.BuildPrepared(stmt, this.datastore, this.systemstore, namespace, false)
		if err != nil {
			return nil, errors.NewPlanError(err, "")
		}

		if logging.LogLevel() >= logging.TRACE {
			request.Output().AddPhaseTime("plan", time.Since(prep))
			request.Output().AddPhaseTime("parse", prep.Sub(parse))
		}
	}

	if logging.LogLevel() >= logging.DEBUG {
		// log EXPLAIN for the request
		logExplain(prepared)
	}

	return prepared, nil
}
Example #3
0
func (this *Server) getPrepared(request Request, namespace string) (*plan.Prepared, errors.Error) {
	prepared := request.Prepared()
	if prepared == nil {
		parse := time.Now()
		stmt, err := n1ql.ParseStatement(request.Statement())
		if err != nil {
			return nil, errors.NewParseSyntaxError(err, "")
		}

		prep := time.Now()
		prepared, err = planner.BuildPrepared(stmt, this.datastore, this.systemstore, namespace, false)
		if err != nil {
			return nil, errors.NewPlanError(err, "")
		}

		// In order to allow monitoring to track prepared statement executed through
		// N1QL "EXECUTE", set request.prepared - because, as of yet, it isn't!
		//
		// HACK ALERT - request does not currently track the request type
		// and even if it did, and prepared.(*plan.Prepared) is set, it
		// does not carry a name or text.
		// This should probably done in build.go and / or build_execute.go,
		// but for now this will do.
		exec, ok := stmt.(*algebra.Execute)
		if ok && exec.Prepared() != nil {
			prep, _ := plan.TrackPrepared(exec.Prepared())
			request.SetPrepared(prep)
		}

		if logging.LogLevel() >= logging.TRACE {
			request.Output().AddPhaseTime("plan", time.Since(prep))
			request.Output().AddPhaseTime("parse", prep.Sub(parse))
		}
	}

	if logging.LogLevel() >= logging.DEBUG {
		// log EXPLAIN for the request
		logExplain(prepared)
	}

	return prepared, nil
}