Default aliasing simplified.

This commit is contained in:
go-jet 2019-06-09 11:06:08 +02:00
parent e772768180
commit ffba8718ca
11 changed files with 46 additions and 70 deletions

View file

@ -14,7 +14,7 @@ func NewAlias(expression Expression, alias string) *Alias {
func (a *Alias) serializeForProjection(statement statementType, out *queryData) error { func (a *Alias) serializeForProjection(statement statementType, out *queryData) error {
err := a.expression.serializeForProjection(statement, out) err := a.expression.serialize(statement, out)
if err != nil { if err != nil {
return err return err

View file

@ -46,8 +46,9 @@ func TestBinaryBoolExpression(t *testing.T) {
boolExpression := Int(2).EQ(Int(3)) boolExpression := Int(2).EQ(Int(3))
assertClauseSerialize(t, boolExpression, "($1 = $2)", int64(2), int64(3)) assertClauseSerialize(t, boolExpression, "($1 = $2)", int64(2), int64(3))
assertProjectionSerialize(t, boolExpression, "$1 = $2", int64(2), int64(3))
assertProjectionSerialize(t, boolExpression.AS("alias_eq_expression"), assertProjectionSerialize(t, boolExpression.AS("alias_eq_expression"),
`$1 = $2 AS "alias_eq_expression"`, int64(2), int64(3)) `($1 = $2) AS "alias_eq_expression"`, int64(2), int64(3))
assertClauseSerialize(t, boolExpression.AND(Int(4).EQ(Int(5))), assertClauseSerialize(t, boolExpression.AND(Int(4).EQ(Int(5))),
"(($1 = $2) AND ($3 = $4))", int64(2), int64(3), int64(4), int64(5)) "(($1 = $2) AND ($3 = $4))", int64(2), int64(3), int64(4), int64(5))
assertClauseSerialize(t, boolExpression.OR(Int(4).EQ(Int(5))), assertClauseSerialize(t, boolExpression.OR(Int(4).EQ(Int(5))),

View file

@ -58,7 +58,7 @@ func (q *queryData) decreaseIdent() {
q.ident -= defaultIdent q.ident -= defaultIdent
} }
func (q *queryData) writeProjection(statement statementType, projections []projection) error { func (q *queryData) writeProjections(statement statementType, projections []projection) error {
q.increaseIdent() q.increaseIdent()
err := serializeProjectionList(statement, projections, q) err := serializeProjectionList(statement, projections, q)
q.decreaseIdent() q.decreaseIdent()

View file

@ -10,11 +10,7 @@ type column interface {
Name() string Name() string
TableName() string TableName() string
// Internal function for tracking tableName that a column belongs to
// for the purpose of serialization
setTableName(table string) setTableName(table string)
defaultAlias() string
defaultAliasProjection() projection
} }
type Column interface { type Column interface {
@ -61,10 +57,6 @@ func (c *columnImpl) defaultAlias() string {
return c.name return c.name
} }
func (c *columnImpl) defaultAliasProjection() projection {
return c.AS(c.defaultAlias())
}
func (c *columnImpl) serializeAsOrderBy(statement statementType, out *queryData) error { func (c *columnImpl) serializeAsOrderBy(statement statementType, out *queryData) error {
if statement == set_statement { if statement == set_statement {
// set Statement (UNION, EXCEPT ...) can reference only select projections in order by clause // set Statement (UNION, EXCEPT ...) can reference only select projections in order by clause
@ -84,6 +76,18 @@ func (c *columnImpl) serializeAsOrderBy(statement statementType, out *queryData)
return c.serialize(statement, out) return c.serialize(statement, out)
} }
func (c columnImpl) serializeForProjection(statement statementType, out *queryData) error {
err := c.serialize(statement, out)
if err != nil {
return err
}
out.writeString(`AS "` + c.defaultAlias() + `"`)
return nil
}
func (c columnImpl) serialize(statement statementType, out *queryData, options ...serializeOption) error { func (c columnImpl) serialize(statement statementType, out *queryData, options ...serializeOption) error {
columnRef := "" columnRef := ""

View file

@ -9,6 +9,6 @@ func TestColumn(t *testing.T) {
assertClauseSerialize(t, column, "col") assertClauseSerialize(t, column, "col")
column.setTableName("table1") column.setTableName("table1")
assertClauseSerialize(t, column, "table1.col") assertClauseSerialize(t, column, "table1.col")
assertProjectionSerialize(t, column.defaultAliasProjection(), `table1.col AS "table1.col"`) assertProjectionSerialize(t, column, `table1.col AS "table1.col"`)
assertProjectionSerialize(t, column.AS("alias1"), `table1.col AS "alias1"`) assertProjectionSerialize(t, column.AS("alias1"), `table1.col AS "alias1"`)
} }

View file

@ -10,24 +10,24 @@ func TestNewBoolColumn(t *testing.T) {
boolColumn := BoolColumn("colBool").From(subQuery) boolColumn := BoolColumn("colBool").From(subQuery)
assertClauseSerialize(t, boolColumn, "sub_query.colBool") assertClauseSerialize(t, boolColumn, "sub_query.colBool")
assertClauseSerialize(t, boolColumn.EQ(Bool(true)), "(sub_query.colBool = $1)", true) assertClauseSerialize(t, boolColumn.EQ(Bool(true)), "(sub_query.colBool = $1)", true)
assertProjectionSerialize(t, boolColumn.defaultAliasProjection(), `sub_query.colBool AS "sub_query.colBool"`) assertProjectionSerialize(t, boolColumn, `sub_query.colBool AS "sub_query.colBool"`)
boolColumn2 := table1ColBool.From(subQuery) boolColumn2 := table1ColBool.From(subQuery)
assertClauseSerialize(t, boolColumn2, `sub_query."table1.colBool"`) assertClauseSerialize(t, boolColumn2, `sub_query."table1.colBool"`)
assertClauseSerialize(t, boolColumn2.EQ(Bool(true)), `(sub_query."table1.colBool" = $1)`, true) assertClauseSerialize(t, boolColumn2.EQ(Bool(true)), `(sub_query."table1.colBool" = $1)`, true)
assertProjectionSerialize(t, boolColumn2.defaultAliasProjection(), `sub_query."table1.colBool" AS "sub_query.table1.colBool"`) assertProjectionSerialize(t, boolColumn2, `sub_query."table1.colBool" AS "sub_query.table1.colBool"`)
} }
func TestNewIntColumn(t *testing.T) { func TestNewIntColumn(t *testing.T) {
intColumn := IntegerColumn("colInt").From(subQuery) intColumn := IntegerColumn("colInt").From(subQuery)
assertClauseSerialize(t, intColumn, "sub_query.colInt") assertClauseSerialize(t, intColumn, "sub_query.colInt")
assertClauseSerialize(t, intColumn.EQ(Int(12)), "(sub_query.colInt = $1)", int64(12)) assertClauseSerialize(t, intColumn.EQ(Int(12)), "(sub_query.colInt = $1)", int64(12))
assertProjectionSerialize(t, intColumn.defaultAliasProjection(), `sub_query.colInt AS "sub_query.colInt"`) assertProjectionSerialize(t, intColumn, `sub_query.colInt AS "sub_query.colInt"`)
intColumn2 := table1ColInt.From(subQuery) intColumn2 := table1ColInt.From(subQuery)
assertClauseSerialize(t, intColumn2, `sub_query."table1.colInt"`) assertClauseSerialize(t, intColumn2, `sub_query."table1.colInt"`)
assertClauseSerialize(t, intColumn2.EQ(Int(14)), `(sub_query."table1.colInt" = $1)`, int64(14)) assertClauseSerialize(t, intColumn2.EQ(Int(14)), `(sub_query."table1.colInt" = $1)`, int64(14))
assertProjectionSerialize(t, intColumn2.defaultAliasProjection(), `sub_query."table1.colInt" AS "sub_query.table1.colInt"`) assertProjectionSerialize(t, intColumn2, `sub_query."table1.colInt" AS "sub_query.table1.colInt"`)
} }
@ -35,11 +35,11 @@ func TestNewFloatColumnColumn(t *testing.T) {
floatColumn := FloatColumn("colFloat").From(subQuery) floatColumn := FloatColumn("colFloat").From(subQuery)
assertClauseSerialize(t, floatColumn, "sub_query.colFloat") assertClauseSerialize(t, floatColumn, "sub_query.colFloat")
assertClauseSerialize(t, floatColumn.EQ(Float(1.11)), "(sub_query.colFloat = $1)", float64(1.11)) assertClauseSerialize(t, floatColumn.EQ(Float(1.11)), "(sub_query.colFloat = $1)", float64(1.11))
assertProjectionSerialize(t, floatColumn.defaultAliasProjection(), `sub_query.colFloat AS "sub_query.colFloat"`) assertProjectionSerialize(t, floatColumn, `sub_query.colFloat AS "sub_query.colFloat"`)
floatColumn2 := table1ColFloat.From(subQuery) floatColumn2 := table1ColFloat.From(subQuery)
assertClauseSerialize(t, floatColumn2, `sub_query."table1.colFloat"`) assertClauseSerialize(t, floatColumn2, `sub_query."table1.colFloat"`)
assertClauseSerialize(t, floatColumn2.EQ(Float(2.22)), `(sub_query."table1.colFloat" = $1)`, float64(2.22)) assertClauseSerialize(t, floatColumn2.EQ(Float(2.22)), `(sub_query."table1.colFloat" = $1)`, float64(2.22))
assertProjectionSerialize(t, floatColumn2.defaultAliasProjection(), `sub_query."table1.colFloat" AS "sub_query.table1.colFloat"`) assertProjectionSerialize(t, floatColumn2, `sub_query."table1.colFloat" AS "sub_query.table1.colFloat"`)
} }

View file

@ -106,7 +106,8 @@ func (i *insertStatementImpl) VALUES_MAPPING(data interface{}) InsertStatement {
} }
func (i *insertStatementImpl) RETURNING(projections ...projection) InsertStatement { func (i *insertStatementImpl) RETURNING(projections ...projection) InsertStatement {
i.returning = defaultProjectionAliasing(projections) //i.returning = defaultProjectionAliasing(projections)
i.returning = projections
return i return i
} }
@ -206,7 +207,7 @@ func (s *insertStatementImpl) Sql() (sql string, args []interface{}, err error)
queryData.nextLine() queryData.nextLine()
queryData.writeString("RETURNING") queryData.writeString("RETURNING")
err = queryData.writeProjection(insert_statement, s.returning) err = queryData.writeProjections(insert_statement, s.returning)
if err != nil { if err != nil {
return return

View file

@ -11,27 +11,13 @@ type ColumnList []Column
func (cl ColumnList) isProjectionType() {} func (cl ColumnList) isProjectionType() {}
func (cl ColumnList) serializeForProjection(statement statementType, out *queryData) error { func (cl ColumnList) serializeForProjection(statement statementType, out *queryData) error {
for i, column := range cl { projections := columnListToProjectionList(cl)
err := column.serializeForProjection(statement, out)
err := serializeProjectionList(statement, projections, out)
if err != nil { if err != nil {
return err return err
} }
if i != len(cl)-1 {
out.writeString(", ")
}
}
return nil return nil
} }
func (cl ColumnList) DefaultAlias() []projection {
newColumnList := []projection{}
for _, column := range cl {
newColumn := column.defaultAliasProjection()
newColumnList = append(newColumnList, newColumn)
}
return newColumnList
}

View file

@ -49,26 +49,10 @@ type selectStatementImpl struct {
forUpdate bool forUpdate bool
} }
func defaultProjectionAliasing(projections []projection) []projection {
aliasedProjections := []projection{}
for _, projection := range projections {
if column, ok := projection.(Column); ok {
aliasedProjections = append(aliasedProjections, column.defaultAliasProjection())
} else if columnList, ok := projection.(ColumnList); ok {
aliasedProjections = append(aliasedProjections, columnList.DefaultAlias()...)
} else {
aliasedProjections = append(aliasedProjections, projection)
}
}
return aliasedProjections
}
func newSelectStatement(table ReadableTable, projections []projection) SelectStatement { func newSelectStatement(table ReadableTable, projections []projection) SelectStatement {
newSelect := &selectStatementImpl{ newSelect := &selectStatementImpl{
table: table, table: table,
projections: defaultProjectionAliasing(projections), projections: projections,
limit: -1, limit: -1,
offset: -1, offset: -1,
forUpdate: false, forUpdate: false,
@ -117,11 +101,11 @@ func (s *selectStatementImpl) serializeImpl(out *queryData) error {
out.writeString("DISTINCT") out.writeString("DISTINCT")
} }
if s.projections == nil || len(s.projections) == 0 { if len(s.projections) == 0 {
return errors.New("No column selected for projection.") return errors.New("no column selected for projection")
} }
err := out.writeProjection(select_statement, s.projections) err := out.writeProjections(select_statement, s.projections)
if err != nil { if err != nil {
return err return err

View file

@ -48,7 +48,7 @@ func (u *updateStatementImpl) WHERE(expression BoolExpression) UpdateStatement {
} }
func (u *updateStatementImpl) RETURNING(projections ...projection) UpdateStatement { func (u *updateStatementImpl) RETURNING(projections ...projection) UpdateStatement {
u.returning = defaultProjectionAliasing(projections) u.returning = projections
return u return u
} }

View file

@ -87,7 +87,7 @@ func serializeProjectionList(statement statementType, projections []projection,
} }
if col == nil { if col == nil {
return errors.New("projection Expression is nil.") return errors.New("projection Expression is nil")
} }
if err := col.serializeForProjection(statement, out); err != nil { if err := col.serializeForProjection(statement, out); err != nil {
@ -118,15 +118,15 @@ func isNil(v interface{}) bool {
return v == nil || (reflect.ValueOf(v).Kind() == reflect.Ptr && reflect.ValueOf(v).IsNil()) return v == nil || (reflect.ValueOf(v).Kind() == reflect.Ptr && reflect.ValueOf(v).IsNil())
} }
//func stringExpressionListToExpressionList(stringExpressions []StringExpression) []Expression{ func columnListToProjectionList(columns []Column) []projection {
// var ret []Expression var ret []projection
//
// for _, strExp := range stringExpressions { for _, column := range columns {
// ret = append(ret, strExp) ret = append(ret, column)
// } }
//
// return ret return ret
//} }
func Query(statement Statement, db execution.Db, destination interface{}) error { func Query(statement Statement, db execution.Db, destination interface{}) error {
query, args, err := statement.Sql() query, args, err := statement.Sql()