Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

smith: add all argument columns to ORDER BY #87085

Merged
merged 1 commit into from
Aug 31, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 26 additions & 24 deletions pkg/internal/sqlsmith/scalar.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,10 +410,6 @@ func makeFunc(s *Smither, ctx Context, typ *types.T, refs colRefs) (tree.TypedEx
}
}

// Some aggregation functions benefit from an order by clause.
var orderExpr tree.Expr
var orderType *types.T

args := make(tree.TypedExprs, 0)
for _, argTyp := range fn.overload.Types.Types() {
// Postgres is picky about having Int4 arguments instead of Int8.
Expand All @@ -425,10 +421,6 @@ func makeFunc(s *Smither, ctx Context, typ *types.T, refs colRefs) (tree.TypedEx
if class == tree.AggregateClass || class == tree.WindowClass {
var ok bool
arg, ok = makeColRef(s, argTyp, refs)
if ok && len(args) == 0 {
orderExpr = arg
orderType = argTyp
}
if !ok {
// If we can't find a col ref for our aggregate function, just use a
// constant.
Expand Down Expand Up @@ -458,20 +450,30 @@ func makeFunc(s *Smither, ctx Context, typ *types.T, refs colRefs) (tree.TypedEx
order tree.OrderBy
orderTypes []*types.T
)
addOrdCol := func(expr tree.Expr, typ *types.T) {
order = append(order, &tree.Order{Expr: expr, Direction: s.randDirection()})
orderTypes = append(orderTypes, typ)
}
s.sample(len(refs)-len(parts), 2, func(i int) {
ref := refs[i+len(parts)]
order = append(order, &tree.Order{
Expr: ref.item,
Direction: s.randDirection(),
})
orderTypes = append(orderTypes, ref.typ)
addOrdCol(ref.item, ref.typ)
})
if s.disableNondeterministicFns && orderExpr != nil {
order = append(order, &tree.Order{
Expr: orderExpr,
Direction: s.randDirection(),
})
orderTypes = append(orderTypes, orderType)
if s.disableNondeterministicFns {
switch fn.def.Name {
case "lead", "lag":
// Lead and lag need all columns to be added to the ORDER BY because
// while they respect the order, they can return any value within the
// partition. This means we need to be consistent about which rows fall
// on the boundary between peer groups.
for _, ref := range refs {
addOrdCol(ref.typedExpr(), ref.typ)
}
default:
// Other window functions only need to order by the argument columns.
for _, arg := range args {
addOrdCol(arg, arg.ResolvedType())
}
}
}
var frame *tree.WindowFrame
if s.coin() {
Expand All @@ -496,7 +498,7 @@ func makeFunc(s *Smither, ctx Context, typ *types.T, refs colRefs) (tree.TypedEx
)

// Some aggregation functions need an order by clause to be deterministic.
if s.disableNondeterministicFns && orderExpr != nil {
if s.disableNondeterministicFns && len(args) > 0 {
switch fn.def.Name {
case "array_agg",
"concat_agg",
Expand All @@ -508,10 +510,10 @@ func makeFunc(s *Smither, ctx Context, typ *types.T, refs colRefs) (tree.TypedEx
"string_agg",
"xmlagg":
funcExpr.AggType = tree.GeneralAgg
funcExpr.OrderBy = tree.OrderBy{{
Expr: orderExpr,
Direction: s.randDirection(),
}}
funcExpr.OrderBy = make(tree.OrderBy, len(args))
for i := range funcExpr.OrderBy {
funcExpr.OrderBy[i] = &tree.Order{Expr: args[i], Direction: s.randDirection()}
}
}
}

Expand Down