Repository navigation
dolt 2.5.0 - #319152
Merged
Merged
dolt 2.5.0#319152
Conversation
daeho-ro
approved these changes
Oct 17, 2026
Contributor
|
🤖 An automated task has requested bottles to be published to this PR. Caution Please do not push to this PR branch before the bottle commits have been pushed, as this results in a state that is difficult to recover from. If you need to resolve a merge conflict, please use a merge commit. Do not force-push to this PR branch. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Created by
brew bumpCreated with
brew bump-formula-pr.Details
release notes
Fix dolthub/dolt#12115
Fix dolthub/dolt#12115
Fix dolthub/dolt#12106
Fixes #12090.
Fixes #12089.
This adds support for concurrent GC runs against different databases on the same server. Each GC run captures the outstanding sessions that are present when it starts and blocks on visiting only their roots. The sessions themselves can keep track of more than one outstanding waiters.
Explicit semantics are added for sessions which are themselves within a GC Safepoint Waiter, in order to prevent a potential deadlock. While the Waiter is outstanding, new Waiters which come to wait on that session can immediately visit its roots, just like the sessionAwareSafepointController would have done for that session itself when creating its own Waiter.
dolt_merge_bases()table function, allowing for multiple merge bases--allflag todolt merge-basecli operation.dolt_merge_base()behavior remains unchanged.A significant amount of testing git and it's
merge-base --allbehavior led to the testing harness added here. thego/libraries/doltcore/commitgraph/merge_bases_test.gois effectively the git behavior ofmerge base codified.
Behavior of merge-base with shallow clones (ghost commits) was incomplete, and errored in situations it should not have. This area is much more thoroughly tested now.
Related: Merge and three-dot diff use only the tallest of several merge bases, which breaks the schema-branch pattern dolthub/dolt#12050
Fix dolthub/dolt#12067
Closing an embedded SQL engine now stops and joins its branch-activity tracker and primary binlog manager, including when engine construction fails. Primary shutdown interrupts blocked replica writes and waits for active streams; disconnecting a replica preserves other streams, and stream exit closes the current rotated binlog file.
Based on #12068 by Alex Giurgiu; the original contributor commits and authorship are preserved.
Closing a keyless secondary-index scan before it is drained could leave its producer goroutine blocked on a full channel. The scan state and its expanded duplicate rows then stay reachable after the caller stops reading.
Closenow cancels an iterator-owned child context and waits for the producer, without cancelling the caller's context. No public API, SQL syntax or configuration changes.Test
TestKeylessIndexIterCloseStopsProducerinserts ten identical keyless rows, reads one, and closes the iterator insidetesting/synctest, which fails if the producer is still blocked when the test ends. It fails without the fix and passes with it.Closealso waits for it comes from the code (eg.Wait()), not from the test.Example
In a manual check (not part of this PR) with a keyless tablek(a BIGINT, b BIGINT), indexidx_b(b)and 20 rows per value ofb:SELECT a FROM k FORCE INDEX (idx_b) WHERE b = 3 LIMIT 1left one blocked producer before the fix and none after.LIMIT 1over 50 outer rows left 50 blocked producers before the fix and none after.Checked
indexpackage tests, normal and race; the new test ran 50 times under race.TestIndexes,TestIndexPrefixandTestGeneratedColumns, normal and race.go vet, copyright headers andcheck_fmt.sh.In one of our environments,
TestQueries/select_length(compress(repeat('a',_1000)))fails (expected 24, actual 21) on bothmainand this branch. It is outside the index path. We did not run the full Go or SQL engine suites, and we have not measured how often this happens in production.Generated by Perfloop. Human sponsor: Tomás Senart.
Fix dolthub/dolt#11904
Fix dolthub/dolt#12060
Fixes #12056.
Close #12072
SyncRootsreturnednilwhensrcDb.NomsRootfailed, soDOLT_BACKUPsync, sync-url and restore reported success without transferring the source root. This returns the wrapped error instead, matching how the destination root read just below already handles its error.When both branches add the same generated column, report a schema conflict if its
AS (...)expression orVIRTUAL/STOREDmode differs, instead of silently keeping one definition. Identical additions still merge cleanly.Compare these properties in both column equality methods and add merge tests for each case.
Fixes #11367
Three smallish changes:
This lets us write the zeros without interacting with allocation or GC and without the allocated array needing to RSS (outside the VMM mapping overhead).
ErrTableAlreadyExistsfor existing nonlocal tablesFix dolthub/dolt#12039
test1 and ranges both have a pk column, so the unqualified min(pk) and max(pk) are ambiguous. go-mysql-server b4f13d62c36d rejects them, failing the test on every run since #12035.
Accelerates lookup joins with SQL row inputs using shared iteration and type-aware key conversion.
Fixes Query is 1.76x slower in Dolt than MySQL dolthub/dolt#11636
Companions: Preserve numeric overflow handling in lookup joins dolthub/doltgresql#3554 and Fix extended-type hash key conversion dolthub/go-mysql-server#3997.
fdatasyncavoid unnecessary metadata updates to the file system, resulting in ~25% improvement in write performance.Fix dolthub/dolt#12021
Enables atomic updates across branch working sets and heads with dolt_commit_all and the dolt_multi_branch_commit setting.
Companion Doltgres PR: Update Dolt and skip incompatible transaction tests dolthub/doltgresql#3615
go-mysql-server
DecimalModFixes dolthub/dolt#12124
This is done in
DecimalDiv, but it seems like the step was skipped forDecimalMod.replaceSortedMinMaxFixes #4037
orderByScope.colsproperties for SetOps using that of the merged columnsFixes dolthub/dolt#11714
Based on #3977
Previously, left and right elements in tuples were converted to a common type before comparing.
For
DATETIMEtypes, certain values would be converted to NULL when they did not need to be converted at all.Fixes: Fix null safe equals for tuple comparisons dolthub/dolt#12109
Part of a body of work to remove the global SystemVariables and StatusVariables registries and make them state on the Engine itself.
Part of a body of work to remove the global SystemVariables and StatusVariables registries and make them state on the Engine itself.
Part of a body of work to remove the global SystemVariables and StatusVariables registries and make them state on the Engine itself.
Part of a body of work to remove these globals and make them state on the Engine itself.
JSON_PATHs pointing to null objects and null slicesThis PR adds regression tests for
JSON_EXTRACTwhere theJSON_PATHpoints to a nil object and attempts to slice into it.Depends on: Fix panic for NULL object and NULL slice dolthub/jsonpath#8
Fixes:
JSON_EXTRACT('{"a": null}', '$.a[0]')panics dolthub/dolt#12103Fix dolthub/dolt#12107
Based on #4014
Fixes dolthub/dolt#12093
MIN/MAXaggregates without an explicitGROUP BYshould still return a singleNULLrow when no rows match. For such cases whenMIN/MAXwas aggregating over a primary index, we were returning no rows; this was because inreplaceAgg, we were removing theGROUP BYnode, which was still needed to return the correct results via thegroupByIter.This PR does the following:
replaceAggtoreplaceSortedMinMaxto more accurately reflect what the rule doesGROUP BYnodereplaceSortedMinMaxreturn aLIMIT 1over anIndexedTableAccessinstead of aLIMIT 1 ORDER BYnode. Because theGROUP BYnode is preserved, thereplaceIdxSortrule no longer replaces the previously createdLIMIT 1 ORDER BYnode with aLIMIT 1over anIndexedTableAccess1. Instead,replaceIdxSortHelpermust be called directly withinreplaceSortedMinMax.locatecase whenstrlength is 0 andpositionis greater than 0fixes:
LOCATEpanics on empty string dolthub/dolt#12102Carries column-level
IF EXISTSinto drop plans and skips missing columns during schema validation. Adds coverage for existing/missing columns, repeated drops, and missing-table errors.Uses Vitess main following the merge of dolthub/vitess#501. ALTER TABLE and analyzer tests pass. Part of dolthub/doltgresql#3536.
MAX/MINwithoutGROUP BYreturned no row instead of oneNULLrow when no row matched, wheneverreplaceAggcould read the aggregated primary key column in index order:replaceAggreplaced theGroupBywithLimit(1)over aSort, so empty input produced no row. It now keeps theGroupByand puts theLimit(1)over theSortbeneath it, so the scan still reads a single row when the index provides the order.replaceIdxSortdoesn't descend into aGroupBy, soreplaceAggconverts thatSortto an index scan itself. The 13 changed plans are the existing MAX/MIN plans, each gaining theGroupBy.The empty-input queries added to
QueryTestsfail without the fix. Reported in Ungrouped MAX/MIN over a primary-key column returns no row when nothing matches dolthub/dolt#12093.DATETIMEstring parsingThis PR drops the regexes used for
DATETIMEstring parsing in favor of regular logic.The new implementation covers many missing warnings, addresses several edge cases, and handles additional delimiters missing from the previous implementation.
Additionally, fixes some wire tests that were previously silently failing.
Fixes:
DATEandDATETIMEdelimiters dolthub/dolt#11750This PR fixes two related but distinct panics.
We had some duplicated logic when optimizing joins, where each implementation had a different bug that was fixed in the other.
In
convertSemiToInnerJoin, we generated GetField expressions that used the table name of the underlying table, not the table alias. This could cause these expressions to not resolve correctly.In
convertAntiToLeftJoin, we used the pruned table schema instead of the full table schema when calculating ColumnIds, resulting in a potential out-of-bounds access.Dolt PR: [no-release-notes] Bump GMS dolthub/dolt#12082
Doltgres PR: [no-release-notes] Bump Dolt dolthub/doltgresql#3589
A join whose sides both have a row count and a distinct count of 0, as filtered reads of tables without statistics are estimated, made the selectivity 1/0 = +Inf and the cardinality 0 * +Inf = NaN. Converting NaN to uint64 is implementation-defined: arm64 gives 0, amd64 gives 1<<63. So on amd64 such a join was estimated at 2^63 rows, a hash or lookup join over it was priced in the 1e16s, and a nested-loop join won; on arm64 the same statement planned a hash join.
The distinct count is now at least 1, so the cardinality is 0 on both, as arm64 already estimated it. The test fails on amd64 without the fix.
Preserve GetField column IDs when adding aggregate inputs so HAVING retains grouping columns and evaluates the correct values. Fixes the incorrect result exposed by #3797.
Adds the minimal repro and related ordinary/prepared regressions, with a TODO to migrate them after #3990. Engine regressions and planner, analyzer, row execution, and aggregation tests pass; SQL expectations match MySQL and PostgreSQL.
Nested stored procedure calls should not create a new transaction. Instead their changes are applied to the existing transaction.
Fixes: Stored procedure that CALLs another procedure inside an explicit transaction silently discards the caller's earlier writes dolthub/dolt#11950
Filters on SRF outputs now remain above row expansion, while safe predicates still push down and preserve correlation tracking.
Fixes extended-type hash joins by converting keys into the comparison type.
Companions: Accelerate lookup joins with SQL row inputs dolthub/dolt#12034 and Preserve numeric overflow handling in lookup joins dolthub/doltgresql#3554.
SIGNto handle signed floating points < 0.5 and string truncationFix dolthub/go-mysql-server#3988
TIMEparsingThis PR further improves TIME parsing/conversions to more closely match MySQL's behavior.
fixes: truncate strings when casting to
timedolthub/dolt#10000This moves the
ExternalFunctionProviderso that integrators can set it via overrides. We also add a call to it so that integrators are able to use functions from their provider in column defaults.This fixes an OOM issue that occurs from recursive views.
Wildcard-only
LIKEfilters such asLIKE '%'andLIKE '%%%'now simplify toIS NOT NULLfor string operands. The rewrite only runs whenLIKEis the full filter expression, preserving NULL behavior in nested expressions.This also covers non-UTF-8 strings and constant-folded patterns.
Tests:
go test -tags=gms_pure_go ./sql/expression -count=1go test -tags=gms_pure_go ./sql/analyzer/... -count=1go test -tags=gms_pure_go ./enginetest -run '^TestCharsetCollationEngine$' -count=1Fixes #3943
TIMEfunctionbased off of: infer fractional seconds precision for TIME function dolthub/go-mysql-server#3986
partially addresses:
TIME()function infers precision based off input dolthub/dolt#11944This PR adds a flag to QueryTests that asserts that the generated row iterator supports the ValueRowIter interface. This interface is typically more performant than the traditional RowIter, so we want to make sure that we don't regress on queries that use it.
Dolt PR: [no-release-notes] Bump GMS dolthub/dolt#12029
Doltgres PR: [no-release-notes] Bump Dolt dolthub/doltgresql#3549
Fixes dolthub/dolt#11714
A set-op
ORDER BYthat named a projected column re-evaluated the left branch's expression, rather than reading the set op's output column.buildSortConditionsonly rewrites aliases, so an unaliased literal, or a function such asabs(-1000), sorted by a constant. This change points those terms at the output column, typed with the merged column type. Terms that are already aGetFieldare left unchanged, so existing plans don't change.The expected results in the new script test come from MySQL 8.4.11. Without the fix, 10 of the 16 assertions fail. The rest are guards, including
select 10 union select '9' order by 1, which has to keep sorting as strings.go test ./sql/... ./enginetest/...passes.There are two related problems on main that I left out of scope:
select a from t union select 'x' order by 1still sorts the table column with its own int type. MySQL compares as strings here.select a, a from t union select b, 1 from u order by 2sorts by column 1, because both projections share one column id.Allow projection pruning to traverse HAVING while retaining the columns needed by grouping, aggregates, and joins. HAVING expressions with subqueries continue to keep the outer table unpruned.
Part of dolthub/dolt#11923
Use a structural identity when deduplicating window expressions so distinct resolved columns with colliding rendered names are retained independently.
The identity includes expression structure and resolved field IDs plus window partition, order, NULL-ordering, and frame semantics, while excluding the assigned root output ID.
Fixes dolthub/dolt#11855
Implicit ordered
LAST_VALUE,BIT_AND,BIT_OR, andBIT_XORdid not consistently use the defaultRANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROWpeer semantics.Use the resolved peer group for
LAST_VALUEand the shared aggregate default-frame path for the bitwise aggregates. Regression coverage includes peer rows, the exact runningBIT_ORcase, explicit-equivalent frames, descending order, and compound ordering. The new assertions match MySQL 8.0.45 and PostgreSQL 15.17.Fixes dolthub/dolt#11856
Fixes dolthub/dolt#11857
Nullable numeric
RANGEframes could include unrelated rows when NULL boundary comparisons disagreed with the window's ordering. Preserve the effective NULL placement in RANGE framers and use it when scanning boundaries, supporting both MySQL's NULL-first and PostgreSQL's NULL-last ascending defaults.Regression coverage checks bounded nullable frames and explicitly verifies sorted rows and peer intervals for all four direction/NULL-rank combinations. The shared SQL results match real MySQL 8.4.11 and PostgreSQL 15.17.
Fixes dolthub/dolt#11858
Correlated aggregates in nested queries could be assigned to the syntactically inner query even when their arguments belonged to an outer query. This could evaluate an aggregate in the wrong scope and produce runtime type errors.
This change determines aggregate ownership from resolved argument columns instead of AST nesting. It:
GROUP_CONCATand its ordering expressions.Coverage includes ordinary and prepared execution, nested and parenthesized queries, joins, CTEs, unions, alias shadowing, mixed local and outer arguments, ordered
GROUP_CONCAT, and strict-grouping failures.The related grouped-window validation gap remains tracked in #3856.
Fixes #3814
vitess
Parses and formats
ALTER TABLE ... DROP COLUMN IF EXISTS, with a column-level flag separate from table-levelIF EXISTS. Adds parse/format round-trip coverage; the full parser test package passes.Part of dolthub/doltgresql#3536.
EXPLAINqueriesPreviously, because Explain parse nodes did not implement
WalkableSQLNode, Vitess would not walk them to populate input expressions on subqueries. This let to cases where go-mysql-server would produce a different plan for aDESCRIBE PLANquery compared to the original query.Closed Issues
modyields incorrect negative resultsORDER BYdoes not seem to be applied to unionsNULLliteral key for aNOT NULLcolumnJSON_EXTRACTpanics when one of several paths matches nothingJSON_EXTRACT('{"a": null}', '$.a[0]')panicsLOCATEpanics on empty stringTIMESTAMPDIFFshould return null for invalid datetimesDATEandDATETIMEdelimitersCREATE TABLE IF NOT EXISTSfails for an existing nonlocal table on a non-target branchtimeDESCRIBE PLAN {{query}}can result in a different plan than{{query}}RANGEbounds expand to the whole partitiondolt versionblocks for 30 s or more on every call when api.github.com is slow or unreachableindex out of rangeinreplaceAggfor ungrouped MIN/MAX of a non-key column when WHERE fixes the whole primary keycol LIKE '%'tocol IS NOT NULLin analyzerView the full release notes at https://github.com/dolthub/dolt/releases/tag/v2.5.0.
Footnotes
replaceIdxSortdoes not work forGROUP BYnodes due to how it can be nested inside and/or around anORDER BY, i.e.Sort, node. ↩