Skip to content

[test](fe) Test forwarding prepared executions that reuse cached parameter types - #70150

Merged
morningman merged 1 commit into
apache:masterfrom
morningman:b2m-t49-forward-cached-param-types
Nov 5, 2026
Merged

morningman merged 1 commit into
apache:masterfrom
morningman:b2m-t49-forward-cached-param-types

Conversation

@morningman

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: #68162, #69314

Problem Summary:

In short. This ports MysqlPreparedStatementForwardingTest from branch-4.1 #68162 to master. Master already has the fix the test guards, through #69314. The port adds what master's own tests do not cover: a NULL bitmap of two bytes, and the forward request that FEOpExecutor builds and Thrift carries. The PR changes tests only.

Background. A client that runs a server-side prepared statement again may leave out the parameter types (new_params_bind_flag = 0) and have the server reuse the ones it cached. A follower forwards every COM_STMT_EXECUTE to the master. The master prepares the statement again for each forwarded execution, so it has no cached types and cannot bind the parameters. #68162 fixed this on branch-4.1, together with the Lance prepared vector search it was written for. Master fixed it independently in #69314: when the client reuses cached types, MysqlConnectProcessor.handleExecute writes the forwarded packet again, with the NULL bitmap, new_params_bind_flag = 1, every type code including the unsigned flag, and the values. #69314 also has the prepare stage plan with the context of the re-parsed statement, which is the other generic part of #68162. Its tests in MysqlConnectProcessorLongDataTest cover cached types, unsigned flags, changing NULLs, changing types, all-NULL executions and the prepare context.

What those tests leave out. They use at most four parameters, so the NULL bitmap always fits in one byte. They also give the master the buffer kept on the follower's context, rather than the request FEOpExecutor.buildStmtForwardParams builds.

What this PR adds. The test runs a ten-parameter statement five times on a follower connection:

  • The parameter types are sent with the first and the fourth execution; the other executions reuse the cached ones.
  • One execution has a NULL parameter in each byte of the NULL bitmap.
  • An unsigned INT parameter becomes a BIGINT in the fourth execution.

After each execution, the test builds the forward request with FEOpExecutor, passes it through a Thrift round trip and executes it on a new proxy context whose placeholders have no types. It then checks three things: every parameter binds to the same value as on the follower, the unsigned flag carries over, and the client's packet is read to its end and left unchanged. The code is the 4.1 test adapted to master's structure: master's PrepareCommand, query id and audit setup, as in MysqlConnectProcessorLongDataTest, and expressions compared directly. The 4.1 assertion that the follower keeps the client's buffer was dropped, because master writes a separate buffer for cached types by design.

Results.

