Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Range columns in query builder #13

Open
vigneshgurusamy opened this issue Apr 11, 2022 · 6 comments
Open

Range columns in query builder #13

vigneshgurusamy opened this issue Apr 11, 2022 · 6 comments
Labels
enhancement New feature or request

Comments

@vigneshgurusamy
Copy link

Hi,

I'm planning to migrate existing timestamp columns to tsrange using generated column like mentioned in the blog

https://blog.brackets.sk/ranges-in-laravel-7-using-postgresql/

I see tsrange() is supported for Migration but not in the query builder.

Is there any plan to add range column support in the query builder in the near future?

@tpetry
Copy link
Owner

tpetry commented Apr 11, 2022

I will add rich support for all the PostgreSQL types at some point, I just don't have an effective plan for it yet. With every method I add, there's a chance for a conflict with Laravel's own query builder methods, like the recent whereJsonContainsKey one.

But you don't have to use the raw method, you can use the normal where method like this:

$query->where('valid_range', '@>', now())

And you should better use tstzrange because timestamps without a timezone are discouraged in PostgreSQL: Don't use timestamp (without time zone)

@tpetry tpetry added the enhancement New feature or request label Apr 11, 2022
@boris-glumpler
Copy link

boris-glumpler commented Apr 11, 2022

@tpetry slightly off-topic here... In the wiki article you linked it also says to not use timestamp(0) or timestamptz(0), which Laravel uses by default. How would you handle this in Laravel?

Edit: Did not know that you can pass null for the precision to disable it.

@vigneshgurusamy
Copy link
Author

@tpetry I have tried to use your suggestions with tstzrange but it fails without explicit type cast

create table vacations
(
    vacation_id     serial primary key,
    vacation_range  tstzrange
);
> DB::table('vacations')->where('vacation_range', '@>', now())->get();

Illuminate\Database\QueryException with message 'SQLSTATE[22P02]: Invalid text representation: 7 ERROR:  malformed range literal: "2022-12-08 05:35:02"
DETAIL:  Missing left parenthesis or bracket.
CONTEXT:  unnamed portal parameter $1 = '...' (SQL: select * from "vacations" where "vacation_range" @> 2022-12-08 05:35:02)'

Raw query with explicit type cast works

DB::table('vacations')
  ->whereRaw("vacation_range @> ?::TIMESTAMPTZ", [now()])
  ->get();

Am I missing something here?

@tpetry
Copy link
Owner

tpetry commented Dec 8, 2022

The value in your first query is missing the timezone, therefore it is not working.

@vigneshgurusamy
Copy link
Author

@tpetry I have tried with multiple combinations with timezone & without timezone data types, but no luck.

create table vacations
(
    vacation_id     serial primary key,
    vacation_range  tsrange,
    vacation_range_tz  tstzrange
);

Not working

$ts = now()->setTimezone('Asia/Kolkata');

DB::table('vacations')->where('vacation_range', '@>', $ts)->get();
DB::table('vacations')->where('vacation_range', '@>', $ts->toIso8601String())->get();
DB::table('vacations')->where('vacation_range_tz', '@>', $ts)->get();
DB::table('vacations')->where('vacation_range_tz', '@>', $ts->toIso8601String())->get();

Working

$ts = now()->setTimezone('Asia/Kolkata');

DB::table('vacations')
  ->whereRaw("vacation_range @> ?::TIMESTAMP", [$ts->toIso8601String()])
  ->get();

DB::table('vacations')
  ->whereRaw("vacation_range_tz @> ?::TIMESTAMPTZ", [$ts->toIso8601String()])
  ->get();

I feel I cannot use where() method for range data types.

@tpetry
Copy link
Owner

tpetry commented Dec 16, 2022

You are correct. The @> operator defaults to using a range value (which I use in my application), if you want to pass it a single value you need to cast the placeholder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants