diff --git a/internal/jet/column_list.go b/internal/jet/column_list.go index a4a0b66..4834871 100644 --- a/internal/jet/column_list.go +++ b/internal/jet/column_list.go @@ -1,5 +1,7 @@ package jet +import "strings" + // ColumnList is a helper type to support list of columns as single projection type ColumnList []ColumnExpression @@ -39,6 +41,21 @@ func (cl ColumnList) Except(excludedColumns ...Column) ColumnList { return ret } +// As will create new projection list where each column is wrapped with a new table alias. +// tableAlias should be in the form 'name' or 'name.*', or it can also be an empty string. +// For instance: If projection list has a column 'Artist.Name', and tableAlias is 'Musician.*', returned projection list will +// have a column wrapped in alias 'Musician.Name'. If tableAlias is empty string, it removes existing table alias ('Artist.Name' becomes 'Name'). +func (cl ColumnList) As(tableAlias string) ProjectionList { + if tableAlias > "" { + tableAlias = strings.TrimRight(tableAlias, ".*") + "." + } + ret := make(ProjectionList, 0, len(cl)) + for _, c := range cl { + ret = append(ret, c.AS(tableAlias+c.Name())) + } + return ret +} + func (cl ColumnList) fromImpl(subQuery SelectTable) Projection { newProjectionList := ProjectionList{} diff --git a/internal/jet/projection.go b/internal/jet/projection.go index 3139d3f..09f1c2b 100644 --- a/internal/jet/projection.go +++ b/internal/jet/projection.go @@ -31,11 +31,15 @@ func (pl ProjectionList) serializeForProjection(statement StatementType, out *SQ } // As will create new projection list where each column is wrapped with a new table alias. -// tableAlias should be in the form 'name' or 'name.*'. +// tableAlias should be in the form 'name' or 'name.*', or it can be an empty string, which will remove existing table alias. // For instance: If projection list has a column 'Artist.Name', and tableAlias is 'Musician.*', returned projection list will -// have a column wrapped in alias 'Musician.Name'. +// have a column wrapped in alias 'Musician.Name'. If tableAlias is empty string, it removes existing table alias ('Artist.Name' becomes 'Name'). func (pl ProjectionList) As(tableAlias string) ProjectionList { - tableAlias = strings.TrimRight(tableAlias, ".*") + tableAliasWithDot := "" + if tableAlias != "" { + tableAlias = strings.TrimRight(tableAlias, ".*") + tableAliasWithDot = tableAlias + "." + } newProjectionList := ProjectionList{} @@ -43,16 +47,14 @@ func (pl ProjectionList) As(tableAlias string) ProjectionList { switch p := projection.(type) { case ProjectionList: newProjectionList = append(newProjectionList, p.As(tableAlias)) - case ColumnExpression: - newProjectionList = append(newProjectionList, newAlias(p, tableAlias+"."+p.Name())) case ColumnList: - for _, c := range p { - newProjectionList = append(newProjectionList, newAlias(c, tableAlias+"."+c.Name())) - } + newProjectionList = append(newProjectionList, p.As(tableAlias)) + case ColumnExpression: + newProjectionList = append(newProjectionList, newAlias(p, tableAliasWithDot+p.Name())) case *alias: newAlias := *p _, columnName := extractTableAndColumnName(newAlias.alias) - newAlias.alias = tableAlias + "." + columnName + newAlias.alias = tableAliasWithDot + columnName newProjectionList = append(newProjectionList, &newAlias) } } diff --git a/internal/jet/projection_test.go b/internal/jet/projection_test.go index 96727d5..0370b43 100644 --- a/internal/jet/projection_test.go +++ b/internal/jet/projection_test.go @@ -27,6 +27,18 @@ AVG(table1.col_int) AS "new_alias.avg", table2.col3 AS "new_alias.col3", table2.col4 AS "new_alias.col4"`) + aliasedProjectionList = projectionList.As("") + + assertProjectionSerialize(t, aliasedProjectionList, + `table1.col3 AS "col3", +SUM(table1.col_int) AS "sum", +SUM(table1.col_int) AS "sum", +table1.col_bool AS "col_bool", +AVG(table1.col_int) AS "avg", +AVG(table1.col_int) AS "avg", +table2.col3 AS "col3", +table2.col4 AS "col4"`) + subQueryProjections := projectionList.fromImpl(NewSelectTable(nil, "subQuery")) assertProjectionSerialize(t, subQueryProjections,