Skip to content

Commit

Permalink
sql/pgwire: support for decoding JSON[] OID by aliasing to JSONB[] OID
Browse files Browse the repository at this point in the history
fixes cockroachdb#90839

Previously, with the parameter type oid (199) for JSON[], the pgwire parse message
will fail to be executed with a `unknown oid type: 199`. We now aliasing it
to the one for `JSONB[]`.

This commit follows the changes in cockroachdb#88379.

Release note (sql change): The pgwire protocol implementation can
now accept arguments of the JSON[] type (oid=199). Previously, it could
only accept JSONB[] (oid=3804). Internally, JSON[] and JSONB[] values are
still identical, so this change only affects how the values are received
over the wire protocol.
  • Loading branch information
ZhouXing19 committed Jan 18, 2023
1 parent 9529945 commit 7a0ac0c
Show file tree
Hide file tree
Showing 8 changed files with 538 additions and 26 deletions.
9 changes: 6 additions & 3 deletions pkg/sql/conn_executor_prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,11 +417,14 @@ func (ex *connExecutor) execBind(
} else {
typ, ok := types.OidToType[t]
if !ok {
// These special cases for json, json[] is here so we can
// support decoding parameters with oid=json/json[] without
// adding full support for these type.
// TODO(sql-exp): Remove this if we support JSON.
if t == oid.T_json {
// This special case is here so we can support decoding parameters
// with oid=json without adding full support for the JSON type.
// TODO(sql-exp): Remove this if we support JSON.
typ = types.Json
} else if t == oid.T__json {
typ = types.JSONArrayForDecodingOnly
} else {
var err error
typ, err = ex.planner.ResolveTypeByOID(ctx, t)
Expand Down
11 changes: 8 additions & 3 deletions pkg/sql/pgwire/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -969,13 +969,18 @@ func (c *conn) handleParse(
sqlTypeHints[i] = nil
continue
}
// This special case for json, json[] is here so we can support decoding
// parameters with oid=json/json[] without adding full support for these
// type.
// TODO(sql-exp): Remove this if we support JSON.
if t == oid.T_json {
// This special case is here so we can support decoding parameters
// with oid=json without adding full support for the JSON type.
// TODO(sql-exp): Remove this if we support JSON.
sqlTypeHints[i] = types.Json
continue
}
if t == oid.T__json {
sqlTypeHints[i] = types.JSONArrayForDecodingOnly
continue
}
v, ok := types.OidToType[t]
if !ok {
err := pgwirebase.NewProtocolViolationErrorf("unknown oid type: %v", t)
Expand Down
28 changes: 28 additions & 0 deletions pkg/sql/pgwire/pgwirebase/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,34 @@ func DecodeDatum(
return nil, err
}
return tree.ParseDJSON(string(b))
case oid.T__json, oid.T__jsonb:
var arr pgtype.JSONBArray
if err := arr.DecodeText(nil, b); err != nil {
return nil, tree.MakeParseError(string(b), typ, err)
}
if arr.Status != pgtype.Present {
return tree.DNull, nil
}
if err := validateArrayDimensions(len(arr.Dimensions), len(arr.Elements)); err != nil {
return nil, err
}
out := tree.NewDArray(types.Jsonb)
var d tree.Datum
var err error
for _, v := range arr.Elements {
if v.Status != pgtype.Present {
d = tree.DNull
} else {
d, err = tree.ParseDJSON(string(v.Bytes))
if err != nil {
return nil, err
}
}
if err := out.Append(d); err != nil {
return nil, err
}
}
return out, nil
case oid.T_tsquery:
ret, err := tsearch.ParseTSQuery(string(b))
if err != nil {
Expand Down
Loading

0 comments on commit 7a0ac0c

Please sign in to comment.