package squirrel

import (
	
	
	
	

	
)

type selectData struct {
	PlaceholderFormat PlaceholderFormat
	RunWith           BaseRunner
	Prefixes          []Sqlizer
	Options           []string
	Columns           []Sqlizer
	From              Sqlizer
	Joins             []Sqlizer
	WhereParts        []Sqlizer
	GroupBys          []string
	HavingParts       []Sqlizer
	OrderByParts      []Sqlizer
	Limit             string
	Offset            string
	Suffixes          []Sqlizer
}

func ( *selectData) () (sql.Result, error) {
	if .RunWith == nil {
		return nil, RunnerNotSet
	}
	return ExecWith(.RunWith, )
}

func ( *selectData) () (*sql.Rows, error) {
	if .RunWith == nil {
		return nil, RunnerNotSet
	}
	return QueryWith(.RunWith, )
}

func ( *selectData) () RowScanner {
	if .RunWith == nil {
		return &Row{err: RunnerNotSet}
	}
	,  := .RunWith.(QueryRower)
	if ! {
		return &Row{err: RunnerNotQueryRunner}
	}
	return QueryRowWith(, )
}

func ( *selectData) () ( string,  []interface{},  error) {
	, ,  = .toSql()
	if  != nil {
		return
	}

	,  = .PlaceholderFormat.ReplacePlaceholders()
	return
}

func ( *selectData) () ( string,  []interface{},  error) {
	return .toSql()
}

func ( *selectData) () ( string,  []interface{},  error) {
	if len(.Columns) == 0 {
		 = fmt.Errorf("select statements must have at least one result column")
		return
	}

	 := &bytes.Buffer{}

	if len(.Prefixes) > 0 {
		,  = appendToSql(.Prefixes, , " ", )
		if  != nil {
			return
		}

		.WriteString(" ")
	}

	.WriteString("SELECT ")

	if len(.Options) > 0 {
		.WriteString(strings.Join(.Options, " "))
		.WriteString(" ")
	}

	if len(.Columns) > 0 {
		,  = appendToSql(.Columns, , ", ", )
		if  != nil {
			return
		}
	}

	if .From != nil {
		.WriteString(" FROM ")
		,  = appendToSql([]Sqlizer{.From}, , "", )
		if  != nil {
			return
		}
	}

	if len(.Joins) > 0 {
		.WriteString(" ")
		,  = appendToSql(.Joins, , " ", )
		if  != nil {
			return
		}
	}

	if len(.WhereParts) > 0 {
		.WriteString(" WHERE ")
		,  = appendToSql(.WhereParts, , " AND ", )
		if  != nil {
			return
		}
	}

	if len(.GroupBys) > 0 {
		.WriteString(" GROUP BY ")
		.WriteString(strings.Join(.GroupBys, ", "))
	}

	if len(.HavingParts) > 0 {
		.WriteString(" HAVING ")
		,  = appendToSql(.HavingParts, , " AND ", )
		if  != nil {
			return
		}
	}

	if len(.OrderByParts) > 0 {
		.WriteString(" ORDER BY ")
		,  = appendToSql(.OrderByParts, , ", ", )
		if  != nil {
			return
		}
	}

	if len(.Limit) > 0 {
		.WriteString(" LIMIT ")
		.WriteString(.Limit)
	}

	if len(.Offset) > 0 {
		.WriteString(" OFFSET ")
		.WriteString(.Offset)
	}

	if len(.Suffixes) > 0 {
		.WriteString(" ")

		,  = appendToSql(.Suffixes, , " ", )
		if  != nil {
			return
		}
	}

	 = .String()
	return
}
Builder
SelectBuilder builds SQL SELECT statements.
Format methods
PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the query.
func ( SelectBuilder) ( PlaceholderFormat) SelectBuilder {
	return builder.Set(, "PlaceholderFormat", ).(SelectBuilder)
}
Runner methods
RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec. For most cases runner will be a database connection. Internally we use this to mock out the database connection for testing.
func ( SelectBuilder) ( BaseRunner) SelectBuilder {
	return setRunWith(, ).(SelectBuilder)
}
Exec builds and Execs the query with the Runner set by RunWith.
func ( SelectBuilder) () (sql.Result, error) {
	 := builder.GetStruct().(selectData)
	return .Exec()
}
Query builds and Querys the query with the Runner set by RunWith.
func ( SelectBuilder) () (*sql.Rows, error) {
	 := builder.GetStruct().(selectData)
	return .Query()
}
QueryRow builds and QueryRows the query with the Runner set by RunWith.
func ( SelectBuilder) () RowScanner {
	 := builder.GetStruct().(selectData)
	return .QueryRow()
}
Scan is a shortcut for QueryRow().Scan.
func ( SelectBuilder) ( ...interface{}) error {
	return .QueryRow().Scan(...)
}
SQL methods
ToSql builds the query into a SQL string and bound args.
func ( SelectBuilder) () (string, []interface{}, error) {
	 := builder.GetStruct().(selectData)
	return .ToSql()
}

func ( SelectBuilder) () (string, []interface{}) {
	, ,  := .ToSql()
	if  != nil {
		panic()
	}
	return , 
}

