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

     1  package sqlb
     2  
     3  import (
     4  	"fmt"
     5  	r "reflect"
     6  	"testing"
     7  	"time"
     8  )
     9  
    10  func TestReify(t *testing.T) {
    11  	t.Run(`nil`, func(t *testing.T) {
    12  		text, args := Reify(nil)
    13  		eq(t, ``, text)
    14  		eq(t, list(nil), args)
    15  	})
    16  
    17  	t.Run(`empty`, func(t *testing.T) {
    18  		text, args := Reify(rei(``))
    19  		eq(t, ``, text)
    20  		eq(t, list(nil), args)
    21  	})
    22  
    23  	t.Run(`non-empty`, func(t *testing.T) {
    24  		text, args := Reify(rei(`select A from B where C`, 10, 20, 30))
    25  		eq(t, `select A from B where C`, text)
    26  		eq(t, list{10, 20, 30}, args)
    27  	})
    28  
    29  	t.Run(`multiple`, func(t *testing.T) {
    30  		text, args := Reify(
    31  			nil,
    32  			rei(`one`, 10),
    33  			nil,
    34  			rei(`two`, 20),
    35  			nil,
    36  		)
    37  		eq(t, `one two`, text)
    38  		eq(t, list{10, 20}, args)
    39  	})
    40  }
    41  
    42  func TestStr(t *testing.T) {
    43  	testExpr(t, rei(``), Str(``))
    44  	testExpr(t, rei(`one`), Str(`one`))
    45  
    46  	testExprs(t, rei(``))
    47  	testExprs(t, rei(``), Str(``))
    48  	testExprs(t, rei(`one`), Str(`one`))
    49  	testExprs(t, rei(`one_two`), Str(`one_two`))
    50  	testExprs(t, rei(`one_two three_four`), Str(`one_two`), Str(`three_four`))
    51  }
    52  
    53  func TestIdent(t *testing.T) {
    54  	testExpr(t, rei(`""`), Ident(``))
    55  	testExpr(t, rei(`" "`), Ident(` `))
    56  	testExpr(t, rei(`"one.two"`), Ident(`one.two`))
    57  	testExpr(t, rei(`"one.two.three"`), Ident(`one.two.three`))
    58  
    59  	testExprs(t, rei(``))
    60  	testExprs(t, rei(`""`), Ident(``))
    61  	testExprs(t, rei(`"" ""`), Ident(``), Ident(``))
    62  	testExprs(t, rei(`"one" ""`), Ident(`one`), Ident(``))
    63  	testExprs(t, rei(`"" "two"`), Ident(``), Ident(`two`))
    64  	testExprs(t, rei(`"one" "two"`), Ident(`one`), Ident(`two`))
    65  }
    66  
    67  func TestIdentifier(t *testing.T) {
    68  	testExpr(t, rei(``), Identifier(nil))
    69  	testExpr(t, rei(``), Identifier{})
    70  	testExpr(t, rei(`""`), Identifier{``})
    71  	testExpr(t, rei(`"one"`), Identifier{`one`})
    72  	testExpr(t, rei(`"one".""`), Identifier{`one`, ``})
    73  	testExpr(t, rei(`""."two"`), Identifier{``, `two`})
    74  	testExpr(t, rei(`"one"."two"`), Identifier{`one`, `two`})
    75  	testExpr(t, rei(`"one".""."three"`), Identifier{`one`, ``, `three`})
    76  	testExpr(t, rei(`"one"."two"."three"`), Identifier{`one`, `two`, `three`})
    77  
    78  	testExprs(
    79  		t,
    80  		rei(`"one" "two"."three"`),
    81  		Identifier(nil),
    82  		Identifier{},
    83  		Identifier{`one`},
    84  		Identifier{`two`, `three`},
    85  	)
    86  }
    87  
    88  func TestPath(t *testing.T) {
    89  	testExpr(t, rei(``), Path(nil))
    90  	testExpr(t, rei(``), Path{})
    91  	testExpr(t, rei(`""`), Path{``})
    92  	testExpr(t, rei(`"one"`), Path{`one`})
    93  	testExpr(t, rei(`("one").""`), Path{`one`, ``})
    94  	testExpr(t, rei(`("")."two"`), Path{``, `two`})
    95  	testExpr(t, rei(`("one")."two"`), Path{`one`, `two`})
    96  	testExpr(t, rei(`("one").""."three"`), Path{`one`, ``, `three`})
    97  	testExpr(t, rei(`("one")."two"."three"`), Path{`one`, `two`, `three`})
    98  
    99  	testExprs(
   100  		t,
   101  		rei(`"one" ("two")."three"`),
   102  		Path(nil),
   103  		Path{},
   104  		Path{`one`},
   105  		Path{`two`, `three`},
   106  	)
   107  }
   108  
   109  func TestPseudoPath(t *testing.T) {
   110  	testExpr(t, rei(``), PseudoPath(nil))
   111  	testExpr(t, rei(``), PseudoPath{})
   112  	testExpr(t, rei(`""`), PseudoPath{``})
   113  	testExpr(t, rei(`"one"`), PseudoPath{`one`})
   114  	testExpr(t, rei(`"one.two"`), PseudoPath{`one`, `two`})
   115  	testExpr(t, rei(`".."`), PseudoPath{``, ``, ``})
   116  	testExpr(t, rei(`".two."`), PseudoPath{``, `two`, ``})
   117  	testExpr(t, rei(`"one.two.three"`), PseudoPath{`one`, `two`, `three`})
   118  
   119  	testExprs(
   120  		t,
   121  		rei(`$1 "one.two.three" $2`, 10, 20),
   122  		PseudoPath(nil),
   123  		rei(`$1`, 10),
   124  		PseudoPath{`one`, `two`, `three`},
   125  		rei(`$2`, 20),
   126  	)
   127  }
   128  
   129  func TestAliasedPath(t *testing.T) {
   130  	testExpr(t, rei(``), AliasedPath(nil))
   131  	testExpr(t, rei(``), AliasedPath{})
   132  	testExpr(t, rei(`""`), AliasedPath{``})
   133  	testExpr(t, rei(`"one"`), AliasedPath{`one`})
   134  	testExpr(t, rei(`("one")."two" as "one.two"`), AliasedPath{`one`, `two`})
   135  	testExpr(t, rei(`("one")."two"."three" as "one.two.three"`), AliasedPath{`one`, `two`, `three`})
   136  
   137  	testExprs(
   138  		t,
   139  		rei(`$1 "one" ("one")."two"."three" as "one.two.three" $2`, 10, 20),
   140  		AliasedPath(nil),
   141  		rei(`$1`, 10),
   142  		AliasedPath{`one`},
   143  		AliasedPath{`one`, `two`, `three`},
   144  		rei(`$2`, 20),
   145  	)
   146  }
   147  
   148  func TestTable(t *testing.T) {
   149  	testExpr(t, rei(``), Table(nil))
   150  	testExpr(t, rei(``), Table{})
   151  	testExpr(t, rei(`table ""`), Table{``})
   152  	testExpr(t, rei(`table "one"`), Table{`one`})
   153  	testExpr(t, rei(`table "one"."two"`), Table{`one`, `two`})
   154  	testExpr(t, rei(`table ""."two"`), Table{``, `two`})
   155  	testExpr(t, rei(`table "one".""`), Table{`one`, ``})
   156  	testExpr(t, rei(`table "one"."two"."three"`), Table{`one`, `two`, `three`})
   157  
   158  	testExprs(
   159  		t,
   160  		rei(`$1 table "one" table "two" $2`, 10, 20),
   161  		rei(`$1`, 10),
   162  		Table{},
   163  		Table{`one`},
   164  		Table{},
   165  		Table{`two`},
   166  		Table{},
   167  		rei(`$2`, 20),
   168  	)
   169  }
   170  
   171  func TestExprs(t *testing.T) {
   172  	testExprs(t, rei(``))
   173  	testExprs(t, rei(``), Exprs{})
   174  	testExprs(t, rei(``), Exprs{nil})
   175  
   176  	testExprs(
   177  		t,
   178  		rei(`one two`, 10, 20),
   179  		Exprs{
   180  			nil,
   181  			rei(`one`, 10),
   182  			nil,
   183  			rei(`two`, 20),
   184  			nil,
   185  		},
   186  	)
   187  }
   188  
   189  func TestAny(t *testing.T) {
   190  	testExpr(t, rei(`any ($1)`, nil), Any{})
   191  	testExpr(t, rei(`any ($1)`, list{10, 20, 30}), Any{list{10, 20, 30}})
   192  	testExpr(t, rei(`any (one)`), Any{Str(`one`)})
   193  
   194  	testExprs(
   195  		t,
   196  		rei(`any ($1) any ($2)`, 10, 20),
   197  		Any{10},
   198  		Any{20},
   199  	)
   200  }
   201  
   202  func TestAssign(t *testing.T) {
   203  	testExpr(t, rei(`"" = $1`, nil), Assign{})
   204  	testExpr(t, rei(`"one" = $1`, nil), Assign{`one`, nil})
   205  	testExpr(t, rei(`"" = $1`, 10), Assign{``, 10})
   206  	testExpr(t, rei(`"one" = (two)`), Assign{`one`, Str(`two`)})
   207  
   208  	testExprs(
   209  		t,
   210  		rei(`"" = $1 "one" = $2 "two" = (three) "four" = $3`, nil, 10, 40),
   211  		Assign{},
   212  		Assign{`one`, 10},
   213  		Assign{`two`, Str(`three`)},
   214  		Assign{`four`, 40},
   215  	)
   216  }
   217  
   218  func TestEq(t *testing.T) {
   219  	testExpr(t, rei(`$1 is null`, nil), Eq{nil, nil})
   220  	testExpr(t, rei(`$1 is null`, 10), Eq{10, nil})
   221  	testExpr(t, rei(`$1 = $2`, nil, 10), Eq{nil, 10})
   222  	testExpr(t, rei(`$1 = $2`, true, false), Eq{true, false})
   223  	testExpr(t, rei(`$1 = $2`, 10, 20), Eq{10, 20})
   224  	testExpr(t, rei(`$1 = $2`, 10, []int{20}), Eq{10, []int{20}})
   225  	testExpr(t, rei(`$1 = $2`, []int{10}, 20), Eq{[]int{10}, 20})
   226  	testExpr(t, rei(`$1 = $2`, []int{10}, []int{20}), Eq{[]int{10}, []int{20}})
   227  	testExpr(t, rei(`(one) is null`), Eq{Str(`one`), nil})
   228  	testExpr(t, rei(`(one) = $1`, 10), Eq{Str(`one`), 10})
   229  	testExpr(t, rei(`$1 = (two)`, 10), Eq{10, Str(`two`)})
   230  	testExpr(t, rei(`(one) = (two)`), Eq{Str(`one`), Str(`two`)})
   231  
   232  	testExprs(
   233  		t,
   234  		rei(`$1 = $2 $3 = $4`, 10, 20, 30, 40),
   235  		Eq{10, 20},
   236  		Eq{30, 40},
   237  	)
   238  }
   239  
   240  func TestNeq(t *testing.T) {
   241  	testExpr(t, rei(`$1 is not null`, nil), Neq{nil, nil})
   242  	testExpr(t, rei(`$1 is not null`, 10), Neq{10, nil})
   243  	testExpr(t, rei(`$1 <> $2`, nil, 10), Neq{nil, 10})
   244  	testExpr(t, rei(`$1 <> $2`, true, false), Neq{true, false})
   245  	testExpr(t, rei(`$1 <> $2`, 10, 20), Neq{10, 20})
   246  	testExpr(t, rei(`$1 <> $2`, 10, []int{20}), Neq{10, []int{20}})
   247  	testExpr(t, rei(`$1 <> $2`, []int{10}, 20), Neq{[]int{10}, 20})
   248  	testExpr(t, rei(`$1 <> $2`, []int{10}, []int{20}), Neq{[]int{10}, []int{20}})
   249  	testExpr(t, rei(`(one) is not null`), Neq{Str(`one`), nil})
   250  	testExpr(t, rei(`(one) <> $1`, 10), Neq{Str(`one`), 10})
   251  	testExpr(t, rei(`$1 <> (two)`, 10), Neq{10, Str(`two`)})
   252  	testExpr(t, rei(`(one) <> (two)`), Neq{Str(`one`), Str(`two`)})
   253  
   254  	testExprs(
   255  		t,
   256  		rei(`$1 <> $2 $3 <> $4`, 10, 20, 30, 40),
   257  		Neq{10, 20},
   258  		Neq{30, 40},
   259  	)
   260  }
   261  
   262  func TestEqAny(t *testing.T) {
   263  	testExpr(t, rei(`$1 = any ($2)`, nil, nil), EqAny{})
   264  	testExpr(t, rei(`$1 = any ($2)`, 10, 20), EqAny{10, 20})
   265  	testExpr(t, rei(`(one) = any ($1)`, 20), EqAny{Str(`one`), 20})
   266  	testExpr(t, rei(`$1 = any (two)`, 10), EqAny{10, Str(`two`)})
   267  	testExpr(t, rei(`(one) = any (two)`), EqAny{Str(`one`), Str(`two`)})
   268  
   269  	testExprs(
   270  		t,
   271  		rei(`$1 = any ($2) $3 = any ($4)`, 10, 20, 30, 40),
   272  		EqAny{10, 20},
   273  		EqAny{30, 40},
   274  	)
   275  }
   276  
   277  func TestNeqAny(t *testing.T) {
   278  	testExpr(t, rei(`$1 <> any ($2)`, nil, nil), NeqAny{})
   279  	testExpr(t, rei(`$1 <> any ($2)`, 10, 20), NeqAny{10, 20})
   280  	testExpr(t, rei(`(one) <> any ($1)`, 20), NeqAny{Str(`one`), 20})
   281  	testExpr(t, rei(`$1 <> any (two)`, 10), NeqAny{10, Str(`two`)})
   282  	testExpr(t, rei(`(one) <> any (two)`), NeqAny{Str(`one`), Str(`two`)})
   283  
   284  	testExprs(
   285  		t,
   286  		rei(`$1 <> any ($2) $3 <> any ($4)`, 10, 20, 30, 40),
   287  		NeqAny{10, 20},
   288  		NeqAny{30, 40},
   289  	)
   290  }
   291  
   292  func TestNot(t *testing.T) {
   293  	testExpr(t, rei(`not $1`, nil), Not{})
   294  	testExpr(t, rei(`not $1`, 10), Not{10})
   295  	testExpr(t, rei(`not ()`), Not{Str(``)})
   296  	testExpr(t, rei(`not (one)`), Not{Str(`one`)})
   297  
   298  	testExprs(
   299  		t,
   300  		rei(`not $1 not $2`, nil, nil),
   301  		Not{},
   302  		Not{},
   303  	)
   304  
   305  	testExprs(
   306  		t,
   307  		rei(`not $1 not (two) not $2`, 10, 20),
   308  		Not{10},
   309  		Not{Str(`two`)},
   310  		Not{20},
   311  	)
   312  }
   313  
   314  func TestSeq(t *testing.T) {
   315  	testExpr(t, rei(``), Seq{})
   316  	testExpr(t, rei(`empty`), Seq{Empty: `empty`})
   317  	testExpr(t, rei(`empty`), Seq{`empty`, `delim`, list(nil)})
   318  	testExpr(t, rei(`empty`), Seq{`empty`, `delim`, list{}})
   319  	testExpr(t, rei(`$1`, nil), Seq{`empty`, `delim`, list{nil}})
   320  	testExpr(t, rei(`$1`, 10), Seq{`empty`, `delim`, list{10}})
   321  	testExpr(t, rei(`one`), Seq{Val: Str(`one`)})
   322  	testExpr(t, rei(`one`, 10), Seq{Val: rei(`one`, 10)})
   323  
   324  	testExpr(
   325  		t,
   326  		rei(`$1 delim $2`, 10, 20),
   327  		Seq{`empty`, `delim`, list{10, 20}},
   328  	)
   329  
   330  	testExpr(
   331  		t,
   332  		rei(`$1 delim $2 delim $3`, 10, 20, 30),
   333  		Seq{`empty`, `delim`, list{10, 20, 30}},
   334  	)
   335  
   336  	testExpr(
   337  		t,
   338  		rei(`(one) delim $1 delim (two)`, 10),
   339  		Seq{`empty`, `delim`, list{Str(`one`), 10, Str(`two`)}},
   340  	)
   341  
   342  	testExprs(
   343  		t,
   344  		rei(`one two`),
   345  		Str(`one`),
   346  		Seq{},
   347  		Str(`two`),
   348  	)
   349  
   350  	testExprs(
   351  		t,
   352  		rei(`one empty two`),
   353  		Str(`one`),
   354  		Seq{`empty`, ``, nil},
   355  		Str(`two`),
   356  	)
   357  
   358  	testExprs(
   359  		t,
   360  		rei(`one $1 two`, 10, 20),
   361  		Str(`one`),
   362  		Seq{`empty`, `delim`, list{10}},
   363  		rei(`two`, 20),
   364  	)
   365  }
   366  
   367  func TestComma(t *testing.T) {
   368  	testExpr(t, rei(``), Comma{})
   369  	testExpr(t, rei(``), Comma{Comma{Comma{}}})
   370  	testExpr(t, rei(``), Comma{list{}})
   371  	testExpr(t, rei(``), Comma{list{Comma{list{}}}})
   372  	testExpr(t, rei(`one`), Comma{Str(`one`)})
   373  	testExpr(t, rei(`one`, 10), Comma{rei(`one`, 10)})
   374  	testExpr(t, rei(`$1`, 10), Comma{list{10}})
   375  	testExpr(t, rei(`$1, $2`, 10, 20), Comma{list{10, 20}})
   376  	testExpr(t, rei(`$1, $2, $3`, 10, 20, 30), Comma{list{10, 20, 30}})
   377  	testExpr(t, rei(`(one), $1`, 10), Comma{list{Str(`one`), 10}})
   378  	testExpr(t, rei(`$1, (one)`, 10), Comma{list{10, Str(`one`)}})
   379  }
   380  
   381  func TestAnd(t *testing.T) {
   382  	testExpr(t, rei(`true`), And{})
   383  
   384  	t.Run(`slice`, func(t *testing.T) {
   385  		testExpr(t, rei(`$1`, nil), And{list{nil}})
   386  		testExpr(t, rei(`$1`, 10), And{[]int{10}})
   387  		testExpr(t, rei(`$1 and $2`, 10, 20), And{[]int{10, 20}})
   388  		testExpr(t, rei(`$1 and $2 and $3`, 10, 20, 30), And{[]int{10, 20, 30}})
   389  		testExpr(t, rei(`one`), And{[]Str{`one`}})
   390  		testExpr(t, rei(`(one) and (two)`), And{[]Str{`one`, `two`}})
   391  		testExpr(t, rei(`(one) and (two) and (three)`), And{[]Str{`one`, `two`, `three`}})
   392  
   393  		testExpr(
   394  			t,
   395  			rei(`$1 and (one) and $2 and (two) and $3`, 10, 20, 30),
   396  			And{list{10, Str(`one`), 20, Str(`two`), 30}},
   397  		)
   398  
   399  		testExprs(t, rei(`true true`), And{}, And{})
   400  		testExprs(t, rei(`true $1 and $2`, 10, 20), And{}, And{[]int{10, 20}})
   401  		testExprs(t, rei(`$1 and $2 true`, 10, 20), And{[]int{10, 20}}, And{})
   402  		testExprs(t, rei(`$1 and $2 $3 and $4`, 10, 20, 30, 40), And{[]int{10, 20}}, And{[]int{30, 40}})
   403  	})
   404  
   405  	t.Run(`struct`, func(t *testing.T) {
   406  		testExpr(t, rei(`true`), And{Void{}})
   407  		testExpr(t, rei(`true`), And{struct{ _ string }{}})
   408  		testExpr(t, rei(`true`), And{struct{ Col string }{}})
   409  
   410  		testExpr(t, rei(`true`), And{struct {
   411  			_ string `db:"col"`
   412  		}{}})
   413  
   414  		testExpr(t, rei(`"col" = $1`, ``), And{struct {
   415  			Col string `db:"col"`
   416  		}{}})
   417  
   418  		testExpr(t, rei(`"col" is null`), And{struct {
   419  			Col *string `db:"col"`
   420  		}{}})
   421  
   422  		str := `one`
   423  		testExpr(t, rei(`"col" = $1`, &str), And{struct {
   424  			Col *string `db:"col"`
   425  		}{&str}})
   426  
   427  		testExpr(
   428  			t,
   429  			rei(
   430  				`"one" = $1 and "embed_id" = $2 and "embed_name" = $3 and "two" = $4`,
   431  				`outer one`, `embed id`, `embed name`, 20,
   432  			),
   433  			And{
   434  				struct {
   435  					One string `db:"one"`
   436  					Embed
   437  					Two int `db:"two"`
   438  				}{
   439  					One: `outer one`,
   440  					Embed: Embed{
   441  						Id:   `embed id`,
   442  						Name: `embed name`,
   443  					},
   444  					Two: 20,
   445  				},
   446  			},
   447  		)
   448  	})
   449  }
   450  
   451  func TestOr(t *testing.T) {
   452  	testExpr(t, rei(`false`), Or{})
   453  
   454  	t.Run(`slice`, func(t *testing.T) {
   455  		testExpr(t, rei(`$1`, nil), Or{list{nil}})
   456  		testExpr(t, rei(`$1`, 10), Or{[]int{10}})
   457  		testExpr(t, rei(`$1 or $2`, 10, 20), Or{[]int{10, 20}})
   458  		testExpr(t, rei(`$1 or $2 or $3`, 10, 20, 30), Or{[]int{10, 20, 30}})
   459  		testExpr(t, rei(`one`), Or{[]Str{`one`}})
   460  		testExpr(t, rei(`(one) or (two)`), Or{[]Str{`one`, `two`}})
   461  		testExpr(t, rei(`(one) or (two) or (three)`), Or{[]Str{`one`, `two`, `three`}})
   462  
   463  		testExpr(
   464  			t,
   465  			rei(`$1 or (one) or $2 or (two) or $3`, 10, 20, 30),
   466  			Or{list{10, Str(`one`), 20, Str(`two`), 30}},
   467  		)
   468  
   469  		testExprs(t, rei(`false false`), Or{}, Or{})
   470  		testExprs(t, rei(`false $1 or $2`, 10, 20), Or{}, Or{[]int{10, 20}})
   471  		testExprs(t, rei(`$1 or $2 false`, 10, 20), Or{[]int{10, 20}}, Or{})
   472  		testExprs(t, rei(`$1 or $2 $3 or $4`, 10, 20, 30, 40), Or{[]int{10, 20}}, Or{[]int{30, 40}})
   473  	})
   474  
   475  	t.Run(`struct`, func(t *testing.T) {
   476  		testExpr(t, rei(`false`), Or{Void{}})
   477  		testExpr(t, rei(`false`), Or{struct{ _ string }{}})
   478  		testExpr(t, rei(`false`), Or{struct{ Col string }{}})
   479  
   480  		testExpr(t, rei(`false`), Or{struct {
   481  			_ string `db:"col"`
   482  		}{}})
   483  
   484  		testExpr(t, rei(`"col" = $1`, ``), Or{struct {
   485  			Col string `db:"col"`
   486  		}{}})
   487  
   488  		testExpr(t, rei(`"col" is null`), Or{struct {
   489  			Col *string `db:"col"`
   490  		}{}})
   491  
   492  		str := `one`
   493  		testExpr(t, rei(`"col" = $1`, &str), Or{struct {
   494  			Col *string `db:"col"`
   495  		}{&str}})
   496  
   497  		testExpr(
   498  			t,
   499  			rei(
   500  				`"one" = $1 or "embed_id" = $2 or "embed_name" = $3 or "two" = $4`,
   501  				`outer one`, `embed id`, `embed name`, 20,
   502  			),
   503  			Or{
   504  				struct {
   505  					One string `db:"one"`
   506  					Embed
   507  					Two int `db:"two"`
   508  				}{
   509  					One: `outer one`,
   510  					Embed: Embed{
   511  						Id:   `embed id`,
   512  						Name: `embed name`,
   513  					},
   514  					Two: 20,
   515  				},
   516  			},
   517  		)
   518  	})
   519  }
   520  
   521  func TestAnds(t *testing.T) {
   522  	testExpr(t, rei(`true`), Ands{})
   523  	testExpr(t, rei(`$1`, 10), Ands{10})
   524  	testExpr(t, rei(`$1 and $2`, 10, 20), Ands{10, 20})
   525  	testExpr(t, rei(`$1 and $2 and $3`, 10, 20, 30), Ands{10, 20, 30})
   526  	testExpr(t, rei(`true`), Ands{Ands{Ands{}}})
   527  	testExpr(t, rei(`$1`, 10), Ands{Ands{Ands{10}}})
   528  	testExpr(t, rei(`(true) and ($1)`, 10), Ands{Ands{Ands{}}, Ands{Ands{10}}})
   529  	testExpr(t, rei(`($1) and (true)`, 10), Ands{Ands{Ands{10}}, Ands{Ands{}}})
   530  	testExpr(t, rei(`($1) and ($2)`, 10, 20), Ands{Ands{Ands{10}}, Ands{Ands{20}}})
   531  	testExpr(t, rei(`$1 and $2`, 10, 20), Ands{Ands{10, 20}})
   532  	testExpr(t, rei(`($1 and $2) and ($3 and $4)`, 10, 20, 30, 40), Ands{Ands{10, 20}, Ands{30, 40}})
   533  }
   534  
   535  func TestOrs(t *testing.T) {
   536  	testExpr(t, rei(`false`), Ors{})
   537  	testExpr(t, rei(`$1`, 10), Ors{10})
   538  	testExpr(t, rei(`$1 or $2`, 10, 20), Ors{10, 20})
   539  	testExpr(t, rei(`$1 or $2 or $3`, 10, 20, 30), Ors{10, 20, 30})
   540  	testExpr(t, rei(`false`), Ors{Ors{Ors{}}})
   541  	testExpr(t, rei(`$1`, 10), Ors{Ors{Ors{10}}})
   542  	testExpr(t, rei(`(false) or ($1)`, 10), Ors{Ors{Ors{}}, Ors{Ors{10}}})
   543  	testExpr(t, rei(`($1) or (false)`, 10), Ors{Ors{Ors{10}}, Ors{Ors{}}})
   544  	testExpr(t, rei(`($1) or ($2)`, 10, 20), Ors{Ors{Ors{10}}, Ors{Ors{20}}})
   545  	testExpr(t, rei(`$1 or $2`, 10, 20), Ors{Ors{10, 20}})
   546  	testExpr(t, rei(`($1 or $2) or ($3 or $4)`, 10, 20, 30, 40), Ors{Ors{10, 20}, Ors{30, 40}})
   547  }
   548  
   549  func TestCond(t *testing.T) {
   550  	testExpr(t, rei(``), Cond{})
   551  	testExpr(t, rei(`empty`), Cond{Empty: `empty`})
   552  	testExpr(t, rei(`one`), Cond{Val: Str(`one`)})
   553  	testExpr(t, rei(`one`, 10), Cond{Val: rei(`one`, 10)})
   554  
   555  	t.Run(`slice`, func(t *testing.T) {
   556  		testExpr(t, rei(`empty`), Cond{`empty`, `delim`, list(nil)})
   557  		testExpr(t, rei(`empty`), Cond{`empty`, `delim`, list{}})
   558  		testExpr(t, rei(`$1`, nil), Cond{`empty`, `delim`, list{nil}})
   559  		testExpr(t, rei(`$1`, 10), Cond{`empty`, `delim`, list{10}})
   560  
   561  		testExpr(
   562  			t,
   563  			rei(`$1 delim $2`, 10, 20),
   564  			Cond{`empty`, `delim`, list{10, 20}},
   565  		)
   566  
   567  		testExpr(
   568  			t,
   569  			rei(`$1 delim $2 delim $3`, 10, 20, 30),
   570  			Cond{`empty`, `delim`, list{10, 20, 30}},
   571  		)
   572  
   573  		testExpr(
   574  			t,
   575  			rei(`(one) delim $1 delim (two)`, 10),
   576  			Cond{`empty`, `delim`, list{Str(`one`), 10, Str(`two`)}},
   577  		)
   578  	})
   579  
   580  	t.Run(`struct`, func(t *testing.T) {
   581  		testExpr(t, rei(`empty`), Cond{`empty`, `delim`, Void{}})
   582  
   583  		testExpr(
   584  			t,
   585  			rei(`empty`),
   586  			Cond{`empty`, `delim`, struct {
   587  				_ string `db:"col"`
   588  			}{}},
   589  		)
   590  
   591  		testExpr(
   592  			t,
   593  			rei(`"col" = (one)`),
   594  			Cond{`empty`, `delim`, struct {
   595  				Col any `db:"col"`
   596  			}{Str(`one`)}},
   597  		)
   598  	})
   599  }
   600  
   601  func TestCond_filter(t *testing.T) {
   602  	test := func(exp R, val any, fil Haser) {
   603  		t.Helper()
   604  		testExpr(t, exp, Cond{`empty`, `delim`, Partial{val, fil}})
   605  	}
   606  
   607  	test(rei(`empty`), PairStruct{10, 20}, nil)
   608  	test(rei(`empty`), &PairStruct{10, 20}, nil)
   609  	test(rei(`"one" = $1 delim "two" = $2`, 10, 20), PairStruct{10, 20}, HaserTrue{})
   610  	test(rei(`"one" = $1 delim "two" = $2`, 10, 20), &PairStruct{10, 20}, HaserTrue{})
   611  }
   612  
   613  func TestCols(t *testing.T) {
   614  	test := func(exp string, typ any) {
   615  		t.Helper()
   616  		testExpr(t, rei(exp), Cols{typ})
   617  	}
   618  
   619  	test(`*`, nil)
   620  	test(`*`, int(0))
   621  	test(`*`, (*int)(nil))
   622  	test(`*`, string(``))
   623  	test(`*`, (*string)(nil))
   624  	test(`*`, time.Time{})
   625  	test(`*`, (*time.Time)(nil))
   626  
   627  	test(``, Void{})
   628  	test(``, &Void{})
   629  	test(``, []Void{})
   630  	test(``, []*Void{})
   631  	test(``, &[]Void{})
   632  	test(``, &[]*Void{})
   633  
   634  	test(`"one"`, UnitStruct{})
   635  	test(`"one"`, &UnitStruct{})
   636  	test(`"one"`, []UnitStruct{})
   637  	test(`"one"`, []*UnitStruct{})
   638  	test(`"one"`, &[]UnitStruct{})
   639  	test(`"one"`, &[]*UnitStruct{})
   640  
   641  	test(`"one", "two"`, PairStruct{})
   642  	test(`"one", "two"`, &PairStruct{})
   643  	test(`"one", "two"`, []PairStruct{})
   644  	test(`"one", "two"`, []*PairStruct{})
   645  	test(`"one", "two"`, &[]PairStruct{})
   646  	test(`"one", "two"`, &[]*PairStruct{})
   647  
   648  	test(`"one", "two", "three"`, TrioStruct{})
   649  	test(`"one", "two", "three"`, &TrioStruct{})
   650  	test(`"one", "two", "three"`, []TrioStruct{})
   651  	test(`"one", "two", "three"`, []*TrioStruct{})
   652  	test(`"one", "two", "three"`, &[]TrioStruct{})
   653  	test(`"one", "two", "three"`, &[]*TrioStruct{})
   654  
   655  	const outer = `"embed_id", "embed_name", "outer_id", "outer_name"`
   656  	test(outer, Outer{})
   657  	test(outer, &Outer{})
   658  	test(outer, []Outer{})
   659  	test(outer, []*Outer{})
   660  	test(outer, []**Outer{})
   661  	test(outer, &[]Outer{})
   662  	test(outer, &[]*Outer{})
   663  	test(outer, &[]**Outer{})
   664  
   665  	const external = `"id", "name", "internal"`
   666  	test(external, External{})
   667  	test(external, &External{})
   668  	test(external, []External{})
   669  	test(external, []*External{})
   670  	test(external, []**External{})
   671  	test(external, &[]External{})
   672  	test(external, &[]*External{})
   673  	test(external, &[]**External{})
   674  }
   675  
   676  func TestColsDeep(t *testing.T) {
   677  	test := func(exp string, typ any) {
   678  		t.Helper()
   679  		eq(t, exp, TypeColsDeep(typeElemOf(typ)))
   680  		testExpr(t, rei(exp), ColsDeep{typ})
   681  	}
   682  
   683  	test(`*`, nil)
   684  	test(`*`, int(0))
   685  	test(`*`, (*int)(nil))
   686  	test(`*`, string(``))
   687  	test(`*`, (*string)(nil))
   688  	test(`*`, time.Time{})
   689  	test(`*`, (*time.Time)(nil))
   690  
   691  	test(``, Void{})
   692  	test(``, &Void{})
   693  	test(``, (*Void)(nil))
   694  	test(``, []Void{})
   695  	test(``, []*Void{})
   696  	test(``, &[]Void{})
   697  	test(``, &[]*Void{})
   698  
   699  	const outer = `"embed_id", "embed_name", "outer_id", "outer_name"`
   700  	test(outer, Outer{})
   701  	test(outer, &Outer{})
   702  	test(outer, []Outer{})
   703  	test(outer, []*Outer{})
   704  	test(outer, []**Outer{})
   705  	test(outer, &[]Outer{})
   706  	test(outer, &[]*Outer{})
   707  	test(outer, &[]**Outer{})
   708  
   709  	const external = `"id", "name", ("internal")."id" as "internal.id", ("internal")."name" as "internal.name"`
   710  	test(external, External{})
   711  	test(external, &External{})
   712  	test(external, []External{})
   713  	test(external, []*External{})
   714  	test(external, []**External{})
   715  	test(external, &[]External{})
   716  	test(external, &[]*External{})
   717  	test(external, &[]**External{})
   718  }
   719  
   720  func TestStructValues(t *testing.T) {
   721  	testExpr(t, rei(``), StructValues{})
   722  	testExpr(t, rei(``), StructValues{Void{}})
   723  	testExpr(t, rei(``), StructValues{&Void{}})
   724  	testExpr(t, rei(``), StructValues{(*UnitStruct)(nil)})
   725  	testExpr(t, rei(``), StructValues{(*PairStruct)(nil)})
   726  	testExpr(t, rei(``), StructValues{(*TrioStruct)(nil)})
   727  
   728  	testExpr(t, rei(`$1`, nil), StructValues{UnitStruct{}})
   729  	testExpr(t, rei(`$1`, nil), StructValues{&UnitStruct{}})
   730  	testExpr(t, rei(`$1`, 10), StructValues{UnitStruct{10}})
   731  	testExpr(t, rei(`$1`, 10), StructValues{&UnitStruct{10}})
   732  	testExpr(t, rei(`$1, $2`, 10, 20), StructValues{PairStruct{10, 20}})
   733  	testExpr(t, rei(`$1, $2, $3`, 10, 20, 30), StructValues{TrioStruct{10, 20, 30}})
   734  	testExpr(t, rei(`(one), (two), $1`, 30), StructValues{TrioStruct{Str(`one`), Str(`two`), 30}})
   735  
   736  	testExpr(t, rei(`$1, $2, $3, $4`, ``, ``, ``, ``), StructValues{Outer{}})
   737  	testExpr(t, rei(`$1, $2, $3`, ``, ``, Internal{}), StructValues{External{}})
   738  
   739  	testExprs(
   740  		t,
   741  		rei(`$1, $2 $3, $4, $5`, 10, 20, 30, 40, 50),
   742  		StructValues{PairStruct{10, 20}},
   743  		StructValues{TrioStruct{30, 40, 50}},
   744  	)
   745  }
   746  
   747  func TestStructValues_filter(t *testing.T) {
   748  	testExpr(t, rei(``), StructValues{Partial{PairStruct{10, 20}, nil}})
   749  	testExpr(t, rei(``), StructValues{Partial{&PairStruct{10, 20}, nil}})
   750  	testExpr(t, rei(`$1, $2`, 10, 20), StructValues{Partial{PairStruct{10, 20}, HaserTrue{}}})
   751  	testExpr(t, rei(`$1, $2`, 10, 20), StructValues{Partial{&PairStruct{10, 20}, HaserTrue{}}})
   752  }
   753  
   754  func TestStructInsert(t *testing.T) {
   755  	testExpr(t, rei(`default values`), StructInsert{})
   756  	testExpr(t, rei(`default values`), StructInsert{Void{}})
   757  	testExpr(t, rei(`default values`), StructInsert{&Void{}})
   758  
   759  	testExpr(t, rei(`("one") values ($1)`, nil), StructInsert{UnitStruct{}})
   760  	testExpr(t, rei(`("one") values ($1)`, nil), StructInsert{&UnitStruct{}})
   761  	testExpr(t, rei(`("one") values ($1)`, `two`), StructInsert{UnitStruct{`two`}})
   762  	testExpr(t, rei(`("one") values ($1)`, `two`), StructInsert{&UnitStruct{`two`}})
   763  	testExpr(t, rei(`("one") values ($1)`, 10), StructInsert{UnitStruct{10}})
   764  	testExpr(t, rei(`("one") values ($1)`, 10), StructInsert{&UnitStruct{10}})
   765  	testExpr(t, rei(`("one") values ((two))`), StructInsert{&UnitStruct{Str(`two`)}})
   766  
   767  	testExpr(t, rei(`("one", "two") values ($1, $2)`, nil, nil), StructInsert{PairStruct{}})
   768  	testExpr(t, rei(`("one", "two") values ($1, $2)`, nil, nil), StructInsert{&PairStruct{}})
   769  	testExpr(t, rei(`("one", "two") values ($1, $2)`, 10, 20), StructInsert{PairStruct{10, 20}})
   770  	testExpr(t, rei(`("one", "two") values ((one), $1)`, 20), StructInsert{&PairStruct{Str(`one`), 20}})
   771  	testExpr(t, rei(`("one", "two") values ($1, (two))`, 10), StructInsert{&PairStruct{10, Str(`two`)}})
   772  
   773  	testExpr(
   774  		t,
   775  		rei(
   776  			`("embed_id", "embed_name", "outer_id", "outer_name") values ($1, $2, $3, $4)`,
   777  			`embed id`, `embed name`, `outer id`, `outer name`,
   778  		),
   779  		StructInsert{Outer{
   780  			Id:   `outer id`,
   781  			Name: `outer name`,
   782  			Embed: Embed{
   783  				Id:   `embed id`,
   784  				Name: `embed name`,
   785  			},
   786  		}},
   787  	)
   788  
   789  	testExpr(
   790  		t,
   791  		rei(
   792  			`("id", "name", "internal") values ($1, $2, $3)`,
   793  			`external id`, `external name`, Internal{`internal id`, `internal name`},
   794  		),
   795  		StructInsert{External{
   796  			Id:   `external id`,
   797  			Name: `external name`,
   798  			Internal: Internal{
   799  				Id:   `internal id`,
   800  				Name: `internal name`,
   801  			},
   802  		}},
   803  	)
   804  
   805  	testExprs(
   806  		t,
   807  		rei(`default values ("one") values ($1) ("one") values ($2) default values`, 10, 20),
   808  		StructInsert{},
   809  		StructInsert{UnitStruct{10}},
   810  		StructInsert{UnitStruct{20}},
   811  		StructInsert{},
   812  	)
   813  }
   814  
   815  func TestStructInsert_filter(t *testing.T) {
   816  	testExpr(t, rei(`default values`), StructInsert{Partial{PairStruct{10, 20}, nil}})
   817  	testExpr(t, rei(`default values`), StructInsert{Partial{&PairStruct{10, 20}, nil}})
   818  	testExpr(t, rei(`("one", "two") values ($1, $2)`, 10, 20), StructInsert{Partial{PairStruct{10, 20}, HaserTrue{}}})
   819  	testExpr(t, rei(`("one", "two") values ($1, $2)`, 10, 20), StructInsert{Partial{&PairStruct{10, 20}, HaserTrue{}}})
   820  }
   821  
   822  /*
   823  Uses `TypeCols` and `StructInsert` internally.
   824  We only need a few sanity checks.
   825  */
   826  func TestStructsInsert(t *testing.T) {
   827  	testExpr(t, rei(``), StructsInsertOf[any]())
   828  	testExpr(t, rei(`() values ()`), StructsInsertOf(Void{}))
   829  	testExpr(t, rei(`() values ()`), StructsInsertOf(&Void{}))
   830  
   831  	testExpr(t, rei(``), StructsInsertOf[UnitStruct]())
   832  	testExpr(t, rei(`("one") values ($1)`, nil), StructsInsertOf(UnitStruct{}))
   833  	testExpr(t, rei(`("one") values ($1)`, nil), StructsInsertOf(&UnitStruct{}))
   834  	testExpr(t, rei(`("one") values ($1)`, `two`), StructsInsertOf(UnitStruct{`two`}))
   835  	testExpr(t, rei(`("one") values ($1)`, `two`), StructsInsertOf(&UnitStruct{`two`}))
   836  	testExpr(t, rei(`("one") values ($1)`, 10), StructsInsertOf(UnitStruct{10}))
   837  	testExpr(t, rei(`("one") values ($1)`, 10), StructsInsertOf(&UnitStruct{10}))
   838  	testExpr(t, rei(`("one") values ((two))`), StructsInsertOf(&UnitStruct{Str(`two`)}))
   839  
   840  	testExpr(
   841  		t,
   842  		rei(`("one") values ($1), ($2)`, 10, 20),
   843  		StructsInsertOf(UnitStruct{10}, UnitStruct{20}),
   844  	)
   845  
   846  	testExpr(t, rei(`("one", "two") values ($1, $2)`, 10, 20), StructsInsertOf(PairStruct{10, 20}))
   847  
   848  	testExpr(
   849  		t,
   850  		rei(`("one", "two") values ($1, $2), ($3, $4)`, 10, 20, 30, 40),
   851  		StructsInsertOf(PairStruct{10, 20}, PairStruct{30, 40}),
   852  	)
   853  }
   854  
   855  func TestStructAssign(t *testing.T) {
   856  	panics(t, `assignment must have at least one field`, func() {
   857  		StructAssign{}.AppendExpr(nil, nil)
   858  	})
   859  
   860  	panics(t, `assignment must have at least one field`, func() {
   861  		StructAssign{Void{}}.AppendExpr(nil, nil)
   862  	})
   863  
   864  	panics(t, `assignment must have at least one field`, func() {
   865  		StructAssign{&Void{}}.AppendExpr(nil, nil)
   866  	})
   867  
   868  	testExpr(t, rei(`"one" = $1`, nil), StructAssign{UnitStruct{}})
   869  	testExpr(t, rei(`"one" = $1`, 10), StructAssign{UnitStruct{10}})
   870  	testExpr(t, rei(`"one" = (two)`), StructAssign{UnitStruct{Str(`two`)}})
   871  
   872  	testExpr(t, rei(`"one" = $1, "two" = $2`, nil, nil), StructAssign{PairStruct{}})
   873  	testExpr(t, rei(`"one" = $1, "two" = $2`, 10, 20), StructAssign{PairStruct{10, 20}})
   874  	testExpr(t, rei(`"one" = (three), "two" = $1`, 20), StructAssign{PairStruct{Str(`three`), 20}})
   875  	testExpr(t, rei(`"one" = $1, "two" = (three)`, 10), StructAssign{PairStruct{10, Str(`three`)}})
   876  	testExpr(t, rei(`"one" = (three), "two" = (four)`), StructAssign{PairStruct{Str(`three`), Str(`four`)}})
   877  
   878  	testExprs(
   879  		t,
   880  		rei(`"one" = $1 "one" = $2`, 10, 20),
   881  		StructAssign{UnitStruct{10}},
   882  		StructAssign{UnitStruct{20}},
   883  	)
   884  }
   885  
   886  func TestStructAssign_filter(t *testing.T) {
   887  	testExpr(t, rei(`"one" = $1, "two" = $2`, 10, 20), StructAssign{Partial{PairStruct{10, 20}, HaserTrue{}}})
   888  	testExpr(t, rei(`"one" = $1, "two" = $2`, 10, 20), StructAssign{Partial{&PairStruct{10, 20}, HaserTrue{}}})
   889  
   890  	panics(t, `assignment must have at least one field`, func() {
   891  		testExpr(t, rei(`default values`), StructAssign{Partial{PairStruct{10, 20}, nil}})
   892  	})
   893  
   894  	panics(t, `assignment must have at least one field`, func() {
   895  		testExpr(t, rei(`default values`), StructAssign{Partial{&PairStruct{10, 20}, nil}})
   896  	})
   897  }
   898  
   899  func TestSelectCols(t *testing.T) {
   900  	testExpr(t, rei(``), SelectCols{})
   901  	testExpr(t, rei(`select "one"`), SelectCols{nil, UnitStruct{}})
   902  	testExpr(t, rei(`table "some_table"`), SelectCols{Table{`some_table`}, nil})
   903  
   904  	testExpr(
   905  		t,
   906  		rei(`with _ as (table "some_table") select "one" from _`),
   907  		SelectCols{Table{`some_table`}, UnitStruct{}},
   908  	)
   909  
   910  	testExpr(
   911  		t,
   912  		rei(`with _ as (table "some_table") select "embed_id", "embed_name", "outer_id", "outer_name" from _`),
   913  		SelectCols{Table{`some_table`}, Outer{}},
   914  	)
   915  
   916  	testExpr(
   917  		t,
   918  		rei(`with _ as (table "some_table") select "id", "name", "internal" from _`),
   919  		SelectCols{Table{`some_table`}, External{}},
   920  	)
   921  }
   922  
   923  func TestSelectColsDeep(t *testing.T) {
   924  	testExpr(t, rei(``), SelectColsDeep{})
   925  	testExpr(t, rei(`select "one"`), SelectColsDeep{nil, UnitStruct{}})
   926  	testExpr(t, rei(`table "some_table"`), SelectColsDeep{Table{`some_table`}, nil})
   927  
   928  	testExpr(
   929  		t,
   930  		rei(`with _ as (table "some_table") select "one" from _`),
   931  		SelectColsDeep{Table{`some_table`}, UnitStruct{}},
   932  	)
   933  
   934  	testExpr(
   935  		t,
   936  		rei(`with _ as (table "some_table") select "embed_id", "embed_name", "outer_id", "outer_name" from _`),
   937  		SelectColsDeep{Table{`some_table`}, Outer{}},
   938  	)
   939  
   940  	testExpr(
   941  		t,
   942  		rei(`with _ as (table "some_table") select "id", "name", ("internal")."id" as "internal.id", ("internal")."name" as "internal.name" from _`),
   943  		SelectColsDeep{Table{`some_table`}, External{}},
   944  	)
   945  }
   946  
   947  func TestPrefix(t *testing.T) {
   948  	testExpr(t, rei(``), Prefix{})
   949  	testExpr(t, rei(``), Prefix{`prefix`, nil})
   950  	testExpr(t, rei(`prefix `), Prefix{`prefix`, Str(``)})
   951  	testExpr(t, rei(`prefix one`), Prefix{`prefix`, Str(`one`)})
   952  	testExpr(t, rei(`one`), Prefix{``, Str(`one`)})
   953  	testExpr(t, rei(`one`, 10), Prefix{``, rei(`one`, 10)})
   954  	testExpr(t, rei(`prefix one`, 10), Prefix{`prefix`, rei(`one`, 10)})
   955  	testExpr(t, rei(`prefix one`, 10), Prefix{`prefix `, rei(`one`, 10)})
   956  
   957  	testExprs(
   958  		t,
   959  		rei(`one two three four`, 10, 20, 30, 40),
   960  		Prefix{`one`, rei(`two`, 10, 20)},
   961  		Prefix{`three`, rei(`four`, 30, 40)},
   962  	)
   963  }
   964  
   965  func TestWrap(t *testing.T) {
   966  	testExpr(t, rei(``), Wrap{})
   967  	testExpr(t, rei(``), Wrap{`prefix`, nil, ``})
   968  	testExpr(t, rei(``), Wrap{``, nil, `suffix`})
   969  	testExpr(t, rei(``), Wrap{`prefix`, nil, `suffix`})
   970  	testExpr(t, rei(`prefix `), Wrap{`prefix`, Str(``), ``})
   971  	testExpr(t, rei(`suffix`), Wrap{``, Str(``), `suffix`})
   972  	testExpr(t, rei(`prefix suffix`), Wrap{`prefix`, Str(``), `suffix`})
   973  	testExpr(t, rei(`one`, 10), Wrap{``, rei(`one`, 10), ``})
   974  	testExpr(t, rei(`prefix one`, 10), Wrap{`prefix`, rei(`one`, 10), ``})
   975  	testExpr(t, rei(`one suffix`, 10), Wrap{``, rei(`one`, 10), `suffix`})
   976  	testExpr(t, rei(`prefix one suffix`, 10), Wrap{`prefix`, rei(`one`, 10), `suffix`})
   977  
   978  	testExprs(
   979  		t,
   980  		rei(`one two three four five six`, 10, 20, 30, 40),
   981  		Wrap{`one`, rei(`two`, 10, 20), `three`},
   982  		Wrap{`four`, rei(`five`, 30, 40), `six`},
   983  	)
   984  }
   985  
   986  func TestOrderBy(t *testing.T) {
   987  	testExpr(t, rei(``), OrderBy{})
   988  	testExpr(t, rei(`order by ""`), OrderBy{Ident(``)})
   989  	testExpr(t, rei(`order by "one"`), OrderBy{Ident(`one`)})
   990  	testExpr(t, rei(`order by one`, 10), OrderBy{rei(`one`, 10)})
   991  
   992  	testExprs(
   993  		t,
   994  		rei(`one order by two`, 10, 20),
   995  		rei(`one`, 10),
   996  		OrderBy{rei(`two`, 20)},
   997  	)
   998  }
   999  
  1000  func TestSelect(t *testing.T) {
  1001  	test := exprTest(t)
  1002  
  1003  	test(rei(`select * from ""`), Select{})
  1004  	test(rei(`select * from "table_name"`), Select{`table_name`, nil})
  1005  	test(rei(`select * from "" where $1`, 10), Select{``, 10})
  1006  
  1007  	test(
  1008  		rei(`select * from "table_name" where (one) = $1`, 10),
  1009  		Select{`table_name`, Eq{Str(`one`), 10}},
  1010  	)
  1011  
  1012  	test(
  1013  		rei(`select * from "table_name" where "one" = $1 and "two" = $2`, 10, 20),
  1014  		Select{`table_name`, PairStruct{10, 20}},
  1015  	)
  1016  
  1017  	test(
  1018  		rei(`select * from "table_name" where $1 and $2`, 10, 20),
  1019  		Select{`table_name`, list{10, 20}},
  1020  	)
  1021  
  1022  	test(
  1023  		rei(`select * from "table_name" where $1 and $2`, 10, 20),
  1024  		Select{`table_name`, Ands{10, 20}},
  1025  	)
  1026  
  1027  	test(
  1028  		rei(`select * from "table_name" where $1 or $2`, 10, 20),
  1029  		Select{`table_name`, Ors{10, 20}},
  1030  	)
  1031  
  1032  	testExprs(
  1033  		t,
  1034  		rei(`select * from "one" where $1 select * from "two" where $2`, 10, 20),
  1035  		Select{`one`, 10},
  1036  		Select{`two`, 20},
  1037  	)
  1038  }
  1039  
  1040  func TestInsert(t *testing.T) {
  1041  	test := exprTest(t)
  1042  
  1043  	test(
  1044  		rei(`insert into "" default values returning *`),
  1045  		Insert{},
  1046  	)
  1047  
  1048  	test(
  1049  		rei(`insert into "table_name" default values returning *`),
  1050  		Insert{`table_name`, nil},
  1051  	)
  1052  
  1053  	test(
  1054  		rei(`insert into "" ("one") values ($1) returning *`, 10),
  1055  		Insert{``, UnitStruct{10}},
  1056  	)
  1057  
  1058  	test(
  1059  		rei(`insert into "table_name" ("one") values ($1) returning *`, 10),
  1060  		Insert{`table_name`, UnitStruct{10}},
  1061  	)
  1062  
  1063  	test(
  1064  		rei(`insert into "" ("one", "two") values ($1, $2) returning *`, 10, 20),
  1065  		Insert{``, PairStruct{10, 20}},
  1066  	)
  1067  
  1068  	test(
  1069  		rei(`insert into "table_name" ("one", "two") values ($1, $2) returning *`, 10, 20),
  1070  		Insert{`table_name`, PairStruct{10, 20}},
  1071  	)
  1072  
  1073  	test(
  1074  		rei(`insert into "table_name" default values returning *`),
  1075  		Insert{`table_name`, Partial{UnitStruct{10}, nil}},
  1076  	)
  1077  
  1078  	testExprs(
  1079  		t,
  1080  		rei(
  1081  			`insert into "table0" ("one") values ($1) returning * `+
  1082  				`insert into "table1" ("one") values ($2) returning *`,
  1083  			10, 20,
  1084  		),
  1085  		Insert{`table0`, UnitStruct{10}},
  1086  		Insert{`table1`, UnitStruct{20}},
  1087  	)
  1088  }
  1089  
  1090  func TestUpdate(t *testing.T) {
  1091  	test := exprTest(t)
  1092  
  1093  	test(rei(`update "" returning *`), Update{})
  1094  
  1095  	test(
  1096  		rei(`update "" set "one" = $1 returning *`, 10),
  1097  		Update{``, nil, UnitStruct{10}},
  1098  	)
  1099  
  1100  	test(
  1101  		rei(`update "" where "one" = $1 returning *`, 10),
  1102  		Update{``, UnitStruct{10}, nil},
  1103  	)
  1104  
  1105  	test(
  1106  		rei(`update "" set "one" = $1, "two" = $2 where "one" = $3 returning *`, 20, 30, 10),
  1107  		Update{``, UnitStruct{10}, PairStruct{20, 30}},
  1108  	)
  1109  
  1110  	test(rei(`update "some_table" returning *`), Update{`some_table`, nil, nil})
  1111  
  1112  	test(
  1113  		rei(`update "some_table" set "one" = $1 returning *`, 10),
  1114  		Update{`some_table`, nil, UnitStruct{10}},
  1115  	)
  1116  
  1117  	test(
  1118  		rei(`update "some_table" where "one" = $1 returning *`, 10),
  1119  		Update{`some_table`, UnitStruct{10}, nil},
  1120  	)
  1121  
  1122  	test(
  1123  		rei(`update "some_table" set "one" = $1, "two" = $2 where "one" = $3 returning *`, 20, 30, 10),
  1124  		Update{`some_table`, UnitStruct{10}, PairStruct{20, 30}},
  1125  	)
  1126  
  1127  	test(
  1128  		rei(`update "some_table" set "one" = $1 where null returning *`, 20),
  1129  		Update{`some_table`, Partial{UnitStruct{10}, nil}, UnitStruct{20}},
  1130  	)
  1131  
  1132  	testExprs(
  1133  		t,
  1134  		rei(
  1135  			`update "table0" where "one" = $1 returning * `+
  1136  				`update "table1" set "one" = $2 returning *`,
  1137  			10, 20,
  1138  		),
  1139  		Update{`table0`, UnitStruct{10}, nil},
  1140  		Update{`table1`, nil, UnitStruct{20}},
  1141  	)
  1142  }
  1143  
  1144  func TestDelete(t *testing.T) {
  1145  	test := exprTest(t)
  1146  
  1147  	test(rei(`delete from "" where null returning *`), Delete{})
  1148  
  1149  	test(
  1150  		rei(`delete from "some_table" where null returning *`),
  1151  		Delete{`some_table`, nil},
  1152  	)
  1153  
  1154  	test(
  1155  		rei(`delete from "" where "one" = $1 and "two" = $2 returning *`, 10, 20),
  1156  		Delete{``, PairStruct{10, 20}},
  1157  	)
  1158  
  1159  	test(
  1160  		rei(`delete from "some_table" where "one" = $1 and "two" = $2 returning *`, 10, 20),
  1161  		Delete{`some_table`, PairStruct{10, 20}},
  1162  	)
  1163  
  1164  	test(
  1165  		rei(`delete from "some_table" where "one" = $1 or "two" = $2 returning *`, 10, 20),
  1166  		Delete{`some_table`, Or{PairStruct{10, 20}}},
  1167  	)
  1168  
  1169  	test(
  1170  		rei(`delete from "" where null returning *`),
  1171  		Delete{``, Partial{PairStruct{10, 20}, nil}},
  1172  	)
  1173  
  1174  	test(
  1175  		rei(`delete from "some_table" where null returning *`),
  1176  		Delete{`some_table`, Partial{PairStruct{10, 20}, nil}},
  1177  	)
  1178  
  1179  	testExprs(
  1180  		t,
  1181  		rei(
  1182  			`delete from "table0" where "one" = $1 returning * `+
  1183  				`delete from "table1" where "one" = $2 returning *`,
  1184  			10, 20,
  1185  		),
  1186  		Delete{`table0`, UnitStruct{10}},
  1187  		Delete{`table1`, UnitStruct{20}},
  1188  	)
  1189  }
  1190  
  1191  func TestUpsert(t *testing.T) {
  1192  	test := exprTest(t)
  1193  
  1194  	test(
  1195  		rei(`insert into "" default values returning *`),
  1196  		Upsert{},
  1197  	)
  1198  
  1199  	test(
  1200  		rei(`insert into "table" default values returning *`),
  1201  		Upsert{`table`, Void{}, Void{}},
  1202  	)
  1203  
  1204  	test(
  1205  		rei(`insert into "" ("one") values ($1) returning *`, 10),
  1206  		Upsert{``, nil, UnitStruct{10}},
  1207  	)
  1208  
  1209  	test(
  1210  		rei(`insert into "" ("one") values ($1) returning *`, 10),
  1211  		Upsert{``, Void{}, UnitStruct{10}},
  1212  	)
  1213  
  1214  	test(
  1215  		rei(`insert into "table" ("one", "two") values ($1, $2) returning *`, 10, 20),
  1216  		Upsert{`table`, Void{}, PairStruct{10, 20}},
  1217  	)
  1218  
  1219  	test(
  1220  		rei(`insert into "table" ("one") values ($1) on conflict ("one") do update set "one" = excluded."one" returning *`, 10),
  1221  		Upsert{`table`, UnitStruct{10}, nil},
  1222  	)
  1223  
  1224  	test(
  1225  		rei(`insert into "table" ("one", "two") values ($1, $2) on conflict ("one") do update set "one" = excluded."one", "two" = excluded."two" returning *`, 10, 20),
  1226  		Upsert{`table`, UnitStruct{10}, UnitStruct1{20}},
  1227  	)
  1228  
  1229  	test(
  1230  		rei(`insert into "table" ("one", "two", "three", "four") values ($1, $2, $3, $4) on conflict ("one", "two") do update set "one" = excluded."one", "two" = excluded."two", "three" = excluded."three", "four" = excluded."four" returning *`, 10, 20, 30, 40),
  1231  		Upsert{`table`, PairStruct{10, 20}, PairStruct1{30, 40}},
  1232  	)
  1233  }
  1234  
  1235  func TestUpsert_sparse(t *testing.T) {
  1236  	test := exprTest(t)
  1237  	keys := PairStruct{10, 20}
  1238  	cols := PairStruct1{30, 40}
  1239  
  1240  	test(
  1241  		rei(`insert into "table" ("one", "two") values ($1, $2) on conflict ("one", "two") do update set "one" = excluded."one", "two" = excluded."two" returning *`, 10, 20),
  1242  		Upsert{`table`, keys, Partial{Val: cols}},
  1243  	)
  1244  
  1245  	test(
  1246  		rei(`insert into "table" ("one", "two", "three") values ($1, $2, $3) on conflict ("one", "two") do update set "one" = excluded."one", "two" = excluded."two", "three" = excluded."three" returning *`, 10, 20, 30),
  1247  		Upsert{`table`, keys, Partial{cols, HaserSlice{`three`}}},
  1248  	)
  1249  
  1250  	test(
  1251  		rei(`insert into "table" ("one", "two", "four") values ($1, $2, $3) on conflict ("one", "two") do update set "one" = excluded."one", "two" = excluded."two", "four" = excluded."four" returning *`, 10, 20, 40),
  1252  		Upsert{`table`, keys, Partial{cols, HaserSlice{`four`}}},
  1253  	)
  1254  
  1255  	test(
  1256  		rei(`insert into "table" ("one", "two", "three", "four") values ($1, $2, $3, $4) on conflict ("one", "two") do update set "one" = excluded."one", "two" = excluded."two", "three" = excluded."three", "four" = excluded."four" returning *`, 10, 20, 30, 40),
  1257  		Upsert{`table`, keys, Partial{cols, HaserSlice{`three`, `four`}}},
  1258  	)
  1259  
  1260  	test(
  1261  		rei(`insert into "table" ("one", "three", "four") values ($1, $2, $3) on conflict ("one") do update set "one" = excluded."one", "three" = excluded."three", "four" = excluded."four" returning *`, 10, 30, 40),
  1262  		Upsert{`table`, Partial{keys, HaserSlice{`one`}}, cols},
  1263  	)
  1264  
  1265  	test(
  1266  		rei(`insert into "table" ("one", "four") values ($1, $2) on conflict ("one") do update set "one" = excluded."one", "four" = excluded."four" returning *`, 10, 40),
  1267  		Upsert{
  1268  			`table`,
  1269  			Partial{keys, HaserSlice{`one`}},
  1270  			Partial{cols, HaserSlice{`four`}},
  1271  		},
  1272  	)
  1273  }
  1274  
  1275  func TestSelectCount(t *testing.T) {
  1276  	test := exprTest(t)
  1277  
  1278  	test(rei(`select count(*)`), SelectCount{})
  1279  	test(rei(`with _ as (one) select count(*) from _`), SelectCount{Str(`one`)})
  1280  
  1281  	test(
  1282  		rei(`with _ as (coalesce ($1, $2)) select count(*) from _`, 10, 20),
  1283  		SelectCount{Call{`coalesce`, []int{10, 20}}},
  1284  	)
  1285  
  1286  	testExprs(
  1287  		t,
  1288  		rei(`coalesce ($1, $2) with _ as (coalesce ($3, $4)) select count(*) from _`, 10, 20, 30, 40),
  1289  		Call{`coalesce`, []int{10, 20}},
  1290  		SelectCount{Call{`coalesce`, []int{30, 40}}},
  1291  	)
  1292  }
  1293  
  1294  func TestCall(t *testing.T) {
  1295  	testExpr(t, rei(`()`), Call{})
  1296  	testExpr(t, rei(`prefix ()`), Call{`prefix`, nil})
  1297  	testExpr(t, rei(`()`), Call{``, Str(``)})
  1298  
  1299  	// TODO reconsider. When the input is a single `Expr`, we may want to always
  1300  	// additionally parenthesize it.
  1301  	testExpr(t, rei(`(one)`), Call{``, Str(`one`)})
  1302  
  1303  	testExpr(t, rei(`()`), Call{``, list{}})
  1304  	testExpr(t, rei(`($1)`, nil), Call{``, list{nil}})
  1305  	testExpr(t, rei(`($1)`, 10), Call{``, list{10}})
  1306  	testExpr(t, rei(`($1, $2)`, 10, 20), Call{``, list{10, 20}})
  1307  	testExpr(t, rei(`((one), $1)`, 20), Call{``, list{Str(`one`), 20}})
  1308  	testExpr(t, rei(`($1, (two))`, 10), Call{``, list{10, Str(`two`)}})
  1309  	testExpr(t, rei(`((one), (two))`), Call{``, list{Str(`one`), Str(`two`)}})
  1310  
  1311  	testExpr(t, rei(`prefix ()`), Call{`prefix`, list{}})
  1312  	testExpr(t, rei(`prefix ($1)`, nil), Call{`prefix`, list{nil}})
  1313  	testExpr(t, rei(`prefix ($1)`, 10), Call{`prefix`, list{10}})
  1314  	testExpr(t, rei(`prefix ($1, $2)`, 10, 20), Call{`prefix`, list{10, 20}})
  1315  	testExpr(t, rei(`prefix ((one), $1)`, 20), Call{`prefix`, list{Str(`one`), 20}})
  1316  	testExpr(t, rei(`prefix ($1, (two))`, 10), Call{`prefix`, list{10, Str(`two`)}})
  1317  	testExpr(t, rei(`prefix ((one), (two))`), Call{`prefix`, list{Str(`one`), Str(`two`)}})
  1318  
  1319  	testExprs(
  1320  		t,
  1321  		rei(`() () ($1) prefix ($2)`, 10, 20),
  1322  		Call{},
  1323  		Call{},
  1324  		Call{``, list{10}},
  1325  		Call{`prefix`, list{20}},
  1326  	)
  1327  }
  1328  
  1329  func TestRowNumberOver(t *testing.T) {
  1330  	testExpr(t, rei(`0`), RowNumberOver{})
  1331  	testExpr(t, rei(`row_number() over ()`), RowNumberOver{Str(``)})
  1332  	testExpr(t, rei(`row_number() over (one)`), RowNumberOver{Str(`one`)})
  1333  	testExpr(t, rei(`row_number() over (one)`, 10), RowNumberOver{rei(`one`, 10)})
  1334  
  1335  	testExprs(
  1336  		t,
  1337  		rei(`0 row_number() over (one) row_number() over (two)`, 10, 20),
  1338  		RowNumberOver{},
  1339  		RowNumberOver{rei(`one`, 10)},
  1340  		RowNumberOver{rei(`two`, 20)},
  1341  	)
  1342  }
  1343  
  1344  func TestStrQ_without_args(t *testing.T) {
  1345  	testExpr(t, rei(``), StrQ{})
  1346  	testExpr(t, rei(`one`), StrQ{`one`, nil})
  1347  	testExpr(t, rei(`one`), StrQ{`one`, Dict(nil)})
  1348  	testExpr(t, rei(`one two`), StrQ{`one two`, nil})
  1349  	testExprs(t, rei(`one two `), StrQ{}, StrQ{`one`, nil}, StrQ{}, StrQ{`two`, nil}, StrQ{})
  1350  
  1351  	panics(t, `expected arguments, got none`, func() {
  1352  		StrQ{`$1`, nil}.AppendExpr(nil, nil)
  1353  	})
  1354  
  1355  	panics(t, `expected arguments, got none`, func() {
  1356  		StrQ{`:one`, nil}.AppendExpr(nil, nil)
  1357  	})
  1358  }
  1359  
  1360  func TestListQ_invalid(t *testing.T) {
  1361  	panics(t, `non-parametrized expression "" expected no arguments`, func() {
  1362  		ListQ(``, nil).AppendExpr(nil, nil)
  1363  	})
  1364  
  1365  	panics(t, `expected arguments, got none`, func() {
  1366  		ListQ(`$1`).AppendExpr(nil, nil)
  1367  	})
  1368  
  1369  	panics(t, `expected arguments, got none`, func() {
  1370  		ListQ(`:one`).AppendExpr(nil, nil)
  1371  	})
  1372  
  1373  	panics(t, `missing ordinal argument "$2" (index 1)`, func() {
  1374  		ListQ(`$2`, 10).AppendExpr(nil, nil)
  1375  	})
  1376  
  1377  	panics(t, `missing named argument ":one" (key "one")`, func() {
  1378  		ListQ(`:one`, 10).AppendExpr(nil, nil)
  1379  	})
  1380  
  1381  	panics(t, `unused ordinal argument "$2" (index 1)`, func() {
  1382  		ListQ(`$1`, 10, 20).AppendExpr(nil, nil)
  1383  	})
  1384  
  1385  	t.Run(`ValidateUnusedArguments`, func(t *testing.T) {
  1386  		prev := ValidateUnusedArguments
  1387  		ValidateUnusedArguments = false
  1388  		t.Cleanup(func() { ValidateUnusedArguments = prev })
  1389  
  1390  		// No panic when validation is disabled.
  1391  		ListQ(`$1`, 10, 20).AppendExpr(nil, nil)
  1392  	})
  1393  }
  1394  
  1395  func TestListQ_empty_args(t *testing.T) {
  1396  	testExpr(t, rei(``), ListQ(``))
  1397  	testExpr(t, rei(`one`), ListQ(`one`))
  1398  }
  1399  
  1400  func TestListQ_normal(t *testing.T) {
  1401  	test := exprTest(t)
  1402  
  1403  	test(rei(`one = $1`, nil), ListQ(`one = $1`, nil))
  1404  	test(rei(`one = $1`, 10), ListQ(`one = $1`, 10))
  1405  	test(rei(`one = $1`, 10), ListQ(`one = $1 `, 10))
  1406  
  1407  	test(rei(`one = $1, two = $1`, 10), ListQ(`one = $1, two = $1`, 10))
  1408  	test(rei(`one = $1, two = $2`, 10, 20), ListQ(`one = $1, two = $2`, 10, 20))
  1409  
  1410  	test(
  1411  		rei(`one = $1, two = $2, three = $1, four = $2`, 10, 20),
  1412  		ListQ(`one = $1, two = $2, three = $1, four = $2`, 10, 20),
  1413  	)
  1414  
  1415  	test(rei(`one = one`), ListQ(`one = $1`, Str(`one`)))
  1416  
  1417  	test(
  1418  		rei(`one = one, two = one`),
  1419  		ListQ(`one = $1, two = $1`, Str(`one`)),
  1420  	)
  1421  
  1422  	test(
  1423  		rei(`one = one`, 10),
  1424  		ListQ(`one = $1`, rei(`one`, 10)),
  1425  	)
  1426  
  1427  	test(
  1428  		rei(`one = one, two = $1, three = three`, 20),
  1429  		ListQ(
  1430  			`one = $1, two = $2, three = $3`,
  1431  			Str(`one`),
  1432  			20,
  1433  			Str(`three`),
  1434  		),
  1435  	)
  1436  }
  1437  
  1438  func TestDictQ_invalid(t *testing.T) {
  1439  	panics(t, `non-parametrized expression "" expected no arguments`, func() {
  1440  		DictQ(``, Dict{`one`: 10}).AppendExpr(nil, nil)
  1441  	})
  1442  
  1443  	panics(t, `expected arguments, got none`, func() {
  1444  		DictQ(`$1`, nil).AppendExpr(nil, nil)
  1445  	})
  1446  
  1447  	panics(t, `expected arguments, got none`, func() {
  1448  		DictQ(`:one`, nil).AppendExpr(nil, nil)
  1449  	})
  1450  
  1451  	panics(t, `expected arguments, got none`, func() {
  1452  		DictQ(`$1`, Dict{}).AppendExpr(nil, nil)
  1453  	})
  1454  
  1455  	panics(t, `expected arguments, got none`, func() {
  1456  		DictQ(`:one`, Dict{}).AppendExpr(nil, nil)
  1457  	})
  1458  
  1459  	panics(t, `missing ordinal argument "$1" (index 0)`, func() {
  1460  		DictQ(`$1`, Dict{`one`: 10}).AppendExpr(nil, nil)
  1461  	})
  1462  
  1463  	panics(t, `missing ordinal argument "$1" (index 0)`, func() {
  1464  		DictQ(`$1 :one`, Dict{`one`: 10}).AppendExpr(nil, nil)
  1465  	})
  1466  
  1467  	panics(t, `missing ordinal argument "$1" (index 0)`, func() {
  1468  		DictQ(`:one $1`, Dict{`one`: 10}).AppendExpr(nil, nil)
  1469  	})
  1470  
  1471  	panics(t, `missing named argument ":one" (key "one")`, func() {
  1472  		DictQ(`:one`, Dict{`two`: 20}).AppendExpr(nil, nil)
  1473  	})
  1474  
  1475  	panics(t, `missing named argument ":one" (key "one")`, func() {
  1476  		DictQ(`one:one`, Dict{`two`: 20}).AppendExpr(nil, nil)
  1477  	})
  1478  
  1479  	panics(t, `unused named argument ":two" (key "two")`, func() {
  1480  		DictQ(`:one`, Dict{`one`: 10, `two`: 20}).AppendExpr(nil, nil)
  1481  	})
  1482  }
  1483  
  1484  func TestDictQ_empty_args(t *testing.T) {
  1485  	testExpr(t, rei(``), DictQ(``, nil))
  1486  	testExpr(t, rei(`one`), DictQ(`one`, nil))
  1487  	testExpr(t, rei(`one two`), DictQ(`one two`, nil))
  1488  	testExpr(t, rei(``), DictQ(``, Dict(nil)))
  1489  	testExpr(t, rei(``), DictQ(``, Dict{}))
  1490  }
  1491  
  1492  func TestDictQ_normal(t *testing.T) {
  1493  	test := exprTest(t)
  1494  
  1495  	test(rei(`one = $1`, nil), DictQ(`one = :one`, Dict{`one`: nil}))
  1496  	test(rei(`one = $1`, 10), DictQ(`one = :one`, Dict{`one`: 10}))
  1497  
  1498  	// There was a parser bug that broke this.
  1499  	test(rei(`one = $1`, 10), DictQ(`one = :one `, Dict{`one`: 10}))
  1500  
  1501  	test(rei(`one = $1, two = $1`, 10), DictQ(`one = :one, two = :one`, Dict{`one`: 10}))
  1502  	test(rei(`one = $1, two = $2`, 10, 20), DictQ(`one = :one, two = :two`, Dict{`one`: 10, `two`: 20}))
  1503  
  1504  	test(
  1505  		rei(`one = $1, two = $2, three = $1, four = $2`, 10, 20),
  1506  		DictQ(`one = :one, two = :two, three = :one, four = :two`, Dict{`one`: 10, `two`: 20}),
  1507  	)
  1508  
  1509  	test(
  1510  		rei(`one = one`),
  1511  		DictQ(`one = :one`, Dict{`one`: Str(`one`)}),
  1512  	)
  1513  
  1514  	test(
  1515  		rei(`one = one, two = one`),
  1516  		DictQ(`one = :one, two = :one`, Dict{`one`: Str(`one`)}),
  1517  	)
  1518  
  1519  	test(
  1520  		rei(`one = one`, 10),
  1521  		DictQ(`one = :one`, Dict{`one`: rei(`one`, 10)}),
  1522  	)
  1523  
  1524  	test(
  1525  		rei(`one = one, two = $1, three = three`, 20),
  1526  		DictQ(`one = :one, two = :two, three = :three`, Dict{
  1527  			`one`:   Str(`one`),
  1528  			`two`:   20,
  1529  			`three`: Str(`three`),
  1530  		}),
  1531  	)
  1532  }
  1533  
  1534  func TestStructQ_invalid(t *testing.T) {
  1535  	panics(t, `non-parametrized expression "" expected no arguments`, func() {
  1536  		StructQ(``, Void{}).AppendExpr(nil, nil)
  1537  	})
  1538  
  1539  	panics(t, `expected arguments, got none`, func() {
  1540  		StructQ(`$1`, nil).AppendExpr(nil, nil)
  1541  	})
  1542  
  1543  	panics(t, `expected arguments, got none`, func() {
  1544  		StructQ(`:one`, nil).AppendExpr(nil, nil)
  1545  	})
  1546  
  1547  	panics(t, `missing ordinal argument "$1" (index 0)`, func() {
  1548  		StructQ(`$1`, Void{}).AppendExpr(nil, nil)
  1549  	})
  1550  
  1551  	panics(t, `missing named argument ":one" (key "one")`, func() {
  1552  		StructQ(`:one`, Void{}).AppendExpr(nil, nil)
  1553  	})
  1554  }
  1555  
  1556  func TestStructQ_empty_args(t *testing.T) {
  1557  	testExpr(t, rei(``), StructQ(``, nil))
  1558  	testExpr(t, rei(``), StructQ(``, nil))
  1559  	testExpr(t, rei(`one`), StructQ(`one`, nil))
  1560  	testExpr(t, rei(`one two`), StructQ(`one two`, nil))
  1561  	testExpr(t, rei(``), StructQ(``, (*Void)(nil)))
  1562  	testExpr(t, rei(`one`), StructQ(`one`, (*Void)(nil)))
  1563  }
  1564  
  1565  func TestStructQ_fields(t *testing.T) {
  1566  	test := exprTest(t)
  1567  
  1568  	panics(t, `missing named argument ":one" (key "one")`, func() {
  1569  		StructQ(`:one`, UnitStruct{10}).AppendExpr(nil, nil)
  1570  	})
  1571  
  1572  	test(rei(`one = $1`, nil), StructQ(`one = :One`, UnitStruct{}))
  1573  	test(rei(`one = $1`, 10), StructQ(`one = :One`, UnitStruct{10}))
  1574  
  1575  	panics(t, `missing named argument ":one" (key "one")`, func() {
  1576  		StructQ(`:one`, PairStruct{10, 20}).AppendExpr(nil, nil)
  1577  	})
  1578  
  1579  	panics(t, `missing named argument ":two" (key "two")`, func() {
  1580  		StructQ(`:two`, PairStruct{10, 20}).AppendExpr(nil, nil)
  1581  	})
  1582  
  1583  	test(rei(`one = $1, two = $1`, 10), StructQ(`one = :One, two = :One`, PairStruct{10, 20}))
  1584  	test(rei(`one = $1, two = $2`, 10, 20), StructQ(`one = :One, two = :Two`, PairStruct{10, 20}))
  1585  
  1586  	test(
  1587  		rei(`one = $1, two = $2, three = $1, four = $2`, 10, 20),
  1588  		StructQ(`one = :One, two = :Two, three = :One, four = :Two`, PairStruct{10, 20}),
  1589  	)
  1590  
  1591  	test(
  1592  		rei(`one = one, two = $1, three = three`, 20),
  1593  		StructQ(`one = :One, two = :Two, three = :Three`, TrioStruct{
  1594  			Str(`one`),
  1595  			20,
  1596  			Str(`three`),
  1597  		}),
  1598  	)
  1599  }
  1600  
  1601  func TestStructQ_methods(t *testing.T) {
  1602  	test := exprTest(t)
  1603  
  1604  	panics(t, `missing named argument ":GetVal" (key "GetVal")`, func() {
  1605  		StructQ(`:GetVal`, UnitStruct{}).AppendExpr(nil, nil)
  1606  	})
  1607  
  1608  	test(rei(`$1`, `val`), StructQ(`:GetVal`, Void{}))
  1609  
  1610  	panics(t, `expected 0 parameters, found 1 parameters`, func() {
  1611  		StructQ(`:UnaryVoid`, UnitStruct{}).AppendExpr(nil, nil)
  1612  	})
  1613  
  1614  	panics(t, `expected 1 return parameter, found 2 return parameters`, func() {
  1615  		StructQ(`:NullaryPair`, UnitStruct{}).AppendExpr(nil, nil)
  1616  	})
  1617  
  1618  	test(rei(`one = $1`, nil), StructQ(`one = :GetOne`, UnitStruct{}))
  1619  	test(rei(`one = $1`, 10), StructQ(`one = :GetOne`, UnitStruct{10}))
  1620  
  1621  	panics(t, `missing named argument ":one" (key "one")`, func() {
  1622  		StructQ(`:one`, PairStruct{10, 20}).AppendExpr(nil, nil)
  1623  	})
  1624  
  1625  	panics(t, `missing named argument ":two" (key "two")`, func() {
  1626  		StructQ(`:two`, PairStruct{10, 20}).AppendExpr(nil, nil)
  1627  	})
  1628  
  1629  	test(rei(`one = $1, two = $1`, 10), StructQ(`one = :GetOne, two = :GetOne`, PairStruct{10, 20}))
  1630  	test(rei(`one = $1, two = $2`, 10, 20), StructQ(`one = :GetOne, two = :GetTwo`, PairStruct{10, 20}))
  1631  
  1632  	test(
  1633  		rei(`one = $1, two = $2, three = $1, four = $2`, 10, 20),
  1634  		StructQ(`one = :GetOne, two = :GetTwo, three = :GetOne, four = :GetTwo`, PairStruct{10, 20}),
  1635  	)
  1636  
  1637  	test(
  1638  		rei(`one = one, two = $1, three = three`, 20),
  1639  		StructQ(`one = :GetOne, two = :GetTwo, three = :GetThree`, TrioStruct{
  1640  			Str(`one`),
  1641  			20,
  1642  			Str(`three`),
  1643  		}),
  1644  	)
  1645  }
  1646  
  1647  func TestPrep_Parse(t *testing.T) {
  1648  	testPrepParse(t, func(src string, tokens []Token, hasParams bool) {
  1649  		t.Helper()
  1650  		prep := Prep{Source: src}
  1651  		prep.Parse()
  1652  		eq(t, Prep{src, tokens, hasParams}, prep)
  1653  	})
  1654  }
  1655  
  1656  func TestPreparse(t *testing.T) {
  1657  	testPrepParse(t, func(src string, tokens []Token, hasParams bool) {
  1658  		t.Helper()
  1659  		eq(t, Prep{src, tokens, hasParams}, Preparse(src))
  1660  	})
  1661  }
  1662  
  1663  func testPrepParse(t testing.TB, test func(string, []Token, bool)) {
  1664  	test(``, nil, false)
  1665  	test(`one`, []Token{Token{`one`, TokenTypeText}}, false)
  1666  	test(`$1`, []Token{Token{`$1`, TokenTypeOrdinalParam}}, true)
  1667  	test(`:one`, []Token{Token{`:one`, TokenTypeNamedParam}}, true)
  1668  
  1669  	test(
  1670  		`one $1 two :three four $2 five :six`,
  1671  		[]Token{
  1672  			Token{`one `, TokenTypeText},
  1673  			Token{`$1`, TokenTypeOrdinalParam},
  1674  			Token{` two `, TokenTypeText},
  1675  			Token{`:three`, TokenTypeNamedParam},
  1676  			Token{` four `, TokenTypeText},
  1677  			Token{`$2`, TokenTypeOrdinalParam},
  1678  			Token{` five `, TokenTypeText},
  1679  			Token{`:six`, TokenTypeNamedParam},
  1680  		},
  1681  		true,
  1682  	)
  1683  
  1684  	test(
  1685  		/*pgsql*/ `
  1686  one
  1687  -- line comment $1 :one
  1688  :two
  1689  /* block comment $1 :one */
  1690  three
  1691  `,
  1692  		[]Token{
  1693  			Token{`one `, TokenTypeText},
  1694  			Token{`:two`, TokenTypeNamedParam},
  1695  			Token{`  three`, TokenTypeText},
  1696  		},
  1697  		true,
  1698  	)
  1699  }
  1700  
  1701  func TestPreparse_dedup(t *testing.T) {
  1702  	test := func(val string) {
  1703  		t.Helper()
  1704  
  1705  		eq(t, Preparse(val), Preparse(val))
  1706  		sliceIs(t, prepCache.Get(val).Tokens, prepCache.Get(val).Tokens)
  1707  
  1708  		prep := Preparse(val)
  1709  
  1710  		eq(t, prep, Preparse(val))
  1711  		eq(t, prep, Preparse(val))
  1712  	}
  1713  
  1714  	test(``)
  1715  	test(` `)
  1716  	test(`one`)
  1717  	test(`one two`)
  1718  	test(`one :two`)
  1719  	test(`one :two three`)
  1720  
  1721  	notEq(t, Preparse(``), Preparse(` `))
  1722  	notEq(t, Preparse(``), Preparse(`one`))
  1723  	notEq(t, Preparse(` `), Preparse(`one`))
  1724  }
  1725  
  1726  /*
  1727  Note: parametrized expression building is verified in various tests for `StrQ`,
  1728  which uses a `Prep` internally. This is mostly for verifying the automatic
  1729  "unparam" mode and associated assertions.
  1730  */
  1731  func TestPrep_AppendParamExpr_unparam(t *testing.T) {
  1732  	test := func(exp R, vals ...string) {
  1733  		t.Helper()
  1734  		eq(t, exp, reiFrom(reifyUnparamPreps(vals...)))
  1735  	}
  1736  
  1737  	test(rei(``))
  1738  	test(rei(``), ``)
  1739  	test(rei(``), ``, ``)
  1740  	test(rei(`one`), `one`)
  1741  	test(rei(`one`), ``, `one`, ``)
  1742  	test(rei(`one two`), ``, `one`, ``, `two`, ``)
  1743  
  1744  	testNilArgs := func(val string) {
  1745  		t.Helper()
  1746  		eq(t, rei(val), reifyParamExpr(Preparse(val), nil))
  1747  		eq(t, rei(val), reifyParamExpr(Preparse(val), Dict(nil)))
  1748  		eq(t, rei(val), reifyParamExpr(Preparse(val), (*Dict)(nil)))
  1749  		eq(t, rei(val), reifyParamExpr(Preparse(val), (*StructDict)(nil)))
  1750  	}
  1751  
  1752  	testNilArgs(``)
  1753  	testNilArgs(`one`)
  1754  	testNilArgs(`one two`)
  1755  
  1756  	testPanic := func(val string) {
  1757  		t.Helper()
  1758  
  1759  		prep := Preparse(val)
  1760  		msg := fmt.Sprintf(`non-parametrized expression %q expected no arguments, got`, val)
  1761  
  1762  		panics(t, msg, func() {
  1763  			prep.AppendParamExpr(nil, nil, Dict{})
  1764  		})
  1765  
  1766  		panics(t, msg, func() {
  1767  			prep.AppendParamExpr(nil, nil, StructDict{})
  1768  		})
  1769  	}
  1770  
  1771  	testPanic(``)
  1772  	testPanic(`one`)
  1773  	testPanic(`one two`)
  1774  }
  1775  
  1776  func Test_combinations(t *testing.T) {
  1777  	testExpr(
  1778  		t,
  1779  		rei(`($1 or $2) = ($3 or $4)`, 10, 20, 30, 40),
  1780  		Eq{Ors{10, 20}, Ors{30, 40}},
  1781  	)
  1782  
  1783  	testExpr(
  1784  		t,
  1785  		rei(`($1 or $2) and ($3 or $4) and $5`, 10, 20, 30, 40, 50),
  1786  		Ands{Ors{10, 20}, Ors{30, 40}, 50},
  1787  	)
  1788  
  1789  	testExpr(
  1790  		t,
  1791  		rei(`select "some_column" from "some_table"`),
  1792  		StrQ{`select :col from :tab`, Dict{
  1793  			`col`: Ident(`some_column`),
  1794  			`tab`: Ident(`some_table`),
  1795  		}},
  1796  	)
  1797  }
  1798  
  1799  func Test_column_fields(t *testing.T) {
  1800  	eq(
  1801  		t,
  1802  		[][2]string{
  1803  			{`embed_id`, `embed id`},
  1804  			{`embed_name`, `embed name`},
  1805  			{`outer_id`, `outer id`},
  1806  			{`outer_name`, `outer name`},
  1807  		},
  1808  		tCols(),
  1809  	)
  1810  }
  1811  
  1812  func tCols() (out [][2]string) {
  1813  	val := r.ValueOf(testOuter)
  1814  	for _, field := range loadStructDbFields(val.Type()) {
  1815  		out = append(out, [2]string{
  1816  			FieldDbName(field),
  1817  			val.FieldByIndex(field.Index).String(),
  1818  		})
  1819  	}
  1820  	return
  1821  }
  1822  
  1823  func TestList(t *testing.T) {
  1824  	zero := List(nil)
  1825  	empty := List{}
  1826  	full := List{10, 20, 30, 40, 50, 60, 70, 80}
  1827  
  1828  	eq(t, true, zero.IsEmpty())
  1829  	eq(t, true, empty.IsEmpty())
  1830  	eq(t, false, full.IsEmpty())
  1831  
  1832  	eq(t, 0, zero.Len())
  1833  	eq(t, 0, empty.Len())
  1834  	eq(t, 8, full.Len())
  1835  
  1836  	testNamedEmpty := func(dict ArgDict) {
  1837  		t.Helper()
  1838  
  1839  		test := func(key string) {
  1840  			t.Helper()
  1841  			val, ok := dict.GotNamed(key)
  1842  			eq(t, nil, val)
  1843  			eq(t, false, ok)
  1844  		}
  1845  
  1846  		test(`-1`)
  1847  		test(`0`)
  1848  		test(`1`)
  1849  		test(`2`)
  1850  		test(`$-1`)
  1851  		test(`-$1`)
  1852  		test(`$0`)
  1853  		test(`$1`)
  1854  		test(`$2`)
  1855  	}
  1856  
  1857  	testNamedEmpty(zero)
  1858  	testNamedEmpty(empty)
  1859  	testNamedEmpty(full)
  1860  
  1861  	testOrdEmpty := func(dict ArgDict) {
  1862  		t.Helper()
  1863  		for key := range counter(64) {
  1864  			val, ok := dict.GotOrdinal(key)
  1865  			eq(t, nil, val)
  1866  			eq(t, false, ok)
  1867  		}
  1868  	}
  1869  
  1870  	testOrdEmpty(zero)
  1871  	testOrdEmpty(empty)
  1872  
  1873  	testOrdFull := func(key int, expVal any, expOk bool) {
  1874  		t.Helper()
  1875  		val, ok := full.GotOrdinal(key)
  1876  		eq(t, expVal, val)
  1877  		eq(t, expOk, ok)
  1878  	}
  1879  
  1880  	testOrdFull(-1, nil, false)
  1881  	testOrdFull(0, 10, true)
  1882  	testOrdFull(1, 20, true)
  1883  	testOrdFull(2, 30, true)
  1884  	testOrdFull(3, 40, true)
  1885  	testOrdFull(4, 50, true)
  1886  	testOrdFull(5, 60, true)
  1887  	testOrdFull(6, 70, true)
  1888  	testOrdFull(7, 80, true)
  1889  	testOrdFull(8, nil, false)
  1890  	testOrdFull(9, nil, false)
  1891  	testOrdFull(10, nil, false)
  1892  	testOrdFull(11, nil, false)
  1893  	testOrdFull(12, nil, false)
  1894  	testOrdFull(13, nil, false)
  1895  	testOrdFull(14, nil, false)
  1896  	testOrdFull(15, nil, false)
  1897  	testOrdFull(16, nil, false)
  1898  }
  1899  
  1900  func TestDict(t *testing.T) {
  1901  	testArgDictMap[Dict](t)
  1902  
  1903  	panics(t, `unused named argument ":two" (key "two")`, func() {
  1904  		tryUnusedNamedArg[Dict]()
  1905  	})
  1906  }
  1907  
  1908  func TestLaxDict(t *testing.T) {
  1909  	testArgDictMap[LaxDict](t)
  1910  	tryUnusedNamedArg[LaxDict]()
  1911  }
  1912  
  1913  func TestStructDict(t *testing.T) {
  1914  	zero := StructDict{}
  1915  	empty := StructDict{r.ValueOf(Void{})}
  1916  	full := benchStructDict
  1917  
  1918  	eq(t, 0, zero.Len())
  1919  	eq(t, 0, empty.Len())
  1920  	eq(t, 0, full.Len())
  1921  
  1922  	testArgDictNamed(t, zero, empty, full)
  1923  }
  1924  
  1925  type ArgDictMap interface {
  1926  	ArgDict
  1927  	~map[string]any
  1928  }
  1929  
  1930  func testArgDictMap[Type ArgDictMap](t *testing.T) {
  1931  	zero := Type(nil)
  1932  	empty := Type{}
  1933  	full := benchDict
  1934  
  1935  	eq(t, 0, zero.Len())
  1936  	eq(t, 0, empty.Len())
  1937  	eq(t, 24, full.Len())
  1938  
  1939  	testArgDictNamed(t, zero, empty, full)
  1940  }
  1941  
  1942  func tryUnusedNamedArg[Type ArgDictMap]() {
  1943  	StrQ{`:one`, Type{`one`: 10, `two`: 20}}.AppendExpr(nil, nil)
  1944  }
  1945  
  1946  func testArgDictNamed(t testing.TB, zero, empty, full ArgDict) {
  1947  	eq(t, true, zero.IsEmpty())
  1948  	eq(t, true, empty.IsEmpty())
  1949  	eq(t, false, full.IsEmpty())
  1950  
  1951  	testOrd := func(val ArgDict) {
  1952  		t.Helper()
  1953  		for key := range counter(64) {
  1954  			val, ok := zero.GotOrdinal(key)
  1955  			eq(t, nil, val)
  1956  			eq(t, false, ok)
  1957  		}
  1958  	}
  1959  
  1960  	testOrd(zero)
  1961  	testOrd(empty)
  1962  	testOrd(full)
  1963  
  1964  	testKeyVal := func(key, exp string) {
  1965  		t.Helper()
  1966  
  1967  		val, ok := zero.GotNamed(key)
  1968  		eq(t, nil, val)
  1969  		eq(t, false, ok)
  1970  
  1971  		val, ok = empty.GotNamed(key)
  1972  		eq(t, nil, val)
  1973  		eq(t, false, ok)
  1974  
  1975  		val, ok = full.GotNamed(key)
  1976  		notEq(t, nil, val)
  1977  		eq(t, true, ok)
  1978  		eq(t, exp, val.(string))
  1979  	}
  1980  
  1981  	testKeyVal(`Key_c603c58746a69833a1528050c33d`, `val_e1436c61440383a80ebdc245b930`)
  1982  	testKeyVal(`Key_abfbb9e94e4093a47683e8ef606b`, `val_a6108ccd40789cecf4da1052c5ae`)
  1983  	testKeyVal(`Key_907b548d45948a206907ed9c9097`, `val_9271789147789ecb2beb11c97a78`)
  1984  	testKeyVal(`Key_5ee2513a41a88d173cd53d389c14`, `val_2b6205fb4bf882ab65f3795b2384`)
  1985  	testKeyVal(`Key_0ac8b89b46bba5d4d076e71d6232`, `val_226b2c3a4c5591084d3a120de2d8`)
  1986  	testKeyVal(`Key_b754f88b42fcbd6c30e3bb544909`, `val_9c639ea74d099446ec3aa2a736a8`)
  1987  	testKeyVal(`Key_e52daa684071891a1dae084bfd00`, `val_71fc2d114b2aaa3b5c1c399d28f6`)
  1988  	testKeyVal(`Key_3106dc324be4b3ff5d477e71c593`, `val_9183d36e4b53a5e2b26ca950a721`)
  1989  	testKeyVal(`Key_a7b558a54d178bdb6fcf3368939b`, `val_f0bc980a408c81a959168aa8aabc`)
  1990  	testKeyVal(`Key_1622da954c8a8f6fec82e6fd3c34`, `val_4afe6fa84722a214e4e777aa6bcf`)
  1991  	testKeyVal(`Key_fa3892644f1392aee8e66b799b3f`, `val_c45ce5ec46b7809d5df5cd1c815b`)
  1992  	testKeyVal(`Key_b9aa15254438b0b7a32489947c50`, `val_6b119aad4bc280a3dfa675fe88a5`)
  1993  
  1994  	testKeyVal(`Key_ce59b8e14f77b6e6e9cd28cecacd`, `val_c76bd35c42d49ccb4408f92fb222`)
  1995  	testKeyVal(`Key_87819a034834a3530b8255e76e4d`, `val_a185f0a946e894d1628bb98b673e`)
  1996  	testKeyVal(`Key_c31042674737a95d1cba33b61687`, `val_02bae4964cfa9ebd23b5d3f57ee6`)
  1997  	testKeyVal(`Key_7bc7a0d346c2b87e3110b2d192d3`, `val_2208de3a476299877d36f149ab94`)
  1998  	testKeyVal(`Key_3b17f4454d44abbbeb2eb5b61235`, `val_dfb68e4d459aa5c649dcb07e0bfb`)
  1999  	testKeyVal(`Key_83e52b714a9d8a0ba6dd87658acf`, `val_2ec2ca5046038e80cfa3cb23dff2`)
  2000  	testKeyVal(`Key_82c96b4d4965a08fa6735e973caa`, `val_fae699f449a1aaf138b1ae2bb9b0`)
  2001  	testKeyVal(`Key_7580ec1f4d42a7aafddf4f818b97`, `val_fc6b97924798b1b790cfb6e31750`)
  2002  	testKeyVal(`Key_bc03a581465c873ceea04027d6ab`, `val_ab22ce72453cb2577aa731dae72c`)
  2003  	testKeyVal(`Key_dcfa83ed4be89cf05d5e3eba6f2a`, `val_b773e8ce401c8313b1400b973fa1`)
  2004  	testKeyVal(`Key_2bc5f64447879c1152ae9b904718`, `val_e9d6438d42339e4c62db260c458b`)
  2005  	testKeyVal(`Key_4f0e9d9b4d1ea77c510337ae6c2a`, `val_60a4b1bf406f98826c706ab153d1`)
  2006  }
  2007  
  2008  func TestPartial(t *testing.T) {
  2009  	t.Run(`Get`, func(t *testing.T) {
  2010  		test := func(val any) {
  2011  			eq(t, val, Partial{val, nil}.Get())
  2012  		}
  2013  
  2014  		test(nil)
  2015  		test(10)
  2016  		test(`str`)
  2017  		test((*Void)(nil))
  2018  		test(Void{})
  2019  		test(&Void{})
  2020  		test(Outer{})
  2021  		test(&Outer{})
  2022  		test(Partial{})
  2023  		test(&Partial{})
  2024  	})
  2025  
  2026  	t.Run(`AllowField`, func(t *testing.T) {
  2027  		test := func(exp bool, val any, fil Haser, tag r.StructTag) {
  2028  			t.Helper()
  2029  			eq(t, exp, Partial{val, fil}.AllowField(r.StructField{Tag: tag}))
  2030  		}
  2031  
  2032  		test(false, nil, nil, ``)
  2033  		test(false, UnitStruct{}, nil, ``)
  2034  		test(false, nil, HaserFalse{}, ``)
  2035  		test(false, UnitStruct{}, HaserFalse{}, ``)
  2036  		test(false, nil, HaserTrue{}, ``)
  2037  		test(false, UnitStruct{}, HaserTrue{}, ``)
  2038  
  2039  		test(false, nil, nil, `json:""`)
  2040  		test(false, UnitStruct{}, nil, `json:""`)
  2041  		test(false, nil, HaserFalse{}, `json:""`)
  2042  		test(false, UnitStruct{}, HaserFalse{}, `json:""`)
  2043  		test(false, nil, HaserTrue{}, `json:""`)
  2044  		test(false, UnitStruct{}, HaserTrue{}, `json:""`)
  2045  
  2046  		test(false, nil, nil, `json:"-"`)
  2047  		test(false, UnitStruct{}, nil, `json:"-"`)
  2048  		test(false, nil, HaserFalse{}, `json:"-"`)
  2049  		test(false, UnitStruct{}, HaserFalse{}, `json:"-"`)
  2050  		test(false, nil, HaserTrue{}, `json:"-"`)
  2051  		test(false, UnitStruct{}, HaserTrue{}, `json:"-"`)
  2052  
  2053  		test(false, nil, nil, `db:"someName"`)
  2054  		test(false, UnitStruct{}, nil, `db:"someName"`)
  2055  		test(false, nil, HaserFalse{}, `db:"someName"`)
  2056  		test(false, UnitStruct{}, HaserFalse{}, `db:"someName"`)
  2057  		test(false, nil, HaserTrue{}, `db:"someName"`)
  2058  		test(false, UnitStruct{}, HaserTrue{}, `db:"someName"`)
  2059  
  2060  		test(false, nil, nil, `json:"someName"`)
  2061  		test(false, UnitStruct{}, nil, `json:"someName"`)
  2062  		test(false, nil, HaserFalse{}, `json:"someName"`)
  2063  		test(false, UnitStruct{}, HaserFalse{}, `json:"someName"`)
  2064  		test(true, nil, HaserTrue{}, `json:"someName"`)
  2065  		test(true, UnitStruct{}, HaserTrue{}, `json:"someName"`)
  2066  	})
  2067  }
  2068  
  2069  // Incomplete, TODO more.
  2070  func TestTryString(t *testing.T) {
  2071  	test := func(exp string, src any) {
  2072  		t.Helper()
  2073  		eq(t, exp, TryString(src))
  2074  	}
  2075  
  2076  	test(``, nil)
  2077  	test(``, ``)
  2078  	test(``, (*string)(nil))
  2079  	test(``, (**string)(nil))
  2080  	test(``, (*int)(nil))
  2081  	test(``, (**int)(nil))
  2082  	test(`one`, `one`)
  2083  	test(`one`, []byte(`one`))
  2084  	test(`0`, 0)
  2085  	test(`10`, 10)
  2086  	test(`123.456`, 123.456)
  2087  	test(`true`, true)
  2088  	test(`false`, false)
  2089  	test(`0001-02-03 04:05:06.000000007 +0000 UTC`, time.Date(1, 2, 3, 4, 5, 6, 7, time.UTC))
  2090  	test(`""`, Ident(``))
  2091  	test(`"one"`, Ident(`one`))
  2092  
  2093  	panics(t, `unsupported type "[]int" of kind "slice"`, func() {
  2094  		TryString([]int(nil))
  2095  	})
  2096  
  2097  	panics(t, `unsupported type "struct {}" of kind "struct"`, func() {
  2098  		TryString(struct{}{})
  2099  	})
  2100  
  2101  	panics(t, `unsupported type "map[int]int" of kind "map"`, func() {
  2102  		TryString((map[int]int)(nil))
  2103  	})
  2104  
  2105  	panics(t, `unsupported type "func(interface {}) string" of kind "func"`, func() {
  2106  		TryString(TryString)
  2107  	})
  2108  
  2109  	panics(t, `unsupported type "chan int" of kind "chan"`, func() {
  2110  		TryString((chan int)(nil))
  2111  	})
  2112  }
  2113  
  2114  // Incomplete, TODO more.
  2115  func TestTryAppend(t *testing.T) {
  2116  	test := func(exp string, src any) {
  2117  		t.Helper()
  2118  		const prefix = `this prefix must be preserved `
  2119  		eq(t, prefix+exp, string(TryAppend([]byte(prefix), src)))
  2120  	}
  2121  
  2122  	test(``, nil)
  2123  	test(``, ``)
  2124  	test(``, (*string)(nil))
  2125  	test(``, (**string)(nil))
  2126  	test(``, (*int)(nil))
  2127  	test(``, (**int)(nil))
  2128  	test(`one`, `one`)
  2129  	test(`one`, []byte(`one`))
  2130  	test(`0`, 0)
  2131  	test(`10`, 10)
  2132  	test(`123.456`, 123.456)
  2133  	test(`true`, true)
  2134  	test(`false`, false)
  2135  	test(`0001-02-03T04:05:06.000000007Z`, time.Date(1, 2, 3, 4, 5, 6, 7, time.UTC))
  2136  	test(`""`, Ident(``))
  2137  	test(`"one"`, Ident(`one`))
  2138  
  2139  	panics(t, `unsupported type "[]int" of kind "slice"`, func() {
  2140  		TryAppend(nil, []int(nil))
  2141  	})
  2142  
  2143  	panics(t, `unsupported type "struct {}" of kind "struct"`, func() {
  2144  		TryAppend(nil, struct{}{})
  2145  	})
  2146  
  2147  	panics(t, `unsupported type "map[int]int" of kind "map"`, func() {
  2148  		TryAppend(nil, (map[int]int)(nil))
  2149  	})
  2150  
  2151  	panics(t, `unsupported type "func([]uint8, interface {}) []uint8" of kind "func"`, func() {
  2152  		TryAppend(nil, TryAppend)
  2153  	})
  2154  
  2155  	panics(t, `unsupported type "chan int" of kind "chan"`, func() {
  2156  		TryAppend(nil, (chan int)(nil))
  2157  	})
  2158  }
  2159  
  2160  func TestSliceCommaAppender(t *testing.T) {
  2161  	test := func(exp string, val Encoder) { testEncoder(t, exp, val) }
  2162  
  2163  	type SCA = SliceCommaAppender
  2164  
  2165  	test(``, SCA{})
  2166  	test(``, SCA{nil})
  2167  	test(``, SCA{SCA{}})
  2168  	test(``, SCA{list(nil)})
  2169  	test(``, SCA{list{}})
  2170  	test(``, SCA{list{nil}})
  2171  	test(``, SCA{list{nil, nil}})
  2172  	test(``, SCA{list{nil, nil}})
  2173  	test(``, SCA{Stringer{nil}})
  2174  	test(``, SCA{list{Stringer{nil}}})
  2175  	test(``, SCA{list{nil, Stringer{}, nil, Stringer{``}}})
  2176  	test(`10`, SCA{list{Stringer{10}}})
  2177  	test(`10`, SCA{list{nil, Stringer{10}, nil}})
  2178  	test(`10`, SCA{list{nil, Stringer{``}, Stringer{10}, nil, Stringer{``}}})
  2179  	test(`10,20`, SCA{list{Stringer{10}, nil, Stringer{20}}})
  2180  	test(`10,20`, SCA{list{nil, Stringer{10}, nil, Stringer{20}, nil, Stringer{``}}})
  2181  	test(`10,20,30`, SCA{list{SCA{Stringer{10}}, SCA{list{Stringer{20}, Stringer{``}, Stringer{30}}}}})
  2182  }
  2183  
  2184  func TestCommaAppender(t *testing.T) {
  2185  	type Type = CommaAppender[AppenderTo]
  2186  
  2187  	test := func(exp string, val Encoder) { testEncoder(t, exp, val) }
  2188  
  2189  	test(``, Type{})
  2190  	test(``, Type{nil, nil, nil})
  2191  	test(``, Type{nil, Type{}, Type{nil}, nil, Stringer{}})
  2192  	test(``, Type{Stringer{nil}})
  2193  	test(``, Type{nil, Stringer{}, nil, Stringer{``}})
  2194  	test(`10`, Type{Stringer{10}})
  2195  	test(`10`, Type{nil, Stringer{10}, nil})
  2196  	test(`10`, Type{nil, Stringer{``}, Stringer{10}, nil, Stringer{``}})
  2197  	test(`10,20`, Type{Stringer{10}, nil, Stringer{20}})
  2198  	test(`10,20`, Type{nil, Stringer{10}, nil, Stringer{20}, nil, Stringer{``}})
  2199  	test(`10,20,30`, Type{Type{Stringer{10}}, Type{Stringer{20}, Stringer{``}, Stringer{30}}})
  2200  }
  2201  
  2202  func TestArrayAppender(t *testing.T) {
  2203  	type Comma = CommaAppender[AppenderTo]
  2204  	type Type = ArrayAppender[AppenderTo]
  2205  
  2206  	test := func(exp string, val Encoder) { testEncoder(t, exp, val) }
  2207  
  2208  	test(`{}`, Type{})
  2209  	test(`{}`, Type{nil, nil, nil})
  2210  	test(`{}`, Type{nil, Comma{}, Comma{nil}, nil, Stringer{}})
  2211  	test(`{{},{}}`, Type{nil, Type{}, Type{nil}, nil, Stringer{}})
  2212  	test(`{}`, Type{Stringer{nil}})
  2213  	test(`{}`, Type{nil, Stringer{}, nil, Stringer{``}})
  2214  	test(`{10}`, Type{Stringer{10}})
  2215  	test(`{10}`, Type{nil, Stringer{10}, nil})
  2216  	test(`{10}`, Type{nil, Stringer{``}, Stringer{10}, nil, Stringer{``}})
  2217  	test(`{10,20}`, Type{Stringer{10}, nil, Stringer{20}})
  2218  	test(`{10,20}`, Type{nil, Stringer{10}, nil, Stringer{20}, nil, Stringer{``}})
  2219  	test(`{10,20,30}`, Type{Comma{Stringer{10}}, Comma{Stringer{20}, Stringer{``}, Stringer{30}}})
  2220  	test(`{{10},{20,30}}`, Type{Type{Stringer{10}}, Type{Stringer{20}, Stringer{``}, Stringer{30}}})
  2221  }
  2222  
  2223  func TestLimit(t *testing.T) {
  2224  	testExpr(t, rei(``), Limit{})
  2225  	testExpr(t, rei(`limit $1`, 0), Limit{0})
  2226  	testExpr(t, rei(`limit $1`, -10), Limit{-10})
  2227  	testExpr(t, rei(`limit $1`, 10), Limit{10})
  2228  	testExpr(t, rei(`limit $1`, ``), Limit{``})
  2229  	testExpr(t, rei(`limit $1`, `one`), Limit{`one`})
  2230  	testExpr(t, rei(`limit ()`), Limit{Str(``)})
  2231  	testExpr(t, rei(`limit (one)`), Limit{Str(`one`)})
  2232  	testExpr(t, rei(`limit ($1)`, 10), Limit{rei(`$1`, 10)})
  2233  
  2234  	testExprs(
  2235  		t,
  2236  		rei(`$1 limit $2 $3 limit ($4)`, 10, 20, 30, 40),
  2237  		rei(`$1`, 10),
  2238  		Limit{20},
  2239  		rei(`$3`, 30),
  2240  		Limit{rei(`$4`, 40)},
  2241  	)
  2242  }
  2243  
  2244  func TestOffset(t *testing.T) {
  2245  	testExpr(t, rei(``), Offset{})
  2246  	testExpr(t, rei(`offset $1`, 0), Offset{0})
  2247  	testExpr(t, rei(`offset $1`, -10), Offset{-10})
  2248  	testExpr(t, rei(`offset $1`, 10), Offset{10})
  2249  	testExpr(t, rei(`offset $1`, ``), Offset{``})
  2250  	testExpr(t, rei(`offset $1`, `one`), Offset{`one`})
  2251  	testExpr(t, rei(`offset ()`), Offset{Str(``)})
  2252  	testExpr(t, rei(`offset (one)`), Offset{Str(`one`)})
  2253  	testExpr(t, rei(`offset ($1)`, 10), Offset{rei(`$1`, 10)})
  2254  
  2255  	testExprs(
  2256  		t,
  2257  		rei(`$1 offset $2 $3 offset ($4)`, 10, 20, 30, 40),
  2258  		rei(`$1`, 10),
  2259  		Offset{20},
  2260  		rei(`$3`, 30),
  2261  		Offset{rei(`$4`, 40)},
  2262  	)
  2263  }
  2264  
  2265  func TestLimitUint(t *testing.T) {
  2266  	testExpr(t, rei(``), LimitUint(0))
  2267  	testExpr(t, rei(`limit 10`), LimitUint(10))
  2268  	testExpr(t, rei(`limit 20`), LimitUint(20))
  2269  
  2270  	testExprs(
  2271  		t,
  2272  		rei(`$1 limit 30 $2 limit 40`, 10, 20),
  2273  		rei(`$1`, 10),
  2274  		LimitUint(30),
  2275  		rei(`$2`, 20),
  2276  		LimitUint(40),
  2277  	)
  2278  }
  2279  
  2280  func TestOffsetUint(t *testing.T) {
  2281  	testExpr(t, rei(``), OffsetUint(0))
  2282  	testExpr(t, rei(`offset 10`), OffsetUint(10))
  2283  	testExpr(t, rei(`offset 20`), OffsetUint(20))
  2284  
  2285  	testExprs(
  2286  		t,
  2287  		rei(`$1 offset 30 $2 offset 40`, 10, 20),
  2288  		rei(`$1`, 10),
  2289  		OffsetUint(30),
  2290  		rei(`$2`, 20),
  2291  		OffsetUint(40),
  2292  	)
  2293  }
  2294  
  2295  func TestReturningAll(t *testing.T) {
  2296  	testExpr(t, rei(`returning *`), ReturningAll{})
  2297  	testExprs(t, rei(`returning *`), ReturningAll{})
  2298  	testExprs(t, rei(`returning * returning *`), ReturningAll{}, ReturningAll{})
  2299  }