Skip to content

[fix](arrow-flight) Support table type metadata and filters - #67899

Merged
morningman merged 6 commits into
apache:masterfrom
hutiefang76:frank/doris-flight-table-types
Nov 3, 2026
Merged

morningman merged 6 commits into
apache:masterfrom
hutiefang76:frank/doris-flight-table-types

Conversation

@hutiefang76

@hutiefang76 hutiefang76 commented Sep 12, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Related to #67578 (partial A3).

Flight SQL clients can obtain FlightInfo for GetTableTypes, but reading its ticket fails with UNIMPLEMENTED. GetTables also forwards only the first table_types entry to a service that treats only VIEW as a filter: [VIEW, BASE TABLE] loses base tables, while [BASE TABLE] or an unknown type can return excluded rows.

Implement the type stream using the same Doris names as GetTables (BASE TABLE, SYSTEM VIEW and VIEW), sorted according to Flight SQL. Match the complete filter against the existing authorized listing before collecting optional schemas. Request only name/type metadata to avoid unused table statistics, and retain the session guard and Arrow buffer cleanup on failed sends.

A type is the TABLE_TYPE that information_schema.tables reports for the object: table streams are VIEW, and external catalogs report their tables and views as BASE TABLE. The service lists every authorized object and the filter runs on that listing. Requested names match case-insensitively, and TABLE and SYSTEM TABLE, which Flight SQL calls commonly supported, select BASE TABLE and SYSTEM VIEW: the ADBC Flight SQL driver asks for table (Doris's own ADBC catalog lists a Doris source with getObjects(..., {"table"})), and JDBC tools ask for TABLE. Any other name matches only a type of that name, so UNKNOWN selects nothing.

Because the filter now runs on the full listing, FrontendServiceImpl.listTableStatus refreshes a cloud follower's partition versions from the meta service only when UPDATE_TIME is requested, the one column that reads them. GetTables, which asks for names and types, never waits on those RPCs or is cut short when they fail, and information_schema.tables scans that do not read UPDATE_TIME skip the refresh too.

Release note

Flight SQL clients can enumerate supported table types and filter table metadata by multiple types accurately. Type names match case-insensitively, and TABLE and SYSTEM TABLE are accepted for BASE TABLE and SYSTEM VIEW.

Check List (For Author)

  • Test:
    • CI on 221a0af passed: FE UT FlightSqlSchemaHelperTableTypesTest (27: every filter with and without schemas, aliases and mixed case, external catalog) and FlightSqlTableTypesTest (3, including GetFlightInfo -> DoGet through a real FlightServer); regression arrow_flight_sql_p0/test_table_types_over_arrow_flight in P0 and cloud_p0 (Flight SQL JDBC getTableTypes() / getTables() with the filters above, then the same RPCs from a plain Flight SQL client); the 21 external_table_p0/adbc suites, which list a Doris source through the ADBC Flight SQL driver, in External.
    • 747a1d4 adds FrontendServiceImplTest#testListTableStatusRefreshesCloudFollowerVersionsOnlyForUpdateTime: a cloud follower whose version RPC fails lists a base table and a view for TABLE_NAME and TABLE_TYPE without calling it, and still calls it for UPDATE_TIME. FlightSqlSchemaHelperTableTypesTest also checks that GetTables requests exactly TABLE_NAME and TABLE_TYPE. The command below passes locally (75 tests) and FE Checkstyle reports 0 violations.
  • Behavior changed: Yes. GetTableTypes now returns BASE TABLE, SYSTEM VIEW and VIEW. Empty type filters retain all authorized tables; unknown-only filters return no rows. On a non-master FE in cloud mode, listing table status fetches partition versions from the meta service only when UPDATE_TIME is requested.
  • Does this need documentation: No new configuration or API schema.

Validation command (JDK 17, matching Thrift 0.24.0 compiler):

bash run-fe-ut.sh --run org.apache.doris.arrowflight.FlightSqlTableTypesTest,org.apache.doris.arrowflight.FlightSqlSchemaHelperTableTypesTest,org.apache.doris.arrowflight.DorisFlightSqlProducerTest,org.apache.doris.arrowflight.FlightSqlSchemaHelperSerializedSchemaTest,org.apache.doris.service.FrontendServiceImplTest

The branch was rebased onto master 2a4191c (merge commits dropped). 2a31c4d, 1258c51, 221a0af and 747a1d4 were added on top by a maintainer: end-to-end GetTableTypes checks through the Flight RPC, the type-name aliases, closing the test's plain Flight session, and the cloud follower version refresh limited to UPDATE_TIME. No local toolchain configuration or generated sources are included.

AI assistance: DeepSeek and Codex assisted review, conflict resolution, validation and this description.

@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?

hutiefang76 added a commit to hutiefang76/doris that referenced this pull request Sep 13, 2026
### What problem does this PR solve?

Related PR: apache#67899

Problem Summary: Exercise SQL-created base tables and views through the Arrow
Flight JDBC metadata APIs, covering type enumeration and complete type filters.
The suite executes DDL over Flight and consumes GetTableTypes/GetTables streams.

### Release note

None

### Check List (For Author)

- Test: official regression runner, 1 suite passed against a test FE with real
  Flight/MySQL services and the built-in mocked BE; 30 related FE unit tests
  passed. No native BE or data-scan integration was exercised.
- Behavior changed: No, test-only addition
- Does this need documentation: No
@hutiefang76

Copy link
Copy Markdown
Contributor Author

I’m syncing this with current master. The conflict is in the schema-helper imports; I’ll keep the newer Arrow type support and rerun the Flight metadata tests before pushing.

hutiefang76 added a commit to hutiefang76/doris that referenced this pull request Oct 15, 2026
### What problem does this PR solve?

Related PR: apache#67899

Problem Summary: Resolve the schema-helper import conflict while retaining master Arrow type support and the table-types metadata fix.

### Release note

None; this commit synchronizes the existing PR with master.

### Check List (For Author)

- Test: FE Checkstyle passed with zero violations. Official selected FE unit-test command attempted; blocked before execution by the Intel-only grpc-java 1.34.0 generator on this ARM macOS host.
- Behavior changed: No additional behavior beyond the existing PR and master.
- Does this need documentation: No.

Signed-off-by: hutiefang76 <[email protected]>
@hutiefang76

Copy link
Copy Markdown
Contributor Author

Merged master in 58c16ac and resolved the import conflict, retaining the newer Arrow type support. FE Checkstyle reports zero violations.

I attempted the selected tests through run-fe-ut.sh, but the build stops before test execution at the Intel-only grpc-java 1.34.0 generator on this ARM Mac. I have updated the description so the earlier 30-test and SQL/Flight regression results are not mistaken for verification of this merged head. The local toolchain files are not part of the patch.

@morningman morningman self-assigned this Oct 29, 2026
hutiefang76 and others added 3 commits October 29, 2026 23:16
Related to apache#67578 (partial A3).

Flight SQL clients can obtain FlightInfo for GetTableTypes, but reading its ticket fails with UNIMPLEMENTED. GetTables also forwards only the first table_types entry to a service that treats only VIEW as a filter: [VIEW, BASE TABLE] loses base tables, while [BASE TABLE] or an unknown type can return excluded rows.

Implement the type stream using the same Doris names as GetTables, sorted according to Flight SQL. Match the complete filter against the existing authorized listing before collecting optional schemas. Request only name/type metadata to avoid unused table statistics, and retain the session guard and Arrow buffer cleanup on failed sends.

Flight SQL clients can enumerate supported table types and filter table metadata by multiple types accurately.

- Test:
  - [x] Unit Test: 30 passed via run-fe-ut.sh, including 19 new regression cases and 11 existing producer/schema cases.
  - Baseline: the 19 new cases produced 15 failures/errors on unmodified master, reproducing UNIMPLEMENTED and incorrect filtering.
  - Coverage includes both schema modes, filter order, unknown/duplicate types, external catalog propagation, serialized column alignment and repeated success/failure buffer cleanup.
  - FE Checkstyle: 0 violations.
  - No live-cluster or end-to-end ADBC driver test was run.
- Behavior changed: Yes. GetTableTypes now returns BASE TABLE, SYSTEM VIEW and VIEW. Empty type filters retain all authorized tables; unknown-only filters return no rows.
- Does this need documentation: No new configuration or API schema.

Validation command (JDK 17, matching Thrift 0.24.0 compiler):

```sh
bash run-fe-ut.sh --run org.apache.doris.arrowflight.FlightSqlTableTypesTest,org.apache.doris.arrowflight.FlightSqlSchemaHelperTableTypesTest,org.apache.doris.arrowflight.DorisFlightSqlProducerTest,org.apache.doris.arrowflight.FlightSqlSchemaHelperArrowTypeTest
```
### What problem does this PR solve?

Related PR: apache#67899

Problem Summary: Exercise SQL-created base tables and views through the Arrow
Flight JDBC metadata APIs, covering type enumeration and complete type filters.
The suite executes DDL over Flight and consumes GetTableTypes/GetTables streams.

### Release note

None

### Check List (For Author)

- Test: official regression runner, 1 suite passed against a test FE with real
  Flight/MySQL services and the built-in mocked BE; 30 related FE unit tests
  passed. No native BE or data-scan integration was exercised.
- Behavior changed: No, test-only addition
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: None

Related PR: apache#68631

Problem Summary:

branch-4.1 apache#68631 (also on branch-4.2) implemented the GetTableTypes data
stream and tested it end to end over Flight RPC: a unit test that runs a
real FlightServer and FlightSqlClient, and a regression suite that uses a
plain Flight SQL client. The tests in this PR call
`getStreamTableTypes()` directly with a mocked listener, or go through
JDBC `getTableTypes()`, so the GetFlightInfo -> DoGet sequence that a
plain Flight SQL client sends was not covered.

This commit adds both checks from apache#68631:

- `FlightSqlTableTypesTest#tableTypesAreSortedAndStableThroughFlightRpc`
  calls GetTableTypes three times through a real FlightServer. Each call
  must return the GetTableTypes schema with one endpoint, and DoGet must
  return the same sorted types. Only DoGet resolves the session. The
  4.x version mocked the ConnectContext and checked that nothing touched
  it. On master the metadata stream runs as a command of the session
  (`FlightProtocolAdapter.runCommand`), which reads the context, so the
  test uses `ConnectContext.forFlight` as the other tests here do.
- `test_table_types_over_arrow_flight` sends the same RPCs three times
  from a plain Flight SQL client, checking the field name, type and
  nullability, then runs a query on the session afterwards.

### Release note

None

### Check List (For Author)

- Test: Unit Test / Regression test
- Behavior changed: No
- Does this need documentation: No

Co-authored-by: Gabriel <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@morningman
morningman force-pushed the frank/doris-flight-table-types branch from 58c16ac to 2a31c4d Compare October 29, 2026 15:33
@morningman

Copy link
Copy Markdown
Contributor

@hutiefang76 I rebased this branch onto the current master and added one commit on top, so it can go through CI and review:

  • Rebase: your two commits were cherry-picked onto master 2a4191c1dc9 with your authorship kept, and the two merge commits were dropped. The only conflict was the same FlightSqlSchemaHelper import block you resolved in 58c16ac, resolved the same way. Your part of the diff is unchanged.
  • 2a31c4d brings over the end-to-end checks of branch-4.1 [fix](flight-sql) Return analyzed query schemas and table type metadata #68631, which implemented GetTableTypes there. FlightSqlTableTypesTest#tableTypesAreSortedAndStableThroughFlightRpc calls GetTableTypes three times through a real FlightServer and FlightSqlClient. test_table_types_over_arrow_flight sends the same GetFlightInfo -> DoGet calls from a plain Flight SQL client and then runs a query on the same session. The existing tests call getStreamTableTypes() directly or go through JDBC, so this sequence was not covered.

Local results: FlightSqlTableTypesTest, FlightSqlSchemaHelperTableTypesTest, FlightSqlSchemaHelperSerializedSchemaTest, FlightSqlNativeVariantTest, DorisFlightSqlProducerTest and FrontendServiceImplTest pass (67 tests, Checkstyle included). All 21 suites under arrow_flight_sql_p0, including test_table_types_over_arrow_flight and test_get_tables_schema, pass on a local cluster built from this branch.

@morningman

Copy link
Copy Markdown
Contributor

run buildall

@morningman

Copy link
Copy Markdown
Contributor

/review

@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.

Static review of PR 67899 at head 2a31c4d completed in one round and converged. The change implements Arrow Flight SQL GetTableTypes with the authenticated session/command lifecycle already used by the other metadata streams, publishes the three non-null Doris table type values in deterministic order, and applies multi-type GetTables filters after the existing authorization checks. Required-column projection still supplies the mandatory table name/type fields and avoids unrelated status lookups; filtered includeSchema requests describe only the authorized matching tables.

The main checkpoints were all verified: the requested metadata behavior is implemented and covered by the added helper, producer, and SQL regression tests; the diff is focused with no configuration, persistence, thrift/protobuf, or FE-BE protocol changes; session locking, listener error conversion, and Arrow root ownership follow existing paths; no new static-initialization, concurrency, or transaction/data-write risk was found; and the enum-derived advertised types match the values emitted by GetTables across internal and external catalog paths. No additional user focus was provided. The existing inline request for a SQL regression test is already addressed by the new regression suite and is not reposted.

This invocation performed static review only; no builds or tests were run here. No new P0/P1/P2/P3 finding is substantiated, so no inline comments are submitted.

Review converged after 1 round(s).

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17579	5151	5030	5030
q2	2120	300	255	255
q3	10266	1377	828	828
q4	4680	467	337	337
q5	7444	798	532	532
q6	188	185	153	153
q7	757	790	594	594
q8	9248	1334	1109	1109
q9	5458	4205	4181	4181
q10	6816	1275	1016	1016
q11	443	246	235	235
q12	636	394	287	287
q13	18085	3647	2984	2984
q14	278	269	253	253
q15	q16	701	709	665	665
q17	1194	738	597	597
q18	6957	6137	6097	6097
q19	1097	936	616	616
q20	389	340	230	230
q21	4665	2622	2536	2536
q22	377	336	273	273
Total cold run time: 99378 ms
Total hot run time: 28808 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5896	5849	5864	5849
q2	702	594	558	558
q3	5590	5759	5243	5243
q4	2246	2167	1590	1590
q5	5751	5714	5798	5714
q6	241	182	139	139
q7	2249	1989	1794	1794
q8	2998	2506	2513	2506
q9	7508	7468	7405	7405
q10	3608	3570	3155	3155
q11	588	393	376	376
q12	670	671	511	511
q13	3400	3645	3009	3009
q14	293	286	253	253
q15	q16	658	693	614	614
q17	7756	7025	6873	6873
q18	12997	12265	12816	12265
q19	922	814	835	814
q20	2123	2153	1930	1930
q21	5769	4735	4738	4735
q22	514	457	440	440
Total cold run time: 72479 ms
Total hot run time: 65773 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 150855 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 2a31c4d622b27ce97e0e7cc9a653fc4d69ce4ac2, data reload: false

query5	4328	577	440	440
query6	420	201	193	193
query7	4802	435	232	232
query8	325	173	146	146
query9	8766	3204	3156	3156
query10	477	311	250	250
query11	6035	3866	3572	3572
query12	147	93	88	88
query13	1257	437	312	312
query14	6114	3868	3593	3593
query14_1	3418	3343	3343	3343
query15	203	190	177	177
query16	942	419	386	386
query17	828	641	499	499
query18	2410	413	295	295
query19	206	162	132	132
query20	83	83	81	81
query21	202	128	102	102
query22	13050	12999	12750	12750
query23	13388	12833	12376	12376
query23_1	12543	12511	12564	12511
query24	7364	808	486	486
query24_1	474	473	485	473
query25	536	423	361	361
query26	1278	258	142	142
query27	2757	435	271	271
query28	4606	2024	1988	1988
query29	1581	599	447	447
query30	305	215	185	185
query31	1023	927	820	820
query32	147	96	95	95
query33	525	307	243	243
query34	880	849	500	500
query35	740	775	686	686
query36	820	873	741	741
query37	126	96	83	83
query38	1806	1709	1638	1638
query39	793	795	750	750
query39_1	746	728	746	728
query40	214	118	98	98
query41	70	69	68	68
query42	87	84	83	83
query43	339	367	313	313
query44	1308	699	704	699
query45	178	177	172	172
query46	825	961	582	582
query47	2728	2868	2877	2868
query48	303	328	226	226
query49	587	405	298	298
query50	670	276	214	214
query51	10426	10328	10536	10328
query52	80	79	78	78
query53	185	210	154	154
query54	243	203	202	202
query55	71	69	68	68
query56	260	223	212	212
query57	1651	1608	1591	1591
query58	294	275	264	264
query59	2176	2229	2034	2034
query60	300	236	239	236
query61	160	166	179	166
query62	393	335	287	287
query63	193	164	175	164
query64	2882	898	721	721
query65	3313	3258	3228	3228
query66	1789	419	300	300
query67	20261	20174	19985	19985
query68	2977	1011	621	621
query69	373	284	238	238
query70	840	773	759	759
query71	297	234	208	208
query72	2693	2584	2299	2299
query73	532	530	297	297
query74	4619	4487	4324	4324
query75	2333	2257	1935	1935
query76	2330	1009	580	580
query77	346	421	273	273
query78	9672	9777	9209	9209
query79	1011	844	536	536
query80	1101	439	325	325
query81	600	325	274	274
query82	581	132	115	115
query83	292	195	179	179
query84	327	125	100	100
query85	1100	451	362	362
query86	353	236	233	233
query87	1972	1922	1800	1800
query88	3731	2757	2730	2730
query89	330	280	236	236
query90	1770	172	162	162
query91	157	149	124	124
query92	98	79	78	78
query93	1038	988	571	571
query94	513	280	271	271
query95	574	326	352	326
query96	684	483	235	235
query97	2428	2413	2359	2359
query98	162	152	148	148
query99	769	774	645	645
Total cold run time: 234876 ms
Total hot run time: 150855 ms

@hello-stephen

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

query1	0.00	0.00	0.01
query2	0.09	0.05	0.05
query3	0.27	0.09	0.09
query4	1.60	0.09	0.09
query5	0.23	0.24	0.24
query6	1.16	0.69	0.67
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.41	0.35	0.36
query10	0.57	0.55	0.59
query11	0.20	0.14	0.14
query12	0.17	0.15	0.14
query13	0.48	0.48	0.48
query14	1.04	1.01	1.00
query15	0.63	0.59	0.61
query16	0.33	0.30	0.34
query17	1.09	1.17	1.12
query18	0.20	0.19	0.19
query19	2.11	1.99	1.93
query20	0.02	0.02	0.01
query21	15.48	0.19	0.14
query22	4.78	0.05	0.05
query23	16.27	0.34	0.12
query24	2.88	0.74	0.35
query25	0.09	0.06	0.04
query26	1.31	0.21	0.15
query27	0.05	0.05	0.05
query28	3.55	0.79	0.36
query29	12.48	4.19	3.37
query30	0.27	0.14	0.10
query31	2.76	0.56	0.33
query32	3.22	0.61	0.50
query33	3.15	3.18	3.22
query34	15.56	3.99	3.36
query35	3.36	3.31	3.36
query36	0.55	0.45	0.44
query37	0.09	0.07	0.06
query38	0.05	0.04	0.03
query39	0.04	0.03	0.03
query40	0.18	0.15	0.14
query41	0.09	0.03	0.03
query42	0.03	0.03	0.03
query43	0.04	0.03	0.04
Total cold run time: 96.98 s
Total hot run time: 24.19 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (28/28) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 100.00% (28/28) 🎉
Increment coverage report
Complete coverage report

…etTables

### What problem does this PR solve?

Issue Number: None

Related PR: apache#67899

Problem Summary: GetTables now filters the authorized tables by every requested
table type with an exact match against Doris's names (BASE TABLE, VIEW, SYSTEM
VIEW). Clients do not send those names. Flight SQL leaves the names to the
server but calls TABLE, VIEW and SYSTEM TABLE the commonly supported ones, and
that is what clients ask for: the ADBC Flight SQL driver sends "table" (Doris's
own ADBC catalog lists tables with getObjects(..., {"table"})), JDBC tools send
"TABLE". Before the exact filter, Doris only recognised VIEW and answered every
other type with all objects, so these requests worked; with it they match
nothing.

