Skip to content

Window function fixes#2894

Open
fulghum wants to merge 4 commits into
mainfrom
fulghum/window-functions
Open

Window function fixes#2894
fulghum wants to merge 4 commits into
mainfrom
fulghum/window-functions

Conversation

@fulghum

@fulghum fulghum commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Related to #1796

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor
Main PR
covering_index_scan_postgres 1806.67/s 1834.14/s +1.5%
groupby_scan_postgres 123.50/s ${\color{red}105.02/s}$ ${\color{red}-15.0\%}$
index_join_postgres 645.51/s 649.12/s +0.5%
index_join_scan_postgres 787.77/s 790.37/s +0.3%
index_scan_postgres 24.26/s 24.44/s +0.7%
oltp_delete_insert_postgres 781.25/s 757.82/s -3.0%
oltp_insert 668.23/s 659.34/s -1.4%
oltp_point_select 2784.69/s 2816.29/s +1.1%
oltp_read_only 2794.00/s 2825.76/s +1.1%
oltp_read_write 2294.73/s 2223.87/s -3.1%
oltp_update_index 712.56/s 691.45/s -3.0%
oltp_update_non_index 733.14/s 719.07/s -2.0%
oltp_write_only 1733.36/s 1670.08/s -3.7%
select_random_points 1764.65/s 1807.30/s +2.4%
select_random_ranges 1060.89/s 1071.52/s +1.0%
table_scan_postgres 23.53/s 23.30/s -1.0%
types_delete_insert_postgres 745.60/s 718.02/s -3.7%
types_table_scan_postgres 10.34/s 10.08/s -2.6%

@itoqa

itoqa Bot commented Jul 1, 2026

Copy link
Copy Markdown

Ito QA test results
Commit: 20df33e: 10 test cases ran, 4 failed ❌, 5 passed ✅, 1 additional finding ⚠️.

Summary

The run covered SQL analytics behavior around window functions, including normal query flows and tougher compositions like sorting by computed ranks, lateral subqueries, and aggregate expressions. Basic lateral and conformance-style paths looked healthy, but several edge-case query shapes still crash instead of returning results or typed errors.

Not safe to merge yet — this change appears to introduce multiple failures in the same window-query execution area, including runtime crashes on valid analytics patterns. While some baseline and regression paths pass and at least one similar issue appears pre-existing, the newly introduced crash-level defects make merge risk high for production query reliability.

Tests run by Ito

View full run

Result Severity Type Description
Medium severity Output Transparent wrapper depth changes planner shape, but casting logic only handles direct Window or one-hop wrappers, so equivalent queries fail with a row field-index error instead of returning ranked rows.
Medium severity Output The engine panics in numeric implicit-cast evaluation when the CASE expression consumes rank values that were sanitized to int64.
Minor severity Output The engine errors when an outer ORDER BY targets the computed rank/dense_rank output, indicating a mismatch between expected field indices and the produced row schema.
Minor severity Regression The non-empty variant fails with interface conversion panic (float64 to int32) in int4 output/send during row encoding, while the empty variant passes because no row serialization occurs.
Interface Window functions in the select list with a subquery-based filter executed successfully and returned 8 rows without unsupported window-evaluation errors.
Interface LATERAL subquery with row_number() OVER (ORDER BY o_id) returned correct per-customer row numbers and completed without scalar-eval fallback errors.
Interface Composed LATERAL window queries with arithmetic, COALESCE, CASE, and nested subquery wrapping all executed successfully without ErrWindowUnsupported errors.
Regression The upstream window conformance package test ran and passed, confirming this path is active instead of skipped.
Regression The scripted window regression suite passed, and the runner-blocked status came from a harness shutdown hang after completion rather than a product defect.
⚠️ Medium severity Output The query crashes during execution when ORDER BY references the projected window rank alias, even though baseline window query execution and metadata typing succeed.
Additional Findings Details

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

🟡 Window rank query fails under outer ORDER BY
  • Severity: Medium Medium severity
  • Description: The query crashes during execution when ORDER BY references the projected window rank alias, even though baseline window query execution and metadata typing succeed.
  • Impact: Queries that combine a window rank projection with an outer sort on that rank can fail at runtime, blocking affected analytics and reporting flows.
  • Steps to Reproduce:
    1. Create and seed table o with rows that allow rank() OVER (PARTITION BY c_id ORDER BY o_id).
    2. Run SELECT c_id, o_id, rank() OVER (PARTITION BY c_id ORDER BY o_id) AS rnk FROM o ORDER BY rnk;
    3. Observe runtime failure: unable to find field with index 4 in row of 4 columns.
  • Stub / mock content: Authentication was bypassed in the QA run via QA_AUTH_BYPASS=1 in the auth handler, but no data-path mock or query-result stub was applied to the window execution path under test.
  • Code Analysis: TypeSanitizer adds special rewriting for Project/Filter/GroupBy when the child is a Window or a one-hop wrapper such as Sort (server/analyzer/type_sanitizer.go lines 51-73 and 272-283). The failing query shape is exactly this window-plus-sort path, and the runtime error indicates a row field index mismatch (index 4 for a 4-column row), which is consistent with expression/schema misalignment in this analyzer rewrite path when ORDER BY consumes projected window output.
Evidence Package

Tip

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

Comment thread server/analyzer/type_sanitizer.go
Comment thread server/analyzer/type_sanitizer.go
Comment thread server/analyzer/type_sanitizer.go
Comment thread server/analyzer/type_sanitizer.go
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor
Main PR
Total 42090 42090
Successful 18275 18291
Failures 23815 23799
Partial Successes1 5335 5340
Main PR
Successful 43.4189% 43.4569%
Failures 56.5811% 56.5431%

${\color{red}Regressions (1)}$

matview

QUERY:          CREATE VIEW mvtest_tvv AS SELECT sum(totamt) AS grandtot FROM mvtest_tv;
RECEIVED ERROR: in aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'sum(mvtest_tv.totamt)'; this is incompatible with sql_mode=only_full_group_by (errno 1140) (sqlstate HY000)

${\color{lightgreen}Progressions (18)}$

aggregates

QUERY: SELECT sum(four) AS sum_1500 FROM onek;
QUERY: SELECT sum(a) AS sum_198 FROM aggtest;
QUERY: select sum('NaN'::numeric) from generate_series(1,3);
QUERY: select avg('NaN'::numeric) from generate_series(1,3);
QUERY: select ten, count(*), sum(four) from onek
group by ten order by ten;
QUERY: select ten, count(four), sum(DISTINCT four) from onek
group by ten order by ten;
QUERY: select unique1, count(*), sum(twothousand) from tenk1
group by unique1
having sum(fivethous) > 4975
order by sum(twothousand);

numeric

QUERY: SELECT SUM(9999::numeric) FROM generate_series(1, 100000);
QUERY: SELECT SUM((-9999)::numeric) FROM generate_series(1, 100000);

subselect

QUERY: select sum(ss.tst::int) from
  onek o cross join lateral (
  select i.ten in (select f1 from int4_tbl where f1 <= o.hundred) as tst,
         random() as r
  from onek i where i.unique1 = o.unique1 ) ss
where o.ten = 0;
QUERY: select sum(o.four), sum(ss.a) from
  onek o cross join lateral (
    with recursive x(a) as
      (select o.four as a
       union
       select a + 1 from x
       where a < 10)
    select * from x
  ) ss
where o.ten = 1;

window

QUERY: SELECT row_number() OVER (ORDER BY unique2) FROM tenk1 WHERE unique2 < 10;
QUERY: SELECT * FROM(
  SELECT count(*) OVER (PARTITION BY four ORDER BY ten) +
    sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS total,
    count(*) OVER (PARTITION BY four ORDER BY ten) AS fourcount,
    sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS twosum
    FROM tenk1
)sub
WHERE total <> fourcount + twosum;
QUERY: SELECT rank() OVER (ORDER BY length('abc'));
QUERY: SELECT * FROM
  (SELECT empno,
          salary,
          rank() OVER (ORDER BY salary DESC) r
   FROM empsalary) emp
WHERE r <= 3;
QUERY: SELECT * FROM
  (SELECT empno,
          salary,
          dense_rank() OVER (ORDER BY salary DESC) dr
   FROM empsalary) emp
WHERE dr = 1;
QUERY: SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
  FROM (VALUES(1,1),(2,2),(3,3),(4,4)) t(i,v);

with

QUERY: WITH RECURSIVE t(n) AS (
    VALUES (1)
UNION ALL
    SELECT n+1 FROM t WHERE n < 100
)
SELECT sum(n) FROM t;

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.

@fulghum fulghum force-pushed the fulghum/window-functions branch from 3d68acb to 2bbe503 Compare July 6, 2026 20:53
@itoqa

itoqa Bot commented Jul 6, 2026

Copy link
Copy Markdown

Ito QA test results
Ito Diff Report20df33e2bbe503: 20 test cases ran, 2 new failures ❌, 3 fixed ✅, 10 passing ✅, 5 additional findings ⚠️.

Diff Summary

This run exercised SQL window and aggregation behavior across normal query flows and edge-case shapes, including nested query wrappers, type compatibility at the client boundary, and large-number arithmetic limits. Most core ranking and sum scenarios behaved as expected, but a couple of changed paths still show stability and type-consistency gaps.

Merge with caution — this PR has two attributable new failures, including one medium-severity correctness/stability issue and one minor type-contract mismatch in changed aggregate behavior. Additional medium findings were also observed but are marked unrelated to this PR, so they are caveats rather than merge blockers for this change.

Tests run by Ito

View full run

Result State Severity Type Description
❌ New Failure Medium severity General Window aggregate queries wrapped in a subquery projection panic during assignment casting, while semantically equivalent direct window queries return correct rows.
❌ New Failure Minor severity Interface The sanitizer does not consistently wrap GroupBy Sum aggregates with AggCast, so integer SUM results keep GMS float64 typing at the protocol boundary.
❌->✅ Fixed Output All verified rank() and dense_rank() queries under a Sort wrapper returned PostgreSQL bigint on the wire (OID 20, size 8) and decoded cleanly as int64 values.
❌->✅ Fixed Output rank() and dense_rank() over 100k- and 1M-row partitions returned PostgreSQL bigint (OID 20, size 8) and decoded cleanly as int64 with no overflow, wraparound, or cast failures.
❌->✅ Fixed Output rank(), dense_rank(), and row_number() returned bigint-compatible values and overflow scenarios were rejected with explicit bigint out-of-range errors.
Passing General Re-verification confirms integer SUM results stay bigint-compatible and consistent across GROUP BY, DISTINCT, window, subquery, UNION, CTE, CROSS JOIN, CASE, and COALESCE paths, with expected overflow behavior when casting oversized totals back to int.
Passing General The harness skip pattern sum(col1 * col2) > 0 remains narrowly scoped: the intended MySQL-semantics query is skipped, while unrelated assertions in the same enginetest block continue to execute.
Passing Interface Window queries using ROW_NUMBER completed successfully and returned expected rows without triggering an unsupported window evaluation path.
Passing Interface The correlated LATERAL window query returned the expected row-number sequence for each customer and completed without fallback errors.
Passing Interface A composed LATERAL query using ROW_NUMBER() with inner ORDER BY and outer COALESCE returned stable results across repeated runs, with no ErrWindowUnsupported fallback.
Passing Interface The runner marked this case blocked due to a harness hang, but direct Go and SQL verification confirmed ExplicitCast preserves column IDs and casted window aliases sort correctly.
Passing Interface The runner marked this case blocked due to a harness/container interruption, but the recorded INTERFACE-6 verification executed 16 representative non-window scalar functions through pgx with compatible wire types and no decoding errors, so the product behavior matches the expected result.
Passing Output The partitioned window SUM query returned the expected total on every row and decoded the SUM column as bigint-compatible int64 without type mismatch.
Passing Regression The enginetest package TestWindowFunctions path executed without a skip and passed, confirming the re-enabled upstream window conformance suite runs in package tests.
Passing Regression The rank-alias query with outer descending order and LIMIT 3 returned the expected top rows {6, 6}, {5, 5}, and {4, 4} in order.
⚠️ Additional Finding Medium severity Output Expected exact integer SUM totals (18014398509481989 and 9007199254740995), but the engine returned 18014398509481988 and 9007199254740996; windowed cumulative totals also show drift at high-magnitude steps.
⚠️ Additional Finding Medium severity Output For SubqueryAlias wrapper chains (Project -> SubqueryAlias -> Project -> Window), rank output is emitted as numeric (OID 1700) instead of bigint (OID 20), while other wrapper chains keep bigint.
⚠️ Additional Finding Medium severity Regression The aggregate value is numerically correct (6) but has the wrong runtime/result type (float64 instead of int64), violating PostgreSQL SUM(int) semantics and failing client-side expectations.
⚠️ Additional Finding Medium severity Regression Empty-result variants pass because no rows are decoded, but the non-empty SUM(CASE ...) assertion fails with a type mismatch: expected int64 and got float64 for value 6.
⚠️ Additional Finding Medium severity Regression The query returns the correct numeric total but with the wrong wire/runtime type (float64), failing Postgres-compatible type expectations.
Additional Findings Details

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

