2025-02-14 14:10:29 +01:00
|
|
|
//go:build postgres
|
|
|
|
|
// +build postgres
|
|
|
|
|
|
2024-01-31 15:30:09 +01:00
|
|
|
package postgres
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"github.com/go-jet/jet/v2/internal/testutils"
|
2024-03-07 18:01:31 +01:00
|
|
|
"github.com/go-jet/jet/v2/qrm"
|
2024-01-31 15:30:09 +01:00
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
|
|
"github.com/jackc/pgtype"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
"math/big"
|
|
|
|
|
"testing"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
. "github.com/go-jet/jet/v2/postgres"
|
|
|
|
|
"github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/test_sample/model"
|
2025-02-14 14:10:29 +01:00
|
|
|
"github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/test_sample/table"
|
2024-01-31 15:30:09 +01:00
|
|
|
)
|
|
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
func TestRangeTableSelect(t *testing.T) {
|
2024-01-31 15:30:09 +01:00
|
|
|
skipForCockroachDB(t)
|
|
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
int4Range := INT4_RANGE(Int(11), Int(20))
|
|
|
|
|
int8Range := INT8_RANGE(Int(100), Int(250), String("[)"))
|
|
|
|
|
numRange := NUM_RANGE(Int(11), Float(22.22))
|
|
|
|
|
dateRange := DATE_RANGE(Date(2010, 10, 1), DateExp(PLUS_INFINITY))
|
|
|
|
|
tsRange := TS_RANGE(
|
|
|
|
|
Timestamp(2020, 02, 01, 0, 0, 0),
|
|
|
|
|
Timestamp(2020, 10, 01, 0, 0, 0),
|
|
|
|
|
)
|
|
|
|
|
tstzRange := TSTZ_RANGE(
|
|
|
|
|
TimestampzExp(MINUS_INFINITY),
|
|
|
|
|
TimestampzT(time.Date(2014, 01, 01, 15, 0, 0, 0, time.UTC)),
|
|
|
|
|
)
|
2024-01-31 15:30:09 +01:00
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
query := SELECT(
|
2025-02-14 14:10:29 +01:00
|
|
|
table.SampleRanges.AllColumns,
|
|
|
|
|
|
|
|
|
|
table.SampleRanges.Int4Range.EQ(table.SampleRanges.Int4Range).AS("sample.int4eq"),
|
|
|
|
|
table.SampleRanges.Int8Range.EQ(int8Range).AS("sample.int8eq"),
|
|
|
|
|
table.SampleRanges.Int4Range.NOT_EQ(int4Range).AS("sample.int4neq"),
|
|
|
|
|
table.SampleRanges.NumRange.LT(numRange).IS_TRUE().AS("sample.num_lt"),
|
|
|
|
|
table.SampleRanges.DateRange.LT_EQ(dateRange).IS_FALSE().AS("sample.date_lteq"),
|
|
|
|
|
table.SampleRanges.TimestampRange.GT(tsRange).AS("sample.ts_gt"),
|
|
|
|
|
table.SampleRanges.TimestampzRange.GT_EQ(tstzRange).AS("sample.tstz_gteq"),
|
|
|
|
|
table.SampleRanges.Int4Range.CONTAINS(Int32(22)).AS("sample.int4cont"),
|
|
|
|
|
table.SampleRanges.Int8Range.CONTAINS(Int64(75364)).AS("sample.int8cont"),
|
|
|
|
|
table.SampleRanges.Int8Range.CONTAINS_RANGE(int8Range).AS("sample.int8cont_range"),
|
|
|
|
|
table.SampleRanges.NumRange.OVERLAP(numRange).AS("sample.num_overlap"),
|
|
|
|
|
table.SampleRanges.DateRange.UNION(dateRange).AS("sample.date_union"),
|
|
|
|
|
table.SampleRanges.TimestampRange.INTERSECTION(tsRange).AS("sample.ts_ints"),
|
|
|
|
|
table.SampleRanges.TimestampzRange.DIFFERENCE(tstzRange).AS("sample.tstz_diff"),
|
|
|
|
|
table.SampleRanges.Int4Range.UPPER_BOUND().ADD(Int(5)).AS("sample.int4_upper"),
|
|
|
|
|
table.SampleRanges.Int8Range.LOWER_BOUND().SUB(Int(12)).AS("sample.int8_lower"),
|
2025-10-16 15:09:07 +02:00
|
|
|
LOWER_BOUND(table.SampleRanges.DateRange),
|
|
|
|
|
UPPER_BOUND(table.SampleRanges.NumRange).AS("sample.num_upper"),
|
2025-02-14 14:10:29 +01:00
|
|
|
table.SampleRanges.TimestampRange.UPPER_BOUND(),
|
|
|
|
|
table.SampleRanges.DateRange.IS_EMPTY().AS("sample.date_empty"),
|
|
|
|
|
table.SampleRanges.TimestampRange.LOWER_INC().AS("sample.ts_low_inc"),
|
|
|
|
|
table.SampleRanges.TimestampzRange.UPPER_INC().AS("sample.tstz_up_inc"),
|
|
|
|
|
table.SampleRanges.TimestampRange.LOWER_INF().AS("sample.ts_low_inf"),
|
|
|
|
|
table.SampleRanges.TimestampzRange.UPPER_INF().AS("sample.tstz_up_inf"),
|
2024-02-27 10:48:57 +01:00
|
|
|
|
|
|
|
|
RawInt4Range("'[1,2]'").EQ(int4Range),
|
|
|
|
|
RawInt8Range("int8range(15, 25)").EQ(int8Range),
|
|
|
|
|
RawNumRange("numrange(20.0, 30.0)").NOT_EQ(numRange),
|
|
|
|
|
).FROM(
|
2025-02-14 14:10:29 +01:00
|
|
|
table.SampleRanges,
|
2024-02-27 10:48:57 +01:00
|
|
|
).WHERE(
|
2025-02-14 14:10:29 +01:00
|
|
|
table.SampleRanges.DateRange.CONTAINS(Date(2023, 12, 12)),
|
2024-02-27 10:48:57 +01:00
|
|
|
)
|
2024-01-31 15:30:09 +01:00
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
testutils.AssertStatementSql(t, query, `
|
|
|
|
|
SELECT sample_ranges.date_range AS "sample_ranges.date_range",
|
2024-01-31 15:30:09 +01:00
|
|
|
sample_ranges.timestamp_range AS "sample_ranges.timestamp_range",
|
|
|
|
|
sample_ranges.timestampz_range AS "sample_ranges.timestampz_range",
|
|
|
|
|
sample_ranges.int4_range AS "sample_ranges.int4_range",
|
|
|
|
|
sample_ranges.int8_range AS "sample_ranges.int8_range",
|
2024-02-27 10:48:57 +01:00
|
|
|
sample_ranges.num_range AS "sample_ranges.num_range",
|
|
|
|
|
(sample_ranges.int4_range = sample_ranges.int4_range) AS "sample.int4eq",
|
|
|
|
|
(sample_ranges.int8_range = int8range($1, $2, $3::text)) AS "sample.int8eq",
|
|
|
|
|
(sample_ranges.int4_range != int4range($4, $5)) AS "sample.int4neq",
|
|
|
|
|
(sample_ranges.num_range < numrange($6, $7)) IS TRUE AS "sample.num_lt",
|
|
|
|
|
(sample_ranges.date_range <= daterange($8::date, $9)) IS FALSE AS "sample.date_lteq",
|
|
|
|
|
(sample_ranges.timestamp_range > tsrange($10::timestamp without time zone, $11::timestamp without time zone)) AS "sample.ts_gt",
|
|
|
|
|
(sample_ranges.timestampz_range >= tstzrange($12, $13::timestamp with time zone)) AS "sample.tstz_gteq",
|
|
|
|
|
(sample_ranges.int4_range @> $14::integer) AS "sample.int4cont",
|
|
|
|
|
(sample_ranges.int8_range @> $15::bigint) AS "sample.int8cont",
|
|
|
|
|
(sample_ranges.int8_range @> int8range($16, $17, $18::text)) AS "sample.int8cont_range",
|
|
|
|
|
(sample_ranges.num_range && numrange($19, $20)) AS "sample.num_overlap",
|
|
|
|
|
(sample_ranges.date_range + daterange($21::date, $22)) AS "sample.date_union",
|
|
|
|
|
(sample_ranges.timestamp_range * tsrange($23::timestamp without time zone, $24::timestamp without time zone)) AS "sample.ts_ints",
|
|
|
|
|
(sample_ranges.timestampz_range - tstzrange($25, $26::timestamp with time zone)) AS "sample.tstz_diff",
|
|
|
|
|
(UPPER(sample_ranges.int4_range) + $27) AS "sample.int4_upper",
|
|
|
|
|
(LOWER(sample_ranges.int8_range) - $28) AS "sample.int8_lower",
|
|
|
|
|
LOWER(sample_ranges.date_range),
|
|
|
|
|
UPPER(sample_ranges.num_range) AS "sample.num_upper",
|
|
|
|
|
UPPER(sample_ranges.timestamp_range),
|
|
|
|
|
ISEMPTY(sample_ranges.date_range) AS "sample.date_empty",
|
|
|
|
|
LOWER_INC(sample_ranges.timestamp_range) AS "sample.ts_low_inc",
|
|
|
|
|
UPPER_INC(sample_ranges.timestampz_range) AS "sample.tstz_up_inc",
|
|
|
|
|
LOWER_INF(sample_ranges.timestamp_range) AS "sample.ts_low_inf",
|
|
|
|
|
UPPER_INF(sample_ranges.timestampz_range) AS "sample.tstz_up_inf",
|
|
|
|
|
('[1,2]') = int4range($29, $30),
|
|
|
|
|
(int8range(15, 25)) = int8range($31, $32, $33::text),
|
|
|
|
|
(numrange(20.0, 30.0)) != numrange($34, $35)
|
2024-01-31 15:30:09 +01:00
|
|
|
FROM test_sample.sample_ranges
|
2024-02-27 10:48:57 +01:00
|
|
|
WHERE sample_ranges.date_range @> $36::date;
|
|
|
|
|
`)
|
|
|
|
|
|
|
|
|
|
type sample struct {
|
|
|
|
|
model.SampleRanges
|
|
|
|
|
|
|
|
|
|
Int4Eq bool
|
|
|
|
|
Int8Eq bool
|
|
|
|
|
Int4Neq bool
|
|
|
|
|
NumLt bool
|
|
|
|
|
DateLtEq bool
|
|
|
|
|
TsGt bool
|
|
|
|
|
TsTzGtEq bool
|
|
|
|
|
Int4Cont bool
|
|
|
|
|
Int8Cont bool
|
|
|
|
|
Int8ContRange bool
|
|
|
|
|
NumOverlap bool
|
|
|
|
|
DateUnion pgtype.Daterange
|
|
|
|
|
TsInts pgtype.Tsrange
|
|
|
|
|
TsTzDiff pgtype.Tstzrange
|
|
|
|
|
Int4Upper int32
|
|
|
|
|
Int8Lower int64
|
|
|
|
|
NumUpper float64
|
|
|
|
|
DateEmpty bool
|
|
|
|
|
TsLowInc bool
|
|
|
|
|
TsTzUpInc bool
|
|
|
|
|
TsLowInf bool
|
|
|
|
|
TsTzUpInf bool
|
|
|
|
|
}
|
2024-01-31 15:30:09 +01:00
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
var dest sample
|
2025-03-11 10:50:06 +01:00
|
|
|
allowUnusedColumns(func() {
|
|
|
|
|
err := query.Query(db, &dest)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
})
|
2024-01-31 15:30:09 +01:00
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
expectedRow := sample{
|
|
|
|
|
SampleRanges: sampleRangeRow,
|
|
|
|
|
Int4Eq: true,
|
|
|
|
|
Int8Eq: false,
|
|
|
|
|
Int4Neq: false,
|
|
|
|
|
NumLt: false,
|
|
|
|
|
DateLtEq: true,
|
|
|
|
|
TsGt: false,
|
|
|
|
|
TsTzGtEq: true,
|
|
|
|
|
Int4Cont: false,
|
|
|
|
|
Int8Cont: false,
|
|
|
|
|
Int8ContRange: false,
|
|
|
|
|
NumOverlap: false,
|
|
|
|
|
DateUnion: pgtype.Daterange{
|
2024-01-31 15:30:09 +01:00
|
|
|
Lower: pgtype.Date{
|
2024-02-27 10:48:57 +01:00
|
|
|
Time: time.Date(2010, 10, 1, 0, 0, 0, 0, time.UTC),
|
2024-01-31 15:30:09 +01:00
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
Upper: pgtype.Date{
|
2024-02-27 10:48:57 +01:00
|
|
|
Status: pgtype.Present,
|
|
|
|
|
InfinityModifier: pgtype.Infinity,
|
2024-01-31 15:30:09 +01:00
|
|
|
},
|
|
|
|
|
LowerType: pgtype.Inclusive,
|
|
|
|
|
UpperType: pgtype.Exclusive,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
2024-02-27 10:48:57 +01:00
|
|
|
TsInts: pgtype.Tsrange{
|
2024-01-31 15:30:09 +01:00
|
|
|
Lower: pgtype.Timestamp{
|
2024-02-27 10:48:57 +01:00
|
|
|
Time: time.Date(2020, 02, 01, 0, 0, 0, 0, time.UTC),
|
2024-01-31 15:30:09 +01:00
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
Upper: pgtype.Timestamp{
|
2024-02-27 10:48:57 +01:00
|
|
|
Time: time.Date(2020, 10, 01, 0, 0, 0, 0, time.UTC),
|
2024-01-31 15:30:09 +01:00
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
LowerType: pgtype.Inclusive,
|
2024-02-27 10:48:57 +01:00
|
|
|
UpperType: pgtype.Exclusive,
|
2024-01-31 15:30:09 +01:00
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
2024-02-27 10:48:57 +01:00
|
|
|
TsTzDiff: pgtype.Tstzrange{
|
2024-01-31 15:30:09 +01:00
|
|
|
Lower: pgtype.Timestamptz{
|
|
|
|
|
Time: time.Date(2024, 05, 07, 15, 0, 0, 0, time.FixedZone("", 0)),
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
Upper: pgtype.Timestamptz{
|
|
|
|
|
Time: time.Date(2024, 10, 11, 14, 0, 0, 0, time.FixedZone("", 0)),
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
LowerType: pgtype.Inclusive,
|
|
|
|
|
UpperType: pgtype.Exclusive,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
2024-02-27 10:48:57 +01:00
|
|
|
Int4Upper: 25,
|
|
|
|
|
Int8Lower: 188,
|
|
|
|
|
NumUpper: 5000,
|
|
|
|
|
DateEmpty: false,
|
|
|
|
|
TsLowInc: true,
|
|
|
|
|
TsTzUpInc: false,
|
|
|
|
|
TsLowInf: false,
|
|
|
|
|
TsTzUpInf: false,
|
2024-01-31 15:30:09 +01:00
|
|
|
}
|
|
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
testutils.AssertDeepEqual(t, dest, expectedRow, cmp.AllowUnexported(big.Int{}))
|
2024-01-31 15:30:09 +01:00
|
|
|
requireLogged(t, query)
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
func TestRangeSelectColumnsFromSubQuery(t *testing.T) {
|
2024-02-27 10:58:21 +01:00
|
|
|
skipForCockroachDB(t)
|
2024-01-31 15:30:09 +01:00
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
subQuery := SELECT(
|
2025-02-14 14:10:29 +01:00
|
|
|
table.SampleRanges.AllColumns,
|
|
|
|
|
table.SampleRanges.Int4Range.AS("range4"),
|
2024-02-27 10:48:57 +01:00
|
|
|
).FROM(
|
2025-02-14 14:10:29 +01:00
|
|
|
table.SampleRanges,
|
2024-02-27 10:48:57 +01:00
|
|
|
).AsTable("sub_query")
|
2024-01-31 15:30:09 +01:00
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
int4Range := Int4RangeColumn("range4").From(subQuery)
|
2024-01-31 15:30:09 +01:00
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
stmt := SELECT(
|
2025-03-11 10:50:06 +01:00
|
|
|
subQuery.AllColumns().Except(int4Range),
|
2024-02-27 10:48:57 +01:00
|
|
|
int4Range,
|
|
|
|
|
).FROM(
|
|
|
|
|
subQuery,
|
|
|
|
|
)
|
2024-01-31 15:30:09 +01:00
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
testutils.AssertDebugStatementSql(t, stmt, `
|
|
|
|
|
SELECT sub_query."sample_ranges.date_range" AS "sample_ranges.date_range",
|
|
|
|
|
sub_query."sample_ranges.timestamp_range" AS "sample_ranges.timestamp_range",
|
|
|
|
|
sub_query."sample_ranges.timestampz_range" AS "sample_ranges.timestampz_range",
|
|
|
|
|
sub_query."sample_ranges.int4_range" AS "sample_ranges.int4_range",
|
|
|
|
|
sub_query."sample_ranges.int8_range" AS "sample_ranges.int8_range",
|
|
|
|
|
sub_query."sample_ranges.num_range" AS "sample_ranges.num_range",
|
|
|
|
|
sub_query.range4 AS "range4"
|
|
|
|
|
FROM (
|
|
|
|
|
SELECT sample_ranges.date_range AS "sample_ranges.date_range",
|
|
|
|
|
sample_ranges.timestamp_range AS "sample_ranges.timestamp_range",
|
|
|
|
|
sample_ranges.timestampz_range AS "sample_ranges.timestampz_range",
|
|
|
|
|
sample_ranges.int4_range AS "sample_ranges.int4_range",
|
|
|
|
|
sample_ranges.int8_range AS "sample_ranges.int8_range",
|
|
|
|
|
sample_ranges.num_range AS "sample_ranges.num_range",
|
|
|
|
|
sample_ranges.int4_range AS "range4"
|
|
|
|
|
FROM test_sample.sample_ranges
|
|
|
|
|
) AS sub_query;
|
|
|
|
|
`)
|
|
|
|
|
|
|
|
|
|
var dest struct {
|
|
|
|
|
model.SampleRanges
|
|
|
|
|
|
|
|
|
|
Range4 pgtype.Int4range
|
2024-01-31 15:30:09 +01:00
|
|
|
}
|
|
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
err := stmt.Query(db, &dest)
|
2024-01-31 15:30:09 +01:00
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
testutils.AssertDeepEqual(t, dest.SampleRanges.Int4Range, sampleRangeRow.Int4Range)
|
|
|
|
|
testutils.AssertDeepEqual(t, dest.SampleRanges.Int8Range, sampleRangeRow.Int8Range)
|
|
|
|
|
testutils.AssertDeepEqual(t, dest.Range4, sampleRangeRow.Int4Range)
|
2024-01-31 15:30:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestRangeTable_InsertColumn(t *testing.T) {
|
|
|
|
|
skipForCockroachDB(t)
|
|
|
|
|
|
2025-02-14 14:10:29 +01:00
|
|
|
insertQuery := table.SampleRanges.INSERT(table.SampleRanges.AllColumns).
|
2024-01-31 15:30:09 +01:00
|
|
|
VALUES(
|
|
|
|
|
DATE_RANGE(
|
|
|
|
|
Date(2010, 01, 01),
|
2024-02-27 10:48:57 +01:00
|
|
|
DateExp(PLUS_INFINITY),
|
|
|
|
|
String("()"),
|
2024-01-31 15:30:09 +01:00
|
|
|
),
|
|
|
|
|
DEFAULT,
|
2024-02-27 10:48:57 +01:00
|
|
|
TSTZ_RANGE(
|
|
|
|
|
TimestampzExp(MINUS_INFINITY),
|
2024-01-31 15:30:09 +01:00
|
|
|
TimestampzT(time.Date(2014, 01, 01, 15, 0, 0, 0, time.UTC)),
|
|
|
|
|
String("[)"),
|
|
|
|
|
),
|
|
|
|
|
INT4_RANGE(Int(64), Int(128), String("[]")),
|
|
|
|
|
INT8_RANGE(Int(1024), Int(2048), String("[]")),
|
|
|
|
|
DEFAULT,
|
|
|
|
|
).
|
2024-02-27 10:48:57 +01:00
|
|
|
MODEL(
|
|
|
|
|
sampleRangeRow,
|
2025-02-14 14:10:29 +01:00
|
|
|
).RETURNING(table.SampleRanges.AllColumns)
|
2024-01-31 15:30:09 +01:00
|
|
|
|
|
|
|
|
expectedQuery := `
|
|
|
|
|
INSERT INTO test_sample.sample_ranges (date_range, timestamp_range, timestampz_range, int4_range, int8_range, num_range)
|
2024-02-27 10:48:57 +01:00
|
|
|
VALUES (daterange('2010-01-01'::date, 'infinity', '()'::text), DEFAULT, tstzrange('-infinity', '2014-01-01 15:00:00Z'::timestamp with time zone, '[)'::text), int4range(64, 128, '[]'::text), int8range(1024, 2048, '[]'::text), DEFAULT),
|
|
|
|
|
('[2023-09-25,2024-02-10)', '[2020-01-01 00:00:00,2021-01-01 15:00:00]', '[2024-05-07 15:00:00Z,2024-10-11 14:00:00Z)', '[11,20)', '[200,2450)', '[2e3,5e3)')
|
2024-01-31 15:30:09 +01:00
|
|
|
RETURNING sample_ranges.date_range AS "sample_ranges.date_range",
|
|
|
|
|
sample_ranges.timestamp_range AS "sample_ranges.timestamp_range",
|
|
|
|
|
sample_ranges.timestampz_range AS "sample_ranges.timestampz_range",
|
|
|
|
|
sample_ranges.int4_range AS "sample_ranges.int4_range",
|
|
|
|
|
sample_ranges.int8_range AS "sample_ranges.int8_range",
|
|
|
|
|
sample_ranges.num_range AS "sample_ranges.num_range";
|
|
|
|
|
`
|
2024-02-27 10:48:57 +01:00
|
|
|
testutils.AssertDebugStatementSql(t, insertQuery, expectedQuery)
|
|
|
|
|
|
2024-03-07 18:01:31 +01:00
|
|
|
testutils.ExecuteInTxAndRollback(t, db, func(tx qrm.DB) {
|
2024-02-27 10:48:57 +01:00
|
|
|
var dest []model.SampleRanges
|
|
|
|
|
err := insertQuery.Query(tx, &dest)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Len(t, dest, 2)
|
|
|
|
|
testutils.AssertDeepEqual(t, sampleRangeRow, dest[1], cmp.AllowUnexported(big.Int{}))
|
|
|
|
|
})
|
2024-01-31 15:30:09 +01:00
|
|
|
}
|
|
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
func TestRangeTableUpdate(t *testing.T) {
|
2024-01-31 15:30:09 +01:00
|
|
|
skipForCockroachDB(t)
|
|
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
t.Run("using model", func(t *testing.T) {
|
2025-02-14 14:10:29 +01:00
|
|
|
stmt := table.SampleRanges.UPDATE(table.SampleRanges.AllColumns).
|
2024-02-27 10:48:57 +01:00
|
|
|
MODEL(sampleRangeRow).
|
2025-02-14 14:10:29 +01:00
|
|
|
WHERE(table.SampleRanges.TimestampRange.LOWER_INF().IS_FALSE()).
|
|
|
|
|
RETURNING(table.SampleRanges.AllColumns)
|
2024-01-31 15:30:09 +01:00
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
testutils.AssertStatementSql(t, stmt, `
|
|
|
|
|
UPDATE test_sample.sample_ranges
|
|
|
|
|
SET (date_range, timestamp_range, timestampz_range, int4_range, int8_range, num_range) = ($1, $2, $3, $4, $5, $6)
|
|
|
|
|
WHERE LOWER_INF(sample_ranges.timestamp_range) IS FALSE
|
2024-01-31 15:30:09 +01:00
|
|
|
RETURNING sample_ranges.date_range AS "sample_ranges.date_range",
|
|
|
|
|
sample_ranges.timestamp_range AS "sample_ranges.timestamp_range",
|
|
|
|
|
sample_ranges.timestampz_range AS "sample_ranges.timestampz_range",
|
|
|
|
|
sample_ranges.int4_range AS "sample_ranges.int4_range",
|
|
|
|
|
sample_ranges.int8_range AS "sample_ranges.int8_range",
|
|
|
|
|
sample_ranges.num_range AS "sample_ranges.num_range";
|
2024-02-27 10:48:57 +01:00
|
|
|
`)
|
|
|
|
|
|
2024-03-07 18:01:31 +01:00
|
|
|
testutils.ExecuteInTxAndRollback(t, db, func(tx qrm.DB) {
|
2024-02-27 10:48:57 +01:00
|
|
|
var dest []model.SampleRanges
|
|
|
|
|
|
|
|
|
|
err := stmt.Query(tx, &dest)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Len(t, dest, 1)
|
|
|
|
|
testutils.AssertDeepEqual(t, sampleRangeRow, dest[0], cmp.AllowUnexported(big.Int{}))
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("update using SET", func(t *testing.T) {
|
2025-02-14 14:10:29 +01:00
|
|
|
stmt := table.SampleRanges.UPDATE().
|
2024-02-27 10:48:57 +01:00
|
|
|
SET(
|
2025-02-14 14:10:29 +01:00
|
|
|
table.SampleRanges.Int4Range.SET(INT4_RANGE(Int32(-12), Int32(78))),
|
|
|
|
|
table.SampleRanges.Int8Range.SET(INT8_RANGE(Int64(-1200), Int64(7800))),
|
2024-02-27 10:48:57 +01:00
|
|
|
).
|
|
|
|
|
WHERE(
|
2025-02-14 14:10:29 +01:00
|
|
|
table.SampleRanges.TimestampzRange.LOWER_BOUND().GT(Timestampz(2024, 2, 27, 0, 0, 0, 0, "UTC")),
|
2024-02-27 10:48:57 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
testutils.AssertDebugStatementSql(t, stmt, `
|
|
|
|
|
UPDATE test_sample.sample_ranges
|
|
|
|
|
SET int4_range = int4range(-12::integer, 78::integer),
|
|
|
|
|
int8_range = int8range(-1200::bigint, 7800::bigint)
|
2024-07-03 11:56:59 +02:00
|
|
|
WHERE LOWER(sample_ranges.timestampz_range) > '2024-02-27 00:00:00 UTC'::timestamp with time zone;
|
2024-02-27 10:48:57 +01:00
|
|
|
`)
|
|
|
|
|
|
2024-03-07 18:01:31 +01:00
|
|
|
testutils.ExecuteInTxAndRollback(t, db, func(tx qrm.DB) {
|
2024-02-27 10:48:57 +01:00
|
|
|
testutils.AssertExec(t, stmt, tx, 1)
|
|
|
|
|
})
|
|
|
|
|
})
|
2024-01-31 15:30:09 +01:00
|
|
|
|
2024-02-27 10:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var sampleRangeRow = model.SampleRanges{
|
|
|
|
|
DateRange: pgtype.Daterange{
|
|
|
|
|
Lower: pgtype.Date{
|
|
|
|
|
Time: time.Date(2023, 9, 25, 0, 0, 0, 0, time.UTC),
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
Upper: pgtype.Date{
|
|
|
|
|
Time: time.Date(2024, 2, 10, 0, 0, 0, 0, time.UTC),
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
LowerType: pgtype.Inclusive,
|
|
|
|
|
UpperType: pgtype.Exclusive,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
TimestampRange: pgtype.Tsrange{
|
|
|
|
|
Lower: pgtype.Timestamp{
|
|
|
|
|
Time: time.Date(2020, 01, 01, 0, 0, 0, 0, time.UTC),
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
Upper: pgtype.Timestamp{
|
|
|
|
|
Time: time.Date(2021, 01, 01, 15, 0, 0, 0, time.UTC),
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
LowerType: pgtype.Inclusive,
|
|
|
|
|
UpperType: pgtype.Inclusive,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
TimestampzRange: pgtype.Tstzrange{
|
|
|
|
|
Lower: pgtype.Timestamptz{
|
|
|
|
|
Time: time.Date(2024, 05, 07, 15, 0, 0, 0, time.FixedZone("", 0)),
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
Upper: pgtype.Timestamptz{
|
|
|
|
|
Time: time.Date(2024, 10, 11, 14, 0, 0, 0, time.FixedZone("", 0)),
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
LowerType: pgtype.Inclusive,
|
|
|
|
|
UpperType: pgtype.Exclusive,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
Int4Range: pgtype.Int4range{
|
|
|
|
|
Lower: pgtype.Int4{
|
|
|
|
|
Int: 11,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
Upper: pgtype.Int4{
|
|
|
|
|
Int: 20,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
LowerType: pgtype.Inclusive,
|
|
|
|
|
UpperType: pgtype.Exclusive,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
Int8Range: pgtype.Int8range{
|
|
|
|
|
Lower: pgtype.Int8{
|
|
|
|
|
Int: 200,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
Upper: pgtype.Int8{
|
|
|
|
|
Int: 2450,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
LowerType: pgtype.Inclusive,
|
|
|
|
|
UpperType: pgtype.Exclusive,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
NumRange: pgtype.Numrange{
|
|
|
|
|
Lower: pgtype.Numeric{
|
|
|
|
|
Int: big.NewInt(2),
|
|
|
|
|
Exp: 3,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
|
|
|
|
Upper: pgtype.Numeric{
|
|
|
|
|
Int: big.NewInt(5),
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
Exp: 3,
|
|
|
|
|
},
|
|
|
|
|
LowerType: pgtype.Inclusive,
|
|
|
|
|
UpperType: pgtype.Exclusive,
|
|
|
|
|
Status: pgtype.Present,
|
|
|
|
|
},
|
2024-01-31 15:30:09 +01:00
|
|
|
}
|