[PostgreSQL] Add support for WITH statements and Common Table Expressions.
This commit is contained in:
parent
fb8607da29
commit
8aa894730c
10 changed files with 60 additions and 26 deletions
|
|
@ -5,18 +5,23 @@ import (
|
|||
)
|
||||
|
||||
type clauseReturning struct {
|
||||
Projections []jet.Projection
|
||||
ProjectionList []jet.Projection
|
||||
}
|
||||
|
||||
func (r *clauseReturning) Serialize(statementType jet.StatementType, out *jet.SQLBuilder, options ...jet.SerializeOption) {
|
||||
if len(r.Projections) == 0 {
|
||||
if len(r.ProjectionList) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
out.NewLine()
|
||||
out.WriteString("RETURNING")
|
||||
out.IncreaseIdent()
|
||||
out.WriteProjections(statementType, r.Projections)
|
||||
out.WriteProjections(statementType, r.ProjectionList)
|
||||
out.DecreaseIdent()
|
||||
}
|
||||
|
||||
func (r clauseReturning) Projections() ProjectionList {
|
||||
return r.ProjectionList
|
||||
}
|
||||
|
||||
// ========================================== //
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import "github.com/go-jet/jet/internal/jet"
|
|||
|
||||
// DeleteStatement is interface for PostgreSQL DELETE statement
|
||||
type DeleteStatement interface {
|
||||
Statement
|
||||
jet.SerializerStatement
|
||||
|
||||
WHERE(expression BoolExpression) DeleteStatement
|
||||
|
||||
|
|
@ -37,6 +37,6 @@ func (d *deleteStatementImpl) WHERE(expression BoolExpression) DeleteStatement {
|
|||
}
|
||||
|
||||
func (d *deleteStatementImpl) RETURNING(projections ...jet.Projection) DeleteStatement {
|
||||
d.Returning.Projections = projections
|
||||
d.Returning.ProjectionList = projections
|
||||
return d
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ var MINf = jet.MINf
|
|||
// MINi is aggregate function. Returns minimum value of int expression across all input values
|
||||
var MINi = jet.MINi
|
||||
|
||||
// SUM is aggregate function. Returns sum of all expressions
|
||||
var SUM = jet.SUM
|
||||
|
||||
// SUMf is aggregate function. Returns sum of expression across all float expressions
|
||||
var SUMf = jet.SUMf
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import "github.com/go-jet/jet/internal/jet"
|
|||
|
||||
// InsertStatement is interface for SQL INSERT statements
|
||||
type InsertStatement interface {
|
||||
Statement
|
||||
jet.SerializerStatement
|
||||
|
||||
// Insert row of values
|
||||
VALUES(value interface{}, values ...interface{}) InsertStatement
|
||||
|
|
@ -55,7 +55,7 @@ func (i *insertStatementImpl) MODELS(data interface{}) InsertStatement {
|
|||
}
|
||||
|
||||
func (i *insertStatementImpl) RETURNING(projections ...jet.Projection) InsertStatement {
|
||||
i.Returning.Projections = projections
|
||||
i.Returning.ProjectionList = projections
|
||||
return i
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,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.Select.Projections = projections
|
||||
newSelect.Select.ProjectionList = projections
|
||||
newSelect.From.Table = table
|
||||
newSelect.Limit.Count = -1
|
||||
newSelect.Offset.Count = -1
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,37 +4,37 @@ 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...))
|
||||
}
|
||||
|
||||
// INTERSECT returns all rows that are in query results.
|
||||
// It eliminates duplicate rows from its result.
|
||||
func INTERSECT(lhs, rhs jet.StatementWithProjections, selects ...jet.StatementWithProjections) setStatement {
|
||||
func INTERSECT(lhs, rhs jet.SerializerStatement, selects ...jet.SerializerStatement) setStatement {
|
||||
return newSetStatementImpl(intersect, false, toSelectList(lhs, rhs, selects...))
|
||||
}
|
||||
|
||||
// INTERSECT_ALL returns all rows that are in query results.
|
||||
// It does not eliminates duplicate rows from its result.
|
||||
func INTERSECT_ALL(lhs, rhs jet.StatementWithProjections, selects ...jet.StatementWithProjections) setStatement {
|
||||
func INTERSECT_ALL(lhs, rhs jet.SerializerStatement, selects ...jet.SerializerStatement) setStatement {
|
||||
return newSetStatementImpl(intersect, true, toSelectList(lhs, rhs, selects...))
|
||||
}
|
||||
|
||||
// EXCEPT returns all rows that are in the result of query lhs but not in the result of query rhs.
|
||||
// It eliminates duplicate rows from its result.
|
||||
func EXCEPT(lhs, rhs jet.StatementWithProjections) setStatement {
|
||||
func EXCEPT(lhs, rhs jet.SerializerStatement) setStatement {
|
||||
return newSetStatementImpl(except, false, toSelectList(lhs, rhs))
|
||||
}
|
||||
|
||||
// EXCEPT_ALL returns all rows that are in the result of query lhs but not in the result of query rhs.
|
||||
// It does not eliminates duplicate rows from its result.
|
||||
func EXCEPT_ALL(lhs, rhs jet.StatementWithProjections) setStatement {
|
||||
func EXCEPT_ALL(lhs, rhs jet.SerializerStatement) setStatement {
|
||||
return newSetStatementImpl(except, true, toSelectList(lhs, rhs))
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +98,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)
|
||||
|
|
@ -139,6 +139,6 @@ const (
|
|||
except = "EXCEPT"
|
||||
)
|
||||
|
||||
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...)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,30 +54,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) ReadableTable {
|
||||
func (r readableTableInterfaceImpl) INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
|
||||
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) ReadableTable {
|
||||
func (r readableTableInterfaceImpl) LEFT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
|
||||
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) ReadableTable {
|
||||
func (r readableTableInterfaceImpl) RIGHT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
|
||||
return newJoinTable(r.parent, table, jet.RightJoin, onCondition)
|
||||
}
|
||||
|
||||
func (r *readableTableInterfaceImpl) FULL_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
|
||||
func (r readableTableInterfaceImpl) FULL_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
|
||||
return newJoinTable(r.parent, table, jet.FullJoin, onCondition)
|
||||
}
|
||||
|
||||
func (r *readableTableInterfaceImpl) CROSS_JOIN(table ReadableTable) ReadableTable {
|
||||
func (r readableTableInterfaceImpl) CROSS_JOIN(table ReadableTable) ReadableTable {
|
||||
return newJoinTable(r.parent, table, jet.CrossJoin, nil)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
// UpdateStatement is interface of SQL UPDATE statement
|
||||
type UpdateStatement interface {
|
||||
Statement
|
||||
jet.SerializerStatement
|
||||
|
||||
SET(value interface{}, values ...interface{}) UpdateStatement
|
||||
MODEL(data interface{}) UpdateStatement
|
||||
|
|
@ -67,7 +67,7 @@ func (u *updateStatementImpl) WHERE(expression BoolExpression) UpdateStatement {
|
|||
}
|
||||
|
||||
func (u *updateStatementImpl) RETURNING(projections ...jet.Projection) UpdateStatement {
|
||||
u.Returning.Projections = projections
|
||||
u.Returning.ProjectionList = projections
|
||||
return u
|
||||
}
|
||||
|
||||
|
|
|
|||
26
postgres/with_statement.go
Normal file
26
postgres/with_statement.go
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package postgres
|
||||
|
||||
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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue