Skip to content

Add fast path for binary CompiledFuncs - #3029

Merged
jycor merged 4 commits into
mainfrom
james/gb
Aug 5, 2026
Merged

Add fast path for binary CompiledFuncs#3029
jycor merged 4 commits into
mainfrom
james/gb

Conversation

@jycor

@jycor jycor commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

We can avoid memory allocations if we know the number of arguments we're going to process.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
Main PR
covering_index_scan_postgres 2219.51/s 2197.86/s -1.0%
groupby_scan_postgres 149.78/s 159.96/s +6.7%
index_join_postgres 728.00/s 713.31/s -2.1%
index_join_scan_postgres 937.74/s 939.19/s +0.1%
index_scan_postgres 34.00/s 33.81/s -0.6%
oltp_delete_insert_postgres 962.49/s 900.41/s -6.5%
oltp_insert 854.81/s 832.78/s -2.6%
oltp_point_select 4024.57/s 3984.22/s -1.1%
oltp_read_only 3760.32/s 3718.04/s -1.2%
oltp_read_write 2828.97/s 2780.97/s -1.7%
oltp_update_index 869.56/s 857.87/s -1.4%
oltp_update_non_index 968.18/s 907.26/s -6.3%
oltp_write_only 1977.59/s 2019.62/s +2.1%
select_random_points 2305.28/s 2260.38/s -2.0%
select_random_ranges 1728.53/s 1711.55/s -1.0%
table_scan_postgres 33.61/s 33.25/s -1.1%
types_delete_insert_postgres 845.69/s 930.50/s +10.0%
types_table_scan_postgres 14.79/s 15.02/s +1.5%

@itoqa

itoqa Bot commented Aug 4, 2026

Copy link
Copy Markdown

Ito QA test results
Commit: 8555be9: 14 test cases ran, 11 passed ✅, 3 additional findings ⚠️.

Summary

Coverage spans clean builds, server startup and shutdown, basic database operations, prepared-query behavior, connection isolation and recovery, and stable text and binary data handling. It also exercises adversarial malformed-input cases, revealing unsafe error handling while normal application behavior remains healthy.

Safe to merge — the failures identify medium-severity pre-existing defects in reset-state cleanup and malformed wire-input handling, but none are attributable to this dependency-only PR, with no regressions or newly introduced failures. These findings are suitable for follow-up rather than merge blockers.

Tests run by Ito

View full run

Result Severity Type Description
Build The updated dependency downloaded successfully, the Linux build produced the Doltgres artifact, and the focused utility tests passed.
Build A fresh server started with its own data folder, became ready, and completed the table, insert, and select checks. It stopped cleanly and left no process or data-folder residue.
Build The focused wire checks and broad SQL test coverage passed after the local test container was restored and its missing PostgreSQL tools were installed. The earlier errors came from the test environment and command setup, not from the application code.
Engine Creating a table, inserting a row, and running SELECT all succeeded. The query returned pk 7 and the command result returned 1.
Engine The invalid query returned a controlled SQL error, and the same connection then returned 1 and the saved row with pk 7.
Engine The prepared query reported the expected column metadata, accepted the value 7, and returned the matching row.
Engine Direct and prepared queries returned the same values, column names, type IDs, and modifiers across repeated runs.
Session The query description showed the pk column before a value was supplied, and running it with 7 returned 7.
Session Resetting one database connection did not change the other connection's prepared query. Both clients returned their own values, and the service stayed healthy.
Wire A text query returned the expected column name, integer type, width, modifier, and value 7 through the PostgreSQL wire protocol.
Wire Integer, bit, date, time, and array values were returned in binary format with the expected values and NULL marker.
⚠️ Medium severity Session The selected database stayed available and a new query returned 7, but the reset did not prove that the old prepared statement was removed. The server code keeps the old statement in the connection until the client closes it.
⚠️ Medium severity Wire A short binary integer value is not rejected before decoding. The request produces a recovered server panic instead of a normal validation error.
⚠️ Medium severity Wire The malformed array is rejected with an error, but the server reports a recovered panic after attempting to read 4,294,967,294 bytes from a four-byte buffer.
Additional Findings Details

These findings are unrelated to the current changes but were observed during testing.

🟡 Reset leaves old prepared statements available
  • Severity: Medium Medium severity
  • Description: The selected database stayed available and a new query returned 7, but the reset did not prove that the old prepared statement was removed. The server code keeps the old statement in the connection until the client closes it.
  • Impact: A client can reuse stale prepared statements after asking for a clean session, so reset does not fully clear connection state. Applications that rely on reset for isolation may see unexpected results or errors until they close the connection.
  • Steps to Reproduce:
    1. Connect to the local PostgreSQL service and select the sqllogictest database.
    2. Create a named prepared statement on the connection.
    3. Run DISCARD ALL on that same connection.
    4. Try to describe or execute the old named prepared statement and check whether it is rejected as cleared.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: The reset path is split between /tmp/output-agent-workspace/repo/server/connection_handler.go and /tmp/output-agent-workspace/repo/server/doltgres_handler.go. In connection_handler.go:523-525, DISCARD ALL is intercepted and routed to discardAll. discardAll at lines 1230-1239 calls DoltgresHandler.ComResetConnection and sends CommandComplete, but it never clears h.preparedStatements or h.portals. ComResetConnection at doltgres_handler.go:240-259 closes the engine session, creates a replacement session, and restores the selected database; it does not have access to or clear the protocol handler maps. The maps are created once per connection in connection_handler.go:111-112, populated by handleParse at lines 603-608 and handleBind at lines 685-689, and read by handleDescribe at lines 619-635 and handleBind at lines 647-650. Therefore an old named statement can remain addressable after DISCARD ALL even though its engine session was replaced. The smallest fix is to clear h.preparedStatements and h.portals in discardAll after a successful reset, or otherwise make the reset operation explicitly invalidate those two per-connection maps. The PR diff in pr-context.json changes only dependency entries in go.mod and go.sum, so it does not introduce this behavior.
Evidence Package
🟡 Malformed integer input triggers a server panic
  • Severity: Medium Medium severity
  • Description: A short binary integer value is not rejected before decoding. The request produces a recovered server panic instead of a normal validation error.
  • Impact: A client that sends a malformed binary integer gets an error, but the server panics while decoding the request first. The server stays available in the observed case, with no evidence of data loss or a wider outage.
  • Steps to Reproduce:
    1. Connect to the local PostgreSQL server with a client that can send extended-protocol binary parameters.
    2. Bind a parameter declared as INT4 using a payload containing only three bytes instead of four.
    3. Observe the returned protocol error and the recovered panic stack, then run SELECT 1 to verify the server remains available.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: server/functions/int4.go defines int4recv at lines 69-82. Its Callable converts val to []byte, returns nil only for a nil value, creates a reader with utils.NewWireReader(data), and immediately returns reader.ReadInt32() without checking that len(data) is exactly four bytes. ReadInt32 at utils/wirerw.go:68-70 delegates to ReadUint32; ReadUint32 at lines 92-97 calls sliceForRead(4) before advancing readIdx. sliceForRead at lines 132-139 compares the requested length with the remaining buffer and deliberately calls panic(fmt.Sprintf(...)) when fewer than four bytes remain. The captured three-byte bind follows this exact path and the stack identifies int4recv at server/functions/int4.go:81 and sliceForRead at utils/wirerw.go:136. The focused utils/wirerw_test.go:23-43 also explicitly asserts that short reads panic, so this behavior is reproducible source behavior rather than a client or browser artifact. The smallest practical fix is to make the INT4 receive path validate the payload length and return a controlled PostgreSQL error, or to add an error-returning checked read for receive functions, rather than allowing malformed wire input to reach the panic-only reader.
Evidence Package
🟡 Malformed array length triggers a server panic
  • Severity: Medium Medium severity
  • Description: The malformed array is rejected with an error, but the server reports a recovered panic after attempting to read 4,294,967,294 bytes from a four-byte buffer.
  • Impact: A malformed array request can trigger a server panic and expose internal error details. The connection remains usable for later queries, so the effect is limited to the affected request.
  • Steps to Reproduce:
    1. Connect to the local PostgreSQL listener with a client that can send binary parameters.
    2. Send a one-dimensional array payload whose element length field is -2.
    3. Observe the error response and then run SELECT 1 on the same connection.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: server/functions/array.go:204-218 reads each element length as int32 and uses -1 as the only NULL marker. At lines 208-210, any other value, including -2, is passed through uint32(elementLen) and sent to reader.ReadBytes. Therefore -2 becomes 4294967294 instead of being rejected as an invalid negative length. utils/wirerw.go:121-125 forwards that value to sliceForRead, and utils/wirerw.go:128-139 panics when the requested length exceeds the remaining buffer. The captured WIRE-4 response follows this exact path: array_recv_callable at server/functions/array.go:210, ReadBytes at utils/wirerw.go:123, and sliceForRead at utils/wirerw.go:136. The smallest practical fix is to return a controlled malformed-input error in array_recv_callable when elementLen < -1, before converting it to uint32; the shared reader panic should not be used as normal validation for this field.
