func (e *StatementExecutor) executeShowMeasurementsStatement(q *influxql.ShowMeasurementsStatement, ctx *influxql.ExecutionContext) error { if q.Database == "" { return ErrDatabaseNameRequired } measurements, err := e.TSDBStore.Measurements(q.Database, q.Condition) if err != nil || len(measurements) == 0 { return ctx.Send(&influxql.Result{ StatementID: ctx.StatementID, Err: err, }) } if q.Offset > 0 { if q.Offset >= len(measurements) { measurements = nil } else { measurements = measurements[q.Offset:] } } if q.Limit > 0 { if q.Limit < len(measurements) { measurements = measurements[:q.Limit] } } values := make([][]interface{}, len(measurements)) for i, m := range measurements { values[i] = []interface{}{m} } if len(values) == 0 { return ctx.Send(&influxql.Result{ StatementID: ctx.StatementID, }) } return ctx.Send(&influxql.Result{ StatementID: ctx.StatementID, Series: []*models.Row{{ Name: "measurements", Columns: []string{"name"}, Values: values, }}, }) }
func (e *StatementExecutor) executeShowTagValues(q *influxql.ShowTagValuesStatement, ctx *influxql.ExecutionContext) error { if q.Database == "" { return ErrDatabaseNameRequired } tagValues, err := e.TSDBStore.TagValues(q.Database, q.Condition) if err != nil { return ctx.Send(&influxql.Result{ StatementID: ctx.StatementID, Err: err, }) } emitted := false for _, m := range tagValues { values := m.Values if q.Offset > 0 { if q.Offset >= len(values) { values = nil } else { values = values[q.Offset:] } } if q.Limit > 0 { if q.Limit < len(values) { values = values[:q.Limit] } } if len(values) == 0 { continue } row := &models.Row{ Name: m.Measurement, Columns: []string{"key", "value"}, Values: make([][]interface{}, len(values)), } for i, v := range values { row.Values[i] = []interface{}{v.Key, v.Value} } if err := ctx.Send(&influxql.Result{ StatementID: ctx.StatementID, Series: []*models.Row{row}, }); err != nil { return err } emitted = true } // Ensure at least one result is emitted. if !emitted { return ctx.Send(&influxql.Result{ StatementID: ctx.StatementID, }) } return nil }
func (e *StatementExecutor) ExecuteStatement(stmt influxql.Statement, ctx influxql.ExecutionContext) error { // Select statements are handled separately so that they can be streamed. if stmt, ok := stmt.(*influxql.SelectStatement); ok { return e.executeSelectStatement(stmt, &ctx) } var rows models.Rows var messages []*influxql.Message var err error switch stmt := stmt.(type) { case *influxql.AlterRetentionPolicyStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeAlterRetentionPolicyStatement(stmt) case *influxql.CreateContinuousQueryStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeCreateContinuousQueryStatement(stmt) case *influxql.CreateDatabaseStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeCreateDatabaseStatement(stmt) case *influxql.CreateRetentionPolicyStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeCreateRetentionPolicyStatement(stmt) case *influxql.CreateSubscriptionStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeCreateSubscriptionStatement(stmt) case *influxql.CreateUserStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeCreateUserStatement(stmt) case *influxql.DeleteSeriesStatement: err = e.executeDeleteSeriesStatement(stmt, ctx.Database) case *influxql.DropContinuousQueryStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeDropContinuousQueryStatement(stmt) case *influxql.DropDatabaseStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeDropDatabaseStatement(stmt) case *influxql.DropMeasurementStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeDropMeasurementStatement(stmt, ctx.Database) case *influxql.DropSeriesStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeDropSeriesStatement(stmt, ctx.Database) case *influxql.DropRetentionPolicyStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeDropRetentionPolicyStatement(stmt) case *influxql.DropShardStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeDropShardStatement(stmt) case *influxql.DropSubscriptionStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeDropSubscriptionStatement(stmt) case *influxql.DropUserStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeDropUserStatement(stmt) case *influxql.GrantStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeGrantStatement(stmt) case *influxql.GrantAdminStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeGrantAdminStatement(stmt) case *influxql.RevokeStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeRevokeStatement(stmt) case *influxql.RevokeAdminStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeRevokeAdminStatement(stmt) case *influxql.ShowContinuousQueriesStatement: rows, err = e.executeShowContinuousQueriesStatement(stmt) case *influxql.ShowDatabasesStatement: rows, err = e.executeShowDatabasesStatement(stmt) case *influxql.ShowDiagnosticsStatement: rows, err = e.executeShowDiagnosticsStatement(stmt) case *influxql.ShowGrantsForUserStatement: rows, err = e.executeShowGrantsForUserStatement(stmt) case *influxql.ShowMeasurementsStatement: return e.executeShowMeasurementsStatement(stmt, &ctx) case *influxql.ShowRetentionPoliciesStatement: rows, err = e.executeShowRetentionPoliciesStatement(stmt) case *influxql.ShowShardsStatement: rows, err = e.executeShowShardsStatement(stmt) case *influxql.ShowShardGroupsStatement: rows, err = e.executeShowShardGroupsStatement(stmt) case *influxql.ShowStatsStatement: rows, err = e.executeShowStatsStatement(stmt) case *influxql.ShowSubscriptionsStatement: rows, err = e.executeShowSubscriptionsStatement(stmt) case *influxql.ShowTagValuesStatement: return e.executeShowTagValues(stmt, &ctx) case *influxql.ShowUsersStatement: rows, err = e.executeShowUsersStatement(stmt) case *influxql.SetPasswordUserStatement: if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } err = e.executeSetPasswordUserStatement(stmt) case *influxql.ShowQueriesStatement, *influxql.KillQueryStatement: // Send query related statements to the task manager. return e.TaskManager.ExecuteStatement(stmt, ctx) default: return influxql.ErrInvalidQuery } if err != nil { return err } return ctx.Send(&influxql.Result{ StatementID: ctx.StatementID, Series: rows, Messages: messages, }) }
func (e *StatementExecutor) executeSelectStatement(stmt *influxql.SelectStatement, ctx *influxql.ExecutionContext) error { itrs, stmt, err := e.createIterators(stmt, ctx) if err != nil { return err } // Generate a row emitter from the iterator set. em := influxql.NewEmitter(itrs, stmt.TimeAscending(), ctx.ChunkSize) em.Columns = stmt.ColumnNames() em.OmitTime = stmt.OmitTime defer em.Close() // Emit rows to the results channel. var writeN int64 var emitted bool var pointsWriter *BufferedPointsWriter if stmt.Target != nil { pointsWriter = NewBufferedPointsWriter(e.PointsWriter, stmt.Target.Measurement.Database, stmt.Target.Measurement.RetentionPolicy, 10000) } for { row, partial, err := em.Emit() if err != nil { return err } else if row == nil { // Check if the query was interrupted while emitting. select { case <-ctx.InterruptCh: return influxql.ErrQueryInterrupted default: } break } // Write points back into system for INTO statements. if stmt.Target != nil { if err := e.writeInto(pointsWriter, stmt, row); err != nil { return err } writeN += int64(len(row.Values)) continue } result := &influxql.Result{ StatementID: ctx.StatementID, Series: []*models.Row{row}, Partial: partial, } // Send results or exit if closing. if err := ctx.Send(result); err != nil { return err } emitted = true } // Flush remaining points and emit write count if an INTO statement. if stmt.Target != nil { if err := pointsWriter.Flush(); err != nil { return err } var messages []*influxql.Message if ctx.ReadOnly { messages = append(messages, influxql.ReadOnlyWarning(stmt.String())) } return ctx.Send(&influxql.Result{ StatementID: ctx.StatementID, Messages: messages, Series: []*models.Row{{ Name: "result", Columns: []string{"time", "written"}, Values: [][]interface{}{{time.Unix(0, 0).UTC(), writeN}}, }}, }) } // Always emit at least one result. if !emitted { return ctx.Send(&influxql.Result{ StatementID: ctx.StatementID, Series: make([]*models.Row, 0), }) } return nil }