Add support for PostgreSQL interval column

This commit is contained in:
go-jet 2020-02-09 18:37:48 +01:00
parent 641c62098c
commit 3013dc3647
30 changed files with 1038 additions and 255 deletions

View file

@ -13,8 +13,7 @@ func newAlias(expression Expression, aliasName string) Projection {
}
func (a *alias) fromImpl(subQuery SelectTable) Projection {
column := newColumn(a.alias, "", nil)
column.Parent = &column
column := NewColumnImpl(a.alias, "", nil)
column.subQuery = subQuery
return &column

View file

@ -37,19 +37,19 @@ type boolInterfaceImpl struct {
}
func (b *boolInterfaceImpl) EQ(expression BoolExpression) BoolExpression {
return eq(b.parent, expression)
return Eq(b.parent, expression)
}
func (b *boolInterfaceImpl) NOT_EQ(expression BoolExpression) BoolExpression {
return notEq(b.parent, expression)
return NotEq(b.parent, expression)
}
func (b *boolInterfaceImpl) IS_DISTINCT_FROM(rhs BoolExpression) BoolExpression {
return isDistinctFrom(b.parent, rhs)
return IsDistinctFrom(b.parent, rhs)
}
func (b *boolInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs BoolExpression) BoolExpression {
return isNotDistinctFrom(b.parent, rhs)
return IsNotDistinctFrom(b.parent, rhs)
}
func (b *boolInterfaceImpl) AND(expression BoolExpression) BoolExpression {
@ -86,7 +86,7 @@ func (b *boolInterfaceImpl) IS_NOT_UNKNOWN() BoolExpression {
//---------------------------------------------------//
func newBinaryBoolOperatorExpression(lhs, rhs Expression, operator string, additionalParams ...Expression) BoolExpression {
return BoolExp(newBinaryOperatorExpression(lhs, rhs, operator, additionalParams...))
return BoolExp(NewBinaryOperatorExpression(lhs, rhs, operator, additionalParams...))
}
//---------------------------------------------------//

View file

@ -18,8 +18,8 @@ type ColumnExpression interface {
Expression
}
// The base type for real materialized columns.
type columnImpl struct {
// ColumnExpressionImpl is base type for sql columns.
type ColumnExpressionImpl struct {
ExpressionInterfaceImpl
name string
@ -28,34 +28,41 @@ type columnImpl struct {
subQuery SelectTable
}
func newColumn(name string, tableName string, parent ColumnExpression) columnImpl {
bc := columnImpl{
// NewColumnImpl creates new ColumnExpressionImpl
func NewColumnImpl(name string, tableName string, parent ColumnExpression) ColumnExpressionImpl {
bc := ColumnExpressionImpl{
name: name,
tableName: tableName,
}
bc.ExpressionInterfaceImpl.Parent = parent
if parent != nil {
bc.ExpressionInterfaceImpl.Parent = parent
} else {
bc.ExpressionInterfaceImpl.Parent = &bc
}
return bc
}
func (c *columnImpl) Name() string {
// Name returns name of the column
func (c *ColumnExpressionImpl) Name() string {
return c.name
}
func (c *columnImpl) TableName() string {
// TableName returns column table name
func (c *ColumnExpressionImpl) TableName() string {
return c.tableName
}
func (c *columnImpl) setTableName(table string) {
func (c *ColumnExpressionImpl) setTableName(table string) {
c.tableName = table
}
func (c *columnImpl) setSubQuery(subQuery SelectTable) {
func (c *ColumnExpressionImpl) setSubQuery(subQuery SelectTable) {
c.subQuery = subQuery
}
func (c *columnImpl) defaultAlias() string {
func (c *ColumnExpressionImpl) defaultAlias() string {
if c.tableName != "" {
return c.tableName + "." + c.name
}
@ -63,25 +70,31 @@ func (c *columnImpl) defaultAlias() string {
return c.name
}
func (c *columnImpl) serializeForOrderBy(statement StatementType, out *SQLBuilder) {
func (c *ColumnExpressionImpl) fromImpl(subQuery SelectTable) Projection {
newColumn := NewColumnImpl(c.name, c.tableName, nil)
newColumn.setSubQuery(subQuery)
return &newColumn
}
func (c *ColumnExpressionImpl) serializeForOrderBy(statement StatementType, out *SQLBuilder) {
if statement == SetStatementType {
// set Statement (UNION, EXCEPT ...) can reference only select projections in order by clause
out.WriteAlias(c.defaultAlias()) //always quote
return
}
c.serialize(statement, out)
}
func (c columnImpl) serializeForProjection(statement StatementType, out *SQLBuilder) {
func (c ColumnExpressionImpl) serializeForProjection(statement StatementType, out *SQLBuilder) {
c.serialize(statement, out)
out.WriteString("AS")
out.WriteAlias(c.defaultAlias())
}
func (c columnImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
func (c ColumnExpressionImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
if c.subQuery != nil {
out.WriteIdentifier(c.subQuery.Alias())
@ -128,3 +141,13 @@ func (cl ColumnList) TableName() string { return "" }
func (cl ColumnList) setTableName(name string) {}
func (cl ColumnList) setSubQuery(subQuery SelectTable) {}
func (cl ColumnList) defaultAlias() string { return "" }
// SetTableName is utility function to set table name from outside of jet package to avoid making public setTableName
func SetTableName(columnExpression ColumnExpression, tableName string) {
columnExpression.setTableName(tableName)
}
// SetSubQuery is utility function to set table name from outside of jet package to avoid making public setSubQuery
func SetSubQuery(columnExpression ColumnExpression, subQuery SelectTable) {
columnExpression.setSubQuery(subQuery)
}

View file

@ -3,7 +3,7 @@ package jet
import "testing"
func TestColumn(t *testing.T) {
column := newColumn("col", "", nil)
column := NewColumnImpl("col", "", nil)
column.ExpressionInterfaceImpl.Parent = &column
assertClauseSerialize(t, column, "col")

View file

@ -10,11 +10,10 @@ type ColumnBool interface {
type boolColumnImpl struct {
boolInterfaceImpl
columnImpl
ColumnExpressionImpl
}
func (i *boolColumnImpl) fromImpl(subQuery SelectTable) Projection {
func (i *boolColumnImpl) From(subQuery SelectTable) ColumnBool {
newBoolColumn := BoolColumn(i.name)
newBoolColumn.setTableName(i.tableName)
newBoolColumn.setSubQuery(subQuery)
@ -22,16 +21,10 @@ func (i *boolColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newBoolColumn
}
func (i *boolColumnImpl) From(subQuery SelectTable) ColumnBool {
newBoolColumn := i.fromImpl(subQuery).(ColumnBool)
return newBoolColumn
}
// BoolColumn creates named bool column.
func BoolColumn(name string) ColumnBool {
boolColumn := &boolColumnImpl{}
boolColumn.columnImpl = newColumn(name, "", boolColumn)
boolColumn.ColumnExpressionImpl = NewColumnImpl(name, "", boolColumn)
boolColumn.boolInterfaceImpl.parent = boolColumn
return boolColumn
@ -49,19 +42,13 @@ type ColumnFloat interface {
type floatColumnImpl struct {
floatInterfaceImpl
columnImpl
}
func (i *floatColumnImpl) fromImpl(subQuery SelectTable) Projection {
newFloatColumn := FloatColumn(i.name)
newFloatColumn.setTableName(i.tableName)
newFloatColumn.setSubQuery(subQuery)
return newFloatColumn
ColumnExpressionImpl
}
func (i *floatColumnImpl) From(subQuery SelectTable) ColumnFloat {
newFloatColumn := i.fromImpl(subQuery).(ColumnFloat)
newFloatColumn := FloatColumn(i.name)
newFloatColumn.setTableName(i.tableName)
newFloatColumn.setSubQuery(subQuery)
return newFloatColumn
}
@ -70,7 +57,7 @@ func (i *floatColumnImpl) From(subQuery SelectTable) ColumnFloat {
func FloatColumn(name string) ColumnFloat {
floatColumn := &floatColumnImpl{}
floatColumn.floatInterfaceImpl.parent = floatColumn
floatColumn.columnImpl = newColumn(name, "", floatColumn)
floatColumn.ColumnExpressionImpl = NewColumnImpl(name, "", floatColumn)
return floatColumn
}
@ -88,10 +75,10 @@ type ColumnInteger interface {
type integerColumnImpl struct {
integerInterfaceImpl
columnImpl
ColumnExpressionImpl
}
func (i *integerColumnImpl) fromImpl(subQuery SelectTable) Projection {
func (i *integerColumnImpl) From(subQuery SelectTable) ColumnInteger {
newIntColumn := IntegerColumn(i.name)
newIntColumn.setTableName(i.tableName)
newIntColumn.setSubQuery(subQuery)
@ -99,15 +86,11 @@ func (i *integerColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newIntColumn
}
func (i *integerColumnImpl) From(subQuery SelectTable) ColumnInteger {
return i.fromImpl(subQuery).(ColumnInteger)
}
// IntegerColumn creates named integer column.
func IntegerColumn(name string) ColumnInteger {
integerColumn := &integerColumnImpl{}
integerColumn.integerInterfaceImpl.parent = integerColumn
integerColumn.columnImpl = newColumn(name, "", integerColumn)
integerColumn.ColumnExpressionImpl = NewColumnImpl(name, "", integerColumn)
return integerColumn
}
@ -126,10 +109,10 @@ type ColumnString interface {
type stringColumnImpl struct {
stringInterfaceImpl
columnImpl
ColumnExpressionImpl
}
func (i *stringColumnImpl) fromImpl(subQuery SelectTable) Projection {
func (i *stringColumnImpl) From(subQuery SelectTable) ColumnString {
newStrColumn := StringColumn(i.name)
newStrColumn.setTableName(i.tableName)
newStrColumn.setSubQuery(subQuery)
@ -137,15 +120,11 @@ func (i *stringColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newStrColumn
}
func (i *stringColumnImpl) From(subQuery SelectTable) ColumnString {
return i.fromImpl(subQuery).(ColumnString)
}
// StringColumn creates named string column.
func StringColumn(name string) ColumnString {
stringColumn := &stringColumnImpl{}
stringColumn.stringInterfaceImpl.parent = stringColumn
stringColumn.columnImpl = newColumn(name, "", stringColumn)
stringColumn.ColumnExpressionImpl = NewColumnImpl(name, "", stringColumn)
return stringColumn
}
@ -162,10 +141,10 @@ type ColumnTime interface {
type timeColumnImpl struct {
timeInterfaceImpl
columnImpl
ColumnExpressionImpl
}
func (i *timeColumnImpl) fromImpl(subQuery SelectTable) Projection {
func (i *timeColumnImpl) From(subQuery SelectTable) ColumnTime {
newTimeColumn := TimeColumn(i.name)
newTimeColumn.setTableName(i.tableName)
newTimeColumn.setSubQuery(subQuery)
@ -173,15 +152,11 @@ func (i *timeColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newTimeColumn
}
func (i *timeColumnImpl) From(subQuery SelectTable) ColumnTime {
return i.fromImpl(subQuery).(ColumnTime)
}
// TimeColumn creates named time column
func TimeColumn(name string) ColumnTime {
timeColumn := &timeColumnImpl{}
timeColumn.timeInterfaceImpl.parent = timeColumn
timeColumn.columnImpl = newColumn(name, "", timeColumn)
timeColumn.ColumnExpressionImpl = NewColumnImpl(name, "", timeColumn)
return timeColumn
}
@ -197,11 +172,10 @@ type ColumnTimez interface {
type timezColumnImpl struct {
timezInterfaceImpl
columnImpl
ColumnExpressionImpl
}
func (i *timezColumnImpl) fromImpl(subQuery SelectTable) Projection {
func (i *timezColumnImpl) From(subQuery SelectTable) ColumnTimez {
newTimezColumn := TimezColumn(i.name)
newTimezColumn.setTableName(i.tableName)
newTimezColumn.setSubQuery(subQuery)
@ -209,15 +183,11 @@ func (i *timezColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newTimezColumn
}
func (i *timezColumnImpl) From(subQuery SelectTable) ColumnTimez {
return i.fromImpl(subQuery).(ColumnTimez)
}
// TimezColumn creates named time with time zone column.
func TimezColumn(name string) ColumnTimez {
timezColumn := &timezColumnImpl{}
timezColumn.timezInterfaceImpl.parent = timezColumn
timezColumn.columnImpl = newColumn(name, "", timezColumn)
timezColumn.ColumnExpressionImpl = NewColumnImpl(name, "", timezColumn)
return timezColumn
}
@ -234,11 +204,10 @@ type ColumnTimestamp interface {
type timestampColumnImpl struct {
timestampInterfaceImpl
columnImpl
ColumnExpressionImpl
}
func (i *timestampColumnImpl) fromImpl(subQuery SelectTable) Projection {
func (i *timestampColumnImpl) From(subQuery SelectTable) ColumnTimestamp {
newTimestampColumn := TimestampColumn(i.name)
newTimestampColumn.setTableName(i.tableName)
newTimestampColumn.setSubQuery(subQuery)
@ -246,15 +215,11 @@ func (i *timestampColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newTimestampColumn
}
func (i *timestampColumnImpl) From(subQuery SelectTable) ColumnTimestamp {
return i.fromImpl(subQuery).(ColumnTimestamp)
}
// TimestampColumn creates named timestamp column
func TimestampColumn(name string) ColumnTimestamp {
timestampColumn := &timestampColumnImpl{}
timestampColumn.timestampInterfaceImpl.parent = timestampColumn
timestampColumn.columnImpl = newColumn(name, "", timestampColumn)
timestampColumn.ColumnExpressionImpl = NewColumnImpl(name, "", timestampColumn)
return timestampColumn
}
@ -271,11 +236,10 @@ type ColumnTimestampz interface {
type timestampzColumnImpl struct {
timestampzInterfaceImpl
columnImpl
ColumnExpressionImpl
}
func (i *timestampzColumnImpl) fromImpl(subQuery SelectTable) Projection {
func (i *timestampzColumnImpl) From(subQuery SelectTable) ColumnTimestampz {
newTimestampzColumn := TimestampzColumn(i.name)
newTimestampzColumn.setTableName(i.tableName)
newTimestampzColumn.setSubQuery(subQuery)
@ -283,15 +247,11 @@ func (i *timestampzColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newTimestampzColumn
}
func (i *timestampzColumnImpl) From(subQuery SelectTable) ColumnTimestampz {
return i.fromImpl(subQuery).(ColumnTimestampz)
}
// TimestampzColumn creates named timestamp with time zone column.
func TimestampzColumn(name string) ColumnTimestampz {
timestampzColumn := &timestampzColumnImpl{}
timestampzColumn.timestampzInterfaceImpl.parent = timestampzColumn
timestampzColumn.columnImpl = newColumn(name, "", timestampzColumn)
timestampzColumn.ColumnExpressionImpl = NewColumnImpl(name, "", timestampzColumn)
return timestampzColumn
}
@ -308,11 +268,10 @@ type ColumnDate interface {
type dateColumnImpl struct {
dateInterfaceImpl
columnImpl
ColumnExpressionImpl
}
func (i *dateColumnImpl) fromImpl(subQuery SelectTable) Projection {
func (i *dateColumnImpl) From(subQuery SelectTable) ColumnDate {
newDateColumn := DateColumn(i.name)
newDateColumn.setTableName(i.tableName)
newDateColumn.setSubQuery(subQuery)
@ -320,14 +279,10 @@ func (i *dateColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newDateColumn
}
func (i *dateColumnImpl) From(subQuery SelectTable) ColumnDate {
return i.fromImpl(subQuery).(ColumnDate)
}
// DateColumn creates named date column.
func DateColumn(name string) ColumnDate {
dateColumn := &dateColumnImpl{}
dateColumn.dateInterfaceImpl.parent = dateColumn
dateColumn.columnImpl = newColumn(name, "", dateColumn)
dateColumn.ColumnExpressionImpl = NewColumnImpl(name, "", dateColumn)
return dateColumn
}

View file

@ -43,5 +43,74 @@ func TestNewFloatColumnColumn(t *testing.T) {
assertClauseSerialize(t, floatColumn2, `sub_query."table1.col_float"`)
assertClauseSerialize(t, floatColumn2.EQ(Float(2.22)), `(sub_query."table1.col_float" = $1)`, float64(2.22))
assertProjectionSerialize(t, floatColumn2, `sub_query."table1.col_float" AS "table1.col_float"`)
}
func TestNewDateColumnColumn(t *testing.T) {
dateColumn := DateColumn("col_date").From(subQuery)
assertClauseSerialize(t, dateColumn, `sub_query."col_date"`)
assertClauseSerialize(t, dateColumn.EQ(Date(2002, 2, 3)),
`(sub_query."col_date" = $1)`, "2002-02-03")
assertProjectionSerialize(t, dateColumn, `sub_query."col_date" AS "col_date"`)
dateColumn2 := table1ColDate.From(subQuery)
assertClauseSerialize(t, dateColumn2, `sub_query."table1.col_date"`)
assertClauseSerialize(t, dateColumn2.EQ(Date(2002, 2, 3)),
`(sub_query."table1.col_date" = $1)`, "2002-02-03")
assertProjectionSerialize(t, dateColumn2, `sub_query."table1.col_date" AS "table1.col_date"`)
}
func TestNewTimeColumnColumn(t *testing.T) {
timeColumn := TimeColumn("col_time").From(subQuery)
assertClauseSerialize(t, timeColumn, `sub_query."col_time"`)
assertClauseSerialize(t, timeColumn.EQ(Time(1, 1, 1, 1)),
`(sub_query."col_time" = $1)`, "01:01:01.000000001")
assertProjectionSerialize(t, timeColumn, `sub_query."col_time" AS "col_time"`)
timeColumn2 := table1ColTime.From(subQuery)
assertClauseSerialize(t, timeColumn2, `sub_query."table1.col_time"`)
assertClauseSerialize(t, timeColumn2.EQ(Time(2, 2, 2)),
`(sub_query."table1.col_time" = $1)`, "02:02:02")
assertProjectionSerialize(t, timeColumn2, `sub_query."table1.col_time" AS "table1.col_time"`)
}
func TestNewTimezColumnColumn(t *testing.T) {
timezColumn := TimezColumn("col_timez").From(subQuery)
assertClauseSerialize(t, timezColumn, `sub_query."col_timez"`)
assertClauseSerialize(t, timezColumn.EQ(Timez(1, 1, 1, 1, "UTC")),
`(sub_query."col_timez" = $1)`, "01:01:01.000000001 UTC")
assertProjectionSerialize(t, timezColumn, `sub_query."col_timez" AS "col_timez"`)
timezColumn2 := table1ColTimez.From(subQuery)
assertClauseSerialize(t, timezColumn2, `sub_query."table1.col_timez"`)
assertClauseSerialize(t, timezColumn2.EQ(Timez(2, 2, 2, 0, "UTC")),
`(sub_query."table1.col_timez" = $1)`, "02:02:02 UTC")
assertProjectionSerialize(t, timezColumn2, `sub_query."table1.col_timez" AS "table1.col_timez"`)
}
func TestNewTimestampColumnColumn(t *testing.T) {
timestampColumn := TimestampColumn("col_timestamp").From(subQuery)
assertClauseSerialize(t, timestampColumn, `sub_query."col_timestamp"`)
assertClauseSerialize(t, timestampColumn.EQ(Timestamp(1, 1, 1, 1, 1, 1)),
`(sub_query."col_timestamp" = $1)`, "0001-01-01 01:01:01")
assertProjectionSerialize(t, timestampColumn, `sub_query."col_timestamp" AS "col_timestamp"`)
timestampColumn2 := table1ColTimestamp.From(subQuery)
assertClauseSerialize(t, timestampColumn2, `sub_query."table1.col_timestamp"`)
assertClauseSerialize(t, timestampColumn2.EQ(Timestamp(2, 2, 2, 2, 2, 2)),
`(sub_query."table1.col_timestamp" = $1)`, "0002-02-02 02:02:02")
assertProjectionSerialize(t, timestampColumn2, `sub_query."table1.col_timestamp" AS "table1.col_timestamp"`)
}
func TestNewTimestampzColumnColumn(t *testing.T) {
timestampzColumn := TimestampzColumn("col_timestampz").From(subQuery)
assertClauseSerialize(t, timestampzColumn, `sub_query."col_timestampz"`)
assertClauseSerialize(t, timestampzColumn.EQ(Timestampz(1, 1, 1, 1, 1, 1, 0, "UTC")),
`(sub_query."col_timestampz" = $1)`, "0001-01-01 01:01:01 UTC")
assertProjectionSerialize(t, timestampzColumn, `sub_query."col_timestampz" AS "col_timestampz"`)
timestampzColumn2 := table1ColTimestampz.From(subQuery)
assertClauseSerialize(t, timestampzColumn2, `sub_query."table1.col_timestampz"`)
assertClauseSerialize(t, timestampzColumn2.EQ(Timestampz(2, 2, 2, 2, 2, 2, 0, "UTC")),
`(sub_query."table1.col_timestampz" = $1)`, "0002-02-02 02:02:02 UTC")
assertProjectionSerialize(t, timestampzColumn2, `sub_query."table1.col_timestampz" AS "table1.col_timestampz"`)
}

View file

@ -23,43 +23,43 @@ type dateInterfaceImpl struct {
}
func (d *dateInterfaceImpl) EQ(rhs DateExpression) BoolExpression {
return eq(d.parent, rhs)
return Eq(d.parent, rhs)
}
func (d *dateInterfaceImpl) NOT_EQ(rhs DateExpression) BoolExpression {
return notEq(d.parent, rhs)
return NotEq(d.parent, rhs)
}
func (d *dateInterfaceImpl) IS_DISTINCT_FROM(rhs DateExpression) BoolExpression {
return isDistinctFrom(d.parent, rhs)
return IsDistinctFrom(d.parent, rhs)
}
func (d *dateInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs DateExpression) BoolExpression {
return isNotDistinctFrom(d.parent, rhs)
return IsNotDistinctFrom(d.parent, rhs)
}
func (d *dateInterfaceImpl) LT(rhs DateExpression) BoolExpression {
return lt(d.parent, rhs)
return Lt(d.parent, rhs)
}
func (d *dateInterfaceImpl) LT_EQ(rhs DateExpression) BoolExpression {
return ltEq(d.parent, rhs)
return LtEq(d.parent, rhs)
}
func (d *dateInterfaceImpl) GT(rhs DateExpression) BoolExpression {
return gt(d.parent, rhs)
return Gt(d.parent, rhs)
}
func (d *dateInterfaceImpl) GT_EQ(rhs DateExpression) BoolExpression {
return gtEq(d.parent, rhs)
return GtEq(d.parent, rhs)
}
func (d *dateInterfaceImpl) ADD(rhs Interval) TimestampExpression {
return TimestampExp(newBinaryOperatorExpression(d.parent, rhs, "+"))
return TimestampExp(Add(d.parent, rhs))
}
func (d *dateInterfaceImpl) SUB(rhs Interval) TimestampExpression {
return TimestampExp(newBinaryOperatorExpression(d.parent, rhs, "-"))
return TimestampExp(Sub(d.parent, rhs))
}
//---------------------------------------------------//

View file

@ -92,7 +92,8 @@ type binaryOperatorExpression struct {
operator string
}
func newBinaryOperatorExpression(lhs, rhs Serializer, operator string, additionalParam ...Expression) *binaryOperatorExpression {
// NewBinaryOperatorExpression creates new binaryOperatorExpression
func NewBinaryOperatorExpression(lhs, rhs Serializer, operator string, additionalParam ...Expression) *binaryOperatorExpression {
binaryExpression := &binaryOperatorExpression{
lhs: lhs,
rhs: rhs,

View file

@ -29,64 +29,59 @@ type floatInterfaceImpl struct {
}
func (n *floatInterfaceImpl) EQ(rhs FloatExpression) BoolExpression {
return eq(n.parent, rhs)
return Eq(n.parent, rhs)
}
func (n *floatInterfaceImpl) NOT_EQ(rhs FloatExpression) BoolExpression {
return notEq(n.parent, rhs)
return NotEq(n.parent, rhs)
}
func (n *floatInterfaceImpl) IS_DISTINCT_FROM(rhs FloatExpression) BoolExpression {
return isDistinctFrom(n.parent, rhs)
return IsDistinctFrom(n.parent, rhs)
}
func (n *floatInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs FloatExpression) BoolExpression {
return isNotDistinctFrom(n.parent, rhs)
return IsNotDistinctFrom(n.parent, rhs)
}
func (n *floatInterfaceImpl) GT(rhs FloatExpression) BoolExpression {
return gt(n.parent, rhs)
return Gt(n.parent, rhs)
}
func (n *floatInterfaceImpl) GT_EQ(rhs FloatExpression) BoolExpression {
return gtEq(n.parent, rhs)
return GtEq(n.parent, rhs)
}
func (n *floatInterfaceImpl) LT(expression FloatExpression) BoolExpression {
return lt(n.parent, expression)
func (n *floatInterfaceImpl) LT(rhs FloatExpression) BoolExpression {
return Lt(n.parent, rhs)
}
func (n *floatInterfaceImpl) LT_EQ(expression FloatExpression) BoolExpression {
return ltEq(n.parent, expression)
func (n *floatInterfaceImpl) LT_EQ(rhs FloatExpression) BoolExpression {
return LtEq(n.parent, rhs)
}
func (n *floatInterfaceImpl) ADD(expression NumericExpression) FloatExpression {
return newBinaryFloatExpression(n.parent, expression, "+")
func (n *floatInterfaceImpl) ADD(rhs NumericExpression) FloatExpression {
return FloatExp(Add(n.parent, rhs))
}
func (n *floatInterfaceImpl) SUB(expression NumericExpression) FloatExpression {
return newBinaryFloatExpression(n.parent, expression, "-")
func (n *floatInterfaceImpl) SUB(rhs NumericExpression) FloatExpression {
return FloatExp(Sub(n.parent, rhs))
}
func (n *floatInterfaceImpl) MUL(expression NumericExpression) FloatExpression {
return newBinaryFloatExpression(n.parent, expression, "*")
func (n *floatInterfaceImpl) MUL(rhs NumericExpression) FloatExpression {
return FloatExp(Mul(n.parent, rhs))
}
func (n *floatInterfaceImpl) DIV(expression NumericExpression) FloatExpression {
return newBinaryFloatExpression(n.parent, expression, "/")
func (n *floatInterfaceImpl) DIV(rhs NumericExpression) FloatExpression {
return FloatExp(Div(n.parent, rhs))
}
func (n *floatInterfaceImpl) MOD(expression NumericExpression) FloatExpression {
return newBinaryFloatExpression(n.parent, expression, "%")
func (n *floatInterfaceImpl) MOD(rhs NumericExpression) FloatExpression {
return FloatExp(Mod(n.parent, rhs))
}
func (n *floatInterfaceImpl) POW(expression NumericExpression) FloatExpression {
return POW(n.parent, expression)
}
//---------------------------------------------------//
func newBinaryFloatExpression(lhs, rhs Expression, operator string) FloatExpression {
return FloatExp(newBinaryOperatorExpression(lhs, rhs, operator))
func (n *floatInterfaceImpl) POW(rhs NumericExpression) FloatExpression {
return POW(n.parent, rhs)
}
//---------------------------------------------------//

View file

@ -54,71 +54,71 @@ type integerInterfaceImpl struct {
}
func (i *integerInterfaceImpl) EQ(rhs IntegerExpression) BoolExpression {
return eq(i.parent, rhs)
return Eq(i.parent, rhs)
}
func (i *integerInterfaceImpl) NOT_EQ(rhs IntegerExpression) BoolExpression {
return notEq(i.parent, rhs)
return NotEq(i.parent, rhs)
}
func (i *integerInterfaceImpl) IS_DISTINCT_FROM(rhs IntegerExpression) BoolExpression {
return isDistinctFrom(i.parent, rhs)
return IsDistinctFrom(i.parent, rhs)
}
func (i *integerInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs IntegerExpression) BoolExpression {
return isNotDistinctFrom(i.parent, rhs)
return IsNotDistinctFrom(i.parent, rhs)
}
func (i *integerInterfaceImpl) GT(rhs IntegerExpression) BoolExpression {
return gt(i.parent, rhs)
return Gt(i.parent, rhs)
}
func (i *integerInterfaceImpl) GT_EQ(rhs IntegerExpression) BoolExpression {
return gtEq(i.parent, rhs)
return GtEq(i.parent, rhs)
}
func (i *integerInterfaceImpl) LT(expression IntegerExpression) BoolExpression {
return lt(i.parent, expression)
func (i *integerInterfaceImpl) LT(rhs IntegerExpression) BoolExpression {
return Lt(i.parent, rhs)
}
func (i *integerInterfaceImpl) LT_EQ(expression IntegerExpression) BoolExpression {
return ltEq(i.parent, expression)
func (i *integerInterfaceImpl) LT_EQ(rhs IntegerExpression) BoolExpression {
return LtEq(i.parent, rhs)
}
func (i *integerInterfaceImpl) ADD(expression IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "+")
func (i *integerInterfaceImpl) ADD(rhs IntegerExpression) IntegerExpression {
return IntExp(Add(i.parent, rhs))
}
func (i *integerInterfaceImpl) SUB(expression IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "-")
func (i *integerInterfaceImpl) SUB(rhs IntegerExpression) IntegerExpression {
return IntExp(Sub(i.parent, rhs))
}
func (i *integerInterfaceImpl) MUL(expression IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "*")
func (i *integerInterfaceImpl) MUL(rhs IntegerExpression) IntegerExpression {
return IntExp(Mul(i.parent, rhs))
}
func (i *integerInterfaceImpl) DIV(expression IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "/")
func (i *integerInterfaceImpl) DIV(rhs IntegerExpression) IntegerExpression {
return IntExp(Div(i.parent, rhs))
}
func (i *integerInterfaceImpl) MOD(expression IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "%")
func (i *integerInterfaceImpl) MOD(rhs IntegerExpression) IntegerExpression {
return IntExp(Mod(i.parent, rhs))
}
func (i *integerInterfaceImpl) POW(expression IntegerExpression) IntegerExpression {
return IntExp(POW(i.parent, expression))
func (i *integerInterfaceImpl) POW(rhs IntegerExpression) IntegerExpression {
return IntExp(POW(i.parent, rhs))
}
func (i *integerInterfaceImpl) BIT_AND(expression IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "&")
func (i *integerInterfaceImpl) BIT_AND(rhs IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, rhs, "&")
}
func (i *integerInterfaceImpl) BIT_OR(expression IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "|")
func (i *integerInterfaceImpl) BIT_OR(rhs IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, rhs, "|")
}
func (i *integerInterfaceImpl) BIT_XOR(expression IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "#")
func (i *integerInterfaceImpl) BIT_XOR(rhs IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, rhs, "#")
}
func (i *integerInterfaceImpl) BIT_SHIFT_LEFT(intExpression IntegerExpression) IntegerExpression {
@ -131,7 +131,7 @@ func (i *integerInterfaceImpl) BIT_SHIFT_RIGHT(intExpression IntegerExpression)
//---------------------------------------------------//
func newBinaryIntegerOperatorExpression(lhs, rhs IntegerExpression, operator string) IntegerExpression {
return IntExp(newBinaryOperatorExpression(lhs, rhs, operator))
return IntExp(NewBinaryOperatorExpression(lhs, rhs, operator))
}
//---------------------------------------------------//

View file

@ -11,22 +11,27 @@ type IsInterval interface {
isInterval()
}
// IsIntervalImpl is implementation of IsInterval interface
type IsIntervalImpl struct{}
func (i *IsIntervalImpl) isInterval() {}
// NewInterval creates new interval from serializer
func NewInterval(s Serializer) Interval {
newInterval := &intervalImpl{
func NewInterval(s Serializer) *IntervalImpl {
newInterval := &IntervalImpl{
interval: s,
}
return newInterval
}
type intervalImpl struct {
// IntervalImpl is implementation of Interval type
type IntervalImpl struct {
interval Serializer
IsIntervalImpl
}
func (i intervalImpl) isInterval() {}
func (i intervalImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
func (i IntervalImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
out.WriteString("INTERVAL")
i.interval.serialize(statement, out, options...)
}

View file

@ -346,9 +346,9 @@ func (n *rawExpression) serialize(statement StatementType, out *SQLBuilder, opti
// Raw can be used for any unsupported functions, operators or expressions.
// For example: Raw("current_database()")
func Raw(raw string) Expression {
func Raw(raw string, parent ...Expression) Expression {
rawExp := &rawExpression{Raw: raw}
rawExp.ExpressionInterfaceImpl.Parent = rawExp
rawExp.ExpressionInterfaceImpl.Parent = OptionalOrDefaultExpression(rawExp, parent...)
return rawExp
}

View file

@ -29,44 +29,71 @@ func EXISTS(subQuery Expression) BoolExpression {
return newPrefixBoolOperatorExpression(subQuery, "EXISTS")
}
// Returns a representation of "a=b"
func eq(lhs, rhs Expression) BoolExpression {
// Eq returns a representation of "a=b"
func Eq(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "=")
}
// Returns a representation of "a!=b"
func notEq(lhs, rhs Expression) BoolExpression {
// NotEq returns a representation of "a!=b"
func NotEq(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "!=")
}
func isDistinctFrom(lhs, rhs Expression) BoolExpression {
// IsDistinctFrom returns a representation of "a IS DISTINCT FROM b"
func IsDistinctFrom(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "IS DISTINCT FROM")
}
func isNotDistinctFrom(lhs, rhs Expression) BoolExpression {
// IsNotDistinctFrom returns a representation of "a IS NOT DISTINCT FROM b"
func IsNotDistinctFrom(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "IS NOT DISTINCT FROM")
}
// Returns a representation of "a<b"
func lt(lhs Expression, rhs Expression) BoolExpression {
// Lt returns a representation of "a<b"
func Lt(lhs Expression, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "<")
}
// Returns a representation of "a<=b"
func ltEq(lhs, rhs Expression) BoolExpression {
// LtEq returns a representation of "a<=b"
func LtEq(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "<=")
}
// Returns a representation of "a>b"
func gt(lhs, rhs Expression) BoolExpression {
// Gt returns a representation of "a>b"
func Gt(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, ">")
}
// Returns a representation of "a>=b"
func gtEq(lhs, rhs Expression) BoolExpression {
// GtEq returns a representation of "a>=b"
func GtEq(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, ">=")
}
// Add notEq returns a representation of "a + b"
func Add(lhs, rhs Serializer) Expression {
return NewBinaryOperatorExpression(lhs, rhs, "+")
}
// Sub notEq returns a representation of "a - b"
func Sub(lhs, rhs Serializer) Expression {
return NewBinaryOperatorExpression(lhs, rhs, "-")
}
// Mul returns a representation of "a * b"
func Mul(lhs, rhs Serializer) Expression {
return NewBinaryOperatorExpression(lhs, rhs, "*")
}
// Div returns a representation of "a / b"
func Div(lhs, rhs Serializer) Expression {
return NewBinaryOperatorExpression(lhs, rhs, "/")
}
// Mod returns a representation of "a % b"
func Mod(lhs, rhs Serializer) Expression {
return NewBinaryOperatorExpression(lhs, rhs, "%")
}
// --------------- CASE operator -------------------//
// CaseOperator is interface for SQL case operator

View file

@ -28,35 +28,35 @@ type stringInterfaceImpl struct {
}
func (s *stringInterfaceImpl) EQ(rhs StringExpression) BoolExpression {
return eq(s.parent, rhs)
return Eq(s.parent, rhs)
}
func (s *stringInterfaceImpl) NOT_EQ(rhs StringExpression) BoolExpression {
return notEq(s.parent, rhs)
return NotEq(s.parent, rhs)
}
func (s *stringInterfaceImpl) IS_DISTINCT_FROM(rhs StringExpression) BoolExpression {
return isDistinctFrom(s.parent, rhs)
return IsDistinctFrom(s.parent, rhs)
}
func (s *stringInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs StringExpression) BoolExpression {
return isNotDistinctFrom(s.parent, rhs)
return IsNotDistinctFrom(s.parent, rhs)
}
func (s *stringInterfaceImpl) GT(rhs StringExpression) BoolExpression {
return gt(s.parent, rhs)
return Gt(s.parent, rhs)
}
func (s *stringInterfaceImpl) GT_EQ(rhs StringExpression) BoolExpression {
return gtEq(s.parent, rhs)
return GtEq(s.parent, rhs)
}
func (s *stringInterfaceImpl) LT(rhs StringExpression) BoolExpression {
return lt(s.parent, rhs)
return Lt(s.parent, rhs)
}
func (s *stringInterfaceImpl) LT_EQ(rhs StringExpression) BoolExpression {
return ltEq(s.parent, rhs)
return LtEq(s.parent, rhs)
}
func (s *stringInterfaceImpl) CONCAT(rhs Expression) StringExpression {
@ -81,7 +81,7 @@ func (s *stringInterfaceImpl) NOT_REGEXP_LIKE(pattern StringExpression, caseSens
//---------------------------------------------------//
func newBinaryStringOperatorExpression(lhs, rhs Expression, operator string) StringExpression {
return StringExp(newBinaryOperatorExpression(lhs, rhs, operator))
return StringExp(NewBinaryOperatorExpression(lhs, rhs, operator))
}
//---------------------------------------------------//

View file

@ -23,43 +23,43 @@ type timeInterfaceImpl struct {
}
func (t *timeInterfaceImpl) EQ(rhs TimeExpression) BoolExpression {
return eq(t.parent, rhs)
return Eq(t.parent, rhs)
}
func (t *timeInterfaceImpl) NOT_EQ(rhs TimeExpression) BoolExpression {
return notEq(t.parent, rhs)
return NotEq(t.parent, rhs)
}
func (t *timeInterfaceImpl) IS_DISTINCT_FROM(rhs TimeExpression) BoolExpression {
return isDistinctFrom(t.parent, rhs)
return IsDistinctFrom(t.parent, rhs)
}
func (t *timeInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimeExpression) BoolExpression {
return isNotDistinctFrom(t.parent, rhs)
return IsNotDistinctFrom(t.parent, rhs)
}
func (t *timeInterfaceImpl) LT(rhs TimeExpression) BoolExpression {
return lt(t.parent, rhs)
return Lt(t.parent, rhs)
}
func (t *timeInterfaceImpl) LT_EQ(rhs TimeExpression) BoolExpression {
return ltEq(t.parent, rhs)
return LtEq(t.parent, rhs)
}
func (t *timeInterfaceImpl) GT(rhs TimeExpression) BoolExpression {
return gt(t.parent, rhs)
return Gt(t.parent, rhs)
}
func (t *timeInterfaceImpl) GT_EQ(rhs TimeExpression) BoolExpression {
return gtEq(t.parent, rhs)
return GtEq(t.parent, rhs)
}
func (t *timeInterfaceImpl) ADD(rhs Interval) TimeExpression {
return TimeExp(newBinaryOperatorExpression(t.parent, rhs, "+"))
return TimeExp(Add(t.parent, rhs))
}
func (t *timeInterfaceImpl) SUB(rhs Interval) TimeExpression {
return TimeExp(newBinaryOperatorExpression(t.parent, rhs, "-"))
return TimeExp(Sub(t.parent, rhs))
}
//---------------------------------------------------//

View file

@ -23,43 +23,43 @@ type timestampInterfaceImpl struct {
}
func (t *timestampInterfaceImpl) EQ(rhs TimestampExpression) BoolExpression {
return eq(t.parent, rhs)
return Eq(t.parent, rhs)
}
func (t *timestampInterfaceImpl) NOT_EQ(rhs TimestampExpression) BoolExpression {
return notEq(t.parent, rhs)
return NotEq(t.parent, rhs)
}
func (t *timestampInterfaceImpl) IS_DISTINCT_FROM(rhs TimestampExpression) BoolExpression {
return isDistinctFrom(t.parent, rhs)
return IsDistinctFrom(t.parent, rhs)
}
func (t *timestampInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimestampExpression) BoolExpression {
return isNotDistinctFrom(t.parent, rhs)
return IsNotDistinctFrom(t.parent, rhs)
}
func (t *timestampInterfaceImpl) LT(rhs TimestampExpression) BoolExpression {
return lt(t.parent, rhs)
return Lt(t.parent, rhs)
}
func (t *timestampInterfaceImpl) LT_EQ(rhs TimestampExpression) BoolExpression {
return ltEq(t.parent, rhs)
return LtEq(t.parent, rhs)
}
func (t *timestampInterfaceImpl) GT(rhs TimestampExpression) BoolExpression {
return gt(t.parent, rhs)
return Gt(t.parent, rhs)
}
func (t *timestampInterfaceImpl) GT_EQ(rhs TimestampExpression) BoolExpression {
return gtEq(t.parent, rhs)
return GtEq(t.parent, rhs)
}
func (t *timestampInterfaceImpl) ADD(rhs Interval) TimestampExpression {
return TimestampExp(newBinaryOperatorExpression(t.parent, rhs, "+"))
return TimestampExp(Add(t.parent, rhs))
}
func (t *timestampInterfaceImpl) SUB(rhs Interval) TimestampExpression {
return TimestampExp(newBinaryOperatorExpression(t.parent, rhs, "-"))
return TimestampExp(Sub(t.parent, rhs))
}
//-------------------------------------------------

View file

@ -23,43 +23,43 @@ type timestampzInterfaceImpl struct {
}
func (t *timestampzInterfaceImpl) EQ(rhs TimestampzExpression) BoolExpression {
return eq(t.parent, rhs)
return Eq(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) NOT_EQ(rhs TimestampzExpression) BoolExpression {
return notEq(t.parent, rhs)
return NotEq(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) IS_DISTINCT_FROM(rhs TimestampzExpression) BoolExpression {
return isDistinctFrom(t.parent, rhs)
return IsDistinctFrom(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimestampzExpression) BoolExpression {
return isNotDistinctFrom(t.parent, rhs)
return IsNotDistinctFrom(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) LT(rhs TimestampzExpression) BoolExpression {
return lt(t.parent, rhs)
return Lt(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) LT_EQ(rhs TimestampzExpression) BoolExpression {
return ltEq(t.parent, rhs)
return LtEq(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) GT(rhs TimestampzExpression) BoolExpression {
return gt(t.parent, rhs)
return Gt(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) GT_EQ(rhs TimestampzExpression) BoolExpression {
return gtEq(t.parent, rhs)
return GtEq(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) ADD(rhs Interval) TimestampzExpression {
return TimestampzExp(newBinaryOperatorExpression(t.parent, rhs, "+"))
return TimestampzExp(Add(t.parent, rhs))
}
func (t *timestampzInterfaceImpl) SUB(rhs Interval) TimestampzExpression {
return TimestampzExp(newBinaryOperatorExpression(t.parent, rhs, "-"))
return TimestampzExp(Sub(t.parent, rhs))
}
//-------------------------------------------------

View file

@ -23,43 +23,43 @@ type timezInterfaceImpl struct {
}
func (t *timezInterfaceImpl) EQ(rhs TimezExpression) BoolExpression {
return eq(t.parent, rhs)
return Eq(t.parent, rhs)
}
func (t *timezInterfaceImpl) NOT_EQ(rhs TimezExpression) BoolExpression {
return notEq(t.parent, rhs)
return NotEq(t.parent, rhs)
}
func (t *timezInterfaceImpl) IS_DISTINCT_FROM(rhs TimezExpression) BoolExpression {
return isDistinctFrom(t.parent, rhs)
return IsDistinctFrom(t.parent, rhs)
}
func (t *timezInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimezExpression) BoolExpression {
return isNotDistinctFrom(t.parent, rhs)
return IsNotDistinctFrom(t.parent, rhs)
}
func (t *timezInterfaceImpl) LT(rhs TimezExpression) BoolExpression {
return lt(t.parent, rhs)
return Lt(t.parent, rhs)
}
func (t *timezInterfaceImpl) LT_EQ(rhs TimezExpression) BoolExpression {
return ltEq(t.parent, rhs)
return LtEq(t.parent, rhs)
}
func (t *timezInterfaceImpl) GT(rhs TimezExpression) BoolExpression {
return gt(t.parent, rhs)
return Gt(t.parent, rhs)
}
func (t *timezInterfaceImpl) GT_EQ(rhs TimezExpression) BoolExpression {
return gtEq(t.parent, rhs)
return GtEq(t.parent, rhs)
}
func (t *timezInterfaceImpl) ADD(rhs Interval) TimezExpression {
return TimezExp(newBinaryOperatorExpression(t.parent, rhs, "+"))
return TimezExp(Add(t.parent, rhs))
}
func (t *timezInterfaceImpl) SUB(rhs Interval) TimezExpression {
return TimezExp(newBinaryOperatorExpression(t.parent, rhs, "-"))
return TimezExp(Sub(t.parent, rhs))
}
//---------------------------------------------------//

View file

@ -187,3 +187,23 @@ func UnwidColumnList(columns []Column) []Column {
return ret
}
// OptionalOrDefaultString will return first value from variable argument list str or
// defaultStr if variable argument list is empty
func OptionalOrDefaultString(defaultStr string, str ...string) string {
if len(str) > 0 {
return str[0]
}
return defaultStr
}
// OptionalOrDefaultExpression will return first value from variable argument list expression or
// defaultExpression if variable argument list is empty
func OptionalOrDefaultExpression(defaultExpression Expression, expression ...Expression) Expression {
if len(expression) > 0 {
return expression[0]
}
return defaultExpression
}

View file

@ -0,0 +1,19 @@
package jet
import (
"gotest.tools/assert"
"testing"
)
func TestOptionalOrDefaultString(t *testing.T) {
assert.Equal(t, OptionalOrDefaultString("default"), "default")
assert.Equal(t, OptionalOrDefaultString("default", "optional"), "optional")
}
func TestOptionalOrDefaultExpression(t *testing.T) {
defaultExpression := table2ColFloat
optionalExpression := table1Col1
assert.Equal(t, OptionalOrDefaultExpression(defaultExpression), defaultExpression)
assert.Equal(t, OptionalOrDefaultExpression(defaultExpression, optionalExpression), optionalExpression)
}