Skip to content

UNION / EXCEPT / INTERSECT miss shared rows when the first SELECT has its own ORDER BY #2612

Closed as duplicate

Description

@mathiasrw

A set operation whose first SELECT has its own ORDER BY gives a wrong result for UNION, EXCEPT and INTERSECT when both SELECTs share a row. No error is raised. UNION ALL is not affected.

Reproduced on develop (v4.20.1), with the statement cache off:

alasql.options.cache = false;
alasql('CREATE TABLE e1 (a INT); INSERT INTO e1 VALUES (1),(2),(3),(4)');
alasql('CREATE TABLE e2 (a INT); INSERT INTO e2 VALUES (1),(5)');
Query Result Expected
(SELECT a FROM e1 ORDER BY a LIMIT 2) UNION (SELECT a FROM e2 ORDER BY a LIMIT 1) 1,1,2 1,2
(SELECT a FROM e1 ORDER BY a LIMIT 2) EXCEPT (SELECT a FROM e2 ORDER BY a LIMIT 1) 1,2 2
(SELECT a FROM e1 ORDER BY a LIMIT 2) INTERSECT (SELECT a FROM e2 ORDER BY a LIMIT 1) [] 1
(SELECT a FROM e1 ORDER BY a) UNION (SELECT a FROM e2 ORDER BY a) 1,5,1,2,3,4 1,2,3,4,5 (any order)
(SELECT a FROM e1 ORDER BY a) INTERSECT (SELECT a FROM e2 ORDER BY a) [] 1
(SELECT a FROM e1 LIMIT 2) INTERSECT (SELECT a FROM e2 ORDER BY a LIMIT 1) 1 1 ✅ (no ORDER BY on the first SELECT)

Cause

queryfn3 in src/38query.js (the early ORDER BY / LIMIT step added in #2417). To sort the first SELECT before the set operation, it writes the order keys ($$$0, $$$1, ...) onto the first SELECT's rows. They are only removed by removeKeys at the end of queryfn3, after the set operation.

arrayUnionDeep, arrayExceptDeep and arrayIntersectDeep compare whole rows, so a row from the first SELECT ({a: 1, $$$0: 1}) never equals the same row from the second SELECT ({a: 1}).

Direction

Remove the order keys from the first SELECT's rows right after the early sort, before the set operation runs.

Tests: the queries in the table above, run twice each (see #2605).

Related: #2414, #2417, #2605 / #2608 (found while reviewing it), #2582 (rewrites the same block in queryfn3).

Activity

  1. added this to the Breaking change milestone on Oct 20, 2026
  2. mathiasrw commented on Oct 20, 2026

    @mathiasrw
    MemberAuthor

    Duplicate of #2610, which @Anikesh0001 filed first. The extra cases from this issue (ORDER BY without LIMIT, and EXCEPT / UNION with a shared row) are covered by the tests in #2611.

  3. removed this from the Breaking change milestone on Oct 20, 2026
  4. added a commit that references this issue on Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions