@@ -37,6 +37,7 @@ using ::google::cloud::testing_util::IsOkAndHolds;
3737using ::google::cloud::testing_util::StatusIs;
3838using ::testing::AnyOf;
3939using ::testing::ElementsAre;
40+ using ::testing::Eq;
4041using ::testing::HasSubstr;
4142using ::testing::ResultOf;
4243using ::testing::UnorderedElementsAreArray;
@@ -495,6 +496,69 @@ TEST_F(DataTypeIntegrationTest, WriteReadArrayTimestamp) {
495496 EXPECT_THAT (result, IsOkAndHolds (UnorderedElementsAreArray (data)));
496497}
497498
499+ TEST_F (DataTypeIntegrationTest, SelectIntervalScalar) {
500+ if (UsingEmulator ()) GTEST_SKIP ();
501+ auto expected_interval = MakeInterval (" 1-2 3 4:5:6.789123456" );
502+ ASSERT_STATUS_OK (expected_interval);
503+
504+ auto select = SqlStatement (R"sql(
505+ SELECT INTERVAL '1-2 3 4:5:6.789123456' YEAR TO SECOND;)sql" ,
506+ {});
507+
508+ auto result = client_->ExecuteQuery (std::move (select));
509+ for (auto & row : StreamOf<std::tuple<Interval>>(result)) {
510+ ASSERT_STATUS_OK (row);
511+ EXPECT_THAT (std::get<0 >(row.value ()), Eq (*expected_interval));
512+ }
513+ }
514+
515+ TEST_F (DataTypeIntegrationTest, SelectIntervalArray) {
516+ if (UsingEmulator ()) GTEST_SKIP ();
517+ auto expected_interval = MakeInterval (" 1-2 3 4:5:6.789123456" );
518+ ASSERT_STATUS_OK (expected_interval);
519+
520+ auto select = SqlStatement (R"sql(
521+ SELECT ARRAY<INTERVAL>[INTERVAL '1-2 3 4:5:6.789123456' YEAR TO SECOND];)sql" ,
522+ {});
523+
524+ auto result = client_->ExecuteQuery (std::move (select));
525+ for (auto & row : StreamOf<std::tuple<std::vector<Interval>>>(result)) {
526+ ASSERT_STATUS_OK (row);
527+ EXPECT_THAT (std::get<0 >(row.value ()).front (), Eq (*expected_interval));
528+ }
529+ }
530+
531+ TEST_F (DataTypeIntegrationTest, SelectIntervalFromTimestampDiff) {
532+ if (UsingEmulator ()) GTEST_SKIP ();
533+ Interval expected_interval{
534+ std::chrono::duration_cast<std::chrono::nanoseconds>(
535+ std::chrono::hours (1 ))};
536+ std::time_t now_seconds =
537+ std::chrono::system_clock::to_time_t (std::chrono::system_clock::now ());
538+ std::time_t one_hour_later_seconds = now_seconds + 3600 ;
539+
540+ std::vector<std::vector<Timestamp>> const data = {std::vector<Timestamp>{
541+ MakeTimestamp (MakeTime (now_seconds, 0 )).value (),
542+ MakeTimestamp (MakeTime (one_hour_later_seconds, 0 )).value ()}};
543+ auto result = WriteReadData (*client_, data, " ArrayTimestampValue" );
544+ EXPECT_THAT (result, IsOkAndHolds (UnorderedElementsAreArray (data)));
545+
546+ auto statement = SqlStatement (R"sql(
547+ SELECT
548+ CAST(ARRAY_LAST(ArrayTimestampValue) - ARRAY_FIRST(ArrayTimestampValue)
549+ AS INTERVAL) as v1
550+ FROM DataTypes;
551+ )sql" ,
552+ {});
553+
554+ auto query_result = client_->ExecuteQuery (std::move (statement));
555+ using RowType = std::tuple<Interval>;
556+ for (auto & row : StreamOf<RowType>(query_result)) {
557+ ASSERT_STATUS_OK (row);
558+ EXPECT_THAT (std::get<0 >(row.value ()), Eq (expected_interval));
559+ }
560+ }
561+
498562TEST_F (DataTypeIntegrationTest, WriteReadArrayDate) {
499563 std::vector<std::vector<absl::CivilDay>> const data = {
500564 std::vector<absl::CivilDay>{},
0 commit comments