diff --git a/postgres/literal.go b/postgres/literal.go index efba9ba..8ee3235 100644 --- a/postgres/literal.go +++ b/postgres/literal.go @@ -1,8 +1,9 @@ package postgres import ( - "github.com/go-jet/jet/v2/internal/jet" "time" + + "github.com/go-jet/jet/v2/internal/jet" ) // Bool creates new bool literal expression @@ -48,9 +49,14 @@ var String = jet.String // value can be any uuid type with a String method var UUID = jet.UUID -// Bytea craates new bytea literal expression -var Bytea = func(value string) StringExpression { - return CAST(jet.String(value)).AS_BYTEA() +// Bytea creates new bytea literal expression +var Bytea = func(value interface{}) StringExpression { + switch value.(type) { + case string, []byte: + default: + panic("Bytea parameter value has to be of the type string or []byte") + } + return CAST(jet.Literal(value)).AS_BYTEA() } // Date creates new date literal expression diff --git a/postgres/literal_test.go b/postgres/literal_test.go index 197fff7..52a15a0 100644 --- a/postgres/literal_test.go +++ b/postgres/literal_test.go @@ -62,6 +62,11 @@ func TestString(t *testing.T) { assertSerialize(t, String("Some text"), `$1`, "Some text") } +func TestBytea(t *testing.T) { + assertSerialize(t, Bytea("Some text"), `$1::bytea`, "Some text") + assertSerialize(t, Bytea([]byte("Some byte array")), `$1::bytea`, []byte("Some byte array")) +} + func TestDate(t *testing.T) { assertSerialize(t, Date(2014, time.January, 2), `$1::date`, "2014-01-02") assertSerialize(t, DateT(time.Now()), `$1::date`) diff --git a/tests/postgres/sample_test.go b/tests/postgres/sample_test.go index b554431..f1d9999 100644 --- a/tests/postgres/sample_test.go +++ b/tests/postgres/sample_test.go @@ -497,3 +497,54 @@ FROM test_sample."User"; ] `) } + +func TestBytea(t *testing.T) { + byteArrHex := "\\x48656c6c6f20476f7068657221" + byteArrBin := []byte("\x48\x65\x6c\x6c\x6f\x20\x47\x6f\x70\x68\x65\x72\x21") + + insertStmt := AllTypes.INSERT(AllTypes.Bytea, AllTypes.ByteaPtr). + VALUES(byteArrHex, byteArrBin). + RETURNING(AllTypes.Bytea, AllTypes.ByteaPtr) + + testutils.AssertStatementSql(t, insertStmt, ` +INSERT INTO test_sample.all_types (bytea, bytea_ptr) +VALUES ($1, $2) +RETURNING all_types.bytea AS "all_types.bytea", + all_types.bytea_ptr AS "all_types.bytea_ptr"; +`, byteArrHex, byteArrBin) + + var inserted model.AllTypes + err := insertStmt.Query(db, &inserted) + require.NoError(t, err) + + require.Equal(t, string(*inserted.ByteaPtr), "Hello Gopher!") + // It is not possible to initiate bytea column using hex format '\xDEADBEEF' with pq driver. + // pq driver always encodes parameter string if destination column is of type bytea. + // Probably pq driver error. + // require.Equal(t, string(inserted.Bytea), "Hello Gopher!") + + stmt := SELECT( + AllTypes.Bytea, + AllTypes.ByteaPtr, + ).FROM( + AllTypes, + ).WHERE( + AllTypes.ByteaPtr.EQ(Bytea(byteArrBin)), + ) + + testutils.AssertStatementSql(t, stmt, ` +SELECT all_types.bytea AS "all_types.bytea", + all_types.bytea_ptr AS "all_types.bytea_ptr" +FROM test_sample.all_types +WHERE all_types.bytea_ptr = $1::bytea; +`, byteArrBin) + + var dest model.AllTypes + + err = stmt.Query(db, &dest) + require.NoError(t, err) + + require.Equal(t, string(*dest.ByteaPtr), "Hello Gopher!") + // Probably pq driver error. + // require.Equal(t, string(dest.Bytea), "Hello Gopher!") +}