github dolthub/dolt v2.3.1
2.3.1

4 hours ago

Merged PRs

dolt

  • 11568: build(deps): bump undici to 6.28.0

    Summary

    • bump the transitive undici dependency from 6.24.0 to 6.28.0 in the SES email action lockfile
    • resolve Dependabot alerts #137, #138, #139, #140, #171, #172, and #173

    Validation

    • npm ci --ignore-scripts
    • npm run build
    • npm audit --omit=dev (the undici advisories are resolved; the remaining fast-xml-builder finding is covered by #11022)
      [no-release-notes]
  • 11567: /.github/workflows: pin add-and-commit
  • 11556: archives: parallelize/coalesce chunk fetches
    There are a fair number of unit tests are added, but I've also had this verified by the user that raised the issue initially. Local testing with some added trace further convinced me this works as expected.
  • 11537: backup: stop writing the working set on sync
    dolt_backup no longer commits the calling session's open transaction before it copies.
    • Syncing an idle database leaves the backup unchanged.
    • ROLLBACK after sync now works correctly.
      Fix #11488
  • 11335: Bump google.golang.org/grpc from 1.79.3 to 1.82.1 in /go
    Bumps google.golang.org/grpc from 1.79.3 to 1.82.1.
    Release notes

    Sourced from google.golang.org/grpc's releases.

    Release 1.82.1

    Security

    • server: Stop reading from the connection when flooded by HTTP/2 frames. The default value for this limit is 100 frames, excluding DATA and HEADERS, and may be changed by setting environment variable GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT.
    • xds/rbac: Support Metadata and RequestedServerName permissions matcher fields. If present in a DENY rule, previously these would be ignored and fail-open.
    • xds/rbac: Fix panic when parsing unsupported fields in NotRule/NotId permissions.
    • xds/rbac: Support the deprecated source_ip principal identifier by treating it as equivalent to direct_remote_ip.

    Release 1.82.0

    Behavior Changes

    • server: Remove support for GRPC_GO_EXPERIMENTAL_DISABLE_STRICT_PATH_CHECKING environment varibale. Strict incoming RPC path validation (which has been the default since v1.79.3) can no longer be disabled. (#9112)
    • transport: Add environment variable to change the default max header list size from 16MB to 8KB. This may be enabled by setting GRPC_GO_EXPERIMENTAL_ENABLE_8KB_DEFAULT_HEADER_LIST_SIZE=true. This will be enabled by default in a subsequent release. (#9019)
    • balancer: Load Balancing policy registry is now case-sensitive. Set GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES=false (and file an issue) to revert to case-insensitive behavior. (#9017)

    New Features

    • experimental/stats: Expose a new API, NewContextWithLabelCallback, to register a callback that is invoked when telemetry labels are added. (#8877)
    • client: Return a portion of the response body in the error message, when the client receives an unexpected non-gRPC HTTP response, to make debugging easier. (#8929)
    • server: Add environment variable GRPC_GO_SERVER_GOROUTINE_LABELS that controls setting runtime/pprof.Labels on goroutines spawned by the server. Set GRPC_GO_SERVER_GOROUTINE_LABELS=grpc.method=true to add the grpc.method label on goroutines spawned to handle incoming requests. (#9082)

    Bug Fixes

    • xds/server: Fix a memory leak of HTTP filter instances occurring when route configurations are updated in-place during a Route Discovery Service (RDS) update. (#9138)
    • grpc: In the deprecated gzip Compressor (used via the deprecated WithCompressor dial option), enforce the MaxRecvMsgSize limit on the decompressed message buffer, preventing excessive memory allocation from highly compressed payloads. (#9114)
    • stats/opentelemetry: Record retry attempts, grpc.previous-rpc-attempts, at the call level and not the attempt level. (#8923)
    • encoding: Ensure Close() is always called on readers returned from Compressor.Decompress if possible. (#9135)
    • channelz: Fix the LastMessageSentTimestamp and LastMessageReceivedTimestamp fields in SocketMetrics to ensure they contain correct timestamp values. (#9109)

    Release 1.81.1

    Security

    • xds/rbac: Fix a potential authorization bypass caused by incorrectly falling through URI/DNS SANs to Subject Distinguished Name (DN) when matching the authenticated principal name. With this fix, only the first non-empty identity source will be used, as per gRFC A41. (#9111)

    Bug Fixes

    • otel: Segregate client and server RPC information used for metrics and traces, to avoid one overwriting the other. (#9081)

    Release 1.81.0

    Behavior Changes

    • balancer/rls: Switch gauge metrics to asynchronous emission (once per collection cycle) to reduce telemetry noise and align with other gRPC language implementations. (#8808)

    Dependencies

    ... (truncated)

    Commits

  • 11271: Bump golang.org/x/image from 0.38.0 to 0.41.0 in /go
    Bumps golang.org/x/image from 0.38.0 to 0.41.0.
    Commits
    • 0d61147 bmp: reject input with invalid palette index
    • fe8ae45 tiff: limit PackBits decompression output size
    • 542a3d9 go.mod: update golang.org/x dependencies
    • 5cbe89a tiff: reject 0-size images
    • 3d5c9b6 go.mod: update golang.org/x dependencies
    • 854c274 font/sfnt: apply bounds checks before allocating read buffer
    • 96edba0 webp: reject VP8X headers with too-large canvases
    • See full diff in compare view

    > **Note** > Automatic rebases have been disabled on this pull request as it has been open for over 30 days.

go-mysql-server

  • 3710: fix panic in TRIM functions
    Added a conversion for TimeSpan type to LongText and updated errors to not panic.
    fixes: #11455

  • 3703: Fix panic for LIKE expression with empty ESCAPE character
    Despite what MySQL documentation says, empty ESCAPE character actually escapes the NUL character (\0).
    fixes: #11518

  • 3702: fix panic in format()
    fixes: #11517

  • 3700: fix panic on rand(null)
    fixes: #11494

  • 3697: fix inet6 type assertions
    fixes: #11493

  • 3696: cap initial heapsize
    This PR adds a cap to the initial heap size of the maxRowHeap within TopNRowsIter, to prevent overflows.
    Additionally, unnecessarily large order by ... limit x clauses would result wasted time allocating space.
    heap.Push appends to the internal slice, so we'll rely on golang to manage the memory.
    fixes: #11503

  • 3695: Allow NULL and other numerical swap flags for BIN_TO_UUID
    Fixes #11457

  • 3693: fix panic for GeometryFromWKT and various GeoSpatial bugs
    We added support for "pure empty geometry forms", which MySQL doesn't support, except for "GEOMETRYCOLLECTION EMPTY".
    Changes:

    • fix panics for pure empty geometry forms
    • fix panics for invalid axis-order options
    • fix ordering for axis-order options
    • expose st_latitude function
    • fix geospatial srid for st_x() and st_y() functions
      Fixes: #11492
  • 3692: When serializing bytes for a MySQL client, correctly handle wrapped values, such as adaptive encoded columns
    Currently, when a sql.Value contains a wrapped value, but the value's type doesn't implement sql.ValueType, we fail to properly serialize it when sending the bytes to the MySQL client.

  • 3691: block certain statements from PREPARE
    This PR blocks CREATE EVENT and CREATE PROCEDURE from getting created.
    Additionally, adds tests for a variety of DDL statements like DELETE, CREATE, and ALTER.
    Fixes:
    #11417
    #11451

  • 3690: Check for null before casting LAST_INSERT_ID input
    fixes #11454

  • 3689: Refactor window function tests into ScriptTests
    Converts existing window function tests to use ScriptTest and moves those ScriptTests into a new window_function_queries.go file.

  • 3687: SECURITY: Document security stance on panics generated by GMS.
    Add some defensive recover() calls at places where GMS itself spawns goroutines.

  • 3677: Bump jsonpath and add new test for parsing JSON null.
    Fixes #11394
    Our jsonpath dependency wasn't properly parsing paths when the input object was a JSON null value.

  • 3676: Update various window aggregation functions to expect the correct number of children
    Fixes #11428
    Some window functions were expecting the wrong number of child expressions, thus incorrectly throwing an error. However, this error was getting swallowed and going unnoticed during fixExprToScope, which is intentional due to errors being falsely triggered for dual tables or subqueries but does lead to unintentional consequences. As a result, child expressions were not getting properly updated during fixExprToScope, leading to a panic.
    This PR updates WithChildren for those window functions to expect the correct number of children.

  • 3674: Error out for undefined window names
    fixes #11426
    ErrUnknownWindowName was defined but never actually used anywhere. This PR updates the error message to better match MySQL and throws the error when a referenced window name has not actually be defined.

  • 3672: Pass context through aggregate/window check funcs

  • 3671: Handle negative start positions in LOCATE function
    fixes #11393

  • 3670: Fix panic when a RANGE window frame offset pushes a SET/ENUM order-by value outside its valid domain
    Also stops swallowing non-EOF framer errors that let it turn into an out-of-bounds index.
    Fixes: #11397

  • 3669: Combine assignmentExprsToUpdateExprs and buildOnDupUpdateExprs
    Fixes #11389
    This PR addresses a TODO that I had added to combine assignExprsToUpdateExprs and buildOnDupUpdateExprs, since these two functions did pretty much the same thing with a lot of repeated code. buildOnDupUpdateExprs was missing the step to resolve DEFAULT so it made more sense to combine the two functions that it did to rewrite that step.
    This PR also replaces the panic in DefaultColumn.Eval with an error in an effort to reduce the number of panics in GMS and Dolt (#11299).

  • 3667: Clear autocommit transactions on err on all paths

  • 3666: Include orderBy in various window functions to return correct default framer
    fixes #11381
    baseWindowFunction was created to avoid duplicating shared code and is intended to be extended to fully eliminate duplicated code for window functions.
    Also updates tests that were asserting incorrect behavior (verified to match MySQL)
    Some new test cases are skipped for Doltgres (see dolthub/doltgresql#3036 and dolthub/doltgresql#3038)

  • 3665: Adding a new TimeDeltaExpression interface
    Allows window interval arithmetic to work properly with Doltgres' implementation.

  • 3664: Check if SubqueryAlias itself is lateral when prepending rows
    Fixes #11378

  • 3663: bug fix: infer a bindvar's column type
    Fix untyped bind-var type inference to use the comparison expression's own declared type instead of digging into its children. This means operators like #>> (jsonb→text) (from Doltgres) don't leak their operand's type onto the parameter.
    Related to: dolthub/doltgresql#3012

  • 3662: add case for injected exprs in node batch

  • 3661: create schema from inscope columns of the table being parsed as column

  • 3660: bug fixes for schema in table statistics
    As well as other bugs that were preventing table statistics from being used in doltgres

  • 3659: fallback to gms types for extended type histograms
    benchmarks: dolthub/doltgresql#3001 (comment)

  • 3658: When comparing tuples for equality, widen each pair of input values.
    Previously, when comparing tuples, we would cast the right tuple to the type of the left tuple. This is inconsistent with MySQL, which considers each pair of values and converts them both to a widened type.
    This resulted in us returning the incorrect result for the simple query:

    SELECT (1, 1) = (1.1, 1.1);
    

    Dolt would round both of the values on the right to integers prior to comparing them, evaluating to true. The correct behavior is to apply MySQL's type conversion rules to each pair, which in this case would result in both integers being converted to decimals, and the tuples comparing unequal.

  • 3657: check stats prov for empty stat
    Instead of creating the (potentially same) empty stat every time, we should check if it has already been made in the StatsProvider.

  • 3656: Bug fix for CASE expressions with ExtendedType instances
    Related to: dolthub/doltgresql#2980
    Doltgres fix: dolthub/doltgresql#2987

  • 3653: adding prepare tests for insert and update

  • 3652: Allow aliasing column names in a table function

    Depends on: dolthub/vitess#477

  • 3651: Correctly do NullUnsafe comparisons with tuples.
    Previously, all comparisons with tuples acted as though the comparison was null-safe. But the correct behavior is more subtle. Essentially, any comparison operation involving NULL should return NULL if substituting different values for the NULL could result in different outputs.
    This PR fixes most of the incorrect comparisons. Some stragglers remain involving WHERE x IN (SELECT ...) subqueries.
    This PR is inspired by dolthub/go-mysql-server#3640 but doesn't use any of the code from that PR.

  • 3644: add ExtendedTableFunction interface to support table function schema …
    …on OUT parameters

  • 3643: Use buildScalar to get GetField expression for ON UPDATE columns
    fixes #11346
    Building the GetField expression for a column using its index in a table was causing indexing issues when there was also a CTE. Instead, we need to build the the GetField using buildScalar to properly resolve the column within the scope.

  • 3641: Bug fix for a panic when calling a stored procedure without a database selected

  • 3639: have coster consider not picking secondary indexes
    This PR adds a "no index" option to the coster and some additional heuristics for index costing.
    Before, we would always pick any available index, which would sometimes be sub-optimal, especially if the index is a non-covering secondary index.
    Additionally, the normal_dist and exp_dist tables are now seeded to reduce random variability between test runs.
    Benchmarks:
    #11336 (comment)

  • 3638: Bug fixes for secondary indexes using virtual columns
    When updating a row in a secondary index, any virtual generated columns need their generation expression evaluated to get the correct data stored in the secondary index. There were a few edge case with virtual columns and secondary indexes where this evaluation wasn't happening. This PR closes those gaps.
    The first case is when a table rewrite is performed and secondary indexes are rebuilt (e.g. when dropping a column on a table). Not properly evaluating a virtual column's expression caused incorrect data to be stored in the index when it was rebuilt.
    A second case is for referential actions on a foreign key that update a table and its secondary index. Not properly evaluating a virtual column's expression here can also cause incorrect data to be written to the secondary index.
    Fix for failing Dolt CI integration test in: #11333

  • 3634: Add support for multiple expressions in functional indexes

  • 3627: fix stats functions to include schema
    We include the schema in the stats key, but only sometimes fill in the field.

  • 3626: Prevent index offset when comparing rows in topRowsIter
    Fixes #11300
    Appending the row order number to the end of a sql.Row during a Top-N Heap Sort in topRowsIter was causing an index offset when evaluating SortFields that were subqueries, thus resulting in incorrect result.
    This PR

    • modifies topRowsHeap to instead take a rowWithOrder struct that separates out the sql.Row from the order number while still taking the order number into account when sorting the heap.
    • refactoring Sorter.LesserRow logic into a new CompareRows function to allow checking for row equality
    • moves top row(s) iterators to its own file as part of an effort to make our iterators more organized (#3620). This file also includes topRowsHeap since it is only ever used by topRowIter (see dolthub/go-mysql-server#3622 (comment) for next steps)
    • removes ValueRowSortersince it's actually never used anywhere and doesn't even fully implement sort.Interface
  • 3623: memory: use stable sort for secondary index ordering
    memory.TableData.sortSecondaryIndexes sorted secondary index storage with sort.Slice, which uses Go's unstable pdqsort algorithm. Rows that tie on the indexed columns (same key, different primary key) could be reordered relative to each other on every sort, so repeated index rebuilds of the same data could produce different physical row orders.
    This PR switches to sort.SliceStable, which preserves the relative (insertion) order of tied rows, making secondary index storage ordering deterministic across rebuilds.
    Fixes #2877

  • 3621: bug fix: honor named window reference
    An existing bug in GMS was not properly applying a named window reference. We had enginetests for named window references, but they weren't sufficient to catch this because the aggregate function they used produced identical values in both cases. New enginetest cases are added to prevent a regression.
    These two issues were identified by Ito automated review, in dolthub/doltgresql#2913

  • 3619: sql: Fix ALTER USER to allow the Identity field of the User record to be updated.
    CREATE USER ... IDENTITY WITH <plugin> AS '<identity>' correctly parsed and persisted the Identity field. ALTER USER correctly parsed the Identity field but failed to persist the changes. The end result is that GMS had a bug where attempt to alter the identity field on an existing user seemed to succeed but was not reflected in the data going forward.
    Fix the bug so that updates to Identity are reflected and persisted going forward.

  • 3618: Error on SELECT @@SESSION., matching MySQL
    GMS silently returned the global value when a GLOBAL-only system variable was read with an explicitly-qualified SESSION/LOCAL scope (e.g. SELECT @@SESSION.innodb_autoinc_lock_mode), instead of raising MySQL's ERROR 1238 (ErrSystemVariableGlobalOnly).
    buildSysVar's case for SetScope_None/SetScope_Session already carries specifiedScope, which is empty for a bare @@foo reference and non-empty ("session"/"local") only when the scope was explicitly written in the query. This change uses that existing signal to raise ErrSystemVariableGlobalOnly when a global-only variable's scope is explicitly specified as session/local, while leaving the bare @@foo fallback-to-global behavior untouched (MySQL allows that case).
    Also un-skips a pre-existing enginetest case in variable_queries.go that already asserted this exact error — the test was written in anticipation of this fix (Skip: true) and now passes.
    Fixes #6722

  • 3617: special case on extended type for getting compare type

  • 3615: Bump golang.org/x/crypto from 0.46.0 to 0.52.0
    Bumps golang.org/x/crypto from 0.46.0 to 0.52.0.

    Commits
    • a1c0d99 go.mod: update golang.org/x dependencies
    • 3c7c869 ssh: fix deadlock on unexpected channel responses
    • 533fb3f ssh: fix source-address critical option bypass
    • abbc44d ssh: fix incorrect operator order
    • e052873 ssh: fix infinite loop on large channel writes due to integer overflow
    • b61cf85 ssh: enforce user presence verification for security keys
    • 9c2cd33 ssh: enforce strict limits on DSA key parameters
    • 8907318 ssh: reject RSA keys with excessively large moduli
    • ffd87b4 ssh: fix panic when authority callbacks are nil
    • 4e7a738 ssh: fix deadlock on unexpected global responses
    • Additional commits viewable in compare view

    [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golang.org/x/crypto&package-manager=go_modules&previous-version=0.46.0&new-version=0.52.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
    Dependabot commands and options
    You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/dolthub/go-mysql-server/network/alerts).
  • 3614: Report Sum/Avg's true float64 type; add window-func override hook
    Various tweaks to go-mysql-server's unary aggregate function support to enable Doltgres window function support:

    • fixed agg_gen template to be in-sync with generated code after manual changes were applied recently.
    • changed Avg() and Sum()'s definition to always return float64 and removed analyzer code in aggregates.go that override return types for Avg() and Sum() to float64.
    • added a window function override hook (IsWindowFunc).
  • 3613: Apply IndexSearchable optimization to sql.Equality expressions

  • 3612: Bug fix: allow running analysis on indexed join queries with bindvars
    To support Doltgres, the analyzer in GMS needs to support running on queries that contain bindvars. An assumption in indexed join costing was causing a panic for Doltgres when a bindvar appeared in the join condition on an indexed column.
    Doltgres needs to run the analyzer when preparing a statement because of the Postgres wire protocol, which requires more detailed schema information to be returned before the prepared statement is executed.

  • 3611: avoid fmt.Sprintf in groupby hash

  • 3610: pushdown inequalities to merge joins
    Before, only equality filters would be pushed down into the IndexedTableAccess for MergeJoins.
    This PR makes it so all static comparisons are pushed down.
    TODO:

    • The Filter over these IndexedTableAccess nodes are useless and we should drop them
    • The coster needs to properly account for the pushed down filters.
    • We should be able to push down more than just one expression over a column
    • We should be able to push more than just the prefix into the index
  • 3609: server: Add client-disconnect watching to more platforms and more query types.
    Previously GMS had rudimentary logic on Linux to scan the socket state list and watch for a TCP connection associated with a running query to transition to a non-connected state. If that happened, GMS would cancel a Context associated with the query so that it could terminate in a timely manner --- the client was no longer waiting for the response.
    The old implementation had a few downsides:

    1. The scan itself periodically scanned a large table in /proc for every in-flight query. This was relatively expensive and somewhat wasteful.
    2. It only worked on Linux and only for TCP listeners.
    3. It only worked for some queries. In particular, it was never enabled for OkResult queries, or queries that were knowingly going to return only one result. This was an optimization because even setting up the connection logic scanning was somewhat expensive.
      This PR changes GMS to take a different approach. We added (*mysql.Conn).WaitForClientActivity(context.Context) to the vitess layer, and now the server handler uses that to get a quick notification the the client connection received readable activity (probably an EOF) when it was not expecting.
      We still have to be careful to not needless add overhead to very fast-running queries. The approach we take is to have a single goroutine periodically scanning the connection state. Connections themselves register when they start a query and when they end it. The scanning goroutine will start the disconnect watcher on the connection only after its query has been running for a bit of time.
  • 3608: Rewrite pushFilters to use single top-down node traversal
    Split off from #3591
    pushFilters was also previously written with two nested transform.NodeWithCtx (a bottom-up traversal). The outer traversal was done to identify filter nodes. The inner traversal "pushed down" filter expressions to the table level - this was not a true "pushdown" because it was a bottom-up traversal. An additional InspectUp traversal was done for each filter node to collect all the filter expressions in the node tree -- this was unnecessary since any child filter nodes would've already had their filter expressions handled and this resulted in chains of identical filter nodes that later needed to be condensed. An additional Inspect traversal was done per filter node to find projection expressions -- this only needed to be done once with the root node instead of per filter node. pushFilters also checks if the node tree is unresolved at the beginning, adding another traversal. This meant a node tree with n filters would be traversed 2+3n times.
    #3603 reduced the number of traversals done to find projection expressions to 1, instead of once per filter node. This PR rewrites the pushFilters rule to only use a single node traversal that collects filters as the traversal moves down the node tree. It also removes the check for unresolved nodes. These changes reduce the number of node tree traversals to a constant 2.
    This also makes it easier to later combine the pushFilters and moveJoinConditionsToFilter rule (which is done in #3591).
    Query plans have changed because repeated filter expressions (previously from traversing the entire child tree to find all filters) have been de-duped and filter expressions are ANDed slightly differently.

  • 3605: Use TableIds instead of names when mapping filters to tables
    Split off from #3591
    Using table names prevented us from being able to distinguish between tables from different databases with the same unqualified name.
    This PR also updates places where we were not using the correct TableId

    • when condensing a SubqueryAlias into a TableAlias, the new TableAlias should have the same TableId as the SubqueryAlias
    • A view should be getting its TableId from the scope via its name, not the name of its first column
  • 3603: Only get projection expressions once when creating filterSet during filter pushdown
    Split off from #3591
    getProjectionExpressions is only called once, instead of for each Filter node. tableAliases is also removed because it's never actually used anywhere.

  • 3602: Create single override point for SplitConjunction
    SplitConjunction works differently for Doltgres expressions. The integration with Doltgres relied on analyzer.SplitConjunction and memo.SplitConjunction being replaced and called instead of expression.SplitConjunction; however, expression.SplitConjunction was still being called in many places in the analyzer. Not calling the correct version of SplitConjunction was preventing filter expressions from being properly pushed down in Doltgres. Furthermore, expression.SplitConjunction was still being called in rowexec and calling analyzer.SplitConjunction from the rowexec package causes a cyclical import.
    To avoid confusion between the various SplitConjunction instances, this PR replaces the various override variables with a single one in the expression package. This allows SplitConjunction to be consistently replaced throughout GMS without requiring GMS developers to have knowledge of SplitConjunction working differently in Doltgres.
    This change is integrated into Dolgres in dolthub/doltgresql#2865.
    This issue was originally encountered while working on #3591.

  • 3601: cache GeneralizeTypes output and avoid fmt.Sprintf in HashOfSimple
    This PR adds some optimizations to CASE statements and HashLookups

  • 3600: Allow filter pushdown in subqueries when analyzing insert sources
    fixes #11232

  • 3598: Fix JSON_LENGTH and member-access lookups to match MySQL
    JSON_LENGTH returned NULL for empty arrays and the JSON null literal, and member-access paths (.key/.*) on an array returned [] instead of NULL.

    • Empty array now has length 0, JSON null has length 1
    • Member access on a non object yields SQL NULL, at any depth
    • New allocation free path scanner for the pre check
      Fix #11224
      Close #11235
  • 3597: Revert "Merge pull request #3590 from dolthub/aaron/poll-for-closed-connection-more-cases"
    This reverts commit fd2dd1dc271b33b78dab499bea47a321da117f1d, reversing changes made to a5d92faf1ed8ae517399aabbf5d71d9de208d373.
    This may have been a performance regression. Reverting while investigating.

  • 3595: Rollback event-driven stale-client detection.

  • 3594: allow using star expr after sql value for Doltgres

  • 3593: server/handler.go: Use event-driven notification to quickly cancel a running query after a client-disconnect, instead of polling socket state in a platform-dependent way.

  • 3591: Combine pushFilters rule with moveJoinConditionsToFilter
    Fixes #10899
    This PR rewrites the pushFilters rule by combining it with the moveJoinConditionsToFilter.
    Background
    Previously, if a join condition only referenced one side of a join, moveJoinConditionsToFilter would wrap that side with a filter. The idea was that the filter would later get pushed down to the table during pushFilters, but this caused an issue with nested joins where join/filter conditions that referred to multiple tables that were all part of the same child join would get orphaned in the middle of the join tree and then dropped during reorderJoin (#9868). This was partially fixed with #3231, where filters could get pushed into the join condition. However, this didn't work for all join types and also introduced the problem in #10899, where the filter expression pushed down into the join condition was being treated as an edge during reorderJoin, leading to incorrect join plans.
    Why query plan tests changed

    • Filters are no longer automatically getting pushed into join conditions, which affects the join type and join reordering. There are cases where this could still be allowed, but for now, it's safer to not since doing so was causing incorrect join reorders.
    • More CrossJoins. Previously, joins that had all their join conditions pushed down into a filter were getting TRUE assigned as their join condition. This was preventing InnerJoins from being turned into CrossJoins because they had a non-nil join condition, even though nil join conditions are treated as TRUE.
      Additional Work
    • There are cases where parent filter expressions or join conditions can be pushed down into a join condition. This could be achieved by extending filtersByTable to use a FastIntSet to store expressions that reference more than one TableId and for pushdownFiltersAboveTables to propagate up a FastIntSet of child TableIds.
    • There are also join types, such as Left Outer and Anti joins, where a parent filter expression should not be evaluated as a join condition; however, it may be performant to evaluate the filter expression as part of the join iterator to reduce the need for an additional loop through a filter iterator.
    • The replaceCrossJoins may not be necessary and could probably combined into pushFilters as well
  • 3590: server: Use pollForClosedConnection on all query paths, including DML, DDL, OkResults, empty result schemas, etc.

  • 3589: fix JSON control-character escaping and out-of-band text reads
    Escape every control character in JSON output and unwrap lazily loaded text so JSON functions read it correctly.

    • escape U+0000 to U+001F as \uXXXX, keeping the short forms for backspace, tab, newline, form feed, and carriage return.
    • unwrap StringWrapper before evaluating JSON functions, fixing JSON_VALID and friends on large keyless TEXT
    • add serializer, JSON_QUOTE, and function tests
      Block #11215
  • 3587: go.mod: Bump github.com/lestrrat-go/strftime to v1.2.0. Fixes a lock leak which can deadlock queries in Dolt.

  • 3585: Add right side lookup overhead for LookupJoins
    LookupJoins were getting costed lower than they should be, resulting in bad join strategies in some cases.
    This PR adjusts the coster and includes an overhead for the right side of a lookup join.
    An example of the bad join is:

    explain SELECT SUM(CASE WHEN s_quantity = 0 THEN 1 ELSE 0 END) AS stockouts, SUM(ol.ol_amount) AS total_cost FROM stock s JOIN order_line ol ON s.s_i_id = ol.ol_i_id WHERE  s.s_i_id <= 7500;
    plan
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------
    Project
    ├─ columns: [sum(case  when s.s_quantity = 0 then 1 else 0 end as case when s_quantity = 0 then 1 else 0 end) as stockouts, sum(ol.ol_amount) as total_cost]
    └─ GroupBy
    ├─ select: SUM(CASE  WHEN s.s_quantity = 0 THEN 1 ELSE 0 END as CASE WHEN s_quantity = 0 THEN 1 ELSE 0 END), SUM(ol.ol_amount)
    ├─ group:
    └─ LookupJoin
    ├─ TableAlias(ol)
    │   └─ Table
    │       ├─ name: order_line
    │       └─ columns: [ol_i_id ol_amount]
    └─ Filter
    ├─ s.s_i_id <= 7500
    └─ TableAlias(s)
    └─ IndexedTableAccess(stock)
    ├─ index: [stock.s_i_id]
    ├─ columns: [s_i_id s_quantity]
    └─ keys: ol.ol_i_id
    (17 rows)
    

    The more optimal plan uses a HashJoin

    explain SELECT /*+ HASH_JOIN(ol, s) */ HINT SUM(CASE WHEN s_quantity = 0 THEN 1 ELSE 0 END) AS stockouts,
    SUM(ol.ol_amount) AS total_cost
    FROM stock s
    JOIN order_line ol ON s.s_i_id = ol.ol_i_id
    WHERE s.s_i_id <= 7500;
    plan
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------
    Project
    ├─ columns: [sum(case  when s.s_quantity = 0 then 1 else 0 end as case when s_quantity = 0 then 1 else 0 end) as stockouts, sum(ol.ol_amount) as total_cost]
    └─ GroupBy
    ├─ select: SUM(CASE  WHEN s.s_quantity = 0 THEN 1 ELSE 0 END as CASE WHEN s_quantity = 0 THEN 1 ELSE 0 END), SUM(ol.ol_amount)
    ├─ group:
    └─ HashJoin
    ├─ s.s_i_id = ol.ol_i_id
    ├─ TableAlias(ol)
    │   └─ Table
    │       ├─ name: order_line
    │       └─ columns: [ol_i_id ol_amount]
    └─ HashLookup
    ├─ left-key: (ol.ol_i_id)
    ├─ right-key: (s.s_i_id)
    └─ Filter
    ├─ s.s_i_id <= 7500
    └─ TableAlias(s)
    └─ Table
    ├─ name: stock
    └─ columns: [s_i_id s_quantity]
    

    Source: I made it up.

  • 3584: Add LockSubsystem.TryLock for non-blocking lock acquisition
    Extract the single CAS attempt from Lock into a private tryLock helper and expose it as a public TryLock method that returns immediately if the lock is held by another session.
    Callers no longer need to pass a short timeout to Lock and treat ErrLockTimeout as a false return. Referenced by a TODO in dolthub/doltgresql.

  • 3582: fix: panic in regexp functions over large text in group by
    REGEXP_REPLACE on a large TEXT column inside a GROUP BY panic with SIGSEGV.

    • Add a ScriptTest and RegexScriptTests for similar regressions on REGEXP_REPLACE, REGEXP_SUBSTR, REGEXP_LIKE, and REGEXP_INSTR.
      Depends on dolthub/go-icu-regex#13
  • 3581: Fix LIKE 'prefix%' dropping rows with multibyte text
    LIKE 'prefix%' is rewritten into an index range for speed, but the upper bound used byte 255 (U+00FF), which is not the largest character. Any value after prefix above U+00FF falls outside the range and was silently dropped as a WHERE/JOIN filter. Instead, we build the bound per collation:

    • utf8mb4_0900_bin matches are an exact code-point range, so emit GTE prefix AND LT next (prefix and last character incremented by one skipping the surrogate code points).
    • Any other collation GTE prefix AND <LIKE> so the index still narrows the scan while the retained LIKE keeps results correct. These collations may not sort by raw character numbers, or have unique rules (i.e., treating trailing spaces as nothing, so "ab" and "ab " count as equal).
    • Fix TPCH and IMDB plan expectations with old baked-in bound.
      Fix #11182
      Close #11188
  • 3579: make hashjoin compatible with doltgres
    doltgres has different equality expressions, which prevented hashjoins from getting considered during join planning.

  • 3578: fix: retain table comment when primary key is a separate clause
    CREATE TABLE ... COMMENT='c' dropped the comment when PRIMARY KEY was given as a separate clause.

    • Add a comment parameter to IndexedTableCreator.CreateIndexedTable and thread it through the executor.
      Block #11170
  • 3577: fix: return ok result schema for ALTER TABLE comment
    AlterTableComment yields an OkResult row but reported the table schema, so schema-driven renderers (i.e. Dolt) formatted the OkResult against the first column and failed.
    Block #11168
    Fix #11164

  • 3575: decompose tuple inequalities
    This PR extends the tuple in filter decomposition logic to cover tuples in equallities and inequalities.

  • 3574: Ensure SchemaObjectNameValidator is used when a table is renamed

  • 3573: support NOT VALID on foreign key and check constraints
    Depends on dolthub/vitess#471

  • 3572: Rewrite CachedResults node and cachedResultsIter to not use MemoryManager
    This PR is a follow-up to #3561 and further addresses the memory leak mentioned in #3560. While the initial fix in #3561 made it seem like the issue was that we were not properly disposing of the CachedResults node, the real issue was that a cachedResultsIter that never wrote to the CachedResults node was never disposed of in the MemoryManager if it was never closed.
    This PR rewrites the CachedResults node and cachedResultsIter to never actually make use of the MemoryManager. Since we do not make use of parallel partitions, there's no need to have a locking cache. Instead, the results of the cachedResultsIter are stored directly in the CachedResults node. This greatly simplifies both the CachedResults node and the cachedResultsIter.
    This PR also moves the emptyCacheIter and EmptyIter out of the plan package and de-dupes any code related to empty iters.

  • 3571: Add IndexNameGenerator interface
    New IndexNameGenerator interface allows databases to customize the logic that generates index names when they aren't explicitly specified.

  • 3570: improvements to time to wire format
    Should use apd.Decimal.Append() and faster way to append time strings.
    Benchmarks: #11130 (comment)

  • 3568: bug fix for non-found search paths

  • 3567: fix for division on decimals
    BenchmarkPlusHighScaleDecimals:

    before (decimal.Decimal)   2505679               460.8 ns/op
    after (apd.Decimal)        3746318               304.5 ns/op
    

    BenchmarkMinusHighScaleDecimals:

    before (decimal.Decimal)   2619691               449.0 ns/op
    after (apd.Decimal)        3723363               312.1 ns/op
    

    BenchmarkMultHighScaleDecimals:

    before (decimal.Decimal)   2537882               454.6 ns/op
    after (apd.Decimal)        3608662               321.3 ns/op
    

    BenchmarkDivHighScaleDecimals:

    before (decimal.Decimal)   793515               1414 ns/op
    before fix (apd.Decimal)   367                  3112350 ns/op
    after fix (apd.Decimal)    946606               1246 ns/op
    

    BenchmarkDivManyDecimals:

    before (decimal.Decimal)   130582               7691 ns/op
    before fix (apd.Decimal)   54                   21534736 ns/op
    after fix (apd.Decimal)    110416               9347 ns/op
    
  • 3566: analyzer: export BuildForeignKeyEditor for callers outside DML analysis
    Refactors the internal FK-editor builder chain (getForeignKeyEditor, getForeignKeyReferences, getForeignKeyRefActions, cache.GetUpdater, getForeignKeyHandlerFromUpdateTarget) to take *Catalog instead of *Analyzer since only a.Catalog was ever used. Adds an exported BuildForeignKeyEditor entry point so integrators can wrap a writer in a ForeignKeyEditor when their write path doesn't go through the analyzer (e.g. dolt's workspace tables).

  • 3565: Allow unparenthesized function expressions in column defaults.
    MariaDB allows the use of a function expression as a column default expressions without requiring it to be wrapped in parentheses. MySQL does not allow this.
    In order to parse scripts created for MariaDB, we should also accept unwrapped function expressions as column defaults. However, in order to ensure that dumps created by Dolt are compatible with MySQL, we normalize these expressions by wrapping them in parentheses internally.

  • 3563: Introduce SchemaObjectNameValidator interface
    To support custom Postgresql logic for Doltgres, a new interface called RelationNameValidator is added.

  • 3562: pass schema name when retreiving function

  • 3561: fix(rowexec): dispose CachedResults child when closing hashLookupGeneratingIter (#3560)

    Summary

    hashLookupGeneratingIter.Close returned nil without closing the child iter chain or disposing the wrapped *plan.CachedResults node. Every executed hash join over a CachedResults subtree could therefore leak one entry into Analyzer.CachedResultsManager.cachedResultsCaches, freed only by process restart.
    This PR makes Close:

    1. Dispose the CachedResults child if present (releases the global Manager entry).
    2. Propagate Close down the rest of the child iter chain.

    Fix

    func (h *hashLookupGeneratingIter) Close(c *sql.Context) error {
    -    return nil
    +    if cr, ok := h.n.Child.(*plan.CachedResults); ok {
    +        cr.Dispose(c)
    +    }
    +    return h.childIter.Close(c)
    }

    Why

    Full RCA, reproducer, and pprof evidence are in #3560. Headline numbers from the 3-minute, ~30 req/sec workload reported there (Dolt 2.0.6 sql-server vendoring this commit):

    Metric Vanilla Δ Patched Δ Improvement
    RSS +5069 MB +44 MB ~115×
    HeapAlloc (live) +4.3 GB +82 MB ~52×
    HeapObjects (live) +90 million +1.5 million ~60×
    Mallocs - Frees (net live) +204 million +4 million ~50×
    Allocation rate is unchanged (~1.1B mallocs in 3 min both runs); the patched build services the same workload but Frees keeps up with Mallocs.

    Tests

    go test ./sql/rowexec/... passes locally with the patch applied.
    I did not include a unit-level regression test in this PR. In a minimal engine.QueryRowIterToRows test, TrackedRowIter.Close → done → disposeNode already walks the plan tree and disposes the CachedResults via sql.Dispose(ctx, node), so the leak doesn't reproduce that way; faithfully exercising the production path (Dolt sql-server, prepared statements via the MySQL wire protocol) needs significantly more harness scaffolding. Happy to add a test if maintainers can point me at the right entry point.
    Closes #3560

  • 3558: Unwrap wrapped strings before casting to string during RegexpReplace.Eval
    Fixes #11095
    REGEXP_REPLACE queries on LONGTEXT type columns were panicking because we were casting values to strings without unwrapping them. Note that this doesn't happen with tables created in Dolt 2.0 due to the recent changes to adaptive encoding, but we still need to support tables before then.
    Also moved mockStringWrapper to a shared test util package so it can be used in various tests.

  • 3557: Include CHAR and VARCHAR in IN expression optimization
    A few months ago, I added an optimization to avoid building expensive RangeTrees.
    dolthub/go-mysql-server#3330
    This expands that optimization to include CHAR and VARCHAR column types.
    BINARY, VARBINARY, JSON, GEOMETRY, etc. could be included as well with some more effort.
    Internally, these types are represented as []byte, while CHAR and VARCHAR are string, so they are not of type cmp.Ordered and need a different sorting/comparison function (binary.Compare).
    Locally, this seems to give 8-10% improvement on select ... from ... in (<str1>, <str2>, ...) queries

  • 3556: Fix CHAR_LENGTH and LIKE failing on the replacement character
    The replacement character (Unicode U+FFFD, shown when text gets garbled during encoding conversion) is a normal, valid character. But CHAR_LENGTH would error on it instead of counting it. The fix adds that size check, so the valid character (3 bytes) is accepted while genuinely broken input (1 byte) is still rejected.
    Fix #11088

  • 3555: Lookup table when not specified in DROP INDEX statements
    MySQL requires the owning table for an index be explicitly mentioned when dropping an index, but Postgres does not. This change looks up the owning table for an index when it is not specified. Because MySQL requires the table name to be specified, tests for this functionality are in the Doltgres package (PR dolthub/doltgresql#2747).

  • 3553: add partial index on WHERE predicate

  • 3552: Do not allow CASCADE and SET NULL foreign keys on columns that are referenced by STORED generated column expressions
    fixes #11065
    According to the MySQL docs:

    A foreign key constraint on the base column of a stored generated column cannot use CASCADE, SET NULL, or SET DEFAULT as ON UPDATE or ON DELETE referential actions.
    (This is actually not totally true because I was able to create a such foreign key constraint with a SET DEFAULT referential action in MySQL)
    This PR prevents adding such foreign key constraints (with the exception of SET DEFAULT) during CREATE TABLE and ALTER TABLE. Note that in MySQL, the error messages for creating a new table with an invalid foreign key and adding an invalid foreign key to an existing table are different (Cannot add foreign key constraint vs Cannot add foreign key on the base column of stored column.), but I've decided to use the same error message for both cases (Cannot add foreign key on the base column of a stored generated column.).
    CreateTable.CreateForeignKeys was removed and replaced with BaseBuilder.buildCreateTableForeignKeys to avoid a cyclical import.

  • 3551: star expression used in function

  • 3550: modify CompareJSON to use sorted object keys

  • 3546: Cache context to use for String() methods
    This is a replacement for:

    • dolthub/go-mysql-server#3525
      This accomplishes the same effective goal of passing context in the areas that we previously were not (primarily the String() function, which is load-bearing). The above PR changed the interfaces such that nodes and expressions no longer respected the fmt.Stringer interface. This PR instead caches the context inside of all nodes that need a context in their String() function by providing that context at node creation time. This was a tactic that we were already using before my original context threading PR:
    • dolthub/go-mysql-server#3513
      ...and should therefore be no worse than we were before I embarked on this journey.
      It's worth noting that the information_schema tables do not have a proper context inside of their String() function, as those tables are created when the engine is created, and SQL contexts only exist inside of connections/sessions. For now this doesn't impact anything as the Schema(ctx) methods (which use the context from String()) return a precomputed schema, however there are comments in place that warn about the nil context if those methods are ever modified.
  • 3543: Improve costed index scans for tuples by destructuring tuple operations when possible.
    This is an alternative to dolthub/go-mysql-server#3541. It's a simpler and more targeted change.
    In theory, dolthub/go-mysql-server#3541 lays the groundwork for more general-purpose analysis, since it could be used when tuples are used in additional operators (like inequalities), but it also adds additional complexity.
    I'm not sure which approach is better.

  • 3539: Bug fix for dropping sort nodes
    Also fixed a couple under-specified goup concat tests.
    The latter were relying on a particular row storage order which is not guaranteed and broke when Dolt changed some encoding parameters.

  • 3537: sql: opt-in SQL trace redaction

    Summary

    Adds an opt-in redaction layer for the SQL text and identifiers that get attached to OpenTelemetry span attributes — the planbuilder parse-span query attribute and the rowexec table/left/right/index attributes. When enabled via a new sql.Context option, identifiers and literal values are rewritten into stable, low-entropy tokens (n1, n2, ..., v1, v2, ...) that repeat across queries of the same shape so trace storage compresses well.
    Use case: multi-tenant SQL servers (Dolt is one, our own dsabstraction layer is another) where tracing data flows to shared long-term storage. Operators want privacy regulation compliance and tenant isolation without giving up trace visibility entirely.
    Default off to preserve backward compatibility — existing trace consumers reading query, table, left, right, etc. verbatim see no change. Callers opt in with sql.WithTraceRedaction(true).

    How it works

    Two passes over the same SQL, deliberately combined:

    1. Parse to AST, walk it to collect every TableIdent and ColIdent string. The grammar is the authority on which lexemes are identifiers — necessary because vitess treats hundreds of words (NAME, USER, DATA, STATUS, ...) as non-reserved keywords: the lexer emits a keyword token type for them, but real queries use them as bare column / table names.
    2. Lex the SQL and emit token-by-token. Literal token types (STRING, INTEGRAL, FLOAT, HEX, HEXNUM, BIT_LITERAL) redact as values. ID tokens redact as identifiers. COMMENT tokens drop. VALUE_ARG / LIST_ARG pass through. Any other token (keyword, punctuation, multi-char operator) emits structurally — unless its val is in the identifier set from step 1, in which case it redacts as an identifier (this catches the non-reserved-keyword-as-column-name case).
      Coverage is bounded by the grammar's notion of identifier (TableIdent + ColIdent) and the lexer's fixed set of literal token types — not by an evolving list of AST node fields. Future grammar / AST shape changes are covered automatically as long as they go through Walk and produce the same lexer token classes.
      This is deliberately distinct from sqlparser.Normalize / RedactSQLQuery, which is a plan-cache primitive that parameterizes literals only, dedupes only inside SELECT, and skips long values for CPU. The redactor here treats traces as a privacy boundary: every high-cardinality token is rewritten, always dedupes, drops comments, and falls back to <unparseable> on parse failure rather than risk a partial redaction.

    Examples

    Before: SELECT * FROM t WHERE c1 = 'could_be_sensitive'
    After:  SELECT * FROM `n1` WHERE `n2` = 'v1'
    
    Before: SELECT u.name, u.email FROM users AS u
    After:  SELECT `n1` . `n2` , `n1` . `n3` FROM `n4` AS `n1`
    

    name is a non-reserved keyword in the vitess grammar — lexed with a keyword token type, not ID. A pure lexer-driven redactor would leak it. The hybrid grammar+lex approach catches it.

    Before: WITH x (renamed_col) AS (SELECT a FROM t) SELECT * FROM x JOIN y USING (sensitive_join_col)
    After:  WITH `n1` ( `n2` ) AS ( SELECT `n3` FROM `n4` ) SELECT * FROM `n1` JOIN `n5` USING ( `n6` )
    

    CTE column-rename list, USING column list — both are []ColIdent slices on pointer parents. Picked up via the AST walk's identifier collection, redacted at lex time.

    Before: /* PII: alice@example.com */ SELECT 1 FROM t /* inline */
    After:  SELECT :v1 FROM `n1`
    

    Both margin and inline comments are dropped (the lexer emits COMMENT for both — drop happens at the lex pass).

    Concurrency

    The Mapping is eagerly allocated by NewContext when redaction is enabled (never lazy after construction), so concurrent rowexec spans firing while the parser populates the mapping never race on lazy initialization. The Mapping itself uses an internal sync.RWMutex — the fast path for already-minted tokens takes RLock, mints take Lock with a re-check after upgrade.
    A new TestMapping_ConcurrentRedactIsRaceFree exercises the production usage pattern (parent populates during parse, many goroutines read with occasional mint-on-miss) under -race for 500 iterations × 32 goroutines.

    Public API

    // sql.Context option (default off)
    sql.WithTraceRedaction(enabled bool) ContextOption
    // Methods on *Context
    (*Context).TraceRedactionEnabled() bool
    (*Context).RedactionMapping() *sqlredact.Mapping
    (*Context).RedactQueryForTrace(query string) string
    (*Context).RedactNameForTrace(name string) string
    (*Context).RedactStringerForTrace(v interface{ String() string }) string
    // New subpackage
    sqlredact.RedactSQLForTrace(sql string) (redacted string, m *Mapping, err error)
    sqlredact.RedactSQLForTraceInto(sql string, m *Mapping) (string, error)
    sqlredact.NewMapping() *Mapping

    Commits

    1. sqlredact: SQL trace redaction for span attributes (opt-in) — new sql/sqlredact package (parse + lex hybrid, the Mapping with sync.RWMutex), new sql.Context option and helpers, tests including the concurrency stress.
    2. trace: redact SQL identifiers in span attributes — wires planbuilder/parse.go, rowexec/rel.go, rowexec/join_iters.go, rowexec/range_heap_iter.go, and rowexec/ddl_iters.go through the new helpers.

    Test plan

    • go build ./... for ./sql and ./sql/sqlredact clean
    • go test ./sql ./sql/sqlredact all pass (incl. testify assertions and the concurrency test under -race)
    • gofmt -l clean on touched files
    • enginetest end-to-end coverage — not yet added; per CONTRIBUTING.md this is expected. Happy to add a query+expected-redacted-trace fixture if there's an existing pattern for span-attribute assertions, or open to guidance on the right scaffolding.

    Open questions for review

    • Token format n1/v1/:v1/X'v1' — chosen to be short and repeating for compression density. Happy to adopt a different convention (e.g. _redacted_n1) if the project prefers more obviously synthetic markers.
    • The <redacted> placeholder for LIMIT/OFFSET Stringer attrs drops the value entirely under redaction (see commit message rationale). Open to alternative: re-tokenize the fragment text against the mapping, accepting that pushdown-generated synthetic identifiers won't have entries.
    • Any existing convention for end-to-end tests of span attributes that I should hook into?
      🤖 Generated with Claude Code
  • 3532: replace all decimal.Decimal with *apd.Decimal

vitess

  • 477: Adding Columns field to TableFuncExpr
    Allows aliasing columns from a table function.
    Needed primarily for Doltgres, which supports more expressive table functions than MySQL.
  • 476: Small fixes for functional indexes
    • adds test coverage for multi column function indexes
    • fixes Walk() to walk index fields
  • 474: go/mysql: add Conn.WaitForClientActivity to detect a departed client
    On context cancelation, the function returns with a nil error. If the client unexpectedly writes to the connection or closes it, then this method will return a non-nil error.
    Unlike the first attempt at this method, this new implementation accounts for LoadDataInFile. It uses a preempt-able read lease to let the handler read from the client socket even while WaitForClientActivity is outstanding. The Peek becomes active once again after the reads are issued and completed.
  • 473: Revert "Merge pull request #472 from dolthub/aaron/vitess-async-read-eof"
    This reverts commit 02705d5447c2e7062c3ae31f6909d4e5e1c97812, reversing changes made to 0893abc805429d8a31ea9fa395ff118fa95474da.
  • 472: go/mysql: Conn: Add WaitForClientActivity, which has semantics that allow a server to quickly cancel inflight work if a client goes away.
  • 471: add not valid on fkey and check constraints
  • 470: Expand the set of function call expressions that can be used as a column default value without requiring parentheses.
    These forms are not valid MySQL but are accepted by MariaDB. We should also accept them in order to have better compatibility with schemas created for MariaDB.
  • 469: add predicate to indexspec
  • 467: Add ERWarnDeprecatedSyntax 1287
    Blocks #10983

Closed Issues

  • 11467: Dolt panics on a non-numeric NTILE bucket expression
  • 11540: prolly/tree: DiffOp stringer is stale — entry 12 unlabelled, one label transposed, one -linecomment wrong
  • 11455: TRIM panics on a native TIME value
  • 11488: Make CALL DOLT_BACKUP('sync', ...) a no-op when nothing has changed
  • 11517: Dolt panics on a numeric FORMAT locale from a window expression
  • 11518: Dolt panics on empty LIKE ... ESCAPE '' within window expressions
  • 3707: SHOW INDEX FROM table WHERE key_name = ? ignores the WHERE filter
  • 3706: Constraint-violation errors return SQLSTATE HY000 instead of 23000 (MySQL parity gap)
  • 3708: Unmodified Drupal core install fails with "already an active transaction" against Dolt (works against MySQL)
  • 2877: MemoryDB: Building non-unique indexes is nondeterministic
  • 3622: Clean up: move sorters in sql/expression/sort.go out of expression package
  • 3560: CachedResults / HashLookup chain leaks rows-cache for every hash join until process restart

Don't miss a new dolt release

NewReleases is sending notifications on new releases.