-
Notifications
You must be signed in to change notification settings - Fork 863
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
XMLCodec.DecodeValue always returns nil #2227
Comments
Please provide an example using pgx. Your example is not equivalent to the line you highlighted and the line itself is correct. |
Lines 195 to 196 in c2175fe
|
There you go. package main
import (
"encoding/xml"
"fmt"
"github.com/jackc/pgx/v5/pgtype"
)
func main() {
codec := &pgtype.XMLCodec{Marshal: xml.Marshal, Unmarshal: xml.Unmarshal}
out, err := codec.DecodeValue(
pgtype.NewMap(),
uint32(pgtype.XMLOID),
0,
[]byte(`<root><key1>v1</key1><key2>v2</key2></root>`),
)
if err != nil {
panic(err)
}
// out is always nil
fmt.Println(out)
} |
Sorry, but this is not a proper example. At no point, it is guaranteed the |
For example, if you look at the Note that |
It's not guaranteed, but it's the default: Line 94 in c2175fe
Please have another look at these two lines and note that Lines 195 to 196 in c2175fe
We can go back and forth on a "proper" example, but connecting to the database won't change the outcome here. More importantly - did you check the original comment that sparked this issue? @jackc confirmed that this is indeed an issue #2083 (comment). |
He said: "I think you're right.". That is no confirmation, rather just looking at these two lines of code might have confused himself. Yes, Ultimately, I believe |
@felix-roehrich I'm at a loss trying to understand what is not clear here. The library can be used in multiple ways, data can be scanned or it can be relied on the library to pick the best type (which in this case may be bytes). Not only this, but the default serder used, explicitly suggested that using any will result in nothing, which this library is using. See the following example. You are correct that scanning directly into a known type works, however requesting the values directly results in nil and it is unexpected. This is not a nondeterministic problem, since the type is quite evidently determined to be xml. The codec can do better knowing all this. package main
import (
"context"
"os"
"log"
"github.com/jackc/pgx/v5"
)
func main(){
ctx := context.Background()
c, err := pgx.Connect(ctx, os.Getenv("DATABASE_URL"))
defer c.Close(ctx)
if _, err := c.Exec(ctx, `CREATE TABLE IF NOT EXISTS xmldata (data xml)`); err != nil {
log.Fatal(err)
}
if _, err := c.Exec(ctx, `TRUNCATE TABLE xmldata`); err != nil {
log.Fatal(err)
}
bxml := []byte(`<root><key1>v1</key1><key2>v2</key2></root>`)
if _, err := c.Exec(ctx, `INSERT INTO xmldata (data) VALUES ($1)`, bxml); err != nil {
log.Fatal(err)
}
rows, err := c.Query(ctx, `SELECT data FROM xmldata`)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var s string
if err := rows.Scan(&s); err != nil {
log.Fatal(err)
}
log.Printf("svalue: %s\n", s)
vals, err := rows.Values()
if err != nil {
log.Fatal(err)
}
for _, v := range vals {
log.Printf("value: %v, type: %T", v, v)
}
}
} Results in go run main.go
2025/01/10 13:55:03 svalue: <root><key1>v1</key1><key2>v2</key2></root>
2025/01/10 13:55:03 value: <nil>, type: <nil> Another usage where the library is used indirectly via something like pglogical and has to use the codecs directly (e.g. |
Thanks, for your example. In this case the best that can be done, is returning the raw bytes or string. Do you mean that this should be the default behaviour? |
Yes, when the target type is unavailable I believe this is the best option, then the user can do whatever they need with the bytes, e.g. serder into map or custom type.
I disagree, the issue is represented by the assumption where the default un/marshal codec can decode in any, which is what that line did and that is not supported as per |
Previously, DecodeValue would always return nil with the default Unmarshal function. fixes #2227
Previously, DecodeValue would always return nil with the default Unmarshal function. fixes #2227
Thanks for the report. It does appear that Also, perhaps the original author of the XMLCodec may have some feedback - @nickcruess-soda |
Describe the bug
When trying to decode an XML value into a Go type, the driver always returns
nil
, because it tries to unmarshal the value into anany
typed value in this line. According to the documentation,xml.Unmarshal
will discard data that doesn't fit into the supplied value:To Reproduce
Runnable example: https://go.dev/play/p/yLdFqZPaoUo
Expected behavior
Probably that raw XML bytes are returned.
Actual behavior
The returned value contains
nil
.Version
Additional context
Discovered by @lyuboxa #2083 (comment).
The text was updated successfully, but these errors were encountered: