Skip to content

Commit

Permalink
pg_catalog: indoption was not encoded correctly
Browse files Browse the repository at this point in the history
Previously, the indoption field inside pg_index was encoded incorrectly,
which could cause problems for binary clients. Specifically, an int8 was
being sent across the wire, then int2vectors are supposed to be made of
int2. To address this, this patch ensures that an int2 is used and adds
assertion inside the conversion code (for int2vector) to avoid future
problems.

Fixes: #111907

Release note (bug fix): indoption inside pg_index was not properly
encoded, causing clients to be unable to decode it as int2vector.
  • Loading branch information
fqazi committed Oct 6, 2023
1 parent 87dfffb commit 1588a76
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pkg/sql/pg_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -1879,7 +1879,7 @@ https://www.postgresql.org/docs/9.5/catalog-pg-index.html`,
// Also fill in indoption for each column to indicate if the index
// is ASC/DESC and if nulls appear first/last.
collationOids := tree.NewDArray(types.Oid)
indoption := tree.NewDArray(types.Int)
indoption := tree.NewDArray(types.Int2)

colAttNums := make([]descpb.ColumnID, 0, index.NumKeyColumns())
exprs := make([]string, 0, index.NumKeyColumns())
Expand Down
33 changes: 33 additions & 0 deletions pkg/sql/pgwire/testdata/pgtest/int2vector
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# This test validates that int2vector produces an array
# of int2 objects. Previously CRDB incorrectly was returning
# int8 values as observed in #111907, which would cause problems
# for binary pgwire clients.
send
Query {"String": "DROP TABLE IF EXISTS t"}
Query {"String": "CREATE TABLE t (a int primary key, b text)"}
----

until
ReadyForQuery
ReadyForQuery
----
{"Type":"CommandComplete","CommandTag":"DROP TABLE"}
{"Type":"ReadyForQuery","TxStatus":"I"}
{"Type":"CommandComplete","CommandTag":"CREATE TABLE"}
{"Type":"ReadyForQuery","TxStatus":"I"}

send
Parse {"Query": "select i.indoption from pg_index i join pg_class c on i.indrelid = c.oid where c.relname = 't';"}
Bind {"ParameterFormatCodes": [0], "ResultFormatCodes": [1]}
Execute
Sync
----

until
ReadyForQuery
----
{"Type":"ParseComplete"}
{"Type":"BindComplete"}
{"Type":"DataRow","Values":[{"binary":"0000000100000000000000150000000100000001000000020002"}]}
{"Type":"CommandComplete","CommandTag":"SELECT 1"}
{"Type":"ReadyForQuery","TxStatus":"I"}
4 changes: 4 additions & 0 deletions pkg/sql/sem/tree/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -5922,6 +5922,10 @@ func NewDName(d string) Datum {
// NewDIntVectorFromDArray is a helper routine to create a new *DArray,
// initialized from an existing *DArray, with the special oid for IntVector.
func NewDIntVectorFromDArray(d *DArray) Datum {
// Sanity: Validate the type of the array, since it should be int2.
if d.ParamTyp != types.Int2 {
panic(errors.AssertionFailedf("int2vector can only be made from int2 not %v", d.ParamTyp))
}
ret := new(DArray)
*ret = *d
ret.customOid = oid.T_int2vector
Expand Down

0 comments on commit 1588a76

Please sign in to comment.