From 6cc0cdea819a01bbe1daa9c21ded6b8ed92a74f4 Mon Sep 17 00:00:00 2001 From: Jacob Quinn Date: Thu, 29 Oct 2026 21:27:05 -0600 Subject: [PATCH] Bind JSON values as their JSON text json and jsonb columns decode to JSON.LazyValue, but binding one back as a parameter sent Julia's display of it ("LazyObject{String} with 1 entry: ..."). json and jsonb targets rejected that text; text targets stored it silently. LazyValue and JSONText parameters now send their JSON text, in scalars and array elements alike. Co-Authored-By: Claude Opus 5.5 --- src/execute.jl | 4 ++++ test/runtests.jl | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/execute.jl b/src/execute.jl index 6c2fed3..afa8f33 100644 --- a/src/execute.jl +++ b/src/execute.jl @@ -278,6 +278,10 @@ end _param(x::Missing) = x _param(::Nothing) = missing _param(x::AbstractVector{UInt8})::String = string("\\x", bytes2hex(x)) +# json/jsonb results are lazy JSON values; bind them (and raw JSONText) as +# their JSON text, not as Julia's display of them. +_param(x::JSON.LazyValue)::String = JSON.parse(x, JSON.JSONText).value +_param(x::JSON.JSONText)::String = x.value # convert to postgres array literal syntax: { x, y, z } # strings must be double-quoted and double quotes and backslashes escaped # missing values are NULL diff --git a/test/runtests.jl b/test/runtests.jl index d273630..fd4fb84 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1399,6 +1399,15 @@ include("trim_compile_tests.jl") @test array_types_row.date_array == Date[Date(2024, 1, 28)] @test isequal(array_types_row.numeric_array, [Postgres.API.parse_numeric("123.45"), missing]) @test JSON.parse(only(array_types_row.jsonb_array))["a"] == 1 + # JSON values read from the server bind back as their JSON text + json_text = """{"n": 12345678901234567890.5, "s": "é"}""" + json_value = only(Tables.rowtable(DBInterface.execute(conn, "SELECT '$json_text'::jsonb AS j"))).j + json_row = only(Tables.rowtable(DBInterface.execute(conn, + raw"SELECT $1::text AS t, $2::jsonb[]::text AS a, $3::json::text AS raw", + (json_value, [json_value.n, missing], JSON.JSONText("[1, 2]"))))) + @test json_row.t == json_text + @test json_row.a == "{12345678901234567890.5,NULL}" + @test json_row.raw == "[1, 2]" end @testset "Binary Array Round Trips" begin