github.com/ecodeclub/eorm@v0.0.2-0.20231001112437-dae71da914d0/internal/integration/select_test.go (about)

     1  // Copyright 2021 ecodeclub
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  // http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  //go:build e2e
    16  
    17  package integration
    18  
    19  import (
    20  	"context"
    21  	"database/sql"
    22  	"testing"
    23  
    24  	"github.com/ecodeclub/eorm/internal/errs"
    25  	"github.com/stretchr/testify/require"
    26  
    27  	"github.com/ecodeclub/eorm"
    28  	"github.com/ecodeclub/eorm/internal/test"
    29  	"github.com/stretchr/testify/assert"
    30  	"github.com/stretchr/testify/suite"
    31  )
    32  
    33  type SelectTestSuite struct {
    34  	Suite
    35  	data *test.SimpleStruct
    36  }
    37  
    38  func (s *SelectTestSuite) SetupSuite() {
    39  	s.Suite.SetupSuite()
    40  	s.data = test.NewSimpleStruct(1)
    41  	s.data.Int32Ptr = nil
    42  	res := eorm.NewInserter[test.SimpleStruct](s.orm).Values(s.data).Exec(context.Background())
    43  	if res.Err() != nil {
    44  		s.T().Fatal(res.Err())
    45  	}
    46  }
    47  
    48  func (s *SelectTestSuite) TearDownSuite() {
    49  	res := eorm.RawQuery[any](s.orm, "TRUNCATE TABLE `simple_struct`").Exec(context.Background())
    50  	if res.Err() != nil {
    51  		s.T().Fatal(res.Err())
    52  	}
    53  }
    54  
    55  func (s *SelectTestSuite) TestSelectorGet() {
    56  	testCases := []struct {
    57  		name    string
    58  		s       *eorm.Selector[test.SimpleStruct]
    59  		wantErr error
    60  		wantRes *test.SimpleStruct
    61  	}{
    62  		{
    63  			name: "not found",
    64  			s: eorm.NewSelector[test.SimpleStruct](s.orm).
    65  				Where(eorm.C("Id").EQ(9)),
    66  			wantErr: eorm.ErrNoRows,
    67  		},
    68  		{
    69  			name: "found",
    70  			s: eorm.NewSelector[test.SimpleStruct](s.orm).
    71  				Where(eorm.C("Id").EQ(1)),
    72  			wantRes: s.data,
    73  		},
    74  	}
    75  
    76  	for _, tc := range testCases {
    77  		s.T().Run(tc.name, func(t *testing.T) {
    78  			res, err := tc.s.Get(context.Background())
    79  			assert.Equal(t, tc.wantErr, err)
    80  			if err != nil {
    81  				return
    82  			}
    83  			assert.Equal(t, tc.wantRes, res)
    84  		})
    85  	}
    86  }
    87  
    88  func (s *SelectTestSuite) TestSelectorGetBaseType() {
    89  	testCases := []struct {
    90  		name     string
    91  		queryRes func() (any, error)
    92  		wantErr  string
    93  		wantRes  any
    94  	}{
    95  		{
    96  			name: "not found",
    97  			queryRes: func() (any, error) {
    98  				queryer := eorm.NewSelector[test.SimpleStruct](s.orm).
    99  					Where(eorm.C("Id").EQ(9))
   100  				return queryer.Get(context.Background())
   101  			},
   102  			wantErr: eorm.ErrNoRows.Error(),
   103  		},
   104  		{
   105  			name: "res int",
   106  			queryRes: func() (any, error) {
   107  				queryer := eorm.NewSelector[int](s.orm).Select(eorm.C("Id")).
   108  					From(eorm.TableOf(&test.SimpleStruct{}, "t1")).
   109  					Where(eorm.C("Id").EQ(1))
   110  				return queryer.Get(context.Background())
   111  			},
   112  			wantRes: func() *int {
   113  				res := 1
   114  				return &res
   115  			}(),
   116  		},
   117  		{
   118  			name: "res string",
   119  			queryRes: func() (any, error) {
   120  				queryer := eorm.NewSelector[string](s.orm).Select(eorm.C("String")).
   121  					From(eorm.TableOf(&test.SimpleStruct{}, "t1")).
   122  					Where(eorm.C("Id").EQ(1))
   123  				return queryer.Get(context.Background())
   124  			},
   125  			wantRes: func() *string {
   126  				res := "world"
   127  				return &res
   128  			}(),
   129  		},
   130  		{
   131  			name: "res bytes",
   132  			queryRes: func() (any, error) {
   133  				queryer := eorm.NewSelector[[]byte](s.orm).Select(eorm.C("ByteArray")).
   134  					From(eorm.TableOf(&test.SimpleStruct{}, "t1")).
   135  					Where(eorm.C("Id").EQ(1))
   136  				return queryer.Get(context.Background())
   137  			},
   138  			wantRes: func() *[]byte {
   139  				res := []byte("hello")
   140  				return &res
   141  			}(),
   142  		},
   143  		{
   144  			name: "res bool",
   145  			queryRes: func() (any, error) {
   146  				queryer := eorm.NewSelector[bool](s.orm).Select(eorm.C("Bool")).
   147  					From(eorm.TableOf(&test.SimpleStruct{}, "t1")).
   148  					Where(eorm.C("Id").EQ(1))
   149  				return queryer.Get(context.Background())
   150  			},
   151  			wantRes: func() *bool {
   152  				res := true
   153  				return &res
   154  			}(),
   155  		},
   156  		{
   157  			name: "res null string ptr",
   158  			queryRes: func() (any, error) {
   159  				queryer := eorm.NewSelector[sql.NullString](s.orm).Select(eorm.C("NullStringPtr")).
   160  					From(eorm.TableOf(&test.SimpleStruct{}, "t1")).
   161  					Where(eorm.C("Id").EQ(1))
   162  				return queryer.Get(context.Background())
   163  			},
   164  			wantRes: func() *sql.NullString {
   165  				res := sql.NullString{String: "null string", Valid: true}
   166  				return &res
   167  			}(),
   168  		},
   169  		{
   170  			name: "res null int32 ptr",
   171  			queryRes: func() (any, error) {
   172  				queryer := eorm.NewSelector[sql.NullInt32](s.orm).Select(eorm.C("NullInt32Ptr")).
   173  					From(eorm.TableOf(&test.SimpleStruct{}, "t1")).
   174  					Where(eorm.C("Id").EQ(1))
   175  				return queryer.Get(context.Background())
   176  			},
   177  			wantRes: func() *sql.NullInt32 {
   178  				res := sql.NullInt32{Int32: 32, Valid: true}
   179  				return &res
   180  			}(),
   181  		},
   182  		{
   183  			name: "res null bool ptr",
   184  			queryRes: func() (any, error) {
   185  				queryer := eorm.NewSelector[sql.NullBool](s.orm).Select(eorm.C("NullBoolPtr")).
   186  					From(eorm.TableOf(&test.SimpleStruct{}, "t1")).
   187  					Where(eorm.C("Id").EQ(1))
   188  				return queryer.Get(context.Background())
   189  			},
   190  			wantRes: func() *sql.NullBool {
   191  				res := sql.NullBool{Bool: true, Valid: true}
   192  				return &res
   193  			}(),
   194  		},
   195  		{
   196  			name: "res null float64 ptr",
   197  			queryRes: func() (any, error) {
   198  				queryer := eorm.NewSelector[sql.NullFloat64](s.orm).Select(eorm.C("NullFloat64Ptr")).
   199  					From(eorm.TableOf(&test.SimpleStruct{}, "t1")).
   200  					Where(eorm.C("Id").EQ(1))
   201  				return queryer.Get(context.Background())
   202  			},
   203  			wantRes: func() *sql.NullFloat64 {
   204  				res := sql.NullFloat64{Float64: 6.4, Valid: true}
   205  				return &res
   206  			}(),
   207  		},
   208  		{
   209  			name: "res *int accept NULL",
   210  			queryRes: func() (any, error) {
   211  				queryer := eorm.NewSelector[*int](s.orm).Select(eorm.C("Int32Ptr")).
   212  					From(eorm.TableOf(&test.SimpleStruct{}, "t1")).
   213  					Where(eorm.C("Id").EQ(1))
   214  				return queryer.Get(context.Background())
   215  			},
   216  			wantRes: func() **int {
   217  				return new(*int)
   218  			}(),
   219  		},
   220  		{
   221  			name: "res int accept NULL",
   222  			queryRes: func() (any, error) {
   223  				queryer := eorm.NewSelector[int](s.orm).Select(eorm.C("Int32Ptr")).
   224  					From(eorm.TableOf(&test.SimpleStruct{}, "t1")).
   225  					Where(eorm.C("Id").EQ(1))
   226  				return queryer.Get(context.Background())
   227  			},
   228  			wantErr: "sql: Scan error on column index 0, name \"int32_ptr\": converting NULL to int is unsupported",
   229  		},
   230  	}
   231  
   232  	for _, tc := range testCases {
   233  		s.T().Run(tc.name, func(t *testing.T) {
   234  			res, err := tc.queryRes()
   235  			if err != nil {
   236  				assert.EqualError(t, err, tc.wantErr)
   237  				return
   238  			}
   239  			assert.Equal(t, tc.wantRes, res)
   240  		})
   241  	}
   242  }
   243  
   244  func (s *SelectTestSuite) TestRawQueryGetBaseType() {
   245  	testCases := []struct {
   246  		name     string
   247  		queryRes func() (any, error)
   248  		wantErr  error
   249  		wantRes  any
   250  	}{
   251  		{
   252  			name: "res int",
   253  			queryRes: func() (any, error) {
   254  				queryer := eorm.RawQuery[int](s.orm, "SELECT `id` FROM `simple_struct` WHERE `id` = ?;", 1)
   255  				return queryer.Get(context.Background())
   256  			},
   257  			wantRes: func() *int {
   258  				res := 1
   259  				return &res
   260  			}(),
   261  		},
   262  		{
   263  			name: "res int convert string",
   264  			queryRes: func() (any, error) {
   265  				queryer := eorm.RawQuery[string](s.orm, "SELECT `id` FROM `simple_struct` WHERE `id` = ?;", 1)
   266  				return queryer.Get(context.Background())
   267  			},
   268  			wantRes: func() *string {
   269  				res := "1"
   270  				return &res
   271  			}(),
   272  		},
   273  		{
   274  			name: "res int convert bytes",
   275  			queryRes: func() (any, error) {
   276  				queryer := eorm.RawQuery[[]byte](s.orm, "SELECT `id` FROM `simple_struct` WHERE `id` = ?;", 1)
   277  				return queryer.Get(context.Background())
   278  			},
   279  			wantRes: func() *[]byte {
   280  				res := []byte("1")
   281  				return &res
   282  			}(),
   283  		},
   284  		{
   285  			name: "res string",
   286  			queryRes: func() (any, error) {
   287  				queryer := eorm.RawQuery[string](s.orm, "SELECT `string` FROM `simple_struct` WHERE `id` = ?;", 1)
   288  				return queryer.Get(context.Background())
   289  			},
   290  			wantRes: func() *string {
   291  				res := "world"
   292  				return &res
   293  			}(),
   294  		},
   295  		{
   296  			name: "res string  convert bytes",
   297  			queryRes: func() (any, error) {
   298  				queryer := eorm.RawQuery[[]byte](s.orm, "SELECT `string` FROM `simple_struct` WHERE `id` = ?;", 1)
   299  				return queryer.Get(context.Background())
   300  			},
   301  			wantRes: func() *[]byte {
   302  				res := []byte("world")
   303  				return &res
   304  			}(),
   305  		},
   306  		{
   307  			name: "res bytes",
   308  			queryRes: func() (any, error) {
   309  				queryer := eorm.RawQuery[[]byte](s.orm, "SELECT `byte_array` FROM `simple_struct` WHERE `id` = ?;", 1)
   310  				return queryer.Get(context.Background())
   311  			},
   312  			wantRes: func() *[]byte {
   313  				res := []byte("hello")
   314  				return &res
   315  			}(),
   316  		},
   317  		{
   318  			name: "res bytes convert string",
   319  			queryRes: func() (any, error) {
   320  				queryer := eorm.RawQuery[string](s.orm, "SELECT `byte_array` FROM `simple_struct` WHERE `id` = ?;", 1)
   321  				return queryer.Get(context.Background())
   322  			},
   323  			wantRes: func() *string {
   324  				res := "hello"
   325  				return &res
   326  			}(),
   327  		},
   328  		{
   329  			name: "res bool",
   330  			queryRes: func() (any, error) {
   331  				queryer := eorm.RawQuery[bool](s.orm, "SELECT `bool` FROM `simple_struct` WHERE `id` = ?;", 1)
   332  				return queryer.Get(context.Background())
   333  			},
   334  			wantRes: func() *bool {
   335  				res := true
   336  				return &res
   337  			}(),
   338  		},
   339  		{
   340  			name: "res bool convert string",
   341  			queryRes: func() (any, error) {
   342  				queryer := eorm.RawQuery[string](s.orm, "SELECT `bool` FROM `simple_struct` WHERE `id` = ?;", 1)
   343  				return queryer.Get(context.Background())
   344  			},
   345  			wantRes: func() *string {
   346  				res := "1"
   347  				return &res
   348  			}(),
   349  		},
   350  		{
   351  			name: "res bool convert in",
   352  			queryRes: func() (any, error) {
   353  				queryer := eorm.RawQuery[int](s.orm, "SELECT `bool` FROM `simple_struct` WHERE `id` = ?;", 1)
   354  				return queryer.Get(context.Background())
   355  			},
   356  			wantRes: func() *int {
   357  				res := 1
   358  				return &res
   359  			}(),
   360  		},
   361  		{
   362  			name: "res null string ptr",
   363  			queryRes: func() (any, error) {
   364  				queryer := eorm.RawQuery[sql.NullString](s.orm, "SELECT `null_string_ptr` FROM `simple_struct` WHERE `id` = ?;", 1)
   365  				return queryer.Get(context.Background())
   366  			},
   367  			wantRes: func() *sql.NullString {
   368  				res := sql.NullString{String: "null string", Valid: true}
   369  				return &res
   370  			}(),
   371  		},
   372  		{
   373  			name: "res sring convert null string ptr",
   374  			queryRes: func() (any, error) {
   375  				queryer := eorm.RawQuery[sql.NullString](s.orm, "SELECT `string` FROM `simple_struct` WHERE `id` = ?;", 1)
   376  				return queryer.Get(context.Background())
   377  			},
   378  			wantRes: func() *sql.NullString {
   379  				res := sql.NullString{String: "world", Valid: true}
   380  				return &res
   381  			}(),
   382  		},
   383  	}
   384  
   385  	for _, tc := range testCases {
   386  		s.T().Run(tc.name, func(t *testing.T) {
   387  			res, err := tc.queryRes()
   388  			assert.Equal(t, tc.wantErr, err)
   389  			if err != nil {
   390  				return
   391  			}
   392  			assert.Equal(t, tc.wantRes, res)
   393  		})
   394  	}
   395  }
   396  
   397  func TestMySQL8Select(t *testing.T) {
   398  	suite.Run(t, &SelectTestSuite{
   399  		Suite: Suite{
   400  			driver: "mysql",
   401  			dsn:    "root:root@tcp(localhost:13306)/integration_test",
   402  		},
   403  	})
   404  	suite.Run(t, &SelectTestSuiteGetMulti{
   405  		Suite: Suite{
   406  			driver: "mysql",
   407  			dsn:    "root:root@tcp(localhost:13306)/integration_test",
   408  		},
   409  	})
   410  	suite.Run(t, &SelectTestSuiteJoin{
   411  		Suite: Suite{
   412  			driver: "mysql",
   413  			dsn:    "root:root@tcp(localhost:13306)/integration_test",
   414  		},
   415  	})
   416  	suite.Run(t, &SelectTestSuiteLeftJoin{
   417  		Suite: Suite{
   418  			driver: "mysql",
   419  			dsn:    "root:root@tcp(localhost:13306)/integration_test",
   420  		},
   421  	})
   422  	suite.Run(t, &SelectTestSuiteRightJoin{
   423  		Suite: Suite{
   424  			driver: "mysql",
   425  			dsn:    "root:root@tcp(localhost:13306)/integration_test",
   426  		},
   427  	})
   428  }
   429  
   430  type SelectTestSuiteGetMulti struct {
   431  	Suite
   432  	data []*test.SimpleStruct
   433  }
   434  
   435  func (s *SelectTestSuiteGetMulti) SetupSuite() {
   436  	s.Suite.SetupSuite()
   437  	s.data = append(s.data, test.NewSimpleStruct(1))
   438  	s.data = append(s.data, test.NewSimpleStruct(2))
   439  	s.data = append(s.data, test.NewSimpleStruct(3))
   440  	res := eorm.NewInserter[test.SimpleStruct](s.orm).Values(s.data...).Exec(context.Background())
   441  	if res.Err() != nil {
   442  		s.T().Fatal(res.Err())
   443  	}
   444  }
   445  
   446  func (s *SelectTestSuiteGetMulti) TearDownSuite() {
   447  	res := eorm.RawQuery[any](s.orm, "DELETE FROM `simple_struct`").Exec(context.Background())
   448  	if res.Err() != nil {
   449  		s.T().Fatal(res.Err())
   450  	}
   451  }
   452  
   453  func (s *SelectTestSuiteGetMulti) TestSelectorGetMulti() {
   454  	testCases := []struct {
   455  		name    string
   456  		s       *eorm.Selector[test.SimpleStruct]
   457  		wantErr error
   458  		wantRes []*test.SimpleStruct
   459  	}{
   460  		{
   461  			name: "not found",
   462  			s: eorm.NewSelector[test.SimpleStruct](s.orm).
   463  				Where(eorm.C("Id").EQ(9)),
   464  			wantRes: []*test.SimpleStruct{},
   465  		},
   466  		{
   467  			name: "found",
   468  			s: eorm.NewSelector[test.SimpleStruct](s.orm).
   469  				Where(eorm.C("Id").LT(4)),
   470  			wantRes: s.data,
   471  		},
   472  	}
   473  
   474  	for _, tc := range testCases {
   475  		s.T().Run(tc.name, func(t *testing.T) {
   476  			res, err := tc.s.GetMulti(context.Background())
   477  			assert.Equal(t, tc.wantErr, err)
   478  			if err != nil {
   479  				return
   480  			}
   481  			assert.Equal(t, tc.wantRes, res)
   482  		})
   483  	}
   484  }
   485  
   486  func (s *SelectTestSuiteGetMulti) TestSelectorGetMultiBaseType() {
   487  	testCases := []struct {
   488  		name     string
   489  		queryRes func() (any, error)
   490  		wantErr  error
   491  		wantRes  any
   492  	}{
   493  		{
   494  			name: "res int",
   495  			queryRes: func() (any, error) {
   496  				queryer := eorm.NewSelector[int](s.orm).Select(eorm.C("Id")).From(eorm.TableOf(&test.SimpleStruct{}, "t1"))
   497  				return queryer.GetMulti(context.Background())
   498  			},
   499  			wantRes: func() (res []*int) {
   500  				vals := []int{1, 2, 3}
   501  				for i := 0; i < len(vals); i++ {
   502  					res = append(res, &vals[i])
   503  				}
   504  				return
   505  			}(),
   506  		},
   507  		{
   508  			name: "res string",
   509  			queryRes: func() (any, error) {
   510  				queryer := eorm.NewSelector[string](s.orm).Select(eorm.C("String")).From(eorm.TableOf(&test.SimpleStruct{}, "t1"))
   511  				return queryer.GetMulti(context.Background())
   512  			},
   513  			wantRes: func() (res []*string) {
   514  				vals := []string{"world", "world", "world"}
   515  				for i := 0; i < len(vals); i++ {
   516  					res = append(res, &vals[i])
   517  				}
   518  				return
   519  			}(),
   520  		},
   521  		{
   522  			name: "res bytes",
   523  			queryRes: func() (any, error) {
   524  				queryer := eorm.NewSelector[[]byte](s.orm).Select(eorm.C("ByteArray")).From(eorm.TableOf(&test.SimpleStruct{}, "t1"))
   525  				return queryer.GetMulti(context.Background())
   526  			},
   527  			wantRes: func() (res []*[]byte) {
   528  				vals := [][]byte{[]byte("hello"), []byte("hello"), []byte("hello")}
   529  				for i := 0; i < len(vals); i++ {
   530  					res = append(res, &vals[i])
   531  				}
   532  				return
   533  			}(),
   534  		},
   535  		{
   536  			name: "res bool",
   537  			queryRes: func() (any, error) {
   538  				queryer := eorm.NewSelector[bool](s.orm).Select(eorm.C("Bool")).From(eorm.TableOf(&test.SimpleStruct{}, "t1"))
   539  				return queryer.GetMulti(context.Background())
   540  			},
   541  			wantRes: func() (res []*bool) {
   542  				vals := []bool{true, true, true}
   543  				for i := 0; i < len(vals); i++ {
   544  					res = append(res, &vals[i])
   545  				}
   546  				return
   547  			}(),
   548  		},
   549  		{
   550  			name: "res null string ptr",
   551  			queryRes: func() (any, error) {
   552  				queryer := eorm.NewSelector[sql.NullString](s.orm).Select(eorm.C("NullStringPtr")).From(eorm.TableOf(&test.SimpleStruct{}, "t1"))
   553  				return queryer.GetMulti(context.Background())
   554  			},
   555  			wantRes: []*sql.NullString{
   556  				{
   557  					String: "null string",
   558  					Valid:  true,
   559  				},
   560  				{
   561  					String: "null string",
   562  					Valid:  true,
   563  				},
   564  				{
   565  					String: "null string",
   566  					Valid:  true,
   567  				},
   568  			},
   569  		},
   570  		{
   571  			name: "res null int32 ptr",
   572  			queryRes: func() (any, error) {
   573  				queryer := eorm.NewSelector[sql.NullInt32](s.orm).Select(eorm.C("NullInt32Ptr")).From(eorm.TableOf(&test.SimpleStruct{}, "t1"))
   574  				return queryer.GetMulti(context.Background())
   575  			},
   576  			wantRes: []*sql.NullInt32{
   577  				{
   578  					Int32: 32,
   579  					Valid: true,
   580  				},
   581  				{
   582  					Int32: 32,
   583  					Valid: true,
   584  				},
   585  				{
   586  					Int32: 32,
   587  					Valid: true,
   588  				},
   589  			},
   590  		},
   591  		{
   592  			name: "res null bool ptr",
   593  			queryRes: func() (any, error) {
   594  				queryer := eorm.NewSelector[sql.NullBool](s.orm).Select(eorm.C("NullBoolPtr")).From(eorm.TableOf(&test.SimpleStruct{}, "t1"))
   595  				return queryer.GetMulti(context.Background())
   596  			},
   597  			wantRes: []*sql.NullBool{
   598  				{
   599  					Bool:  true,
   600  					Valid: true,
   601  				},
   602  				{
   603  					Bool:  true,
   604  					Valid: true,
   605  				},
   606  				{
   607  					Bool:  true,
   608  					Valid: true,
   609  				},
   610  			},
   611  		},
   612  		{
   613  			name: "res null float64 ptr",
   614  			queryRes: func() (any, error) {
   615  				queryer := eorm.NewSelector[sql.NullFloat64](s.orm).Select(eorm.C("NullFloat64Ptr")).From(eorm.TableOf(&test.SimpleStruct{}, "t1"))
   616  				return queryer.GetMulti(context.Background())
   617  			},
   618  			wantRes: []*sql.NullFloat64{
   619  				{
   620  					Float64: 6.4,
   621  					Valid:   true,
   622  				},
   623  				{
   624  					Float64: 6.4,
   625  					Valid:   true,
   626  				},
   627  				{
   628  					Float64: 6.4,
   629  					Valid:   true,
   630  				},
   631  			},
   632  		},
   633  	}
   634  
   635  	for _, tc := range testCases {
   636  		s.T().Run(tc.name, func(t *testing.T) {
   637  			res, err := tc.queryRes()
   638  			assert.Equal(t, tc.wantErr, err)
   639  			if err != nil {
   640  				return
   641  			}
   642  			assert.EqualValues(t, tc.wantRes, res)
   643  		})
   644  	}
   645  }
   646  
   647  func (s *SelectTestSuiteGetMulti) TestRawQueryGetMultiBaseType() {
   648  	testCases := []struct {
   649  		name     string
   650  		queryRes func() (any, error)
   651  		wantErr  error
   652  		wantRes  any
   653  	}{
   654  		{
   655  			name: "res int",
   656  			queryRes: func() (any, error) {
   657  				queryer := eorm.RawQuery[int](s.orm, "SELECT `id` FROM `simple_struct`;")
   658  				return queryer.GetMulti(context.Background())
   659  			},
   660  			wantRes: func() (res []*int) {
   661  				vals := []int{1, 2, 3}
   662  				for i := 0; i < len(vals); i++ {
   663  					res = append(res, &vals[i])
   664  				}
   665  				return
   666  			}(),
   667  		},
   668  		{
   669  			name: "res string",
   670  			queryRes: func() (any, error) {
   671  				queryer := eorm.RawQuery[string](s.orm, "SELECT `string` FROM `simple_struct`;")
   672  				return queryer.GetMulti(context.Background())
   673  			},
   674  			wantRes: func() (res []*string) {
   675  				vals := []string{"world", "world", "world"}
   676  				for i := 0; i < len(vals); i++ {
   677  					res = append(res, &vals[i])
   678  				}
   679  				return
   680  			}(),
   681  		},
   682  		{
   683  			name: "res bytes",
   684  			queryRes: func() (any, error) {
   685  				queryer := eorm.RawQuery[[]byte](s.orm, "SELECT `byte_array` FROM `simple_struct`;")
   686  				return queryer.GetMulti(context.Background())
   687  			},
   688  			wantRes: func() (res []*[]byte) {
   689  				vals := [][]byte{[]byte("hello"), []byte("hello"), []byte("hello")}
   690  				for i := 0; i < len(vals); i++ {
   691  					res = append(res, &vals[i])
   692  				}
   693  				return
   694  			}(),
   695  		},
   696  		{
   697  			name: "res bool",
   698  			queryRes: func() (any, error) {
   699  				queryer := eorm.RawQuery[bool](s.orm, "SELECT `bool` FROM `simple_struct`;")
   700  				return queryer.GetMulti(context.Background())
   701  			},
   702  			wantRes: func() (res []*bool) {
   703  				vals := []bool{true, true, true}
   704  				for i := 0; i < len(vals); i++ {
   705  					res = append(res, &vals[i])
   706  				}
   707  				return
   708  			}(),
   709  		},
   710  		{
   711  			name: "res null string ptr",
   712  			queryRes: func() (any, error) {
   713  				queryer := eorm.RawQuery[sql.NullString](s.orm, "SELECT `null_string_ptr` FROM `simple_struct`;")
   714  				return queryer.GetMulti(context.Background())
   715  			},
   716  			wantRes: []*sql.NullString{
   717  				{
   718  					String: "null string",
   719  					Valid:  true,
   720  				},
   721  				{
   722  					String: "null string",
   723  					Valid:  true,
   724  				},
   725  				{
   726  					String: "null string",
   727  					Valid:  true,
   728  				},
   729  			},
   730  		},
   731  	}
   732  
   733  	for _, tc := range testCases {
   734  		s.T().Run(tc.name, func(t *testing.T) {
   735  			res, err := tc.queryRes()
   736  			assert.Equal(t, tc.wantErr, err)
   737  			if err != nil {
   738  				return
   739  			}
   740  			assert.EqualValues(t, tc.wantRes, res)
   741  		})
   742  	}
   743  }
   744  
   745  func (s *SelectTestSuiteGetMulti) TestSelectorDistinct() {
   746  
   747  	testcases := []struct {
   748  		name    string
   749  		s       func() (any, error)
   750  		wantErr error
   751  		wantRes any
   752  	}{
   753  		{
   754  			name: "distinct col",
   755  			s: func() (any, error) {
   756  				return eorm.NewSelector[test.SimpleStruct](s.orm).Select(eorm.C("Int")).Distinct().GetMulti(context.Background())
   757  
   758  			},
   759  			wantRes: []*test.SimpleStruct{
   760  				&test.SimpleStruct{
   761  					Int: 12,
   762  				},
   763  			},
   764  		},
   765  		{
   766  			name: "count distinct",
   767  			s: func() (any, error) {
   768  				return eorm.NewSelector[int](s.orm).Select(eorm.CountDistinct("Bool")).
   769  					From(eorm.TableOf(&test.SimpleStruct{}, "t1")).GetMulti(context.Background())
   770  			},
   771  			wantRes: func() []*int {
   772  				val := 1
   773  				return []*int{&val}
   774  			}(),
   775  		},
   776  		{
   777  			name: "having count distinct",
   778  			s: func() (any, error) {
   779  				return eorm.NewSelector[test.SimpleStruct](s.orm).Select(eorm.C("JsonColumn")).GroupBy("JsonColumn").Having(eorm.CountDistinct("JsonColumn").EQ(1)).GetMulti(context.Background())
   780  			},
   781  			wantRes: []*test.SimpleStruct{
   782  				&test.SimpleStruct{
   783  					JsonColumn: &test.JsonColumn{
   784  						Val:   test.User{Name: "Tom"},
   785  						Valid: true,
   786  					},
   787  				},
   788  			},
   789  		},
   790  	}
   791  	for _, tc := range testcases {
   792  		s.T().Run(tc.name, func(t *testing.T) {
   793  			res, err := tc.s()
   794  			assert.Equal(t, tc.wantErr, err)
   795  			if err != nil {
   796  				return
   797  			}
   798  			assert.Equal(t, tc.wantRes, res)
   799  		})
   800  	}
   801  
   802  }
   803  
   804  func TestMySQL8SelectJoin(t *testing.T) {
   805  	suite.Run(t, &SelectTestSuiteJoin{
   806  		Suite: Suite{
   807  			driver: "mysql",
   808  			dsn:    "root:root@tcp(localhost:13306)/integration_test",
   809  		},
   810  	})
   811  	suite.Run(t, &SelectTestSuiteRightJoin{
   812  		Suite: Suite{
   813  			driver: "mysql",
   814  			dsn:    "root:root@tcp(localhost:13306)/integration_test",
   815  		},
   816  	})
   817  	suite.Run(t, &SelectTestSuiteLeftJoin{
   818  		Suite: Suite{
   819  			driver: "mysql",
   820  			dsn:    "root:root@tcp(localhost:13306)/integration_test",
   821  		},
   822  	})
   823  }
   824  
   825  type SelectTestSuiteJoin struct {
   826  	Suite
   827  	data []*test.Order
   828  }
   829  
   830  func (s *SelectTestSuiteJoin) SetupSuite() {
   831  	s.Suite.SetupSuite()
   832  	initSql(s.orm, s.T())
   833  }
   834  
   835  func (s *SelectTestSuiteJoin) TearDownSuite() {
   836  	res := eorm.RawQuery[any](s.orm, "DELETE FROM `order`").Exec(context.Background())
   837  	require.NoError(s.T(), res.Err())
   838  	res = eorm.RawQuery[any](s.orm, "DELETE FROM `order_detail`").Exec(context.Background())
   839  	require.NoError(s.T(), res.Err())
   840  	res = eorm.RawQuery[any](s.orm, "DELETE FROM `item`").Exec(context.Background())
   841  	require.NoError(s.T(), res.Err())
   842  }
   843  func (s *SelectTestSuiteJoin) TestSelectorJoin() {
   844  	testCases := []struct {
   845  		name    string
   846  		s       func() (any, error)
   847  		wantErr error
   848  		wantRes any
   849  	}{
   850  		{
   851  			name: "join",
   852  			s: func() (any, error) {
   853  				t1 := eorm.TableOf(&test.Order{}, "t1")
   854  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
   855  				t3 := t1.LeftJoin(t2).Using("UsingCol1", "UsingCol2")
   856  				return eorm.NewSelector[test.Order](s.orm).Select(t1.AllColumns()).From(t3).Get(context.Background())
   857  			},
   858  			wantRes: &test.Order{Id: 1, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
   859  		},
   860  		{
   861  			name: "join As",
   862  			s: func() (any, error) {
   863  				t1 := eorm.TableOf(&test.Order{}, "t1")
   864  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
   865  				t3 := t1.Join(t2).On(t1.C("Id").EQ(t2.C("OrderId")))
   866  				return eorm.NewSelector[test.Order](s.orm).Select(t1.AllColumns()).From(t3).Get(context.Background())
   867  			},
   868  			wantRes: &test.Order{Id: 1, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
   869  		},
   870  		{
   871  			name: "join using col",
   872  			s: func() (any, error) {
   873  				t1 := eorm.TableOf(&test.Order{}, "t1")
   874  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
   875  				t3 := t1.Join(t2).Using("UsingCol1", "UsingCol2")
   876  				return eorm.NewSelector[test.Order](s.orm).Select(t1.AllColumns()).From(t3).Get(context.Background())
   877  			},
   878  			wantRes: &test.Order{Id: 1, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
   879  		},
   880  		{
   881  			name: "join using invalid col",
   882  			s: func() (any, error) {
   883  				t1 := eorm.TableOf(&test.Order{}, "t1")
   884  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
   885  				t3 := t1.Join(t2).Using("invalid", "UsingCol2")
   886  				return eorm.NewSelector[test.Order](s.orm).Select(t1.AllColumns()).From(t3).Get(context.Background())
   887  			},
   888  			wantErr: errs.NewInvalidFieldError("invalid"),
   889  		},
   890  		{
   891  			name: "join Avg",
   892  			s: func() (any, error) {
   893  				t1 := eorm.TableOf(&test.Order{}, "t1")
   894  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
   895  				t3 := t1.Join(t2).On(t1.C("Id").EQ(t2.C("OrderId")))
   896  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.Avg("UsingCol1").As("using_col1"), t1.Avg("UsingCol2").As("using_col2")).Get(context.Background())
   897  			},
   898  			wantRes: &test.Order{Id: 0, UsingCol1: "0", UsingCol2: "0"},
   899  		},
   900  		{
   901  			name: "join Avg invalid",
   902  			s: func() (any, error) {
   903  				t1 := eorm.TableOf(&test.Order{}, "t1")
   904  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
   905  				t3 := t1.Join(t2).On(t1.C("Id").EQ(t2.C("OrderId")))
   906  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.Avg("invalid").As("using_col1"), t1.Avg("UsingCol2").As("using_col2")).Get(context.Background())
   907  			},
   908  			wantErr: errs.NewInvalidFieldError("invalid"),
   909  		},
   910  		{
   911  			name: "join col",
   912  			s: func() (any, error) {
   913  				t1 := eorm.TableOf(&test.Order{}, "t1")
   914  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
   915  				t3 := t1.Join(t2).On(t1.C("Id").EQ(t2.C("OrderId")))
   916  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.C("UsingCol1"), t2.C("UsingCol2")).Get(context.Background())
   917  			},
   918  			wantRes: &test.Order{Id: 0, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
   919  		},
   920  		{
   921  			name: "join col invalid",
   922  			s: func() (any, error) {
   923  				t1 := eorm.TableOf(&test.Order{}, "t1")
   924  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
   925  				t3 := t1.Join(t2).On(t1.C("Id").EQ(t2.C("OrderId")))
   926  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.C("invalid"), t2.C("UsingCol2")).Get(context.Background())
   927  			},
   928  			wantErr: errs.NewInvalidFieldError("invalid"),
   929  		},
   930  	}
   931  
   932  	for _, tc := range testCases {
   933  		s.T().Run(tc.name, func(t *testing.T) {
   934  			res, err := tc.s()
   935  			assert.Equal(t, tc.wantErr, err)
   936  			if err != nil {
   937  				return
   938  			}
   939  			assert.Equal(t, tc.wantRes, res)
   940  		})
   941  	}
   942  }
   943  
   944  // SelectTestSuiteLeftJoin left join
   945  
   946  type SelectTestSuiteLeftJoin struct {
   947  	Suite
   948  	data []*test.SimpleStruct
   949  }
   950  
   951  func (s *SelectTestSuiteLeftJoin) SetupSuite() {
   952  	s.Suite.SetupSuite()
   953  	initSql(s.orm, s.T())
   954  }
   955  
   956  func (s *SelectTestSuiteLeftJoin) TearDownSuite() {
   957  	res := eorm.RawQuery[any](s.orm, "DELETE FROM `order`").Exec(context.Background())
   958  	require.NoError(s.T(), res.Err())
   959  	res = eorm.RawQuery[any](s.orm, "DELETE FROM `order_detail`").Exec(context.Background())
   960  	require.NoError(s.T(), res.Err())
   961  	res = eorm.RawQuery[any](s.orm, "DELETE FROM `item`").Exec(context.Background())
   962  	require.NoError(s.T(), res.Err())
   963  }
   964  
   965  func (s *SelectTestSuiteLeftJoin) TestSelectorLeftJoin() {
   966  	testCases := []struct {
   967  		name    string
   968  		s       func() (any, error)
   969  		wantErr error
   970  		wantRes any
   971  	}{
   972  		{
   973  			name: "left join",
   974  			s: func() (any, error) {
   975  				t1 := eorm.TableOf(&test.Order{}, "t1")
   976  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
   977  				t3 := t1.LeftJoin(t2).Using("UsingCol1", "UsingCol2")
   978  				return eorm.NewSelector[test.Order](s.orm).Select(t1.AllColumns()).From(t3).Get(context.Background())
   979  			},
   980  			wantRes: &test.Order{Id: 1, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
   981  		},
   982  		{
   983  			name: "left join col",
   984  			s: func() (any, error) {
   985  				t1 := eorm.TableOf(&test.Order{}, "t1")
   986  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
   987  				t3 := t1.LeftJoin(t2).On(t1.C("Id").EQ(t2.C("OrderId")))
   988  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.C("UsingCol1")).Get(context.Background())
   989  			},
   990  			wantRes: &test.Order{Id: 0, UsingCol1: "usingcoa1_1", UsingCol2: ""},
   991  		},
   992  		{
   993  			name: "left join invalid col",
   994  			s: func() (any, error) {
   995  				t1 := eorm.TableOf(&test.Order{}, "t1")
   996  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
   997  				t3 := t1.LeftJoin(t2).On(t1.C("Id").EQ(t2.C("OrderId")))
   998  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.C("invalid")).Get(context.Background())
   999  			},
  1000  			wantErr: errs.NewInvalidFieldError("invalid"),
  1001  		},
  1002  		{
  1003  			name: "left join using col",
  1004  			s: func() (any, error) {
  1005  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1006  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
  1007  				t3 := t1.LeftJoin(t2).Using("UsingCol1", "UsingCol2")
  1008  				return eorm.NewSelector[test.Order](s.orm).Select(t1.AllColumns()).From(t3).Get(context.Background())
  1009  			},
  1010  			wantRes: &test.Order{Id: 1, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
  1011  		},
  1012  		{
  1013  			name: "left join using invalid col",
  1014  			s: func() (any, error) {
  1015  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1016  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
  1017  				t3 := t1.LeftJoin(t2).Using("invalid", "UsingCol2")
  1018  				return eorm.NewSelector[test.Order](s.orm).Select(t1.AllColumns()).From(t3).Get(context.Background())
  1019  			},
  1020  			wantErr: errs.NewInvalidFieldError("invalid"),
  1021  		},
  1022  		{
  1023  			name: "left join Avg ",
  1024  			s: func() (any, error) {
  1025  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1026  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
  1027  				t3 := t1.LeftJoin(t2).Using("UsingCol1", "UsingCol2")
  1028  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.Avg("UsingCol1").As("using_col1")).Get(context.Background())
  1029  			},
  1030  			wantRes: &test.Order{Id: 0, UsingCol1: "0", UsingCol2: ""},
  1031  		},
  1032  		{
  1033  			name: "left join Avg invalid",
  1034  			s: func() (any, error) {
  1035  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1036  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
  1037  				t3 := t1.LeftJoin(t2).Using("UsingCol1", "UsingCol2")
  1038  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.Avg("invalid").As("using_col1")).Get(context.Background())
  1039  			},
  1040  			wantErr: errs.NewInvalidFieldError("invalid"),
  1041  		},
  1042  	}
  1043  
  1044  	for _, tc := range testCases {
  1045  		s.T().Run(tc.name, func(t *testing.T) {
  1046  			res, err := tc.s()
  1047  			assert.Equal(t, tc.wantErr, err)
  1048  			if err != nil {
  1049  				return
  1050  			}
  1051  			assert.Equal(t, tc.wantRes, res)
  1052  		})
  1053  	}
  1054  }
  1055  
  1056  type SelectTestSuiteRightJoin struct {
  1057  	Suite
  1058  	data []*test.SimpleStruct
  1059  }
  1060  
  1061  func (s *SelectTestSuiteRightJoin) SetupSuite() {
  1062  	s.Suite.SetupSuite()
  1063  	initSql(s.orm, s.T())
  1064  }
  1065  
  1066  func (s *SelectTestSuiteRightJoin) TearDownSuite() {
  1067  	res := eorm.RawQuery[any](s.orm, "DELETE FROM `order`").Exec(context.Background())
  1068  	require.NoError(s.T(), res.Err())
  1069  	res = eorm.RawQuery[any](s.orm, "DELETE FROM `order_detail`").Exec(context.Background())
  1070  	require.NoError(s.T(), res.Err())
  1071  	res = eorm.RawQuery[any](s.orm, "DELETE FROM `item`").Exec(context.Background())
  1072  	require.NoError(s.T(), res.Err())
  1073  }
  1074  
  1075  func (s *SelectTestSuiteRightJoin) TestSelectorRightJoin() {
  1076  	testCases := []struct {
  1077  		name    string
  1078  		s       func() (any, error)
  1079  		wantErr error
  1080  		wantRes any
  1081  	}{
  1082  		{
  1083  			name: "Right join",
  1084  			s: func() (any, error) {
  1085  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1086  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
  1087  				t3 := t1.RightJoin(t2).Using("UsingCol1", "UsingCol2")
  1088  				return eorm.NewSelector[test.Order](s.orm).Select(t1.AllColumns()).From(t3).Get(context.Background())
  1089  			},
  1090  			wantRes: &test.Order{Id: 1, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
  1091  		},
  1092  		{
  1093  			name: "right join col",
  1094  			s: func() (any, error) {
  1095  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1096  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
  1097  				t3 := t1.RightJoin(t2).On(t1.C("Id").EQ(t2.C("OrderId")))
  1098  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.C("UsingCol1")).Get(context.Background())
  1099  			},
  1100  			wantRes: &test.Order{Id: 0, UsingCol1: "usingcoa1_1", UsingCol2: ""},
  1101  		},
  1102  		{
  1103  			name: "right join invalid col",
  1104  			s: func() (any, error) {
  1105  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1106  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
  1107  				t3 := t1.RightJoin(t2).Using("UsingCol1", "UsingCol2")
  1108  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.C("invalid")).Get(context.Background())
  1109  			},
  1110  			wantErr: errs.NewInvalidFieldError("invalid"),
  1111  		},
  1112  		{
  1113  			name: "right join using col",
  1114  			s: func() (any, error) {
  1115  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1116  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
  1117  				t3 := t1.RightJoin(t2).Using("UsingCol1", "UsingCol2")
  1118  				return eorm.NewSelector[test.Order](s.orm).Select(t1.AllColumns()).From(t3).Get(context.Background())
  1119  			},
  1120  			wantRes: &test.Order{Id: 1, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
  1121  		},
  1122  		{
  1123  			name: "right join using invalid col",
  1124  			s: func() (any, error) {
  1125  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1126  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
  1127  				t3 := t1.RightJoin(t2).Using("invalid", "UsingCol2")
  1128  				return eorm.NewSelector[test.Order](s.orm).Select(t1.AllColumns()).From(t3).Get(context.Background())
  1129  			},
  1130  			wantErr: errs.NewInvalidFieldError("invalid"),
  1131  		},
  1132  		{
  1133  			name: "right join Avg",
  1134  			s: func() (any, error) {
  1135  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1136  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
  1137  				t3 := t1.RightJoin(t2).Using("UsingCol1", "UsingCol2")
  1138  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.Avg("UsingCol1").As("using_col1")).Get(context.Background())
  1139  			},
  1140  			wantRes: &test.Order{Id: 0, UsingCol1: "0", UsingCol2: ""},
  1141  		},
  1142  		{
  1143  			name: "right join Avg invalid",
  1144  			s: func() (any, error) {
  1145  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1146  				t2 := eorm.TableOf(&test.OrderDetail{}, "t2")
  1147  				t3 := t1.RightJoin(t2).Using("UsingCol1", "UsingCol2")
  1148  				return eorm.NewSelector[test.Order](s.orm).From(t3).Select(t1.Avg("invalid").As("using_col1")).Get(context.Background())
  1149  			},
  1150  			wantErr: errs.NewInvalidFieldError("invalid"),
  1151  		},
  1152  		// 子查詢
  1153  		{
  1154  			name: "join & subquery",
  1155  			s: func() (any, error) {
  1156  				t1 := eorm.TableOf(&test.Order{}, "t1")
  1157  				sub := eorm.NewSelector[test.OrderDetail](s.orm).AsSubquery("sub")
  1158  				return eorm.NewSelector[test.Order](s.orm).
  1159  					Select(eorm.C("Id"), sub.C("UsingCol1")).
  1160  					From(t1.Join(sub).On(t1.C("Id").EQ(sub.C("OrderId")))).
  1161  					Get(context.Background())
  1162  			},
  1163  			wantRes: &test.Order{Id: 1, UsingCol1: "usingcoa1_1", UsingCol2: ""},
  1164  		},
  1165  		{
  1166  			name: "from",
  1167  			s: func() (any, error) {
  1168  				sub := eorm.NewSelector[test.OrderDetail](s.orm).AsSubquery("sub")
  1169  				return eorm.NewSelector[test.Order](s.orm).
  1170  					Select(sub.C("UsingCol1")).
  1171  					From(sub).
  1172  					Where().Get(context.Background())
  1173  			},
  1174  			wantRes: &test.Order{Id: 0, UsingCol1: "usingcoa1_1", UsingCol2: ""},
  1175  		},
  1176  		{
  1177  			name: "in",
  1178  			s: func() (any, error) {
  1179  				sub := eorm.NewSelector[test.OrderDetail](s.orm).Select(eorm.C("OrderId")).AsSubquery("sub")
  1180  				return eorm.NewSelector[test.Order](s.orm).
  1181  					Select(eorm.Columns("Id")).Where(eorm.C("Id").In(sub)).
  1182  					Get(context.Background())
  1183  			},
  1184  			wantRes: &test.Order{Id: 1, UsingCol1: "", UsingCol2: ""},
  1185  		},
  1186  		{
  1187  			name: "all",
  1188  			s: func() (any, error) {
  1189  				sub := eorm.NewSelector[test.OrderDetail](s.orm).Select(eorm.C("OrderId")).AsSubquery("sub")
  1190  				return eorm.NewSelector[test.Order](s.orm).
  1191  					Select(eorm.Columns("Id")).
  1192  					Where(eorm.C("Id").GT(eorm.All(sub))).
  1193  					Get(context.Background())
  1194  			},
  1195  			wantErr: eorm.ErrNoRows,
  1196  		},
  1197  	}
  1198  
  1199  	for _, tc := range testCases {
  1200  		s.T().Run(tc.name, func(t *testing.T) {
  1201  			res, err := tc.s()
  1202  			assert.Equal(t, tc.wantErr, err)
  1203  			if err != nil {
  1204  				return
  1205  			}
  1206  			assert.Equal(t, tc.wantRes, res)
  1207  		})
  1208  	}
  1209  }
  1210  
  1211  func initSql(orm *eorm.DB, t *testing.T) {
  1212  	orderRes := eorm.NewInserter[test.Order](orm).Values(&test.Order{Id: 1, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
  1213  		&test.Order{Id: 2, UsingCol1: "usingcoa1_8", UsingCol2: "usingcoa1_2"},
  1214  		&test.Order{Id: 3, UsingCol1: "usingcoa1_2", UsingCol2: "usingcoa1_2"},
  1215  		&test.Order{Id: 4, UsingCol1: "usingcoa1_5", UsingCol2: "usingcoa1_2"},
  1216  	).Exec(context.Background())
  1217  	require.NoError(t, orderRes.Err())
  1218  	orderDetailRes := eorm.NewInserter[test.OrderDetail](orm).Values(&test.OrderDetail{OrderId: 1, ItemId: 1, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
  1219  		&test.OrderDetail{OrderId: 2, ItemId: 1, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
  1220  		&test.OrderDetail{OrderId: 3, ItemId: 2, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
  1221  		&test.OrderDetail{OrderId: 4, ItemId: 2, UsingCol1: "usingcoa1_1", UsingCol2: "usingcoa1_2"},
  1222  	).Exec(context.Background())
  1223  	require.NoError(t, orderDetailRes.Err())
  1224  
  1225  	itemRes := eorm.NewInserter[test.Item](orm).Values(&test.Item{Id: 1}, &test.Item{Id: 2}, &test.Item{Id: 3}).Exec(context.Background())
  1226  	require.NoError(t, itemRes.Err())
  1227  
  1228  }