handleExecute on master MysqlConnectProcessorLongDataTest (14) MysqlPreparedStatementForwardingTest (1)
as is pass pass
no rewrite of the forwarded packet for cached types (the bug #68162 fixed) 3 fail fails: the master binds untyped placeholders (No value present)
the rewrite keeps only the first byte of the NULL bitmap pass fails: the master reads the packet one byte off

Original author: @Gabriel39

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason

    New MysqlPreparedStatementForwardingTest passes, together with MysqlConnectProcessorLongDataTest, FEOpExecutorMysqlProtocolTest, MysqlConnectProcessorCursorFetchTest and MysqlConnectProcessorExecuteCleanupTest (28 tests). The two mutations in the table above were run against it. This PR changes no production code.

  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

…meter types

### What problem does this PR solve?

Issue Number: None

Related PR: apache#68162, apache#69314

Problem Summary: A client that runs a server-side prepared statement
again can leave out the parameter types (new_params_bind_flag = 0) and
have the server reuse the cached ones. A follower forwards each
COM_STMT_EXECUTE to the master, which prepares the statement again for
every forwarded execution and therefore has no cached types. branch-4.1
fixed this in apache#68162 (the part not specific to Lance). On master, apache#69314
fixed it in MysqlConnectProcessor.handleExecute, which rewrites the packet
it forwards with a complete type table, and its tests cover cached types,
unsigned flags, NULL changes and type updates. Those tests use at most
four parameters, so the NULL bitmap is always one byte. They also hand
the master the buffer from the follower's context, not the request that
FEOpExecutor builds and Thrift carries.

This ports the test apache#68162 added, MysqlPreparedStatementForwardingTest,
to master's structure. A ten-parameter statement runs five times on a
follower connection. Types are sent with the first and the fourth
execution and reused otherwise. One execution sets a NULL in each byte of
the NULL bitmap, and an unsigned INT later becomes a BIGINT. Each
execution is forwarded through FEOpExecutor.buildStmtForwardParams and a
Thrift round trip and runs on a new proxy context with untyped
placeholders. Every parameter must bind there as it did on the follower,
including the unsigned flag, and the client's packet must be read to its
end and left unchanged.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - New MysqlPreparedStatementForwardingTest passes, together with
      MysqlConnectProcessorLongDataTest, FEOpExecutorMysqlProtocolTest,
      MysqlConnectProcessorCursorFetchTest and
      MysqlConnectProcessorExecuteCleanupTest.
    - It fails when handleExecute does not rewrite the forwarded packet
      for cached types, and when the rewrite keeps only the first byte of
      the NULL bitmap; MysqlConnectProcessorLongDataTest does not catch
      the second case.
- Behavior changed: No
- Does this need documentation: No

Co-authored-by: Gabriel <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@morningman

Copy link
Copy Markdown
Contributor Author

run buildall

@morningman

Copy link
Copy Markdown
Contributor Author

/review

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 28213 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 06c21ce5f8345b7c13e9298448477f1b436fa826, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17595	5119	5007	5007
q2	2093	293	246	246
q3	10287	1354	813	813
q4	4677	461	332	332
q5	7429	787	519	519
q6	177	181	151	151
q7	737	781	596	596
q8	9249	1331	1008	1008
q9	5502	4190	4177	4177
q10	6829	1270	1047	1047
q11	432	242	223	223
q12	631	395	280	280
q13	18137	3573	3017	3017
q14	276	273	246	246
q15	q16	717	707	678	678
q17	1183	764	579	579
q18	6963	6178	6085	6085
q19	1108	951	569	569
q20	383	337	232	232
q21	5248	2162	2269	2162
q22	342	289	246	246
Total cold run time: 99995 ms
Total hot run time: 28213 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5562	5570	5546	5546
q2	674	545	556	545
q3	5190	5354	4960	4960
q4	1983	2134	1550	1550
q5	5233	5134	5501	5134
q6	269	209	157	157
q7	2326	2046	1924	1924
q8	3006	2682	2720	2682
q9	8045	8068	7950	7950
q10	3714	3779	3266	3266
q11	597	440	415	415
q12	729	710	533	533
q13	3517	3883	3283	3283
q14	310	315	285	285
q15	q16	705	727	651	651
q17	8166	6999	6850	6850
q18	12993	12180	12920	12180
q19	892	764	760	760
q20	2128	2138	1916	1916
q21	5567	4595	4678	4595
q22	484	442	407	407
Total cold run time: 72090 ms
Total hot run time: 65589 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 150727 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 06c21ce5f8345b7c13e9298448477f1b436fa826, data reload: false

query5	4307	591	437	437
query6	453	209	189	189
query7	4803	436	226	226
query8	310	160	150	150
query9	8775	3139	3149	3139
query10	451	313	258	258
query11	5879	3856	3566	3566
query12	142	91	85	85
query13	1251	447	325	325
query14	6090	3895	3636	3636
query14_1	3367	3322	3327	3322
query15	205	202	198	198
query16	938	442	379	379
query17	869	670	536	536
query18	2433	469	295	295
query19	213	155	126	126
query20	81	82	79	79
query21	204	122	105	105
query22	13049	13094	12911	12911
query23	13410	12620	12425	12425
query23_1	12469	12589	12551	12551
query24	7402	823	467	467
query24_1	482	474	475	474
query25	508	392	330	330
query26	1245	253	140	140
query27	2774	435	280	280
query28	4598	2022	2032	2022
query29	1535	572	415	415
query30	291	216	185	185
query31	995	929	817	817
query32	136	86	86	86
query33	511	293	227	227
query34	878	852	506	506
query35	722	744	654	654
query36	859	856	717	717
query37	121	91	79	79
query38	1760	1712	1673	1673
query39	802	785	751	751
query39_1	729	721	740	721
query40	215	112	93	93
query41	64	61	63	61
query42	87	81	80	80
query43	342	358	306	306
query44	1320	713	733	713
query45	176	193	172	172
query46	830	962	565	565
query47	3009	2993	2753	2753
query48	302	311	224	224
query49	577	402	297	297
query50	684	275	213	213
query51	10423	10472	10115	10115
query52	79	80	71	71
query53	186	208	153	153
query54	235	203	192	192
query55	79	64	63	63
query56	245	232	227	227
query57	1654	1627	1570	1570
query58	293	289	261	261
query59	2191	2247	2049	2049
query60	292	252	239	239
query61	162	163	166	163
query62	396	331	284	284
query63	190	163	161	161
query64	2774	915	744	744
query65	3301	3269	3254	3254
query66	1783	418	294	294
query67	20021	20224	19963	19963
query68	3142	1012	622	622
query69	388	280	248	248
query70	861	777	758	758
query71	295	231	196	196
query72	2655	2585	2372	2372
query73	512	531	295	295
query74	4639	4492	4321	4321
query75	2303	2285	1891	1891
query76	2324	1016	582	582
query77	360	362	273	273
query78	9659	9689	9215	9215
query79	904	837	523	523
query80	505	425	350	350
query81	523	324	273	273
query82	341	140	101	101
query83	303	195	182	182
query84	309	116	98	98
query85	834	431	374	374
query86	313	238	230	230
query87	1944	1921	1832	1832
query88	3750	2821	2774	2774
query89	325	279	236	236
query90	1807	169	162	162
query91	166	191	124	124
query92	100	89	88	88
query93	981	985	575	575
query94	450	305	264	264
query95	571	341	290	290
query96	673	484	239	239
query97	2450	2416	2335	2335
query98	183	150	145	145
query99	771	768	664	664
Total cold run time: 233070 ms
Total hot run time: 150727 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.17 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 06c21ce5f8345b7c13e9298448477f1b436fa826, data reload: false

query1	0.01	0.01	0.01
query2	0.09	0.04	0.04
query3	0.26	0.09	0.10
query4	1.60	0.10	0.10
query5	0.23	0.23	0.23
query6	1.17	0.67	0.67
query7	0.03	0.00	0.00
query8	0.05	0.03	0.04
query9	0.39	0.36	0.36
query10	0.57	0.61	0.58
query11	0.20	0.15	0.16
query12	0.19	0.16	0.15
query13	0.48	0.50	0.48
query14	1.02	1.01	1.00
query15	0.61	0.61	0.60
query16	0.34	0.33	0.34
query17	1.15	1.19	1.07
query18	0.21	0.19	0.18
query19	2.04	2.06	1.95
query20	0.02	0.02	0.01
query21	15.48	0.20	0.13
query22	4.91	0.05	0.05
query23	16.28	0.31	0.12
query24	2.86	0.62	0.37
query25	0.13	0.06	0.05
query26	1.28	0.23	0.15
query27	0.03	0.04	0.04
query28	2.54	0.67	0.38
query29	12.49	4.17	3.27
query30	0.28	0.13	0.10
query31	2.78	0.57	0.33
query32	3.23	0.60	0.49
query33	3.21	3.24	3.25
query34	15.38	3.96	3.37
query35	3.36	3.29	3.33
query36	0.56	0.49	0.42
query37	0.09	0.06	0.06
query38	0.05	0.04	0.04
query39	0.04	0.02	0.02
query40	0.16	0.15	0.14
query41	0.08	0.04	0.02
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 95.96 s
Total hot run time: 24.17 s

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed PR #70150 at head 06c21ce. The only changed file is the FE unit test fe/fe-core/src/test/java/org/apache/doris/qe/MysqlPreparedStatementForwardingTest.java, so no production behavior, locking, persistence, configuration, compatibility, memory, or error-handling path is changed. The test's protocol setup was traced through MysqlConnectProcessor.handleExecute, FEOpExecutor.buildStmtForwardParams, MysqlProtocolAdapter.fillForwardRequest, Thrift binary serialization, and the proxy-side execute path. It covers cached versus new parameter types, an unsigned LONG to signed LONGLONG change, NULL bits in both bytes of a ten-parameter bitmap, unchanged client packet bytes, and all parameter bindings after the Thrift round trip. Construction-mocked StmtExecutor intentionally keeps this as a parser/binding/forwarding test; the existing FE cleanup tests cover per-execution StatementContext lifecycle separately. No existing P0/P1 inline findings or user focus items apply. Static review only; no build or test commands were run by this reviewer. Round 1 converged: all assigned subagents returned NO_NEW_VALUABLE_FINDINGS and every main risk item was dismissed with evidence.

Review converged after 1 round(s).

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage `` 🎉
Increment coverage report
Complete coverage report

@924060929 924060929 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This test-only PR checks prepared executions forwarded from a follower to a freshly prepared master context, which cannot reuse the client's cached parameter types. Independent static review traced handleExecute, FEOpExecutor.buildStmtForwardParams, MysqlProtocolAdapter.fillForwardRequest, Thrift serialization, and proxy-side parameter binding. The test covers a two-byte NULL bitmap, cached and updated types, unsigned INT to signed BIGINT, packet consumption, and unchanged client bytes. No actionable P0/P1/P2 issues were found in the FE scope. APPROVE.

StmtExecutor is mocked, so this validates binding and forwarding rather than SQL execution. No builds or tests were run during this review. The supplied current-head snapshot reports successful FE UT, compilation and P0 regression, but failed check_coverage_fe; required-check rules and the coverage failure cause were not established. This is code approval, not merge clearance.

Automated FE-focused static review (gpt-6.1-sol, high). No build or tests were run.

@morningman
morningman merged commit d03d410 into apache:master Nov 5, 2026
37 of 38 checks passed
@morningman
morningman requested a review from CalvinKirs November 5, 2026 07:19
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