Evidence Package

Tip

Reply with @itoqa to send us feedback on this test run.

@itoqa

itoqa Bot commented Aug 4, 2026

Copy link
Copy Markdown

Ito QA test results
Ito Diff Report8555be93fa8836: 17 test cases ran, 3 fixed ✅, 13 passing ✅, 1 additional finding ⚠️.

Diff Summary

Broad coverage exercised database function execution, argument dispatch, defaults, variadic and NULL handling, error recovery, session reset behavior, and malformed-input defenses. The tested behavior is broadly healthy across normal workflows, edge cases, and adversarial protocol inputs, with one existing limitation in named result columns for table-returning functions.

Safe to merge — the only failure is a high-severity pre-existing behavior issue explicitly marked as unrelated to this PR, with no regressions or PR-attributable failures identified. The table-function limitation is a flag for later rather than a merge blocker for this change.

Tests run by Ito

View full run

Result State Severity Type Description
❌->✅ Fixed Session Resetting the connection kept qa_session selected, removed the temporary table, and allowed a fresh query to return 7.
❌->✅ Fixed Wire Malformed binary lengths are handled by explicit bounds checks, and receive-time panics are recovered into the connection error path. The local target was unavailable, so the protocol exchange could not be replayed, but source inspection found the expected protection.
❌->✅ Fixed Wire A negative array element length other than NULL is rejected before the server reads outside the message buffer. The live endpoint was unavailable, but source inspection supports safe handling and found no application defect.
Passing Conversion A query with a NULL input returned true instead of raising a division-by-zero error, as expected.
Passing Conversion A prepared query returned the expected division-by-zero error, then returned the correct value on retry. An unrelated query also matched the fresh-session control.
Passing Dispatch The local database returned the non-empty version value 15.17 for the server-version query. The query used one argument, so it confirms the one-argument function path rather than the planned zero-argument path.
Passing Dispatch The database returned the expected text and JSON values for calls with two, three, and four arguments. No values were ignored or shifted.
Passing Dispatch The database returned all seven key-value pairs in the JSON object, including the final pair, with the supplied values preserved.
Passing Dispatch Calls that leave optional values out, provide every value, or repeat the call in a query all return the expected values in the correct positions. The prepared-statement check was not part of this result because prepared statements are an explicitly unsupported feature.
Passing Execution The SQL function was created successfully, and calling it with 4 and 5 returned 9.
Passing Execution The PL/pgSQL function was created successfully, and calling it with 6 returned 12 as expected.
Passing Execution Running the set-returning query returned exactly three rows: 1, 2, and 3 in order.
Passing Execution SQL and PL/pgSQL routines returned the same values as the direct call for typed, NULL, and repeated inputs. A bad integer cast returned a controlled error, and the next valid query succeeded.
Passing Variadic The database returned the number, text, empty value, and final number in the same order: [1, "two", null, 4].
Passing Variadic The database returned one for the one-value call and abcd for the four-value call. All supplied values were kept in order.
Passing Variadic The JSON result kept the middle null and the value after it. String concatenation kept the later text, and the strict length check returned null as expected.
⏸️ Skipped Build The updated dependency downloaded successfully, the Linux build produced the Doltgres artifact, and the focused utility tests passed.
⏸️ Skipped Build A fresh server started with its own data folder, became ready, and completed the table, insert, and select checks. It stopped cleanly and left no process or data-folder residue.
⏸️ Skipped Build The focused wire checks and broad SQL test coverage passed after the local test container was restored and its missing PostgreSQL tools were installed. The earlier errors came from the test environment and command setup, not from the application code.
⏸️ Skipped Engine Creating a table, inserting a row, and running SELECT all succeeded. The query returned pk 7 and the command result returned 1.
⏸️ Skipped Engine The invalid query returned a controlled SQL error, and the same connection then returned 1 and the saved row with pk 7.
⏸️ Skipped Engine The prepared query reported the expected column metadata, accepted the value 7, and returned the matching row.
⏸️ Skipped Engine Direct and prepared queries returned the same values, column names, type IDs, and modifiers across repeated runs.
⏸️ Skipped Session The query description showed the pk column before a value was supplied, and running it with 7 returned 7.
⏸️ Skipped Session Resetting one database connection did not change the other connection's prepared query. Both clients returned their own values, and the service stayed healthy.
⏸️ Skipped Wire A text query returned the expected column name, integer type, width, modifier, and value 7 through the PostgreSQL wire protocol.
⏸️ Skipped Wire Integer, bit, date, time, and array values were returned in binary format with the expected values and NULL marker.
⚠️ Additional Finding High severity Execution The function produced the expected rows, but the declared result name was lost. Reading q.value failed with an error saying that q has no value column.
Additional Findings Details

These findings are unrelated to the current changes but were observed during testing.

🟠 Table functions hide named result columns
  • Severity: High High severity
  • Description: The function produced the expected rows, but the declared result name was lost. Reading q.value failed with an error saying that q has no value column.
  • Impact: Users calling a table-returning function cannot read its declared result columns by name. This breaks the affected SQL workflow until the function metadata is corrected.
  • Steps to Reproduce:
    1. Create a SQL-language function named qa_series(start_n integer, stop_n integer) that returns TABLE(value integer) and selects generate_series(start_n, stop_n).
    2. Run SELECT * FROM qa_series(1, 3) and confirm that three rows are returned.
    3. Use the function as q and run SELECT q.value FROM qa_series(1, 3) AS q.
    4. Observe that the query fails because the returned record has no value column, although value was declared in RETURNS TABLE.
  • Stub / mock content: The local SQL server ran with authentication disabled for QA access. No application response data, function behavior, or result rows were mocked or intercepted.
  • Code Analysis: The failure is supported by the production path rather than only by the unavailable browser target. In server/ast/create_function.go:59-64, RETURNS TABLE is converted into an anonymous composite ReturnType through createAnonymousCompositeType, while the ordinary routine parameter list remains separate. server/ast/create_function.go:187-208 creates the composite attributes from the declared table columns, but passes int16(i) at line 191 even though server/types/composite.go:75 and :79-80 define CompositeAttribute.Num as one-based. During persistence, server/node/create_function.go:117-136 serializes only c.Parameters into procedures.Parameter values, so the RETURNS TABLE columns are not present in AllParams. When the function is reconstructed, server/functions/framework/provider.go:97-108 supplies SQLFunction with ReturnType, AllParams, and AllTypes but does not populate a separate ReturnTableType. Consequently server/functions/framework/sql_function.go:65-78 builds the OUT schema only by filtering AllParams for OUT and INOUT modes, producing no named output columns for RETURNS TABLE. server/functions/framework/compiled_function.go:189-195 exposes that empty schema to the table-function interface, and :497-503 passes it to SRF row iteration. The smallest practical fix is to preserve the RETURNS TABLE column definitions in the persisted/reconstructed function metadata and have SQLFunction.GetOutParameters return that schema for table returns; independently, change the anonymous attribute number at create_function.go:191 to int16(i+1). The current PR does not change any of these paths.
Evidence Package

Tip

Reply with @itoqa to send us feedback on this test run.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
Main PR
Total 42090 42090
Successful 18918 18918
Failures 23172 23172
Partial Successes1 5325 5325
Main PR
Successful 44.9465% 44.9465%
Failures 55.0535% 55.0535%

Footnotes

  1. These are tests that we're marking as Successful, however they do not match the expected output in some way. This is due to small differences, such as different wording on the error messages, or the column names being incorrect while the data itself is correct.

@itoqa

itoqa Bot commented Aug 5, 2026

Copy link
Copy Markdown

Ito QA test results
Ito Diff Report3fa88367da9f9e: 18 test cases ran, 1 fixed ✅, 16 passing ✅, 1 additional finding ⚠️.

Diff Summary

Coverage spans core function execution and result handling, including normal calls, argument ordering, defaults, numeric and array values, return types, set-returning results, and grouped operations. It also exercises edge and error paths such as NULL handling, invalid conversions, failed calls followed by retries, malformed variadic definitions, and connection recovery.

Safe to merge — the only observed failure is an unrelated, pre-existing limitation in expanded SQL variadic calls and is not attributable to this PR; no regression or PR-caused failure was identified. The remaining coverage indicates low merge risk, with the unrelated variadic limitation best treated as a flag for later.

Tests run by Ito

View full run

