click

package module
v0.0.0-...-ea54f16 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2025 License: GPL-3.0 Imports: 7 Imported by: 0

README

click: Golang ClickHouse query SQL builder

Go Reference Go Report

1. design overview

  • declarative builder: build ClickHouse SQL declaratively, in simple or advanced ways
  • type-safe: static-typed, extensible SQL template for code reuse
  • feel-like-home: SQL-like, idiomatic Go, no bloated stuff
  • easy to extend & interoperate with:
    • good interoperability with existing popular ORM library (github.com/huandu/go-sqlbuilder)
    • directly generate final query SQL, easy to use outside the library
  • well-tested: test coverage ~87%
    • test coverage

2. features & modules

  1. querybuilder:
    • SimpleQuery: non-nested query shortcut, build with struct
    • Select(): declarative, chained, freestyle builder
  2. expression: fundamental SQL expressions and operators
    • expressions & functions: GreaterThan, LessThan, In, If, ...
    • operators: And, Or, Concatenate

2. examples

2.1 click 101
package main

import (
	"fmt"
	"github.com/keuin/click"
)

const (
	Date click.Column = "date"
	User click.Column = "user"
)

func main() {
	sumVisitCount := click.Alias("visit_count")
	sql, _ := click.
		Select(Date, User, click.As(click.Count(), sumVisitCount)).
		From(click.Table("user_accesses")).
		GroupBy(Date, User).
		OrderBy(sumVisitCount).
		Limit(10).PrettyPrint().BuildString()
	fmt.Println(sql)
}
SELECT
    date,
    user,
    count() AS visit_count
FROM
    user_accesses
GROUP BY
    date,
    user
ORDER BY
    visit_count
LIMIT
    10
2.2 nested query
package main

import (
	"fmt"
	. "github.com/keuin/click"
)

const (
	Date  Column = "date"
	Score Column = "score"
	Tbl   Table  = "tbl"
)

func main() {
	avgScore := As(Avg(Score), LiteralExpression("avg_score"))
	sql, _ := Select(Count()).
		From(
			Select(avgScore).
				From(Tbl).
				Sample(0.1).
				Where(And(
					GreaterOrEqualThan(Date, LiteralExpressionQuoted("2024-01-01")),
					LessThan(Date, LiteralExpressionQuoted("2024-02-01")),
				)).
				GroupBy(Date).
				OrderBy(Date, Asc(Date), Desc(avgScore)).
				Having(GreaterThan(avgScore, LiteralExpression(60))).
				Limit(5).Offset(10),
		).
		PrettyPrint().BuildString()
	fmt.Println(sql)
}
SELECT
	count()
FROM
(
	SELECT
		avg(score) AS avg_score
	FROM
		tbl
	SAMPLE
		0.1
	WHERE
		((date >= '2024-01-01') AND (date < '2024-02-01'))
	GROUP BY
		date
	HAVING
		(avg_score > 60)
	ORDER BY
		date,
		date ASC,
		avg_score DESC
	LIMIT
		5
	OFFSET
		10
)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BinaryExpression

type BinaryExpression struct {
	Operator     Operator
	LeftOperand  Expression
	RightOperand Expression
}

func (BinaryExpression) Expression

func (e BinaryExpression) Expression() string

type Column

type Column string

Column is a ClickHouse table column name, without quotations.

func (Column) Expression

func (e Column) Expression() string

type Expression

type Expression interface {
	Expression() string
}

Expression is a ClickHouse SQL expression AST object.

func Alias

func Alias(s string) Expression

func And

func And(sub ...Expression) Expression

func Avg

func Avg(v Expression) Expression

func Concatenate

func Concatenate(op Operator, sub ...Expression) Expression

func Count

func Count(v ...Expression) Expression

func CountIf

func CountIf(v Expression) Expression

func Equal

func Equal(l Expression, r Expression) Expression

func Fn

func Fn(name string, args ...Expression) Expression

func GreaterOrEqualThan

func GreaterOrEqualThan(l Expression, r Expression) Expression

func GreaterThan

func GreaterThan(l Expression, r Expression) Expression

func If

func If(cond, v1, v2 Expression) Expression

func In

func In(v Expression, ary Tuple) Expression

func IsNotNull

func IsNotNull(v Expression) Expression

func LessOrEqualThan

func LessOrEqualThan(l Expression, r Expression) Expression

func LessThan

func LessThan(l Expression, r Expression) Expression

func LiteralExpression

func LiteralExpression[T any](v T) Expression

LiteralExpression converts a Go value to a SQL string, formatting that value to string with fmt.Sprint.

func LiteralExpressionQuoted

func LiteralExpressionQuoted[T any](v T) Expression

LiteralExpressionQuoted creates literal expression, treating the argument as a string value, not a SQL expression

func LiteralExpressions

func LiteralExpressions[T any](v []T, quoteString bool) (ret []Expression)

func NotEqual

func NotEqual(l Expression, r Expression) Expression

func NotIn

func NotIn(v Expression, ary Tuple) Expression

func Or

func Or(sub ...Expression) Expression

func Sum

func Sum(v Expression) Expression

type Format

type Format string

Format is ClickHouse input/output format. The value is its string ID. User can construct custom formats by converting string to type Format. See https://clickhouse.com/docs/interfaces/formats

const (
	FormatTabSeparated                               Format = "TabSeparated"
	FormatTabSeparatedRaw                            Format = "TabSeparatedRaw"
	FormatTabSeparatedWithNames                      Format = "TabSeparatedWithNames"
	FormatTabSeparatedWithNamesAndTypes              Format = "TabSeparatedWithNamesAndTypes"
	FormatTabSeparatedRawWithNames                   Format = "TabSeparatedRawWithNames"
	FormatTabSeparatedRawWithNamesAndTypes           Format = "TabSeparatedRawWithNamesAndTypes"
	FormatTemplate                                   Format = "Template"
	FormatCSV                                        Format = "CSV"
	FormatCSVWithNames                               Format = "CSVWithNames"
	FormatCSVWithNamesAndTypes                       Format = "CSVWithNamesAndTypes"
	FormatCustomSeparated                            Format = "CustomSeparated"
	FormatCustomSeparatedWithNames                   Format = "CustomSeparatedWithNames"
	FormatCustomSeparatedWithNamesAndTypes           Format = "CustomSeparatedWithNamesAndTypes"
	FormatSQLInsert                                  Format = "SQLInsert"
	FormatValues                                     Format = "Values"
	FormatVertical                                   Format = "Vertical"
	FormatJSON                                       Format = "JSON"
	FormatJSONStrings                                Format = "JSONStrings"
	FormatJSONColumns                                Format = "JSONColumns"
	FormatJSONColumnsWithMetadata                    Format = "JSONColumnsWithMetadata"
	FormatJSONCompact                                Format = "JSONCompact"
	FormatJSONCompactStrings                         Format = "JSONCompactStrings"
	FormatJSONCompactColumns                         Format = "JSONCompactColumns"
	FormatJSONEachRow                                Format = "JSONEachRow"
	FormatPrettyJSONEachRow                          Format = "PrettyJSONEachRow"
	FormatJSONEachRowWithProgress                    Format = "JSONEachRowWithProgress"
	FormatJSONStringsEachRow                         Format = "JSONStringsEachRow"
	FormatJSONStringsEachRowWithProgress             Format = "JSONStringsEachRowWithProgress"
	FormatJSONCompactEachRow                         Format = "JSONCompactEachRow"
	FormatJSONCompactEachRowWithNames                Format = "JSONCompactEachRowWithNames"
	FormatJSONCompactEachRowWithNamesAndTypes        Format = "JSONCompactEachRowWithNamesAndTypes"
	FormatJSONCompactEachRowWithProgress             Format = "JSONCompactEachRowWithProgress"
	FormatJSONCompactStringsEachRow                  Format = "JSONCompactStringsEachRow"
	FormatJSONCompactStringsEachRowWithNames         Format = "JSONCompactStringsEachRowWithNames"
	FormatJSONCompactStringsEachRowWithNamesAndTypes Format = "JSONCompactStringsEachRowWithNamesAndTypes"
	FormatJSONCompactStringsEachRowWithProgress      Format = "JSONCompactStringsEachRowWithProgress"
	FormatJSONObjectEachRow                          Format = "JSONObjectEachRow"
	FormatBSONEachRow                                Format = "BSONEachRow"
	FormatTSKV                                       Format = "TSKV"
	FormatPretty                                     Format = "Pretty"
	FormatPrettyNoEscapes                            Format = "PrettyNoEscapes"
	FormatPrettyMonoBlock                            Format = "PrettyMonoBlock"
	FormatPrettyNoEscapesMonoBlock                   Format = "PrettyNoEscapesMonoBlock"
	FormatPrettyCompact                              Format = "PrettyCompact"
	FormatPrettyCompactNoEscapes                     Format = "PrettyCompactNoEscapes"
	FormatPrettyCompactMonoBlock                     Format = "PrettyCompactMonoBlock"
	FormatPrettyCompactNoEscapesMonoBlock            Format = "PrettyCompactNoEscapesMonoBlock"
	FormatPrettySpace                                Format = "PrettySpace"
	FormatPrettySpaceNoEscapes                       Format = "PrettySpaceNoEscapes"
	FormatPrettySpaceMonoBlock                       Format = "PrettySpaceMonoBlock"
	FormatPrettySpaceNoEscapesMonoBlock              Format = "PrettySpaceNoEscapesMonoBlock"
	FormatPrometheus                                 Format = "Prometheus"
	FormatProtobuf                                   Format = "Protobuf"
	FormatProtobufSingle                             Format = "ProtobufSingle"
	FormatProtobufList                               Format = "ProtobufList"
	FormatAvro                                       Format = "Avro"
	FormatParquet                                    Format = "Parquet"
	FormatArrow                                      Format = "Arrow"
	FormatArrowStream                                Format = "ArrowStream"
	FormatORC                                        Format = "ORC"
	FormatNpy                                        Format = "Npy"
	FormatRowBinary                                  Format = "RowBinary"
	FormatRowBinaryWithNames                         Format = "RowBinaryWithNames"
	FormatRowBinaryWithNamesAndTypes                 Format = "RowBinaryWithNamesAndTypes"
	FormatNative                                     Format = "Native"
	FormatNull                                       Format = "Null"
	FormatXML                                        Format = "XML"
	FormatCapnProto                                  Format = "CapnProto"
	FormatLineAsString                               Format = "LineAsString"
	FormatRawBLOB                                    Format = "RawBLOB"
	FormatMsgPack                                    Format = "MsgPack"
	FormatMarkdown                                   Format = "Markdown"
)

All output-able formats. Those cannot be used as output formats are not listed. See type Format for more info.

type FromExpression

type FromExpression interface {
	FromExpression(style RenderStyle) (string, error)
}

FromExpression is an Expression in FROM clause. Any Expression that can be used in nested query may implement FromExpression, customizing how it will look like when being selected from.

type LiteralOperand

type LiteralOperand struct {
	// contains filtered or unexported fields
}

func (LiteralOperand) String

func (o LiteralOperand) String() string

type Operator

type Operator string
const (
	OpAnd Operator = "AND"
	OpOr  Operator = "OR"
	OpNot Operator = "NOT"
)

func (Operator) String

func (o Operator) String() string

type OrderByExpression

type OrderByExpression interface {
	Expression
	OrderByExpression() string
}

OrderByExpression is an Expression in ORDER BY clause. Any Expression that can be selected may implement OrderByExpression, customizing how it will look like when being ordered by.

func Asc

func Desc

type OrderDirection

type OrderDirection int
const (
	OrderDefault OrderDirection = iota
	OrderAscending
	OrderDescending
)

type RenderStyle

type RenderStyle struct {
	Indent            string
	IndentLevel       int
	ClauseNamePrefix  string
	ClauseNameSuffix  string
	ArgumentPrefix    string
	ArgumentSuffix    string
	ArgumentDelimiter string
}

type SelectBuilder

type SelectBuilder struct {
	// contains filtered or unexported fields
}

SelectBuilder implements builder pattern for constructing SELECT SQLs. Its zero value is a ready-to-use empty builder. It's recommended to use Select as a shortcut.

func Select

func Select(values ...Expression) *SelectBuilder

func (*SelectBuilder) Build

func (s *SelectBuilder) Build() (SelectQuery, error)

func (*SelectBuilder) BuildString

func (s *SelectBuilder) BuildString() (string, error)

func (*SelectBuilder) Format

func (s *SelectBuilder) Format(f Format) *SelectBuilder

func (*SelectBuilder) From

func (s *SelectBuilder) From(table FromExpression) *SelectBuilder

func (*SelectBuilder) FromExpression

func (s *SelectBuilder) FromExpression(style RenderStyle) (string, error)

func (*SelectBuilder) GroupBy

func (s *SelectBuilder) GroupBy(values ...Expression) *SelectBuilder

func (*SelectBuilder) Having

func (s *SelectBuilder) Having(value Expression) *SelectBuilder

func (*SelectBuilder) Limit

func (s *SelectBuilder) Limit(n int) *SelectBuilder

func (*SelectBuilder) Offset

func (s *SelectBuilder) Offset(n int) *SelectBuilder

func (*SelectBuilder) OrderBy

func (s *SelectBuilder) OrderBy(values ...Expression) *SelectBuilder

func (*SelectBuilder) PrettyPrint

func (s *SelectBuilder) PrettyPrint(b ...bool) *SelectBuilder

func (*SelectBuilder) Sample

func (s *SelectBuilder) Sample(v float64) *SelectBuilder

func (*SelectBuilder) Select

func (s *SelectBuilder) Select(values ...Expression) *SelectBuilder

func (*SelectBuilder) Where

func (s *SelectBuilder) Where(where Expression) *SelectBuilder

type SelectExpression

type SelectExpression interface {
	Expression
	SelectExpression() string
}

SelectExpression is an expression in SELECT clause. Any Expression that can be selected may implement SelectExpression, customizing how it will look like when being selected.

type SelectOrderByExpression

type SelectOrderByExpression interface {
	Expression
	SelectExpression
	OrderByExpression
}

type SelectQuery

type SelectQuery interface {
	FromExpression
	String() string
}

type SimpleQuery

type SimpleQuery struct {
	IsTimeSeriesQuery   bool
	TimeColumn          Column
	GranularityFunction string
	StartTime           time.Time
	EndTime             time.Time

	Select  []Expression
	From    string // From is table name
	Where   Expression
	GroupBy []Expression
	OrderBy []Expression
	Having  Expression
	Limit   int // Limit is valid only with positive values
	Offset  int
}

func (SimpleQuery) Build

func (q SimpleQuery) Build() (SelectQuery, error)

func (SimpleQuery) BuildString

func (q SimpleQuery) BuildString() (string, error)

type Table

type Table string

func (Table) FromExpression

func (t Table) FromExpression(_ RenderStyle) (string, error)

type Tuple

type Tuple []Expression

Tuple is ClickHouse tuple object, and must contain at least one element. See https://clickhouse.com/docs/sql-reference/data-types/tuple

func (Tuple) Expression

func (t Tuple) Expression() string

func (Tuple) SelectExpression

func (t Tuple) SelectExpression() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL