From ec82dc73236b7f4f7945de5a401e7ad2ef47fad7 Mon Sep 17 00:00:00 2001 From: Matt Schallert Date: Wed, 19 Feb 2025 18:37:08 -0800 Subject: [PATCH 1/2] [query] Support SCAN_METHOD hint Fixes #203. --- backend/query/query_validator.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/backend/query/query_validator.cc b/backend/query/query_validator.cc index 74fb6f2e..9c37193b 100644 --- a/backend/query/query_validator.cc +++ b/backend/query/query_validator.cc @@ -104,6 +104,11 @@ constexpr absl::string_view kHintTableScanGroupByScanOptimization = constexpr absl::string_view kUseAdditionalParallelism = "use_additional_parallelism"; +constexpr absl::string_view kScanMethod = "scan_method"; +constexpr absl::string_view kScanMethodAuto = "auto"; +constexpr absl::string_view kScanMethodBatch = "batch"; +constexpr absl::string_view kScanMethodRow = "row"; + // Lock scanned ranges constexpr absl::string_view kHintLockScannedRange = "lock_scanned_ranges"; constexpr absl::string_view kHintLockScannedRangeShared = "shared"; @@ -210,7 +215,7 @@ absl::Status QueryValidator::CheckSpannerHintName( zetasql_base::StringViewCaseEqual>>{ {zetasql::RESOLVED_TABLE_SCAN, {kHintForceIndex, kHintTableScanGroupByScanOptimization, - kHintIndexStrategy}}, + kHintIndexStrategy, kScanMethod}}, {zetasql::RESOLVED_JOIN_SCAN, {kHintJoinTypeDeprecated, kHintJoinMethod, kHashJoinBuildSide, kHintJoinForceOrder, kHashJoinExecution}}, @@ -236,6 +241,7 @@ absl::Status QueryValidator::CheckSpannerHintName( kHintAllowSearchIndexesInTransaction, kRequireEnhanceQuery, kEnhanceQueryTimeoutMs, + kScanMethod, }}, {zetasql::RESOLVED_SUBQUERY_EXPR, {kHintJoinTypeDeprecated, kHintJoinMethod, kHashJoinBuildSide, @@ -298,6 +304,7 @@ absl::Status QueryValidator::CheckHintValue( {kHintAllowSearchIndexesInTransaction, zetasql::types::BoolType()}, {kRequireEnhanceQuery, zetasql::types::BoolType()}, {kEnhanceQueryTimeoutMs, zetasql::types::Int64Type()}, + {kScanMethod, zetasql::types::StringType()}, }}; const auto& iter = supported_hint_types->find(name); @@ -393,6 +400,13 @@ absl::Status QueryValidator::CheckHintValue( kHintIndexStrategyForceIndexUnion)) { return error::InvalidHintValue(name, value.DebugString()); } + } else if (absl::EqualsIgnoreCase(name, kScanMethod)) { + const std::string& string_value = value.string_value(); + if (!(absl::EqualsIgnoreCase(string_value, kScanMethodAuto) || + absl::EqualsIgnoreCase(string_value, kScanMethodBatch) || + absl::EqualsIgnoreCase(string_value, kScanMethodRow))) { + return error::InvalidHintValue(name, value.DebugString()); + } } return absl::OkStatus(); } From 5f9ca68fc8dc4da469c897acf2900960885e1147 Mon Sep 17 00:00:00 2001 From: Matt Schallert Date: Wed, 19 Feb 2025 22:32:54 -0800 Subject: [PATCH 2/2] Don't allow "auto" for scan method Docs: > You can't manually set the scan method to AUTO; to do so, remove the > statement hint, and Spanner will set it to the default method. https://cloud.google.com/spanner/docs/reference/standard-sql/query-syntax --- backend/query/query_validator.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/query/query_validator.cc b/backend/query/query_validator.cc index 9c37193b..f2e37454 100644 --- a/backend/query/query_validator.cc +++ b/backend/query/query_validator.cc @@ -105,7 +105,6 @@ constexpr absl::string_view kUseAdditionalParallelism = "use_additional_parallelism"; constexpr absl::string_view kScanMethod = "scan_method"; -constexpr absl::string_view kScanMethodAuto = "auto"; constexpr absl::string_view kScanMethodBatch = "batch"; constexpr absl::string_view kScanMethodRow = "row"; @@ -402,8 +401,7 @@ absl::Status QueryValidator::CheckHintValue( } } else if (absl::EqualsIgnoreCase(name, kScanMethod)) { const std::string& string_value = value.string_value(); - if (!(absl::EqualsIgnoreCase(string_value, kScanMethodAuto) || - absl::EqualsIgnoreCase(string_value, kScanMethodBatch) || + if (!(absl::EqualsIgnoreCase(string_value, kScanMethodBatch) || absl::EqualsIgnoreCase(string_value, kScanMethodRow))) { return error::InvalidHintValue(name, value.DebugString()); }