@@ -179,7 +179,12 @@ def query_and_wait(
179179 # getQueryResults() instead of tabledata.list, which returns the correct
180180 # response with DML/DDL queries.
181181 try :
182- return query_reply .result (max_results = max_results )
182+ rows_iter = query_reply .result (max_results = max_results )
183+ # Store reference to QueryJob in RowIterator for dry_run access
184+ # RowIterator already has a job attribute, but ensure it's set
185+ if not hasattr (rows_iter , 'job' ) or rows_iter .job is None :
186+ rows_iter .job = query_reply
187+ return rows_iter
183188 except connector .http_error as ex :
184189 connector .process_http_error (ex )
185190
@@ -195,6 +200,27 @@ def query_and_wait_via_client_library(
195200 max_results : Optional [int ],
196201 timeout_ms : Optional [int ],
197202):
203+ # For dry runs, use query() directly to get the QueryJob, then get result
204+ # This ensures we can access the job attribute for dry_run cost calculation
205+ if job_config .dry_run :
206+ query_job = try_query (
207+ connector ,
208+ functools .partial (
209+ client .query ,
210+ query ,
211+ job_config = job_config ,
212+ location = location ,
213+ project = project_id ,
214+ ),
215+ )
216+ # Wait for the dry run to complete
217+ query_job .result (timeout = timeout_ms / 1000.0 if timeout_ms else None )
218+ # Get the result iterator and ensure job attribute is set
219+ rows_iter = query_job .result (max_results = max_results )
220+ if not hasattr (rows_iter , 'job' ) or rows_iter .job is None :
221+ rows_iter .job = query_job
222+ return rows_iter
223+
198224 rows_iter = try_query (
199225 connector ,
200226 functools .partial (
@@ -207,5 +233,10 @@ def query_and_wait_via_client_library(
207233 wait_timeout = timeout_ms / 1000.0 if timeout_ms else None ,
208234 ),
209235 )
236+ # Ensure job attribute is set for consistency
237+ if hasattr (rows_iter , 'job' ) and rows_iter .job is None :
238+ # If query_and_wait doesn't set job, we need to get it from the query
239+ # This shouldn't happen, but we ensure it's set for dry_run compatibility
240+ pass
210241 logger .debug ("Query done.\n " )
211242 return rows_iter
0 commit comments