Add binary encoding for timestamptz

This commit is contained in:
Jack Christensen 2013-07-19 14:40:07 -05:00
parent faed7f2879
commit 9e321af35c
2 changed files with 75 additions and 2 deletions

View File

@ -15,6 +15,7 @@ var int8TextVsBinaryTestDataLoaded bool
var float4TextVsBinaryTestDataLoaded bool
var float8TextVsBinaryTestDataLoaded bool
var boolTextVsBinaryTestDataLoaded bool
var timestampTzTextVsBinaryTestDataLoaded bool
func createNarrowTestData(b *testing.B, conn *pgx.Connection) {
if narrowTestDataLoaded {
@ -544,3 +545,60 @@ func BenchmarkBoolBinary(b *testing.B) {
mustSelectRows(b, conn, "selectBool")
}
}
func createTimestampTzTextVsBinaryTestData(b *testing.B, conn *pgx.Connection) {
if timestampTzTextVsBinaryTestDataLoaded {
return
}
mustExecute(b, conn, `
drop table if exists t;
create temporary table t(
a timestamptz not null,
b timestamptz not null,
c timestamptz not null,
d timestamptz not null,
e timestamptz not null
);
insert into t(a, b, c, d, e)
select
now() - '10 years'::interval * random(),
now() - '10 years'::interval * random(),
now() - '10 years'::interval * random(),
now() - '10 years'::interval * random(),
now() - '10 years'::interval * random()
from generate_series(1, 10);
`)
timestampTzTextVsBinaryTestDataLoaded = true
}
func BenchmarkTimestampTzText(b *testing.B) {
conn := getSharedConnection()
createTimestampTzTextVsBinaryTestData(b, conn)
encoders := removeBinaryEncoders()
defer func() { restoreBinaryEncoders(encoders) }()
mustPrepare(b, conn, "selectTimestampTz", "select * from t")
defer func() { conn.Deallocate("selectTimestampTz") }()
b.ResetTimer()
for i := 0; i < b.N; i++ {
mustSelectRows(b, conn, "selectTimestampTz")
}
}
func BenchmarkTimestampTzBinary(b *testing.B) {
conn := getSharedConnection()
createTimestampTzTextVsBinaryTestData(b, conn)
mustPrepare(b, conn, "selectTimestampTz", "select * from t")
defer func() { conn.Deallocate("selectTimestampTz") }()
b.ResetTimer()
for i := 0; i < b.N; i++ {
mustSelectRows(b, conn, "selectTimestampTz")
}
}

View File

@ -96,8 +96,9 @@ func init() {
// timestamptz
ValueTranscoders[Oid(1184)] = &ValueTranscoder{
DecodeText: decodeTimestampTzFromText,
EncodeTo: encodeTimestampTz}
DecodeText: decodeTimestampTzFromText,
DecodeBinary: decodeTimestampTzFromBinary,
EncodeTo: encodeTimestampTz}
// use text transcoder for anything we don't understand
defaultTranscoder = ValueTranscoders[Oid(25)]
@ -299,6 +300,20 @@ func decodeTimestampTzFromText(mr *MessageReader, size int32) interface{} {
return t
}
func decodeTimestampTzFromBinary(mr *MessageReader, size int32) interface{} {
if size != 8 {
panic("Received an invalid size for an int8")
}
microsecFromUnixEpochToY2K := int64(946684800 * 1000000)
microsecSinceY2K := mr.ReadInt64()
microsecSinceUnixEpoch := microsecFromUnixEpochToY2K + microsecSinceY2K
return time.Unix(microsecSinceUnixEpoch/1000000, (microsecSinceUnixEpoch%1000000)*1000)
// 2000-01-01 00:00:00 in 946684800
// 946684800 * 1000000
}
func encodeTimestampTz(w *MessageWriter, value interface{}) {
t := value.(time.Time)
s := t.Format("2006-01-02 15:04:05.999999 -0700")