github.com/mitranim/sqlb@v0.7.2/sqlb_expr.go (about)

     1  package sqlb
     2  
     3  import (
     4  	"fmt"
     5  	r "reflect"
     6  	"strconv"
     7  	"strings"
     8  )
     9  
    10  /*
    11  Shortcut for interpolating strings into queries. Because this implements `Expr`,
    12  when used as an argument in another expression, this will be directly
    13  interpolated into the resulting query string. See the examples.
    14  */
    15  type Str string
    16  
    17  // Implement the `Expr` interface, making this a sub-expression.
    18  func (self Str) AppendExpr(text []byte, args []any) ([]byte, []any) {
    19  	return self.AppendTo(text), args
    20  }
    21  
    22  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
    23  // encoding.
    24  func (self Str) AppendTo(text []byte) []byte {
    25  	return appendMaybeSpaced(text, string(self))
    26  }
    27  
    28  // Implement the `fmt.Stringer` interface for debug purposes.
    29  func (self Str) String() string { return string(self) }
    30  
    31  // Represents an SQL identifier, always quoted.
    32  type Ident string
    33  
    34  // Implement the `Expr` interface, making this a sub-expression.
    35  func (self Ident) AppendExpr(text []byte, args []any) ([]byte, []any) {
    36  	return self.AppendTo(text), args
    37  }
    38  
    39  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
    40  // encoding.
    41  func (self Ident) AppendTo(text []byte) []byte {
    42  	validateIdent(string(self))
    43  	text = maybeAppendSpace(text)
    44  	text = append(text, quoteDouble)
    45  	text = append(text, self...)
    46  	text = append(text, quoteDouble)
    47  	return text
    48  }
    49  
    50  // Implement the `fmt.Stringer` interface for debug purposes.
    51  func (self Ident) String() string { return AppenderString(&self) }
    52  
    53  // Shortcut for internal use.
    54  func (self Ident) BuiAppend(bui *Bui) {
    55  	bui.Text = self.AppendTo(bui.Text)
    56  }
    57  
    58  /*
    59  Represents a nested SQL identifier where all elements are quoted but not
    60  parenthesized. Useful for schema-qualified paths. For nested paths that don't
    61  begin with a schema, use `Path` instead.
    62  */
    63  type Identifier []string
    64  
    65  // Implement the `Expr` interface, making this a sub-expression.
    66  func (self Identifier) AppendExpr(text []byte, args []any) ([]byte, []any) {
    67  	return self.AppendTo(text), args
    68  }
    69  
    70  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
    71  // encoding.
    72  func (self Identifier) AppendTo(text []byte) []byte {
    73  	if len(self) == 0 {
    74  		return text
    75  	}
    76  	for ind, val := range self {
    77  		if ind > 0 {
    78  			text = append(text, `.`...)
    79  		}
    80  		text = Ident(val).AppendTo(text)
    81  	}
    82  	return text
    83  }
    84  
    85  // Implement the `fmt.Stringer` interface for debug purposes.
    86  func (self Identifier) String() string { return AppenderString(&self) }
    87  
    88  // Normalizes the expression, returning nil or a single `Ident` if the length
    89  // allows this. Otherwise returns self as-is.
    90  func (self Identifier) Norm() Expr {
    91  	switch len(self) {
    92  	case 0:
    93  		return Identifier(nil)
    94  	case 1:
    95  		return Ident(self[0])
    96  	default:
    97  		return self
    98  	}
    99  }
   100  
   101  /*
   102  Represents a nested SQL identifier where the first outer element is
   103  parenthesized, and every element is quoted. Useful for nested paths that begin
   104  with a table or view name. For schema-qualified paths, use `Identifier`
   105  instead.
   106  */
   107  type Path []string
   108  
   109  // Implement the `Expr` interface, making this a sub-expression.
   110  func (self Path) AppendExpr(text []byte, args []any) ([]byte, []any) {
   111  	return self.AppendTo(text), args
   112  }
   113  
   114  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   115  // encoding.
   116  func (self Path) AppendTo(text []byte) []byte {
   117  	if len(self) == 0 {
   118  		return text
   119  	}
   120  
   121  	if len(self) == 1 {
   122  		return Ident(self[0]).AppendTo(text)
   123  	}
   124  
   125  	text = appendMaybeSpaced(text, `(`)
   126  	text = Ident(self[0]).AppendTo(text)
   127  	text = append(text, `)`...)
   128  
   129  	for _, val := range self[1:] {
   130  		text = append(text, `.`...)
   131  		text = Ident(val).AppendTo(text)
   132  	}
   133  	return text
   134  }
   135  
   136  // Implement the `fmt.Stringer` interface for debug purposes.
   137  func (self Path) String() string { return AppenderString(&self) }
   138  
   139  // Normalizes the expression, returning nil or a single `Ident` if the length
   140  // allows this. Otherwise returns self as-is.
   141  func (self Path) Norm() Expr {
   142  	switch len(self) {
   143  	case 0:
   144  		return Path(nil)
   145  	case 1:
   146  		return Ident(self[0])
   147  	default:
   148  		return self
   149  	}
   150  }
   151  
   152  /*
   153  Represents an arbitrarily-nested SQL path that gets encoded as a SINGLE quoted
   154  identifier, where elements are dot-separated. This is a common convention for
   155  nested structs, supported by SQL-scanning libraries such as
   156  https://github.com/mitranim/gos.
   157  */
   158  type PseudoPath []string
   159  
   160  // Implement the `Expr` interface, making this a sub-expression.
   161  func (self PseudoPath) AppendExpr(text []byte, args []any) ([]byte, []any) {
   162  	return self.AppendTo(text), args
   163  }
   164  
   165  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   166  // encoding.
   167  func (self PseudoPath) AppendTo(text []byte) []byte {
   168  	if len(self) == 0 {
   169  		return text
   170  	}
   171  
   172  	text = maybeAppendSpace(text)
   173  	text = append(text, quoteDouble)
   174  
   175  	for ind, val := range self {
   176  		validateIdent(val)
   177  		if ind > 0 {
   178  			text = append(text, `.`...)
   179  		}
   180  		text = append(text, val...)
   181  	}
   182  
   183  	text = append(text, quoteDouble)
   184  	return text
   185  }
   186  
   187  // Implement the `fmt.Stringer` interface for debug purposes.
   188  func (self PseudoPath) String() string { return AppenderString(&self) }
   189  
   190  // Normalizes the expression, returning nil or a single `Ident` if the length
   191  // allows this. Otherwise returns self as-is.
   192  func (self PseudoPath) Norm() Expr {
   193  	switch len(self) {
   194  	case 0:
   195  		return PseudoPath(nil)
   196  	case 1:
   197  		return Ident(self[0])
   198  	default:
   199  		return self
   200  	}
   201  }
   202  
   203  /*
   204  Represents an arbitrarily-nested SQL path that gets encoded as `Path` followed
   205  by `PseudoPath` alias. Useful for building "select" clauses. Used internally by
   206  `ColsDeep`.
   207  */
   208  type AliasedPath []string
   209  
   210  // Implement the `Expr` interface, making this a sub-expression.
   211  func (self AliasedPath) AppendExpr(text []byte, args []any) ([]byte, []any) {
   212  	return self.AppendTo(text), args
   213  }
   214  
   215  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   216  // encoding.
   217  func (self AliasedPath) AppendTo(text []byte) []byte {
   218  	if len(self) == 0 {
   219  		return text
   220  	}
   221  
   222  	if len(self) == 1 {
   223  		return Ident(self[0]).AppendTo(text)
   224  	}
   225  
   226  	text = Path(self).AppendTo(text)
   227  	text = append(text, ` as `...)
   228  	text = PseudoPath(self).AppendTo(text)
   229  	return text
   230  }
   231  
   232  // Implement the `fmt.Stringer` interface for debug purposes.
   233  func (self AliasedPath) String() string { return AppenderString(&self) }
   234  
   235  // Normalizes the expression, returning nil or a single `Ident` if the length
   236  // allows this. Otherwise returns self as-is.
   237  func (self AliasedPath) Norm() Expr {
   238  	switch len(self) {
   239  	case 0:
   240  		return AliasedPath(nil)
   241  	case 1:
   242  		return Ident(self[0])
   243  	default:
   244  		return self
   245  	}
   246  }
   247  
   248  /*
   249  Same as `Identifier`, but preceded by the word "table". The SQL clause
   250  "table some_name" is equivalent to "select * from some_name".
   251  */
   252  type Table Identifier
   253  
   254  // Implement the `Expr` interface, making this a sub-expression.
   255  func (self Table) AppendExpr(text []byte, args []any) ([]byte, []any) {
   256  	return self.AppendTo(text), args
   257  }
   258  
   259  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   260  // encoding.
   261  func (self Table) AppendTo(text []byte) []byte {
   262  	if len(self) == 0 {
   263  		return text
   264  	}
   265  	text = appendMaybeSpaced(text, `table`)
   266  	text = Identifier(self).AppendTo(text)
   267  	return text
   268  }
   269  
   270  // Implement the `fmt.Stringer` interface for debug purposes.
   271  func (self Table) String() string { return AppenderString(&self) }
   272  
   273  /*
   274  Variable-sized sequence of expressions. When encoding, expressions will be
   275  space-separated if necessary.
   276  */
   277  type Exprs []Expr
   278  
   279  // Implement the `Expr` interface, making this a sub-expression.
   280  func (self Exprs) AppendExpr(text []byte, args []any) ([]byte, []any) {
   281  	bui := Bui{text, args}
   282  	for _, val := range self {
   283  		bui.Expr(val)
   284  	}
   285  	return bui.Get()
   286  }
   287  
   288  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   289  // encoding.
   290  func (self Exprs) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   291  
   292  // Implement the `fmt.Stringer` interface for debug purposes.
   293  func (self Exprs) String() string { return exprString(self) }
   294  
   295  /*
   296  Represents an SQL "any()" expression. The inner value may be an instance of
   297  `Expr`, or an arbitrary argument.
   298  */
   299  type Any [1]any
   300  
   301  // Implement the `Expr` interface, making this a sub-expression.
   302  func (self Any) AppendExpr(text []byte, args []any) ([]byte, []any) {
   303  	bui := Bui{text, args}
   304  	bui.Str(`any (`)
   305  	bui.Any(self[0])
   306  	bui.Str(`)`)
   307  	return bui.Get()
   308  }
   309  
   310  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   311  // encoding.
   312  func (self Any) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   313  
   314  // Implement the `fmt.Stringer` interface for debug purposes.
   315  func (self Any) String() string { return exprString(self) }
   316  
   317  /*
   318  Represents an SQL assignment such as `"some_col" = arbitrary_expression`. The
   319  LHS must be a column name, while the RHS can be an `Expr` instance or an
   320  arbitrary argument.
   321  */
   322  type Assign struct {
   323  	Lhs Ident
   324  	Rhs any
   325  }
   326  
   327  // Implement the `Expr` interface, making this a sub-expression.
   328  func (self Assign) AppendExpr(text []byte, args []any) ([]byte, []any) {
   329  	bui := Bui{text, args}
   330  	bui.Any(self.Lhs)
   331  	bui.Str(`=`)
   332  	bui.SubAny(self.Rhs)
   333  	return bui.Get()
   334  }
   335  
   336  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   337  // encoding.
   338  func (self Assign) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   339  
   340  // Implement the `fmt.Stringer` interface for debug purposes.
   341  func (self Assign) String() string { return exprString(self) }
   342  
   343  /*
   344  Short for "equal". Represents SQL equality such as `A = B` or `A is null`.
   345  Counterpart to `Neq`.
   346  */
   347  type Eq [2]any
   348  
   349  // Implement the `Expr` interface, making this a sub-expression.
   350  func (self Eq) AppendExpr(text []byte, args []any) ([]byte, []any) {
   351  	text, args = self.AppendLhs(text, args)
   352  	text, args = self.AppendRhs(text, args)
   353  	return text, args
   354  }
   355  
   356  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   357  // encoding.
   358  func (self Eq) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   359  
   360  // Implement the `fmt.Stringer` interface for debug purposes.
   361  func (self Eq) String() string { return exprString(self) }
   362  
   363  /*
   364  Note: LHS and RHS are encoded differently because some SQL equality expressions
   365  are asymmetric. For example, `any` allows an array only on the RHS, and there's
   366  no way to invert it (AFAIK).
   367  */
   368  func (self Eq) AppendLhs(text []byte, args []any) ([]byte, []any) {
   369  	bui := Bui{text, args}
   370  	bui.SubAny(self[0])
   371  	return bui.Get()
   372  }
   373  
   374  func (self Eq) AppendRhs(text []byte, args []any) ([]byte, []any) {
   375  	bui := Bui{text, args}
   376  	val := norm(self[1])
   377  
   378  	if val == nil {
   379  		bui.Str(`is null`)
   380  		return bui.Get()
   381  	}
   382  
   383  	bui.Str(`=`)
   384  	bui.SubAny(val)
   385  	return bui.Get()
   386  }
   387  
   388  /*
   389  Short for "not equal". Represents SQL non-equality such as `A <> B` or
   390  `A is not null`. Counterpart to `Eq`.
   391  */
   392  type Neq [2]any
   393  
   394  // Implement the `Expr` interface, making this a sub-expression.
   395  func (self Neq) AppendExpr(text []byte, args []any) ([]byte, []any) {
   396  	text, args = self.AppendLhs(text, args)
   397  	text, args = self.AppendRhs(text, args)
   398  	return text, args
   399  }
   400  
   401  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   402  // encoding.
   403  func (self Neq) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   404  
   405  // Implement the `fmt.Stringer` interface for debug purposes.
   406  func (self Neq) String() string { return exprString(self) }
   407  
   408  // See the comment on `Eq.AppendLhs`.
   409  func (self Neq) AppendLhs(text []byte, args []any) ([]byte, []any) {
   410  	bui := Bui{text, args}
   411  	bui.SubAny(self[0])
   412  	return bui.Get()
   413  }
   414  
   415  func (self Neq) AppendRhs(text []byte, args []any) ([]byte, []any) {
   416  	bui := Bui{text, args}
   417  	val := norm(self[1])
   418  
   419  	if val == nil {
   420  		bui.Str(`is not null`)
   421  		return bui.Get()
   422  	}
   423  
   424  	bui.Str(`<>`)
   425  	bui.SubAny(val)
   426  	return bui.Get()
   427  }
   428  
   429  // Represents an SQL expression `A = any(B)`. Counterpart to `NeqAny`.
   430  type EqAny [2]any
   431  
   432  // Implement the `Expr` interface, making this a sub-expression.
   433  func (self EqAny) AppendExpr(text []byte, args []any) ([]byte, []any) {
   434  	bui := Bui{text, args}
   435  	bui.SubAny(self[0])
   436  	bui.Str(`=`)
   437  	bui.Set(Any{self[1]}.AppendExpr(bui.Get()))
   438  	return bui.Get()
   439  }
   440  
   441  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   442  // encoding.
   443  func (self EqAny) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   444  
   445  // Implement the `fmt.Stringer` interface for debug purposes.
   446  func (self EqAny) String() string { return exprString(self) }
   447  
   448  // Represents an SQL expression `A <> any(B)`. Counterpart to `EqAny`.
   449  type NeqAny [2]any
   450  
   451  // Implement the `Expr` interface, making this a sub-expression.
   452  func (self NeqAny) AppendExpr(text []byte, args []any) ([]byte, []any) {
   453  	bui := Bui{text, args}
   454  	bui.SubAny(self[0])
   455  	bui.Str(`<>`)
   456  	bui.Set(Any{self[1]}.AppendExpr(bui.Get()))
   457  	return bui.Get()
   458  }
   459  
   460  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   461  // encoding.
   462  func (self NeqAny) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   463  
   464  // Implement the `fmt.Stringer` interface for debug purposes.
   465  func (self NeqAny) String() string { return exprString(self) }
   466  
   467  // Represents SQL logical negation such as `not A`. The inner value can be an
   468  // instance of `Expr` or an arbitrary argument.
   469  type Not [1]any
   470  
   471  // Implement the `Expr` interface, making this a sub-expression.
   472  func (self Not) AppendExpr(text []byte, args []any) ([]byte, []any) {
   473  	bui := Bui{text, args}
   474  	bui.Str(`not`)
   475  	bui.SubAny(self[0])
   476  	return bui.Get()
   477  }
   478  
   479  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   480  // encoding.
   481  func (self Not) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   482  
   483  // Implement the `fmt.Stringer` interface for debug purposes.
   484  func (self Not) String() string { return exprString(self) }
   485  
   486  /*
   487  Represents a sequence of arbitrary sub-expressions or arguments, joined with a
   488  customizable delimiter, with a customizable fallback in case of empty list.
   489  This is mostly an internal tool for building other sequences, such as `And` and
   490  `Or`. The inner value may be nil or a single `Expr`, otherwise it must be a
   491  slice.
   492  */
   493  type Seq struct {
   494  	Empty string
   495  	Delim string
   496  	Val   any
   497  }
   498  
   499  // Implement the `Expr` interface, making this a sub-expression.
   500  func (self Seq) AppendExpr(text []byte, args []any) ([]byte, []any) {
   501  	bui := Bui{text, args}
   502  	val := self.Val
   503  
   504  	impl, _ := val.(Expr)
   505  	if impl != nil {
   506  		bui.Expr(impl)
   507  	} else {
   508  		self.any(&bui, val)
   509  	}
   510  
   511  	return bui.Get()
   512  }
   513  
   514  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   515  // encoding.
   516  func (self Seq) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   517  
   518  // Implement the `fmt.Stringer` interface for debug purposes.
   519  func (self Seq) String() string { return exprString(self) }
   520  
   521  func (self *Seq) any(bui *Bui, val any) {
   522  	switch kindOf(val) {
   523  	case r.Invalid:
   524  		self.appendEmpty(bui)
   525  	case r.Slice:
   526  		self.appendSlice(bui, val)
   527  	default:
   528  		panic(errExpectedSlice(`building SQL expression`, val))
   529  	}
   530  }
   531  
   532  func (self *Seq) appendEmpty(bui *Bui) {
   533  	bui.Str(self.Empty)
   534  }
   535  
   536  func (self Seq) appendSlice(bui *Bui, src any) {
   537  	val := valueOf(src)
   538  
   539  	if val.Len() == 0 {
   540  		self.appendEmpty(bui)
   541  		return
   542  	}
   543  
   544  	if val.Len() == 1 {
   545  		bui.Any(val.Index(0).Interface())
   546  		return
   547  	}
   548  
   549  	for ind := range counter(val.Len()) {
   550  		if ind > 0 {
   551  			bui.Str(self.Delim)
   552  		}
   553  		bui.SubAny(val.Index(ind).Interface())
   554  	}
   555  }
   556  
   557  /*
   558  Represents a comma-separated list of arbitrary sub-expressions. The inner value
   559  may be nil or a single `Expr`, otherwise it must be a slice.
   560  */
   561  type Comma [1]any
   562  
   563  // Implement the `Expr` interface, making this a sub-expression.
   564  func (self Comma) AppendExpr(text []byte, args []any) ([]byte, []any) {
   565  	// May revise in the future. Some SQL expressions, such as composite literals
   566  	// expressed as strings, are sensitive to whitespace around commas.
   567  	return Seq{``, `, `, self[0]}.AppendExpr(text, args)
   568  }
   569  
   570  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   571  // encoding.
   572  func (self Comma) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   573  
   574  // Implement the `fmt.Stringer` interface for debug purposes.
   575  func (self Comma) String() string { return exprString(self) }
   576  
   577  /*
   578  Represents a sequence of arbitrary sub-expressions or arguments joined by the
   579  SQL `and` operator. Rules for the inner value:
   580  
   581  	* nil or empty     -> fallback to `true`
   582  	* single `Expr`    -> render it as-is
   583  	* non-empty slice  -> render its individual elements joined by `and`
   584  	* non-empty struct -> render column equality conditions joined by `and`
   585  */
   586  type And [1]any
   587  
   588  // Implement the `Expr` interface, making this a sub-expression.
   589  func (self And) AppendExpr(text []byte, args []any) ([]byte, []any) {
   590  	return Cond{`true`, `and`, self[0]}.AppendExpr(text, args)
   591  }
   592  
   593  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   594  // encoding.
   595  func (self And) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   596  
   597  // Implement the `fmt.Stringer` interface for debug purposes.
   598  func (self And) String() string { return exprString(self) }
   599  
   600  /*
   601  Represents a sequence of arbitrary sub-expressions or arguments joined by the
   602  SQL `or` operator. Rules for the inner value:
   603  
   604  	* nil or empty     -> fallback to `false`
   605  	* single `Expr`    -> render it as-is
   606  	* non-empty slice  -> render its individual elements joined by `or`
   607  	* non-empty struct -> render column equality conditions joined by `or`
   608  */
   609  type Or [1]any
   610  
   611  // Implement the `Expr` interface, making this a sub-expression.
   612  func (self Or) AppendExpr(text []byte, args []any) ([]byte, []any) {
   613  	return Cond{`false`, `or`, self[0]}.AppendExpr(text, args)
   614  }
   615  
   616  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   617  // encoding.
   618  func (self Or) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   619  
   620  // Implement the `fmt.Stringer` interface for debug purposes.
   621  func (self Or) String() string { return exprString(self) }
   622  
   623  // Syntactic shortcut, same as `And` with a slice of sub-expressions or arguments.
   624  type Ands []any
   625  
   626  // Implement the `Expr` interface, making this a sub-expression.
   627  func (self Ands) AppendExpr(text []byte, args []any) ([]byte, []any) {
   628  	if len(self) == 0 {
   629  		return And{}.AppendExpr(text, args)
   630  	}
   631  	return And{[]any(self)}.AppendExpr(text, args)
   632  }
   633  
   634  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   635  // encoding.
   636  func (self Ands) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   637  
   638  // Implement the `fmt.Stringer` interface for debug purposes.
   639  func (self Ands) String() string { return exprString(self) }
   640  
   641  // Syntactic shortcut, same as `Or` with a slice of sub-expressions or arguments.
   642  type Ors []any
   643  
   644  // Implement the `Expr` interface, making this a sub-expression.
   645  func (self Ors) AppendExpr(text []byte, args []any) ([]byte, []any) {
   646  	if len(self) == 0 {
   647  		return Or{}.AppendExpr(text, args)
   648  	}
   649  	return Or{[]any(self)}.AppendExpr(text, args)
   650  }
   651  
   652  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   653  // encoding.
   654  func (self Ors) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   655  
   656  // Implement the `fmt.Stringer` interface for debug purposes.
   657  func (self Ors) String() string { return exprString(self) }
   658  
   659  /*
   660  Superset of `Seq` with additional support for structs. When the inner value is
   661  a struct, this generates a sequence of equality expressions, comparing the
   662  struct's column names against the corresponding field values. Field values may
   663  be arbitrary sub-expressions or arguments.
   664  
   665  This is mostly an internal tool for building other expression types. Used
   666  internally by `And` and `Or`.
   667  */
   668  type Cond Seq
   669  
   670  // Implement the `Expr` interface, making this a sub-expression.
   671  func (self Cond) AppendExpr(text []byte, args []any) ([]byte, []any) {
   672  	bui := Bui{text, args}
   673  	val := self.Val
   674  
   675  	impl, _ := val.(Expr)
   676  	if impl != nil {
   677  		bui.Expr(impl)
   678  	} else {
   679  		self.any(&bui, val)
   680  	}
   681  
   682  	return bui.Get()
   683  }
   684  
   685  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   686  // encoding.
   687  func (self Cond) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   688  
   689  // Implement the `fmt.Stringer` interface for debug purposes.
   690  func (self Cond) String() string { return exprString(self) }
   691  
   692  func (self *Cond) any(bui *Bui, val any) {
   693  	switch kindOf(val) {
   694  	case r.Invalid:
   695  		self.appendEmpty(bui)
   696  	case r.Struct:
   697  		self.appendStruct(bui, val)
   698  	case r.Slice:
   699  		self.appendSlice(bui, val)
   700  	default:
   701  		bui.Any(val)
   702  	}
   703  }
   704  
   705  func (self *Cond) appendEmpty(bui *Bui) {
   706  	(*Seq)(self).appendEmpty(bui)
   707  }
   708  
   709  // TODO consider if we should support nested non-embedded structs.
   710  func (self *Cond) appendStruct(bui *Bui, src any) {
   711  	iter := makeIter(src)
   712  
   713  	for iter.next() {
   714  		if !iter.first() {
   715  			bui.Str(self.Delim)
   716  		}
   717  
   718  		lhs := Ident(FieldDbName(iter.field))
   719  		rhs := Eq{nil, iter.value.Interface()}
   720  
   721  		// Equivalent to using `Eq` for the full expression, but avoids an
   722  		// allocation caused by converting `Ident` to `Expr`. As a bonus, this also
   723  		// avoids unnecessary parens around the ident.
   724  		bui.Set(lhs.AppendExpr(bui.Get()))
   725  		bui.Set(rhs.AppendRhs(bui.Get()))
   726  	}
   727  
   728  	if iter.empty() {
   729  		self.appendEmpty(bui)
   730  	}
   731  }
   732  
   733  func (self *Cond) appendSlice(bui *Bui, val any) {
   734  	(*Seq)(self).appendSlice(bui, val)
   735  }
   736  
   737  /*
   738  Represents a column list for a "select" expression. The inner value may be of
   739  any type, and is used as a type carrier; its actual value is ignored. If the
   740  inner value is a struct or struct slice, the resulting expression is a list of
   741  column names corresponding to its fields, using a "db" tag. Otherwise the
   742  expression is `*`.
   743  
   744  Unlike many other struct-scanning expressions, this doesn't support filtering
   745  via `Sparse`. It operates at the level of a struct type, not an individual
   746  struct value.
   747  
   748  TODO actually support `Sparse` because it's used for insert.
   749  */
   750  type Cols [1]any
   751  
   752  // Implement the `Expr` interface, making this a sub-expression.
   753  func (self Cols) AppendExpr(text []byte, args []any) ([]byte, []any) {
   754  	return self.AppendTo(text), args
   755  }
   756  
   757  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   758  // encoding.
   759  func (self Cols) AppendTo(text []byte) []byte {
   760  	return appendMaybeSpaced(text, self.String())
   761  }
   762  
   763  // Implement the `fmt.Stringer` interface for debug purposes.
   764  func (self Cols) String() string {
   765  	return TypeCols(r.TypeOf(self[0]))
   766  }
   767  
   768  /*
   769  Represents a column list for a "select" expression. The inner value may be of
   770  any type, and is used as a type carrier; its actual value is ignored. If the
   771  inner value is a struct or struct slice, the resulting expression is a list of
   772  column names corresponding to its fields, using a "db" tag. Otherwise the
   773  expression is `*`.
   774  
   775  Unlike `Cols`, this has special support for nested structs and nested column
   776  paths. See the examples.
   777  
   778  Unlike many other struct-scanning expressions, this doesn't support filtering
   779  via `Sparse`. It operates at the level of a struct type, not an individual
   780  struct value.
   781  */
   782  type ColsDeep [1]any
   783  
   784  // Implement the `Expr` interface, making this a sub-expression.
   785  func (self ColsDeep) AppendExpr(text []byte, args []any) ([]byte, []any) {
   786  	return self.AppendTo(text), args
   787  }
   788  
   789  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   790  // encoding.
   791  func (self ColsDeep) AppendTo(text []byte) []byte {
   792  	return appendMaybeSpaced(text, self.String())
   793  }
   794  
   795  // Implement the `fmt.Stringer` interface for debug purposes.
   796  func (self ColsDeep) String() string {
   797  	return TypeColsDeep(r.TypeOf(self[0]))
   798  }
   799  
   800  /*
   801  Represents comma-separated values from the "db"-tagged fields of an arbitrary
   802  struct. Field/column names are ignored. Values may be arbitrary sub-expressions
   803  or arguments. The value passed to `StructValues` may be nil, which is
   804  equivalent to an empty struct. It may also be an arbitrarily-nested struct
   805  pointer, which is automatically dereferenced.
   806  
   807  Supports filtering. If the inner value implements `Sparse`, then not all fields
   808  are considered to be "present", which is useful for PATCH semantics. See the
   809  docs on `Sparse` and `Part`.
   810  */
   811  type StructValues [1]any
   812  
   813  // Implement the `Expr` interface, making this a sub-expression.
   814  func (self StructValues) AppendExpr(text []byte, args []any) ([]byte, []any) {
   815  	bui := Bui{text, args}
   816  	iter := makeIter(self[0])
   817  	// TODO consider panicking when empty.
   818  	iterAppendVals(&bui, iter, false)
   819  	return bui.Get()
   820  }
   821  
   822  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   823  // encoding.
   824  func (self StructValues) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   825  
   826  // Implement the `fmt.Stringer` interface for debug purposes.
   827  func (self StructValues) String() string { return exprString(self) }
   828  
   829  /*
   830  Represents a names-and-values clause suitable for insertion. The inner value
   831  must be nil or a struct. Nil or empty struct generates a "default values"
   832  clause. Otherwise the resulting expression has SQL column names and values
   833  generated by scanning the input struct. See the examples.
   834  
   835  Supports filtering. If the inner value implements `Sparse`, then not all fields
   836  are considered to be "present", which is useful for PATCH semantics. See the
   837  docs on `Sparse` and `Part`.
   838  */
   839  type StructInsert [1]any
   840  
   841  // Implement the `Expr` interface, making this a sub-expression.
   842  func (self StructInsert) AppendExpr(text []byte, args []any) ([]byte, []any) {
   843  	bui := Bui{text, args}
   844  	iter := makeIter(self[0])
   845  
   846  	/**
   847  	The condition is slightly suboptimal: if the source is `Sparse`, `iter.has`
   848  	may iterate the fields and invoke a filter for multiple fields which happen
   849  	to be "missing", until it finds one that is "present". Then we iterate to
   850  	append cols, and to append values, for a total of three loops. It would be
   851  	more optimal to iterate only for cols and values, not for the condition.
   852  	*/
   853  	if iter.has() {
   854  		bui.Str(`(`)
   855  		iterAppendCols(&bui, iter, false)
   856  		bui.Str(`)`)
   857  		bui.Str(`values (`)
   858  		iterAppendVals(&bui, iter, false)
   859  		bui.Str(`)`)
   860  	} else {
   861  		bui.Str(`default values`)
   862  	}
   863  	return bui.Get()
   864  }
   865  
   866  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   867  // encoding.
   868  func (self StructInsert) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   869  
   870  // Implement the `fmt.Stringer` interface for debug purposes.
   871  func (self StructInsert) String() string { return exprString(self) }
   872  
   873  /*
   874  Shortcut for creating `StructsInsert` from the given values.
   875  Workaround for lack of type inference in type literals.
   876  */
   877  func StructsInsertOf[A any](val ...A) StructsInsert[A] { return val }
   878  
   879  /*
   880  Variant of `StructInsert` that supports multiple structs. Generates a
   881  names-and-values clause suitable for bulk insertion. The inner type must be a
   882  struct. An empty slice generates an empty expression. See the examples.
   883  */
   884  type StructsInsert[A any] []A
   885  
   886  // Implement the `Expr` interface, making this a sub-expression.
   887  func (self StructsInsert[A]) AppendExpr(text []byte, args []any) ([]byte, []any) {
   888  	if len(self) == 0 {
   889  		return text, args
   890  	}
   891  
   892  	bui := Bui{text, args}
   893  
   894  	bui.Str(`(`)
   895  	bui.Str(TypeCols(typeOf((*A)(nil))))
   896  	bui.Str(`) values`)
   897  
   898  	for ind, val := range self {
   899  		if ind > 0 {
   900  			bui.Str(`, `)
   901  		}
   902  		bui.Str(`(`)
   903  		bui.Set(StructValues{val}.AppendExpr(bui.Get()))
   904  		bui.Str(`)`)
   905  	}
   906  
   907  	return bui.Get()
   908  }
   909  
   910  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   911  // encoding.
   912  func (self StructsInsert[_]) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   913  
   914  // Implement the `fmt.Stringer` interface for debug purposes.
   915  func (self StructsInsert[_]) String() string { return exprString(self) }
   916  
   917  /*
   918  Represents an SQL assignment clause suitable for "update set" operations. The
   919  inner value must be a struct. The resulting expression consists of
   920  comma-separated assignments with column names and values derived from the
   921  provided struct. See the example.
   922  
   923  Supports filtering. If the inner value implements `Sparse`, then not all fields
   924  are considered to be "present", which is useful for PATCH semantics. See the
   925  docs on `Sparse` and `Part`. If there are NO fields, panics with
   926  `ErrEmptyAssign`, which can be detected by user code via `errors.Is`.
   927  */
   928  type StructAssign [1]any
   929  
   930  // Implement the `Expr` interface, making this a sub-expression.
   931  func (self StructAssign) AppendExpr(text []byte, args []any) ([]byte, []any) {
   932  	bui := Bui{text, args}
   933  	iter := makeIter(self[0])
   934  
   935  	for iter.next() {
   936  		if !iter.first() {
   937  			bui.Str(`,`)
   938  		}
   939  		bui.Set(Assign{
   940  			Ident(FieldDbName(iter.field)),
   941  			iter.value.Interface(),
   942  		}.AppendExpr(bui.Get()))
   943  	}
   944  
   945  	if iter.empty() {
   946  		panic(ErrEmptyAssign)
   947  	}
   948  
   949  	return bui.Get()
   950  }
   951  
   952  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   953  // encoding.
   954  func (self StructAssign) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   955  
   956  // Implement the `fmt.Stringer` interface for debug purposes.
   957  func (self StructAssign) String() string { return exprString(self) }
   958  
   959  /*
   960  Wraps an arbitrary sub-expression, using `Cols{.Type}` to select specific
   961  columns from it. If `.Type` doesn't specify a set of columns, for example
   962  because it's not a struct type, then this uses the sub-expression as-is without
   963  wrapping. Counterpart to `SelectColsDeep`.
   964  */
   965  type SelectCols struct {
   966  	From Expr
   967  	Type any
   968  }
   969  
   970  // Implement the `Expr` interface, making this a sub-expression.
   971  func (self SelectCols) AppendExpr(text []byte, args []any) ([]byte, []any) {
   972  	// Type-to-string is nearly free due to caching.
   973  	return SelectString{self.From, Cols{self.Type}.String()}.AppendExpr(text, args)
   974  }
   975  
   976  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
   977  // encoding.
   978  func (self SelectCols) AppendTo(text []byte) []byte { return exprAppend(self, text) }
   979  
   980  // Implement the `fmt.Stringer` interface for debug purposes.
   981  func (self SelectCols) String() string { return exprString(self) }
   982  
   983  /*
   984  Wraps an arbitrary sub-expression, using `ColsDeep{.Type}` to select specific
   985  columns from it. If `.Type` doesn't specify a set of columns, for example
   986  because it's not a struct type, then this uses the sub-expression as-is without
   987  wrapping. Counterpart to `SelectCols`.
   988  */
   989  type SelectColsDeep struct {
   990  	From Expr
   991  	Type any
   992  }
   993  
   994  // Implement the `Expr` interface, making this a sub-expression.
   995  func (self SelectColsDeep) AppendExpr(text []byte, args []any) ([]byte, []any) {
   996  	// Type-to-string is nearly free due to caching.
   997  	return SelectString{self.From, ColsDeep{self.Type}.String()}.AppendExpr(text, args)
   998  }
   999  
  1000  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1001  // encoding.
  1002  func (self SelectColsDeep) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1003  
  1004  // Implement the `fmt.Stringer` interface for debug purposes.
  1005  func (self SelectColsDeep) String() string { return exprString(self) }
  1006  
  1007  /*
  1008  Represents an SQL expression "select .What from (.From) as _". Mostly an
  1009  internal tool for building other expression types. Used internally by `Cols`
  1010  and `ColsDeep`; see their docs and examples.
  1011  */
  1012  type SelectString struct {
  1013  	From Expr
  1014  	What string
  1015  }
  1016  
  1017  // Implement the `Expr` interface, making this a sub-expression.
  1018  func (self SelectString) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1019  	bui := Bui{text, args}
  1020  
  1021  	if self.What == `*` {
  1022  		bui.Expr(self.From)
  1023  		return bui.Get()
  1024  	}
  1025  
  1026  	if self.From != nil {
  1027  		bui.Str(`with _ as (`)
  1028  		bui.Expr(self.From)
  1029  		bui.Str(`)`)
  1030  	}
  1031  
  1032  	bui.Str(`select`)
  1033  	bui.Str(self.What)
  1034  
  1035  	if self.From != nil {
  1036  		bui.Str(`from _`)
  1037  	}
  1038  
  1039  	return bui.Get()
  1040  }
  1041  
  1042  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1043  // encoding.
  1044  func (self SelectString) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1045  
  1046  // Implement the `fmt.Stringer` interface for debug purposes.
  1047  func (self SelectString) String() string { return exprString(self) }
  1048  
  1049  /*
  1050  Combines an expression with a string prefix. If the expr is nil, this is a nop,
  1051  and the prefix is ignored. Mostly an internal tool for building other
  1052  expression types.
  1053  */
  1054  type Prefix struct {
  1055  	Prefix string
  1056  	Expr   Expr
  1057  }
  1058  
  1059  // Implement the `Expr` interface, making this a sub-expression.
  1060  func (self Prefix) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1061  	return Wrap{self.Prefix, self.Expr, ``}.AppendExpr(text, args)
  1062  }
  1063  
  1064  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1065  // encoding.
  1066  func (self Prefix) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1067  
  1068  // Implement the `fmt.Stringer` interface for debug purposes.
  1069  func (self Prefix) String() string { return exprString(self) }
  1070  
  1071  /*
  1072  Combines an expression with a string prefix and suffix. If the expr is nil, this
  1073  is a nop, and the prefix and suffix are ignored. Mostly an internal tool for
  1074  building other expression types.
  1075  */
  1076  type Wrap struct {
  1077  	Prefix string
  1078  	Expr   Expr
  1079  	Suffix string
  1080  }
  1081  
  1082  // Difference from `Trio`: if the expr is nil, nothing is appended.
  1083  // Implement the `Expr` interface, making this a sub-expression.
  1084  func (self Wrap) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1085  	bui := Bui{text, args}
  1086  
  1087  	if self.Expr != nil {
  1088  		bui.Str(self.Prefix)
  1089  		bui.Expr(self.Expr)
  1090  		bui.Str(self.Suffix)
  1091  	}
  1092  
  1093  	return bui.Get()
  1094  }
  1095  
  1096  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1097  // encoding.
  1098  func (self Wrap) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1099  
  1100  // Implement the `fmt.Stringer` interface for debug purposes.
  1101  func (self Wrap) String() string { return exprString(self) }
  1102  
  1103  /*
  1104  If the provided expression is not nil, prepends the keywords "order by" to it.
  1105  If the provided expression is nil, this is a nop.
  1106  */
  1107  type OrderBy [1]Expr
  1108  
  1109  // Implement the `Expr` interface, making this a sub-expression.
  1110  func (self OrderBy) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1111  	return Prefix{`order by`, self[0]}.AppendExpr(text, args)
  1112  }
  1113  
  1114  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1115  // encoding.
  1116  func (self OrderBy) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1117  
  1118  // Implement the `fmt.Stringer` interface for debug purposes.
  1119  func (self OrderBy) String() string { return exprString(self) }
  1120  
  1121  // Shortcut for simple "select * from A where B" expressions. See the examples.
  1122  type Select struct {
  1123  	From  Ident
  1124  	Where any
  1125  }
  1126  
  1127  // Implement the `Expr` interface, making this a sub-expression.
  1128  func (self Select) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1129  	bui := Bui{text, args}
  1130  
  1131  	bui.Str(`select * from`)
  1132  	bui.Set(self.From.AppendExpr(bui.Get()))
  1133  
  1134  	if self.Where != nil {
  1135  		bui.Str(`where`)
  1136  		bui.Set(And{self.Where}.AppendExpr(bui.Get()))
  1137  	}
  1138  
  1139  	return bui.Get()
  1140  }
  1141  
  1142  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1143  // encoding.
  1144  func (self Select) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1145  
  1146  // Implement the `fmt.Stringer` interface for debug purposes.
  1147  func (self Select) String() string { return exprString(self) }
  1148  
  1149  // Shortcut for simple `insert into A (B) values (C)` expressions.
  1150  // Also see `Insert` which appends `returning *`.
  1151  type InsertVoid struct {
  1152  	Into   Ident
  1153  	Fields any
  1154  }
  1155  
  1156  // Implement the `Expr` interface, making this a sub-expression.
  1157  func (self InsertVoid) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1158  	bui := Bui{text, args}
  1159  
  1160  	bui.Str(`insert into`)
  1161  	bui.Set(self.Into.AppendExpr(bui.Get()))
  1162  	bui.Set(StructInsert{self.Fields}.AppendExpr(bui.Get()))
  1163  
  1164  	return bui.Get()
  1165  }
  1166  
  1167  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1168  // encoding.
  1169  func (self InsertVoid) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1170  
  1171  // Implement the `fmt.Stringer` interface for debug purposes.
  1172  func (self InsertVoid) String() string { return exprString(self) }
  1173  
  1174  // Shortcut for simple `insert into A (B) values (C) returning *` expressions.
  1175  // See the examples. Also see `InsertVoid` which doesn't have `returning *`.
  1176  type Insert InsertVoid
  1177  
  1178  // Implement the `Expr` interface, making this a sub-expression.
  1179  func (self Insert) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1180  	text, args = InsertVoid(self).AppendExpr(text, args)
  1181  	text, args = ReturningAll{}.AppendExpr(text, args)
  1182  	return text, args
  1183  }
  1184  
  1185  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1186  // encoding.
  1187  func (self Insert) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1188  
  1189  // Implement the `fmt.Stringer` interface for debug purposes.
  1190  func (self Insert) String() string { return exprString(self) }
  1191  
  1192  // Shortcut for simple `update A set B where C` expressions.
  1193  // Also see `Update` which appends `returning *`.
  1194  type UpdateVoid struct {
  1195  	What   Ident
  1196  	Where  any
  1197  	Fields any
  1198  }
  1199  
  1200  // Implement the `Expr` interface, making this a sub-expression.
  1201  func (self UpdateVoid) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1202  	bui := Bui{text, args}
  1203  
  1204  	bui.Str(`update`)
  1205  	bui.Set(self.What.AppendExpr(bui.Get()))
  1206  
  1207  	if self.Fields != nil {
  1208  		bui.Str(`set`)
  1209  		bui.Set(StructAssign{self.Fields}.AppendExpr(bui.Get()))
  1210  	}
  1211  
  1212  	// TODO: when empty, panic with `ErrEmptyAssign` (rename to `ErrEmpty`).
  1213  	if self.Where != nil {
  1214  		bui.Str(`where`)
  1215  		bui.Set(Cond{`null`, `and`, self.Where}.AppendExpr(bui.Get()))
  1216  	}
  1217  
  1218  	return bui.Get()
  1219  }
  1220  
  1221  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1222  // encoding.
  1223  func (self UpdateVoid) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1224  
  1225  // Implement the `fmt.Stringer` interface for debug purposes.
  1226  func (self UpdateVoid) String() string { return exprString(self) }
  1227  
  1228  // Shortcut for simple `update A set B where C returning *` expressions.
  1229  // See the examples. Also see `UpdateVoid` which doesn't have `returning *`.
  1230  type Update UpdateVoid
  1231  
  1232  // Implement the `Expr` interface, making this a sub-expression.
  1233  func (self Update) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1234  	text, args = UpdateVoid(self).AppendExpr(text, args)
  1235  	text, args = ReturningAll{}.AppendExpr(text, args)
  1236  	return text, args
  1237  }
  1238  
  1239  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1240  // encoding.
  1241  func (self Update) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1242  
  1243  // Implement the `fmt.Stringer` interface for debug purposes.
  1244  func (self Update) String() string { return exprString(self) }
  1245  
  1246  // Shortcut for simple `delete from A where B` expressions.
  1247  // Also see `Delete` which appends `returning *`.
  1248  type DeleteVoid struct {
  1249  	From  Ident
  1250  	Where any
  1251  }
  1252  
  1253  // Implement the `Expr` interface, making this a sub-expression.
  1254  func (self DeleteVoid) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1255  	bui := Bui{text, args}
  1256  
  1257  	bui.Str(`delete from`)
  1258  	bui.Set(self.From.AppendExpr(bui.Get()))
  1259  
  1260  	// TODO: when empty, panic with `ErrEmptyAssign` (rename to `ErrEmpty`).
  1261  	bui.Str(`where`)
  1262  	bui.Set(Cond{`null`, `and`, self.Where}.AppendExpr(bui.Get()))
  1263  
  1264  	return bui.Get()
  1265  }
  1266  
  1267  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1268  // encoding.
  1269  func (self DeleteVoid) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1270  
  1271  // Implement the `fmt.Stringer` interface for debug purposes.
  1272  func (self DeleteVoid) String() string { return exprString(self) }
  1273  
  1274  // Shortcut for simple `delete from A where B returning *` expressions.
  1275  // See the examples. Also see `DeleteVoid` which doesn't have `returning *`.
  1276  type Delete DeleteVoid
  1277  
  1278  // Implement the `Expr` interface, making this a sub-expression.
  1279  func (self Delete) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1280  	text, args = DeleteVoid(self).AppendExpr(text, args)
  1281  	text, args = ReturningAll{}.AppendExpr(text, args)
  1282  	return text, args
  1283  }
  1284  
  1285  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1286  // encoding.
  1287  func (self Delete) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1288  
  1289  // Implement the `fmt.Stringer` interface for debug purposes.
  1290  func (self Delete) String() string { return exprString(self) }
  1291  
  1292  /*
  1293  Represents an SQL upsert query like this:
  1294  
  1295  	insert into some_table
  1296  		(key_0, key_1, col_2, col_3)
  1297  	values
  1298  		($1, $2, $3, $4)
  1299  	on conflict (key_0, key_1)
  1300  	do update set
  1301  		key_0 = excluded.key_0,
  1302  		key_1 = excluded.key_1,
  1303  		col_2 = excluded.col_2,
  1304  		col_3 = excluded.col_3
  1305  
  1306  Notes:
  1307  
  1308  	* `.Keys` must be a struct.
  1309  	* `.Keys` supports `Sparse` and may be empty.
  1310  	* When `.Keys` is empty, this is equivalent to the `Insert` type.
  1311  	* `.Cols` must be a struct.
  1312  	* `.Cols` supports `Sparse` and may be empty.
  1313  	* `.Keys` provides names and values for key columns which participate
  1314  		in the `on conflict` clause.
  1315  	* `.Cols` provides names and values for other columns.
  1316  
  1317  Also see `Upsert` which appends the `returning *` clause.
  1318  */
  1319  type UpsertVoid struct {
  1320  	What Ident
  1321  	Keys any
  1322  	Cols any
  1323  }
  1324  
  1325  // Implement the `Expr` interface, making this a sub-expression.
  1326  func (self UpsertVoid) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1327  	keysIter := makeIter(self.Keys)
  1328  	if !keysIter.has() {
  1329  		return InsertVoid{self.What, self.Cols}.AppendExpr(text, args)
  1330  	}
  1331  
  1332  	bui := Bui{text, args}
  1333  	colsIter := makeIter(self.Cols)
  1334  
  1335  	bui.Str(`insert into`)
  1336  	bui.Set(self.What.AppendExpr(bui.Get()))
  1337  
  1338  	// Set of column names for insertion.
  1339  	// Adapted from `StructInsert`.
  1340  	{
  1341  		bui.Str(`(`)
  1342  		iterAppendCols(&bui, keysIter, false)
  1343  		iterAppendCols(&bui, colsIter, true)
  1344  		bui.Str(`)`)
  1345  	}
  1346  
  1347  	bui.Str(`values`)
  1348  
  1349  	// Set of column values for insertion.
  1350  	// Adapted from `StructInsert`.
  1351  	{
  1352  		bui.Str(`(`)
  1353  		iterAppendVals(&bui, keysIter, false)
  1354  		iterAppendVals(&bui, colsIter, true)
  1355  		bui.Str(`)`)
  1356  	}
  1357  
  1358  	// Conflict clause with key column names.
  1359  	{
  1360  		bui.Str(`on conflict (`)
  1361  		iterAppendCols(&bui, keysIter, false)
  1362  		bui.Str(`)`)
  1363  	}
  1364  
  1365  	// Assignment clauses for all columns.
  1366  	{
  1367  		bui.Str(`do update set`)
  1368  		upsertAppendAssignExcluded(&bui, keysIter, false)
  1369  		upsertAppendAssignExcluded(&bui, colsIter, true)
  1370  	}
  1371  
  1372  	return bui.Get()
  1373  }
  1374  
  1375  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1376  // encoding.
  1377  func (self UpsertVoid) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1378  
  1379  // Implement the `fmt.Stringer` interface for debug purposes.
  1380  func (self UpsertVoid) String() string { return exprString(self) }
  1381  
  1382  // Same as `UpsertVoid` but also appends `returning *`.
  1383  type Upsert UpsertVoid
  1384  
  1385  // Implement the `Expr` interface, making this a sub-expression.
  1386  func (self Upsert) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1387  	text, args = UpsertVoid(self).AppendExpr(text, args)
  1388  	text, args = ReturningAll{}.AppendExpr(text, args)
  1389  	return text, args
  1390  }
  1391  
  1392  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1393  // encoding.
  1394  func (self Upsert) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1395  
  1396  // Implement the `fmt.Stringer` interface for debug purposes.
  1397  func (self Upsert) String() string { return exprString(self) }
  1398  
  1399  func iterAppendCols(bui *Bui, iter iter, continued bool) {
  1400  	for iter.next() {
  1401  		if continued || !iter.first() {
  1402  			bui.Str(`,`)
  1403  		}
  1404  		Ident(FieldDbName(iter.field)).BuiAppend(bui)
  1405  	}
  1406  }
  1407  
  1408  func iterAppendVals(bui *Bui, iter iter, continued bool) {
  1409  	for iter.next() {
  1410  		if continued || !iter.first() {
  1411  			bui.Str(`,`)
  1412  		}
  1413  		bui.SubAny(iter.value.Interface())
  1414  	}
  1415  }
  1416  
  1417  func upsertAppendAssignExcluded(bui *Bui, iter iter, continued bool) {
  1418  	for iter.next() {
  1419  		if continued || !iter.first() {
  1420  			bui.Str(`,`)
  1421  		}
  1422  
  1423  		name := Ident(FieldDbName(iter.field))
  1424  		name.BuiAppend(bui)
  1425  		bui.Str(` = excluded.`)
  1426  		name.BuiAppend(bui)
  1427  	}
  1428  }
  1429  
  1430  /*
  1431  Shortcut for selecting `count(*)` from an arbitrary sub-expression. Equivalent
  1432  to `s.SelectString{expr, "count(*)"}`.
  1433  */
  1434  type SelectCount [1]Expr
  1435  
  1436  // Implement the `Expr` interface, making this a sub-expression.
  1437  func (self SelectCount) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1438  	return SelectString{self[0], `count(*)`}.AppendExpr(text, args)
  1439  }
  1440  
  1441  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1442  // encoding.
  1443  func (self SelectCount) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1444  
  1445  // Implement the `fmt.Stringer` interface for debug purposes.
  1446  func (self SelectCount) String() string { return exprString(self) }
  1447  
  1448  /*
  1449  Represents an SQL function call expression. The text prefix is optional and
  1450  usually represents a function name. The args must be either nil, a single
  1451  `Expr`, or a slice of arbitrary sub-expressions or arguments.
  1452  */
  1453  type Call struct {
  1454  	Text string
  1455  	Args any
  1456  }
  1457  
  1458  // Implement the `Expr` interface, making this a sub-expression.
  1459  func (self Call) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1460  	bui := Bui{text, args}
  1461  	bui.Str(self.Text)
  1462  
  1463  	// TODO: when `self.Args` is a single expression, consider always additionally
  1464  	// parenthesizing it. `Comma` doesn't do that.
  1465  	bui.Str(`(`)
  1466  	bui.Set(Comma{self.Args}.AppendExpr(bui.Get()))
  1467  	bui.Str(`)`)
  1468  
  1469  	return bui.Get()
  1470  }
  1471  
  1472  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1473  // encoding.
  1474  func (self Call) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1475  
  1476  // Implement the `fmt.Stringer` interface for debug purposes.
  1477  func (self Call) String() string { return exprString(self) }
  1478  
  1479  /*
  1480  Represents the Postgres window function `row_number`:
  1481  
  1482  	RowNumberOver{}
  1483  	-> `0`
  1484  
  1485  	RowNumberOver{Ords{OrdDesc{Ident(`some_col`)}}}
  1486  	-> `row_number() over (order by "col" desc)`
  1487  
  1488  When the inner expression is nil and the output is `0`, the Postgres query
  1489  planner should be able to optimize it away.
  1490  */
  1491  type RowNumberOver [1]Expr
  1492  
  1493  // Implement the `Expr` interface, making this a sub-expression.
  1494  func (self RowNumberOver) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1495  	if self[0] == nil {
  1496  		return appendMaybeSpaced(text, `0`), args
  1497  	}
  1498  
  1499  	bui := Bui{text, args}
  1500  	bui.Str(`row_number() over (`)
  1501  	bui.Expr(self[0])
  1502  	bui.Str(`)`)
  1503  
  1504  	return bui.Get()
  1505  }
  1506  
  1507  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1508  // encoding.
  1509  func (self RowNumberOver) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1510  
  1511  // Implement the `fmt.Stringer` interface for debug purposes.
  1512  func (self RowNumberOver) String() string { return exprString(self) }
  1513  
  1514  /*
  1515  Short for "string query". Represents an SQL query with parameters such as "$1"
  1516  or ":param_name". Args may be a list of ordinal args (via `List`), a dictionary
  1517  (via `Dict`), a struct (via `StructDict`), or an arbitrary user-defined
  1518  implementation conforming to the interface. When generating the final
  1519  expression, parameters are converted to Postgres-style ordinal parameters such
  1520  as "$1".
  1521  
  1522  Expressions/queries are composable. Named arguments that implement the `Expr`
  1523  interface do not become ordinal parameters/arguments. Instead, they're treated
  1524  as sub-expressions, and may include arbitrary text with their own arguments.
  1525  Parameter collisions between outer and inner queries are completely avoided.
  1526  
  1527  Uses `Preparse` to avoid redundant parsing. Each source string is parsed only
  1528  once, and the resulting `Prep` is cached. As a result, `StrQ` has little
  1529  measurable overhead.
  1530  */
  1531  type StrQ struct {
  1532  	Text string
  1533  	Args ArgDict
  1534  }
  1535  
  1536  // Implement the `Expr` interface, making this a sub-expression.
  1537  func (self StrQ) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1538  	return Preparse(self.Text).AppendParamExpr(text, args, self.Args)
  1539  }
  1540  
  1541  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1542  // encoding.
  1543  func (self StrQ) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1544  
  1545  // Implement the `fmt.Stringer` interface for debug purposes.
  1546  func (self StrQ) String() string { return exprString(self) }
  1547  
  1548  /*
  1549  Short for "preparsed" or "prepared". Partially parsed representation of
  1550  parametrized SQL expressions, suited for efficiently building SQL queries by
  1551  providing arguments. Supports both ordinal and named parameters/arguments. To
  1552  avoid redundant work, this should be parsed and cached only once for each SQL
  1553  query; this deduplication is done by `Preparse` which is also used internally
  1554  by `StrQ`. User code doesn't need to construct this.
  1555  */
  1556  type Prep struct {
  1557  	Source    string
  1558  	Tokens    []Token
  1559  	HasParams bool
  1560  }
  1561  
  1562  // Parses `self.Source`, modifying the receiver. Panics if parsing fails.
  1563  func (self *Prep) Parse() {
  1564  	/**
  1565  	This has all sorts of avoidable allocations, and could be significantly better
  1566  	optimized. However, parsing is ALWAYS slow. We cache the resulting `Prep`
  1567  	for each source string to avoid redundant parsing.
  1568  	*/
  1569  
  1570  	src := strings.TrimSpace(self.Source)
  1571  	tok := Tokenizer{Source: src, Transform: trimWhitespaceAndComments}
  1572  
  1573  	// Suboptimal, could be avoided.
  1574  	buf := make([]byte, 0, 128)
  1575  
  1576  	flush := func() {
  1577  		if len(buf) > 0 {
  1578  			// Suboptimal. It would be better to reslice the source string instead of
  1579  			// allocating new strings.
  1580  			self.Tokens = append(self.Tokens, Token{string(buf), TokenTypeText})
  1581  		}
  1582  		buf = buf[:0]
  1583  	}
  1584  
  1585  	for {
  1586  		tok := tok.Next()
  1587  		if tok.IsInvalid() {
  1588  			break
  1589  		}
  1590  
  1591  		switch tok.Type {
  1592  		case TokenTypeOrdinalParam, TokenTypeNamedParam:
  1593  			flush()
  1594  			self.Tokens = append(self.Tokens, tok)
  1595  			self.HasParams = true
  1596  
  1597  		default:
  1598  			buf = append(buf, tok.Text...)
  1599  		}
  1600  	}
  1601  
  1602  	flush()
  1603  }
  1604  
  1605  // Implement the `ParamExpr` interface. Builds the expression by using the
  1606  // provided named args. Used internally by `StrQ`.
  1607  func (self Prep) AppendParamExpr(text []byte, args []any, dict ArgDict) ([]byte, []any) {
  1608  	if !self.HasParams {
  1609  		return self.appendUnparametrized(text, args, dict)
  1610  	}
  1611  	return self.appendParametrized(text, args, dict)
  1612  }
  1613  
  1614  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1615  // encoding.
  1616  func (self Prep) AppendTo(text []byte) []byte {
  1617  	return Str(self.Source).AppendTo(text)
  1618  }
  1619  
  1620  // Implement the `fmt.Stringer` interface for debug purposes.
  1621  func (self Prep) String() string { return self.Source }
  1622  
  1623  func (self Prep) appendUnparametrized(text []byte, args []any, dict ArgDict) ([]byte, []any) {
  1624  	src := self.Source
  1625  	if !isNil(dict) {
  1626  		panic(errUnexpectedArgs(fmt.Sprintf(`non-parametrized expression %q`, src), dict))
  1627  	}
  1628  	return Str(src).AppendExpr(text, args)
  1629  }
  1630  
  1631  func (self Prep) appendParametrized(text []byte, args []any, dict ArgDict) ([]byte, []any) {
  1632  	if dict == nil {
  1633  		panic(errMissingArgs(fmt.Sprintf(`parametrized expression %q`, self.Source)))
  1634  	}
  1635  
  1636  	bui := Bui{text, args}
  1637  	bui.Grow(len(self.Source), dict.Len())
  1638  
  1639  	tracker := getArgTracker()
  1640  	defer tracker.put()
  1641  
  1642  	for _, tok := range self.Tokens {
  1643  		switch tok.Type {
  1644  		case TokenTypeOrdinalParam:
  1645  			// Parsing the token here is slightly suboptimal, we should preparse numbers.
  1646  			appendOrdinal(&bui, dict, tracker, tok.ParseOrdinalParam())
  1647  
  1648  		case TokenTypeNamedParam:
  1649  			appendNamed(&bui, dict, tracker, tok.ParseNamedParam())
  1650  
  1651  		default:
  1652  			bui.Text = append(bui.Text, tok.Text...)
  1653  		}
  1654  	}
  1655  
  1656  	if ValidateUnusedArguments {
  1657  		tracker.validate(dict)
  1658  	}
  1659  	return bui.Get()
  1660  }
  1661  
  1662  /**
  1663  The implementation of both `appendOrdinal` and `appendNamed` should be roughly
  1664  equivalent to `bui.Any(arg)`, but more efficient for parameters that occur more
  1665  than once. We map each SOURCE PARAMETER to exactly one TARGET PARAMETER and one
  1666  ARGUMENT. If it was simply appended via `bui.Any(arg)`, then every occurrence
  1667  would generate another argument.
  1668  
  1669  The cost of keeping track of found parameters is amortized by recycling them in
  1670  a pool. It saves us the cost of redundant encoding of those arguments, which is
  1671  potentially much larger, for example when an argument is a huge array.
  1672  
  1673  Keeping track of found PARAMETERS also allows us to validate that all ARGUMENTS
  1674  are used.
  1675  */
  1676  func appendOrdinal(bui *Bui, args ArgDict, tracker *argTracker, key OrdinalParam) {
  1677  	arg, ok := args.GotOrdinal(key.Index())
  1678  	if !ok {
  1679  		panic(errMissingOrdinal(key))
  1680  	}
  1681  
  1682  	impl, _ := arg.(Expr)
  1683  	if impl != nil {
  1684  		// Allows validation of used args.
  1685  		tracker.SetOrdinal(key, 0)
  1686  		bui.Expr(impl)
  1687  		return
  1688  	}
  1689  
  1690  	ord, ok := tracker.GotOrdinal(key)
  1691  	if ok {
  1692  		bui.OrphanParam(ord)
  1693  		return
  1694  	}
  1695  
  1696  	ord = bui.OrphanArg(arg)
  1697  	bui.OrphanParam(ord)
  1698  	tracker.SetOrdinal(key, ord)
  1699  }
  1700  
  1701  func appendNamed(bui *Bui, args ArgDict, tracker *argTracker, key NamedParam) {
  1702  	arg, ok := args.GotNamed(key.Key())
  1703  	if !ok {
  1704  		panic(errMissingNamed(key))
  1705  	}
  1706  
  1707  	impl, _ := arg.(Expr)
  1708  	if impl != nil {
  1709  		// Allows validation of used args.
  1710  		tracker.SetNamed(key, 0)
  1711  		bui.Expr(impl)
  1712  		return
  1713  	}
  1714  
  1715  	ord, ok := tracker.GotNamed(key)
  1716  	if ok {
  1717  		bui.OrphanParam(ord)
  1718  		return
  1719  	}
  1720  
  1721  	ord = bui.OrphanArg(arg)
  1722  	bui.OrphanParam(ord)
  1723  	tracker.SetNamed(key, ord)
  1724  }
  1725  
  1726  // Represents an ordinal parameter such as "$1". Mostly for internal use.
  1727  type OrdinalParam int
  1728  
  1729  // Implement the `Expr` interface, making this a sub-expression.
  1730  func (self OrdinalParam) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1731  	return self.AppendTo(text), args
  1732  }
  1733  
  1734  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1735  // encoding.
  1736  func (self OrdinalParam) AppendTo(text []byte) []byte {
  1737  	text = append(text, ordinalParamPrefix)
  1738  	text = strconv.AppendInt(text, int64(self), 10)
  1739  	return text
  1740  }
  1741  
  1742  // Implement the `fmt.Stringer` interface for debug purposes.
  1743  func (self OrdinalParam) String() string { return AppenderString(&self) }
  1744  
  1745  // Returns the corresponding Go index (starts at zero).
  1746  func (self OrdinalParam) Index() int { return int(self) - 1 }
  1747  
  1748  // Inverse of `OrdinalParam.Index`: increments by 1, converting index to param.
  1749  func (self OrdinalParam) FromIndex() OrdinalParam { return self + 1 }
  1750  
  1751  // Represents a named parameter such as ":blah". Mostly for internal use.
  1752  type NamedParam string
  1753  
  1754  // Implement the `Expr` interface, making this a sub-expression.
  1755  func (self NamedParam) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1756  	return self.AppendTo(text), args
  1757  }
  1758  
  1759  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1760  // encoding.
  1761  func (self NamedParam) AppendTo(text []byte) []byte {
  1762  	text = append(text, namedParamPrefix)
  1763  	text = append(text, self...)
  1764  	return text
  1765  }
  1766  
  1767  // Implement the `fmt.Stringer` interface for debug purposes.
  1768  func (self NamedParam) String() string { return AppenderString(&self) }
  1769  
  1770  // Converts to the corresponding dictionary key, which is a plain string. This
  1771  // is a free cast, used to increase code clarity.
  1772  func (self NamedParam) Key() string { return string(self) }
  1773  
  1774  /*
  1775  Represents SQL expression "limit N" with an arbitrary argument or
  1776  sub-expression. Implements `Expr`:
  1777  
  1778  	* If nil  -> append nothing.
  1779  	* If expr -> append "limit (<sub-expression>)".
  1780  	* If val  -> append "limit $N" with the corresponding argument.
  1781  */
  1782  type Limit [1]any
  1783  
  1784  // Implement the `Expr` interface, making this a sub-expression.
  1785  func (self Limit) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1786  	return appendPrefixSub(text, args, `limit`, self[0])
  1787  }
  1788  
  1789  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1790  // encoding.
  1791  func (self Limit) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1792  
  1793  // Implement the `fmt.Stringer` interface for debug purposes.
  1794  func (self Limit) String() string { return AppenderString(&self) }
  1795  
  1796  /*
  1797  Represents SQL expression "offset N" with an arbitrary sub-expression.
  1798  Implements `Expr`:
  1799  
  1800  	* If nil  -> append nothing.
  1801  	* If expr -> append "offset (<sub-expression>)".
  1802  	* If val  -> append "offset $N" with the corresponding argument.
  1803  */
  1804  type Offset [1]any
  1805  
  1806  // Implement the `Expr` interface, making this a sub-expression.
  1807  func (self Offset) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1808  	return appendPrefixSub(text, args, `offset`, self[0])
  1809  }
  1810  
  1811  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1812  // encoding.
  1813  func (self Offset) AppendTo(text []byte) []byte { return exprAppend(self, text) }
  1814  
  1815  // Implement the `fmt.Stringer` interface for debug purposes.
  1816  func (self Offset) String() string { return AppenderString(&self) }
  1817  
  1818  /*
  1819  Represents SQL expression "limit N" with a number. Implements `Expr`:
  1820  
  1821  	* If 0      -> append nothing.
  1822  	* Otherwise -> append literal "limit <N>" such as "limit 1".
  1823  
  1824  Because this is uint64, you can safely and correctly decode arbitrary user input
  1825  into this value, for example into a struct field of this type.
  1826  */
  1827  type LimitUint uint64
  1828  
  1829  // Implement the `Expr` interface, making this a sub-expression.
  1830  func (self LimitUint) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1831  	return self.AppendTo(text), args
  1832  }
  1833  
  1834  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1835  // encoding.
  1836  func (self LimitUint) AppendTo(text []byte) []byte {
  1837  	return appendIntWith(text, `limit`, int64(self))
  1838  }
  1839  
  1840  // Implement the `fmt.Stringer` interface for debug purposes.
  1841  func (self LimitUint) String() string { return AppenderString(&self) }
  1842  
  1843  /*
  1844  Represents SQL expression "offset N" with a number. Implements `Expr`:
  1845  
  1846  	* If 0      -> append nothing.
  1847  	* Otherwise -> append literal "offset <N>" such as "offset 1".
  1848  
  1849  Because this is uint64, you can safely and correctly decode arbitrary user input
  1850  into this value, for example into a struct field of this type.
  1851  */
  1852  type OffsetUint uint64
  1853  
  1854  // Implement the `Expr` interface, making this a sub-expression.
  1855  func (self OffsetUint) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1856  	return self.AppendTo(text), args
  1857  }
  1858  
  1859  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1860  // encoding.
  1861  func (self OffsetUint) AppendTo(text []byte) []byte {
  1862  	return appendIntWith(text, `offset`, int64(self))
  1863  }
  1864  
  1865  // Implement the `fmt.Stringer` interface for debug purposes.
  1866  func (self OffsetUint) String() string { return AppenderString(&self) }
  1867  
  1868  // Represents the Postgres `returning *` clause.
  1869  type ReturningAll struct{}
  1870  
  1871  // Implement the `Expr` interface, making this a sub-expression.
  1872  func (self ReturningAll) AppendExpr(text []byte, args []any) ([]byte, []any) {
  1873  	return self.AppendTo(text), args
  1874  }
  1875  
  1876  // Implement the `AppenderTo` interface, sometimes allowing more efficient text
  1877  // encoding.
  1878  func (self ReturningAll) AppendTo(text []byte) []byte {
  1879  	return appendMaybeSpaced(text, self.String())
  1880  }
  1881  
  1882  // Implement the `fmt.Stringer` interface for debug purposes.
  1883  func (ReturningAll) String() string { return `returning *` }