Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 7, 2025

Description

Implements PostgreSQL-style range types for AlaSQL, enabling temporal and numeric interval operations requested in #55.

Changes

Core Implementation (src/60range.js):

  • alasql.Range class with inclusive/exclusive bounds [lower, upper)
  • Simplified helper functions for type-agnostic comparisons (leverages JavaScript's valueOf() for Date and Number types)
  • Range constructors: int4range, int8range, numrange, daterange, tsrange, tstzrange
  • Range operations: range_union, range_intersection, range_difference
  • Range predicates: range_overlaps, range_contains, range_is_subset, range_is_superset, range_is_disjoint

Build Integration:

  • Added src/60range.js to build pipeline in build.sh

Test Coverage (test/test055-B.js):

  • 21 test cases covering all range types and operations using assert.deepEqual for comprehensive validation
  • Edge cases: empty ranges, boundary conditions, date comparisons

Example Usage

// Integer ranges
alasql('SELECT range_overlaps(int4range(10, 20), int4range(15, 25)) as r')[0].r  // true

// Date ranges in queries
alasql('CREATE TABLE bookings (id INT, period RANGE)');
alasql('INSERT INTO bookings VALUES (1, daterange(?, ?))', [new Date('2024-01-01'), new Date('2024-01-31')]);
alasql('SELECT * FROM bookings WHERE range_overlaps(period, daterange(?, ?))', [...]);

// Range methods
var r1 = alasql.stdfn.INT4RANGE(10, 20);
var r2 = alasql.stdfn.INT4RANGE(15, 25);
r1.union(r2)         // [10, 25)
r1.intersection(r2)  // [15, 20)

Notes

All range types use a unified alasql.Range class rather than PostgreSQL's six distinct implementations. Default bounds follow PostgreSQL convention: inclusive lower, exclusive upper [lower, upper).

Comparison logic leverages JavaScript's built-in valueOf() behavior, making it compatible with Date objects and numeric types without explicit type checking.

Original prompt

This section details on the original issue you should resolve

<issue_title>Feature request: Range types from Postgresql</issue_title>
<issue_description>I do a lot of work with dates, range types would be useful.

http://www.postgresql.org/docs/9.2/static/rangetypes.html
</issue_description>

<agent_instructions>Please make a new test file named test/test055-B.js to verify the expected funktionality. Then start the implementation. I propose using the new functions on set functions like

union(other)

difference(other)

symmetricDifference(other)

isSubsetOf(other)

isSupersetOf(other)

isDisjointFrom(other)​

if that is helping </agent_instructions>

Comments on the Issue (you are @copilot in this section)

@agershun Thank you for request! May I ask you to answer on the following questions: 1. Is it important to keep syntax of operations, like:
    SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0); 
    SELECT int4range(10, 20) * int4range(15, 25);

Now Alasql expression compiler does not check operand types and delegates this work to JavaScript, so I need to create special range_*() functions for these operations, like:

    SELECT range_and(numrange(11.1, 22.2), numrange(20.0, 30.0)); 
    SELECT range_intersect(int4range(10, 20) * int4range(15, 25));

or create special range operators (like @>):

    SELECT numrange(11.1, 22.2) @&& numrange(20.0, 30.0); 
    SELECT int4range(10, 20) @* int4range(15, 25);

Which option is better on your opinion?

  1. Postgres has 6 range datatypes
    int4range — Range of integer
    int8range — Range of bigint
    numrange — Range of numeric
    tsrange — Range of timestamp without time zone
    tstzrange — Range of timestamp with time zone
    daterange — Range of date

But for Alasql all of them will be realized with only 'typeless' range. Do I need to keep all these 6 types or can use only one, like: RANGE(1,2)?

  1. Should I implement '::' as an additional form to CAST/CONVERT functions?

Thank you!

@mathiasrw I have added this as a featurerequest: http://feathub.com/agershun/alasql/+22

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Add support for range types from PostgreSQL Add PostgreSQL range types support Dec 7, 2025
Copilot AI requested a review from mathiasrw December 7, 2025 06:30
Copy link
Member

Choose a reason for hiding this comment

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

Please use deepequal to confirm the full object returned.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated tests to use assert.deepEqual for comprehensive validation of Range objects. This now checks all properties (lower, upper, lowerInc, upperInc) in a single assertion. Commit: b27778c

Copy link
Member

Choose a reason for hiding this comment

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

Is this really the best way to do it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Simplified the comparison helper functions. The original approach explicitly handled Date objects with getTime(), but JavaScript's comparison operators already work correctly with Date objects via valueOf(). The new implementation is simpler and more idiomatic while maintaining the same functionality. Commit: b27778c

Copilot AI requested a review from mathiasrw December 7, 2025 14:56
@mathiasrw mathiasrw added this to the The Back Burner milestone Dec 8, 2025
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.

Feature request: Range types from Postgresql

2 participants