Skip to content

Commit

Permalink
sql: implement information_schema._pg_char_max_length
Browse files Browse the repository at this point in the history
Needed for cockroachdb#69010.

This commit adds implementations for the `information_schema._pg_char_max_length`
builtin function. This functions returns the maximum character length of a type
with the provided ID and modifier.

The builtin is implemented as a user-defined function in Postgres here:
https://github.com/postgres/postgres/blob/master/src/backend/catalog/information_schema.sql

Release justification: None, waiting for v22.1.
  • Loading branch information
nvanbenschoten committed Sep 8, 2021
1 parent 9af7351 commit a8a419c
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
37 changes: 37 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/pg_builtins
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,40 @@ varchar 1043 68
bit 1560 1
varbit 1562 16
numeric 1700 786438

# information_schema._pg_char_max_length

query TI
SELECT typname, information_schema._pg_char_max_length(a.atttypid, a.atttypmod)
FROM pg_attribute a
JOIN pg_type t
ON a.atttypid = t.oid
WHERE attrelid = 'types'::regclass
ORDER BY t.oid
----
text NULL
float8 NULL
bpchar 1
varchar 64
bit 1
varbit 16
numeric NULL

query TI
SELECT typname, information_schema._pg_char_max_length(
information_schema._pg_truetypid(a.*, t.*),
information_schema._pg_truetypmod(a.*, t.*)
)
FROM pg_attribute a
JOIN pg_type t
ON a.atttypid = t.oid
WHERE attrelid = 'types'::regclass
ORDER BY t.oid
----
text NULL
float8 NULL
bpchar 1
varchar 64
bit 1
varbit 16
numeric NULL
45 changes: 44 additions & 1 deletion pkg/sql/sem/builtins/pg_builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ var pgBuiltins = map[string]builtinDefinition{
return tree.DNull, nil
}
maybeTypmod := args[1]
oid := oid.Oid(int(oidArg.(*tree.DOid).DInt))
oid := oid.Oid(oidArg.(*tree.DOid).DInt)
typ, ok := types.OidToType[oid]
if !ok {
// If the type wasn't statically known, try looking it up as a user
Expand Down Expand Up @@ -1935,6 +1935,49 @@ SELECT description
// RETURN CASE WHEN $2.typtype = 'd' THEN $2.typtypmod ELSE $1.atttypmod END;
//
"information_schema._pg_truetypmod": pgTrueTypImpl("atttypmod", "typtypmod", types.Int4),

// NOTE: this could be defined as a user-defined function, like
// it is in Postgres:
// https://github.com/postgres/postgres/blob/master/src/backend/catalog/information_schema.sql
//
// CREATE FUNCTION _pg_char_max_length(typid oid, typmod int4) RETURNS integer
// LANGUAGE sql
// IMMUTABLE
// PARALLEL SAFE
// RETURNS NULL ON NULL INPUT
// RETURN
// CASE WHEN $2 = -1 /* default typmod */
// THEN null
// WHEN $1 IN (1042, 1043) /* char, varchar */
// THEN $2 - 4
// WHEN $1 IN (1560, 1562) /* bit, varbit */
// THEN $2
// ELSE null
// END;
//
"information_schema._pg_char_max_length": makeBuiltin(defProps(),
tree.Overload{
Types: tree.ArgTypes{
{"typid", types.Oid},
{"typmod", types.Int4},
},
ReturnType: tree.FixedReturnType(types.Int),
Fn: func(ctx *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
typid := oid.Oid(args[0].(*tree.DOid).DInt)
typmod := *args[1].(*tree.DInt)
if typmod == -1 {
return tree.DNull, nil
} else if typid == oid.T_bpchar || typid == oid.T_varchar {
return tree.NewDInt(typmod - 4), nil
} else if typid == oid.T_bit || typid == oid.T_varbit {
return tree.NewDInt(typmod), nil
}
return tree.DNull, nil
},
Info: notUsableInfo,
Volatility: tree.VolatilityImmutable,
},
),
}

func getSessionVar(ctx *tree.EvalContext, settingName string, missingOk bool) (tree.Datum, error) {
Expand Down

0 comments on commit a8a419c

Please sign in to comment.