Add support for postgres GROUPING SET, ROLLUP and CUBE grouping operators
Add support for mysql WITH ROLLUP grouping operator Add support for GROUPING operator
This commit is contained in:
parent
31dc7b6dd3
commit
fa69565dbf
9 changed files with 476 additions and 70 deletions
|
|
@ -12,7 +12,7 @@ func OR(expressions ...BoolExpression) BoolExpression {
|
|||
return newBoolExpressionListOperator("OR", expressions...)
|
||||
}
|
||||
|
||||
// ROW is construct one table row from list of expressions.
|
||||
// ROW function is used to create a tuple value that consists of a set of expressions or column values.
|
||||
func ROW(expressions ...Expression) Expression {
|
||||
return NewFunc("ROW", expressions, nil)
|
||||
}
|
||||
|
|
@ -602,16 +602,16 @@ func LEAST(value Expression, values ...Expression) Expression {
|
|||
type funcExpressionImpl struct {
|
||||
ExpressionInterfaceImpl
|
||||
|
||||
name string
|
||||
expressions []Expression
|
||||
noBrackets bool
|
||||
name string
|
||||
parameters parametersSerializer
|
||||
noBrackets bool
|
||||
}
|
||||
|
||||
// NewFunc creates new function with name and expressions parameters
|
||||
func NewFunc(name string, expressions []Expression, parent Expression) *funcExpressionImpl {
|
||||
funcExp := &funcExpressionImpl{
|
||||
name: name,
|
||||
expressions: parameters(expressions),
|
||||
name: name,
|
||||
parameters: parametersSerializer(expressions),
|
||||
}
|
||||
|
||||
if parent != nil {
|
||||
|
|
@ -623,18 +623,43 @@ func NewFunc(name string, expressions []Expression, parent Expression) *funcExpr
|
|||
return funcExp
|
||||
}
|
||||
|
||||
func parameters(expressions []Expression) []Expression {
|
||||
var ret []Expression
|
||||
|
||||
for _, expression := range expressions {
|
||||
if _, isStatement := expression.(Statement); isStatement {
|
||||
ret = append(ret, expression)
|
||||
} else {
|
||||
ret = append(ret, skipWrap(expression))
|
||||
}
|
||||
func (f *funcExpressionImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if serializeOverride := out.Dialect.FunctionSerializeOverride(f.name); serializeOverride != nil {
|
||||
serializeOverrideFunc := serializeOverride(ExpressionListToSerializerList(f.parameters)...)
|
||||
serializeOverrideFunc(statement, out, FallTrough(options)...)
|
||||
return
|
||||
}
|
||||
|
||||
return ret
|
||||
addBrackets := !f.noBrackets || len(f.parameters) > 0
|
||||
|
||||
if addBrackets {
|
||||
out.WriteString(f.name + "(")
|
||||
} else {
|
||||
out.WriteString(f.name)
|
||||
}
|
||||
|
||||
f.parameters.serialize(statement, out, options...)
|
||||
|
||||
if addBrackets {
|
||||
out.WriteString(")")
|
||||
}
|
||||
}
|
||||
|
||||
type parametersSerializer []Expression
|
||||
|
||||
func (p parametersSerializer) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
|
||||
for i, expression := range p {
|
||||
if i > 0 {
|
||||
out.WriteString(", ")
|
||||
}
|
||||
|
||||
if _, isStatement := expression.(Statement); isStatement {
|
||||
expression.serialize(statement, out, options...)
|
||||
} else {
|
||||
skipWrap(expression).serialize(statement, out, options...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NewFloatWindowFunc creates new float function with name and expressions
|
||||
|
|
@ -646,28 +671,6 @@ func newWindowFunc(name string, expressions ...Expression) windowExpression {
|
|||
return windowExpr
|
||||
}
|
||||
|
||||
func (f *funcExpressionImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if serializeOverride := out.Dialect.FunctionSerializeOverride(f.name); serializeOverride != nil {
|
||||
serializeOverrideFunc := serializeOverride(ExpressionListToSerializerList(f.expressions)...)
|
||||
serializeOverrideFunc(statement, out, FallTrough(options)...)
|
||||
return
|
||||
}
|
||||
|
||||
addBrackets := !f.noBrackets || len(f.expressions) > 0
|
||||
|
||||
if addBrackets {
|
||||
out.WriteString(f.name + "(")
|
||||
} else {
|
||||
out.WriteString(f.name)
|
||||
}
|
||||
|
||||
serializeExpressionList(statement, f.expressions, ", ", out)
|
||||
|
||||
if addBrackets {
|
||||
out.WriteString(")")
|
||||
}
|
||||
}
|
||||
|
||||
type boolFunc struct {
|
||||
funcExpressionImpl
|
||||
boolInterfaceImpl
|
||||
|
|
|
|||
|
|
@ -4,3 +4,38 @@ package jet
|
|||
type GroupByClause interface {
|
||||
serializeForGroupBy(statement StatementType, out *SQLBuilder)
|
||||
}
|
||||
|
||||
// GROUPING_SETS operator allows grouping of the rows in a table by multiple sets of columns in a single query.
|
||||
// This can be useful when we want to analyze data by different combinations of columns, without having to write separate
|
||||
// queries for each combination.
|
||||
func GROUPING_SETS(expressions ...Expression) GroupByClause {
|
||||
return Func("GROUPING SETS", expressions...)
|
||||
}
|
||||
|
||||
// ROLLUP operator is used with the GROUP BY clause to generate all prefixes of a group of columns including the empty list.
|
||||
// It creates extra rows in the result set that represent the subtotal values for each combination of columns.
|
||||
func ROLLUP(expressions ...Expression) GroupByClause {
|
||||
return Func("ROLLUP", expressions...)
|
||||
}
|
||||
|
||||
// CUBE operator is used with the GROUP BY clause to generate subtotals for all possible combinations of a group of columns.
|
||||
// It creates extra rows in the result set that represent the subtotal values for each combination of columns.
|
||||
func CUBE(expressions ...Expression) GroupByClause {
|
||||
return Func("CUBE", expressions...)
|
||||
}
|
||||
|
||||
// GROUPING function is used to identify which columns are included in a grouping set or a subtotal row. It takes as input
|
||||
// the name of a column and returns 1 if the column is not included in the current grouping set, and 0 otherwise.
|
||||
// It can be also used with multiple parameters to check if a set of columns is included in the current grouping set. The result
|
||||
// of the GROUPING function would then be an integer bit mask having 1’s for the arguments which have GROUPING(argument) as 1.
|
||||
func GROUPING(expressions ...Expression) IntegerExpression {
|
||||
return IntExp(Func("GROUPING", expressions...))
|
||||
}
|
||||
|
||||
// WITH_ROLLUP operator is used with the GROUP BY clause to generate all prefixes of a group of columns including the empty list.
|
||||
// It creates extra rows in the result set that represent the subtotal values for each combination of columns.
|
||||
func WITH_ROLLUP(expressions ...Expression) GroupByClause {
|
||||
return newCustomExpression(
|
||||
parametersSerializer(expressions), Token("WITH ROLLUP"),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ func (n *wrap) serialize(statementType StatementType, out *SQLBuilder, options .
|
|||
out.WriteString(")")
|
||||
}
|
||||
|
||||
// WRAP wraps list of expressions with brackets '(' and ')'
|
||||
// WRAP wraps list of expressions with brackets - ( expression1, expression2, ... )
|
||||
func WRAP(expression ...Expression) Expression {
|
||||
wrap := &wrap{expressions: expression}
|
||||
wrap.ExpressionInterfaceImpl.Parent = wrap
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue