@@ -479,7 +479,7 @@ func TestIntegration_SnapshotAndRestore(t *testing.T) {
479
479
FROM
480
480
UNNEST(GENERATE_ARRAY(0,999))
481
481
` , qualified )
482
- if _ , err := runQueryJob (ctx , sql ); err != nil {
482
+ if _ , _ , err := runQuerySQL (ctx , sql ); err != nil {
483
483
t .Fatalf ("couldn't instantiate base table: %v" , err )
484
484
}
485
485
@@ -872,7 +872,7 @@ func TestIntegration_DatasetUpdateAccess(t *testing.T) {
872
872
sql := fmt .Sprintf (`
873
873
CREATE FUNCTION ` + "`%s`" + `(x INT64) AS (x * 3);` ,
874
874
routine .FullyQualifiedName ())
875
- if _ , err := runQueryJob (ctx , sql ); err != nil {
875
+ if _ , _ , err := runQuerySQL (ctx , sql ); err != nil {
876
876
t .Fatal (err )
877
877
}
878
878
defer routine .Delete (ctx )
@@ -1288,7 +1288,7 @@ func TestIntegration_RoutineStoredProcedure(t *testing.T) {
1288
1288
END` ,
1289
1289
routine .FullyQualifiedName ())
1290
1290
1291
- if _ , err := runQueryJob (ctx , sql ); err != nil {
1291
+ if _ , _ , err := runQuerySQL (ctx , sql ); err != nil {
1292
1292
t .Fatal (err )
1293
1293
}
1294
1294
defer routine .Delete (ctx )
@@ -2014,7 +2014,7 @@ func TestIntegration_DML(t *testing.T) {
2014
2014
('b', [1], STRUCT<BOOL>(FALSE)),
2015
2015
('c', [2], STRUCT<BOOL>(TRUE))` ,
2016
2016
table .DatasetID , table .TableID )
2017
- stats , err := runQueryJob (ctx , sql )
2017
+ _ , stats , err := runQuerySQL (ctx , sql )
2018
2018
if err != nil {
2019
2019
t .Fatal (err )
2020
2020
}
@@ -2036,12 +2036,18 @@ func TestIntegration_DML(t *testing.T) {
2036
2036
}
2037
2037
}
2038
2038
2039
+ // runQuerySQL runs arbitrary SQL text.
2040
+ func runQuerySQL (ctx context.Context , sql string ) (* JobStatistics , * QueryStatistics , error ) {
2041
+ return runQueryJob (ctx , client .Query (sql ))
2042
+ }
2043
+
2039
2044
// runQueryJob is useful for running queries where no row data is returned (DDL/DML).
2040
- func runQueryJob (ctx context.Context , sql string ) (* QueryStatistics , error ) {
2041
- var stats * QueryStatistics
2045
+ func runQueryJob (ctx context.Context , q * Query ) (* JobStatistics , * QueryStatistics , error ) {
2046
+ var jobStats * JobStatistics
2047
+ var queryStats * QueryStatistics
2042
2048
var err error
2043
2049
err = internal .Retry (ctx , gax.Backoff {}, func () (stop bool , err error ) {
2044
- job , err := client . Query ( sql ) .Run (ctx )
2050
+ job , err := q .Run (ctx )
2045
2051
if err != nil {
2046
2052
if e , ok := err .(* googleapi.Error ); ok && e .Code < 500 {
2047
2053
return true , err // fail on 4xx
@@ -2057,13 +2063,14 @@ func runQueryJob(ctx context.Context, sql string) (*QueryStatistics, error) {
2057
2063
}
2058
2064
status := job .LastStatus ()
2059
2065
if status .Statistics != nil {
2066
+ jobStats = status .Statistics
2060
2067
if qStats , ok := status .Statistics .Details .(* QueryStatistics ); ok {
2061
- stats = qStats
2068
+ queryStats = qStats
2062
2069
}
2063
2070
}
2064
2071
return true , nil
2065
2072
})
2066
- return stats , err
2073
+ return jobStats , queryStats , err
2067
2074
}
2068
2075
2069
2076
func TestIntegration_TimeTypes (t * testing.T ) {
@@ -2103,7 +2110,7 @@ func TestIntegration_TimeTypes(t *testing.T) {
2103
2110
"VALUES ('%s', '%s', '%s', '%s')" ,
2104
2111
table .DatasetID , table .TableID ,
2105
2112
d , CivilTimeString (tm ), CivilDateTimeString (dtm ), ts .Format ("2006-01-02 15:04:05" ))
2106
- if _ , err := runQueryJob (ctx , query ); err != nil {
2113
+ if _ , _ , err := runQuerySQL (ctx , query ); err != nil {
2107
2114
t .Fatal (err )
2108
2115
}
2109
2116
wantRows = append (wantRows , wantRows [0 ])
@@ -2275,6 +2282,44 @@ func TestIntegration_QueryExternalHivePartitioning(t *testing.T) {
2275
2282
checkReadAndTotalRows (t , "HiveQuery" , it , [][]Value {{int64 (50 )}})
2276
2283
}
2277
2284
2285
+ func TestIntegration_QuerySessionSupport (t * testing.T ) {
2286
+ if client == nil {
2287
+ t .Skip ("Integration tests skipped" )
2288
+ }
2289
+ ctx := context .Background ()
2290
+
2291
+ q := client .Query ("CREATE TEMPORARY TABLE temptable AS SELECT 17 as foo" )
2292
+ q .CreateSession = true
2293
+ jobStats , _ , err := runQueryJob (ctx , q )
2294
+ if err != nil {
2295
+ t .Fatalf ("error running CREATE TEMPORARY TABLE: %v" , err )
2296
+ }
2297
+ if jobStats .SessionInfo == nil {
2298
+ t .Fatalf ("expected session info, was nil" )
2299
+ }
2300
+ sessionID := jobStats .SessionInfo .SessionID
2301
+ if len (sessionID ) == 0 {
2302
+ t .Errorf ("expected non-empty sessionID" )
2303
+ }
2304
+
2305
+ q2 := client .Query ("SELECT * FROM temptable" )
2306
+ q2 .ConnectionProperties = []* ConnectionProperty {
2307
+ {Key : "session_id" , Value : sessionID },
2308
+ }
2309
+ jobStats , _ , err = runQueryJob (ctx , q2 )
2310
+ if err != nil {
2311
+ t .Errorf ("error running SELECT: %v" , err )
2312
+ }
2313
+ if jobStats .SessionInfo == nil {
2314
+ t .Fatalf ("expected sessionInfo in second query, was nil" )
2315
+ }
2316
+ got := jobStats .SessionInfo .SessionID
2317
+ if got != sessionID {
2318
+ t .Errorf ("second query mismatched session ID, got %s want %s" , got , sessionID )
2319
+ }
2320
+
2321
+ }
2322
+
2278
2323
func TestIntegration_QueryParameters (t * testing.T ) {
2279
2324
if client == nil {
2280
2325
t .Skip ("Integration tests skipped" )
@@ -2560,7 +2605,7 @@ func TestIntegration_ExtractExternal(t *testing.T) {
2560
2605
sql := fmt .Sprintf (`INSERT %s.%s (name, num)
2561
2606
VALUES ('a', 1), ('b', 2), ('c', 3)` ,
2562
2607
table .DatasetID , table .TableID )
2563
- if _ , err := runQueryJob (ctx , sql ); err != nil {
2608
+ if _ , _ , err := runQuerySQL (ctx , sql ); err != nil {
2564
2609
t .Fatal (err )
2565
2610
}
2566
2611
// Extract to a GCS object as CSV.
@@ -2986,7 +3031,7 @@ func TestIntegration_MaterializedViewLifecycle(t *testing.T) {
2986
3031
FROM
2987
3032
UNNEST(GENERATE_ARRAY(0,999))
2988
3033
` , qualified )
2989
- if _ , err := runQueryJob (ctx , sql ); err != nil {
3034
+ if _ , _ , err := runQuerySQL (ctx , sql ); err != nil {
2990
3035
t .Fatalf ("couldn't instantiate base table: %v" , err )
2991
3036
}
2992
3037
@@ -3114,7 +3159,7 @@ func TestIntegration_ModelLifecycle(t *testing.T) {
3114
3159
UNION ALL
3115
3160
SELECT 'b' AS f1, 3.8 AS label
3116
3161
)` , modelRef )
3117
- if _ , err := runQueryJob (ctx , sql ); err != nil {
3162
+ if _ , _ , err := runQuerySQL (ctx , sql ); err != nil {
3118
3163
t .Fatal (err )
3119
3164
}
3120
3165
defer model .Delete (ctx )
@@ -3297,7 +3342,7 @@ func TestIntegration_RoutineComplexTypes(t *testing.T) {
3297
3342
(SELECT SUM(IF(elem.name = "foo",elem.val,null)) FROM UNNEST(arr) AS elem)
3298
3343
)` ,
3299
3344
routine .FullyQualifiedName ())
3300
- if _ , err := runQueryJob (ctx , sql ); err != nil {
3345
+ if _ , _ , err := runQuerySQL (ctx , sql ); err != nil {
3301
3346
t .Fatal (err )
3302
3347
}
3303
3348
defer routine .Delete (ctx )
@@ -3357,7 +3402,7 @@ func TestIntegration_RoutineLifecycle(t *testing.T) {
3357
3402
sql := fmt .Sprintf (`
3358
3403
CREATE FUNCTION ` + "`%s`" + `(x INT64) AS (x * 3);` ,
3359
3404
routine .FullyQualifiedName ())
3360
- if _ , err := runQueryJob (ctx , sql ); err != nil {
3405
+ if _ , _ , err := runQuerySQL (ctx , sql ); err != nil {
3361
3406
t .Fatal (err )
3362
3407
}
3363
3408
defer routine .Delete (ctx )
0 commit comments