Skip to content

Commit

Permalink
feat(FIR-38076): Geography type support (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
ptiurin authored Dec 3, 2024
1 parent bec7ad5 commit 5505659
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 17 deletions.
28 changes: 26 additions & 2 deletions connection_common_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ func TestConnectionQueryBooleanType(t *testing.T) {

rows, err := conn.QueryContext(context.TODO(), "SELECT true, false, null::boolean;")
if err != nil {
t.Errorf("statement failed with %v", err)
t.Errorf(STATEMENT_ERROR_MSG, err)
}

var b1, b2 bool
Expand All @@ -363,7 +363,7 @@ func TestConnectionQueryByteaType(t *testing.T) {

rows, err := conn.QueryContext(context.TODO(), "SELECT 'abc123'::bytea")
if err != nil {
t.Errorf("statement failed with %v", err)
t.Errorf(STATEMENT_ERROR_MSG, err)
}

var dest []byte
Expand All @@ -378,6 +378,30 @@ func TestConnectionQueryByteaType(t *testing.T) {
}
}

func TestConnectionQueryGeographyType(t *testing.T) {
conn, err := sql.Open("firebolt", dsnMock)
if err != nil {
t.Errorf(OPEN_CONNECTION_ERROR_MSG)
t.FailNow()
}

rows, err := conn.QueryContext(context.TODO(), "SELECT 'POINT(1 1)'::geography")
if err != nil {
t.Errorf(STATEMENT_ERROR_MSG, err)
}

var dest string

assert(rows.Next(), true, t, NEXT_STATEMENT_ERROR_MSG)
if err = rows.Scan(&dest); err != nil {
t.Errorf(SCAN_STATEMENT_ERROR_MSG, err)
}
expected := "0101000020E6100000FEFFFFFFFFFFEF3F000000000000F03F"
if dest != expected {
t.Errorf("Geography type check failed Expected: %s Got: %s", expected, dest)
}
}

func TestLongQuery(t *testing.T) {
var maxValue = longTestValue

Expand Down
13 changes: 8 additions & 5 deletions connection_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ func TestConnectionPreparedStatement(t *testing.T) {

_, err = conn.QueryContext(
context.Background(),
"CREATE TABLE test_prepared_statements (i INT, l LONG, f FLOAT, d DOUBLE, t TEXT, dt DATE, ts TIMESTAMP, tstz TIMESTAMPTZ, b BOOLEAN, ba BYTEA) PRIMARY INDEX i",
"CREATE TABLE test_prepared_statements (i INT, l LONG, f FLOAT, d DOUBLE, t TEXT, dt DATE, ts TIMESTAMP, tstz TIMESTAMPTZ, b BOOLEAN, ba BYTEA, ge GEOGRAPHY) PRIMARY INDEX i",
)
if err != nil {
t.Errorf("create table statement failed with %v", err)
Expand All @@ -221,11 +221,13 @@ func TestConnectionPreparedStatement(t *testing.T) {
ts := time.Date(2021, 1, 1, 2, 10, 20, 3000, time.UTC)
tstz := time.Date(2021, 1, 1, 2, 10, 20, 3000, loc)
ba := []byte("hello_world_123ツ\n\u0048")
ge := "POINT(1 1)"
geEncoded := "0101000020E6100000FEFFFFFFFFFFEF3F000000000000F03F"

_, err = conn.QueryContext(
context.Background(),
"INSERT INTO test_prepared_statements VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
1, int64(2), 0.333333, 0.333333333333, "text", d, ts, tstz, true, ba,
"INSERT INTO test_prepared_statements VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
1, int64(2), 0.333333, 0.333333333333, "text", d, ts, tstz, true, ba, ge,
)

if err != nil {
Expand All @@ -248,8 +250,8 @@ func TestConnectionPreparedStatement(t *testing.T) {
t.FailNow()
}

dest := make([]driver.Value, 10)
pointers := make([]interface{}, 10)
dest := make([]driver.Value, 11)
pointers := make([]interface{}, 11)
for i := range pointers {
pointers[i] = &dest[i]
}
Expand Down Expand Up @@ -284,4 +286,5 @@ func TestConnectionPreparedStatement(t *testing.T) {
break
}
}
assert(dest[10], geEncoded, t, "geography results are not equal")
}
6 changes: 4 additions & 2 deletions rows.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const (

booleanType = "boolean"
byteaType = "bytea"

geographyType = "geography"
)

type fireboltRows struct {
Expand Down Expand Up @@ -109,7 +111,7 @@ func checkTypeValue(columnType string, val interface{}) error {
}
}
return nil
case textType, dateType, pgDateType, timestampType, timestampNtzType, timestampTzType, byteaType:
case textType, dateType, pgDateType, timestampType, timestampNtzType, timestampTzType, byteaType, geographyType:
if _, ok := val.(string); !ok {
return fmt.Errorf("expected to convert a value to string, but couldn't: %v", val)
}
Expand Down Expand Up @@ -192,7 +194,7 @@ func parseSingleValue(columnType string, val interface{}) (driver.Value, error)
return float32(v), err
case doubleType:
return parseFloatValue(val)
case textType:
case textType, geographyType:
return val.(string), nil
case dateType, pgDateType, timestampType, timestampNtzType, timestampTzType:
return parseDateTimeValue(columnType, val.(string))
Expand Down
18 changes: 10 additions & 8 deletions rows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,15 @@ func mockRows(isMultiStatement bool) driver.RowsNextResultSet {
{"name":"new_bool_col","type":"boolean"},
{"name":"decimal_col","type":"Decimal(38, 30) null"},
{"name":"decimal_array_col","type":"array(Decimal(38, 30) null)"},
{"name":"bytea_col","type":"bytea null"}
{"name":"bytea_col","type":"bytea null"},
{"name":"geography_col","type":"geography null"}
],
"data":[
[null,1,0.312321,123213.321321,"text", "2080-12-31","1989-04-15 01:02:03","0002-01-01","1989-04-15 01:02:03.123456","1989-04-15 02:02:03.123456+00",1,[1,2,3],[[]],true, 123.12345678, [123.12345678], "\\x616263313233"],
[2,"37237366456",0.312321,123213.321321,"text","1970-01-01","1970-01-01 00:00:00","0001-01-01","1989-04-15 01:02:03.123457","1989-04-15 01:02:03.1234+05:30",1,[1,2,3],[[]],true, -123.12345678, [-123.12345678, 0.0], "\\x6162630A0AE3858D20E3858E5C"],
[3,null,"inf",123213.321321,"text","1970-01-01","1970-01-01 00:00:00","0001-01-01","1989-04-15 01:02:03.123458","1989-04-15 01:02:03+01",1,[5,2,3,2],[["TEST","TEST1"],["TEST3"]],false, 0.0, [0.0], null],
[2,1,"-inf",123213.321321,"text","1970-01-01","1970-01-01 00:00:00","0001-01-01","1989-04-15 01:02:03.123457","1111-01-05 17:04:42.123456+05:53:28",1,[1,2,3],[[]],false, 123456781234567812345678.123456781234567812345678, [123456781234567812345678.12345678123456781234567812345678], null],
[2,1,"-nan",123213.321321,"text","1970-01-01","1970-01-01 00:00:00","0001-01-01","1989-04-15 01:02:03.123457","1989-04-15 02:02:03.123456-01",1,[1,2,3],[[]],null, null, [null], null]
[null,1,0.312321,123213.321321,"text", "2080-12-31","1989-04-15 01:02:03","0002-01-01","1989-04-15 01:02:03.123456","1989-04-15 02:02:03.123456+00",1,[1,2,3],[[]],true, 123.12345678, [123.12345678], "\\x616263313233", "0101000020E6100000FEFFFFFFFFFFEF3F000000000000F03F"],
[2,"37237366456",0.312321,123213.321321,"text","1970-01-01","1970-01-01 00:00:00","0001-01-01","1989-04-15 01:02:03.123457","1989-04-15 01:02:03.1234+05:30",1,[1,2,3],[[]],true, -123.12345678, [-123.12345678, 0.0], "\\x6162630A0AE3858D20E3858E5C", null],
[3,null,"inf",123213.321321,"text","1970-01-01","1970-01-01 00:00:00","0001-01-01","1989-04-15 01:02:03.123458","1989-04-15 01:02:03+01",1,[5,2,3,2],[["TEST","TEST1"],["TEST3"]],false, 0.0, [0.0], null, null],
[2,1,"-inf",123213.321321,"text","1970-01-01","1970-01-01 00:00:00","0001-01-01","1989-04-15 01:02:03.123457","1111-01-05 17:04:42.123456+05:53:28",1,[1,2,3],[[]],false, 123456781234567812345678.123456781234567812345678, [123456781234567812345678.12345678123456781234567812345678], null, null],
[2,1,"-nan",123213.321321,"text","1970-01-01","1970-01-01 00:00:00","0001-01-01","1989-04-15 01:02:03.123457","1989-04-15 02:02:03.123456-01",1,[1,2,3],[[]],null, null, [null], null, null, null]
],
"rows":5,
"statistics":{
Expand Down Expand Up @@ -112,7 +113,7 @@ func mockRows(isMultiStatement bool) driver.RowsNextResultSet {
func TestRowsColumns(t *testing.T) {
rows := mockRows(false)

columnNames := []string{"int_col", "bigint_col", "float_col", "double_col", "text_col", "date_col", "timestamp_col", "pgdate_col", "timestampntz_col", "timestamptz_col", "legacy_bool_col", "array_col", "nested_array_col", "new_bool_col", "decimal_col", "decimal_array_col", "bytea_col"}
columnNames := []string{"int_col", "bigint_col", "float_col", "double_col", "text_col", "date_col", "timestamp_col", "pgdate_col", "timestampntz_col", "timestamptz_col", "legacy_bool_col", "array_col", "nested_array_col", "new_bool_col", "decimal_col", "decimal_array_col", "bytea_col", "geography_col"}
if !reflect.DeepEqual(rows.Columns(), columnNames) {
t.Errorf("column lists are not equal")
}
Expand All @@ -134,7 +135,7 @@ func TestRowsClose(t *testing.T) {
// TestRowsNext check Next method
func TestRowsNext(t *testing.T) {
rows := mockRows(false)
var dest = make([]driver.Value, 17)
var dest = make([]driver.Value, 18)

// First row
err := rows.Next(dest)
Expand All @@ -157,6 +158,7 @@ func TestRowsNext(t *testing.T) {
assert(len(arr), 1, t, "invalid length of decimal array")
assert(arr[0], 123.12345678, t, "results not equal for decimal array")
assertByte(dest[16].([]byte), []byte("abc123"), t, "")
assert(dest[17], "0101000020E6100000FEFFFFFFFFFFEF3F000000000000F03F", t, "results not equal for geography")

// Second row
err = rows.Next(dest)
Expand Down

0 comments on commit 5505659

Please sign in to comment.