Skip to content

HIVE-30196: Enforce hive.metastore.limit.partition.request in get_partitions_with_specs - #6886

Open
wangyum wants to merge 2 commits into
apache:masterfrom
wangyum:hive.metastore.limit.partition.request
Open

wangyum wants to merge 2 commits into
apache:masterfrom
wangyum:hive.metastore.limit.partition.request

Conversation

@wangyum

@wangyum wangyum commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Problem

get_partitions_with_specs (introduced by HIVE-20306) skipped the hive.metastore.limit.partition.request guard that every regular partition listing RPC enforces — the config's own description enumerates the 8 covered RPCs and this one was absent. The thrift request has no client-side max parameter, so a single call made the metastore materialize all matching partitions server-side before responding.

HiveServer2 paths (PartitionIterable batched iteration, SHOW TABLE EXTENDED, EXCHANGE PARTITION, repl bootstrap, view rewrite analysis) and direct HMS clients (e.g. Spark) use this API, so an operator-configured guard was silently bypassed on it.

What this change does

  1. Fail-fast pre-check in HMSHandler.get_partitions_with_specs, before the expensive fetch, mirroring what the regular listing RPCs already do (checkLimitNumberOfPartitionsByFilter / checkLimitNumberOfPartitionsByPs), mapped per filter mode:
    • filter spec unset → rs.getNumPartitionsByFilter(cat, db, tbl, "")
    • BY_NAMES → the requested partition names count (same as get_partitions_by_names)
    • BY_VALUES → rs.getNumPartitionsByPs (identical predicate: same MetaStoreUtils.makePartNameMatcher on both the SQL and JDO paths)
    • BY_EXPR → rs.getNumPartitionsByFilter on the joined expressions (same PartFilterExprUtil grammar the projection path parses)
  2. Post-fetch backstop on the fetched result size — covers the count/fetch TOCTOU window (concurrent add_partitions) and unknown filter modes.
  3. Adds get_partitions_with_specs to the LIMIT_PARTITION_REQUEST config description.
  4. Authorization ordering is preserved: firePreEvent (pre-event listeners) still runs before the limit checks.

exceedsPartitionFetchLimit / checkLimitNumberOfPartitions were made public static (taking an explicit Configuration) so the handler flow and get_partitions_with_specs share one implementation. The check stays at the RPC layer on purpose: the same store method is also used internally by the column-stats path, so the guard must not become a store-level rule.

Behavior changes (only when the limit is configured; default -1 = disabled is unchanged)

  • Requests matching more partitions than the limit now throw the same MetaException (same message / config name) as the regular listing RPCs.
  • BY_NAMES now uses the strict requested-count semantics, mirroring get_partitions_by_names: requesting more names than the limit fails even if fewer of them exist.
  • no-filter / BY_VALUES / BY_EXPR requests pay one extra count query per request; BY_NAMES is free.
  • Policy decision: projected PartitionSpec responses count as partition objects — response size and DB work scale with the number of matched partitions regardless of projection.

Tests

TestGetPartitionsUsingProjectionAndFilterSpecs (server started with LIMIT_PARTITION_REQUEST=100), new tests against a 101-partition table:

test covers
...ExceedsPartitionLimit no-filter mode over limit → throws
...AtPartitionLimit boundary: exactly 100 → succeeds
...ByNamesExceeds... BY_NAMES, all 101 names exist → throws
...ByNamesRequestedCountExceeds... 150 requested / 50 exist → throws (pins the strict semantics)
...ByValuesExceeds... BY_VALUES partial values matching 101 → throws
...ByExprExceeds... BY_EXPR expression matching 101 → throws
...ExceedsPartitionLimitWithJDO same as the first, DirectSQL disabled → JDO count path

All 32 tests pass, plus TestRemoteHiveMetaStore#testGetPartitionsWithSpec, TestEmbeddedHiveMetaStore#testGetPartitionsWithSpec, and TestHmsServerAuthorization (authorization failure still precedes the limit check).

…titions_with_specs

get_partitions_with_specs skipped the hive.metastore.limit.partition.request
guard that every regular partition listing RPC enforces (get_partitions,
get_partitions_by_names, get_partitions_with_auth, get_partitions_by_filter,
get_partitions_by_expr, get_partitions_ps, get_partitions_ps_with_auth).
Enforce it:

- Fail fast before the partition fetch using the same cheap count queries
  the regular listing RPCs use, mapped per filter mode:
  - filter spec unset -> getNumPartitionsByFilter("")
  - BY_NAMES -> the requested partition names count (as get_partitions_by_names does)
  - BY_VALUES -> getNumPartitionsByPs (same makePartNameMatcher predicate as the fetch)
  - BY_EXPR -> getNumPartitionsByFilter on the joined expressions (same grammar)
- Keep a check on the fetched result size as the final backstop (covers the
  count/fetch TOCTOU window and unknown filter modes)
- Add get_partitions_with_specs to the config description

Default (-1) behavior is unchanged; the guard only applies when the operator
configures the limit.

Related: HIVE-30195 (table-level filter hook check gap in the same RPC)
Co-authored-by: Cursor <cursoragent@cursor.com>
@wangyum

wangyum commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

cc @dengzhhu653

Co-authored-by: Cursor <cursoragent@cursor.com>
@sonarqubecloud

Copy link
Copy Markdown

List<Partition> partitions = getMS()
.getPartitionSpecsByFilterAndProjection(table, request.getProjectionSpec(),
request.getFilterSpec());
GetPartitionsHandler.checkLimitNumberOfPartitions(getConf(), tableName, partitions.size());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need to check again at here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this implementation to GetPartitionsHandler if it's ok? so it shares the same pre check and post check and the fetch limit validation.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants