MySQL cast expressions. Simplified.

This commit is contained in:
go-jet 2019-08-01 10:39:57 +02:00
parent 53dbcd9bfc
commit c342f296ca
10 changed files with 103 additions and 81 deletions

41
cast.go
View file

@ -1,24 +1,32 @@
package jet package jet
type CastType string import "strconv"
type Cast interface { type Cast interface {
As(castType CastType) Expression AS(castType string) Expression
AS_CHAR(lenght ...int) StringExpression
// Cast expression AS date type
AS_DATE() DateExpression
// Cast expression AS numeric type, using precision and optionally scale
AS_DECIMAL() FloatExpression
// Cast expression AS time type
AS_TIME() TimeExpression
} }
type CastImpl struct { type CastImpl struct {
expression Expression expression Expression
} }
func NewCastImpl(expression Expression) Cast { func NewCastImpl(expression Expression) CastImpl {
castImpl := CastImpl{ castImpl := CastImpl{
expression: expression, expression: expression,
} }
return &castImpl return castImpl
} }
func (b *CastImpl) As(castType CastType) Expression { func (b *CastImpl) AS(castType string) Expression {
castExp := &castExpression{ castExp := &castExpression{
expression: b.expression, expression: b.expression,
cast: string(castType), cast: string(castType),
@ -29,6 +37,29 @@ func (b *CastImpl) As(castType CastType) Expression {
return castExp return castExp
} }
func (b *CastImpl) AS_CHAR(lenght ...int) StringExpression {
if len(lenght) > 0 {
return StringExp(b.AS("CHAR(" + strconv.Itoa(lenght[0]) + ")"))
}
return StringExp(b.AS("CHAR"))
}
// Cast expression AS date type
func (b *CastImpl) AS_DATE() DateExpression {
return DateExp(b.AS("DATE"))
}
// Cast expression AS date type
func (b *CastImpl) AS_DECIMAL() FloatExpression {
return FloatExp(b.AS("DECIMAL"))
}
// Cast expression AS date type
func (b *CastImpl) AS_TIME() TimeExpression {
return TimeExp(b.AS("TIME"))
}
type castExpression struct { type castExpression struct {
expressionInterfaceImpl expressionInterfaceImpl

View file

@ -1,9 +1,7 @@
package jet package jet
import "testing" //func TestCastAS(t *testing.T) {
// AssertClauseSerialize(t, NewCastImpl(Int(1)).AS("boolean"), "CAST(? AS boolean)", int64(1))
func TestCastAS(t *testing.T) { // AssertClauseSerialize(t, NewCastImpl(table2Col3).AS("real"), "CAST(table2.col3 AS real)")
AssertClauseSerialize(t, NewCastImpl(Int(1)).As("boolean"), "CAST(? AS boolean)", int64(1)) // AssertClauseSerialize(t, NewCastImpl(table2Col3.ADD(table2Col3)).AS("integer"), "CAST((table2.col3 + table2.col3) AS integer)")
AssertClauseSerialize(t, NewCastImpl(table2Col3).As("real"), "CAST(table2.col3 AS real)") //}
AssertClauseSerialize(t, NewCastImpl(table2Col3.ADD(table2Col3)).As("integer"), "CAST((table2.col3 + table2.col3) AS integer)")
}

View file

@ -5,51 +5,38 @@ import (
) )
type cast interface { type cast interface {
AS_DATE() DateExpression jet.Cast
AS_TIME() TimeExpression
AS_DATETIME() DateTimeExpression AS_DATETIME() DateTimeExpression
AS_CHAR() StringExpression
AS_SIGNED() IntegerExpression AS_SIGNED() IntegerExpression
AS_UNSIGNED() IntegerExpression AS_UNSIGNED() IntegerExpression
AS_BINARY() StringExpression AS_BINARY() StringExpression
} }
type castImpl struct { type castImpl struct {
jet.Cast jet.CastImpl
} }
func CAST(expr jet.Expression) cast { func CAST(expr jet.Expression) cast {
castImpl := &castImpl{} castImpl := &castImpl{}
castImpl.Cast = jet.NewCastImpl(expr) castImpl.CastImpl = jet.NewCastImpl(expr)
return castImpl return castImpl
} }
func (c *castImpl) AS_DATE() DateExpression {
return jet.DateExp(c.As("DATE"))
}
func (c *castImpl) AS_DATETIME() DateTimeExpression { func (c *castImpl) AS_DATETIME() DateTimeExpression {
return jet.TimestampExp(c.As("DATETIME")) return jet.TimestampExp(c.AS("DATETIME"))
}
func (c *castImpl) AS_TIME() TimeExpression {
return jet.TimeExp(c.As("TIME"))
}
func (c *castImpl) AS_CHAR() StringExpression {
return jet.StringExp(c.As("CHAR"))
} }
func (c *castImpl) AS_SIGNED() IntegerExpression { func (c *castImpl) AS_SIGNED() IntegerExpression {
return jet.IntExp(c.As("SIGNED")) return jet.IntExp(c.AS("SIGNED"))
} }
func (c *castImpl) AS_UNSIGNED() IntegerExpression { func (c *castImpl) AS_UNSIGNED() IntegerExpression {
return jet.IntExp(c.As("UNSIGNED")) return jet.IntExp(c.AS("UNSIGNED"))
} }
func (c *castImpl) AS_BINARY() StringExpression { func (c *castImpl) AS_BINARY() StringExpression {
return jet.StringExp(c.As("BINARY")) return jet.StringExp(c.AS("BINARY"))
} }

View file

@ -2,6 +2,8 @@ package mysql
import "github.com/go-jet/jet" import "github.com/go-jet/jet"
type Expression jet.Expression
type ColumnBool jet.ColumnBool type ColumnBool jet.ColumnBool
type BoolExpression jet.BoolExpression type BoolExpression jet.BoolExpression

View file

@ -9,40 +9,40 @@ var dateVar = Date(2000, 12, 30)
func TestDateExpressionEQ(t *testing.T) { func TestDateExpressionEQ(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.EQ(table2ColDate), "(table1.col_date = table2.col_date)") jet.AssertPostgreClauseSerialize(t, table1ColDate.EQ(table2ColDate), "(table1.col_date = table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.EQ(dateVar), "(table1.col_date = $1::date)", "2000-12-30") jet.AssertPostgreClauseSerialize(t, table1ColDate.EQ(dateVar), "(table1.col_date = $1::DATE)", "2000-12-30")
} }
func TestDateExpressionNOT_EQ(t *testing.T) { func TestDateExpressionNOT_EQ(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.NOT_EQ(table2ColDate), "(table1.col_date != table2.col_date)") jet.AssertPostgreClauseSerialize(t, table1ColDate.NOT_EQ(table2ColDate), "(table1.col_date != table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.NOT_EQ(dateVar), "(table1.col_date != $1::date)", "2000-12-30") jet.AssertPostgreClauseSerialize(t, table1ColDate.NOT_EQ(dateVar), "(table1.col_date != $1::DATE)", "2000-12-30")
} }
func TestDateExpressionIS_DISTINCT_FROM(t *testing.T) { func TestDateExpressionIS_DISTINCT_FROM(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_DISTINCT_FROM(table2ColDate), "(table1.col_date IS DISTINCT FROM table2.col_date)") jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_DISTINCT_FROM(table2ColDate), "(table1.col_date IS DISTINCT FROM table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_DISTINCT_FROM(dateVar), "(table1.col_date IS DISTINCT FROM $1::date)", "2000-12-30") jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_DISTINCT_FROM(dateVar), "(table1.col_date IS DISTINCT FROM $1::DATE)", "2000-12-30")
} }
func TestDateExpressionIS_NOT_DISTINCT_FROM(t *testing.T) { func TestDateExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_NOT_DISTINCT_FROM(table2ColDate), "(table1.col_date IS NOT DISTINCT FROM table2.col_date)") jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_NOT_DISTINCT_FROM(table2ColDate), "(table1.col_date IS NOT DISTINCT FROM table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_NOT_DISTINCT_FROM(dateVar), "(table1.col_date IS NOT DISTINCT FROM $1::date)", "2000-12-30") jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_NOT_DISTINCT_FROM(dateVar), "(table1.col_date IS NOT DISTINCT FROM $1::DATE)", "2000-12-30")
} }
func TestDateExpressionGT(t *testing.T) { func TestDateExpressionGT(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.GT(table2ColDate), "(table1.col_date > table2.col_date)") jet.AssertPostgreClauseSerialize(t, table1ColDate.GT(table2ColDate), "(table1.col_date > table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.GT(dateVar), "(table1.col_date > $1::date)", "2000-12-30") jet.AssertPostgreClauseSerialize(t, table1ColDate.GT(dateVar), "(table1.col_date > $1::DATE)", "2000-12-30")
} }
func TestDateExpressionGT_EQ(t *testing.T) { func TestDateExpressionGT_EQ(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.GT_EQ(table2ColDate), "(table1.col_date >= table2.col_date)") jet.AssertPostgreClauseSerialize(t, table1ColDate.GT_EQ(table2ColDate), "(table1.col_date >= table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.GT_EQ(dateVar), "(table1.col_date >= $1::date)", "2000-12-30") jet.AssertPostgreClauseSerialize(t, table1ColDate.GT_EQ(dateVar), "(table1.col_date >= $1::DATE)", "2000-12-30")
} }
func TestDateExpressionLT(t *testing.T) { func TestDateExpressionLT(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.LT(table2ColDate), "(table1.col_date < table2.col_date)") jet.AssertPostgreClauseSerialize(t, table1ColDate.LT(table2ColDate), "(table1.col_date < table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.LT(dateVar), "(table1.col_date < $1::date)", "2000-12-30") jet.AssertPostgreClauseSerialize(t, table1ColDate.LT(dateVar), "(table1.col_date < $1::DATE)", "2000-12-30")
} }
func TestDateExpressionLT_EQ(t *testing.T) { func TestDateExpressionLT_EQ(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.LT_EQ(table2ColDate), "(table1.col_date <= table2.col_date)") jet.AssertPostgreClauseSerialize(t, table1ColDate.LT_EQ(table2ColDate), "(table1.col_date <= table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.LT_EQ(dateVar), "(table1.col_date <= $1::date)", "2000-12-30") jet.AssertPostgreClauseSerialize(t, table1ColDate.LT_EQ(dateVar), "(table1.col_date <= $1::DATE)", "2000-12-30")
} }

View file

@ -6,6 +6,7 @@ import (
) )
type cast interface { type cast interface {
jet.Cast
// Cast expression AS bool type // Cast expression AS bool type
AS_BOOL() BoolExpression AS_BOOL() BoolExpression
// Cast expression AS smallint type // Cast expression AS smallint type
@ -16,18 +17,14 @@ type cast interface {
AS_BIGINT() IntegerExpression AS_BIGINT() IntegerExpression
// Cast expression AS numeric type, using precision and optionally scale // Cast expression AS numeric type, using precision and optionally scale
AS_NUMERIC(precision int, scale ...int) FloatExpression AS_NUMERIC(precision int, scale ...int) FloatExpression
// Cast expression AS numeric type, using precision and optionally scale
AS_DECIMAL() FloatExpression
// Cast expression AS real type // Cast expression AS real type
AS_REAL() FloatExpression AS_REAL() FloatExpression
// Cast expression AS double precision type // Cast expression AS double precision type
AS_DOUBLE() FloatExpression AS_DOUBLE() FloatExpression
// Cast expression AS text type // Cast expression AS text type
AS_TEXT() StringExpression AS_TEXT() StringExpression
// Cast expression AS date type
AS_DATE() DateExpression
// Cast expression AS time type
AS_TIME() TimeExpression
// Cast expression AS time with time timezone type // Cast expression AS time with time timezone type
AS_TIMEZ() TimezExpression AS_TIMEZ() TimezExpression
// Cast expression AS timestamp type // Cast expression AS timestamp type
@ -37,33 +34,33 @@ type cast interface {
} }
type castImpl struct { type castImpl struct {
jet.Cast jet.CastImpl
} }
func CAST(expr jet.Expression) cast { func CAST(expr jet.Expression) cast {
castImpl := &castImpl{} castImpl := &castImpl{}
castImpl.Cast = jet.NewCastImpl(expr) castImpl.CastImpl = jet.NewCastImpl(expr)
return castImpl return castImpl
} }
func (b *castImpl) AS_BOOL() BoolExpression { func (b *castImpl) AS_BOOL() BoolExpression {
return jet.BoolExp(b.As("boolean")) return jet.BoolExp(b.AS("boolean"))
} }
func (b *castImpl) AS_SMALLINT() IntegerExpression { func (b *castImpl) AS_SMALLINT() IntegerExpression {
return jet.IntExp(b.As("smallint")) return jet.IntExp(b.AS("smallint"))
} }
// Cast expression AS integer type // Cast expression AS integer type
func (b *castImpl) AS_INTEGER() IntegerExpression { func (b *castImpl) AS_INTEGER() IntegerExpression {
return jet.IntExp(b.As("integer")) return jet.IntExp(b.AS("integer"))
} }
// Cast expression AS bigint type // Cast expression AS bigint type
func (b *castImpl) AS_BIGINT() IntegerExpression { func (b *castImpl) AS_BIGINT() IntegerExpression {
return jet.IntExp(b.As("bigint")) return jet.IntExp(b.AS("bigint"))
} }
// Cast expression AS numeric type, using precision and optionally scale // Cast expression AS numeric type, using precision and optionally scale
@ -76,49 +73,40 @@ func (b *castImpl) AS_NUMERIC(precision int, scale ...int) FloatExpression {
castType = fmt.Sprintf("numeric(%d)", precision) castType = fmt.Sprintf("numeric(%d)", precision)
} }
return jet.FloatExp(b.As(jet.CastType(castType))) return jet.FloatExp(b.AS(castType))
}
func (b *castImpl) AS_DECIMAL() FloatExpression {
return jet.FloatExp(b.As("decimal"))
} }
// Cast expression AS real type // Cast expression AS real type
func (b *castImpl) AS_REAL() FloatExpression { func (b *castImpl) AS_REAL() FloatExpression {
return jet.FloatExp(b.As("real")) return jet.FloatExp(b.AS("real"))
} }
// Cast expression AS double precision type // Cast expression AS double precision type
func (b *castImpl) AS_DOUBLE() FloatExpression { func (b *castImpl) AS_DOUBLE() FloatExpression {
return jet.FloatExp(b.As("double precision")) return jet.FloatExp(b.AS("double precision"))
} }
// Cast expression AS text type // Cast expression AS text type
func (b *castImpl) AS_TEXT() StringExpression { func (b *castImpl) AS_TEXT() StringExpression {
return jet.StringExp(b.As("text")) return jet.StringExp(b.AS("text"))
} }
// Cast expression AS date type // Cast expression AS date type
func (b *castImpl) AS_DATE() DateExpression { func (b *castImpl) AS_TIME() jet.TimeExpression {
return jet.DateExp(b.As("date")) return TimeExp(b.AS("time without time zone"))
}
// Cast expression AS time type
func (b *castImpl) AS_TIME() TimeExpression {
return jet.TimeExp(b.As("time without time zone"))
} }
// Cast expression AS time with time timezone type // Cast expression AS time with time timezone type
func (b *castImpl) AS_TIMEZ() TimezExpression { func (b *castImpl) AS_TIMEZ() TimezExpression {
return jet.TimezExp(b.As("time with time zone")) return jet.TimezExp(b.AS("time with time zone"))
} }
// Cast expression AS timestamp type // Cast expression AS timestamp type
func (b *castImpl) AS_TIMESTAMP() TimestampExpression { func (b *castImpl) AS_TIMESTAMP() TimestampExpression {
return jet.TimestampExp(b.As("timestamp without time zone")) return jet.TimestampExp(b.AS("timestamp without time zone"))
} }
// Cast expression AS timestamp with timezone type // Cast expression AS timestamp with timezone type
func (b *castImpl) AS_TIMESTAMPZ() TimestampzExpression { func (b *castImpl) AS_TIMESTAMPZ() TimestampzExpression {
return jet.TimestampzExp(b.As("timestamp with time zone")) return jet.TimestampzExp(b.AS("timestamp with time zone"))
} }

View file

@ -5,6 +5,10 @@ import (
"testing" "testing"
) )
func TestExpressionCAST_AS(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(String("test")).AS("text"), `$1::text`, "test")
}
func TestExpressionCAST_AS_BOOL(t *testing.T) { func TestExpressionCAST_AS_BOOL(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(Int(1)).AS_BOOL(), "$1::boolean", int64(1)) jet.AssertPostgreClauseSerialize(t, CAST(Int(1)).AS_BOOL(), "$1::boolean", int64(1))
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_BOOL(), "table2.col3::boolean") jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_BOOL(), "table2.col3::boolean")
@ -41,7 +45,7 @@ func TestExpressionCAST_AS_TEXT(t *testing.T) {
} }
func TestExpressionCAST_AS_DATE(t *testing.T) { func TestExpressionCAST_AS_DATE(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_DATE(), "table2.col3::date") jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_DATE(), "table2.col3::DATE")
} }
func TestExpressionCAST_AS_TIME(t *testing.T) { func TestExpressionCAST_AS_TIME(t *testing.T) {

View file

@ -12,31 +12,40 @@ import (
func TestCast(t *testing.T) { func TestCast(t *testing.T) {
query := SELECT( query := SELECT(
CAST(String("test")).AS("CHAR CHARACTER SET utf8").AS("result.AS1"),
CAST(String("2011-02-02")).AS_DATE().AS("result.date"), CAST(String("2011-02-02")).AS_DATE().AS("result.date"),
CAST(String("14:06:10")).AS_TIME().AS("result.time"), CAST(String("14:06:10")).AS_TIME().AS("result.time"),
CAST(String("2011-02-02 14:06:10")).AS_DATETIME().AS("result.datetime"), CAST(String("2011-02-02 14:06:10")).AS_DATETIME().AS("result.datetime"),
CAST(Int(150)).AS_CHAR().AS("result.char"),
CAST(Int(150)).AS_CHAR().AS("result.char1"),
CAST(Int(150)).AS_CHAR(30).AS("result.char2"),
CAST(Int(5).SUB(Int(10))).AS_SIGNED().AS("result.signed"), CAST(Int(5).SUB(Int(10))).AS_SIGNED().AS("result.signed"),
CAST(Int(5).ADD(Int(10))).AS_UNSIGNED().AS("result.unsigned"), CAST(Int(5).ADD(Int(10))).AS_UNSIGNED().AS("result.unsigned"),
CAST(String("Some text")).AS_BINARY().AS("result.binary"), CAST(String("Some text")).AS_BINARY().AS("result.binary"),
).FROM(AllTypes) ).FROM(AllTypes)
testutils.AssertStatementSql(t, query, ` testutils.AssertStatementSql(t, query, `
SELECT CAST(? AS DATE) AS "result.date", SELECT CAST(? AS CHAR CHARACTER SET utf8) AS "result.AS1",
CAST(? AS DATE) AS "result.date",
CAST(? AS TIME) AS "result.time", CAST(? AS TIME) AS "result.time",
CAST(? AS DATETIME) AS "result.datetime", CAST(? AS DATETIME) AS "result.datetime",
CAST(? AS CHAR) AS "result.char", CAST(? AS CHAR) AS "result.char1",
CAST(? AS CHAR(30)) AS "result.char2",
CAST((? - ?) AS SIGNED) AS "result.signed", CAST((? - ?) AS SIGNED) AS "result.signed",
CAST((? + ?) AS UNSIGNED) AS "result.unsigned", CAST((? + ?) AS UNSIGNED) AS "result.unsigned",
CAST(? AS BINARY) AS "result.binary" CAST(? AS BINARY) AS "result.binary"
FROM test_sample.all_types; FROM test_sample.all_types;
`, "2011-02-02", "14:06:10", "2011-02-02 14:06:10", int64(150), int64(5), int64(10), int64(5), int64(10), "Some text") `, "test", "2011-02-02", "14:06:10", "2011-02-02 14:06:10", int64(150), int64(150), int64(5),
int64(10), int64(5), int64(10), "Some text")
type Result struct { type Result struct {
As1 string
Date time.Time Date time.Time
Time time.Time Time time.Time
DateTime time.Time DateTime time.Time
Char string Char1 string
Char2 string
Signed int Signed int
Unsigned int Unsigned int
Binary string Binary string
@ -49,10 +58,12 @@ FROM test_sample.all_types;
assert.NilError(t, err) assert.NilError(t, err)
assert.DeepEqual(t, dest, Result{ assert.DeepEqual(t, dest, Result{
As1: "test",
Date: *testutils.Date("2011-02-02"), Date: *testutils.Date("2011-02-02"),
Time: *testutils.TimeWithoutTimeZone("14:06:10"), Time: *testutils.TimeWithoutTimeZone("14:06:10"),
DateTime: *testutils.TimestampWithoutTimeZone("2011-02-02 14:06:10", 0), DateTime: *testutils.TimestampWithoutTimeZone("2011-02-02 14:06:10", 0),
Char: "150", Char1: "150",
Char2: "150",
Signed: -5, Signed: -5,
Unsigned: 15, Unsigned: 15,
Binary: "Some text", Binary: "Some text",

View file

@ -65,6 +65,7 @@ func TestExpressionOperators(t *testing.T) {
AllTypes.SmallIntPtr.NOT_IN(Int(11), Int(22), NULL), AllTypes.SmallIntPtr.NOT_IN(Int(11), Int(22), NULL),
AllTypes.SmallIntPtr.NOT_IN(AllTypes.SELECT(AllTypes.IntegerPtr)), AllTypes.SmallIntPtr.NOT_IN(AllTypes.SELECT(AllTypes.IntegerPtr)),
postgres.CAST(Int(150)).AS_CHAR(12),
postgres.CAST(String("TRUE")).AS_BOOL(), postgres.CAST(String("TRUE")).AS_BOOL(),
postgres.CAST(String("111")).AS_SMALLINT(), postgres.CAST(String("111")).AS_SMALLINT(),
postgres.CAST(String("111")).AS_INTEGER(), postgres.CAST(String("111")).AS_INTEGER(),
@ -320,7 +321,7 @@ SELECT (all_types.numeric = all_types.numeric) AS "eq1",
TRUNC(ABS(all_types.decimal), $29) AS "abs", TRUNC(ABS(all_types.decimal), $29) AS "abs",
TRUNC(POWER(all_types.decimal, $30), $31) AS "power", TRUNC(POWER(all_types.decimal, $30), $31) AS "power",
TRUNC(SQRT(all_types.decimal), $32) AS "sqrt", TRUNC(SQRT(all_types.decimal), $32) AS "sqrt",
TRUNC(CBRT(all_types.decimal)::decimal, $33) AS "cbrt", TRUNC(CBRT(all_types.decimal)::DECIMAL, $33) AS "cbrt",
CEIL(all_types.real) AS "ceil", CEIL(all_types.real) AS "ceil",
FLOOR(all_types.real) AS "floor", FLOOR(all_types.real) AS "floor",
ROUND(all_types.decimal) AS "round1", ROUND(all_types.decimal) AS "round1",

View file

@ -27,7 +27,7 @@ func newDialectFinder() *DialectFinder {
} }
} }
func (f *DialectFinder) dialect() Dialect { func (f *DialectFinder) mustGetDialect() Dialect {
if len(f.dialects) == 0 { if len(f.dialects) == 0 {
panic("jet: can't detect dialect") panic("jet: can't detect dialect")
} }
@ -59,5 +59,5 @@ func detectDialect(element acceptsVisitor, dialectOverride ...Dialect) Dialect {
dialectFinder := newDialectFinder() dialectFinder := newDialectFinder()
element.accept(dialectFinder) element.accept(dialectFinder)
return dialectFinder.dialect() return dialectFinder.mustGetDialect()
} }