Result State Severity Type Description
❌->✅ Fixed Execution Source review found that set-returning calls keep their rows and multi-OUT records in the expected shape. The earlier invocation error could not be tied to this production code, and the follow-up check was limited by unavailable local server infrastructure.
Passing Conversion A prepared function call returned the expected error for an invalid second value. A valid retry and a separate query on the same connection both returned the correct results.
Passing Conversion The non-strict function received NULL and returned its NULL-aware result. A non-NULL value also returned the expected result, so argument handling works correctly.
Passing Conversion The invalid second value returned the expected conversion error. A valid repeat call and a later control query both succeeded, so the failed call did not affect the connection.
Passing Conversion A strict call with NULL returned NULL without evaluating the invalid later value. The same behavior worked for a binary operator and a row-based filter; the separate constant-cast error came from planning the query, not from the function call.
Passing Conversion A bad second value returned the expected cast error each time. Later valid calls returned the right results, so the failed call did not affect the connection.
Passing Dispatch The concatenation and JSON calls returned every supplied value in the original order.
Passing Dispatch A function used its default values in the correct positions when some inputs were left out, and kept all values in order when every input was supplied. The same behavior held in a computed projection; the prepared-statement check was unavailable because this server does not support PREPARE.
Passing Dispatch Both the direct query and the table-style query returned 12 as an integer.
Passing Dispatch Adding 2.5 and 2 returned 4.5 with the numeric type. The prepared-statement check could not run because this local server build does not support PREPARE or EXECUTE.
Passing Dispatch Integer array functions returned the expected length and joined values. The prepared-statement check could not run because this local server does not support prepared statements.
Passing Dispatch One-, two-, and three-argument calls returned the expected text, array order, and null value. The direct checks found no user-facing error at the two-argument optimization boundary.
Passing Execution Direct, SQL-language, and PL/pgSQL calls returned the expected text values, preserved NULL, and stayed usable on a repeated call.
Passing Execution Arithmetic returned 12 and comparison returned true. The client also received the expected integer and boolean type information.
Passing Execution Grouped rows kept every variadic argument, and the group containing NULL values kept the correct row and non-NULL counts.
Passing Execution Set-returning queries returned all expected rows and values. Column types stayed correct, NULL handling was preserved, and the session worked normally after an invalid cast.
Passing Variadic Creating a variadic function with a non-array target returned a clear error, and the same connection successfully ran a later query.
⏸️ Skipped Conversion A query with a NULL input returned true instead of raising a division-by-zero error, as expected.
⏸️ Skipped Dispatch The local database returned the non-empty version value 15.17 for the server-version query. The query used one argument, so it confirms the one-argument function path rather than the planned zero-argument path.
⏸️ Skipped Dispatch The database returned all seven key-value pairs in the JSON object, including the final pair, with the supplied values preserved.
⏸️ Skipped Execution The SQL function was created successfully, and calling it with 4 and 5 returned 9.
⏸️ Skipped Execution The PL/pgSQL function was created successfully, and calling it with 6 returned 12 as expected.
⏸️ Skipped Execution Running the set-returning query returned exactly three rows: 1, 2, and 3 in order.
⏸️ Skipped Session Resetting the connection kept qa_session selected, removed the temporary table, and allowed a fresh query to return 7.
⏸️ Skipped Variadic The database returned the number, text, empty value, and final number in the same order: [1, "two", null, 4].
⏸️ Skipped Variadic The database returned one for the one-value call and abcd for the four-value call. All supplied values were kept in order.
⏸️ Skipped Variadic The JSON result kept the middle null and the value after it. String concatenation kept the later text, and the strict length check returned null as expected.
⏸️ Skipped Wire Malformed binary lengths are handled by explicit bounds checks, and receive-time panics are recovered into the connection error path. The local target was unavailable, so the protocol exchange could not be replayed, but source inspection found the expected protection.
⏸️ Skipped Wire A negative array element length other than NULL is rejected before the server reads outside the message buffer. The live endpoint was unavailable, but source inspection supports safe handling and found no application defect.
⚠️ Additional Finding Medium severity Variadic The function is created, but a call with expanded variadic values fails with a function-not-found error instead of returning the fixed value and the ordered variadic array.
Additional Findings Details

These findings are unrelated to the current changes but were observed during testing.

🟡 Expanded SQL variadic calls cannot resolve
  • Severity: Medium Medium severity
  • Description: The function is created, but a call with expanded variadic values fails with a function-not-found error instead of returning the fixed value and the ordered variadic array.
  • Impact: Users cannot call SQL variadic functions with expanded values, so affected queries fail instead of returning the expected result. They can avoid this specific path by using non-variadic functions or calls that do not expand the arguments.
  • Steps to Reproduce:
    1. Create a SQL-language function with one fixed integer parameter followed by VARIADIC integer[].
    2. Call the function with one fixed integer and three additional integer arguments, such as qa_variadic_pack(7, 11, 13, 17).
    3. Check the result: the call returns a function-not-found error instead of passing 7 separately and [11, 13, 17] as one array.
  • Stub / mock content: The test used a locally created SQL-language function and a local database connection; no stubs, mocks, or application bypasses were applied.
  • Code Analysis: SQLFunction.VariadicIndex in server/functions/framework/sql_function.go:118-122 returns -1 unconditionally, even when SQLFunction.Variadic is true and AllParams contains a ParameterMode_VARIADIC parameter. Overloads.overloadsForParams in server/functions/framework/overloads.go:75-131 only expands a function when overload.VariadicIndex() is non-negative; with -1, the SQL function remains a two-parameter signature and cannot match the four supplied integer arguments. The later CompiledFunction.Eval path in server/functions/framework/compiled_function.go:471-484 calls coalesceVariadicValues only after a variadic overload has been selected, so that array packaging cannot repair the failed resolution. The smallest practical fix is to make SQLFunction.VariadicIndex return the input-parameter index of its ParameterMode_VARIADIC entry, allowing the existing overload expansion and coalescing code to handle the call.
Evidence Package

Tip

Reply with @itoqa to send us feedback on this test run.

@jycor jycor changed the title test no string gb Add fast path for binary CompiledFuncs Aug 5, 2026

@fulghum fulghum left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jycor
jycor enabled auto-merge (squash) August 5, 2026 21:10
@itoqa

itoqa Bot commented Aug 5, 2026

Copy link
Copy Markdown

Ito QA test results

History reset (rebase or force-push detected). Starting test narrative over.

Commit: 36ad825: 14 test cases ran, 1 failed ❌, 13 passed ✅.

Summary

Coverage spans core database expression behavior, including normal function and operator results, type conversion, return types, filtering, set-returning queries, and server recovery after errors. It also exercises edge cases involving nulls, invalid inputs, polymorphic values, and error propagation, with overall behavior healthy except for a crash-prone array operation.

Merge with caution — the PR introduces a medium-severity server crash in a specific polymorphic array input path, making this an attributable reliability regression rather than a harmless test issue. The remaining exercised behavior is healthy, but the crash warrants a targeted fix before treating the change as fully safe.

Tests run by Ito

View full run

Result Severity Type Description
Medium severity Arrays The database crashes when a text literal is appended to an integer array. The expected behavior is to convert the compatible value and return the new array, or return a controlled SQL error without a panic.
Arrays Array concatenation and append returned integer arrays, while position lookups returned integer positions for integer and text arrays.
Casts Two-argument SQL functions returned the expected values, so compatible inputs reached the functions without conversion errors.
Casts The rounding query accepted the integer precision value, returned 1.23, and matched the result from the explicitly typed call.
Casts An invalid numeric value returned the same conversion error on both attempts. The second expression was not evaluated, and the function did not run after the first error.
Dispatch The local SQL server returned 8 for power(2, 3), so a normal two-argument built-in function completed successfully.
Dispatch The comparison 5 > 2 returned true, and the two-argument procedure returned 5 as expected.
Dispatch Typed, cast-required, and repeated two-argument calculations all returned 8 with the expected integer type.
Dispatch The direct and cast-required queries both returned 8 as double precision. The prepared-query check could not run because this local SQL engine does not support PREPARE.
Nulls The strict function returned SQL NULL when its first value was NULL, without evaluating the erroring second expression.
Nulls Invalid argument values and function failures reach the client as their original errors, with no successful result or duplicate failure.
Runtime The project built and passed its full Go test suite, the local SQL server started, and a basic binary expression returned 42 as an integer.
Runtime The query returned the complete ordered sequence from 2 through 6, with all five rows present.
Runtime Filtering and text conversion returned the expected row and type. A division-by-zero error was reported safely, and the server still answered the next query.

Tip

Reply with @itoqa to send us feedback on this test run.

Comment thread server/functions/framework/compiled_function.go
@jycor
jycor merged commit 9e82e54 into main Aug 5, 2026
27 of 28 checks passed
@jycor
jycor deleted the james/gb branch August 5, 2026 22:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants