All data types are cast to string when query results are parsed
cat1s-smile opened this issue · 5 comments
Hello! I'm using go_ora and facing the issue when all query results are represented as string (with both go_ora and database/sql interfaces)
The problem appears in 2.8.11, but in 2.8.7 everything works fine
My code:
url := go_ora.BuildUrl("localhost", 1521, "oradb12345", "system", "oradb", make(map[string]string))
conn, _ := go_ora.NewConnection(url)
conn.Open()
query := "SELECT NULL as a, TO_NUMBER('1234567890123456789') as b, 'asdasd' as c, JSON('{\"name\":\"Beda\"}') as d FROM dual"
r, err := conn.QueryContext(context.Background(), query, []driver.NamedValue{})
dst := make([]driver.Value, len(r.Columns()))
r.Next(dst)
Also in 2.8.7 (in 2.8.11 JSON is broken) I got JSON as []uint8
In debug mode I can see that go_ora detects its type as OCIBlobLocator and sets isJson=false (because uds_flags=1024)
For json column, is there some kind of query which go_ora will unmarshal as map[string]any or []map[string]any (for json array) ?
My service gets sql query from from user, so it's impossible to determine if it should unmarshal some result or not
Hi @cat1s-smile
json and LONG issue is fixed in v2.8.13 you can check
using string to represent numbers is discussed at #533
Thank you for answering
But for JSON select queries (introduced in Oracle 21) the problem still exists
(I can see that insert discussed in #540 )
2 ways to reproduce:
SELECT NULL as a, TO_NUMBER('1234567890123456789') as b, 'asdasd' as c, JSON('{\"name\":\"Beda\"}') as d FROM dual
This query causes ORA-40569: Unimplemented JSON feature.
Also when I try to select it from table:
CREATE TABLE mytable (
id NUMBER PRIMARY KEY,
data JSON
)
tablespace USERS;
INSERT INTO mytable (id, data)
VALUES (1, '{"name": "John", "age": 30}');
SELECT id, data
FROM mytable;
I get 0 rows (EOF in error message)
to explain the code:
client version is lower than 21 (which is the version that support pure json type). before 21 json is a special type of BLOB
so server will downgrade its version to client version.
I get the implementation of IsJson
from python driver = uds_flags & 0x100
now I see the server sending uds_flags = 0x400
so to solve the issue I will use both uds_flags & 0x500
after make this change both code (you describe above) run without errors.
I push a new commit contain this change to test
Thanks, this fix works
But is there a way to automatically unmarshal json to map[string]any / []map[string]any on go-ora side?
I see in parameter.go that it has JSON TNSType = 119
But I get json columns as OCIBlobLocator (TNSType = 113)
In debug I can see that now isJson = true, but this info inaccessible in sql.ColumnType
yes I take definition for json data type from python driver but to use it I should upgrade client version to be >= 21 which is a big deal