[MySQL] Add support for WITH statements and Common Table Expressions.

This commit is contained in:
go-jet 2020-05-24 17:56:35 +02:00
parent 8aa894730c
commit f5fae577d7
6 changed files with 42 additions and 13 deletions

View file

@ -85,6 +85,9 @@ var MINi = jet.MINi
// MINf is aggregate function. Returns minimum value of float expression across all input values
var MINf = jet.MINf
// SUM is aggregate function. Returns sum of all expressions
var SUM = jet.SUM
// SUMi is aggregate function. Returns sum of integer expression.
var SUMi = jet.SUMi

View file

@ -69,7 +69,7 @@ func newSelectStatement(table ReadableTable, projections []Projection) SelectSta
&newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.Window, &newSelect.OrderBy,
&newSelect.Limit, &newSelect.Offset, &newSelect.For, &newSelect.ShareLock)
newSelect.Select.Projections = projections
newSelect.Select.ProjectionList = projections
newSelect.From.Table = table
newSelect.Limit.Count = -1
newSelect.Offset.Count = -1

View file

@ -13,7 +13,7 @@ type selectTableImpl struct {
readableTableInterfaceImpl
}
func newSelectTable(selectStmt jet.StatementWithProjections, alias string) SelectTable {
func newSelectTable(selectStmt jet.SerializerStatement, alias string) SelectTable {
subQuery := &selectTableImpl{
SelectTable: jet.NewSelectTable(selectStmt, alias),
}

View file

@ -4,13 +4,13 @@ import "github.com/go-jet/jet/internal/jet"
// UNION effectively appends the result of sub-queries(select statements) into single query.
// It eliminates duplicate rows from its result.
func UNION(lhs, rhs jet.StatementWithProjections, selects ...jet.StatementWithProjections) setStatement {
func UNION(lhs, rhs jet.SerializerStatement, selects ...jet.SerializerStatement) setStatement {
return newSetStatementImpl(union, false, toSelectList(lhs, rhs, selects...))
}
// UNION_ALL effectively appends the result of sub-queries(select statements) into single query.
// It does not eliminates duplicate rows from its result.
func UNION_ALL(lhs, rhs jet.StatementWithProjections, selects ...jet.StatementWithProjections) setStatement {
func UNION_ALL(lhs, rhs jet.SerializerStatement, selects ...jet.SerializerStatement) setStatement {
return newSetStatementImpl(union, true, toSelectList(lhs, rhs, selects...))
}
@ -54,7 +54,7 @@ type setStatementImpl struct {
setOperator jet.ClauseSetStmtOperator
}
func newSetStatementImpl(operator string, all bool, selects []jet.StatementWithProjections) setStatement {
func newSetStatementImpl(operator string, all bool, selects []jet.SerializerStatement) setStatement {
newSetStatement := &setStatementImpl{}
newSetStatement.ExpressionStatement = jet.NewExpressionStatementImpl(Dialect, jet.SetStatementType, newSetStatement,
&newSetStatement.setOperator)
@ -93,6 +93,6 @@ const (
union = "UNION"
)
func toSelectList(lhs, rhs jet.StatementWithProjections, selects ...jet.StatementWithProjections) []jet.StatementWithProjections {
return append([]jet.StatementWithProjections{lhs, rhs}, selects...)
func toSelectList(lhs, rhs jet.SerializerStatement, selects ...jet.SerializerStatement) []jet.SerializerStatement {
return append([]jet.SerializerStatement{lhs, rhs}, selects...)
}

View file

@ -49,30 +49,30 @@ type readableTableInterfaceImpl struct {
}
// Generates a select query on the current tableName.
func (r *readableTableInterfaceImpl) SELECT(projection1 Projection, projections ...Projection) SelectStatement {
func (r readableTableInterfaceImpl) SELECT(projection1 Projection, projections ...Projection) SelectStatement {
return newSelectStatement(r.parent, append([]Projection{projection1}, projections...))
}
// Creates a inner join tableName Expression using onCondition.
func (r *readableTableInterfaceImpl) INNER_JOIN(table ReadableTable, onCondition BoolExpression) joinSelectUpdateTable {
func (r readableTableInterfaceImpl) INNER_JOIN(table ReadableTable, onCondition BoolExpression) joinSelectUpdateTable {
return newJoinTable(r.parent, table, jet.InnerJoin, onCondition)
}
// Creates a left join tableName Expression using onCondition.
func (r *readableTableInterfaceImpl) LEFT_JOIN(table ReadableTable, onCondition BoolExpression) joinSelectUpdateTable {
func (r readableTableInterfaceImpl) LEFT_JOIN(table ReadableTable, onCondition BoolExpression) joinSelectUpdateTable {
return newJoinTable(r.parent, table, jet.LeftJoin, onCondition)
}
// Creates a right join tableName Expression using onCondition.
func (r *readableTableInterfaceImpl) RIGHT_JOIN(table ReadableTable, onCondition BoolExpression) joinSelectUpdateTable {
func (r readableTableInterfaceImpl) RIGHT_JOIN(table ReadableTable, onCondition BoolExpression) joinSelectUpdateTable {
return newJoinTable(r.parent, table, jet.RightJoin, onCondition)
}
func (r *readableTableInterfaceImpl) FULL_JOIN(table ReadableTable, onCondition BoolExpression) joinSelectUpdateTable {
func (r readableTableInterfaceImpl) FULL_JOIN(table ReadableTable, onCondition BoolExpression) joinSelectUpdateTable {
return newJoinTable(r.parent, table, jet.FullJoin, onCondition)
}
func (r *readableTableInterfaceImpl) CROSS_JOIN(table ReadableTable) joinSelectUpdateTable {
func (r readableTableInterfaceImpl) CROSS_JOIN(table ReadableTable) joinSelectUpdateTable {
return newJoinTable(r.parent, table, jet.CrossJoin, nil)
}

26
mysql/with_statement.go Normal file
View file

@ -0,0 +1,26 @@
package mysql
import "github.com/go-jet/jet/internal/jet"
// CommonTableExpression contains information about a CTE.
type CommonTableExpression struct {
readableTableInterfaceImpl
jet.CommonTableExpression
}
// WITH function creates new WITH statement from list of common table expressions
func WITH(cte ...jet.CommonTableExpressionDefinition) func(statement jet.SerializerStatement) Statement {
return jet.WITH(Dialect, cte...)
}
// CTE creates new named CommonTableExpression
func CTE(name string) CommonTableExpression {
cte := CommonTableExpression{
readableTableInterfaceImpl: readableTableInterfaceImpl{},
CommonTableExpression: jet.CTE(name),
}
cte.parent = &cte
return cte
}