Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
123568: workload/schemachange: add routine input DEFAULT expressions r=fqazi a=fqazi

Previously, the randomized schema changer workload would generate functions with no default parameters and only use enum types for input parameters. This limited what was tested by this workload. To address this, this patch will generate functions with default values and non-enum type parameters.  Additionally, function invocations will now use non-null values for input parameters.

Fixes: cockroachdb#121718

Release note: None

Co-authored-by: Faizan Qazi <[email protected]>
  • Loading branch information
craig[bot] and fqazi committed May 6, 2024
2 parents b4ad399 + 91f7f4b commit 4e6c1d7
Showing 1 changed file with 93 additions and 9 deletions.
102 changes: 93 additions & 9 deletions pkg/workload/schemachange/operation_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"github.com/cockroachdb/errors"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
"github.com/lib/pq/oid"
"golang.org/x/exp/slices"
)

Expand Down Expand Up @@ -3936,7 +3937,9 @@ func (og *operationGenerator) createFunction(ctx context.Context, tx pgx.Tx) (*o
}, `SELECT
quote_ident(schema_id::REGNAMESPACE::STRING) AS schema,
quote_ident(name) AS name,
array_to_string(proargnames, ',') AS args
array_to_string(proargnames, ',') AS args,
proargtypes AS argtypes,
pronargdefaults as numdefaults
FROM
functions
INNER JOIN pg_catalog.pg_proc ON oid = (id + 100000)
Expand Down Expand Up @@ -3968,6 +3971,7 @@ FROM
var droppingEnumMembers []string
var possibleBodyReferences []string
var possibleParamReferences []string
var possibleParamReferencesWithDefaults []string
var possibleReturnReferences []string
var fnDuplicate bool

Expand All @@ -3979,6 +3983,55 @@ FROM
possibleReturnReferences = append(possibleReturnReferences, enum["name"].(string))
possibleParamReferences = append(possibleParamReferences, fmt.Sprintf(`enum_%d %s`, i, enum["name"]))
}
// PGLSN was added in 23.2.
pgLSNNotSupported, err := isClusterVersionLessThan(
ctx,
tx,
clusterversion.V23_2.Version())
if err != nil {
return nil, err
}
// REFCURSOR was added in 23.2.
refCursorNotSupported, err := isClusterVersionLessThan(
ctx,
tx,
clusterversion.V23_2.Version())
if err != nil {
return nil, err
}

defaultExpressionsNotSupported, err := isClusterVersionLessThan(
ctx,
tx,
clusterversion.V24_1.Version())
if err != nil {
return nil, err
}

// Generate random parameters / values for builtin types.
for i, typeVal := range randgen.SeedTypes {
// If we have types where invalid values can exist then skip over these,
// since randgen will not introspect to generate valid values (i.e. OID
// and REGCLASS).
if typeVal.Identical(types.AnyTuple) ||
typeVal.IsWildcardType() ||
typeVal == types.RegClass ||
typeVal.Family() == types.OidFamily ||
(pgLSNNotSupported && typeVal.Family() == types.PGLSNFamily) ||
(refCursorNotSupported && typeVal.Family() == types.RefCursorFamily) {
continue
}
possibleReturnReferences = append(possibleReturnReferences, typeVal.SQLStandardName())
possibleParamReferences = append(possibleParamReferences, fmt.Sprintf("val_%d %s", i+len(enums), typeVal.SQLStandardName()))
optionalDefaultValue := randgen.RandDatum(og.params.rng, typeVal, true)
if !defaultExpressionsNotSupported {
possibleParamReferencesWithDefaults = append(possibleParamReferencesWithDefaults, fmt.Sprintf("val_%d %s DEFAULT %s",
i+len(enums)+len(randgen.SeedTypes),
typeVal.SQLStandardName(),
tree.AsStringWithFlags(optionalDefaultValue, tree.FmtParsable)))
}

}

for _, member := range enumMembers {
if member["dropping"].(bool) {
Expand All @@ -4003,14 +4056,41 @@ FROM
args := ""
if function["args"] != nil {
args = function["args"].(string)
argTypesStr := strings.Split(function["argtypes"].(string), " ")
argTypes := make([]int, 0, len(argTypesStr))
// Determine how many default arguemnts should be used.
numDefaultArgs := int(function["numdefaults"].(int16))
if numDefaultArgs > 0 {
numDefaultArgs = rand.Intn(numDefaultArgs)
}
// Populate the arguments for this signature, and select some number
// of default arguments.
for _, oidStr := range argTypesStr {
oid, err := strconv.Atoi(oidStr)
if err != nil {
return nil, err
}
argTypes = append(argTypes, oid)
}
argIn := strings.Builder{}
// TODO(fqazi): Longer term we should populate actual arguments and
// not just NULLs.
for range strings.Split(args, ",") {
for idx := range strings.Split(args, ",") {
// We have hit the default arguments that we want to not populate.
if idx > len(argTypesStr)-numDefaultArgs {
break
}
if argIn.Len() > 0 {
argIn.WriteString(",")
}
argIn.WriteString("NULL")
// Resolve the type for each column and if possible generate a random
// value via randgen.
oidValue := oid.Oid(argTypes[idx])
typ, ok := types.OidToType[oidValue]
if !ok {
argIn.WriteString("NULL")
} else {
randomDatum := randgen.RandDatum(og.params.rng, typ, true)
argIn.WriteString(tree.AsStringWithFlags(randomDatum, tree.FmtParsable))
}
}
args = argIn.String()
}
Expand All @@ -4034,8 +4114,12 @@ FROM
},
"ParamRefs": func() (string, error) {
refs, err := PickBetween(og.params.rng, 1, 99, possibleParamReferences)
if err != nil {
return "", err
}
refsWithDefaults, err := PickBetween(og.params.rng, 1, 99, possibleParamReferencesWithDefaults)
if useParamRefs && err == nil {
return strings.Join(refs, ", "), nil
return strings.Join(append(refs, refsWithDefaults...), ", "), nil
}
return "", nil //nolint:returnerrcheck
},
Expand Down Expand Up @@ -4109,7 +4193,7 @@ func (og *operationGenerator) dropFunction(ctx context.Context, tx pgx.Tx) (*opS
FROM functions
JOIN LATERAL (
SELECT
COALESCE(array_agg(quote_ident(typnamespace::REGNAMESPACE::TEXT) || '.' || quote_ident(typname)), '{}') AS funcargs
COALESCE(array_agg(replace(quote_ident(typnamespace::REGNAMESPACE::TEXT) || '.' || quote_ident(typname), 'pg_catalog.', '')), '{}') AS funcargs
FROM pg_catalog.pg_type
JOIN LATERAL (
SELECT unnest(proargtypes) AS oid FROM pg_catalog.pg_proc WHERE oid = (id + 100000)
Expand Down Expand Up @@ -4190,7 +4274,7 @@ func (og *operationGenerator) alterFunctionRename(ctx context.Context, tx pgx.Tx
FROM functions
JOIN LATERAL (
SELECT
COALESCE(array_agg(quote_ident(typnamespace::REGNAMESPACE::TEXT) || '.' || quote_ident(typname)), '{}') AS funcargs
COALESCE(array_agg(replace(quote_ident(typnamespace::REGNAMESPACE::TEXT) || '.' || quote_ident(typname), 'pg_catalog.', '')), '{}') AS funcargs
FROM pg_catalog.pg_type
JOIN LATERAL (
SELECT unnest(proargtypes) AS oid FROM pg_catalog.pg_proc WHERE oid = (id + 100000)
Expand Down Expand Up @@ -4283,7 +4367,7 @@ func (og *operationGenerator) alterFunctionSetSchema(
FROM functions
JOIN LATERAL (
SELECT
COALESCE(array_agg(quote_ident(typnamespace::REGNAMESPACE::TEXT) || '.' || quote_ident(typname)), '{}') AS funcargs
COALESCE(array_agg(replace(quote_ident(typnamespace::REGNAMESPACE::TEXT) || '.' || quote_ident(typname), 'pg_catalog.', '')), '{}') AS funcargs
FROM pg_catalog.pg_type
JOIN LATERAL (
SELECT unnest(proargtypes) AS oid FROM pg_catalog.pg_proc WHERE oid = (id + 100000)
Expand Down

0 comments on commit 4e6c1d7

Please sign in to comment.