89 lines
1.7 KiB
Go
89 lines
1.7 KiB
Go
package clause
|
|
|
|
import "strings"
|
|
|
|
// With Common Table Expressions
|
|
type With struct {
|
|
Recursive bool
|
|
Exprs []Expression
|
|
Expression Expression
|
|
}
|
|
|
|
// Name with clause name
|
|
func (with With) Name() string {
|
|
return "WITH"
|
|
}
|
|
|
|
// Build build with clause
|
|
func (with With) Build(builder Builder) {
|
|
if with.Expression != nil {
|
|
with.Expression.Build(builder)
|
|
return
|
|
}
|
|
if len(with.Exprs) == 0 {
|
|
return
|
|
}
|
|
|
|
if with.Recursive {
|
|
builder.WriteString("RECURSIVE ")
|
|
}
|
|
for idx, expr := range with.Exprs {
|
|
if idx != 0 {
|
|
builder.WriteByte(',')
|
|
}
|
|
expr.Build(builder)
|
|
}
|
|
}
|
|
|
|
// MergeClause merge with clauses
|
|
func (with With) MergeClause(clause *Clause) {
|
|
if w, ok := clause.Expression.(With); ok {
|
|
if !with.Recursive {
|
|
with.Recursive = w.Recursive
|
|
}
|
|
if w.Expression != nil {
|
|
with.Expression = w.Expression
|
|
with.Exprs = nil
|
|
} else if with.Expression == nil {
|
|
exprs := make([]Expression, len(w.Exprs)+len(with.Exprs))
|
|
copy(exprs, w.Exprs)
|
|
copy(exprs[len(w.Exprs):], with.Exprs)
|
|
with.Exprs = exprs
|
|
}
|
|
}
|
|
clause.Expression = with
|
|
}
|
|
|
|
// WithExpression with expression
|
|
type WithExpression struct {
|
|
Name string
|
|
Columns []string
|
|
Expr Expression
|
|
}
|
|
|
|
func (with WithExpression) Build(builder Builder) {
|
|
if with.Name == "" || with.Expr == nil {
|
|
return
|
|
}
|
|
|
|
builder.WriteQuoted(with.Name)
|
|
|
|
if len(with.Columns) > 0 {
|
|
builder.WriteByte(' ')
|
|
builder.WriteByte('(')
|
|
for idx, column := range with.Columns {
|
|
if idx != 0 {
|
|
builder.WriteByte(',')
|
|
}
|
|
column = strings.TrimSpace(column)
|
|
builder.WriteQuoted(column)
|
|
}
|
|
builder.WriteByte(')')
|
|
}
|
|
|
|
builder.WriteString(" AS ")
|
|
builder.WriteByte('(')
|
|
with.Expr.Build(builder)
|
|
builder.WriteByte(')')
|
|
}
|