[fix](point query) Enforce fixed key predicates in prepared point queries - #67885
Open
morrySnow wants to merge 1 commit into
Open
[fix](point query) Enforce fixed key predicates in prepared point queries#67885morrySnow wants to merge 1 commit into
morrySnow wants to merge 1 commit into
Conversation
morrySnow
requested review from
924060929,
englefly and
starocean999
as code owners
September 11, 2026 18:02
Contributor
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
Contributor
Author
|
run buildall |
Contributor
FE UT Coverage ReportIncrement line coverage |
### What problem does this PR solve?
Issue Number: None
Related PR: None
Problem Summary: Server-side prepared point queries could reuse a cached scan plan after a restrictive row policy added a fixed equality on the same key column as a placeholder. The direct path rediscovered key values from mutable translated conjuncts and rewrote every predicate sharing that column name, so a later binding could overwrite the policy literal and contaminate subsequent executions. Freeze placeholder bindings and exact fixed literals into an immutable key template, derive a typed tuple per execution, return a schema-correct empty batch before pruning or backend RPC for NULL or conflicting bindings, and fall back to normal planning for inexact coercions or unprovable predicates.
### Release note
Prepared point queries now preserve fixed row-policy key constraints across repeated server-side executions and safely fall back when a predicate cannot be represented as an exact physical lookup key.
### Check List (For Author)
- Test:
- Unit Test: ExecuteCommandTest, ShortCircuitQueryContextTest, and PointQueryExecutorTest (21 tests).
- Regression test: prepared_point_query_row_policy.
- Build/checkstyle: DISABLE_BUILD_UI=ON ./build.sh --fe.
- Behavior changed: Yes. Prepared point queries now return an empty result before tablet lookup when a bound key conflicts with an exact fixed predicate or is NULL; unprovable predicates use normal planning.
- Does this need documentation: No.
morrySnow
force-pushed
the
fix/enforce-prepared-point-policy-key-constraints
branch
from
September 11, 2026 20:44
371563b to
a77b540
Compare
Contributor
Author
|
run buildall |
8 tasks
morrySnow
marked this pull request as draft
September 12, 2026 03:06
Contributor
TPC-H: Total hot run time: 16954 ms |
Contributor
TPC-DS: Total hot run time: 81829 ms |
Contributor
ClickBench: Total hot run time: 14.6 s |
hello-stephen
pushed a commit
that referenced
this pull request
Sep 12, 2026
…67897) Since today every `Doris_DorisCloudRegression_VaultP0` run dies in the `run` step before executing a single test, e.g. #67883 (TeamCity build 39010) and #67881 / #67882 / #67885 / #67886 / #67892 / #67893: ``` doris-external--minio Pulling doris-external--minio Error Error response from daemon: pull access denied for minio/minio, repository does not exist or may require 'docker login': denied: requested access to the resource is denied ERROR: start minio docker twice failed ``` MinIO stopped publishing container images in October 2025 (the project is a source-only distribution now, see minio/minio#21647) and the `minio/minio` and `minio/mc` repositories have since been removed from Docker Hub altogether (`https://hub.docker.com/v2/repositories/minio/minio/` answers 404, same for `minio/mc`). The few VaultP0 runs that still pass do so only on agents that have the image cached locally (their logs have no `Pulling` line). The iceberg, hudi and polaris third-party fixtures, `test_file_cache_warmup_read_metrics_docker` (which runs a `docker run minio/minio` itself), the all-in-one `cloud.yml` and the datalake samples reference the same images and are one cache eviction away from the same failure. `quay.io/minio/minio` and `quay.io/minio/mc` still serve every tag we use -- `RELEASE.2024-11-07T00-52-20Z`, `RELEASE.2025-01-20T14-49-07Z`, mc `RELEASE.2025-01-17T23-25-50Z`, the two 2022 tags of the samples and `latest` -- and MinIO keeps pushing hotfix tags there (latest one dated 2026-04). `docker manifest inspect` resolves all of them (amd64 / arm64 / ppc64le). So every reference gets the `quay.io/` prefix and the tags stay exactly as they were: same builds, different registry. The CI agents already pull from quay.io for the OceanBase fixture. A longer-term option is to mirror these three tags into the project's own `doristhirdpartydocker` namespace, which already hosts hive / zookeeper / kafka / trinodb; that needs someone with push access to that Docker Hub organization and can follow separately.
morrySnow
marked this pull request as ready for review
September 12, 2026 11:22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Server-side prepared point queries could reuse a cached scan plan after a row policy added a fixed equality on the same key column as a placeholder. A later parameter binding could replace the policy literal in the cached conjunct, both bypassing the fixed restriction and contaminating subsequent executions of the same prepared handle.
Root cause
The direct point-query path rediscovered key values from translated scan conjuncts and updated every cached binary predicate sharing a column name. That representation lost the provenance between caller-controlled placeholders and fixed statement or policy literals, and made shared plan state mutable across executions.
Reproduction
Create a unique-key merge-on-write table with a composite key and a restrictive row policy such as
tenant_id = 1. Prepare a query withtenant_id = ? AND item_id = ?, then execute the same handle with tenant values1,2, and1again (and withNULL). The conflicting binding must return no rows, while the repeated matching binding must still work without changing the cached plan. A lossy predicate such asCAST(tenant_id AS CHAR(1)) = '1'must remain on the normal planning path.Fix
NULLor conflicts with a fixed key literal.Tests
./run-fe-ut.sh --run "org.apache.doris.nereids.trees.plans.commands.ExecuteCommandTest,org.apache.doris.qe.PointQueryExecutorTest,org.apache.doris.qe.ShortCircuitQueryContextTest"./build.sh --fe(through the sandbox FE update flow)./run-regression-test.sh --conf regression-test/conf/regression-conf.groovy.custom --run -f regression-test/suites/prepared_stmt_p0/prepared_point_query_row_policy.groovy