mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-09-13 00:42:14 +00:00
ci/backport-issue-assignee
5019
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ab0b1f5cce |
fix: bump jemalloc crates to 0.7 and patch tikv-jemalloc-sys with tcache init fix (#9103)
* fix: bump jemalloc crates to 0.7 and patch tikv-jemalloc-sys with tcache init fix Upgrade tikv-jemallocator / tikv-jemalloc-ctl / tikv-jemalloc-sys from 0.6 to 0.7, which embeds jemalloc 5.3.1 (includes a056c20d 'Handle tcache init failures gracefully'). On top of that, patch tikv-jemalloc-sys to the GreptimeTeam fork that adds the remaining upstream fix 54f22c83 'Initialize TSD tcache before enabling it' (GreptimeTeam/jemalloc#1, GreptimeTeam/jemallocator#1). Without the ordering fix, a reentrant allocation during TSD bootstrap (e.g. heap-profiling prof_tdata init / sampled backtrace when prof:true is active) can observe an enabled-but-uninitialized tcache, corrupting per-thread tcache metadata and crashing the process in arena_stats_merge, calloc, or the libgcc unwinder. The patch is pinned by rev and should be removed once tikv/jemallocator ships a jemalloc snapshot that includes 54f22c83. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * chore: bump tikv-jemalloc-sys patch rev to merged release-5.3.1 GreptimeTeam/jemalloc#1 has been merged; point the patch at the jemallocator commit referencing the merge commit on release-5.3.1. Jemalloc source content is unchanged. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * chore: point tikv-jemalloc-sys patch at GreptimeTeam/jemallocator main GreptimeTeam/jemallocator#1 has been merged; reference the merge commit e1846d8c on main instead of the PR head branch. Jemalloc source content is unchanged. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(servers): bump tikv-jemallocator dev-dependency to 0.7 main added a target.'cfg(not(windows))'.dev-dependencies entry on tikv-jemallocator 0.6 for servers after this branch diverged. On the merge ref it pulled tikv-jemalloc-sys 0.6 from crates.io, which conflicts with the patched 0.7 (links = "jemalloc" may only appear once in the dependency graph), failing version selection in CI. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> --------- Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> |
||
|
|
fa128adb8e |
feat: support request-level insert WAL skipping (#9088)
* refactor: add skip_wal fields to internal write requests Signed-off-by: WenyXu <wenymedia@gmail.com> * chore(deps): update greptime-proto for insert skip_wal Signed-off-by: WenyXu <wenymedia@gmail.com> * feat(mito): support request-level WAL skipping Signed-off-by: WenyXu <wenymedia@gmail.com> * feat(metric-engine): handle request-level WAL policies Signed-off-by: WenyXu <wenymedia@gmail.com> * feat: propagate insert WAL policy through query context Signed-off-by: WenyXu <wenymedia@gmail.com> * feat: support session-level insert WAL policy via SET Signed-off-by: WenyXu <wenymedia@gmail.com> * fix(metric-engine): require uniform WAL policy in batch puts Signed-off-by: WenyXu <wenymedia@gmail.com> * test(metric-engine): simplify WAL policy coverage Signed-off-by: WenyXu <wenymedia@gmail.com> * refactor(servers): simplify gRPC hint extraction Signed-off-by: WenyXu <wenymedia@gmail.com> * test: flatten Mito and Metric WAL scenario orchestration Signed-off-by: WenyXu <wenymedia@gmail.com> * refactor: separate WAL and memtable-only mutations Signed-off-by: WenyXu <wenymedia@gmail.com> * refactor: carry skip-WAL policy in table insert requests Signed-off-by: WenyXu <wenymedia@gmail.com> * test: flatten skip-WAL policy cases Signed-off-by: WenyXu <wenymedia@gmail.com> * refactor: clarify WAL notifier naming Signed-off-by: WenyXu <wenymedia@gmail.com> * chore: pin merged skip-WAL proto revision Signed-off-by: WenyXu <wenymedia@gmail.com> --------- Signed-off-by: WenyXu <wenymedia@gmail.com> |
||
|
|
536f42e4a2 |
feat(json2): support ALTER syntax for JSON column settings (#9094)
feat(json2): support alter syntax for JSON2 columns Signed-off-by: fys <fengys1996@gmail.com> This is the commit message #3: |
||
|
|
0f625a7e92 |
fix(promql): correct counter reset accumulation in rate windows (#9089)
* fix(promql): correct counter reset accumulation in rate windows `prom_rate` and `prom_increase` reused the previous window's counter-reset correction when the next window slid forward by exactly one sample, adding the entering reset and subtracting the leaving one. Running a sum through addition and subtraction does not restore the earlier terms in f64: a large reset absorbs the smaller ones that must survive it, and an expired infinity leaves a NaN that no later window can clear. `prom_delta` shares the code but is not a counter function, so it never took that path. Index the reset positions of the value array once instead, and reduce each window over the resets it contains, in sample order. The result is bit-identical to scanning the window directly, so windows keep the direct reduction when they request fewer sample pairs than the input has. Also sweep the query step in the rate benchmarks: the cost of the reset correction depends on how much the windows overlap, which no existing case varied. Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> * test(promql): cover counter reset precision over adjacent rate windows The unit tests build the range windows directly, so they do not show that a plain PromQL range query produces the window layout that lost the correction. This case does: with a query step equal to the sample interval, `increase` over the second window returns 1.333 before the fix and 2.667 after it. Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> * perf(promql): advance the counter reset bounds instead of searching Locating a window's resets with two binary searches costs more than the reduction it replaces once a series resets often enough for the searches to get deep: on a 20k-sample counter resetting every 37 samples, stepping the windows by one sample was 2.7x slower than the previous code, against 1.2x for a counter that never resets. Windows normally advance, so walk the bounds forward from the previous window and only search when they move back. The cost then no longer depends on the reset density. Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> * perf(promql): cut the per-window cost of the counter reset index Two costs the index added showed up on a one-sample query step, where the removed fast path used to answer each window with two comparisons. Cache the two reset positions that bound the active slice. A window that only advanced and reached neither of them covers the same resets as the previous one, so the common case is four integer comparisons and no lookup at all. Stop summing the requested sample pairs once they exceed one pass over the values. The sum only decides which side of that comparison the input falls on, and a query with a short lookback and a long step settles it after a few windows instead of after every key. Together these take the one-sample step from 25-32% slower than the previous code down to 6-11%, measured as before / after / before to bound drift. No other step value regresses, and a ten-sample step stays about 88% faster. Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> * fix(promql): accumulate counter resets into the running result `prom_rate` and `prom_increase` summed a window's counter-reset corrections on their own and added that sum to `last - first`. Prometheus folds each reset into the running result instead, and so did this code before #7880. The two are not interchangeable in f64: over samples `[1e16, 1, 0, 1]` the isolated sum rounds `1e16 + 1.0` back to `1e16`, which then cancels against the first sample and reports no increase at all, where folding the resets in one at a time keeps the 1.0. Restore the original order. The reset index accumulates into the result the same way, so it still matches a direct scan of the window bit for bit, but a window's contribution can no longer be cached as a standalone value and is re-added from its own difference each time. The bounds are still cached, so a window that did not cross a reset skips the lookup, and one that holds no resets returns without touching the index at all. Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> * test(promql): note which reset boundaries the stride of one walks Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> --------- Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> |
||
|
|
adda50e03f |
feat: add repartition partition count hint (#9080)
Signed-off-by: WenyXu <wenymedia@gmail.com> |
||
|
|
2d78220a4f |
fix(flow): drain frontend probe response before selecting peer (#9082)
* fix(flow): drain frontend probe response before selecting peer Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * refactor(flow): reuse record batch collector for frontend probe Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> --------- Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> |
||
|
|
2933f95672 |
perf(servers): drop the output sort for Prometheus range queries (#9090)
* perf(servers): drop the output sort for Prometheus range queries Matrix responses sort samples by timestamp and series by labels while serializing, so the sort the PromQL planner puts at the root of a range query plan never reaches the client. Mark the query as not requiring output ordering in `do_range_query`, and let the frontend strip the root sort (through projections, and only when it carries no fetch) before execution. Instant queries are unchanged, so `sort()` and `sort_desc()` keep their observable order. Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> * test(servers): pin the matrix response against input row order Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> * test(servers): drop redundant response assertions in the ordering test Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> * perf(servers): drop the output sort for gRPC gateway range queries Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> --------- Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> |
||
|
|
60899d19ee |
perf(servers): defer Prometheus sample value formatting to serialization (#9091)
Building a matrix response allocated one `String` per sample while the record batches were scanned, then dropped it after the JSON body was written. Keep the `f64` in `PromSampleValue::Number` instead and format it with ryu while serializing, so no per-sample string is allocated. `PromSampleValue::Text` keeps values parsed from a JSON body, so deserializing and re-serializing a response is unchanged. Vector and scalar results still expose `String`, since they hold a single sample. Signed-off-by: Dennis Zhuang <xzhuang@greptime.com> |
||
|
|
38577c8854 |
refactor: support plugin-backed admin functions (#9083)
* feat: add bulk load SQL extension points Add `CREATE BULK LOAD` parsing and `BulkLoadHandler` dispatch. Expose private system table factories through `src/catalog`. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * refactor: support plugin-backed admin functions Replace the custom bulk-load SQL hooks with access to process `Plugins` through `FunctionState`. Preserve typed external errors from ADMIN functions in `src/operator/src/error.rs`. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> --------- Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> |
||
|
|
6fa1023b7f |
feat(mito2): introduce TWCS active window compaction (#9011)
* feat(mito2): support independent TWCS trigger_file_num for active and inactive windows Split the single TWCS trigger_file_num into per-window-state thresholds: the active window keeps the existing trigger (default 4, legacy compaction.twcs.trigger_file_num stays a compatible alias), while inactive windows use a new trigger (default 2). Inactive windows additionally fall back from balanced L0-only/L1-only candidates to a progress-making unbalanced mixed candidate so historical windows can converge; the active window retains the row/byte balance guards. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(mito2): bound inactive TWCS window convergence by rewrite budget Inactive windows that cannot compact within one level previously either stayed stuck (a threshold-qualified but unbalanced level returned no candidate without trying any fallback) or fell back to a mixed merge with no balance checks at all, which could rewrite a huge compacted file to absorb tiny fresh files. Inactive windows now converge progressively: threshold-qualified balanced picks, sub-threshold balanced single-level picks, a mixed merge whose total rewrite must fit in the output file budget, and finally an L0-only merge without balance checks. Windows that qualify for none of these are left uncompacted, bounding write amplification. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * test(mito2): cover TWCS window trigger options in alter_table_options sqlness case Exercise SET/UNSET of compaction.twcs.active_window.trigger_file_num and compaction.twcs.inactive_window.trigger_file_num end to end, including that setting the canonical active key removes the legacy compaction.twcs.trigger_file_num alias from the table options. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(mito2): derive TWCS active window from the max-sequence file The active window was determined by the max event-time window among level-0 files. Between an L0 compaction removing its inputs and the next flush landing, level 0 is empty, so the active window transiently became None and every window fell back to the inactive rules - triggering full-window convergence merges during ongoing ingestion whose outputs are then superseded by new data. Flush and compaction outputs both inherit the max input sequence, so the file with the highest sequence across all levels always tracks the most recent write. Use its window as the active window, falling back to the previous L0-based rule when no file carries a sequence (legacy files). The new helper deliberately computes window keys with the assign_to_windows convention (truncate to seconds, then align up), because the result is compared against window keys produced there; the older ceil-based helper is kept unchanged for the legacy fallback path. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * feat(mito2): add active-window L1 compaction safety trigger Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * test(compat): cover TWCS active window options Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(mito2): align TWCS window trigger validation Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(mito2): resolve database TWCS trigger aliases Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(mito2): prioritize newer compaction windows Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(mito2): repick serial compaction outputs Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * feat(mito2): configure inactive-window L1 trigger Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * feat(mito2): prioritize TWCS compaction candidates Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(meta): preserve TWCS trigger downgrade compatibility Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(sql): distinguish invalid database option values Separate database option key and value validation so recognized keys report the invalid value and its constraint. Add parser coverage for invalid, valid, and unknown options. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * docs(meta): explain TWCS legacy key compatibility Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * refactor(mito2): clarify active window trigger field Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(options): normalize TWCS trigger aliases Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(mito2): ignore ineligible files for active window Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(mito2): mark explicit TWCS options as overrides Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(mito2): normalize zero compaction output size Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(options): validate database TWCS trigger values Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * style(store-api): collapse TWCS alias conflict condition Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> --------- Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> |
||
|
|
7cf84892d2 |
perf(table): filter decoded rows with dynamic predicates (#9004)
* perf(table): filter decoded rows with dynamic predicates Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(table): preserve unknown dynamic filter rows Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * refactor(table): use null guards for dynamic filters Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(table): preserve null inputs during dynamic pruning Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(perf): cover frontend join dynamic filter transfer Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(table): reset dynamic filters and scanner pruning state Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> --------- Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> |
||
|
|
da5cb1a190 |
perf(promql): push down last row for instant queries (#9034)
* perf(promql): push down last row for instant queries Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test: guard instant last row correctness Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test: update instant query explain results Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix: apply last row after source deduplication Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix: scope post-merge last row selection Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(perf): cover instant PromQL last row Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(perf): sort generated SST rows before writing Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(promql): cover instant last row selection in sqlness Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(promql): avoid last row hints for lossy timestamp casts Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(promql): preserve stale marker semantics across flushes Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(promql): decode dictionary labels in stale regression Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(promql): avoid reserved column name in stale fixture Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(promql): exercise LastRow hints and filtered results Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * refactor: keep after-merge mode in LastRow selector Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix: reject instant LastRow across residual filters Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test: expect after-merge selector in instant vector guards Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * docs: explain instant LastRow filter eligibility Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix: restrict instant LastRow to safe selector nodes Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * refactor: show LastRow merge mode directly in diagnostics Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test: refresh LastRow display in explain expectations Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> --------- Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> |
||
|
|
c65a4e545e |
feat: make the series index resilient to time index unit widening (#8996)
* feat: record time unit per series index file The series index stores __series_min_ts/__series_max_ts as raw i64 in the time index unit at write time, but the searcher built its range predicates from the region's current unit, so files written before a time index unit widening would be compared in the wrong unit. Record the unit in the min/max ts fields' Arrow metadata when writing and build the per-file time predicates from it when searching, so each file is interpreted in the unit it was written with. The writer now also requires a timestamp time index. Signed-off-by: Ning Sun <sunning@greptime.com> * fix: address review comments on series index time units - split schema validation (validate_index_schema) from unit extraction (index_time_unit), distinguishing missing vs unsupported unit metadata in the errors instead of one misleading 'missing a valid metadata' - encode the recorded unit with an explicit exhaustive match rather than Debug formatting, so the on-disk encoding is reviewed next to its parser - extract time_index_unit to drop the unwrap in series_index_schema and the duplicated timestamp-time-index ensure in validate_metadata - test one searcher reading files with different recorded units, and the rejection of missing, unknown and mismatched units Signed-off-by: Ning Sun <sunning@greptime.com> * refactor: reuse TimeUnit's Display form for the recorded unit string common_time::timestamp::TimeUnit already implements Display with the exact strings the series index records ("Second"/"Millisecond"/ "Microsecond"/"Nanosecond"), so drop the local time_unit_as_str mapping and use it; the parse side stays local since no FromStr counterpart exists anywhere yet. Signed-off-by: Ning Sun <sunning@greptime.com> * feat: parse TimeUnit from its Display form in common-time Add FromStr for common_time::timestamp::TimeUnit, accepting exactly the Display form ("Second"/"Millisecond"/"Microsecond"/"Nanosecond") and failing with a new UnsupportedTimeUnit error (InvalidArguments). The series index now records and parses the unit with the common codec, dropping its local parse_time_unit. Signed-off-by: Ning Sun <sunning@greptime.com> * feat: parse TimeUnit case-insensitively Lowercase the input before matching so "millisecond" and "MILLISECOND" parse like "Millisecond"; the error still reports the original string. Signed-off-by: Ning Sun <sunning@greptime.com> * feat: store series index min/max timestamps as native Timestamp columns Replace the Int64 min/max columns plus 'time_unit' field metadata with native Timestamp(unit) columns, so the unit rides on the datatype and each file is interpreted in the unit it was written with naturally. - series_index_schema types the columns from the time index unit; the writer reinterprets the raw i64 series bounds in that type (arrow's Int64->Timestamp cast reinterprets, it does not rescale) - the searcher reads the unit from each file's column datatype, builds Timestamp-typed predicates via datatypes' timestamp_to_scalar_value, and reinterprets parquet INT64 statistics in the column type so row-group pruning compares like-typed values - index files whose min/max columns are not Timestamp (written before this change) are rejected - the pruning test now asserts time-range predicates prune row groups, not just tag predicates Signed-off-by: Ning Sun <sunning@greptime.com> * refactor: drop the TimeUnit string codec from common-time With the unit carried by the Timestamp datatype, the FromStr impl and UnsupportedTimeUnit error added for the field-metadata approach have no consumer; remove them. Signed-off-by: Ning Sun <sunning@greptime.com> * refactor: fold index file validation into a single pass The series index format is unreleased and unwired, so no compatibility classes are needed: validate_index_schema checks all columns and returns the min/max columns' unit directly, replacing the separate index_time_unit extraction. Signed-off-by: Ning Sun <sunning@greptime.com> * refactor: carry timestamps through SeriesIndexRow SeriesIndexRow and the aggregation path now hold common_time::Timestamp instead of raw i64s: timestamp_values interprets the input column in the writer's unit (rejecting a timestamp array whose unit differs, instead of silently reinterpreting it), and rows_to_batch builds the native Timestamp columns directly from the rows' units without an Int64 round trip through arrow cast. Signed-off-by: Ning Sun <sunning@greptime.com> * fix: require a timestamp time index column in series index input The writer already refuses non-timestamp time indexes on the metadata side, and its input batches always carry the region's ts column as a timestamp array, so accepting plain Int64 columns only left a silent unit-interpretation hole; reject them instead. Signed-off-by: Ning Sun <sunning@greptime.com> * refactor: rescale series index input timestamps into the file unit The input array's unit is self-describing, so converting with Timestamp::convert_to cannot mislabel values; a mismatch no longer needs to be an error. Only a value that overflows the file's unit fails the write. This also makes the writer ready to aggregate old-unit batches after a time index widening. Signed-off-by: Ning Sun <sunning@greptime.com> * refactor: drop redundant unit checks in series index writer The alter path flushes memtables before widening the region's time index unit, so a writer never receives batches in the region's previous unit. Reject a unit mismatch at the input boundary instead of rescaling per value, and build the index batch in the writer's recorded unit instead of re-deriving it from the schema and re-checking every row. Signed-off-by: Ning Sun <sunning@greptime.com> * fix: address review comments --------- Signed-off-by: Ning Sun <sunning@greptime.com> |
||
|
|
27ea5dfb91 |
feat(auth): support per-user MySQL authentication methods (#9078)
Signed-off-by: shuiyisong <xixing.sys@gmail.com> |
||
|
|
6b9165f633 |
fix(servers): return text[] for SELECT array[null] in PostgreSQL protocol (#9058)
fix(servers): return text array for null array literals Signed-off-by: Tyagiquamar <mohdquamartyagi@gmail.com> |
||
|
|
4fd35462d6 |
fix(prometheus): align batch flush deadline with creation (#8802)
* fix(prometheus): align batch flush deadline with creation Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * test(servers): sync pending worker submission with explicit ack Replace the mpsc capacity() polling in the pending rows batcher deadline test with a test-only WorkerCommand::Ack round trip. The FIFO channel guarantees the worker has dequeued and processed the submission (and anchored the flush deadline) before the test advances virtual time, removing reliance on an implementation detail that can be flaky under scheduling variance. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * test(servers): await pending worker flush results with bounded timeout Replace the try_recv() yield-polling loop in the pending rows batcher deadline test with a direct await bounded by tokio::time::timeout. Under paused time the timeout auto-advances the clock and fires deterministically, so the test fails reliably instead of intermittently missing the result on slower CI or under contention. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> --------- Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> |
||
|
|
6fb5d2ebad |
feat(mito2): add series index catalog and lifecycle foundation (#9053)
* refactor(mito2): add series index catalog and lifecycle components Signed-off-by: evenyag <realevenyag@gmail.com> * feat(mito2): restore series index catalogs on region open Signed-off-by: evenyag <realevenyag@gmail.com> * refactor(mito2): simplify series index foundation and maintenance Signed-off-by: evenyag <realevenyag@gmail.com> * refactor(mito2): separate series index purge task and simplify tests Signed-off-by: evenyag <realevenyag@gmail.com> * docs: defer experimental series index configuration examples Signed-off-by: evenyag <realevenyag@gmail.com> * feat(mito): make series index maintenance interval configurable Signed-off-by: evenyag <realevenyag@gmail.com> * fix(mito2): correct series index cleanup on close and drop Signed-off-by: evenyag <realevenyag@gmail.com> * test(mito2): revert drop test changes Signed-off-by: evenyag <realevenyag@gmail.com> * test: update config API expectation for series index settings Signed-off-by: evenyag <realevenyag@gmail.com> * refactor: use tokio unbounded channel for series index purger Signed-off-by: evenyag <realevenyag@gmail.com> * chore(mito2): simplify review test scope and clarify index config Signed-off-by: evenyag <realevenyag@gmail.com> --------- Signed-off-by: evenyag <realevenyag@gmail.com> |
||
|
|
b46de8c828 |
feat(telemetry): add log directory size retention (#8997)
* feat(telemetry): add log directory size retention Signed-off-by: WenyXu <wenymedia@gmail.com> * test: update config API logging fixture Signed-off-by: WenyXu <wenymedia@gmail.com> * fix(telemetry): recover log retention state Signed-off-by: WenyXu <wenymedia@gmail.com> * fix(telemetry): handle log retention cleanup errors Signed-off-by: WenyXu <wenymedia@gmail.com> * test(telemetry): cover log count retention on rotation Signed-off-by: WenyXu <wenymedia@gmail.com> * test(telemetry): cover log directory retention Signed-off-by: WenyXu <wenymedia@gmail.com> * perf(telemetry): avoid log filename allocation Signed-off-by: WenyXu <wenymedia@gmail.com> --------- Signed-off-by: WenyXu <wenymedia@gmail.com> |
||
|
|
be482553b0 |
fix(mito2): harden flat merge and use winner_tree (#9064)
* fix(mito2): reject non-flat batches in flat merge instead of panicking - SortColumns::new becomes fallible try_new: batches missing the flat-format internal columns (time index, __primary_key, __sequence) at the fixed trailing positions now yield InvalidRecordBatch instead of a downcast panic, completing the generic-schema gate that only covered BatchBuilder output assembly. Document the flat-format input contract on FlatMergeIterator/FlatMergeReader. - Clarify why BatchBuilder's schema gate uses >= 3 columns when a real flat-format schema always has at least 4. - Add schema-structure tests: empty primary keys (tables without tags), dictionary-encoded string tag columns with per-source dictionaries, and graceful rejection of batches without internal columns. Signed-off-by: Lei, HUANG <mrsatangel@gmail.com> * test(mito2): scan tables with various schemas through flat merge Add an engine-level test that writes, flushes and scans regions without tags (empty primary key) and with multiple string tags (dictionary-encoded in the flat input schema), so the flat merge reader merges an SST with the memtable on real schemas instead of hand-built batches. Signed-off-by: Lei, HUANG <mrsatangel@gmail.com> * refactor(mito2): use winner_tree dependency Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * Update comments for FlatMergeIterator struct Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Signed-off-by: Lei, HUANG <mrsatangel@gmail.com> Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
ad5ccc98ec |
fix(cli): sanitize store_addrs in kvbackend build log (#8967)
* fix(cli): sanitize store_addrs in kvbackend build log Close #7525. The CLI's kvbackend construction log was printing raw store_addrs which could contain sensitive connection strings (e.g. PostgreSQL DSNs with passwords). Changes: - Add sanitize_store_addrs() helper that reuses common_meta::kv_backend::util::sanitize_connection_string(), consistent with MetasrvOptions and StartCommand patterns. - Replace raw store_addrs in the info! log with sanitized version. - Add unit tests covering MySQL URLs, PostgreSQL DSNs, etcd addresses, and empty store_addrs cases. Signed-off-by: qiang_liu Signed-off-by: qiang_liu <qiang_liu@trendmicro.com> Signed-off-by: LiuQhahah <liuqiang9596@gmail.com> * fix(cli): drop redundant sanitize tests per review sanitize_connection_string in common_meta already covers MySQL URLs, PostgreSQL DSNs and credential-free etcd addresses with its own tests. The added tests only exercised a trivial map+collect wrapper, so remove them per review nit. Signed-off-by: LiuQhahah <liuqiang9596@gmail.com> --------- Signed-off-by: qiang_liu Signed-off-by: qiang_liu <qiang_liu@trendmicro.com> Signed-off-by: LiuQhahah <liuqiang9596@gmail.com> Co-authored-by: dennis zhuang <killme2008@gmail.com> |
||
|
|
307fe0a692 |
feat(mito2): adapt bulk memtable encode threshold to write buffer size (#9056)
* feat(mito2): adapt bulk memtable encode bytes threshold to write buffer size The default encode_bytes_threshold is now max(64MB, min(global_write_buffer_size / 32, 512MB)) instead of a fixed 64MB, so it scales with the memtable budget. GREPTIME_BULK_ENCODE_BYTES_THRESHOLD and the per-region option still override the default. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * test(mito2): clarify binary units in bulk threshold test The threshold test uses powers of 1024, so label its values as MiB and GiB instead of decimal MB and GB. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * refactor(mito2): resolve bulk encode threshold in memtable provider Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> --------- Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> |
||
|
|
9a65561226 |
feat(auth): support bearer token authentication over SQL protocols (#8899)
* chore: add mysql and pg auth method choose hook Signed-off-by: shuiyisong <xixing.sys@gmail.com> * feat(auth): support bearer token authentication over SQL protocols Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: fix CR issues Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix(mysql): authenticate bearer tokens in the handshake catalog Signed-off-by: shuiyisong <xixing.sys@gmail.com> --------- Signed-off-by: shuiyisong <xixing.sys@gmail.com> |
||
|
|
88d43ee648 | feat: update dashboard to v0.13.15 (#9051) | ||
|
|
35f5485974 |
feat(meta): record logical-table reconciliation events (#8941)
* feat(meta): add logical table reconciliation events Signed-off-by: dhruvxvaishnav <dhruvvaishnav687@gmail.com> * fix(meta): preserve logical reconciliation progress Signed-off-by: dhruvxvaishnav <dhruvvaishnav687@gmail.com> * fix(meta): preserve logical region retry progress Signed-off-by: dhruvxvaishnav <dhruvvaishnav687@gmail.com> * fix(meta): simplify logical reconciliation events Signed-off-by: dhruvxvaishnav <dhruvvaishnav687@gmail.com> * test(meta): assert logical event values Signed-off-by: dhruvxvaishnav <dhruvvaishnav687@gmail.com> --------- Signed-off-by: dhruvxvaishnav <dhruvvaishnav687@gmail.com> |
||
|
|
9940de4917 |
feat: add scanbench query suites and structured results (#9050)
* perf: add scanbench partition diagnostics Port benchmark source and documentation from c5dd5e6356a8903f1dcf493eb46dc318612dc953. Exclude the Mito metrics changes. Signed-off-by: evenyag <realevenyag@gmail.com> * feat: support scanbench query suites Signed-off-by: evenyag <realevenyag@gmail.com> (cherry picked from commit def9c22069b0d29c611695a68ad1b31110c845cb) Signed-off-by: evenyag <realevenyag@gmail.com> * docs: align scanbench port with existing engine metrics Remove documentation and fixture references to unported Mito metrics. Enable dev-tools in the build example and remove the obsolete force-flat-format option. Signed-off-by: evenyag <realevenyag@gmail.com> --------- Signed-off-by: evenyag <realevenyag@gmail.com> |
||
|
|
4c12ea1aba |
chore(deps): bump opendal to 0.58.1 (#8742)
* chore(deps): bump opendal to 0.58.1 Upgrade direct opendal dependency and workspace object_store_opendal pin from 0.57 to 0.58 (lockfile resolves opendal 0.58.1 / object_store_opendal 0.58.0). Adapt to OpenDAL 0.58 composition API: - Operator::new returns a finished operator; drop .finish() call sites - Replace HttpClientLayer / raw::HttpClient with OperationContext + HttpTransporter (ReqwestTransport) - Migrate SecureFsBackend and MockLayer from Access/LayeredAccess to Service + Layer::apply_service - Rewrite SecureFs reader/writer/lister for sync factories and StreamRead - Use OperatorInfo::capability() instead of removed native_capability() Signed-off-by: Xuanwo <github@xuanwo.io> Signed-off-by: WenyXu <wenymedia@gmail.com> * chore: retrigger CI after udeps runner segfault Signed-off-by: Xuanwo <github@xuanwo.io> Signed-off-by: WenyXu <wenymedia@gmail.com> * fix(object-store): restore suffix read simulation for secure fs Signed-off-by: WenyXu <wenymedia@gmail.com> * fix: adapt remaining callers to OpenDAL 0.58 Signed-off-by: WenyXu <wenymedia@gmail.com> --------- Signed-off-by: Xuanwo <github@xuanwo.io> Signed-off-by: WenyXu <wenymedia@gmail.com> Co-authored-by: WenyXu <wenymedia@gmail.com> |
||
|
|
bb9b7e8778 |
fix: re-scan stream-backed tables in recursive CTEs (#9039)
* fix: re-scan stream-backed tables in recursive CTEs A recursive CTE re-executes its recursive term on every iteration, but DfTableProviderAdapter hands StreamScanAdapter a single-use stream built at planning time. The second iteration failed with "Stream already exhausted" for every table served through DataSource::get_stream — information_schema, pg_catalog, the computed entity-graph tables and numbers. Keep that stream for the first execution and open a new one over the same scan request for later executions. Closes #9037 Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * refactor: drop redundant binding in stream factory Signed-off-by: Dennis Zhuang <killme2008@gmail.com> --------- Signed-off-by: Dennis Zhuang <killme2008@gmail.com> |
||
|
|
765ed7865f |
feat(client): compress insert transport (#9036)
* feat(client): compress bulk insert transport Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * feat(client): compress row insert transport Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix: address comments Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> --------- Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> |
||
|
|
c3ea022de5 |
perf(mito2): blazing-fast tournament tree merger (#8989)
* perf(mito2): optimize flat merge heap and primary-key interleave Replace the per-row BinaryHeap pop/push cycle in FlatMerge with an in-place root mutation plus a single sift-down repair on a custom RootHeap, keeping the cold heap and direct-batch fast path unchanged. Fallible or awaiting batch transitions move the hot node out of the heap first, preserving error and cancellation semantics. Exploit the globally sorted merge output to build the internal Dictionary<UInt32, Binary> primary-key column with a one-pass ordered gather: append a Binary value only when the PK changes and reuse the current key for adjacent equal PKs, bypassing Arrow dictionary masks, hash interning and key remapping. Non-PK columns still use Arrow interleave. Also cache the current primary-key byte range in RowCursor to avoid repeated dictionary range decoding during comparisons, and add a setup-free Criterion benchmark with exact output-row assertions. 32-way/1 row-per-series/40-tag improves 955.79ms -> 562.36ms (-41.2%); 0-tag -39.5%, 64 rows/series -79.8%, 8-way -56.1%, single-iterator control +0.3%. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * test(mito2): add rows-per-series sweep to flat merge bench Add 32-way/40-tag shapes for 1, 10, 100, 1000 and 10000 rows per series, and allow FLAT_MERGE_BENCH_SHAPE to match shape name prefixes so the whole sweep can run in one invocation. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * test(mito2): add oracle-based correctness tests for RootHeap Drive RootHeap and a std BinaryHeap oracle with the same seeded op sequence (push / pop / mutate-root + repair) and assert peek, len, best_child and the full drain order after every operation. A second run with a tiny value range makes duplicates dominate, covering the equal-key branches of sift_up/sift_down and best_child. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * perf(mito2): replace hot heap with a tournament tree in flat merge Replace the hot RootHeap with a fixed-capacity tournament (winner) tree over per-node slots: every internal node caches the champion of its subtree, so advancing the winner only replays the ~log2(k) nodes on its leaf-to-root path with one compare per level, instead of the heap's two-compares-per-level sift that also re-compares the same node pairs on every row. Two fast paths keep dense shapes at O(1) per row: - champion retention: after mutating the winner in place, skip the replay entirely when it still beats the runner-up (its path caches are unchanged by construction); - a second-best slot cache, invalidated on any structural change, so the retention check costs a single compare without walking the tree. The cold heap, hot/cold overlap window, direct-batch fast path and the remove-before-fallible-fetch batch transition semantics are unchanged. Vs the RootHeap version: 1rps/32way/40tag -19.7%, 0tag -34.4%, 8way -15.9%, 64rps -30.5%, sweep 10/100/1000/10000rps -29~32%; vs the original BinaryHeap baseline the main shape is -52.8%. The single-iterator control is +8% (+50ns one-time construction allocation, no merge work). Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(mito2): support generic schemas in flat merge Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix(mito2): satisfy clippy in flat merge benchmark Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * perf(mito2): cache flat merge primary key index Compute the internal primary-key column index once when constructing BatchBuilder and reuse it for every output batch. Preserve the column-name gate for generic schemas. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * test(mito2): benchmark high-fan-in flat merges Add sparse 64, 128, 256, and 512-way merge shapes while keeping the total input fixed at 3.2 million rows. Compared with the merge-base heap implementation, median time improves by 56.0%, 60.8%, 55.6%, and 56.1%, respectively. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> --------- Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> |
||
|
|
54fcf36452 |
fix(frontend): isolate internal Flight authentication (#9045)
Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> |
||
|
|
fa794fae7a |
fix: match system schema names case-insensitively (#9040)
* fix: match system schema names case-insensitively Database names that arrive over a protocol (the MySQL handshake and COM_INIT_DB, the Postgres startup parameter, the HTTP `db` parameter, the gRPC dbname header) never reach the SQL parser, which is what lowercases unquoted identifiers. Since #8062 stopped lowercasing them wholesale, connecting to `INFORMATION_SCHEMA` in any spelling but the canonical one fails with "Unknown database" -- including the `USE <db>` that a MySQL client turns into COM_INIT_DB. Fold only system schema names to their canonical spelling, so user schema names keep the case they were created with. `is_reserved_schema_name` uses the same match, otherwise a quoted `CREATE DATABASE "INFORMATION_SCHEMA"` creates a schema shadowed by the system one. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * refactor: hoist system schema names into a const Signed-off-by: Dennis Zhuang <killme2008@gmail.com> --------- Signed-off-by: Dennis Zhuang <killme2008@gmail.com> |
||
|
|
a932433d21 |
fix(wal): bound Kafka requests and extend latency buckets (#9026)
* fix(wal): bound Kafka requests and extend latency buckets Signed-off-by: WenyXu <wenymedia@gmail.com> * chore(wal): update rskafka request timeout revision Signed-off-by: WenyXu <wenymedia@gmail.com> * docs(config): document Kafka WAL timeouts in MetaSrv Signed-off-by: WenyXu <wenymedia@gmail.com> * style: sort common-wal dev dependencies Signed-off-by: WenyXu <wenymedia@gmail.com> --------- Signed-off-by: WenyXu <wenymedia@gmail.com> |
||
|
|
d67d3501a9 |
fix(json2): keep empty structs in remainder (#9027)
Signed-off-by: luofucong <luofc@foxmail.com> |
||
|
|
cf9a9639b0 |
perf(mito2): postpone covered time index filters (#8998)
* perf(mito2): postpone covered time index filters Signed-off-by: evenyag <realevenyag@gmail.com> * perf(mito2): reuse implied time range for prefilter Signed-off-by: evenyag <realevenyag@gmail.com> * refactor(mito2): build finalized scan inputs Signed-off-by: evenyag <realevenyag@gmail.com> * fix(mito2): reject empty implied time filters Signed-off-by: evenyag <realevenyag@gmail.com> * fix(mito2): guard last row shortcut with remaining filters Signed-off-by: evenyag <realevenyag@gmail.com> --------- Signed-off-by: evenyag <realevenyag@gmail.com> |
||
|
|
ed1f2d9f4e |
fix(pipeline): coalesce concurrent pipeline cache misses (#9022)
* fix(pipeline): coalesce concurrent pipeline cache misses The pipeline cache reads with a plain `moka::sync::Cache::get` and falls through to a distributed query on a miss, so when the 10s TTL expires every in-flight write request on a frontend issues its own scan of the single-region `greptime_private.pipelines` table. Concurrent scans per expiry scale with write QPS, and every frontend's burst lands on the same datanode. A user running high-throughput ingestion through a pipeline saw that datanode overloaded. Switch to `moka::future::Cache::try_get_with` so concurrent misses on the same key share one loader. This requires a single-key lookup, so cache entries are now keyed by the requested schema rather than the schema the pipeline is stored under; resolving a request to a stored schema stays in the loader, which is the authoritative path and already handles the empty-schema and multi-schema cases. A lookup for a schema not yet cached costs one extra read, now protected from amplification by the coalescing it enables. `remove_cache` previously only walked the compiled-pipeline cache, so an entry populated by `get_pipeline_str` alone (the pipeline read API) survived deletion until it expired. It now walks all three caches. Also make the TTL configurable as `pipeline.cache_ttl`, default unchanged at 10s. The TTL is what propagates a pipeline change to other frontends, so raising it trades staleness for fewer reads. Refs #9021 Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix(pipeline): restore cross-schema semantics broken by the new cache key Keying cache entries by the requested schema dropped two behaviours that the previous stored-schema key provided for free. Creating a new version only wrote the creating request's schema, so another schema on the same frontend kept serving its cached `latest` — an older version — until the entry expired. Since the whole point of making the TTL configurable is to let operators raise it, that window is not bounded by anything useful. Creation now invalidates every schema's `latest` alias for that name before priming the cache, leaving the version-pinned keys alone. The failover cache lost its reach across schemas the same way: a global pipeline (stored under the empty schema) loaded by schema A was cached under `A`, so schema B using it for the first time while the pipeline table was down missed and failed ingestion. The failover cache has no loader and so is not subject to the single-key model of `try_get_with`; it keeps the stored-schema key and the empty-schema-first resolution. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * refactor(pipeline): drop cache priming on create and fold the sweep helpers Priming the cache on create saved one read on a low-frequency operation and cost a concept: entries were written under the creating request's schema while `PipelineContent.schema` said empty, so the two schemas in play disagreed. Invalidating the `latest` aliases is required regardless — that is what makes a new version visible to other schemas — so dropping the priming loses only the saved read, which coalescing now protects anyway. `insert_and_compile` no longer needs the caller's schema. `remove_cache` and the create-time invalidation collapse into one `invalidate(name, version)`; `None` sweeps only the `latest` aliases, which is exactly what creation wants. That leaves `invalidate_by_suffixes` and `cache_keys` with a single caller each, so both are inlined. Drop the `PipelineOptions` humantime test: `load_config_test` loads both example TOMLs, which now carry `cache_ttl = "10s"`, and would fail the same way if the serde attribute were lost. The `toml` dev-dependency goes with it. The two invalidation tests are now checked to be orthogonal: removing the version suffix fails only the delete test, and sweeping just the compiled cache fails both. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix(pipeline): keep failover populated across a create The `latest` sweep on create clears the failover cache along with the loaded ones, and after dropping the priming there was nothing writing it back. An outage between the create and the first read-back left neither `latest` nor the explicit version with anything to fall back on, failing ingestion — worse than before, since the previous version's failover entry was swept too. Creation now goes through `PipelineCache::on_pipeline_created`, which pairs the sweep with a failover write of the new empty-schema definition. The two must happen together, so they live behind one method rather than at the call site. Also commit the Cargo.lock entry for the dropped `toml` dev-dependency, and trim the comments added over the last few commits down to what the code does not already say. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> --------- Signed-off-by: Dennis Zhuang <killme2008@gmail.com> |
||
|
|
ad7b0ace64 |
feat(flow): support eval schedule offsets (#8878)
* feat(flow): support eval schedule offsets Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(flow): remove redundant schedule assertion Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * refactor(flow): trim eval offset compatibility scope Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(flow): trim eval offset edge coverage Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * docs(flow): trim eval offset comment noise Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(flow): address eval offset review feedback Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(compat): cover Flow eval offset persistence Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> --------- Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> |
||
|
|
84bd993131 |
refactor(json2): concretize JSON2 schemas at merge scan boundaries (#9016)
* refactor(json2): concretize JSON2 schemas at merge scan boundaries Infer concrete JSON2 output types from remote plans and expose them on MergeScanLogicalPlan before physical planning. Recompute affected local schemas and remove the JSON2-specific rewrite from MergeScanExec. Add SQLness coverage for whole JSON2 columns in windows and joins. Signed-off-by: luofucong <luofc@foxmail.com> * fix ci Signed-off-by: luofucong <luofc@foxmail.com> --------- Signed-off-by: luofucong <luofc@foxmail.com> |
||
|
|
b86da3d35f |
feat: support raw OTLP delta metrics (#8970)
* feat: support raw OTLP delta metrics Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: fmt Signed-off-by: shuiyisong <xixing.sys@gmail.com> * test(promql): update sqlness results for normalized label matching Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: derive temporality label from default column prefix Signed-off-by: shuiyisong <xixing.sys@gmail.com> * test(promql): add analyze coverage for delta temporality Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix(promql): scope label alignment to temporality marker Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: handle count-only histograms and vector broadcasts Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: exclude temporality marker from entity descriptions Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: use a fixed label for OTLP aggregation temporality Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix(promql): preserve mixed-range semantics for raw delta Signed-off-by: shuiyisong <xixing.sys@gmail.com> --------- Signed-off-by: shuiyisong <xixing.sys@gmail.com> |
||
|
|
945e53e0a3 |
fix(client): isolate query and control transports (#8990)
* refactor(client): isolate query and control transports Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(client): cover retained Flight transport isolation Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * style(client): satisfy retained Flight test lint Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * docs(client): clarify transport lane routing Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> --------- Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> |
||
|
|
d62a5a990a |
feat(json2): support list indexing for JSON2 columns (#9013)
feat(query): support list indexing for JSON2 columns Extend JSON2 paths through DataFusion field-access planning, including nested list indexes and object fields following an index. Preserve Variant reads for bracket JSONPath expressions and normalize dot accesses after subscripts to work around the current DataFusion planner limitation. Add unit and sqlness coverage for nested indexes, type conflicts, missing paths, flushes, and compacted SSTs. Signed-off-by: luofucong <luofc@foxmail.com> |
||
|
|
d7571c1278 |
feat(mito2): add SST range index searcher (#9003)
* feat(mito2): add SST range index searcher Signed-off-by: evenyag <realevenyag@gmail.com> * refactor(mito2): reuse parquet index reader Signed-off-by: evenyag <realevenyag@gmail.com> * refactor(mito2): simplify range index pruning Signed-off-by: evenyag <realevenyag@gmail.com> * test(mito2): cover missing range index series Signed-off-by: evenyag <realevenyag@gmail.com> --------- Signed-off-by: evenyag <realevenyag@gmail.com> |
||
|
|
d351b7d471 |
feat(mito2): pass operation type to write cache upload hook (#9012)
Extend `WriteCacheUploadStoreWrapper::wrap` with the `OperationType` of the upload so implementations can apply per-operation policies (e.g. throttling compaction uploads but not flush uploads). Flush and compaction paths forward their existing `SstWriteRequest::op_type`; `put_and_upload_sst` is flush-only and index rebuild uploads are reported as compaction uploads. Files: `src/mito2/src/cache/write_cache.rs`, `src/mito2/src/sst/index.rs`. Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> |
||
|
|
05c65f54a8 |
feat(json2): support empty and null JSON2 value (#9010)
* feat(json2): support empty and null JSON2 value Signed-off-by: fys <fengys1996@gmail.com> * test(json2): cover explicit NULL and omitted-column inserts Signed-off-by: fys <fengys1996@gmail.com> * fix: cargo fmt Signed-off-by: fys <fengys1996@gmail.com> * fix: infer empty JSON object as object type Signed-off-by: fys <fengys1996@gmail.com> --------- Signed-off-by: fys <fengys1996@gmail.com> |
||
|
|
27a7047f31 |
feat: preserve row sequences and support exact sequence-range reads (#8865)
* feat(mito2): support exact sequence range reads Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(mito2): cover preserve row sequence table alter Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(mito2): clear preserve_row_sequence marker on copy_region_from copy_region_from copies source FileMeta into the target region, which has an independent sequence domain. The physical per-row sequences in the copied file belong to the source region only; trusting them in the target would let an exact sequence-range request replay source-domain rows as if they were target sequences. Clear the preserve_row_sequence marker on copied files so the target fails closed with SequenceRangeUnsupported until the scan provably cannot intersect the copied rows. Add a regression test: copying from a preserve-enabled source into a preserve-enabled target clears the marker, and an exact (2, 7] request on the target returns SequenceRangeUnsupported instead of replaying source rows. Fixes #8865 Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * style: remove redundant doc comments for exact sequence range options Approved comment-cleanup-only changes for #8865: drop outdated doc summaries duplicated on the exact_sequence_range wrapper and the preserve_row_sequence field, drop pure-restatement doc comments on the SetRegionOption/UnsetRegionOption PreserveRowSequence variants, and remove the four structural SQL comments from the alter_preserve_row_sequence case. No behavior changes; .result regenerated by the sqlness runner. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(mito2): fail closed exact reads on copied files and extension ranges Address review feedback on #8865: - copy_region_from: clear the source-domain FileMeta::sequence along with the preserve_row_sequence marker. An unmarked file retaining a stale source-domain max sequence could be silently skipped by files_allow_exact_sequence_range() as 'proven disjoint' in the target's independent sequence domain, dropping rows on exact (C, H] reads. With sequence=None the capability check fails closed (SequenceRangeUnsupported) until the copied rows are provably disjoint. - Engine/reader: reject exact sequence-range reads whenever a follower region has an extension range provider attached. Extension streams are returned without a row-level sequence filter, so exactness cannot be proven; treat the capability as missing (fail closed) instead of emitting out-of-range rows. The reader also fails closed as defense in depth. Tests: extend copy_region_from regression to assert the copied file's sequence hint is cleared; mito2 suite 1148/1148 passing. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * style(mito2): use doc comments for test function descriptions Elevate the block comments describing test functions (in scan_test and copy_region_from_test) to /// doc comments, matching the convention used elsewhere in the exact sequence range change. No logic change. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * refactor(mito2): extract helpers and trim comment noise in exact sequence reads PR finalization for #8865 (zero behavior change, full mito2 suite green): - engine: extract validate_sequence_fences and sequence_range_unsupported_reason, keeping error variants, check order and reason strings identical; OSS binds the extension blocker to false. - handle_copy_region: extract remap_copied_file_meta and file_descriptors_for_meta; rename file_ids -> source_file_ids and files_to_copy -> new_file_metas. - compactor: rename max_input_sequence -> known_max_input_sequence, document the None semantics (empty input vs unknown sequence). - Remove restating/outdated comments (ScanInput::sequence_range doc first line, outdated file-pruning note, options test restatements), compress verbatim comments while keeping why/invariants/contracts. Verified: cargo check -p mito2 (+ --features enterprise), cargo fmt, git diff --check, mito2 suite 1148/1148 passing. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(mito2): reject foreign-region SSTs in exact sequence reads Reading an SST whose FileMeta.region_id differs from the scanned region means the region's sequence domain is broken (manifest corruption or a repartition/copy path that leaked a source-domain file). Treat this as an explicit RegionSequenceDomainBroken error instead of silently ignoring the file's sequence or falling back to a full scan: the region is unusable for exact sequence-range reads until the foreign lineage is compacted away or repaired. - files_allow_exact_sequence_range / exact_sequence_range now return Result and propagate the error through engine fence validation and scan construction (StatusCode::Internal, distinct from the fallback-capable SequenceRangeUnsupported). - Row-level flat-batch sequence filtering rejects foreign-region files as defense in depth. - Engine test asserts the broken-domain error rather than Unsupported/fallback. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(mito2): never trust unmarked SSTs for exact-range disjoint skipping An unmarked file's FileMeta.sequence may be synthesized by the region-edit or repartition paths (committed+1 import barrier), not a physical max of its rows. Treating it as a whole-file disjoint proof could permanently skip rows that were never incrementally consumed once the flow checkpoint passes that value. Exact sequence-range capability now requires every SST in the region to carry the preserve_row_sequence marker; any unmarked file disables exactness (fallback), and the (C, H] file-selection skip also only applies to marked files. Foreign-region files still raise RegionSequenceDomainBroken as before. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(mito2): scope exact sequence-range capability to the time-selected read set The exact capability check used to walk the entire SstVersion, so a single unmarked or foreign-region SST anywhere in the region disabled exact reads or raised RegionSequenceDomainBroken even when the request's time range could never touch that file. Both the engine fence and the scan builder now derive the read set with shared time-pruning + exact-min/sst-min selection and validate capability only over the files actually selected: a time-pruned file cannot contribute a row to (C, H], so it cannot affect exactness. The existing fail-loud semantics are unchanged for every selected file (foreign region id -> RegionSequenceDomainBroken; unmarked -> exact unavailable). Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(mito2): wash untrusted sequences in compaction and restore barrier skipping Compaction with any non-preserved input now writes a sequence-less output: the physical __sequence column is zeroed (the flat format requires the internal columns) and FileMeta.sequence records the region-local admission barrier committed_sequence + 1 (falling back to the flushed frontier). preserve_row_sequence stays false. Exact sequence-range scans interpret an unmarked file's sequence as an admission barrier: barrier <= C means flow has already consumed the whole file, so it is skipped at file level; a missing or newer barrier fails closed. Foreign-region files stay in the selected read set so the capability fence still raises RegionSequenceDomainBroken. This closes the recovery loop: after a region repartition, one time-scoped fallback consumes the migrated rows, then compaction washes the untrusted per-row sequences away and exact incremental reads resume via file-level barrier skipping. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore(mito2): drop restating comments in known_max_input_sequence tests Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(mito2): trim SQLness result EOF whitespace Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * refactor(mito2): reuse exact scan file selection Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(mito2): strengthen sequence scan coverage Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * style(mito2): trim ALTER option comments Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(mito2): remove no-op bulk compaction check Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(mito2): preserve trusted row sequences when reading SSTs Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix(mito2): preserve target sequence domain for imported SSTs Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(mito2): add trailing blank line to SQLness result EOF Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore(mito2): trim exact sequence scan plumbing Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * refactor(mito2): fold exact SST selection checks Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(mito2): make legacy compaction rewrite deterministic Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(mito2): make PK compaction rewrite deterministic Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> --------- Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> |
||
|
|
15317a131b |
feat(json2): support JSON2 paths in SQL functions (#9007)
feat(query): support JSON2 paths in SQL functions Update the DataFusion fork to expose scalar function planning hooks. Infer JSON2 path output types from scalar, aggregate, and window function signatures, while preserving the default Utf8View behavior for functions that accept arbitrary inputs. Add unit and sqlness coverage for type conflicts, mixed typed and untyped JSON paths, filters, aggregates, and window functions. Signed-off-by: luofucong <luofc@foxmail.com> |
||
|
|
534ab31297 |
feat(flow): add row inserts to frontend client (#9006)
* feat(flow): add row inserts to frontend client Signed-off-by: fys <fengys1996@gmail.com> * feat(flow): support hints for frontend row inserts Signed-off-by: fys <fengys1996@gmail.com> * fix: handle poisoned frontend handler lock in row inserts Signed-off-by: fys <fengys1996@gmail.com> --------- Signed-off-by: fys <fengys1996@gmail.com> |
||
|
|
9c135ebcb3 |
feat!: stabilize streaming analyze metrics (#8966)
* feat: stabilize streaming analyze metrics Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * feat: expose analyze memory usage Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * refactor: simplify analyze stream handling Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * fix: preserve analyze stream sequence on panic Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore: log analyze stream worker panic Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> --------- Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> |
||
|
|
43c30d1446 |
feat(runtime): add weighted workload scheduler (#8736)
* feat(runtime): add weighted workload scheduler Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * feat(runtime): switch catio to GreptimeTeam fork with admission-wait metrics Use the GreptimeTeam/catio fork (pinned c20eafc) which adds ClassStats::total_admission_wait and ClassStats::admitted, recorded at each QUEUED -> ADMITTED transition. This exposes the scheduler's own admission delay (excluding Tokio queueing and poll execution), enabling admission-wait based fairness gates. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore: bump catio to dynamic-config revision Bump the catio scheduler fork to 9f4b028 which adds Scheduler::set_weight and Scheduler::set_max_concurrent_polls for runtime configuration. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * feat(perf): runtime-adjustable workload scheduler parameters Expose dynamic adjustment of the experimental workload scheduler at runtime: - common-runtime: set_workload_scheduler_weights and set_workload_scheduler_max_concurrent_polls, which forward to the catio scheduler's set_weight/set_max_concurrent_polls when the scheduler is enabled and reject zero values. - servers: /debug/workload_scheduler/weights and /debug/workload_scheduler/max_concurrent_polls POST handlers, so operators can rebalance query/write shares or admission concurrency without restarting the datanode. Both endpoints return 400 with a clear reason when the scheduler is disabled or the requested value is invalid. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * feat(perf): add GET /debug/workload_scheduler status endpoint Returns the current weights (per class), max_concurrent_polls, active_polls and per-class counters (queued, tasks, wakes, polls, completed, cancelled, admitted, total_admission_wait) as JSON. When the scheduler is disabled, returns enabled=false with the other fields omitted, so operators can distinguish 'disabled' from an error. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore: bump catio to time-accounting revision Bump the catio scheduler fork to 257ba56 which replaces admission-count accounting with real execution-time accounting (pass += exec_time / (weight * concurrency)), so CPU share follows the configured weights regardless of poll length. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore: bump catio to lock-free sampling revision Bump the catio scheduler fork to efdc0a4 which adds an optional downsampled clock sampling mode (SchedulerBuilder::sample_every_polls, default off) with a lock-free per-class atomic counter, so the downsampled path costs one fetch_add per poll instead of a global mutex. Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore: pin catio to scheduler PR head Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * feat(runtime): add scheduler bypass control Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore: advance catio scheduler fixes Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore: pin merged catio scheduler Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore: regenerate config docs for workload scheduler Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore: pin catio scheduler test fix Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(http): satisfy scheduler lifecycle clippy Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test: add distributed scheduler toggle coverage Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * feat: finalize workload scheduler runtime controls Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore: pin merged catio atomic weights Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * chore: preserve unrelated lockfile resolution Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * perf(runtime): downsample scheduler time accounting Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * test(runtime): verify cross-runtime scheduler progress Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * feat(runtime): configure scheduler poll sampling Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * docs(runtime): clarify scheduler activation Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> * docs(runtime): explain scheduler use case Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> --------- Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com> Co-authored-by: Ruihang Xia <waynestxia@gmail.com> |
||
|
|
02278d301b |
feat: derive k8s.node from OTLP resource attributes (#9002)
The k8s.pod runs_on k8s.node rule can only fire from kube_pod_info: it is the only table declaring both endpoints, and co-declared edges require both on the same row. A deployment sending only OTLP has no kube-state-metrics tables, so its node layer is invisible and that rule has no source at all, even though the resource attributes carry k8s.node.name. Declare k8s.node in otlp_trace_entities and in the synthesized resource descriptor, and project k8s.node.name in the descriptor writer so the column the declaration needs exists. Identity is the name rather than k8s.node.uid: kube-state-metrics carries no node UID, so the name is the only identity both sources can agree on. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> |
||
|
|
6f1dd0cb76 |
feat: allow widening the time index column's timestamp unit via ALTER TABLE, mito2 table only (#8894)
* feat: allow widening the time index column's timestamp unit via ALTER TABLE ... MODIFY COLUMN Previously MODIFY COLUMN rejected the time index column outright. Now the time index unit can be widened (Second -> Milli -> Micro -> Nano), which is lossless for data that fits the target unit: historical data in old SSTs is cast to the new unit on read by the existing schema-compat layer, and compaction rewrites it lazily. Narrowing and non-timestamp targets remain rejected; tag columns keep being rejected. Widening is rejected if any SST's time range would overflow the target unit's i64 range (e.g. millisecond -> nanosecond beyond year 2262), since the cast would silently null those values. Read-path correctness for old-unit SSTs (verified by new engine e2e tests and sqlness WHERE queries): - row-group min/max pruning: parquet statistics of a timestamp column are raw integers in the file's unit; when the region metadata's type differs (also the case for altered field columns), stats are now interpreted in the file's type and converted to the expected type before pruning. Without this, a new-unit predicate silently pruned whole row groups of old-unit files (wrong results, rows missing). - SST-level simple filters are skipped for columns whose file type differs from the expected type; the predicate is applied by the query layer's residual filter above the region scan. Also drop the stale "timestamp columns cannot change type" debug_assert. - retry idempotency: a same-type ModifyColumnType on the time index validates as a no-op and `need_alter` returns false, so a retried alter procedure (region already altered before the previous attempt failed) converges instead of aborting forever. - add TimeUnit ordering and ConcreteDataType::is_timestamp_unit_widening_to - relax ModifyColumnType validation in store-api and table metadata - tests: unit tests in datatypes/store-api/table; mito2 engine e2e tests (flushed SST + new writes + reopen + retry + overflow + predicate scans, cross-unit dedup, mixed-unit SSTs, compaction); sqlness cases incl. partitioned table and WHERE filters over old-unit data Signed-off-by: Ning Sun <sunning@greptime.com> * fix: resolve parquet filter issue * test: provide sqlness tests * refactor: drop trivial test cases and shorten comments Review pass over the branch's additions: - datatypes: keep a representative subset of the widening-matrix asserts - table: collapse the three single-branch rejection blocks into one loop - mito2: drop the boundary gt_eq and post-compaction predicate asserts (covered by the exact-filter regression test and sqlness); drop the engine-level gt_eq/lt_eq casts (full operator matrix stays in the cast_timestamp_unit unit tests) - sqlness: drop a bare full scan already covered by the filter above it - shorten function doc comments across datatypes/store-api/table/mito2/ recordbatch to the essential semantics Signed-off-by: Ning Sun <sunning@greptime.com> * fix: drop physical prefilter for columns whose file type differs Follow-up to the review feedback on CompatBatch/prune reader/filter handling for widened time index units. Between/InList/IsNull predicates are prefiltered by PhysicalFilterContext, which builds its physical expression against the FILE's schema while the predicate literals are in the expected (post-alter) unit. Evaluating them against an old-unit SST raised a cross-unit comparison error (Timestamp(ms) >= Timestamp(µs)) that failed the whole scan. Physical prefilter predicates are best-effort pruning hints (the query layer re-applies them above the scan), so drop the prefilter when the column's file type differs from the expected type, mirroring the simple-filter strategy. Verified: Between and a non-rewritten (large) InList on old-unit data no longer error and filter exactly end-to-end (sqlness), and no matching rows are lost at the engine level (engine test). Signed-off-by: Ning Sun <sunning@greptime.com> * test: add direct unit tests for stats cast and prefilter drop The two-step stats cast (reinterpret raw Int64 stats in the file's timestamp type, then rescale to the expected type) and the physical prefilter drop on file/expected type mismatch were only covered end-to-end; add localized unit tests so a regression fails at the exact site: - stats.rs (previously no tests): RowGroupPruningStats min/max over a hand-built RowGroupMetaData — passthrough with no expected metadata, passthrough on same type, and rescale (1000ms -> 1_000_000us, not 1000us) on a widened expected unit - reader.rs: PhysicalFilterContext::new_opt keeps a Between prefilter when file and expected types match and drops it on unit mismatch Signed-off-by: Ning Sun <sunning@greptime.com> * fix: tolerate mixed time units range cache key coverage check * docs: flag mixed-unit hazard in the (unwired) series index The series index stores per-series min/max ts as raw Int64 in the unit of the region metadata at write time, and the searcher builds its range predicates from a single per-region metadata. After a time index unit widen, files of one region would carry mixed units, so a per-file unit (or an index rebuild on such alters) is required before this index is wired into scans. Leave notes at both sites. Signed-off-by: Ning Sun <sunning@greptime.com> * test: cover mixed-unit compaction for sparse encoding and strict windows Compaction-path audit follow-up. The compat cast and window math were already covered for dense regions; add the two remaining e2e scenarios: - sparse primary key encoding (used by metric-engine physical regions): widening then compacting mixed-unit files rewrites the old-unit time index correctly through the sparse compaction compat path - strict-window manual compaction: each window output trims rows with a predicate built in the region's new unit against an old-unit file; every instant must survive exactly once (no loss, no cross-window duplication), rescaled Also documents the audit finding that Regular ranged (manual) compaction never trims rows: TwcsPicker sets output_time_range to None and the request time range only selects candidate windows. Signed-off-by: Ning Sun <sunning@greptime.com> * test: cover time index unit change in FlatCompatBatch directly The compat layer's rescaling of a widened time index was only verified end-to-end; add direct unit tests for both paths: - dense: identical units skip compat entirely; a widened unit rescales the time index column (1000ms -> 1_000_000us, not reinterpreted) while other columns pass through and the output schema matches the expected metadata - compact sparse (the metric-engine compaction path): same rescaling Signed-off-by: Ning Sun <sunning@greptime.com> * refactor: move timestamp unit division into common-time The exact unit division (UnitQuotient + div_mod_units) is time semantics, not filter logic; move it next to TimeUnit in common-time with a compact test covering representable/non-representable values, negative (floor) instants, and quotient overflow. The ScalarValue helpers stay in filter.rs since common-time has no datafusion dependency. Signed-off-by: Ning Sun <sunning@greptime.com> * test: compat rescales a widened time index and fills an added column together The realistic multi-alter sequence (widen at T1, add column at T2, read a T0 SST) exercises cast and default-fill in the same compute_index_and_fields pass; assert both in one output batch. Signed-off-by: Ning Sun <sunning@greptime.com> * fix: preflight time index widening overflow before any region alters Address review feedback on the overflow guard: - preflight: when the frontend operator receives a widening alter on the time index, run an existence scan (ts outside the target unit's i64 range, LIMIT 1, via the query engine so it covers every region of the table in both standalone and distributed modes) BEFORE any DDL task is submitted. A region that fits can no longer commit the new schema while another region rejects the alter with a non-retryable error. File and row-group pruning keep the scan cheap when nothing overflows. The per-region check in mito2 stays as the final guard for data written after the preflight (the remaining race window); without a validate-only wire field (region.proto lives in the external greptime-proto repo) a fully atomic two-phase validate/commit is out of scope here. - fast path: cast_timestamp_unit returns the filter unchanged when the literal is already in the target unit, skipping the div-mod rebuild. Signed-off-by: Ning Sun <sunning@greptime.com> * fix: address review comments * fix: address auto review comments * fix: remove time index widening overflow preflight Overflow needs timestamps beyond the target unit's i64 range (~year 2262 for nanoseconds), which real workloads never write, so the two existence scans before every widening alter are not worth the cost. Region validation already rejects the alter when an SST's time range overflows the target unit; it now logs the rejection (with the offending file) and returns a deterministic client-facing message. Signed-off-by: Ning Sun <sunning@greptime.com> * test: make sqlness test stable * fix: log instead of rejecting time index widening overflow Overflowing values cast to NULL on read but do not otherwise affect reads or writes, so the alter is allowed; the region-level check now only logs (with the offending file) when an SST's time range exceeds the target unit's i64 range. Signed-off-by: Ning Sun <sunning@greptime.com> --------- Signed-off-by: Ning Sun <sunning@greptime.com> |