Skip to content

[feature](mongodb) Add native catalog, reader and BSON SerDe - #70327

Open
Gabriel39 wants to merge 4 commits into
apache:masterfrom
Gabriel39:dev/mongodb-native-catalog
Open

Gabriel39 wants to merge 4 commits into
apache:masterfrom
Gabriel39:dev/mongodb-native-catalog

Conversation

@Gabriel39

@Gabriel39 Gabriel39 commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Background

The native MongoDB dependency preparation (#70249) provides the FE Java driver and BE C driver, but does not register a usable Catalog. Doris needs a native metadata and scan path that preserves BSON types and reads collection, view, and time-series namespaces directly.

What problem does this PR solve?

Issue Number: #70251
Related PR: #70249 (client dependencies)
PR Type: Feature

Problem Summary:

Implement D01, D03, and D04 of the native MongoDB Catalog roadmap, plus the minimal single-Split descriptor needed to connect them. Users can create a type=mongodb Catalog and query ordinary collections, standard views, and time-series measurements through a native C++ reader. FE pins explicit, validator, or document schemas; concrete DataTypeSerDe implementations convert BSON without losing int64 precision, ObjectId bytes, or binary subtype identity.

Details

  • Change map: 3,088 added production/build lines, 2,231 test/fixture lines, 350 generated regression-result lines, and 157 documentation lines (33 removed lines total). FE adds the Connector SPI provider, catalog-owned metadata client, schema resolution, stable handles, plugin packaging, and a single native scan range. BE adds the cursor/pool lifecycle and BSON view/context, with decoding in existing concrete SerDes. Tests include deterministic MongoDB fixtures, FE/BE unit tests, and a SQL regression suite with generated expected results.
  • Scope: read-only single-cursor scans of ordinary collections, standard views, and time-series collections. Views retain their own pipeline/collation and work with view-only find access; internal time-series buckets are hidden. All SQL filters, LIKE/REGEXP, joins, windows, aggregates, sorting, and LIMIT are evaluated in Doris. Predicate/projection pushdown, parallel range planning, common snapshots, and shared-source admission remain separate work items.
  • Design: FE sends stable namespace/configuration/schema values through TMongoScanDesc. BE owns bounded client-pool leases and cursors with RAII and closes them on EOF, early termination, cancellation, and errors. BSON conversions validate physical tags and exact numeric/date ranges; compound columns roll back on failure. The BSON helpers, MongoFileReader lifecycle, and all TMongoScanDesc fields document their ownership, units, scope, and constraints. Metadata pagination uses the pinned Java driver core operation and its server-affine cursor while retaining authorized/name-only listing and namespace kinds. BE inherits complete URI read preferences, including tags and max staleness. BSON validation uses a depth-bounded iterator stack; unsupported validator structures fall back as a whole in auto mode and fail clearly in validator mode. Canonical Extended JSON and raw BSON provide document access. Reader profiles expose read/decode/filter time, rows, and BSON bytes.
  • Usage: CREATE CATALOG mongo_native PROPERTIES ("type"="mongodb", "mongodb.uri"="mongodb://mongo.example:27017", "mongodb.databases"="sample"). See the connector README for explicit schemas, credentials, supported mappings, and fixture setup. ObjectId uses VARBINARY(12); use FROM_BINARY for supported hex/string analysis because direct VARBINARY operators retain their existing engine restrictions. Declared VARBINARY length remains schema metadata; BSON decoding preserves full ObjectId, BinData, and document payloads.
  • Default behavior: auto chooses a namespace's explicit mapping, a fully representable ordinary-collection validator, or document mode; it never samples source rows. All mapped fields are nullable and are not declared keys. Mismatches fail by default; optional top-level null substitution retains atomic nested writes. Dates use UTC. Batch size and query timeout use session settings; connection/read defaults belong to the Catalog.
  • Compatibility: the new Catalog uses the dependencies introduced by [chore](build) Add native MongoDB client dependencies #70249. Existing connectors and their serialization paths retain their behavior. Cross-version capability negotiation is outside this change.

Testing

All checks below ran locally:

  • Complete FE build (build.sh --fe) and complete ASAN BE build (build.sh --be).
  • FE connector unit tests: 31 passed, including schema resolution, metadata/driver cursor cleanup, handle serialization, session policies and native scan descriptors. Related FE core and legacy MongoDB connector tests also passed through run-fe-ut.sh.
  • BE unit tests through run-be-ut.sh: 142 passed across BSON SerDe/reader/real-driver error paths and existing decoded-value/name/VARBINARY coverage. The focused ObjectId/raw-BSON length tests failed before the fix and passed afterward. New coverage verifies bounded BSON validation memory, depth and element limits, and preservation of complete URI read preferences; the depth-boundary test was rerun after its final refactor.
  • Native MongoDB SQL regression against the deployed FE/BE and MongoDB 8.0.20: generated expected output, then independently compared it; final rerun 1 suite passed, 0 failed/fatal/skipped after recreating the source fixtures. Coverage includes explicit BSON null versus missing fields, integer/decimal bounds, float subnormal/nonfinite/signed-zero values, datetime/timestamp boundaries, binary bytes/subtypes, strings, nested values, mismatch policies, and document limits. New fixtures cover unsupported tuple/pattern/dependency validators, a wide BSON document, and metadata pagination beyond 128 namespaces.
  • License headers: the PR incremental scan passed with skywalking-eyes v0.8.0 after adding the ASF header to the MongoDB ServiceLoader descriptor.
  • FE Checkstyle: zero violations. Clang-format 16.0.6 on all 31 affected C++ source/header files, build hygiene, and the repository clang-tidy check passed. Static analysis used compilation commands from the completed BE/UT builds, expanded from unity commands for individual files.
  • Two-mongos integration with 140 collections reproduced CursorNotFound on the old implementation; the updated implementation completed 20 consecutive full listings. Matching URI read-preference tags read successfully; unmatched tags correctly timed out instead of silently routing elsewhere. Unit tests also verify preservation of URI max staleness.
  • Full diff/self-review and private-context audit completed.

Notes for Reviewers

Start with MongoSchema, MongoScanPlanProvider, mongodb_reader.cpp, and the BSON SerDe tests. The regression suite covers all three logical object kinds, schema refresh, historical validator violations, source permissions, exact/special BSON values, nested rollback, SQL analysis, batch boundaries, and repeated early cursor closure. The current local integration environment uses MongoDB 8.0.20; MongoDB 7, full replica-set/mongos topology qualification (including failover and live staleness behavior), TLS/authentication matrices, performance, and soak evidence remain in the tracking issue. The two-mongos check above is a focused metadata-cursor and tag-routing test.

Release note

Add a native read-only MongoDB Catalog supporting explicit/validator/document schemas, native BSON decoding, and single-cursor reads of collections, standard views, and time-series measurements.

Check List (For Author)

  • Behavior changed: Yes (see Details).
  • Does this need documentation: Yes; connector and fixture READMEs are included. Public user-documentation and release qualification remain tracked in [Feature][Tracking] Native MongoDB Catalog #70251.
  • Pre-submission status: Ready for review; local validation listed above, CI pending.

AI Disclosure

  • Tool: Codex (GPT-6).
  • Generated: implementation, tests, documentation, and this description.
  • Human review: pending maintainer review.

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

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

### Background

The native MongoDB connector registers its provider through Java ServiceLoader.
Service descriptors support hash comments and are checked by the license workflow.

### What problem does this PR solve?

Issue Number: apache#70251
Related PR: apache#70327 (introduced the service descriptor)
PR Type: Bugfix

Problem Summary:

The license workflow rejects the new provider descriptor because it has no ASF
license header. Add the same hash-comment header used by the other connectors.

### Details

- Frequency: every license check of the original descriptor.
- Root cause: the new META-INF/services resource contained only the provider name.
- Why existing tests missed it: ServiceLoader accepts the unlicensed descriptor;
  runtime discovery tests do not validate source licensing.
- Fix: add the ASF header as hash comments and document why that syntax is valid.
- Other paths and branches: the existing connector descriptors already carry headers.

### Testing

Skywalking-eyes v0.8.0 passed the PR incremental check with zero invalid files.
All 26 MongoDB connector unit tests passed, including ServiceLoader discovery.
FE Checkstyle passed with zero violations during Maven validate.

### Release note

None.

### Check List (For Author)

- Behavior changed: No.
- Does this need documentation: No.
- Pre-submission status: Ready; local license, unit and style checks pass.

### AI Disclosure

- Tool: Codex (GPT-6).
- Generated: the descriptor comment and commit message.
- Human review: pending maintainer review.
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: You’ve hit your usage limit. Visit https://chatgpt.com/settings/usage to purchase more credits or try again at Nov 11th, 2026 6:35 AM.
Workflow run: https://github.com/apache/doris/actions/runs/42166583347

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

…versions

### Background

Native MongoDB scans decode BSON through Doris DataTypeSerDes. VARBINARY length
is metadata in existing readers, while the new BSON path added a length check.

### What problem does this PR solve?

Issue Number: apache#70251
Related PR: apache#70327 (introduces the native reader)
PR Type: Bugfix

Problem Summary:

BSON ObjectId, BinData and raw documents can be rejected solely because their
payload exceeds the declared VARBINARY length. Restore the existing metadata
semantics and preserve all bytes. Expand regression coverage for NULL, missing,
boundary and invalid values, and explain the BSON/reader/scan-descriptor contracts.

### Details

- **Change map:** 106 added production/comment lines, 169 test/fixture lines,
  60 generated regression-result lines and 2 documentation lines; 24 removed lines.
- **Frequency:** whenever a valid BSON binary payload exceeds a declared length.
- **Root cause:** the BSON-only SerDe length member enforced a restriction absent
  from other VARBINARY readers.
- **Why existing tests missed it:** the previous BSON test expected this rejection;
  it did not compare the existing VARBINARY length semantics.
- **Fix:** remove the length argument/check while retaining BSON tag/subtype checks,
  exact byte copying, and mismatch rollback. Document borrowed-value lifetimes,
  reader lifecycle, and every TMongoScanDesc field.
- **Other paths and branches:** existing VARBINARY readers retain their behavior;
  no wire field IDs, types or requiredness change.

### Testing

The two focused ObjectId/raw-BSON tests failed before the fix and passed after it.
All 137 selected BE tests passed through run-be-ut.sh. All 26 MongoDB FE connector
tests passed, with zero Checkstyle violations. The complete ASAN BE build passed.
The SQL regression generated expected output and independently compared it against
a recreated MongoDB 8.0.20 fixture: one suite passed, zero failed/fatal/skipped.
Coverage includes explicit NULL versus absent keys, numeric extrema/nonfinite/
subnormal values, decimal overflow and rounding, datetime boundaries and precision,
ObjectId/BinData bytes and subtype mismatches, strings, nested values and document
limits. Clang-format 16, clang-tidy and build hygiene passed.

### Release note

MongoDB binary decoding preserves full ObjectId, BinData and document bytes
regardless of the declared VARBINARY length.

### Check List (For Author)

- Behavior changed: Yes (see Details).
- Does this need documentation: Yes; connector README updated.
- Pre-submission status: Ready; local checks passed, CI pending.

### AI Disclosure

- Tool: Codex (GPT-6).
- Generated: code, comments, tests, fixtures, documentation and this message.
- Human review: pending maintainer review.
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

### Background

The native MongoDB Catalog discovers logical namespaces through the Java driver
and reads BSON through the native driver and Doris SerDes. Auto schema mode must
retain every declared value through a complete typed schema or document fallback.

### What problem does this PR solve?

Issue Number: apache#70251
Related PR: apache#70327 (introduces the affected native paths)
PR Type: Bugfix

Problem Summary:

Wide BSON validation can allocate tens of MiB outside query memory accounting.
Metadata continuation can reach the wrong mongos, URI routing criteria are lost,
and valid unsupported validators can either hide fields or fail auto resolution.
Bound traversal scratch, delegate metadata cursor ownership to the pinned driver,
preserve full read preferences, and reject unrepresentable validators consistently.

### Details

- **Change map:** 131 added production/build lines, 298 test/fixture lines,
  51 generated regression-result lines and 17 documentation lines; 146 removed lines.
- **Frequency:** wide nested documents; paginated metadata across multiple mongos;
  URI tag/max-staleness settings; tuple, pattern and conditional-field validators.
- **Root cause:** a width-sized untracked worklist, independent raw cursor commands,
  mode-only read preferences and an incomplete typed validator grammar.
- **Why existing tests missed it:** standalone metadata fakes assumed that session
  identity implied server affinity; routing tests checked only mode names, schema
  tests missed valid tuple/pattern forms, and traversal had no allocation probe.
- **Fix:** use a fixed-depth iterator stack; retain driver-owned BatchCursor
  connection sources and cleanup; copy complete URI preferences in FE and BE;
  turn tuple and schema-bearing constructs into the existing whole-collection
  fallback in auto mode and explicit errors in validator mode. Preserve URI
  precedence, metadata primary reads, permissions and object kinds.
- **Other paths and branches:** recursively check root/nested/array-element schemas;
  change no existing connector path, Thrift field layout or capability negotiation.

### Testing

Focused tests reproduced the original schema/routing failures and a 48 MiB BSON
validation allocation. The old live implementation reproduced CursorNotFound
while listing 140 collections across two mongos routers. All 31 FE connector tests
and 142 selected BE tests passed; the refactored depth test passed a focused rerun.
Complete FE and ASAN BE builds passed, with zero FE Checkstyle violations.
Clang-format 16, clang-tidy and header hygiene passed for affected files.
The MongoDB SQL suite generated expected output and independently compared it:
one suite passed, zero failed/fatal/skipped, including fallback values, view-only
permissions, a 900,000-container scalar scan and metadata batch boundaries.
The fixed two-router implementation completed 20 full 140-name listings. Matching
URI tags returned the scalar value; unmatched tags timed out instead of reading
an ineligible member. Maximum staleness preservation is covered by both driver
unit tests; this is not a failover or soak qualification.

### Release note

Preserve MongoDB routing criteria and metadata cursor affinity, fall back completely
for unsupported validator schemas, and bound wide BSON validation scratch memory.

### Check List (For Author)

- Behavior changed: Yes (see Details).
- Does this need documentation: Yes; connector and fixture READMEs updated.
- Pre-submission status: Ready; local checks passed, CI pending.

### AI Disclosure

- Tool: Codex (GPT-6).
- Generated: implementation, comments, tests, fixtures, documentation and this message.
- Human review: pending maintainer review.
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@Gabriel39

Copy link
Copy Markdown
Contributor Author

Local pipeline review — ✅ PASS

schema: doris-repo-review/v1
status: PASS
pr: apache/doris#70327
commit: 2134c7569c7ae93fa981fc1695ccfed680726235
base: 59c49656240451ed1caab1e69e69bbe0be8c61aa
reviewed_at: 2026-11-06T15:35+08:00
reviewer: Gabriel39
model: gpt-6-astra
effort: xhigh
findings: {blocker: 0, major: 0, minor: 0, nit: 0}
rounds: 1
converged: true

Notes for maintainers

  • Static source and pinned dependency-contract review; builds, tests, live topology and performance/soak validation were not run as part of this review.

Reviewed locally with the doris-repo-review pipeline. Repository policy may accept this receipt for the matching commit; it is not a human Apache approval.

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Review recovery stopped: shared time budget or helper timeout exhausted
Workflow run: https://github.com/apache/doris/actions/runs/42179532956

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

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

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17605	5147	5037	5037
q2	2131	314	257	257
q3	10256	1383	825	825
q4	4683	465	338	338
q5	7437	801	533	533
q6	184	189	159	159
q7	758	790	595	595
q8	9245	1373	1109	1109
q9	5760	4217	4214	4214
q10	6813	1290	1024	1024
q11	423	241	227	227
q12	642	402	283	283
q13	18110	3631	3055	3055
q14	277	270	240	240
q15	q16	727	717	664	664
q17	1212	756	581	581
q18	7041	6195	6137	6137
q19	1096	983	590	590
q20	386	339	230	230
q21	5567	2503	2446	2446
q22	378	315	268	268
Total cold run time: 100731 ms
Total hot run time: 28812 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	6186	5894	6050	5894
q2	718	628	585	585
q3	5662	5862	5276	5276
q4	2074	2140	1553	1553
q5	5795	5885	5632	5632
q6	234	187	144	144
q7	2261	2055	1814	1814
q8	3007	2760	2686	2686
q9	7992	7635	7543	7543
q10	3614	3566	3107	3107
q11	584	405	376	376
q12	670	658	502	502
q13	3275	3603	3015	3015
q14	288	292	262	262
q15	q16	658	679	617	617
q17	7675	7105	6878	6878
q18	12923	12214	12902	12214
q19	900	785	769	769
q20	2152	2128	1886	1886
q21	5556	4614	4688	4614
q22	494	446	415	415
Total cold run time: 72718 ms
Total hot run time: 65782 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 154360 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 2134c7569c7ae93fa981fc1695ccfed680726235, data reload: false

query5	4321	529	392	392
query6	431	218	217	217
query7	4820	472	236	236
query8	328	172	155	155
query9	8791	3211	3220	3211
query10	456	339	272	272
query11	6078	3900	3580	3580
query12	149	95	86	86
query13	1252	459	336	336
query14	6161	3959	3661	3661
query14_1	3455	3405	3400	3400
query15	206	214	181	181
query16	952	422	404	404
query17	866	665	548	548
query18	2420	433	313	313
query19	200	174	140	140
query20	87	86	89	86
query21	211	132	111	111
query22	12996	12919	12770	12770
query23	13645	12797	12514	12514
query23_1	12661	12610	12484	12484
query24	7361	847	494	494
query24_1	493	487	496	487
query25	548	460	373	373
query26	1253	280	152	152
query27	2740	464	281	281
query28	4586	2062	2090	2062
query29	1559	608	438	438
query30	295	216	182	182
query31	1018	939	814	814
query32	143	90	96	90
query33	518	313	236	236
query34	917	903	532	532
query35	748	750	652	652
query36	811	829	723	723
query37	129	100	80	80
query38	1762	1714	1687	1687
query39	792	802	747	747
query39_1	719	716	738	716
query40	219	114	111	111
query41	67	63	62	62
query42	103	85	83	83
query43	359	374	309	309
query44	1387	714	712	712
query45	184	179	167	167
query46	875	1010	564	564
query47	2999	2893	2812	2812
query48	298	329	237	237
query49	606	411	298	298
query50	722	291	227	227
query51	10533	10495	10425	10425
query52	83	80	71	71
query53	195	217	158	158
query54	253	206	209	206
query55	78	73	68	68
query56	239	227	258	227
query57	1657	1665	1538	1538
query58	293	272	258	258
query59	2139	2148	2014	2014
query60	275	236	209	209
query61	147	146	145	145
query62	397	339	289	289
query63	197	160	164	160
query64	2755	901	741	741
query65	3307	3268	3266	3266
query66	1752	461	307	307
query67	22626	22638	22510	22510
query68	3318	1038	629	629
query69	382	295	258	258
query70	867	767	775	767
query71	305	243	212	212
query72	2747	2597	2310	2310
query73	560	568	306	306
query74	4619	4524	4370	4370
query75	2434	2325	1940	1940
query76	2349	1144	619	619
query77	373	404	283	283
query78	9836	9759	9247	9247
query79	990	958	551	551
query80	569	463	389	389
query81	523	323	274	274
query82	587	148	115	115
query83	312	227	199	199
query84	309	131	109	109
query85	939	427	370	370
query86	264	241	233	233
query87	1989	1945	1793	1793
query88	3786	2776	2774	2774
query89	334	289	247	247
query90	2012	178	167	167
query91	162	150	124	124
query92	102	94	87	87
query93	1073	1028	595	595
query94	578	314	250	250
query95	586	316	312	312
query96	705	510	244	244
query97	2431	2449	2380	2380
query98	163	160	149	149
query99	762	756	666	666
Total cold run time: 238305 ms
Total hot run time: 154360 ms

@hello-stephen

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

query1	0.01	0.01	0.00
query2	0.10	0.04	0.05
query3	0.26	0.10	0.10
query4	1.60	0.10	0.10
query5	0.23	0.24	0.24
query6	1.18	0.68	0.69
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.39	0.34	0.35
query10	0.57	0.57	0.57
query11	0.19	0.14	0.14
query12	0.18	0.15	0.14
query13	0.49	0.49	0.48
query14	1.02	1.01	1.00
query15	0.61	0.60	0.61
query16	0.35	0.33	0.33
query17	1.13	1.12	1.10
query18	0.24	0.18	0.18
query19	2.12	2.03	2.00
query20	0.02	0.01	0.01
query21	15.42	0.20	0.14
query22	4.84	0.05	0.06
query23	16.28	0.31	0.13
query24	1.06	0.24	0.16
query25	0.08	0.05	0.05
query26	0.77	0.22	0.17
query27	0.02	0.03	0.03
query28	3.59	0.91	0.37
query29	12.48	4.17	3.23
query30	0.30	0.12	0.10
query31	2.77	0.56	0.33
query32	3.21	0.59	0.52
query33	3.19	3.20	3.29
query34	15.31	3.96	3.35
query35	3.36	3.36	3.35
query36	0.54	0.46	0.45
query37	0.09	0.07	0.06
query38	0.05	0.04	0.04
query39	0.04	0.04	0.03
query40	0.18	0.15	0.14
query41	0.09	0.04	0.03
query42	0.04	0.03	0.03
query43	0.04	0.03	0.04
Total cold run time: 94.54 s
Total hot run time: 24.09 s

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants