dryRunQuery performs a dry run validation of the query without executing it. Returns validation status and estimated bytes to be processed.
(ctx context.Context, statement string, queryContext db.QueryContext)
| 218 | // dryRunQuery performs a dry run validation of the query without executing it. |
| 219 | // Returns validation status and estimated bytes to be processed. |
| 220 | func (d *Driver) dryRunQuery(ctx context.Context, statement string, queryContext db.QueryContext) ([]*v1pb.QueryResult, error) { |
| 221 | statements, err := util.SanitizeSQL(statement) |
| 222 | if err != nil { |
| 223 | return nil, err |
| 224 | } |
| 225 | |
| 226 | var results []*v1pb.QueryResult |
| 227 | for _, stmt := range statements { |
| 228 | startTime := time.Now() |
| 229 | |
| 230 | q := d.client.Query(stmt) |
| 231 | q.DefaultDatasetID = d.databaseName |
| 232 | q.DryRun = true |
| 233 | |
| 234 | if queryContext.OperatorEmail != "" { |
| 235 | q.Labels = map[string]string{"operator_email": encodeOperatorEmail(queryContext.OperatorEmail)} |
| 236 | } |
| 237 | |
| 238 | job, err := q.Run(ctx) |
| 239 | if err != nil { |
| 240 | results = append(results, &v1pb.QueryResult{ |
| 241 | Statement: stmt, |
| 242 | Error: err.Error(), |
| 243 | Latency: durationpb.New(time.Since(startTime)), |
| 244 | }) |
| 245 | continue |
| 246 | } |
| 247 | |
| 248 | // For dry run, the job completes immediately - use Status() instead of Wait() |
| 249 | status := job.LastStatus() |
| 250 | if status == nil { |
| 251 | results = append(results, &v1pb.QueryResult{ |
| 252 | Statement: stmt, |
| 253 | Error: "failed to get job status", |
| 254 | Latency: durationpb.New(time.Since(startTime)), |
| 255 | }) |
| 256 | continue |
| 257 | } |
| 258 | |
| 259 | if err := status.Err(); err != nil { |
| 260 | results = append(results, &v1pb.QueryResult{ |
| 261 | Statement: stmt, |
| 262 | Error: err.Error(), |
| 263 | Latency: durationpb.New(time.Since(startTime)), |
| 264 | }) |
| 265 | continue |
| 266 | } |
| 267 | |
| 268 | // Extract dry run results |
| 269 | result := &v1pb.QueryResult{ |
| 270 | Statement: stmt, |
| 271 | Latency: durationpb.New(time.Since(startTime)), |
| 272 | } |
| 273 | |
| 274 | if stats, ok := status.Statistics.Details.(*bigquery.QueryStatistics); ok { |
| 275 | bytesProcessed := stats.TotalBytesProcessed |
| 276 | |
| 277 | // Format output similar to bq CLI |
no test coverage detected