🟡 Integer SUM loses precision at high magnitudes
  • Severity: Medium Medium severity
  • Description: Expected exact integer SUM totals (18014398509481989 and 9007199254740995), but the engine returned 18014398509481988 and 9007199254740996; windowed cumulative totals also show drift at high-magnitude steps.
  • Impact: Users can receive incorrect SUM totals for very large values, which can misstate analytics or financial aggregates by small amounts.
  • Steps to Reproduce:
    1. Create a table with BIGINT values that produce exact sums above 2^53, such as (9007199254740991, 9007199254740991, 7) and (4503599627370496, 4503599627370496, 3).
    2. Run SELECT grp, SUM(n) FROM sum_precision_inputs GROUP BY grp ORDER BY grp; and compare results to exact integer arithmetic.
    3. Run a windowed SUM query over the same values and compare intermediate cumulative totals to exact expected integers.
    4. Observe that returned totals are off by +/-1 for affected rows despite bigint decoding in the client.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: server/analyzer/type_sanitizer.go wraps integer SUM outputs with cast helpers but documents that GMS SUM always accumulates float64 internally. server/expression/agg_cast.go then converts the float64 buffer result using int64(math.RoundToEven(f)), which cannot recover exact integer values once precision was already lost above 2^53. This explains the observed +/-1 drift and shows a real production-code defect in numeric correctness.
Evidence Package
🟡 Two-hop SubqueryAlias wrapper returns numeric instead of bigint for rank
  • Severity: Medium Medium severity
  • Description: For SubqueryAlias wrapper chains (Project -> SubqueryAlias -> Project -> Window), rank output is emitted as numeric (OID 1700) instead of bigint (OID 20), while other wrapper chains keep bigint.
  • Impact: Some query shapes return a different numeric type for the same window-ranking output, which can break clients that rely on stable PostgreSQL type mappings.
  • Steps to Reproduce:
    1. Run SELECT c_id, rank() OVER (ORDER BY c_id) AS rk FROM c; and observe rk as OID 20 (bigint).
    2. Run SELECT rk FROM (SELECT c_id, rank() OVER (ORDER BY c_id) AS rk FROM c) t ORDER BY rk; and observe rk as OID 1700 (numeric).
    3. Compare the two results to confirm type instability for equivalent rank output under SubqueryAlias wrapping.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: In server/analyzer/type_sanitizer.go, rank outputs are explicitly cast from UINT64 to Int64 only when isWindowOrWrapsWindow(child) is true (lines 62-68). That check depends on findWindowNode, whose wrapper traversal switch (lines 338-345) includes Sort/Limit/Offset/Distinct/Filter/Project but not *plan.SubqueryAlias. As a result, SubqueryAlias-wrapped windows are not recognized as window-backed here, so the UINT64-to-Int64 cast is skipped and wire typing falls back to numeric. The smallest practical fix is to make findWindowNode recurse through *plan.SubqueryAlias like the other transparent wrappers.
Evidence Package
🟡 CASE-over-rank SUM returns float instead of bigint
  • Severity: Medium Medium severity
  • Description: The aggregate value is numerically correct (6) but has the wrong runtime/result type (float64 instead of int64), violating PostgreSQL SUM(int) semantics and failing client-side expectations.
  • Impact: Window-function queries using conditional SUM logic can return a floating-point type instead of the expected integer type, which may break consumers that enforce integer-typed results.
  • Steps to Reproduce:
    1. Run go test -v ./testing/go -run '^TestWindowFunctions$' -count=1 in the repository test environment.
    2. Execute SELECT sum(CASE WHEN r > 0 THEN 1 ELSE 0 END) FROM (SELECT rank() OVER (ORDER BY c_id) AS r FROM c) t from the scripted test set.
    3. Observe the decoded result type is float64 instead of expected int64, causing assertion failure in TestWindowFunctions/basic_window_functions.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: TypeSanitizer only wraps Sum with NewAggCast when the active node is *plan.GroupBy (server/analyzer/type_sanitizer.go), which misses aggregate expressions that are surfaced through a Project wrapper in this query shape. The PR added this narrowed GroupBy-only cast and new regression assertions, so the failing path is a remaining pre-existing limitation in aggregate type handling rather than a direct new behavioral break caused by changed lines.
Evidence Package
🟡 SUM over ranked rows returns float64
  • Severity: Medium Medium severity
  • Description: Empty-result variants pass because no rows are decoded, but the non-empty SUM(CASE ...) assertion fails with a type mismatch: expected int64 and got float64 for value 6.
  • Impact: Queries using this window-function aggregation pattern can fail or return unexpected numeric types when rows are present, disrupting affected reporting or API flows.
  • Steps to Reproduce:
    1. Run TestWindowFunctions in testing/go/window_test.go.
    2. Execute SELECT sum(CASE WHEN r > 0 THEN 1 ELSE 0 END) FROM (SELECT rank() OVER (ORDER BY c_id) AS r FROM c) t.
    3. Observe the decoded row value is float64(6) instead of int64(6) when non-empty rows are returned.
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: In server/analyzer/type_sanitizer.go, SUM gets AggCast only when the current parent node is exactly *plan.GroupBy (lines 145-152). The failing query shape uses an outer projection over an implicit grouping path, so this guard can miss the runtime float64-to-int64 conversion. The helper findGroupByChild (lines 350-360) only traverses Having wrappers and does not cover Project wrappers, leaving a practical gap where GroupBy-backed SUM outputs can still be exposed with stale/incorrect typing.
Evidence Package
🟡 CASE-over-rank SUM returns float64 instead of bigint
  • Severity: Medium Medium severity
  • Description: The query returns the correct numeric total but with the wrong wire/runtime type (float64), failing Postgres-compatible type expectations.
  • Impact: Queries in this window-function path return a float type instead of Postgres-compatible bigint semantics, which can break application code that relies on integer result types. Users may see type mismatches or downstream query failures unless callers add explicit casts.
  • Steps to Reproduce:
    1. Create table c (c_id INT PRIMARY KEY, bill TEXT) and insert rows with c_id values 1 through 6.
    2. Run SELECT sum(CASE WHEN r > 0 THEN 1 ELSE 0 END) FROM (SELECT rank() OVER (ORDER BY c_id) AS r FROM c) t.
    3. Observe the returned row decodes as float64(6) instead of int64(6) (Postgres bigint semantics for SUM over integer expressions).
  • Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
  • Code Analysis: TypeSanitizer attempts to apply AggCast for Sum in GroupBy to coerce integer SUM results to bigint, but this path still permits the failing query shape to return float64. The failure aligns with a production-code defect in aggregate type coercion for this CASE-over-rank subquery. The smallest practical fix is to ensure the GroupBy SUM path always applies an effective float64-to-int64 cast for integer-valued SUM inputs in this query pattern (or equivalently enforce bigint output typing at this node before serialization).
Evidence Package

Tip

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

Comment thread server/analyzer/type_sanitizer.go
Comment thread server/analyzer/type_sanitizer.go Outdated
@fulghum fulghum force-pushed the fulghum/window-functions branch 4 times, most recently from b2a5fdf to 5fecff5 Compare July 6, 2026 23:16
@itoqa

itoqa Bot commented Jul 7, 2026

Copy link
Copy Markdown

Ito QA test results

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

Commit: 4f77605: 10 test cases ran, 9 passed ✅, 1 additional finding ⚠️.

Summary

This run covered core SQL calculation behavior across aggregates, cast handling, windowed computations, and mixed-type value processing, including boundary-scale and nested-query paths that stress correctness and type consistency. Overall behavior is stable for the change under review, with only a known pre-existing precision mismatch in integer averaging semantics still present.

Safe to merge — the results show no regressions or other failures attributable to this PR, so current merge risk from this change is low. The remaining medium-severity issue is an existing aggregate precision behavior gap outside this PR and is best tracked separately.

Tests run by Ito

View full run

Result Severity Type Description
Aggregate Grouped SUM(int4) produced the expected totals (6 and 9), and overflow-based type checks confirmed the SUM result is bigint-compatible in this run.
Aggregate Boundary-scale grouped and windowed SUM/AVG results at about 10^12 matched expected arithmetic with no overflow or conversion corruption in this run.
Cast Explicit SUM/AVG casts stayed correctly bound through GROUP BY, HAVING, and ORDER BY usage, and returned the expected numeric-formatted values for both groups.
Cast Nested subquery projections of casted SUM and AVG aliases returned expected numeric values, and the outer ORDER BY and LIMIT operated correctly with no alias-binding regressions.
Cast The triple-nested aggregate query returned stable per-column values and numeric outputs, with no alias drift across wrapper layers.
Values VALUES queries mixing int, numeric, float, and NULL literals executed successfully with coherent inferred column behavior across casting, arithmetic, sorting, filtering, and string operations.
Window row_number, rank, and dense_rank returned correct partitioned rankings and were accepted by bigint columns without explicit casts.
Window SUM() OVER and AVG() OVER values remained correct after aliasing in an inner SELECT and projection from an outer SELECT, with SUM values accepted by bigint columns and AVG values preserved as fractional numeric output.
Window ORDER BY, DISTINCT, LIMIT, OFFSET, and multi-level subquery wrappers all preserved corrected window output typing and bigint compatibility; the FILTER-clause syntax error reflects an unsupported engine feature in this build rather than a regression in wrapper recursion.
⚠️ Medium severity Aggregate The test expected PostgreSQL numeric semantics for AVG over integer inputs, but the observed output matches float8-derived precision behavior.
Additional Findings Details

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

🟡 AVG over integer columns keeps float precision artifacts
  • Severity: Medium Medium severity
  • Description: The test expected PostgreSQL numeric semantics for AVG over integer inputs, but the observed output matches float8-derived precision behavior.
  • Impact: Queries that use AVG on integer columns can return floating-point precision artifacts instead of PostgreSQL-compatible numeric results, which can silently skew reported values in analytics and business logic.
  • Steps to Reproduce:
    1. Create an integer fixture table with rows (1,1), (1,2), (1,5), (2,2), (2,3), (2,7).
    2. Run SELECT grouping_key, AVG(v1) FROM agg_fixture GROUP BY grouping_key ORDER BY grouping_key and observe group 1 returns 2.6666666666666665.
    3. Compare AVG(v1) against 8::float8/3::float8 and 8::numeric/3::numeric for grouping_key=1; the float8 equality is true while numeric equality is false.
    4. Render AVG(v1)::text alongside float8 and numeric division text values and confirm AVG text matches float8 text, not numeric text.
  • Stub / mock content: The run disabled local SCRAM authentication in the QA container to allow direct test connections, and no query-result mocks, route interception, or forced fault injection were applied to this test.
  • Code Analysis: The analyzer intentionally maps Avg(int16/int32/int64) to numeric (server/analyzer/type_sanitizer.go), but the same code documents that GMS AVG accumulates as float64. The PR-added AggCast conversion then turns that float64 into numeric using strconv.FormatFloat(f, 'f', -1, 64) in convertAggResult (server/expression/agg_cast.go), which preserves binary floating-point artifacts like 2.6666666666666665 instead of exact numeric-average semantics. A targeted fix is to compute integer AVG with an exact numeric accumulator (or sum/count numeric division) rather than converting a float64 approximation at the end.
Evidence Package

Tip

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

@fulghum fulghum force-pushed the fulghum/window-functions branch from 4f77605 to f256286 Compare July 7, 2026 20:17
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.

1 participant