Added support for window clause and functions.
This commit is contained in:
parent
b7363a554b
commit
5ba10d35db
13 changed files with 973 additions and 48 deletions
|
|
@ -87,6 +87,47 @@ var SUMf = jet.SUMf
|
|||
// SUMi is aggregate function. Returns sum of expression across all integer expression.
|
||||
var SUMi = jet.SUMi
|
||||
|
||||
// -------------------- Window functions -----------------------//
|
||||
|
||||
// ROW_NUMBER returns number of the current row within its partition, counting from 1
|
||||
var ROW_NUMBER = jet.ROW_NUMBER
|
||||
|
||||
// RANK of the current row with gaps; same as row_number of its first peer
|
||||
var RANK = jet.RANK
|
||||
|
||||
// DENSE_RANK returns rank of the current row without gaps; this function counts peer groups
|
||||
var DENSE_RANK = jet.DENSE_RANK
|
||||
|
||||
// PERCENT_RANK calculates relative rank of the current row: (rank - 1) / (total partition rows - 1)
|
||||
var PERCENT_RANK = jet.PERCENT_RANK
|
||||
|
||||
// CUME_DIST calculates cumulative distribution: (number of partition rows preceding or peer with current row) / total partition rows
|
||||
var CUME_DIST = jet.CUME_DIST
|
||||
|
||||
// NTILE returns integer ranging from 1 to the argument value, dividing the partition as equally as possible
|
||||
var NTILE = jet.NTILE
|
||||
|
||||
// LAG returns value evaluated at the row that is offset rows before the current row within the partition;
|
||||
// if there is no such row, instead return default (which must be of the same type as value).
|
||||
// Both offset and default are evaluated with respect to the current row.
|
||||
// If omitted, offset defaults to 1 and default to null
|
||||
var LAG = jet.LAG
|
||||
|
||||
// LEAD returns value evaluated at the row that is offset rows after the current row within the partition;
|
||||
// if there is no such row, instead return default (which must be of the same type as value).
|
||||
// Both offset and default are evaluated with respect to the current row.
|
||||
// If omitted, offset defaults to 1 and default to null
|
||||
var LEAD = jet.LEAD
|
||||
|
||||
// FIRST_VALUE returns value evaluated at the row that is the first row of the window frame
|
||||
var FIRST_VALUE = jet.FIRST_VALUE
|
||||
|
||||
// LAST_VALUE returns value evaluated at the row that is the last row of the window frame
|
||||
var LAST_VALUE = jet.LAST_VALUE
|
||||
|
||||
// NTH_VALUE returns value evaluated at the row that is the nth row of the window frame (counting from 1); null if no such row
|
||||
var NTH_VALUE = jet.NTH_VALUE
|
||||
|
||||
//--------------------- String functions ------------------//
|
||||
|
||||
// BIT_LENGTH returns number of bits in string expression
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package postgres
|
||||
|
||||
import "github.com/go-jet/jet/internal/jet"
|
||||
import (
|
||||
"github.com/go-jet/jet/internal/jet"
|
||||
"math"
|
||||
)
|
||||
|
||||
// RowLock is interface for SELECT statement row lock types
|
||||
type RowLock = jet.RowLock
|
||||
|
|
@ -13,6 +16,27 @@ var (
|
|||
KEY_SHARE = jet.NewRowLock("KEY SHARE")
|
||||
)
|
||||
|
||||
// Window function clauses
|
||||
var (
|
||||
PARTITION_BY = jet.PARTITION_BY
|
||||
ORDER_BY = jet.ORDER_BY
|
||||
UNBOUNDED = int64(math.MaxInt64)
|
||||
CURRENT_ROW = jet.CURRENT_ROW
|
||||
)
|
||||
|
||||
// PRECEDING window frame clause
|
||||
func PRECEDING(offset int64) jet.FrameExtent {
|
||||
return jet.PRECEDING(toJetFrameOffset(offset))
|
||||
}
|
||||
|
||||
// FOLLOWING window frame clause
|
||||
func FOLLOWING(offset int64) jet.FrameExtent {
|
||||
return jet.FOLLOWING(toJetFrameOffset(offset))
|
||||
}
|
||||
|
||||
// Window definition reference
|
||||
var Window = jet.WindowName
|
||||
|
||||
// SelectStatement is interface for PostgreSQL SELECT statement
|
||||
type SelectStatement interface {
|
||||
Statement
|
||||
|
|
@ -24,6 +48,7 @@ type SelectStatement interface {
|
|||
WHERE(expression BoolExpression) SelectStatement
|
||||
GROUP_BY(groupByClauses ...jet.GroupByClause) SelectStatement
|
||||
HAVING(boolExpression BoolExpression) SelectStatement
|
||||
WINDOW(name string) windowExpand
|
||||
ORDER_BY(orderByClauses ...jet.OrderByClause) SelectStatement
|
||||
LIMIT(limit int64) SelectStatement
|
||||
OFFSET(offset int64) SelectStatement
|
||||
|
|
@ -47,15 +72,9 @@ func SELECT(projection Projection, projections ...Projection) SelectStatement {
|
|||
func newSelectStatement(table ReadableTable, projections []Projection) SelectStatement {
|
||||
newSelect := &selectStatementImpl{}
|
||||
newSelect.ExpressionStatement = jet.NewExpressionStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select,
|
||||
&newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.OrderBy,
|
||||
&newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.Window, &newSelect.OrderBy,
|
||||
&newSelect.Limit, &newSelect.Offset, &newSelect.For)
|
||||
|
||||
// statementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select,
|
||||
// &newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.OrderBy,
|
||||
// &newSelect.Limit, &newSelect.Offset, &newSelect.For)
|
||||
//
|
||||
//newSelect.expressionStatementImpl.expressionInterfaceImpl.Parent = newSelect
|
||||
|
||||
newSelect.Select.Projections = toJetProjectionList(projections)
|
||||
newSelect.From.Table = table
|
||||
newSelect.Limit.Count = -1
|
||||
|
|
@ -75,6 +94,7 @@ type selectStatementImpl struct {
|
|||
Where jet.ClauseWhere
|
||||
GroupBy jet.ClauseGroupBy
|
||||
Having jet.ClauseHaving
|
||||
Window jet.ClauseWindow
|
||||
OrderBy jet.ClauseOrderBy
|
||||
Limit jet.ClauseLimit
|
||||
Offset jet.ClauseOffset
|
||||
|
|
@ -106,6 +126,11 @@ func (s *selectStatementImpl) HAVING(boolExpression BoolExpression) SelectStatem
|
|||
return s
|
||||
}
|
||||
|
||||
func (s *selectStatementImpl) WINDOW(name string) windowExpand {
|
||||
s.Window.Definitions = append(s.Window.Definitions, jet.WindowDefinition{Name: name})
|
||||
return windowExpand{selectStatement: s}
|
||||
}
|
||||
|
||||
func (s *selectStatementImpl) ORDER_BY(orderByClauses ...jet.OrderByClause) SelectStatement {
|
||||
s.OrderBy.List = orderByClauses
|
||||
return s
|
||||
|
|
@ -129,3 +154,25 @@ func (s *selectStatementImpl) FOR(lock RowLock) SelectStatement {
|
|||
func (s *selectStatementImpl) AsTable(alias string) SelectTable {
|
||||
return newSelectTable(s, alias)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
||||
type windowExpand struct {
|
||||
selectStatement *selectStatementImpl
|
||||
}
|
||||
|
||||
func (w windowExpand) AS(window ...jet.Window) SelectStatement {
|
||||
if len(window) == 0 {
|
||||
return w.selectStatement
|
||||
}
|
||||
windowsDefinition := w.selectStatement.Window.Definitions
|
||||
windowsDefinition[len(windowsDefinition)-1].Window = window[0]
|
||||
return w.selectStatement
|
||||
}
|
||||
|
||||
func toJetFrameOffset(offset int64) jet.Serializer {
|
||||
if offset == UNBOUNDED {
|
||||
return jet.UNBOUNDED
|
||||
}
|
||||
return jet.FixedLiteral(offset)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue