github.com/vedadiyan/sqlparser@v1.0.0/pkg/sqltypes/proto3.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package sqltypes 18 19 import ( 20 "google.golang.org/protobuf/proto" 21 22 "github.com/vedadiyan/sqlparser/pkg/vterrors" 23 24 querypb "github.com/vedadiyan/sqlparser/pkg/query" 25 ) 26 27 // This file contains the proto3 conversion functions for the structures 28 // defined here. 29 30 // RowToProto3 converts []Value to proto3. 31 func RowToProto3(row []Value) *querypb.Row { 32 result := &querypb.Row{} 33 _ = RowToProto3Inplace(row, result) 34 return result 35 } 36 37 // RowToProto3Inplace converts []Value to proto3 and stores the conversion in the provided Row 38 func RowToProto3Inplace(row []Value, result *querypb.Row) int { 39 if result.Lengths == nil { 40 result.Lengths = make([]int64, 0, len(row)) 41 } else { 42 result.Lengths = result.Lengths[:0] 43 } 44 total := 0 45 for _, c := range row { 46 if c.IsNull() { 47 result.Lengths = append(result.Lengths, -1) 48 continue 49 } 50 length := c.Len() 51 result.Lengths = append(result.Lengths, int64(length)) 52 total += length 53 } 54 if result.Values == nil { 55 result.Values = make([]byte, 0, total) 56 } else { 57 result.Values = result.Values[:0] 58 } 59 for _, c := range row { 60 if c.IsNull() { 61 continue 62 } 63 result.Values = append(result.Values, c.Raw()...) 64 } 65 return total 66 } 67 68 // RowsToProto3 converts [][]Value to proto3. 69 func RowsToProto3(rows [][]Value) []*querypb.Row { 70 if len(rows) == 0 { 71 return nil 72 } 73 74 result := make([]*querypb.Row, len(rows)) 75 for i, r := range rows { 76 result[i] = RowToProto3(r) 77 } 78 return result 79 } 80 81 // proto3ToRows converts a proto3 rows to [][]Value. The function is private 82 // because it uses the trusted API. 83 func proto3ToRows(fields []*querypb.Field, rows []*querypb.Row) [][]Value { 84 if len(rows) == 0 { 85 // TODO(sougou): This is needed for backward compatibility. 86 // Remove when it's not needed any more. 87 return [][]Value{} 88 } 89 90 result := make([][]Value, len(rows)) 91 for i, r := range rows { 92 result[i] = MakeRowTrusted(fields, r) 93 } 94 return result 95 } 96 97 // ResultToProto3 converts Result to proto3. 98 func ResultToProto3(qr *Result) *querypb.QueryResult { 99 if qr == nil { 100 return nil 101 } 102 return &querypb.QueryResult{ 103 Fields: qr.Fields, 104 RowsAffected: qr.RowsAffected, 105 InsertId: qr.InsertID, 106 Rows: RowsToProto3(qr.Rows), 107 Info: qr.Info, 108 SessionStateChanges: qr.SessionStateChanges, 109 } 110 } 111 112 // Proto3ToResult converts a proto3 Result to an internal data structure. This function 113 // should be used only if the field info is populated in qr. 114 func Proto3ToResult(qr *querypb.QueryResult) *Result { 115 if qr == nil { 116 return nil 117 } 118 return &Result{ 119 Fields: qr.Fields, 120 RowsAffected: qr.RowsAffected, 121 InsertID: qr.InsertId, 122 Rows: proto3ToRows(qr.Fields, qr.Rows), 123 Info: qr.Info, 124 SessionStateChanges: qr.SessionStateChanges, 125 } 126 } 127 128 // CustomProto3ToResult converts a proto3 Result to an internal data structure. This function 129 // takes a separate fields input because not all QueryResults contain the field info. 130 // In particular, only the first packet of streaming queries contain the field info. 131 func CustomProto3ToResult(fields []*querypb.Field, qr *querypb.QueryResult) *Result { 132 if qr == nil { 133 return nil 134 } 135 return &Result{ 136 Fields: qr.Fields, 137 RowsAffected: qr.RowsAffected, 138 InsertID: qr.InsertId, 139 Rows: proto3ToRows(fields, qr.Rows), 140 Info: qr.Info, 141 SessionStateChanges: qr.SessionStateChanges, 142 } 143 } 144 145 // ResultsToProto3 converts []Result to proto3. 146 func ResultsToProto3(qr []Result) []*querypb.QueryResult { 147 if len(qr) == 0 { 148 return nil 149 } 150 result := make([]*querypb.QueryResult, len(qr)) 151 for i, q := range qr { 152 result[i] = ResultToProto3(&q) 153 } 154 return result 155 } 156 157 // Proto3ToResults converts proto3 results to []Result. 158 func Proto3ToResults(qr []*querypb.QueryResult) []Result { 159 if len(qr) == 0 { 160 return nil 161 } 162 result := make([]Result, len(qr)) 163 for i, q := range qr { 164 result[i] = *Proto3ToResult(q) 165 } 166 return result 167 } 168 169 // QueryResponsesToProto3 converts []QueryResponse to proto3. 170 func QueryResponsesToProto3(qr []QueryResponse) []*querypb.ResultWithError { 171 if len(qr) == 0 { 172 return nil 173 } 174 result := make([]*querypb.ResultWithError, len(qr)) 175 for i, q := range qr { 176 result[i] = &querypb.ResultWithError{ 177 Result: ResultToProto3(q.QueryResult), 178 Error: vterrors.ToVTRPC(q.QueryError), 179 } 180 } 181 return result 182 } 183 184 // Proto3ToQueryReponses converts proto3 queryResponse to []QueryResponse. 185 func Proto3ToQueryReponses(qr []*querypb.ResultWithError) []QueryResponse { 186 if len(qr) == 0 { 187 return nil 188 } 189 result := make([]QueryResponse, len(qr)) 190 for i, q := range qr { 191 result[i] = QueryResponse{ 192 QueryResult: Proto3ToResult(q.Result), 193 QueryError: vterrors.FromVTRPC(q.Error), 194 } 195 } 196 return result 197 } 198 199 // Proto3ResultsEqual compares two arrays of proto3 Result. 200 // reflect.DeepEqual shouldn't be used because of the protos. 201 func Proto3ResultsEqual(r1, r2 []*querypb.QueryResult) bool { 202 if len(r1) != len(r2) { 203 return false 204 } 205 for i, r := range r1 { 206 if !proto.Equal(r, r2[i]) { 207 return false 208 } 209 } 210 return true 211 } 212 213 // Proto3QueryResponsesEqual compares two arrays of proto3 QueryResponse. 214 // reflect.DeepEqual shouldn't be used because of the protos. 215 func Proto3QueryResponsesEqual(r1, r2 []*querypb.ResultWithError) bool { 216 if len(r1) != len(r2) { 217 return false 218 } 219 for i, r := range r1 { 220 if !proto.Equal(r, r2[i]) { 221 return false 222 } 223 } 224 return true 225 } 226 227 // Proto3ValuesEqual compares two arrays of proto3 Value. 228 func Proto3ValuesEqual(v1, v2 []*querypb.Value) bool { 229 if len(v1) != len(v2) { 230 return false 231 } 232 for i, v := range v1 { 233 if !proto.Equal(v, v2[i]) { 234 return false 235 } 236 } 237 return true 238 }