Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot scan timestamp (OID 1114) in binary format into *string #2118

Open
xakepp35 opened this issue Aug 29, 2024 · 5 comments
Open

cannot scan timestamp (OID 1114) in binary format into *string #2118

xakepp35 opened this issue Aug 29, 2024 · 5 comments
Labels

Comments

@xakepp35
Copy link

Describe the bug
I am using protobuf generated structures, and it does not have time.Time type. However it have string type, which is sufficient for my goals. But library does not allow to scan timestamp as string. How can i do so? I cannot modify Response struct, as its a generated code. Also i dont want to copy from intermediate struct.

To Reproduce
try to scan timestamp column to *string field

package main

import (
	"context"
	"log"
	"os"

	"github.com/jackc/pgx/v5"
)

type Response struct {
	CreatedAt  string `protobuf:"bytes,11,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`    // created_at date,
}

func main() {
	conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close(context.Background())
	var res Response
	err :=  conn.QueryRow(context.Background(), "SELECT created_at FROM table").Scan(&res.CreatedAt)
	if err != nil {
		panic(err.Error()) // <-- err will follow caption
	}
}

Expected behavior
CreatedAt containing timestamp in RFC3339Nano string format

Actual behavior
non-nil err, containing message: "cannot scan timestamp (OID 1114) in binary format into *string"

@xakepp35 xakepp35 added the bug label Aug 29, 2024
@jackc
Copy link
Owner

jackc commented Aug 30, 2024

Here are some things you could try in rough order of difficulty:

  1. Cast the timestamp to string in your query (e.g. SELECT created_at::text FROM table).
  2. Tell pgx to use the text format all the time by changing the default query exec mode to QueryExecModeExec.
  3. Make your own string backed type that implements Timestamp(tz)Scanner. Cast your string to it when you scan. See the zeronull package for an example of that style.
  4. Copy the Timestamp(tz)Codec from pgx into your project, change it to allow scanning to a string, and register your new Codec on the connection.
  5. Create a new TryWrapScanPlanFunc that implements your custom behavior.

@hmoazzem
Copy link

hmoazzem commented Oct 8, 2024

Just ran into it, and somehow got it working.

type SomeObject struct {
  OID pgtype.Int8 `json:"oid"`
}

Now SomeObject.OID.Int64 does give desired OID. @jackc what you think of it?

@jackc
Copy link
Owner

jackc commented Oct 9, 2024

@hmoazzem I don't see how that code relates to scanning a binary timestamp into a *string.

@hmoazzem
Copy link

Maybe after looking at several issues I lost track of relevance. I was getting error scanning OID field, so searched and looked at many issues with OID in title

Anyway, what go data type would you (recommend to) use for OID?

@jackc
Copy link
Owner

jackc commented Oct 10, 2024

@hmoazzem uint32 or https://pkg.go.dev/github.com/jackc/pgx/[email protected]/pgtype#Uint32 if you need it to be nullable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants