Add postgres interval cast.
This commit is contained in:
parent
4a3579e7f9
commit
a2fbc4f53a
4 changed files with 56 additions and 20 deletions
|
|
@ -2,8 +2,9 @@ package postgres
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/go-jet/jet/internal/jet"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/go-jet/jet/internal/jet"
|
||||||
)
|
)
|
||||||
|
|
||||||
type cast interface {
|
type cast interface {
|
||||||
|
|
@ -32,7 +33,7 @@ type cast interface {
|
||||||
AS_TIME() TimeExpression
|
AS_TIME() TimeExpression
|
||||||
// Cast expression AS text type
|
// Cast expression AS text type
|
||||||
AS_TEXT() StringExpression
|
AS_TEXT() StringExpression
|
||||||
|
// Cast expression AS bytea type
|
||||||
AS_BYTEA() StringExpression
|
AS_BYTEA() StringExpression
|
||||||
// Cast expression AS time with time timezone type
|
// Cast expression AS time with time timezone type
|
||||||
AS_TIMEZ() TimezExpression
|
AS_TIMEZ() TimezExpression
|
||||||
|
|
@ -40,6 +41,8 @@ type cast interface {
|
||||||
AS_TIMESTAMP() TimestampExpression
|
AS_TIMESTAMP() TimestampExpression
|
||||||
// Cast expression AS timestamp with timezone type
|
// Cast expression AS timestamp with timezone type
|
||||||
AS_TIMESTAMPZ() TimestampzExpression
|
AS_TIMESTAMPZ() TimestampzExpression
|
||||||
|
// Cast expression AS interval type
|
||||||
|
AS_INTERVAL() IntervalExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
type castImpl struct {
|
type castImpl struct {
|
||||||
|
|
@ -151,3 +154,8 @@ func (b *castImpl) AS_TIMESTAMP() TimestampExpression {
|
||||||
func (b *castImpl) AS_TIMESTAMPZ() TimestampzExpression {
|
func (b *castImpl) AS_TIMESTAMPZ() TimestampzExpression {
|
||||||
return TimestampzExp(b.AS("timestamp with time zone"))
|
return TimestampzExp(b.AS("timestamp with time zone"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cast expression AS interval type
|
||||||
|
func (b *castImpl) AS_INTERVAL() IntervalExpression {
|
||||||
|
return IntervalExp(b.AS("interval"))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,3 +62,10 @@ func TestExpressionCAST_AS_TIMESTAMP(t *testing.T) {
|
||||||
func TestExpressionCAST_AS_TIMESTAMPZ(t *testing.T) {
|
func TestExpressionCAST_AS_TIMESTAMPZ(t *testing.T) {
|
||||||
assertSerialize(t, CAST(table2Col3).AS_TIMESTAMPZ(), "table2.col3::timestamp with time zone")
|
assertSerialize(t, CAST(table2Col3).AS_TIMESTAMPZ(), "table2.col3::timestamp with time zone")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExpressionCAST_AS_INTERVAL(t *testing.T) {
|
||||||
|
assertSerialize(t, CAST(table2ColTimez).AS_INTERVAL(), "table2.col_timez::interval")
|
||||||
|
assertSerialize(t, CAST(Time(20, 11, 10)).AS_INTERVAL(), "$1::time without time zone::interval", "20:11:10")
|
||||||
|
assertSerialize(t, table2ColDate.SUB(CAST(Time(20, 11, 10)).AS_INTERVAL()),
|
||||||
|
"(table2.col_date - $1::time without time zone::interval)", "20:11:10")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,3 +129,22 @@ func unitToString(unit quantityAndUnit) string {
|
||||||
panic("jet: invalid INTERVAL unit type")
|
panic("jet: invalid INTERVAL unit type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------//
|
||||||
|
|
||||||
|
type intervalWrapper struct {
|
||||||
|
jet.IsInterval
|
||||||
|
Expression
|
||||||
|
}
|
||||||
|
|
||||||
|
func newIntervalExpressionWrap(expression Expression) IntervalExpression {
|
||||||
|
intervalWrap := intervalWrapper{Expression: expression}
|
||||||
|
return &intervalWrap
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntervalExp is interval expression wrapper around arbitrary expression.
|
||||||
|
// Allows go compiler to see any expression as interval expression.
|
||||||
|
// Does not add sql cast to generated sql builder output.
|
||||||
|
func IntervalExp(expression Expression) IntervalExpression {
|
||||||
|
return newIntervalExpressionWrap(expression)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
|
|
||||||
"github.com/go-jet/jet/internal/testutils"
|
"github.com/go-jet/jet/internal/testutils"
|
||||||
"github.com/go-jet/jet/postgres"
|
|
||||||
. "github.com/go-jet/jet/postgres"
|
. "github.com/go-jet/jet/postgres"
|
||||||
"github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/model"
|
"github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/model"
|
||||||
. "github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/table"
|
. "github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/table"
|
||||||
|
|
@ -136,22 +135,23 @@ LIMIT $5;
|
||||||
func TestExpressionCast(t *testing.T) {
|
func TestExpressionCast(t *testing.T) {
|
||||||
|
|
||||||
query := AllTypes.SELECT(
|
query := AllTypes.SELECT(
|
||||||
postgres.CAST(Int(150)).AS_CHAR(12).AS("char12"),
|
CAST(Int(150)).AS_CHAR(12).AS("char12"),
|
||||||
postgres.CAST(String("TRUE")).AS_BOOL(),
|
CAST(String("TRUE")).AS_BOOL(),
|
||||||
postgres.CAST(String("111")).AS_SMALLINT(),
|
CAST(String("111")).AS_SMALLINT(),
|
||||||
postgres.CAST(String("111")).AS_INTEGER(),
|
CAST(String("111")).AS_INTEGER(),
|
||||||
postgres.CAST(String("111")).AS_BIGINT(),
|
CAST(String("111")).AS_BIGINT(),
|
||||||
postgres.CAST(String("11.23")).AS_NUMERIC(30, 10),
|
CAST(String("11.23")).AS_NUMERIC(30, 10),
|
||||||
postgres.CAST(String("11.23")).AS_NUMERIC(30),
|
CAST(String("11.23")).AS_NUMERIC(30),
|
||||||
postgres.CAST(String("11.23")).AS_NUMERIC(),
|
CAST(String("11.23")).AS_NUMERIC(),
|
||||||
postgres.CAST(String("11.23")).AS_REAL(),
|
CAST(String("11.23")).AS_REAL(),
|
||||||
postgres.CAST(String("11.23")).AS_DOUBLE(),
|
CAST(String("11.23")).AS_DOUBLE(),
|
||||||
postgres.CAST(Int(234)).AS_TEXT(),
|
CAST(Int(234)).AS_TEXT(),
|
||||||
postgres.CAST(String("1/8/1999")).AS_DATE(),
|
CAST(String("1/8/1999")).AS_DATE(),
|
||||||
postgres.CAST(String("04:05:06.789")).AS_TIME(),
|
CAST(String("04:05:06.789")).AS_TIME(),
|
||||||
postgres.CAST(String("04:05:06 PST")).AS_TIMEZ(),
|
CAST(String("04:05:06 PST")).AS_TIMEZ(),
|
||||||
postgres.CAST(String("1999-01-08 04:05:06")).AS_TIMESTAMP(),
|
CAST(String("1999-01-08 04:05:06")).AS_TIMESTAMP(),
|
||||||
postgres.CAST(String("January 8 04:05:06 1999 PST")).AS_TIMESTAMPZ(),
|
CAST(String("January 8 04:05:06 1999 PST")).AS_TIMESTAMPZ(),
|
||||||
|
CAST(String("04:05:06")).AS_INTERVAL(),
|
||||||
|
|
||||||
TO_CHAR(AllTypes.Timestamp, String("HH12:MI:SS")),
|
TO_CHAR(AllTypes.Timestamp, String("HH12:MI:SS")),
|
||||||
TO_CHAR(AllTypes.Integer, String("999")),
|
TO_CHAR(AllTypes.Integer, String("999")),
|
||||||
|
|
@ -361,7 +361,7 @@ func TestFloatOperators(t *testing.T) {
|
||||||
TRUNC(ABSf(AllTypes.Decimal), Int(2)).AS("abs"),
|
TRUNC(ABSf(AllTypes.Decimal), Int(2)).AS("abs"),
|
||||||
TRUNC(POWER(AllTypes.Decimal, Float(2.1)), Int(2)).AS("power"),
|
TRUNC(POWER(AllTypes.Decimal, Float(2.1)), Int(2)).AS("power"),
|
||||||
TRUNC(SQRT(AllTypes.Decimal), Int(2)).AS("sqrt"),
|
TRUNC(SQRT(AllTypes.Decimal), Int(2)).AS("sqrt"),
|
||||||
TRUNC(postgres.CAST(CBRT(AllTypes.Decimal)).AS_DECIMAL(), Int(2)).AS("cbrt"),
|
TRUNC(CAST(CBRT(AllTypes.Decimal)).AS_DECIMAL(), Int(2)).AS("cbrt"),
|
||||||
|
|
||||||
CEIL(AllTypes.Real).AS("ceil"),
|
CEIL(AllTypes.Real).AS("ceil"),
|
||||||
FLOOR(AllTypes.Real).AS("floor"),
|
FLOOR(AllTypes.Real).AS("floor"),
|
||||||
|
|
@ -619,6 +619,8 @@ func TestTimeExpression(t *testing.T) {
|
||||||
AllTypes.Timestampz.ADD(INTERVAL(1, HOUR)),
|
AllTypes.Timestampz.ADD(INTERVAL(1, HOUR)),
|
||||||
AllTypes.Timestampz.SUB(INTERVAL(1, MINUTE)),
|
AllTypes.Timestampz.SUB(INTERVAL(1, MINUTE)),
|
||||||
|
|
||||||
|
AllTypes.Date.SUB(CAST(String("04:05:06")).AS_INTERVAL()),
|
||||||
|
|
||||||
CURRENT_DATE(),
|
CURRENT_DATE(),
|
||||||
CURRENT_TIME(),
|
CURRENT_TIME(),
|
||||||
CURRENT_TIME(2),
|
CURRENT_TIME(2),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue