You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by "sollhui (via GitHub)" <gi...@apache.org> on 2026/10/21 08:09:36 UTC
[PR] [perf](fs) Push down Azure glob listing prefixes [doris]
sollhui opened a new pull request, #69383:
URL: https://github.com/apache/doris/pull/69383
### What problem does this PR solve?
Related PR: #64941, #64684
Azure glob listing scans only the longest static prefix. For example, `date=2025-{0[3-9],1[0-2]}-01/*` scans everything under `date=2025-`, including unrelated dates.
Extract the object-storage glob helpers into `ObjectStorageGlob` and use them for Azure and S3-compatible listing. Bounded alternatives become sorted, non-overlapping remote list prefixes; unsafe or excessive expansion falls back to a conservative prefix and still applies the complete matcher. Numeric ranges retain zero padding and can match large ranges without enumerating every value. Azure limits and resume cursors continue across expanded prefixes, and object-storage cursors consistently use unsigned UTF-8 order. S3 directory buckets retain slash-terminated prefixes and reject unsupported key-based pagination.
This reapplies the final changes from #64941 to current master (`cca2231716264a15cbc884fbeac96eef4eafd66b`). It adapts the S3 changes to `fe-filesystem-s3-base`, retains the existing SPI hooks and notification matcher, merges the offset test into master's existing tests, and preserves master's escaped/nested glob and suffix-sensitive prefix behavior. Hadoop's `GlobPattern` expansion remains unchanged.
### Release note
Reduce Azure glob listing scans for bounded patterns. Correct object-storage numeric-range and UTF-8 cursor handling. Reject limited/resumed S3 directory-bucket glob listing because it cannot support key-based pagination.
### Check List (For Author)
- Test:
- [x] Unit Test: ported and extended coverage for prefix pushdown, fallback, numeric ranges, padding, escaping, nesting, limits, UTF-8 cursors, and directory buckets.
- Local validation: Checkstyle passed for `fe-filesystem-spi`, `fe-filesystem-azure`, `fe-filesystem-s3-base`, and `fe-core`; `git diff --check` passed.
- Unit execution is pending CI. Attempted `bash run-fe-ut.sh --run ObjectStorageGlobTest,AzureFileSystemTest,S3FileSystemTest,S3CompatibleFileSystemTest,S3SourceOffsetProviderTest`, but the standard script stopped at the JDK check: this host has no configured JDK 17. No unit-test success is claimed.
- Behavior changed:
- [x] Yes. Azure pushes down expanded prefixes; object-storage ranges preserve padding and large-range semantics; cursor comparisons use UTF-8 order; directory-bucket key pagination fails explicitly.
- Does this need documentation?
- [x] No. No new configuration or syntax.
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](storage) Prune Azure glob listing with expanded prefixes [doris]
Posted by "sollhui (via GitHub)" <gi...@apache.org>.
sollhui merged PR #69383:
URL: https://github.com/apache/doris/pull/69383
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6317272170
<details>
<summary>TPC-H: <b>Total hot run time: 28854 ms</b></summary>
```
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit edfc98a8389b23f617a42efa9758414fd9c89c02, data reload: false
------ Round 1 ----------------------------------
============================================
q1 17603 5152 5282 5152
q2 2102 323 259 259
q3 10214 1406 837 837
q4 4683 470 340 340
q5 7432 804 533 533
q6 191 187 159 159
q7 761 801 608 608
q8 9967 1334 1075 1075
q9 5655 4236 4222 4222
q10 6875 1303 1029 1029
q11 436 248 227 227
q12 708 397 278 278
q13 18247 3691 3038 3038
q14 279 281 252 252
q15 q16 777 716 663 663
q17 2796 765 590 590
q18 7061 6210 6134 6134
q19 1794 978 608 608
q20 409 346 227 227
q21 5793 2329 2486 2329
q22 394 331 294 294
Total cold run time: 104177 ms
Total hot run time: 28854 ms
----- Round 2, with runtime_filter_mode=off -----
============================================
q1 5993 5975 5896 5896
q2 766 605 595 595
q3 5594 5658 5232 5232
q4 2022 2187 1566 1566
q5 6028 5709 5760 5709
q6 249 192 149 149
q7 2246 2034 1826 1826
q8 2976 2624 2670 2624
q9 7537 7511 7496 7496
q10 3674 3598 3177 3177
q11 579 440 414 414
q12 714 675 511 511
q13 3248 3574 3051 3051
q14 293 292 265 265
q15 q16 668 679 607 607
q17 7751 7130 6975 6975
q18 13035 12224 13023 12224
q19 918 794 817 794
q20 2154 2164 1944 1944
q21 5692 4798 4820 4798
q22 509 457 420 420
Total cold run time: 72646 ms
Total hot run time: 66273 ms
```
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Push down Azure glob listing prefixes [doris]
Posted by "sollhui (via GitHub)" <gi...@apache.org>.
sollhui commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6311280280
/review
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6336053547
# FE Regression Coverage Report
Increment line coverage ` 9.52% (6/63)` :tada:
[Increment coverage report](http://coverage.selectdb-in.cc/coverage/69383_32dfb1c24ad3b39d86581514e237f909738c3aa5_merge_fe/increment_report/index.html)
[Complete coverage report](http://coverage.selectdb-in.cc/coverage/69383_32dfb1c24ad3b39d86581514e237f909738c3aa5_merge_fe/report/index.html)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6317477437
<details>
<summary>TPC-DS: <b>Total hot run time: 150455 ms</b></summary>
```
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit edfc98a8389b23f617a42efa9758414fd9c89c02, data reload: false
query5 4312 593 452 452
query6 427 204 189 189
query7 4803 440 220 220
query8 314 168 155 155
query9 8786 3063 3070 3063
query10 487 305 260 260
query11 6035 3864 3566 3566
query12 149 93 88 88
query13 1246 443 321 321
query14 6054 3938 3636 3636
query14_1 3380 3468 3415 3415
query15 209 210 186 186
query16 960 481 419 419
query17 864 665 526 526
query18 2432 419 312 312
query19 194 167 138 138
query20 87 87 85 85
query21 209 130 111 111
query22 12987 12977 12834 12834
query23 13417 12900 12430 12430
query23_1 12593 12490 12616 12490
query24 7412 817 462 462
query24_1 479 473 466 466
query25 561 425 368 368
query26 1258 259 138 138
query27 2764 444 277 277
query28 4639 1929 1917 1917
query29 1555 602 456 456
query30 298 259 179 179
query31 1010 928 799 799
query32 146 91 86 86
query33 508 292 219 219
query34 897 842 499 499
query35 730 744 652 652
query36 824 813 751 751
query37 116 94 79 79
query38 1773 1759 1642 1642
query39 796 789 734 734
query39_1 721 722 750 722
query40 215 111 91 91
query41 64 63 62 62
query42 82 79 79 79
query43 341 358 309 309
query44 1303 677 683 677
query45 179 175 167 167
query46 816 968 554 554
query47 2854 3045 2616 2616
query48 298 301 215 215
query49 561 392 293 293
query50 702 285 217 217
query51 10244 10532 10490 10490
query52 81 76 70 70
query53 185 205 159 159
query54 249 188 198 188
query55 76 67 64 64
query56 237 220 202 202
query57 1628 1624 1585 1585
query58 275 257 252 252
query59 2109 2144 1996 1996
query60 292 247 253 247
query61 162 148 145 145
query62 390 328 289 289
query63 184 156 154 154
query64 2708 950 746 746
query65 3346 3287 3261 3261
query66 1765 412 298 298
query67 20082 20132 19935 19935
query68 2973 984 596 596
query69 371 281 248 248
query70 845 794 754 754
query71 290 233 215 215
query72 2641 2730 2277 2277
query73 515 517 289 289
query74 4623 4536 4329 4329
query75 2305 2288 1893 1893
query76 2361 999 580 580
query77 333 377 274 274
query78 9908 9640 9198 9198
query79 1012 841 534 534
query80 539 412 332 332
query81 514 313 276 276
query82 576 132 109 109
query83 308 201 183 183
query84 307 120 104 104
query85 833 435 370 370
query86 321 238 233 233
query87 1995 1983 1799 1799
query88 3642 2646 2624 2624
query89 317 280 239 239
query90 1879 164 166 164
query91 161 152 127 127
query92 99 83 91 83
query93 979 984 564 564
query94 442 307 286 286
query95 577 320 357 320
query96 663 485 232 232
query97 2480 2482 2322 2322
query98 169 152 152 152
query99 773 765 653 653
Total cold run time: 233353 ms
Total hot run time: 150455 ms
```
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6334208871
# FE UT Coverage Report
Increment line coverage ` 100.00% (8/8)` :tada:
[Increment coverage report](http://coverage.selectdb-in.cc/coverage/69383_32dfb1c24ad3b39d86581514e237f909738c3aa5/fe_increment_report/index.html)
[Complete coverage report](http://coverage.selectdb-in.cc/coverage/69383_32dfb1c24ad3b39d86581514e237f909738c3aa5/fe_report/index.html)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "sollhui (via GitHub)" <gi...@apache.org>.
sollhui commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6331544614
run buildall
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6333483423
<details>
<summary>TPC-H: <b>Total hot run time: 28324 ms</b></summary>
```
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 32dfb1c24ad3b39d86581514e237f909738c3aa5, data reload: false
------ Round 1 ----------------------------------
============================================
q1 17621 5168 5065 5065
q2 2113 319 251 251
q3 10235 1352 829 829
q4 4674 457 332 332
q5 7425 786 534 534
q6 183 185 150 150
q7 752 788 597 597
q8 9252 1348 1105 1105
q9 5529 4212 4197 4197
q10 6833 1288 1049 1049
q11 443 252 229 229
q12 640 393 281 281
q13 18080 3561 2939 2939
q14 276 271 248 248
q15 q16 711 730 654 654
q17 1171 743 566 566
q18 6927 6160 6093 6093
q19 1102 973 604 604
q20 386 346 221 221
q21 4427 2134 2301 2134
q22 341 295 246 246
Total cold run time: 99121 ms
Total hot run time: 28324 ms
----- Round 2, with runtime_filter_mode=off -----
============================================
q1 5618 5556 5606 5556
q2 680 567 534 534
q3 5221 5341 4940 4940
q4 1986 2118 1550 1550
q5 5286 5165 5456 5165
q6 251 190 148 148
q7 2383 2039 1812 1812
q8 3015 2670 2676 2670
q9 8007 7991 7983 7983
q10 3747 3674 3254 3254
q11 615 592 429 429
q12 713 716 530 530
q13 3461 3846 3239 3239
q14 315 324 300 300
q15 q16 696 709 633 633
q17 8373 7552 6931 6931
q18 13026 12193 12830 12193
q19 897 817 768 768
q20 2149 2125 1901 1901
q21 5679 4605 4702 4605
q22 519 464 414 414
Total cold run time: 72637 ms
Total hot run time: 65555 ms
```
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6314732222
# FE UT Coverage Report
Increment line coverage ` 50.00% (1/2)` :tada:
[Increment coverage report](http://coverage.selectdb-in.cc/coverage/69383_edfc98a8389b23f617a42efa9758414fd9c89c02/fe_increment_report/index.html)
[Complete coverage report](http://coverage.selectdb-in.cc/coverage/69383_edfc98a8389b23f617a42efa9758414fd9c89c02/fe_report/index.html)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6333677244
<details>
<summary>ClickBench: <b>Total hot run time: 24.22 s</b></summary>
```
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 32dfb1c24ad3b39d86581514e237f909738c3aa5, data reload: false
query1 0.01 0.01 0.00
query2 0.09 0.05 0.05
query3 0.26 0.08 0.08
query4 1.61 0.10 0.09
query5 0.26 0.24 0.24
query6 1.17 0.67 0.66
query7 0.04 0.01 0.01
query8 0.05 0.04 0.04
query9 0.39 0.34 0.33
query10 0.60 0.56 0.58
query11 0.19 0.14 0.14
query12 0.18 0.14 0.14
query13 0.49 0.49 0.48
query14 1.02 1.03 1.03
query15 0.62 0.60 0.60
query16 0.35 0.35 0.33
query17 1.16 1.15 1.11
query18 0.20 0.18 0.20
query19 2.11 1.99 1.93
query20 0.02 0.01 0.01
query21 15.48 0.20 0.13
query22 4.88 0.05 0.05
query23 16.29 0.30 0.12
query24 3.04 0.54 0.46
query25 0.11 0.04 0.06
query26 1.53 0.21 0.15
query27 0.06 0.03 0.04
query28 3.90 0.67 0.36
query29 12.52 4.01 3.23
query30 0.28 0.13 0.09
query31 2.77 0.58 0.33
query32 3.23 0.59 0.50
query33 3.20 3.25 3.22
query34 15.42 4.01 3.40
query35 3.39 3.33 3.33
query36 0.55 0.43 0.43
query37 0.09 0.06 0.06
query38 0.05 0.04 0.03
query39 0.04 0.03 0.04
query40 0.17 0.16 0.13
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: 97.99 s
Total hot run time: 24.22 s
```
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "sollhui (via GitHub)" <gi...@apache.org>.
sollhui commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6331548941
/review
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6333611891
<details>
<summary>TPC-DS: <b>Total hot run time: 150979 ms</b></summary>
```
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 32dfb1c24ad3b39d86581514e237f909738c3aa5, data reload: false
query5 4294 584 450 450
query6 425 204 194 194
query7 4794 441 230 230
query8 333 182 148 148
query9 8770 3092 3104 3092
query10 472 309 257 257
query11 6011 3882 3570 3570
query12 151 96 89 89
query13 1286 462 321 321
query14 6112 3955 3644 3644
query14_1 3379 3434 3438 3434
query15 203 204 182 182
query16 941 445 405 405
query17 845 650 535 535
query18 2409 437 315 315
query19 193 165 134 134
query20 85 83 83 83
query21 208 129 108 108
query22 12855 12983 12787 12787
query23 13470 12837 12390 12390
query23_1 12584 12587 12495 12495
query24 7380 817 464 464
query24_1 481 461 472 461
query25 531 421 357 357
query26 1259 258 143 143
query27 2764 437 271 271
query28 4634 1959 1972 1959
query29 1571 598 448 448
query30 292 217 189 189
query31 996 931 826 826
query32 147 95 89 89
query33 518 299 254 254
query34 930 849 490 490
query35 758 761 663 663
query36 812 789 732 732
query37 132 94 78 78
query38 1775 1708 1676 1676
query39 788 782 747 747
query39_1 748 722 742 722
query40 221 119 98 98
query41 71 67 67 67
query42 86 87 81 81
query43 343 371 317 317
query44 1314 689 685 685
query45 179 176 162 162
query46 851 957 564 564
query47 2691 3044 2903 2903
query48 300 316 233 233
query49 600 408 346 346
query50 698 283 210 210
query51 10210 10640 10514 10514
query52 80 83 69 69
query53 182 206 151 151
query54 236 205 211 205
query55 68 67 70 67
query56 243 225 200 200
query57 1628 1640 1585 1585
query58 284 262 251 251
query59 2097 2122 1912 1912
query60 287 240 235 235
query61 148 141 144 141
query62 378 352 304 304
query63 192 153 157 153
query64 2740 936 794 794
query65 3341 3270 3270 3270
query66 1785 418 311 311
query67 20367 19995 20027 19995
query68 3054 999 621 621
query69 378 301 253 253
query70 837 762 766 762
query71 283 238 210 210
query72 2767 2571 2274 2274
query73 509 527 299 299
query74 4593 4525 4328 4328
query75 2337 2313 1915 1915
query76 2321 1015 598 598
query77 350 355 271 271
query78 9829 9707 9137 9137
query79 983 856 531 531
query80 1226 434 333 333
query81 601 317 268 268
query82 582 131 107 107
query83 302 202 185 185
query84 311 130 101 101
query85 861 425 363 363
query86 392 242 228 228
query87 2007 1959 1779 1779
query88 3712 2677 2661 2661
query89 340 292 243 243
query90 1860 168 168 168
query91 162 148 127 127
query92 97 89 86 86
query93 1122 1008 578 578
query94 637 295 280 280
query95 576 320 300 300
query96 664 485 234 234
query97 2460 2414 2350 2350
query98 160 153 149 149
query99 766 749 637 637
Total cold run time: 234728 ms
Total hot run time: 150979 ms
```
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Push down Azure glob listing prefixes [doris]
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6311235739
Thank you for your contribution to Apache Doris.
Don't know what should be done next? See [How to process your PR](https://doris.apache.org/community/how-to-contribute/review-and-ci).
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?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Push down Azure glob listing prefixes [doris]
Posted by "sollhui (via GitHub)" <gi...@apache.org>.
sollhui commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6311271713
run buildall
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "hello-stephen (via GitHub)" <gi...@apache.org>.
hello-stephen commented on PR #69383:
URL: https://github.com/apache/doris/pull/69383#issuecomment-6317581368
<details>
<summary>ClickBench: <b>Total hot run time: 24.2 s</b></summary>
```
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit edfc98a8389b23f617a42efa9758414fd9c89c02, data reload: false
query1 0.01 0.01 0.01
query2 0.10 0.05 0.05
query3 0.26 0.08 0.09
query4 1.62 0.11 0.10
query5 0.27 0.24 0.24
query6 1.16 0.69 0.68
query7 0.04 0.00 0.01
query8 0.06 0.04 0.03
query9 0.42 0.34 0.34
query10 0.59 0.57 0.64
query11 0.21 0.14 0.14
query12 0.18 0.14 0.15
query13 0.47 0.50 0.51
query14 1.01 1.01 1.04
query15 0.64 0.61 0.60
query16 0.34 0.34 0.36
query17 1.15 1.12 1.15
query18 0.19 0.18 0.18
query19 2.04 2.00 1.92
query20 0.02 0.02 0.01
query21 15.48 0.19 0.13
query22 4.97 0.05 0.06
query23 16.25 0.32 0.13
query24 3.16 0.63 0.34
query25 0.11 0.05 0.06
query26 1.12 0.21 0.15
query27 0.05 0.06 0.05
query28 3.17 0.79 0.36
query29 12.51 4.03 3.22
query30 0.28 0.13 0.10
query31 2.77 0.54 0.32
query32 3.21 0.59 0.50
query33 3.25 3.19 3.22
query34 15.28 4.01 3.40
query35 3.36 3.36 3.37
query36 0.56 0.46 0.42
query37 0.10 0.07 0.06
query38 0.05 0.04 0.04
query39 0.04 0.03 0.03
query40 0.17 0.15 0.15
query41 0.08 0.03 0.03
query42 0.04 0.03 0.03
query43 0.05 0.03 0.03
Total cold run time: 96.84 s
Total hot run time: 24.2 s
```
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
Re: [PR] [perf](fs) Prune Azure glob listing with expanded prefixes [doris]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on code in PR #69383:
URL: https://github.com/apache/doris/pull/69383#discussion_r4334770927
##########
fe/fe-filesystem/fe-filesystem-azure/src/main/java/org/apache/doris/filesystem/azure/AzureFileSystem.java:
##########
@@ -397,51 +398,62 @@ public GlobListing globListWithLimit(Location path, String startAfter, long maxB
// base = uri with the key portion stripped, preserving the original scheme/host syntax.
String base = uri.substring(0, uri.length() - keyPattern.length());
- Pattern matcher = Pattern.compile(globToRegex(keyPattern));
- String listKeyPrefix = longestNonGlobPrefix(keyPattern);
- String listPrefixUri = base + listKeyPrefix;
+ String expandedKeyPattern = ObjectStorageGlob.expandNumericRanges(keyPattern);
+ Pattern matcher = Pattern.compile(globToRegex(expandedKeyPattern));
+ String listKeyPrefix = longestNonGlobPrefix(expandedKeyPattern);
+ List<String> listKeyPrefixes = ObjectStorageGlob.expandedGlobListPrefixes(expandedKeyPattern);
Review Comment:
[P2] Fall back when class-range endpoints contain escapes
For `data/[\a-z]/*/file.csv`, the new prefix expander consumes `\a` as a complete alternative and emits only `data/-/`, `data/a/`, and `data/z/`. The full matcher emits `[\Qa\E-z]`, an ordinary `a-z` range, so it accepts `data/m/sub/file.csv`, but none of the remote LIST calls can return that blob. Escaped upper endpoints such as `[a-\c]` have the same mismatch. Azure previously listed the conservative `data/` prefix and found these matches; importing the existing S3 expander introduces silent omissions here. Parse escaped range endpoints consistently with the matcher, or retain a conservative prefix for these classes.
##########
fe/fe-filesystem/fe-filesystem-azure/src/main/java/org/apache/doris/filesystem/azure/AzureFileSystem.java:
##########
@@ -397,51 +398,62 @@ public GlobListing globListWithLimit(Location path, String startAfter, long maxB
// base = uri with the key portion stripped, preserving the original scheme/host syntax.
String base = uri.substring(0, uri.length() - keyPattern.length());
- Pattern matcher = Pattern.compile(globToRegex(keyPattern));
- String listKeyPrefix = longestNonGlobPrefix(keyPattern);
- String listPrefixUri = base + listKeyPrefix;
+ String expandedKeyPattern = ObjectStorageGlob.expandNumericRanges(keyPattern);
+ Pattern matcher = Pattern.compile(globToRegex(expandedKeyPattern));
+ String listKeyPrefix = longestNonGlobPrefix(expandedKeyPattern);
+ List<String> listKeyPrefixes = ObjectStorageGlob.expandedGlobListPrefixes(expandedKeyPattern);
List<FileEntry> files = new ArrayList<>();
long totalSize = 0L;
- String maxFile = "";
- String continuationToken = null;
+ String nextMatchAfterLimit = "";
+ String lastMatchedKey = "";
boolean reachLimit = false;
- outer:
- do {
- RemoteObjects page = objStorage.listObjects(listPrefixUri, continuationToken);
- for (RemoteObject obj : page.getObjectList()) {
- String key = obj.getKey();
- if (key.endsWith(DIR_MARKER_SUFFIX)) {
- continue;
- }
- if (startAfter != null && !startAfter.isEmpty() && key.compareTo(startAfter) <= 0) {
- continue;
- }
- if (!matcher.matcher(key).matches()) {
- continue;
- }
- if ((maxFiles > 0 && files.size() >= maxFiles)
- || (maxBytes > 0 && totalSize >= maxBytes)) {
- maxFile = key;
- reachLimit = true;
- break outer;
+ for (String currentListKeyPrefix : listKeyPrefixes) {
+ String continuationToken = null;
+ String listPrefixUri = base + currentListKeyPrefix;
Review Comment:
[P2] Encode expanded prefixes before rebuilding the Azure URI
A valid glob such as `data/[$-&]/*/file.csv` expands to prefixes containing `$`, `%`, and `&`. This concatenation sends the generated `data/%/` through `AzureObjStorage.listObjects`, which reparses it with `AzureUri.parse` and `URLDecoder.decode`; the bare percent escape throws `IllegalArgumentException`, aborting the listing even if the container only has ordinary matching `$`/`&` keys. The previous conservative `data/` scan succeeded. Generated `+` and `#` prefixes are likewise changed into spaces or truncated. Encode the raw prefix while preserving path separators, or pass the raw prefix directly to the listing API. The storage mocks in the new tests bypass this second parse.
##########
fe/fe-filesystem/fe-filesystem-azure/src/main/java/org/apache/doris/filesystem/azure/AzureFileSystem.java:
##########
@@ -397,51 +398,62 @@ public GlobListing globListWithLimit(Location path, String startAfter, long maxB
// base = uri with the key portion stripped, preserving the original scheme/host syntax.
String base = uri.substring(0, uri.length() - keyPattern.length());
- Pattern matcher = Pattern.compile(globToRegex(keyPattern));
- String listKeyPrefix = longestNonGlobPrefix(keyPattern);
- String listPrefixUri = base + listKeyPrefix;
+ String expandedKeyPattern = ObjectStorageGlob.expandNumericRanges(keyPattern);
+ Pattern matcher = Pattern.compile(globToRegex(expandedKeyPattern));
+ String listKeyPrefix = longestNonGlobPrefix(expandedKeyPattern);
+ List<String> listKeyPrefixes = ObjectStorageGlob.expandedGlobListPrefixes(expandedKeyPattern);
List<FileEntry> files = new ArrayList<>();
long totalSize = 0L;
- String maxFile = "";
- String continuationToken = null;
+ String nextMatchAfterLimit = "";
+ String lastMatchedKey = "";
boolean reachLimit = false;
- outer:
- do {
- RemoteObjects page = objStorage.listObjects(listPrefixUri, continuationToken);
- for (RemoteObject obj : page.getObjectList()) {
- String key = obj.getKey();
- if (key.endsWith(DIR_MARKER_SUFFIX)) {
- continue;
- }
- if (startAfter != null && !startAfter.isEmpty() && key.compareTo(startAfter) <= 0) {
- continue;
- }
- if (!matcher.matcher(key).matches()) {
- continue;
- }
- if ((maxFiles > 0 && files.size() >= maxFiles)
- || (maxBytes > 0 && totalSize >= maxBytes)) {
- maxFile = key;
- reachLimit = true;
- break outer;
+ for (String currentListKeyPrefix : listKeyPrefixes) {
+ String continuationToken = null;
+ String listPrefixUri = base + currentListKeyPrefix;
+ do {
+ RemoteObjects page = objStorage.listObjects(listPrefixUri, continuationToken);
+ for (RemoteObject obj : page.getObjectList()) {
+ String key = obj.getKey();
+ if (key.endsWith(DIR_MARKER_SUFFIX)) {
+ continue;
+ }
+ if (startAfter != null && !startAfter.isEmpty()
+ && ObjectStorageGlob.compareUtf8Binary(key, startAfter) <= 0) {
Review Comment:
[P2] Apply resume cursors in the Azure endpoint listing order
The configurable Azure endpoint can use Microsoft's Azurite, whose [flat listing implementation](https://github.com/Azure/Azurite/blob/main/src/blob/persistence/LokiBlobMetadataStore.ts) sorts names with JavaScript string comparisons (UTF-16 ordinal). For `data/*.csv`, that order puts `data/😀.csv` before `data/A.csv` (U+FF21). With `maxFiles=1`, the first call returns the emoji key; resuming from that returned key now discards the unconsumed fullwidth-A key because it sorts before the emoji in UTF-8. The former `String.compareTo` retained it. Keep prefix ordering, remote enumeration and cursor filtering consistent with the endpoint order, and cover a limited no-brace listing in ordinal order. This counterexample is established from the official emulator source; live Azure service ordering was not exercised.
##########
fe/fe-filesystem/fe-filesystem-spi/src/main/java/org/apache/doris/filesystem/spi/ObjectStorageGlob.java:
##########
@@ -0,0 +1,725 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.filesystem.spi;
+
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Provider-neutral glob helpers for object-storage keys.
+ */
+public final class ObjectStorageGlob {
+
+ private static final int MAX_EXPANDED_GLOB_LIST_PREFIXES = 256;
+ private static final Comparator<String> UTF8_BINARY_ORDER = ObjectStorageGlob::compareUtf8Binary;
+ private static final Pattern NUMERIC_RANGE_PATTERN = Pattern.compile("-?\\d+\\.\\.-?\\d+");
+ private static final Pattern NUMERIC_RANGE_ALTERNATIVE = Pattern.compile("(-?\\d+)\\.\\.(-?\\d+)");
+
+ private ObjectStorageGlob() {
+ }
+
+ /**
+ * Returns the longest key prefix that contains no glob metacharacters.
+ */
+ public static String longestNonGlobPrefix(String globPattern) {
+ int earliest = globPattern.length();
+ for (char c : new char[]{'*', '?', '[', '{', '\\'}) {
+ int idx = globPattern.indexOf(c);
+ if (idx >= 0 && idx < earliest) {
+ earliest = idx;
+ }
+ }
+ return globPattern.substring(0, earliest);
+ }
+
+ /**
+ * Returns object-store list prefixes that are safe to push down for a glob pattern.
+ *
+ * <p>Unlike {@link #longestNonGlobPrefix(String)}, this expands bounded glob constructs
+ * ({@code {...}} alternation and positive {@code [...]} character classes) before the first
+ * unbounded wildcard. For example,
+ * {@code date=2025-{0[3-9],1[0-2]}-01/mp_id=8/*} becomes concrete date prefixes instead
+ * of one broad {@code date=2025-} scan. If expansion would be too large or unsafe, it
+ * falls back to the conservative longest static prefix.
+ */
+ public static List<String> expandedGlobListPrefixes(String globPattern) {
+ List<String> prefixes = expandGlobListPrefixes(globPattern, true);
+ return prefixes == null ? List.of(longestNonGlobPrefix(globPattern)) : prefixes;
+ }
+
+ private static List<String> expandGlobListPrefixes(String globPattern, boolean allowPartialPrefix) {
+ List<String> prefixes = new ArrayList<>();
+ prefixes.add("");
+ int i = 0;
+ while (i < globPattern.length()) {
+ char c = globPattern.charAt(i);
+ if (c == '*' || c == '?') {
+ return allowPartialPrefix ? compactPrefixes(prefixes) : null;
+ }
+ if (c == '\\') {
+ if (i + 1 < globPattern.length()) {
+ appendLiteral(prefixes, globPattern.charAt(i + 1));
+ i += 2;
+ } else {
+ appendLiteral(prefixes, c);
+ i++;
+ }
+ continue;
+ }
+ if (c == '[') {
+ PrefixExpansion charClass = expandCharacterClass(globPattern, i);
+ if (charClass == null) {
+ return allowPartialPrefix ? compactPrefixes(prefixes) : null;
+ }
+ prefixes = appendAlternatives(prefixes, charClass.values);
+ if (prefixes == null) {
+ return null;
+ }
+ i = charClass.nextIndex;
+ continue;
+ }
+ if (c == '{') {
+ PrefixExpansion brace = expandBraceGroup(globPattern, i);
+ if (brace == null) {
+ return allowPartialPrefix ? compactPrefixes(prefixes) : null;
+ }
+ prefixes = appendAlternatives(prefixes, brace.values);
+ if (prefixes == null) {
+ return null;
+ }
+ i = brace.nextIndex;
+ continue;
+ }
+ appendLiteral(prefixes, c);
+ i++;
+ }
+ // Complete brace arms must retain distinct values until the surrounding suffix is appended.
+ return allowPartialPrefix ? compactPrefixes(prefixes) : prefixes;
+ }
+
+ private static void appendLiteral(List<String> prefixes, char c) {
+ for (int i = 0; i < prefixes.size(); i++) {
+ prefixes.set(i, prefixes.get(i) + c);
+ }
+ }
+
+ private static List<String> appendAlternatives(List<String> prefixes, List<String> alternatives) {
+ long expandedSize = (long) prefixes.size() * alternatives.size();
+ if (expandedSize > MAX_EXPANDED_GLOB_LIST_PREFIXES) {
+ return null;
+ }
+ List<String> expanded = new ArrayList<>((int) expandedSize);
+ for (String prefix : prefixes) {
+ for (String alternative : alternatives) {
+ expanded.add(prefix + alternative);
+ }
+ }
+ return expanded;
+ }
+
+ private static PrefixExpansion expandCharacterClass(String globPattern, int openIndex) {
+ int closeIndex = findClosingBracket(globPattern, openIndex);
+ if (closeIndex < 0 || closeIndex == openIndex + 1) {
+ return null;
+ }
+ int i = openIndex + 1;
+ char first = globPattern.charAt(i);
+ if (first == '!' || first == '^') {
+ return null;
+ }
+ if (containsSurrogate(globPattern, i, closeIndex)) {
+ return null;
+ }
+ List<String> values = new ArrayList<>();
+ while (i < closeIndex) {
+ char current = globPattern.charAt(i);
+ if (current == '\\') {
+ if (i + 1 >= closeIndex) {
+ return null;
+ }
+ values.add(String.valueOf(globPattern.charAt(i + 1)));
+ i += 2;
+ continue;
+ }
+ if (i + 2 < closeIndex && globPattern.charAt(i + 1) == '-') {
+ char rangeEnd = globPattern.charAt(i + 2);
+ int step = current <= rangeEnd ? 1 : -1;
+ for (char ch = current; step > 0 ? ch <= rangeEnd : ch >= rangeEnd; ch += step) {
+ values.add(String.valueOf(ch));
+ if (values.size() > MAX_EXPANDED_GLOB_LIST_PREFIXES) {
+ return null;
+ }
+ }
+ i += 3;
+ continue;
+ }
+ values.add(String.valueOf(current));
+ i++;
+ }
+ return new PrefixExpansion(values, closeIndex + 1);
+ }
+
+ private static int findClosingBracket(String globPattern, int openIndex) {
+ for (int i = openIndex + 1; i < globPattern.length(); i++) {
+ char c = globPattern.charAt(i);
+ if (c == '\\') {
+ i++;
+ continue;
+ }
+ if (c == ']') {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private static boolean containsSurrogate(String text, int start, int end) {
+ for (int i = start; i < end; i++) {
+ if (Character.isSurrogate(text.charAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static PrefixExpansion expandBraceGroup(String globPattern, int openIndex) {
+ int closeIndex = findClosingBrace(globPattern, openIndex);
+ if (closeIndex < 0) {
+ return null;
+ }
+ List<String> alternatives = splitBraceAlternatives(
+ globPattern.substring(openIndex + 1, closeIndex));
+ if (alternatives.isEmpty()) {
+ return null;
+ }
+ List<String> values = new ArrayList<>();
+ for (String alternative : alternatives) {
+ if (containsNumericRange(alternative)) {
+ return null;
+ }
+ List<String> expandedAlternative = expandGlobListPrefixes(alternative, false);
+ if (expandedAlternative == null) {
+ return null;
+ }
+ values.addAll(expandedAlternative);
+ if (values.size() > MAX_EXPANDED_GLOB_LIST_PREFIXES) {
+ return null;
+ }
+ }
+ return new PrefixExpansion(values, closeIndex + 1);
+ }
+
+ private static int findClosingBrace(String globPattern, int openIndex) {
+ int depth = 0;
+ for (int i = openIndex; i < globPattern.length(); i++) {
+ char c = globPattern.charAt(i);
+ if (c == '\\') {
+ i++;
+ continue;
+ }
+ if (c == '[') {
+ int closeBracket = findClosingBracket(globPattern, i);
+ if (closeBracket >= 0) {
+ i = closeBracket;
+ continue;
+ }
+ }
+ if (c == '{') {
+ depth++;
+ } else if (c == '}') {
+ depth--;
+ if (depth == 0) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ private static List<String> splitBraceAlternatives(String content) {
+ List<String> alternatives = new ArrayList<>();
+ int depth = 0;
+ int start = 0;
+ for (int i = 0; i < content.length(); i++) {
+ char c = content.charAt(i);
+ if (c == '\\') {
+ i++;
+ continue;
+ }
+ if (c == '[') {
+ int closeBracket = findClosingBracket(content, i);
+ if (closeBracket >= 0) {
+ i = closeBracket;
+ continue;
+ }
+ }
+ if (c == '{') {
+ depth++;
+ } else if (c == '}') {
+ if (depth == 0) {
+ return Collections.emptyList();
+ }
+ depth--;
+ } else if (c == ',' && depth == 0) {
+ alternatives.add(content.substring(start, i));
+ start = i + 1;
+ }
+ }
+ if (depth != 0) {
+ return Collections.emptyList();
+ }
+ alternatives.add(content.substring(start));
+ return alternatives;
+ }
+
+ private static List<String> compactPrefixes(List<String> prefixes) {
+ List<String> sorted = new ArrayList<>(prefixes);
+ sorted.sort(UTF8_BINARY_ORDER);
+ List<String> compact = new ArrayList<>();
+ for (String prefix : sorted) {
+ if (prefix.isEmpty()) {
+ return List.of("");
+ }
+ boolean covered = false;
+ for (String existing : compact) {
+ if (prefix.startsWith(existing)) {
+ covered = true;
+ break;
+ }
+ }
+ if (!covered) {
+ compact.add(prefix);
+ }
+ }
+ return compact;
+ }
+
+ /**
+ * Compares object keys by unsigned UTF-8 byte order, matching object-store listing order.
+ */
+ public static int compareUtf8Binary(String left, String right) {
+ byte[] leftBytes = left.getBytes(StandardCharsets.UTF_8);
+ byte[] rightBytes = right.getBytes(StandardCharsets.UTF_8);
+ int commonLength = Math.min(leftBytes.length, rightBytes.length);
+ for (int i = 0; i < commonLength; i++) {
+ int result = Integer.compare(
+ Byte.toUnsignedInt(leftBytes[i]), Byte.toUnsignedInt(rightBytes[i]));
+ if (result != 0) {
+ return result;
+ }
+ }
+ return Integer.compare(leftBytes.length, rightBytes.length);
+ }
+
+ /**
+ * Expands bounded {N..M} numeric ranges inside brace groups into comma-separated alternatives.
+ */
+ public static String expandNumericRanges(String pattern) {
+ StringBuilder expanded = new StringBuilder();
+ for (int i = 0; i < pattern.length(); i++) {
+ char c = pattern.charAt(i);
+ if (c == '\\') {
+ expanded.append(c);
+ if (i + 1 < pattern.length()) {
+ expanded.append(pattern.charAt(++i));
+ }
+ } else if (c == '[') {
+ int closeIndex = findClosingBracket(pattern, i);
+ if (closeIndex >= 0) {
+ expanded.append(pattern, i, closeIndex + 1);
+ i = closeIndex;
+ } else {
+ expanded.append(c);
+ }
+ } else if (c == '{') {
+ int closeIndex = findClosingBrace(pattern, i);
+ if (closeIndex >= 0) {
+ expanded.append('{').append(expandNumericBraceGroup(
+ pattern.substring(i + 1, closeIndex))).append('}');
+ i = closeIndex;
+ } else {
+ expanded.append(c);
+ }
+ } else {
+ expanded.append(c);
+ }
+ }
+ return expanded.toString();
+ }
+
+ private static String expandNumericBraceGroup(String content) {
+ List<String> segments = splitBraceAlternatives(content);
+ boolean isMixed = segments.size() > 1;
+ LinkedHashSet<String> values = new LinkedHashSet<>();
+ for (String segment : segments) {
+ Matcher range = numericRangeMatcher(segment, isMixed);
+ if (range == null) {
+ values.add(expandNumericRanges(segment));
+ } else {
+ long from;
+ long to;
+ try {
+ from = Long.parseLong(range.group(1));
+ to = Long.parseLong(range.group(2));
+ } catch (NumberFormatException e) {
+ return content;
+ }
+ long cardinality = numericRangeCardinality(from, to);
+ if (cardinality < 0 || cardinality > MAX_EXPANDED_GLOB_LIST_PREFIXES - values.size()) {
+ return content;
+ }
+ long step = from <= to ? 1L : -1L;
+ boolean zeroPad = hasLeadingZero(range.group(1)) || hasLeadingZero(range.group(2));
+ int width = Math.max(digitWidth(range.group(1)), digitWidth(range.group(2)));
+ for (long offset = 0; offset < cardinality; offset++) {
+ long value = step > 0 ? from + offset : from - offset;
+ values.add(formatRangeValue(value, width, zeroPad));
+ }
+ }
+ if (values.size() > MAX_EXPANDED_GLOB_LIST_PREFIXES) {
+ return content;
+ }
+ }
+ return String.join(",", values);
+ }
+
+ private static Matcher numericRangeMatcher(String alternative, boolean isMixed) {
+ Matcher matcher = NUMERIC_RANGE_ALTERNATIVE.matcher(isMixed ? alternative.trim() : alternative);
+ if (!matcher.matches() || (!isMixed
+ && (matcher.group(1).startsWith("-") || matcher.group(2).startsWith("-")))) {
+ return null;
+ }
+ return matcher;
+ }
+
+ private static boolean containsNumericRange(String text) {
+ return NUMERIC_RANGE_PATTERN.matcher(text).find();
+ }
+
+ private static long numericRangeCardinality(long from, long to) {
+ try {
+ long distance = from <= to
+ ? Math.subtractExact(to, from)
+ : Math.subtractExact(from, to);
+ return Math.addExact(distance, 1L);
+ } catch (ArithmeticException e) {
+ return -1L;
+ }
+ }
+
+ private static boolean hasLeadingZero(String value) {
+ String digits = value.startsWith("-") ? value.substring(1) : value;
+ return digits.length() > 1 && digits.charAt(0) == '0';
+ }
+
+ private static int digitWidth(String value) {
+ return value.startsWith("-") ? value.length() - 1 : value.length();
+ }
+
+ private static String formatRangeValue(long value, int width, boolean zeroPad) {
+ if (!zeroPad) {
+ return Long.toString(value);
+ }
+ if (value == Long.MIN_VALUE) {
Review Comment:
[P2] Preserve zero padding for the minimum long value
The early return skips the padding loop even when the requested width exceeds 19 digits. For the valid mixed range `data_{-09223372036854775808..-09223372036854775807,x}.csv`, both endpoints parse as longs, the cardinality is 2 and the digit width is 20, but normalization emits `-9223372036854775808` for the first arm and keeps the leading zero for the second. Consequently Azure/S3 listing and `compileGlobPattern` omit the correctly padded minimum key and accept its unpadded counterpart. The BigInteger regex fallback preserves this width, so behavior also differs between normalization paths. Derive magnitude digits without negating `Long.MIN_VALUE`, then apply the common padding logic to this value as well.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org