Reproduction: an ADBC catalog whose source is a Doris Arrow Flight SQL endpoint
lists no tables, so SHOW TABLES is empty and every query fails with "Unknown
table" (all 18 external_table_p0/adbc suites fail in the External pipeline);
JDBC getTables(..., {"TABLE"}) returns no rows and {"TABLE", "VIEW"} returns
only views.

Fix: map each requested type before matching. The comparison ignores case,
TABLE selects BASE TABLE and SYSTEM TABLE selects SYSTEM VIEW; any other name
still matches only a type of that name, so UNKNOWN still selects nothing.

### Release note

None

### Check List (For Author)

- Test: Unit Test / Regression test
    - FlightSqlSchemaHelperTableTypesTest: table, TABLE + VIEW, view,
      SYSTEM TABLE and mixed-case names, with and without schemas
    - test_table_types_over_arrow_flight: TABLE, table, table + view through
      Flight SQL JDBC
    - external_table_p0/adbc suites against a local cluster
- Behavior changed: No (restores the listing these clients got before the
  multi-type filter)
- Does this need documentation: No

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@morningman

Copy link
Copy Markdown
Contributor

@hutiefang76 The External pipeline on 2a31c4d failed all 18 external_table_p0/adbc suites with Unknown table ... (SHOW TABLES on an ADBC catalog came back empty), and the cause is the new multi-type filter in GetTables, so I added 1258c51 on top.

  • Doris's own ADBC catalog lists a Flight SQL source with getObjects(..., tableTypes = {"table"}) (AdbcConnectorMetadata), and the ADBC Flight SQL driver forwards that as CommandGetTables.table_types = ["table"]. Before this PR the endpoint only recognised VIEW and answered any other type with every object; the connector then keeps the rows whose table_type is TABLE or BASE TABLE. With the exact filter, "table" matches none of BASE TABLE / VIEW / SYSTEM VIEW, so the catalog lists no tables. Reproduced on a local cluster: test_adbc_catalog_scan passes with master's FE and fails at show_tables (empty result) with this branch.
  • JDBC tools hit the same thing. Flight SQL leaves the names to the server but says "TABLE, VIEW, and SYSTEM TABLE are commonly supported", and tools often call getTables(..., {"TABLE"}) or {"TABLE", "VIEW"}; on this branch the first returned nothing and the second only views.
  • 1258c51 maps each requested type before matching: the comparison ignores case, TABLE selects BASE TABLE, SYSTEM TABLE selects SYSTEM VIEW, and any other name still matches only a type of that name, so UNKNOWN still selects nothing. FlightSqlSchemaHelperTableTypesTest gets five more filter cases (table, TABLE + VIEW, view, SYSTEM TABLE, mixed case), and test_table_types_over_arrow_flight three more getTables calls.

Local results on 1258c51: FlightSqlSchemaHelperTableTypesTest (27) and FlightSqlTableTypesTest (3) pass with Checkstyle; making the mapping return the requested name unchanged turns exactly the 10 new cases red. On a local cluster with this FE, all 21 external_table_p0/adbc suites pass (test_adbc_multi_backend skips itself on one backend), and so do all 21 suites under arrow_flight_sql_p0, including test_table_types_over_arrow_flight.

@morningman

Copy link
Copy Markdown
Contributor

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17583	5191	5053	5053
q2	2167	305	252	252
q3	10239	1461	823	823
q4	4675	467	340	340
q5	7433	794	520	520
q6	181	184	155	155
q7	756	792	606	606
q8	9259	1351	1075	1075
q9	5678	4238	4333	4238
q10	6817	1283	1040	1040
q11	441	246	230	230
q12	636	399	282	282
q13	18102	3719	3058	3058
q14	271	275	242	242
q15	q16	734	720	674	674
q17	1210	780	598	598
q18	6962	6196	6122	6122
q19	1110	954	607	607
q20	382	336	227	227
q21	5230	2127	2315	2127
q22	350	297	254	254
Total cold run time: 100216 ms
Total hot run time: 28523 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5631	5622	5610	5610
q2	679	582	532	532
q3	5252	5385	4888	4888
q4	2006	2148	1574	1574
q5	5262	5154	5738	5154
q6	249	197	147	147
q7	2284	2137	1885	1885
q8	3203	2888	2778	2778
q9	8050	7909	8010	7909
q10	3732	3670	3230	3230
q11	623	423	410	410
q12	690	680	526	526
q13	3602	3901	3248	3248
q14	311	327	299	299
q15	q16	704	706	637	637
q17	8347	7536	7114	7114
q18	12950	12186	12905	12186
q19	924	805	826	805
q20	2173	2136	1915	1915
q21	5600	4581	4674	4581
q22	493	463	411	411
Total cold run time: 72765 ms
Total hot run time: 65839 ms

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (38/38) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 151889 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 1258c51dfe7e56750e864289f965f5e3c209a9a0, data reload: false

query5	4310	597	444	444
query6	436	215	200	200
query7	4807	452	245	245
query8	326	164	146	146
query9	8789	3234	3268	3234
query10	478	312	259	259
query11	6030	3855	3554	3554
query12	145	89	87	87
query13	1264	460	335	335
query14	6124	3928	3626	3626
query14_1	3412	3428	3440	3428
query15	205	196	178	178
query16	944	433	401	401
query17	878	672	534	534
query18	2418	432	317	317
query19	196	177	139	139
query20	84	86	85	85
query21	214	127	109	109
query22	12936	12951	12777	12777
query23	13520	12855	12439	12439
query23_1	12584	12526	12616	12526
query24	7349	828	484	484
query24_1	485	496	509	496
query25	540	417	369	369
query26	1280	259	146	146
query27	2770	451	275	275
query28	4594	2081	2072	2072
query29	1593	605	453	453
query30	302	228	185	185
query31	1010	966	826	826
query32	145	97	96	96
query33	543	305	241	241
query34	882	860	516	516
query35	767	755	653	653
query36	828	802	760	760
query37	122	103	88	88
query38	1783	1764	1684	1684
query39	790	814	745	745
query39_1	732	739	735	735
query40	222	124	102	102
query41	75	74	71	71
query42	92	85	90	85
query43	344	365	315	315
query44	1342	713	723	713
query45	180	182	207	182
query46	833	968	568	568
query47	2856	2906	2865	2865
query48	301	307	221	221
query49	565	403	293	293
query50	685	279	214	214
query51	10566	10472	10508	10472
query52	79	79	71	71
query53	184	201	149	149
query54	231	204	205	204
query55	75	69	62	62
query56	252	218	215	215
query57	1648	1617	1578	1578
query58	286	262	258	258
query59	2164	2171	1964	1964
query60	299	252	228	228
query61	151	149	148	148
query62	391	326	291	291
query63	186	154	158	154
query64	2720	971	752	752
query65	3337	3290	3277	3277
query66	1794	416	309	309
query67	20037	20197	20138	20138
query68	3176	1024	637	637
query69	379	285	260	260
query70	853	797	774	774
query71	314	244	215	215
query72	2712	2587	2306	2306
query73	535	531	304	304
query74	4611	4491	4328	4328
query75	2332	2288	1897	1897
query76	2327	1027	597	597
query77	350	371	271	271
query78	9682	9754	9236	9236
query79	973	910	548	548
query80	755	434	333	333
query81	547	321	265	265
query82	573	132	105	105
query83	279	197	189	189
query84	311	120	104	104
query85	965	419	365	365
query86	345	229	230	229
query87	1985	1965	1783	1783
query88	3876	2846	2836	2836
query89	322	285	240	240
query90	1709	167	161	161
query91	160	157	126	126
query92	100	90	92	90
query93	1040	1014	587	587
query94	496	309	259	259
query95	579	386	300	300
query96	721	483	247	247
query97	2467	2442	2331	2331
query98	168	154	154	154
query99	766	773	660	660
Total cold run time: 234733 ms
Total hot run time: 151889 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.09	0.05	0.05
query3	0.26	0.09	0.09
query4	1.61	0.10	0.10
query5	0.24	0.25	0.25
query6	1.18	0.68	0.67
query7	0.04	0.01	0.01
query8	0.06	0.04	0.03
query9	0.40	0.35	0.36
query10	0.55	0.56	0.61
query11	0.20	0.16	0.15
query12	0.18	0.14	0.14
query13	0.50	0.51	0.49
query14	1.04	1.01	1.00
query15	0.62	0.59	0.60
query16	0.35	0.34	0.34
query17	1.13	1.16	1.14
query18	0.21	0.20	0.19
query19	2.14	1.99	1.98
query20	0.02	0.02	0.01
query21	15.48	0.20	0.14
query22	4.75	0.05	0.05
query23	16.27	0.31	0.12
query24	3.18	0.68	0.31
query25	0.11	0.06	0.05
query26	1.11	0.22	0.14
query27	0.05	0.04	0.03
query28	2.52	0.74	0.36
query29	12.56	4.15	3.25
query30	0.27	0.13	0.10
query31	2.78	0.55	0.34
query32	3.23	0.59	0.49
query33	3.22	3.33	3.17
query34	15.31	4.00	3.38
query35	3.35	3.33	3.35
query36	0.55	0.50	0.42
query37	0.08	0.06	0.07
query38	0.05	0.04	0.04
query39	0.03	0.03	0.03
query40	0.17	0.15	0.14
query41	0.09	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.03	0.04
Total cold run time: 96.07 s
Total hot run time: 24.19 s

@morningman

Copy link
Copy Markdown
Contributor

/review

@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.

Static review of PR 67899 at head 1258c51 found the GetTableTypes implementation consistent with Doris's advertised BASE TABLE, SYSTEM VIEW, and VIEW mappings. GetTables now requests only name/type status fields, applies case-insensitive aliases and multi-type filtering after catalog, database, and table SHOW authorization, and describes only the authorized matches. The producer reuses the existing session command lock, Flight schema/ticket path, listener error handling, and root allocator cleanup. No separate correctness, authorization, concurrency, lifecycle, protocol, configuration, persistence, data-write, or observability defect was verified.

The existing review thread 3999564249 requested a SQL regression test; the added regression suite addresses that request, so no duplicate blocking comment is carried. The user supplied no additional focus. The new FE and regression tests were inspected but not executed because this contract is static-only.

Verified finding: the raw Flight client in the new regression test authenticates a persistent server-side session but closes only the transport and allocator. Without FlightSqlClient.closeSession, the connection-pool slot and session channel remain until wait_timeout, which can exhaust Flight/user connection quotas or interfere with later suites. Close the session with the bearer token in a finally block before closing the transport. Review convergence was reached in round 2.

Review converged after 2 round(s).

Integer.parseInt(config.get("extArrowFlightSqlPort")))
new RootAllocator().withCloseable { allocator ->
FlightClient.builder(allocator, location).build().withCloseable { flight ->
def token = flight.authenticateBasicToken(config.get("extArrowFlightSqlUser"),

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.

[P2] Close the raw Flight SQL session before closing the client. authenticateBasicToken opens a Doris session in the shared connection pool, and closing the transport/allocator does not call FlightSqlProducer.closeSession; the session remains registered until CloseSession, KILL CONNECTION, or wait_timeout. This suite therefore leaks one connection slot per run and can exhaust the Flight/user quota or interfere with later suites. Keep the token and call client.closeSession(new CloseSessionRequest(), token) in a finally block before closing flight.

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.

Fixed in 221a0af. The suite now ends the plain Flight SQL session in a finally block with flight.closeSession(new CloseSessionRequest(), token) before the client and the allocator close, as the other arrow_flight_sql_p0 suites with a plain Flight client do. On a local cluster, the ArrowFlightSQL sessions in SHOW PROCESSLIST grew by two per run of the suite before this change (the framework's Flight SQL JDBC connection and the leaked one) and grow by one after it; the suite passes in both cases.

@morningman
morningman requested a review from yiguolei October 31, 2026 04:00
…types suite

### What problem does this PR solve?

Issue Number: None

Related PR: apache#67899

Problem Summary: test_table_types_over_arrow_flight calls GetTableTypes
through a plain Flight SQL client. authenticateBasicToken opens a Doris
session in the Flight connection pool, and the suite then closed only the
client and the allocator. Closing the transport does not call CloseSession,
so each run left one session of the test user registered until wait_timeout.
The other arrow_flight_sql_p0 suites that use a plain Flight client close
their sessions.

Fix: end the session in a finally block with
closeSession(new CloseSessionRequest(), token), the way the drivers do,
before the client and the allocator close.

On a local cluster, the ArrowFlightSQL sessions in SHOW PROCESSLIST grow by
two per run of the suite before this change (the framework's Flight SQL JDBC
connection and the leaked one) and by one after it.

### Release note

None

### Check List (For Author)

- Test: Regression test
    - test_table_types_over_arrow_flight passes on a local cluster with this
      PR's FE, before and after the change; SHOW PROCESSLIST as above
- Behavior changed: No
- Does this need documentation: No

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@morningman

Copy link
Copy Markdown
Contributor

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17622	5170	5041	5041
q2	2147	296	240	240
q3	10256	1477	823	823
q4	4679	463	334	334
q5	7444	791	533	533
q6	176	184	157	157
q7	748	798	595	595
q8	9252	1322	1049	1049
q9	5485	4188	4182	4182
q10	6799	1286	1031	1031
q11	436	250	245	245
q12	658	401	293	293
q13	18071	3610	2979	2979
q14	275	272	246	246
q15	q16	712	698	666	666
q17	1195	754	580	580
q18	6963	6175	6082	6082
q19	1103	960	613	613
q20	408	343	226	226
q21	5282	2183	2310	2183
q22	343	302	248	248
Total cold run time: 100054 ms
Total hot run time: 28346 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5545	5567	5600	5567
q2	675	557	540	540
q3	5194	5404	4928	4928
q4	1985	2149	1585	1585
q5	5286	5151	5475	5151
q6	250	203	154	154
q7	2365	1998	1887	1887
q8	3013	2688	2651	2651
q9	8036	7885	7914	7885
q10	3765	3927	3277	3277
q11	623	443	421	421
q12	726	730	539	539
q13	3437	3903	3373	3373
q14	309	332	309	309
q15	q16	708	711	654	654
q17	8392	7052	6962	6962
q18	13014	12110	12879	12110
q19	916	810	807	807
q20	2147	2132	1903	1903
q21	5741	4655	4693	4655
q22	493	456	420	420
Total cold run time: 72620 ms
Total hot run time: 65778 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 151417 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 221a0af5da1921c00a5d419ebfef04c518e4d8ee, data reload: false

query5	4329	591	445	445
query6	435	207	186	186
query7	4819	445	237	237
query8	330	169	153	153
query9	8793	3164	3176	3164
query10	492	309	265	265
query11	6080	3877	3561	3561
query12	157	95	87	87
query13	1254	422	322	322
query14	6144	3935	3663	3663
query14_1	3468	3387	3416	3387
query15	211	203	183	183
query16	958	440	402	402
query17	850	670	538	538
query18	2421	432	319	319
query19	201	172	150	150
query20	87	86	83	83
query21	214	133	109	109
query22	12977	13009	12898	12898
query23	13478	12779	12515	12515
query23_1	12639	12591	12534	12534
query24	7382	849	489	489
query24_1	497	479	485	479
query25	540	424	367	367
query26	1258	263	147	147
query27	2753	439	272	272
query28	4637	2017	2008	2008
query29	1549	608	464	464
query30	306	221	185	185
query31	1028	929	811	811
query32	143	96	90	90
query33	544	301	246	246
query34	922	867	507	507
query35	748	763	638	638
query36	814	796	707	707
query37	127	103	85	85
query38	1769	1732	1665	1665
query39	791	801	748	748
query39_1	739	722	735	722
query40	218	116	99	99
query41	87	73	69	69
query42	89	86	86	86
query43	346	368	311	311
query44	1331	701	722	701
query45	180	184	171	171
query46	859	988	575	575
query47	2946	2841	2814	2814
query48	296	331	230	230
query49	580	397	312	312
query50	686	285	214	214
query51	10664	10580	10400	10400
query52	79	82	69	69
query53	192	211	157	157
query54	232	199	181	181
query55	68	67	70	67
query56	234	222	216	216
query57	1643	1643	1559	1559
query58	284	271	256	256
query59	2139	2126	1994	1994
query60	282	247	231	231
query61	147	139	154	139
query62	387	334	282	282
query63	191	155	158	155
query64	2756	969	785	785
query65	3331	3281	3273	3273
query66	1772	433	303	303
query67	20117	20112	19931	19931
query68	3091	1019	628	628
query69	378	312	250	250
query70	869	779	773	773
query71	297	236	212	212
query72	2680	2590	2292	2292
query73	510	525	297	297
query74	4635	4523	4352	4352
query75	2338	2285	1911	1911
query76	2326	1021	606	606
query77	340	384	280	280
query78	9876	9705	9193	9193
query79	1014	874	526	526
query80	1220	421	356	356
query81	590	324	265	265
query82	594	136	104	104
query83	309	215	177	177
query84	312	120	100	100
query85	862	424	366	366
query86	397	241	221	221
query87	1986	1936	1792	1792
query88	3857	2783	2753	2753
query89	333	279	237	237
query90	1869	169	170	169
query91	170	156	128	128
query92	99	81	92	81
query93	1072	1020	573	573
query94	629	299	278	278
query95	581	382	310	310
query96	689	489	244	244
query97	2448	2416	2311	2311
query98	169	159	145	145
query99	772	762	650	650
Total cold run time: 236200 ms
Total hot run time: 151417 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 221a0af5da1921c00a5d419ebfef04c518e4d8ee, data reload: false

query1	0.01	0.00	0.01
query2	0.10	0.05	0.04
query3	0.26	0.09	0.08
query4	1.61	0.09	0.11
query5	0.23	0.24	0.24
query6	1.17	0.70	0.68
query7	0.04	0.01	0.00
query8	0.05	0.03	0.04
query9	0.41	0.34	0.36
query10	0.57	0.60	0.58
query11	0.21	0.14	0.13
query12	0.20	0.15	0.14
query13	0.49	0.49	0.49
query14	1.03	1.02	1.00
query15	0.62	0.60	0.60
query16	0.35	0.35	0.34
query17	1.07	1.13	1.14
query18	0.21	0.20	0.19
query19	2.07	1.97	1.98
query20	0.02	0.01	0.01
query21	15.48	0.19	0.14
query22	4.89	0.05	0.05
query23	16.28	0.32	0.13
query24	3.10	0.55	0.34
query25	0.10	0.07	0.05
query26	0.84	0.22	0.16
query27	0.04	0.04	0.05
query28	3.42	0.77	0.37
query29	12.49	4.16	3.27
query30	0.28	0.13	0.11
query31	2.77	0.55	0.33
query32	3.22	0.60	0.50
query33	3.19	3.20	3.14
query34	15.30	4.00	3.37
query35	3.36	3.35	3.34
query36	0.55	0.43	0.43
query37	0.09	0.06	0.07
query38	0.06	0.04	0.03
query39	0.04	0.02	0.02
query40	0.16	0.14	0.13
query41	0.09	0.03	0.03
query42	0.04	0.03	0.02
query43	0.05	0.03	0.03
Total cold run time: 96.56 s
Total hot run time: 24.17 s

@morningman

Copy link
Copy Markdown
Contributor

@hutiefang76 I pushed 221a0af on top of your branch for the round-2 review finding: test_table_types_over_arrow_flight now closes the plain Flight SQL session it opens (thread r4429901003). Only the test changes.

@morningman

Copy link
Copy Markdown
Contributor

/review

@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 all five changed files at 221a0af5da1921c00a5d419ebfef04c518e4d8ee, with upstream/downstream tracing and two review rounds. One new P2 finding is reported inline: removing the service's VIEW filter exposes VIEW-only discovery on cloud followers to unrelated OLAP version RPC failures, allowing a successful but incomplete result. This should be corrected.

No additional user focus was supplied. The existing request for a SQL/Flight regression is addressed by the added suite. Existing session-leak comment 4429901003 is fixed by the token-preserving CloseSession call in finally; it is not reposted. No existing P0/P1 finding remains to carry forward.

Critical checkpoint Conclusion
Goal and evidence The type stream and complete type-set filtering are implemented; the cloud-follower failure case remains incorrect as reported inline. New helper, producer/RPC and JDBC/plain-client tests were inspected.
Scope and reuse Focused production changes reuse TableType.toMysqlType and streamMetadata, with three accompanying test files.
Concurrency and locks Existing bounded session-command locking, thread-context restoration and metadata-lock patterns are retained. New roots and filter state are per request; static type data is safely published.
Lifecycle and memory Request Arrow roots close on success and exceptions; producer/session allocators have separate ownership. Result sets, streams and the raw regression session have cleanup.
Configuration None added.
Compatibility Existing schemas and ticket encoding are retained. The new type stream has the required schema and sorted output described by the Arrow 19 Flight SQL specification. No storage-format change.
Thrift/protobuf IDs No definition changes.
Parallel paths Checked both schema modes, internal/system/external type representations, aliases/case variants and empty/single/multiple/unknown/duplicate filters. The cloud-follower path is the reported exception.
Conditional checks Null filter, set membership and empty-result branches have concrete command semantics; no additional incorrect branch found.
Test coverage Tests cover metadata values, filters, schema alignment, repeated RPCs, failed sends and later query use. They lack a controlled real-service cloud-follower version-failure case, requested inline.
Test results Assertions and decoded schemas inspected; no .out files changed. No test-success claim for this invocation.
Observability and errors Stream errors use existing logging/status conversion. The existing service catch newly allows silent result truncation through this change, as reported inline; no additional telemetry need identified.
Transactions and persistence No production transaction/EditLog/replay modifications.
Writes and atomicity Production metadata paths remain read-only; no new write/crash-recovery protocol.
FE/BE variables None added.
Performance Set matching and schema collection are linear in the retained metadata. Projection removes unused stats/comments, but excluded cloud OLAP tables can still cause unnecessary version work; covered by the same finding. No benchmark run.
Other/core invariants No rowset, committed-data visibility or delete-bitmap changes; no additional substantiated defect after the final recheck.

All reviewers returned NO_NEW_VALUABLE_FINDINGS in round 2 beyond the accepted finding, and all candidates and initial risks have dispositions. No unresolved static coverage question remains. This was a static-only review: no builds, tests, benchmarks, runtime reproductions or native-BE validation were performed. The added tests' current-head execution remains unverified.

Review converged after 2 round(s).

String dbName = getDbsResult.getDbs().get(dbIndex);
String catalogName = getDbsResult.isSetCatalogs() ? getDbsResult.getCatalogs().get(dbIndex) : "";
TListTableStatusResult listTableStatusResult = listTableStatus(dbName, catalogName);
List<TTableStatus> tables = listTableStatus(dbName, catalogName).getTables();

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.

[P2] Keep VIEW-only listings independent of OLAP version RPCs

After removing setType("VIEW"), a GetTables request filtered to VIEW also enumerates matching OLAP tables. On a cloud follower, FrontendServiceImpl.listTableStatus calls CloudPartition.getSnapshotVisibleVersion even for this name/type-only projection. With an expired cache, an MS RPC failure is caught around the entire enumeration and returns only the accumulated prefix. If that base table precedes a view, the view is silently missing although it needs no partition version; the previous VIEW-only path never visited the base table. Skip the version refresh for this projection, or apply the canonical type predicate before that work, and cover this cloud-follower failure case using the real service.

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.

Fixed in 747a1d4. On a non-master FE in cloud mode, listTableStatus now refreshes an OLAP table's partition versions only when the request needs UPDATE_TIME, the one status column that reads them (OlapTable.getUpdateTime() takes the partitions' visible version time). GetTables asks for TABLE_NAME and TABLE_TYPE only, so no GetTables request, VIEW-only or not, waits on the meta service or is cut short by it. information_schema.tables scans that read UPDATE_TIME (projected or in a predicate) and requests without required_columns still refresh as before (#43451); information_schema.views asks for views only and never reaches the refresh. FrontendServiceImplTest#testListTableStatusRefreshesCloudFollowerVersionsOnlyForUpdateTime runs the service as a cloud follower whose version RPC fails: with the name/type projection it returns both the base table and the view without calling it, and with UPDATE_TIME it still calls it. Without the change the first listing calls it and comes back empty, since the base table's failed refresh ends the enumeration before either object is added. FlightSqlSchemaHelperTableTypesTest now also checks that GetTables sends exactly TABLE_NAME and TABLE_TYPE.

…r UPDATE_TIME

### What problem does this PR solve?

Issue Number: None

Related PR: apache#67899

Problem Summary: GetTables no longer passes its first requested type to
FrontendServiceImpl.listTableStatus, so a request for VIEW only now lists
every object in the database and the Flight SQL helper filters the rows.
On a non-master FE in cloud mode, listTableStatus refreshes each OLAP
table's partition versions from the meta service before it lists the
table (apache#43451), whatever columns the caller asked for. GetTables asks for
TABLE_NAME and TABLE_TYPE only, and neither reads a partition version;
only UPDATE_TIME does (OlapTable.getUpdateTime() takes the partitions'
visible version time).

So when the cached versions on the follower have expired, every GetTables
request waits on meta service RPCs for each OLAP table it lists. When the
meta service keeps failing, the RpcException leaves the per-table loop for
the catch around the whole enumeration, which logs a warning and returns
the rows collected so far: the request succeeds without that table and
every object after it, views included.

Fix: refresh the partition versions only when the request needs
UPDATE_TIME. A request without required_columns (an older BE) still needs
every column and still refreshes, and so does an information_schema.tables
scan that reads UPDATE_TIME in its projection or in a predicate.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - FrontendServiceImplTest#testListTableStatusRefreshesCloudFollowerVersionsOnlyForUpdateTime:
      a cloud follower whose version RPC fails lists a base table and a
      view for TABLE_NAME and TABLE_TYPE without calling it, and still
      calls it for UPDATE_TIME; without the new condition the first
      listing calls it and loses rows
    - FlightSqlSchemaHelperTableTypesTest: GetTables requests exactly
      TABLE_NAME and TABLE_TYPE
- Behavior changed: Yes. On a non-master FE in cloud mode, listing table
  status fetches partition versions from the meta service only when
  UPDATE_TIME is requested
- Does this need documentation: No

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@morningman

Copy link
Copy Markdown
Contributor

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17625	5213	5068	5068
q2	2094	325	276	276
q3	10207	1390	840	840
q4	4677	456	333	333
q5	7432	782	526	526
q6	179	186	157	157
q7	766	805	597	597
q8	9268	1280	1087	1087
q9	5870	4229	4188	4188
q10	6840	1278	1053	1053
q11	419	254	236	236
q12	638	407	294	294
q13	18073	3563	3024	3024
q14	276	273	245	245
q15	q16	713	708	649	649
q17	1198	751	584	584
q18	6975	6168	6105	6105
q19	1117	944	623	623
q20	384	341	247	247
q21	4912	2134	2293	2134
q22	343	291	253	253
Total cold run time: 100006 ms
Total hot run time: 28519 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5602	5603	5605	5603
q2	679	557	532	532
q3	5204	5404	4942	4942
q4	2000	2168	1562	1562
q5	5233	5157	5682	5157
q6	277	201	160	160
q7	2276	2087	1874	1874
q8	3075	2721	2645	2645
q9	8045	7912	7973	7912
q10	3722	3776	3231	3231
q11	645	455	398	398
q12	724	735	530	530
q13	3470	3845	3344	3344
q14	316	318	295	295
q15	q16	729	728	660	660
q17	8396	7136	6905	6905
q18	12967	12188	12852	12188
q19	941	819	824	819
q20	2147	2133	1927	1927
q21	5544	4543	4681	4543
q22	519	427	414	414
Total cold run time: 72511 ms
Total hot run time: 65641 ms

@morningman

Copy link
Copy Markdown
Contributor

@hutiefang76 I pushed 747a1d4 on top of your branch for the round-3 review finding (thread r4430787448). GetTables no longer passes its first requested type to listTableStatus, so a VIEW-only request now lists every object, and on a non-master FE in cloud mode the service refreshed each OLAP table's partition versions from the meta service before listing it, whatever columns were requested. When that RPC failed, the listing stopped at that table and the request still succeeded, without that table and everything after it. The refresh now runs only when UPDATE_TIME is requested, the one column that reads those versions, so GetTables (names and types) no longer depends on it, and information_schema.tables scans that read UPDATE_TIME refresh as before. This brings service/FrontendServiceImpl.java and FrontendServiceImplTest into the PR.

Local results on 747a1d4: FrontendServiceImplTest (30), FlightSqlSchemaHelperTableTypesTest (27), DorisFlightSqlProducerTest (12), FlightSqlTableTypesTest (3), FlightSqlSchemaHelperSerializedSchemaTest (3) and FlightSqlNativeVariantTest (3) pass, and FE Checkstyle reports 0 violations. With the new condition removed, only the new test fails: the name/type listing comes back empty.

@morningman

Copy link
Copy Markdown
Contributor

/review

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 150978 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 747a1d466603a080cc28034511f5b2ff7661781d, data reload: false

query5	4321	574	472	472
query6	431	209	191	191
query7	4807	448	222	222
query8	314	184	146	146
query9	8769	3178	3183	3178
query10	474	311	261	261
query11	6014	3859	3587	3587
query12	146	91	88	88
query13	1250	454	330	330
query14	6190	3890	3602	3602
query14_1	3399	3415	3411	3411
query15	203	198	179	179
query16	947	440	393	393
query17	832	647	497	497
query18	2413	415	299	299
query19	195	157	128	128
query20	88	82	86	82
query21	210	126	102	102
query22	12861	12977	12816	12816
query23	13309	12728	12559	12559
query23_1	12492	12596	12445	12445
query24	7386	834	470	470
query24_1	471	474	466	466
query25	524	424	363	363
query26	1261	271	139	139
query27	2735	439	270	270
query28	4653	2056	2027	2027
query29	1558	605	463	463
query30	305	236	187	187
query31	1026	932	822	822
query32	139	99	94	94
query33	531	308	249	249
query34	885	867	527	527
query35	731	771	638	638
query36	838	829	709	709
query37	129	102	86	86
query38	1754	1758	1666	1666
query39	783	792	749	749
query39_1	745	735	750	735
query40	225	117	100	100
query41	71	68	69	68
query42	99	86	85	85
query43	353	375	314	314
query44	1340	697	707	697
query45	186	178	170	170
query46	830	953	569	569
query47	3004	2692	2887	2692
query48	308	329	242	242
query49	584	402	293	293
query50	697	280	213	213
query51	10703	10475	10706	10475
query52	82	82	78	78
query53	189	210	155	155
query54	248	221	204	204
query55	73	65	67	65
query56	240	219	212	212
query57	1664	1582	1564	1564
query58	302	272	272	272
query59	2169	2222	1987	1987
query60	316	257	243	243
query61	170	166	170	166
query62	395	347	297	297
query63	192	164	170	164
query64	2819	943	730	730
query65	3308	3272	3258	3258
query66	1776	418	303	303
query67	20179	20056	19980	19980
query68	3073	1017	607	607
query69	378	292	244	244
query70	841	779	763	763
query71	301	231	215	215
query72	2697	2609	2200	2200
query73	513	526	298	298
query74	4660	4523	4330	4330
query75	2312	2296	1906	1906
query76	2315	1019	601	601
query77	393	368	275	275
query78	9709	9761	9155	9155
query79	1017	846	526	526
query80	526	427	343	343
query81	522	321	275	275
query82	580	132	103	103
query83	302	198	180	180
query84	311	129	106	106
query85	850	431	365	365
query86	322	233	228	228
query87	2002	1915	1810	1810
query88	3826	2782	2756	2756
query89	340	281	240	240
query90	1894	172	173	172
query91	165	152	130	130
query92	95	97	99	97
query93	1009	1005	572	572
query94	442	291	260	260
query95	566	387	308	308
query96	716	495	233	233
query97	2446	2421	2301	2301
query98	164	149	151	149
query99	759	766	651	651
Total cold run time: 234497 ms
Total hot run time: 150978 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.09	0.05	0.05
query3	0.27	0.09	0.08
query4	1.61	0.10	0.10
query5	0.25	0.26	0.26
query6	1.17	0.71	0.69
query7	0.03	0.00	0.00
query8	0.06	0.04	0.03
query9	0.42	0.37	0.38
query10	0.62	0.63	0.62
query11	0.19	0.14	0.14
query12	0.18	0.15	0.14
query13	0.51	0.52	0.52
query14	1.05	1.05	1.05
query15	0.66	0.62	0.63
query16	0.38	0.37	0.36
query17	1.16	1.14	1.12
query18	0.22	0.19	0.20
query19	2.13	2.00	1.99
query20	0.02	0.01	0.02
query21	15.48	0.20	0.14
query22	4.76	0.05	0.05
query23	16.29	0.33	0.13
query24	3.07	0.79	0.40
query25	0.11	0.07	0.05
query26	1.34	0.22	0.16
query27	0.05	0.05	0.05
query28	3.00	0.74	0.37
query29	12.49	4.16	3.25
query30	0.27	0.14	0.12
query31	2.78	0.58	0.34
query32	3.22	0.62	0.53
query33	3.15	3.22	3.21
query34	15.38	4.28	3.54
query35	3.45	3.47	3.49
query36	0.57	0.44	0.43
query37	0.10	0.07	0.06
query38	0.05	0.03	0.04
query39	0.04	0.02	0.02
query40	0.18	0.15	0.15
query41	0.08	0.02	0.02
query42	0.04	0.03	0.02
query43	0.04	0.03	0.04
Total cold run time: 96.97 s
Total hot run time: 24.92 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.

Static review of PR #67899 at head 747a1d4 converged in round 1.

The change meets its stated goal: GetTableTypes now streams the canonical sorted Doris types, and GetTables normalizes case and TABLE/SYSTEM TABLE aliases before filtering the authorized listing. I traced the full path through FlightInfo/DoGet, session command serialization, Arrow root ownership, FrontendServiceImpl.listTableStatus, describeTables, TableIf.TableType mappings, external catalog propagation, and includeSchema alignment. SHOW authorization is applied before local filtering and rechecked for schema descriptions.

The cloud follower change is projection-safe: names/types-only requests send TABLE_NAME and TABLE_TYPE, requiredColumns normalization prevents UPDATE_TIME refresh for that projection, and legacy/unset projections plus UPDATE_TIME consumers retain the refresh. Status fields and required Thrift fields remain valid. Error/listener handling and allocator cleanup follow the existing metadata streams, including failed sends.

I independently revalidated existing inline context: the VIEW-only cloud version-RPC issue and the raw Flight session leak are fixed at this head, and the requested SQL regression coverage is present. No P0/P1 or other substantiated new finding remains, so there are no inline comments or existing blocking IDs. The user review focus file contains no additional focus. Added unit and regression tests were inspected for coverage, determinism, and cleanup; this invocation did not execute builds or tests under the static-only review contract.

Review converged after 1 round(s).

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (39/39) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 92.31% (36/39) 🎉
Increment coverage report
Complete coverage report

@morningman

Copy link
Copy Markdown
Contributor

run p0

@morningman
morningman merged commit f109e13 into apache:master Nov 3, 2026
42 of 43 checks passed
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

PR approved by anyone and no changes requested.

@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Nov 3, 2026
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

PR approved by at least one committer and no changes requested.

morningman added a commit that referenced this pull request Nov 4, 2026
…Schema (#69867)

### What problem does this PR solve?

Issue Number: None

Related PR: #68631, #68768

Problem Summary:

**In short.** This ports branch-4.1 #68631 (also on branch-4.2) to
master. A Flight SQL `CreatePreparedStatement` now returns the analyzed
result schema of the statement, `GetSchema` is implemented for both
statements and prepared statements, and a prepared execution is checked
against the schema that Prepare advertised. Before this PR, Prepare
always returned a fixed one-column placeholder, and `GetSchema` answered
UNIMPLEMENTED. The analysis runs in the FE only and does not plan or
execute the query.

Original author: @Gabriel39

**Background.** Flight SQL clients learn the shape of a result before
they fetch it. The Arrow Flight SQL JDBC driver prepares every statement
and builds `ResultSetMetaData` from the dataset schema that
`CreatePreparedStatement` returns. ADBC exposes the same schema as
`execute_schema`, and `GetSchema` is the RPC that asks for it without
running anything.

**The problem, and what it cost.** On master:

| | master today | with this PR |
|---|---|---|
| `CreatePreparedStatement` dataset schema | always `ResultMeta: Utf8`,
whatever the statement | the statement's columns, names and Arrow types
as BE / FE will send them; statements whose schema cannot be told before
they run, and results with an untyped NULL column, keep the placeholder
(see below) |
| `GetSchema` for a statement or a prepared statement | UNIMPLEMENTED |
the analyzed schema, or UNIMPLEMENTED for a statement that keeps the
placeholder |
| Invalid SQL | fails only at execution | fails at Prepare with
INVALID_ARGUMENT |
| A query whose privilege check fails | fails only at execution | still
fails only at execution: Prepare keeps the placeholder, because only the
check on the executed plan decides (see below), and GetSchema answers
UNIMPLEMENTED without a schema |
| Prepared handle used after the session's catalog / database changed,
or after the result schema changed (e.g. another session's DDL) | runs
the unqualified SQL in whatever namespace the session has now, with
whatever columns come back | refused with NOT_FOUND "prepare again", and
the result left by that execution is dropped |
| Prepared handle presented by another session | resolved by the
identity written in the handle | must start with the caller's own
identity (from #68768) |
| TIMEV2 / VARBINARY columns in GetTables and Prepare schemas | `Null`,
while BE sends `float64` / `binary` | `Float64` / `Binary`, as BE sends
them |

A client that trusts the advertised schema saw one string column for
every query, and could not ask for a schema at all without executing.

**How this PR fixes it.**

- `arrowflight/FlightSqlQuerySchema` analyzes the statement on a clone
of the session variables: a USE / SWITCH prefix is resolved in a
temporary namespace, the analysis `StatementContext` is closed on the
same thread, and the connector statement scope it may have opened is
closed explicitly. Each field gets the same `doris_type` markers and
native Variant layout the execution side uses
(`FlightSqlSchemaHelper.withDorisTypeMetadata` / `nativeVariantField`),
and TIMESTAMPTZ carries the canonical session time zone that BE stamps
on its batches.
- Privileges are checked on the analyzed plan after the CTEs that
execution inlines have been inlined (`PullUpCteAnchor`, `CTEInline`, as
the rewriter does before its own check). A CTE used once is therefore
checked only on the columns the query reads, and a CTE used more than
once on every column it selects, which is also how execution checks
them. The rewriter normalizes the plan further before it checks
privileges. For example, it drops an ORDER BY under a derived table, so
the analyzed plan can read a column that the executed plan does not.
When the analyzed plan is denied, the statement keeps the placeholder
and execution decides. No schema is disclosed in either case.
- FE-side commands whose result header does not depend on running them
now report that header without running: HELP, SHOW SNAPSHOT, SHOW CREATE
TABLE (one header selector shared with `doRun`, including master's
stream, plugin-view and system-table cases), SHOW PROC `/` and
`/current_queries`, SHOW CONFIG, and EXPLAIN PLAN PROCESS (Rule / Before
/ After).
- `ShowStoragePolicyCommand.getMetaData()` returned the four-column
USING header for every form, while plain SHOW STORAGE POLICY answers the
seven columns of `StoragePolicy.STORAGE_META_DATA`. It now returns the
header of the form that runs. This also corrects the column definitions
that MySQL `COM_STMT_PREPARE` reports for the statement. No other SHOW
command declares a header that differs from the one it returns.
- WARM UP SELECT keeps the placeholder. It answers OK instead of its
statistics whenever planning proves its source empty: a predicate that
folds to false, no partition left after pruning, or partitions without
data.
- A result with an untyped NULL column keeps the placeholder too, at any
depth (`SELECT NULL`, `SELECT id, NULL FROM t`, `ARRAY(NULL)`).
`DorisArrowTypeMapping` gives NULL_TYPE Arrow `Null`, but BE builds such
a column as a `UInt8` flagged as a NULL literal and sends it as nullable
`Bool`, so an advertised `Null` would expire the handle at every
execution. A typed NULL (`CAST(NULL AS VARCHAR(20))`) is described as
its type.
- The prepared query kept in `FlightProtocolAdapter` records the SQL,
the namespace and the advertised schema. A prepared execution
re-analyzes the statement and compares the result with the advertised
schema before it runs, and compares the schema it actually produced
before it publishes a DoGet ticket. It is the session's next request
whether or not these checks pass: before them, it drops what the
previous request left, as a statement's execution does, while Prepare
and GetSchema are metadata requests and leave it. On a mismatch, the
handle is removed, the execution is cancelled, and the deferred
coordinator, the channel result and the endpoints are dropped. A handle
whose statement can no longer be described when it is re-analyzed, for
example after a column grant was revoked, expires the same way, and the
statement prepared again keeps the placeholder. A USE / SWITCH inside
the statement rebinds only that handle.
- `DorisArrowTypeMapping` maps TIMEV2 to `Float64` and VARBINARY to
`Binary`, the types BE sends. TIMESTAMPTZ keeps the fixed `"UTC"` in
GetTables, and AGG_STATE keeps `Null` there.
- `FeServiceClient` rejects a remote Doris metadata timeout whose
milliseconds do not fit in an int, instead of letting it wrap around.

Where master differs from branch-4.x:

- branch-4.x answers UNIMPLEMENTED at Prepare for statements whose
schema it cannot tell before they run: DESC, SHOW DATA / PARTITIONS /
QUERY STATS / PYTHON PACKAGES, other PROC nodes, COPY INTO, WARM UP
CLUSTER, multi-statement requests that do not start with USE / SWITCH,
`?` placeholders, and result types the FE cannot describe. Python ADBC
falls back to executing without a prepared statement, but the Arrow
Flight SQL JDBC driver prepares every statement and has no fallback, so
on master these statements would fail over JDBC.
`test_arrow_flight_session_lifecycle` runs DESC and `SET @multi = 2;
SELECT ...` through JDBC. Here, these statements keep today's
placeholder schema, and their handles are not checked at execution.
- branch-4.x checks privileges on the analyzed plan as it is, so a CTE
used once is checked on every column it selects, and any denial fails
Prepare. Here, CTEs are inlined first, and a remaining denial keeps the
placeholder.
- branch-4.x advertises the statistics header for WARM UP SELECT and
then rejects, as a schema change, an execution whose source turned out
empty. Here, WARM UP SELECT keeps the placeholder.
- branch-4.x advertises Arrow `Null` for an untyped NULL column, which
BE sends as `Bool`, so every prepared execution of such a query is
rejected as a schema change. Here, such a result keeps the placeholder.
- The analysis and the checks run under the session's command lock
(`FlightProtocolAdapter.runCommand` / `callCommand`) instead of
`synchronized (connectContext)`, and the namespace is saved and restored
with `getNameSpaceContext()` / `restoreNameSpaceContext()`.
- EXPLAIN PLAN PROCESS has a result over Flight on master, so it gets a
static header instead of UNIMPLEMENTED. PLAN REPLAYER and SHOW CREATE
PROCEDURE do not exist on master and are not carried over.
- SWITCH resolves the default database through the connector provider
(`Env.defaultDatabaseOnUse`, now shared with `Env.changeCatalog`)
instead of `EsExternalCatalog.DEFAULT_DB`.
- TIMESTAMPTZ fields carry the canonical session time zone that BE
stamps, where branch-4.x uses the raw session value.
- Only the two handle checks from #68768 that do not depend on parameter
binding are taken: the caller-prefix check and rebinding only the handle
that ran the USE / SWITCH. Parameter binding itself is not part of this
PR.
- `GetTableTypes`, the other half of #68631, is implemented by #67899.

Cost: every Prepare, every prepared execution and every `GetSchema` runs
one more FE analysis of the statement.

**Results.** On a local cluster built from this branch, every suite
under `arrow_flight_sql_p0` passes: the new `test_schema_only` and
`test_get_tables_schema`, plus the seven suites that run through Flight
JDBC, `test_arrow_flight_session_lifecycle` among them.
`datatype_p0/uuid/test_uuid_arrow_flight` passes too. `test_schema_only`
checks the advertised schema of each kind of statement against what its
execution actually returns. That covers queries, the side-effect-free
frontend-side commands executed as prepared statements (SHOW STORAGE
POLICY among them), a WARM UP SELECT on an empty table (executed in
cloud mode, the only mode that warms up internal tables), and a
`group_concat_state` AGG_STATE, which BE sends as Utf8.

Co-authored-by: Gabriel <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. backport/4.2-master reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants