github.com/influxdata/influxdb/v2@v2.7.6/influxql/query/result.go (about) 1 package query 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 8 "github.com/influxdata/influxdb/v2/models" 9 "github.com/influxdata/influxql" 10 ) 11 12 const ( 13 // WarningLevel is the message level for a warning. 14 WarningLevel = "warning" 15 ) 16 17 // TagSet is a fundamental concept within the query system. It represents a composite series, 18 // composed of multiple individual series that share a set of tag attributes. 19 type TagSet struct { 20 Filters []influxql.Expr 21 SeriesKeys []string 22 Key []byte 23 } 24 25 // AddFilter adds a series-level filter to the Tagset. 26 func (t *TagSet) AddFilter(key string, filter influxql.Expr) { 27 t.SeriesKeys = append(t.SeriesKeys, key) 28 t.Filters = append(t.Filters, filter) 29 } 30 31 func (t *TagSet) Len() int { return len(t.SeriesKeys) } 32 func (t *TagSet) Less(i, j int) bool { return t.SeriesKeys[i] < t.SeriesKeys[j] } 33 func (t *TagSet) Swap(i, j int) { 34 t.SeriesKeys[i], t.SeriesKeys[j] = t.SeriesKeys[j], t.SeriesKeys[i] 35 t.Filters[i], t.Filters[j] = t.Filters[j], t.Filters[i] 36 } 37 38 // Reverse reverses the order of series keys and filters in the TagSet. 39 func (t *TagSet) Reverse() { 40 for i, j := 0, len(t.Filters)-1; i < j; i, j = i+1, j-1 { 41 t.Filters[i], t.Filters[j] = t.Filters[j], t.Filters[i] 42 t.SeriesKeys[i], t.SeriesKeys[j] = t.SeriesKeys[j], t.SeriesKeys[i] 43 } 44 } 45 46 // LimitTagSets returns a tag set list with SLIMIT and SOFFSET applied. 47 func LimitTagSets(a []*TagSet, slimit, soffset int) []*TagSet { 48 // Ignore if no limit or offset is specified. 49 if slimit == 0 && soffset == 0 { 50 return a 51 } 52 53 // If offset is beyond the number of tag sets then return nil. 54 if soffset > len(a) { 55 return nil 56 } 57 58 // Clamp limit to the max number of tag sets. 59 if soffset+slimit > len(a) { 60 slimit = len(a) - soffset 61 } 62 return a[soffset : soffset+slimit] 63 } 64 65 // Message represents a user-facing message to be included with the result. 66 type Message struct { 67 Level string `json:"level"` 68 Text string `json:"text"` 69 } 70 71 // ReadOnlyWarning generates a warning message that tells the user the command 72 // they are using is being used for writing in a read only context. 73 // 74 // This is a temporary method while to be used while transitioning to read only 75 // operations for issue #6290. 76 func ReadOnlyWarning(stmt string) *Message { 77 return &Message{ 78 Level: WarningLevel, 79 Text: fmt.Sprintf("deprecated use of '%s' in a read only context, please use a POST request instead", stmt), 80 } 81 } 82 83 // Result represents a resultset returned from a single statement. 84 // Rows represents a list of rows that can be sorted consistently by name/tag. 85 type Result struct { 86 // StatementID is just the statement's position in the query. It's used 87 // to combine statement results if they're being buffered in memory. 88 StatementID int 89 Series models.Rows 90 Messages []*Message 91 Partial bool 92 Err error 93 } 94 95 // MarshalJSON encodes the result into JSON. 96 func (r *Result) MarshalJSON() ([]byte, error) { 97 // Define a struct that outputs "error" as a string. 98 var o struct { 99 StatementID int `json:"statement_id"` 100 Series []*models.Row `json:"series,omitempty"` 101 Messages []*Message `json:"messages,omitempty"` 102 Partial bool `json:"partial,omitempty"` 103 Err string `json:"error,omitempty"` 104 } 105 106 // Copy fields to output struct. 107 o.StatementID = r.StatementID 108 o.Series = r.Series 109 o.Messages = r.Messages 110 o.Partial = r.Partial 111 if r.Err != nil { 112 o.Err = r.Err.Error() 113 } 114 115 return json.Marshal(&o) 116 } 117 118 // UnmarshalJSON decodes the data into the Result struct 119 func (r *Result) UnmarshalJSON(b []byte) error { 120 var o struct { 121 StatementID int `json:"statement_id"` 122 Series []*models.Row `json:"series,omitempty"` 123 Messages []*Message `json:"messages,omitempty"` 124 Partial bool `json:"partial,omitempty"` 125 Err string `json:"error,omitempty"` 126 } 127 128 err := json.Unmarshal(b, &o) 129 if err != nil { 130 return err 131 } 132 r.StatementID = o.StatementID 133 r.Series = o.Series 134 r.Messages = o.Messages 135 r.Partial = o.Partial 136 if o.Err != "" { 137 r.Err = errors.New(o.Err) 138 } 139 return nil 140 }