github.com/jackc/pgx/v5@v5.5.5/pgtype/range_codec_test.go (about)

     1  package pgtype_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	pgx "github.com/jackc/pgx/v5"
     8  	"github.com/jackc/pgx/v5/pgtype"
     9  	"github.com/jackc/pgx/v5/pgxtest"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func TestRangeCodecTranscode(t *testing.T) {
    14  	skipCockroachDB(t, "Server does not support range types (see https://github.com/cockroachdb/cockroach/issues/27791)")
    15  
    16  	pgxtest.RunValueRoundTripTests(context.Background(), t, defaultConnTestRunner, nil, "int4range", []pgxtest.ValueRoundTripTest{
    17  		{
    18  			pgtype.Range[pgtype.Int4]{LowerType: pgtype.Empty, UpperType: pgtype.Empty, Valid: true},
    19  			new(pgtype.Range[pgtype.Int4]),
    20  			isExpectedEq(pgtype.Range[pgtype.Int4]{LowerType: pgtype.Empty, UpperType: pgtype.Empty, Valid: true}),
    21  		},
    22  		{
    23  			pgtype.Range[pgtype.Int4]{
    24  				LowerType: pgtype.Inclusive,
    25  				Lower:     pgtype.Int4{Int32: 1, Valid: true},
    26  				Upper:     pgtype.Int4{Int32: 5, Valid: true},
    27  				UpperType: pgtype.Exclusive, Valid: true,
    28  			},
    29  			new(pgtype.Range[pgtype.Int4]),
    30  			isExpectedEq(pgtype.Range[pgtype.Int4]{
    31  				LowerType: pgtype.Inclusive,
    32  				Lower:     pgtype.Int4{Int32: 1, Valid: true},
    33  				Upper:     pgtype.Int4{Int32: 5, Valid: true},
    34  				UpperType: pgtype.Exclusive, Valid: true,
    35  			}),
    36  		},
    37  		{pgtype.Range[pgtype.Int4]{}, new(pgtype.Range[pgtype.Int4]), isExpectedEq(pgtype.Range[pgtype.Int4]{})},
    38  		{nil, new(pgtype.Range[pgtype.Int4]), isExpectedEq(pgtype.Range[pgtype.Int4]{})},
    39  	})
    40  }
    41  
    42  func TestRangeCodecTranscodeCompatibleRangeElementTypes(t *testing.T) {
    43  	ctr := defaultConnTestRunner
    44  	ctr.AfterConnect = func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
    45  		pgxtest.SkipCockroachDB(t, conn, "Server does not support range types (see https://github.com/cockroachdb/cockroach/issues/27791)")
    46  	}
    47  
    48  	pgxtest.RunValueRoundTripTests(context.Background(), t, ctr, nil, "numrange", []pgxtest.ValueRoundTripTest{
    49  		{
    50  			pgtype.Range[pgtype.Float8]{LowerType: pgtype.Empty, UpperType: pgtype.Empty, Valid: true},
    51  			new(pgtype.Range[pgtype.Float8]),
    52  			isExpectedEq(pgtype.Range[pgtype.Float8]{LowerType: pgtype.Empty, UpperType: pgtype.Empty, Valid: true}),
    53  		},
    54  		{
    55  			pgtype.Range[pgtype.Float8]{
    56  				LowerType: pgtype.Inclusive,
    57  				Lower:     pgtype.Float8{Float64: 1, Valid: true},
    58  				Upper:     pgtype.Float8{Float64: 5, Valid: true},
    59  				UpperType: pgtype.Exclusive, Valid: true,
    60  			},
    61  			new(pgtype.Range[pgtype.Float8]),
    62  			isExpectedEq(pgtype.Range[pgtype.Float8]{
    63  				LowerType: pgtype.Inclusive,
    64  				Lower:     pgtype.Float8{Float64: 1, Valid: true},
    65  				Upper:     pgtype.Float8{Float64: 5, Valid: true},
    66  				UpperType: pgtype.Exclusive, Valid: true,
    67  			}),
    68  		},
    69  		{pgtype.Range[pgtype.Float8]{}, new(pgtype.Range[pgtype.Float8]), isExpectedEq(pgtype.Range[pgtype.Float8]{})},
    70  		{nil, new(pgtype.Range[pgtype.Float8]), isExpectedEq(pgtype.Range[pgtype.Float8]{})},
    71  	})
    72  }
    73  
    74  func TestRangeCodecScanRangeTwiceWithUnbounded(t *testing.T) {
    75  	skipCockroachDB(t, "Server does not support range types (see https://github.com/cockroachdb/cockroach/issues/27791)")
    76  
    77  	defaultConnTestRunner.RunTest(context.Background(), t, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
    78  
    79  		var r pgtype.Range[pgtype.Int4]
    80  
    81  		err := conn.QueryRow(context.Background(), `select '[1,5)'::int4range`).Scan(&r)
    82  		require.NoError(t, err)
    83  
    84  		require.Equal(
    85  			t,
    86  			pgtype.Range[pgtype.Int4]{
    87  				Lower:     pgtype.Int4{Int32: 1, Valid: true},
    88  				Upper:     pgtype.Int4{Int32: 5, Valid: true},
    89  				LowerType: pgtype.Inclusive,
    90  				UpperType: pgtype.Exclusive,
    91  				Valid:     true,
    92  			},
    93  			r,
    94  		)
    95  
    96  		err = conn.QueryRow(ctx, `select '[1,)'::int4range`).Scan(&r)
    97  		require.NoError(t, err)
    98  
    99  		require.Equal(
   100  			t,
   101  			pgtype.Range[pgtype.Int4]{
   102  				Lower:     pgtype.Int4{Int32: 1, Valid: true},
   103  				Upper:     pgtype.Int4{},
   104  				LowerType: pgtype.Inclusive,
   105  				UpperType: pgtype.Unbounded,
   106  				Valid:     true,
   107  			},
   108  			r,
   109  		)
   110  
   111  		err = conn.QueryRow(ctx, `select 'empty'::int4range`).Scan(&r)
   112  		require.NoError(t, err)
   113  
   114  		require.Equal(
   115  			t,
   116  			pgtype.Range[pgtype.Int4]{
   117  				Lower:     pgtype.Int4{},
   118  				Upper:     pgtype.Int4{},
   119  				LowerType: pgtype.Empty,
   120  				UpperType: pgtype.Empty,
   121  				Valid:     true,
   122  			},
   123  			r,
   124  		)
   125  	})
   126  }
   127  
   128  func TestRangeCodecDecodeValue(t *testing.T) {
   129  	skipCockroachDB(t, "Server does not support range types (see https://github.com/cockroachdb/cockroach/issues/27791)")
   130  
   131  	defaultConnTestRunner.RunTest(context.Background(), t, func(ctx context.Context, _ testing.TB, conn *pgx.Conn) {
   132  
   133  		for _, tt := range []struct {
   134  			sql      string
   135  			expected any
   136  		}{
   137  			{
   138  				sql: `select '[1,5)'::int4range`,
   139  				expected: pgtype.Range[any]{
   140  					Lower:     int32(1),
   141  					Upper:     int32(5),
   142  					LowerType: pgtype.Inclusive,
   143  					UpperType: pgtype.Exclusive,
   144  					Valid:     true,
   145  				},
   146  			},
   147  		} {
   148  			t.Run(tt.sql, func(t *testing.T) {
   149  				rows, err := conn.Query(ctx, tt.sql)
   150  				require.NoError(t, err)
   151  
   152  				for rows.Next() {
   153  					values, err := rows.Values()
   154  					require.NoError(t, err)
   155  					require.Len(t, values, 1)
   156  					require.Equal(t, tt.expected, values[0])
   157  				}
   158  
   159  				require.NoError(t, rows.Err())
   160  			})
   161  		}
   162  	})
   163  }