func (self *ShardData) getProcessor(querySpec *parser.QuerySpec, processor engine.Processor) (engine.Processor, error) { switch qt := querySpec.Query().Type(); qt { case parser.Delete, parser.DropSeries: return NilProcessor{}, nil case parser.Select: // continue default: panic(fmt.Errorf("Unexpected query type: %s", qt)) } if querySpec.IsSinglePointQuery() { return engine.NewPassthroughEngine(processor, 1), nil } query := querySpec.SelectQuery() var err error // We should aggregate at the shard level if self.ShouldAggregateLocally(querySpec) { log.Debug("creating a query engine") processor, err = engine.NewQueryEngine(processor, query, nil) if err != nil { return nil, err } goto addFilter } // we shouldn't limit the queries if they have aggregates and aren't // aggregated locally, otherwise the aggregation result which happen // in the coordinator will get partial data and will be incorrect if query.HasAggregates() { log.Debug("creating a passthrough engine") processor = engine.NewPassthroughEngine(processor, 1000) goto addFilter } // This is an optimization so we don't send more data that we should // over the wire. The coordinator has its own Passthrough which does // the final limit. if l := query.Limit; l > 0 { log.Debug("creating a passthrough engine with limit") processor = engine.NewPassthroughEngineWithLimit(processor, 1000, query.Limit) } addFilter: if query := querySpec.SelectQuery(); query != nil && query.GetFromClause().Type != parser.FromClauseInnerJoin { // Joins do their own filtering since we need to get all // points before filtering. This is due to the fact that some // where expressions will be difficult to compute before the // points are joined together, think where clause with // left.column = 'something' or right.column = // 'something_else'. We can't filter the individual series // separately. The filtering happens in merge.go:55 processor = engine.NewFilteringEngine(query, processor) } return processor, nil }
func (self *Permissions) CheckQueryPermissions(user common.User, db string, querySpec *parser.QuerySpec) (ok bool, err common.AuthorizationError) { switch querySpec.Query().Type() { case parser.Delete: return self.AuthorizeDeleteQuery(user, db) case parser.Select: return self.AuthorizeSelectQuery(user, db, querySpec) default: return true, "" } }
func (self *Coordinator) runDropSeriesQuery(querySpec *parser.QuerySpec) error { user := querySpec.User() db := querySpec.Database() series := querySpec.Query().DropSeriesQuery.GetTableName() if ok, err := self.permissions.AuthorizeDropSeries(user, db, series); !ok { return err } err := self.raftServer.DropSeries(db, series) if err != nil { return err } return nil }
func (self *Coordinator) runListSeriesQuery(querySpec *parser.QuerySpec, p engine.Processor) error { allSeries := self.clusterConfiguration.MetaStore.GetSeriesForDatabase(querySpec.Database()) matchingSeries := allSeries q := querySpec.Query().GetListSeriesQuery() if q.HasRegex() { matchingSeries = nil regex := q.GetRegex() for _, s := range allSeries { if !regex.MatchString(s) { continue } matchingSeries = append(matchingSeries, s) } } name := "list_series_result" var fields []string points := make([]*protocol.Point, len(matchingSeries)) if q.IncludeSpaces { fields = []string{"name", "space"} spaces := self.clusterConfiguration.GetShardSpacesForDatabase(querySpec.Database()) for i, s := range matchingSeries { spaceName := "" for _, sp := range spaces { if sp.MatchesSeries(s) { spaceName = sp.Name break } } fieldValues := []*protocol.FieldValue{ {StringValue: proto.String(s)}, {StringValue: proto.String(spaceName)}, } points[i] = &protocol.Point{Values: fieldValues} } } else { fields = []string{"name"} for i, s := range matchingSeries { fieldValues := []*protocol.FieldValue{ {StringValue: proto.String(s)}, } points[i] = &protocol.Point{Values: fieldValues} } } seriesResult := &protocol.Series{Name: &name, Fields: fields, Points: points} _, err := p.Yield(seriesResult) return err }