func ( SelectBuilder) () (string, []interface{}, error) {
	 := builder.GetStruct().(selectData)
	return .toSqlRaw()
}
Prefix adds an expression to the beginning of the query
func ( SelectBuilder) ( string,  ...interface{}) SelectBuilder {
	return .PrefixExpr(Expr(, ...))
}
PrefixExpr adds an expression to the very beginning of the query
func ( SelectBuilder) ( Sqlizer) SelectBuilder {
	return builder.Append(, "Prefixes", ).(SelectBuilder)
}
Distinct adds a DISTINCT clause to the query.
func ( SelectBuilder) () SelectBuilder {
	return .Options("DISTINCT")
}
Options adds select option to the query
func ( SelectBuilder) ( ...string) SelectBuilder {
	return builder.Extend(, "Options", ).(SelectBuilder)
}
Columns adds result columns to the query.
func ( SelectBuilder) ( ...string) SelectBuilder {
	 := make([]interface{}, 0, len())
	for ,  := range  {
		 = append(, newPart())
	}
	return builder.Extend(, "Columns", ).(SelectBuilder)
}
Column adds a result column to the query. Unlike Columns, Column accepts args which will be bound to placeholders in the columns string, for example: Column("IF(col IN ("+squirrel.Placeholders(3)+"), 1, 0) as col", 1, 2, 3)
func ( SelectBuilder) ( interface{},  ...interface{}) SelectBuilder {
	return builder.Append(, "Columns", newPart(, ...)).(SelectBuilder)
}
From sets the FROM clause of the query.
func ( SelectBuilder) ( string) SelectBuilder {
	return builder.Set(, "From", newPart()).(SelectBuilder)
}
FromSelect sets a subquery into the FROM clause of the query.
Prevent misnumbered parameters in nested selects (#183).
	 = .PlaceholderFormat(Question)
	return builder.Set(, "From", Alias(, )).(SelectBuilder)
}
JoinClause adds a join clause to the query.
func ( SelectBuilder) ( interface{},  ...interface{}) SelectBuilder {
	return builder.Append(, "Joins", newPart(, ...)).(SelectBuilder)
}
Join adds a JOIN clause to the query.
func ( SelectBuilder) ( string,  ...interface{}) SelectBuilder {
	return .JoinClause("JOIN "+, ...)
}
LeftJoin adds a LEFT JOIN clause to the query.
func ( SelectBuilder) ( string,  ...interface{}) SelectBuilder {
	return .JoinClause("LEFT JOIN "+, ...)
}
RightJoin adds a RIGHT JOIN clause to the query.
func ( SelectBuilder) ( string,  ...interface{}) SelectBuilder {
	return .JoinClause("RIGHT JOIN "+, ...)
}
Where adds an expression to the WHERE clause of the query. Expressions are ANDed together in the generated SQL. Where accepts several types for its pred argument: nil OR "" - ignored. string - SQL expression. If the expression has SQL placeholders then a set of arguments must be passed as well, one for each placeholder. map[string]interface{} OR Eq - map of SQL expressions to values. Each key is transformed into an expression like "<key> = ?", with the corresponding value bound to the placeholder. If the value is nil, the expression will be "<key> IS NULL". If the value is an array or slice, the expression will be "<key> IN (?,?,...)", with one placeholder for each item in the value. These expressions are ANDed together. Where will panic if pred isn't any of the above types.
func ( SelectBuilder) ( interface{},  ...interface{}) SelectBuilder {
	if  == nil ||  == "" {
		return 
	}
	return builder.Append(, "WhereParts", newWherePart(, ...)).(SelectBuilder)
}
GroupBy adds GROUP BY expressions to the query.
func ( SelectBuilder) ( ...string) SelectBuilder {
	return builder.Extend(, "GroupBys", ).(SelectBuilder)
}
Having adds an expression to the HAVING clause of the query. See Where.
func ( SelectBuilder) ( interface{},  ...interface{}) SelectBuilder {
	return builder.Append(, "HavingParts", newWherePart(, ...)).(SelectBuilder)
}
OrderByClause adds ORDER BY clause to the query.
func ( SelectBuilder) ( interface{},  ...interface{}) SelectBuilder {
	return builder.Append(, "OrderByParts", newPart(, ...)).(SelectBuilder)
}
OrderBy adds ORDER BY expressions to the query.
func ( SelectBuilder) ( ...string) SelectBuilder {
	for ,  := range  {
		 = .OrderByClause()
	}

	return 
}
Limit sets a LIMIT clause on the query.
func ( SelectBuilder) ( uint64) SelectBuilder {
	return builder.Set(, "Limit", fmt.Sprintf("%d", )).(SelectBuilder)
}
Limit ALL allows to access all records with limit
func ( SelectBuilder) () SelectBuilder {
	return builder.Delete(, "Limit").(SelectBuilder)
}
Offset sets a OFFSET clause on the query.
func ( SelectBuilder) ( uint64) SelectBuilder {
	return builder.Set(, "Offset", fmt.Sprintf("%d", )).(SelectBuilder)
}
RemoveOffset removes OFFSET clause.
func ( SelectBuilder) () SelectBuilder {
	return builder.Delete(, "Offset").(SelectBuilder)
}
Suffix adds an expression to the end of the query
func ( SelectBuilder) ( string,  ...interface{}) SelectBuilder {
	return .SuffixExpr(Expr(, ...))
}
SuffixExpr adds an expression to the end of the query
func ( SelectBuilder) ( Sqlizer) SelectBuilder {
	return builder.Append(, "Suffixes", ).(SelectBuilder)