2019-03-02 12:34:08 +01:00
|
|
|
// Modeling of columns
|
|
|
|
|
|
2019-06-21 13:56:57 +02:00
|
|
|
package jet
|
2019-03-02 12:34:08 +01:00
|
|
|
|
2019-08-11 14:29:03 +02:00
|
|
|
type Column interface {
|
2019-03-02 12:34:08 +01:00
|
|
|
Name() string
|
2019-03-30 10:17:32 +01:00
|
|
|
TableName() string
|
2019-06-08 16:34:15 +02:00
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
SetTableName(table string)
|
|
|
|
|
SetSubQuery(subQuery SelectTable)
|
|
|
|
|
DefaultAlias() string
|
2019-06-08 16:34:15 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
// Column is common column interface for all types of columns.
|
2019-08-11 14:29:03 +02:00
|
|
|
type ColumnExpression interface {
|
|
|
|
|
Column
|
2019-06-08 16:34:15 +02:00
|
|
|
Expression
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The base type for real materialized columns.
|
2019-06-08 16:34:15 +02:00
|
|
|
type columnImpl struct {
|
2019-08-11 09:52:02 +02:00
|
|
|
ExpressionInterfaceImpl
|
2019-07-28 14:57:02 +02:00
|
|
|
noOpVisitorImpl
|
2019-03-31 14:07:58 +02:00
|
|
|
|
2019-06-08 16:34:15 +02:00
|
|
|
name string
|
|
|
|
|
tableName string
|
2019-06-18 14:35:32 +02:00
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
subQuery SelectTable
|
2019-03-17 20:41:03 +01:00
|
|
|
}
|
|
|
|
|
|
2019-08-11 14:29:03 +02:00
|
|
|
func newColumn(name string, tableName string, parent ColumnExpression) columnImpl {
|
2019-06-08 16:34:15 +02:00
|
|
|
bc := columnImpl{
|
|
|
|
|
name: name,
|
|
|
|
|
tableName: tableName,
|
2019-03-31 14:07:58 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-11 09:52:02 +02:00
|
|
|
bc.ExpressionInterfaceImpl.Parent = parent
|
2019-03-31 14:07:58 +02:00
|
|
|
|
|
|
|
|
return bc
|
|
|
|
|
}
|
2019-03-02 12:34:08 +01:00
|
|
|
|
2019-06-08 16:34:15 +02:00
|
|
|
func (c *columnImpl) Name() string {
|
2019-03-02 12:34:08 +01:00
|
|
|
return c.name
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-08 16:34:15 +02:00
|
|
|
func (c *columnImpl) TableName() string {
|
2019-03-30 10:17:32 +01:00
|
|
|
return c.tableName
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
func (c *columnImpl) SetTableName(table string) {
|
2019-03-30 10:17:32 +01:00
|
|
|
c.tableName = table
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
func (c *columnImpl) SetSubQuery(subQuery SelectTable) {
|
2019-06-18 14:35:32 +02:00
|
|
|
c.subQuery = subQuery
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
func (c *columnImpl) DefaultAlias() string {
|
2019-06-08 16:34:15 +02:00
|
|
|
if c.tableName != "" {
|
|
|
|
|
return c.tableName + "." + c.name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return c.name
|
2019-06-05 17:15:20 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
func (c *columnImpl) serializeForOrderBy(statement StatementType, out *SqlBuilder) error {
|
|
|
|
|
if statement == SetStatementType {
|
2019-05-12 18:15:23 +02:00
|
|
|
// set Statement (UNION, EXCEPT ...) can reference only select projections in order by clause
|
2019-08-03 14:10:47 +02:00
|
|
|
out.writeAlias(c.DefaultAlias()) //always quote
|
2019-05-08 12:49:36 +02:00
|
|
|
|
|
|
|
|
return nil
|
2019-05-03 12:51:57 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-08 13:47:01 +02:00
|
|
|
return c.serialize(statement, out)
|
2019-05-08 12:49:36 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
func (c columnImpl) serializeForProjection(statement StatementType, out *SqlBuilder) error {
|
2019-06-09 11:06:08 +02:00
|
|
|
err := c.serialize(statement, out)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
out.WriteString("AS")
|
|
|
|
|
out.writeAlias(c.DefaultAlias())
|
2019-06-09 11:06:08 +02:00
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
func (c columnImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
|
2019-05-12 18:15:23 +02:00
|
|
|
|
2019-06-18 14:35:32 +02:00
|
|
|
if c.subQuery != nil {
|
|
|
|
|
out.writeIdentifier(c.subQuery.Alias())
|
2019-06-17 12:05:52 +02:00
|
|
|
out.writeByte('.')
|
2019-08-03 14:10:47 +02:00
|
|
|
out.writeIdentifier(c.DefaultAlias(), true)
|
2019-06-18 14:35:32 +02:00
|
|
|
} else {
|
|
|
|
|
if c.tableName != "" {
|
|
|
|
|
out.writeIdentifier(c.tableName)
|
|
|
|
|
out.writeByte('.')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out.writeIdentifier(c.name)
|
2019-03-30 10:17:32 +01:00
|
|
|
}
|
2019-03-09 14:20:44 +01:00
|
|
|
|
2019-03-31 14:07:58 +02:00
|
|
|
return nil
|
2019-03-02 12:34:08 +01:00
|
|
|
}
|
2019-06-14 14:35:50 +02:00
|
|
|
|
|
|
|
|
//------------------------------------------------------//
|
2019-07-16 12:17:27 +02:00
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
type IColumnList interface {
|
|
|
|
|
Projection
|
2019-08-11 14:29:03 +02:00
|
|
|
Column
|
2019-06-14 14:35:50 +02:00
|
|
|
|
2019-08-11 14:29:03 +02:00
|
|
|
Columns() []ColumnExpression
|
2019-08-03 14:10:47 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-11 14:29:03 +02:00
|
|
|
func ColumnList(columns ...ColumnExpression) IColumnList {
|
2019-08-03 14:10:47 +02:00
|
|
|
return columnListImpl(columns)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ColumnList is redefined type to support list of columns as single Projection
|
2019-08-11 14:29:03 +02:00
|
|
|
type columnListImpl []ColumnExpression
|
2019-08-03 14:10:47 +02:00
|
|
|
|
2019-08-11 14:29:03 +02:00
|
|
|
func (cl columnListImpl) Columns() []ColumnExpression {
|
2019-08-03 14:10:47 +02:00
|
|
|
return cl
|
|
|
|
|
}
|
2019-06-14 14:35:50 +02:00
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
func (cl columnListImpl) fromImpl(subQuery SelectTable) Projection {
|
2019-06-18 14:35:32 +02:00
|
|
|
newProjectionList := ProjectionList{}
|
|
|
|
|
|
|
|
|
|
for _, column := range cl {
|
2019-08-03 14:10:47 +02:00
|
|
|
newProjectionList = append(newProjectionList, column.fromImpl(subQuery))
|
2019-06-18 14:35:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newProjectionList
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
func (cl columnListImpl) serializeForProjection(statement StatementType, out *SqlBuilder) error {
|
|
|
|
|
projections := ColumnListToProjectionList(cl)
|
2019-06-14 14:35:50 +02:00
|
|
|
|
2019-08-03 14:10:47 +02:00
|
|
|
err := SerializeProjectionList(statement, projections, out)
|
2019-06-14 14:35:50 +02:00
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-16 12:17:27 +02:00
|
|
|
// dummy column interface implementation
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
// Name is placeholder for ColumnList to implement Column interface
|
2019-08-03 14:10:47 +02:00
|
|
|
func (cl columnListImpl) Name() string { return "" }
|
2019-07-18 17:43:11 +02:00
|
|
|
|
|
|
|
|
// TableName is placeholder for ColumnList to implement Column interface
|
2019-08-03 14:10:47 +02:00
|
|
|
func (cl columnListImpl) TableName() string { return "" }
|
|
|
|
|
func (cl columnListImpl) SetTableName(name string) {}
|
|
|
|
|
func (cl columnListImpl) SetSubQuery(subQuery SelectTable) {}
|
|
|
|
|
func (cl columnListImpl) DefaultAlias() string { return "" }
|