github.com/snowflakedb/gosnowflake@v1.9.0/htap_test.go (about)

     1  package gosnowflake
     2  
     3  import (
     4  	"context"
     5  	"database/sql/driver"
     6  	"fmt"
     7  	"reflect"
     8  	"strconv"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  )
    13  
    14  func TestSortingByPriority(t *testing.T) {
    15  	qcc := (&queryContextCache{}).init()
    16  	sc := htapTestSnowflakeConn()
    17  
    18  	qceA := queryContextEntry{ID: 12, Timestamp: 123, Priority: 7, Context: "a"}
    19  	qceB := queryContextEntry{ID: 13, Timestamp: 124, Priority: 9, Context: "b"}
    20  	qceC := queryContextEntry{ID: 14, Timestamp: 125, Priority: 6, Context: "c"}
    21  	qceD := queryContextEntry{ID: 15, Timestamp: 126, Priority: 8, Context: "d"}
    22  
    23  	t.Run("Add to empty cache", func(t *testing.T) {
    24  		qcc.add(sc, qceA)
    25  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceA}) {
    26  			t.Fatalf("no entries added to cache. %v", qcc.entries)
    27  		}
    28  	})
    29  	t.Run("Add another entry with different id, timestamp and priority - greater priority", func(t *testing.T) {
    30  		qcc.add(sc, qceB)
    31  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceA, qceB}) {
    32  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
    33  		}
    34  	})
    35  	t.Run("Add another entry with different id, timestamp and priority - lesser priority", func(t *testing.T) {
    36  		qcc.add(sc, qceC)
    37  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceC, qceA, qceB}) {
    38  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
    39  		}
    40  	})
    41  	t.Run("Add another entry with different id, timestamp and priority - priority in the middle", func(t *testing.T) {
    42  		qcc.add(sc, qceD)
    43  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceC, qceA, qceD, qceB}) {
    44  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
    45  		}
    46  	})
    47  }
    48  
    49  func TestAddingQcesWithTheSameIdAndLaterTimestamp(t *testing.T) {
    50  	qcc := (&queryContextCache{}).init()
    51  	sc := htapTestSnowflakeConn()
    52  
    53  	qceA := queryContextEntry{ID: 12, Timestamp: 123, Priority: 7, Context: "a"}
    54  	qceB := queryContextEntry{ID: 13, Timestamp: 124, Priority: 9, Context: "b"}
    55  	qceC := queryContextEntry{ID: 12, Timestamp: 125, Priority: 6, Context: "c"}
    56  	qceD := queryContextEntry{ID: 12, Timestamp: 126, Priority: 6, Context: "d"}
    57  
    58  	t.Run("Add to empty cache", func(t *testing.T) {
    59  		qcc.add(sc, qceA)
    60  		qcc.add(sc, qceB)
    61  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceA, qceB}) {
    62  			t.Fatalf("no entries added to cache. %v", qcc.entries)
    63  		}
    64  	})
    65  	t.Run("Add another entry with different priority", func(t *testing.T) {
    66  		qcc.add(sc, qceC)
    67  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceC, qceB}) {
    68  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
    69  		}
    70  	})
    71  	t.Run("Add another entry with same priority", func(t *testing.T) {
    72  		qcc.add(sc, qceD)
    73  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceD, qceB}) {
    74  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
    75  		}
    76  	})
    77  }
    78  
    79  func TestAddingQcesWithTheSameIdAndSameTimestamp(t *testing.T) {
    80  	qcc := (&queryContextCache{}).init()
    81  	sc := htapTestSnowflakeConn()
    82  
    83  	qceA := queryContextEntry{ID: 12, Timestamp: 123, Priority: 7, Context: "a"}
    84  	qceB := queryContextEntry{ID: 13, Timestamp: 124, Priority: 9, Context: "b"}
    85  	qceC := queryContextEntry{ID: 12, Timestamp: 123, Priority: 6, Context: "c"}
    86  	qceD := queryContextEntry{ID: 12, Timestamp: 123, Priority: 6, Context: "d"}
    87  
    88  	t.Run("Add to empty cache", func(t *testing.T) {
    89  		qcc.add(sc, qceA)
    90  		qcc.add(sc, qceB)
    91  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceA, qceB}) {
    92  			t.Fatalf("no entries added to cache. %v", qcc.entries)
    93  		}
    94  	})
    95  	t.Run("Add another entry with different priority", func(t *testing.T) {
    96  		qcc.add(sc, qceC)
    97  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceC, qceB}) {
    98  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
    99  		}
   100  	})
   101  	t.Run("Add another entry with same priority", func(t *testing.T) {
   102  		qcc.add(sc, qceD)
   103  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceC, qceB}) {
   104  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
   105  		}
   106  	})
   107  }
   108  
   109  func TestAddingQcesWithTheSameIdAndEarlierTimestamp(t *testing.T) {
   110  	qcc := (&queryContextCache{}).init()
   111  	sc := htapTestSnowflakeConn()
   112  
   113  	qceA := queryContextEntry{ID: 12, Timestamp: 123, Priority: 7, Context: "a"}
   114  	qceB := queryContextEntry{ID: 13, Timestamp: 124, Priority: 9, Context: "b"}
   115  	qceC := queryContextEntry{ID: 12, Timestamp: 122, Priority: 6, Context: "c"}
   116  	qceD := queryContextEntry{ID: 12, Timestamp: 122, Priority: 7, Context: "d"}
   117  
   118  	t.Run("Add to empty cache", func(t *testing.T) {
   119  		qcc.add(sc, qceA)
   120  		qcc.add(sc, qceB)
   121  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceA, qceB}) {
   122  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
   123  		}
   124  	})
   125  	t.Run("Add another entry with different priority", func(t *testing.T) {
   126  		qcc.add(sc, qceC)
   127  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceA, qceB}) {
   128  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
   129  		}
   130  	})
   131  	t.Run("Add another entry with same priority", func(t *testing.T) {
   132  		qcc.add(sc, qceD)
   133  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceA, qceB}) {
   134  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
   135  		}
   136  	})
   137  }
   138  
   139  func TestAddingQcesWithDifferentId(t *testing.T) {
   140  	qcc := (&queryContextCache{}).init()
   141  	sc := htapTestSnowflakeConn()
   142  
   143  	qceA := queryContextEntry{ID: 12, Timestamp: 123, Priority: 7, Context: "a"}
   144  	qceB := queryContextEntry{ID: 13, Timestamp: 124, Priority: 9, Context: "b"}
   145  	qceC := queryContextEntry{ID: 14, Timestamp: 122, Priority: 7, Context: "c"}
   146  	qceD := queryContextEntry{ID: 15, Timestamp: 122, Priority: 6, Context: "d"}
   147  
   148  	t.Run("Add to empty cache", func(t *testing.T) {
   149  		qcc.add(sc, qceA)
   150  		qcc.add(sc, qceB)
   151  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceA, qceB}) {
   152  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
   153  		}
   154  	})
   155  	t.Run("Add another entry with same priority", func(t *testing.T) {
   156  		qcc.add(sc, qceC)
   157  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceC, qceB}) {
   158  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
   159  		}
   160  	})
   161  	t.Run("Add another entry with different priority", func(t *testing.T) {
   162  		qcc.add(sc, qceD)
   163  		if !reflect.DeepEqual(qcc.entries, []queryContextEntry{qceD, qceC, qceB}) {
   164  			t.Fatalf("unexpected qcc entries. %v", qcc.entries)
   165  		}
   166  	})
   167  }
   168  
   169  func TestAddingQueryContextCacheEntry(t *testing.T) {
   170  	runSnowflakeConnTest(t, func(sct *SCTest) {
   171  		t.Run("First query (may be on empty cache)", func(t *testing.T) {
   172  			entriesBefore := make([]queryContextEntry, len(sct.sc.queryContextCache.entries))
   173  			copy(entriesBefore, sct.sc.queryContextCache.entries)
   174  			sct.mustQuery("SELECT 1", nil)
   175  			entriesAfter := sct.sc.queryContextCache.entries
   176  
   177  			if !containsNewEntries(entriesAfter, entriesBefore) {
   178  				t.Error("no new entries added to the query context cache")
   179  			}
   180  		})
   181  
   182  		t.Run("Second query (cache should not be empty)", func(t *testing.T) {
   183  			entriesBefore := make([]queryContextEntry, len(sct.sc.queryContextCache.entries))
   184  			copy(entriesBefore, sct.sc.queryContextCache.entries)
   185  			if len(entriesBefore) == 0 {
   186  				t.Fatalf("cache should not be empty after first query")
   187  			}
   188  			sct.mustQuery("SELECT 2", nil)
   189  			entriesAfter := sct.sc.queryContextCache.entries
   190  
   191  			if !containsNewEntries(entriesAfter, entriesBefore) {
   192  				t.Error("no new entries added to the query context cache")
   193  			}
   194  		})
   195  	})
   196  }
   197  
   198  func containsNewEntries(entriesAfter []queryContextEntry, entriesBefore []queryContextEntry) bool {
   199  	if len(entriesAfter) > len(entriesBefore) {
   200  		return true
   201  	}
   202  
   203  	for _, entryAfter := range entriesAfter {
   204  		for _, entryBefore := range entriesBefore {
   205  			if !reflect.DeepEqual(entryBefore, entryAfter) {
   206  				return true
   207  			}
   208  		}
   209  	}
   210  
   211  	return false
   212  }
   213  
   214  func TestPruneBySessionValue(t *testing.T) {
   215  	qce1 := queryContextEntry{1, 1, 1, ""}
   216  	qce2 := queryContextEntry{2, 2, 2, ""}
   217  	qce3 := queryContextEntry{3, 3, 3, ""}
   218  
   219  	testcases := []struct {
   220  		size     string
   221  		expected []queryContextEntry
   222  	}{
   223  		{
   224  			size:     "1",
   225  			expected: []queryContextEntry{qce1},
   226  		},
   227  		{
   228  			size:     "2",
   229  			expected: []queryContextEntry{qce1, qce2},
   230  		},
   231  		{
   232  			size:     "3",
   233  			expected: []queryContextEntry{qce1, qce2, qce3},
   234  		},
   235  		{
   236  			size:     "4",
   237  			expected: []queryContextEntry{qce1, qce2, qce3},
   238  		},
   239  	}
   240  
   241  	for _, tc := range testcases {
   242  		t.Run(tc.size, func(t *testing.T) {
   243  			sc := &snowflakeConn{
   244  				cfg: &Config{
   245  					Params: map[string]*string{
   246  						queryContextCacheSizeParamName: &tc.size,
   247  					},
   248  				},
   249  			}
   250  
   251  			qcc := (&queryContextCache{}).init()
   252  
   253  			qcc.add(sc, qce1)
   254  			qcc.add(sc, qce2)
   255  			qcc.add(sc, qce3)
   256  
   257  			if !reflect.DeepEqual(qcc.entries, tc.expected) {
   258  				t.Errorf("unexpected cache entries. expected: %v, got: %v", tc.expected, qcc.entries)
   259  			}
   260  		})
   261  	}
   262  }
   263  
   264  func TestPruneByDefaultValue(t *testing.T) {
   265  	qce1 := queryContextEntry{1, 1, 1, ""}
   266  	qce2 := queryContextEntry{2, 2, 2, ""}
   267  	qce3 := queryContextEntry{3, 3, 3, ""}
   268  	qce4 := queryContextEntry{4, 4, 4, ""}
   269  	qce5 := queryContextEntry{5, 5, 5, ""}
   270  	qce6 := queryContextEntry{6, 6, 6, ""}
   271  
   272  	sc := &snowflakeConn{
   273  		cfg: &Config{
   274  			Params: map[string]*string{},
   275  		},
   276  	}
   277  
   278  	qcc := (&queryContextCache{}).init()
   279  	qcc.add(sc, qce1)
   280  	qcc.add(sc, qce2)
   281  	qcc.add(sc, qce3)
   282  	qcc.add(sc, qce4)
   283  	qcc.add(sc, qce5)
   284  
   285  	if len(qcc.entries) != 5 {
   286  		t.Fatalf("Expected 5 elements, got: %v", len(qcc.entries))
   287  	}
   288  
   289  	qcc.add(sc, qce6)
   290  	if len(qcc.entries) != 5 {
   291  		t.Fatalf("Expected 5 elements, got: %v", len(qcc.entries))
   292  	}
   293  }
   294  
   295  func TestNoQcesClearsCache(t *testing.T) {
   296  	qce1 := queryContextEntry{1, 1, 1, ""}
   297  
   298  	sc := &snowflakeConn{
   299  		cfg: &Config{
   300  			Params: map[string]*string{},
   301  		},
   302  	}
   303  
   304  	qcc := (&queryContextCache{}).init()
   305  	qcc.add(sc, qce1)
   306  
   307  	if len(qcc.entries) != 1 {
   308  		t.Fatalf("improperly inited cache")
   309  	}
   310  
   311  	qcc.add(sc)
   312  
   313  	if len(qcc.entries) != 0 {
   314  		t.Errorf("after adding empty context list cache should be cleared")
   315  	}
   316  }
   317  
   318  func htapTestSnowflakeConn() *snowflakeConn {
   319  	return &snowflakeConn{
   320  		cfg: &Config{
   321  			Params: map[string]*string{},
   322  		},
   323  	}
   324  }
   325  
   326  func TestQueryContextCacheDisabled(t *testing.T) {
   327  	origDsn := dsn
   328  	defer func() {
   329  		dsn = origDsn
   330  	}()
   331  	dsn += "&disableQueryContextCache=true"
   332  	runSnowflakeConnTest(t, func(sct *SCTest) {
   333  		sct.mustExec("SELECT 1", nil)
   334  		if len(sct.sc.queryContextCache.entries) > 0 {
   335  			t.Error("should not contain any entries")
   336  		}
   337  	})
   338  }
   339  
   340  func TestHybridTablesE2E(t *testing.T) {
   341  	skipOnJenkins(t, "HTAP is not enabled on environment")
   342  	if runningOnGithubAction() && !runningOnAWS() {
   343  		t.Skip("HTAP is enabled only on AWS")
   344  	}
   345  	runID := time.Now().UnixMilli()
   346  	testDb1 := fmt.Sprintf("hybrid_db_test_%v", runID)
   347  	testDb2 := fmt.Sprintf("hybrid_db_test_%v_2", runID)
   348  	runSnowflakeConnTest(t, func(sct *SCTest) {
   349  		dbQuery := sct.mustQuery("SELECT CURRENT_DATABASE()", nil)
   350  		defer dbQuery.Close()
   351  		currentDb := make([]driver.Value, 1)
   352  		dbQuery.Next(currentDb)
   353  		defer func() {
   354  			sct.mustExec(fmt.Sprintf("USE DATABASE %v", currentDb[0]), nil)
   355  			sct.mustExec(fmt.Sprintf("DROP DATABASE IF EXISTS %v", testDb1), nil)
   356  			sct.mustExec(fmt.Sprintf("DROP DATABASE IF EXISTS %v", testDb2), nil)
   357  		}()
   358  
   359  		t.Run("Run tests on first database", func(t *testing.T) {
   360  			sct.mustExec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %v", testDb1), nil)
   361  			sct.mustExec("CREATE HYBRID TABLE test_hybrid_table (id INT PRIMARY KEY, text VARCHAR)", nil)
   362  
   363  			sct.mustExec("INSERT INTO test_hybrid_table VALUES (1, 'a')", nil)
   364  			rows := sct.mustQuery("SELECT * FROM test_hybrid_table", nil)
   365  			defer rows.Close()
   366  			row := make([]driver.Value, 2)
   367  			rows.Next(row)
   368  			if row[0] != "1" || row[1] != "a" {
   369  				t.Errorf("expected 1, got %v and expected a, got %v", row[0], row[1])
   370  			}
   371  
   372  			sct.mustExec("INSERT INTO test_hybrid_table VALUES (2, 'b')", nil)
   373  			rows2 := sct.mustQuery("SELECT * FROM test_hybrid_table", nil)
   374  			defer rows2.Close()
   375  			rows2.Next(row)
   376  			if row[0] != "1" || row[1] != "a" {
   377  				t.Errorf("expected 1, got %v and expected a, got %v", row[0], row[1])
   378  			}
   379  			rows2.Next(row)
   380  			if row[0] != "2" || row[1] != "b" {
   381  				t.Errorf("expected 2, got %v and expected b, got %v", row[0], row[1])
   382  			}
   383  			if len(sct.sc.queryContextCache.entries) != 2 {
   384  				t.Errorf("expected two entries in query context cache, got: %v", sct.sc.queryContextCache.entries)
   385  			}
   386  		})
   387  		t.Run("Run tests on second database", func(t *testing.T) {
   388  			sct.mustExec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %v", testDb2), nil)
   389  			sct.mustExec("CREATE HYBRID TABLE test_hybrid_table_2 (id INT PRIMARY KEY, text VARCHAR)", nil)
   390  			sct.mustExec("INSERT INTO test_hybrid_table_2 VALUES (3, 'c')", nil)
   391  
   392  			rows := sct.mustQuery("SELECT * FROM test_hybrid_table_2", nil)
   393  			defer rows.Close()
   394  			row := make([]driver.Value, 2)
   395  			rows.Next(row)
   396  			if row[0] != "3" || row[1] != "c" {
   397  				t.Errorf("expected 3, got %v and expected c, got %v", row[0], row[1])
   398  			}
   399  			if len(sct.sc.queryContextCache.entries) != 3 {
   400  				t.Errorf("expected three entries in query context cache, got: %v", sct.sc.queryContextCache.entries)
   401  			}
   402  		})
   403  		t.Run("Run tests on first database again", func(t *testing.T) {
   404  			sct.mustExec(fmt.Sprintf("USE DATABASE %v", testDb1), nil)
   405  
   406  			sct.mustExec("INSERT INTO test_hybrid_table VALUES (4, 'd')", nil)
   407  
   408  			rows := sct.mustQuery("SELECT * FROM test_hybrid_table", nil)
   409  			defer rows.Close()
   410  			if len(sct.sc.queryContextCache.entries) != 3 {
   411  				t.Errorf("expected three entries in query context cache, got: %v", sct.sc.queryContextCache.entries)
   412  			}
   413  		})
   414  	})
   415  }
   416  
   417  func TestHTAPOptimizations(t *testing.T) {
   418  	if runningOnGithubAction() {
   419  		t.Skip("insufficient permissions")
   420  	}
   421  	for _, useHtapOptimizations := range []bool{true, false} {
   422  		runSnowflakeConnTest(t, func(sct *SCTest) {
   423  			t.Run("useHtapOptimizations="+strconv.FormatBool(useHtapOptimizations), func(t *testing.T) {
   424  				if useHtapOptimizations {
   425  					sct.mustExec("ALTER SESSION SET ENABLE_SNOW_654741_FOR_TESTING = true", nil)
   426  				}
   427  				runID := time.Now().UnixMilli()
   428  				t.Run("Schema", func(t *testing.T) {
   429  					newSchema := fmt.Sprintf("test_schema_%v", runID)
   430  					if strings.EqualFold(sct.sc.cfg.Schema, newSchema) {
   431  						t.Errorf("schema should not be switched")
   432  					}
   433  
   434  					sct.mustExec(fmt.Sprintf("CREATE SCHEMA %v", newSchema), nil)
   435  					defer sct.mustExec(fmt.Sprintf("DROP SCHEMA %v", newSchema), nil)
   436  
   437  					if !strings.EqualFold(sct.sc.cfg.Schema, newSchema) {
   438  						t.Errorf("schema should be switched, expected %v, got %v", newSchema, sct.sc.cfg.Schema)
   439  					}
   440  
   441  					query := sct.mustQuery("SELECT 1", nil)
   442  					query.Close()
   443  
   444  					if !strings.EqualFold(sct.sc.cfg.Schema, newSchema) {
   445  						t.Errorf("schema should be switched, expected %v, got %v", newSchema, sct.sc.cfg.Schema)
   446  					}
   447  				})
   448  				t.Run("Database", func(t *testing.T) {
   449  					newDatabase := fmt.Sprintf("test_database_%v", runID)
   450  					if strings.EqualFold(sct.sc.cfg.Database, newDatabase) {
   451  						t.Errorf("database should not be switched")
   452  					}
   453  
   454  					sct.mustExec(fmt.Sprintf("CREATE DATABASE %v", newDatabase), nil)
   455  					defer sct.mustExec(fmt.Sprintf("DROP DATABASE %v", newDatabase), nil)
   456  
   457  					if !strings.EqualFold(sct.sc.cfg.Database, newDatabase) {
   458  						t.Errorf("database should be switched, expected %v, got %v", newDatabase, sct.sc.cfg.Database)
   459  					}
   460  
   461  					query := sct.mustQuery("SELECT 1", nil)
   462  					query.Close()
   463  
   464  					if !strings.EqualFold(sct.sc.cfg.Database, newDatabase) {
   465  						t.Errorf("database should be switched, expected %v, got %v", newDatabase, sct.sc.cfg.Database)
   466  					}
   467  				})
   468  				t.Run("Warehouse", func(t *testing.T) {
   469  					newWarehouse := fmt.Sprintf("test_warehouse_%v", runID)
   470  					if strings.EqualFold(sct.sc.cfg.Warehouse, newWarehouse) {
   471  						t.Errorf("warehouse should not be switched")
   472  					}
   473  
   474  					sct.mustExec(fmt.Sprintf("CREATE WAREHOUSE %v", newWarehouse), nil)
   475  					defer sct.mustExec(fmt.Sprintf("DROP WAREHOUSE %v", newWarehouse), nil)
   476  
   477  					if !strings.EqualFold(sct.sc.cfg.Warehouse, newWarehouse) {
   478  						t.Errorf("warehouse should be switched, expected %v, got %v", newWarehouse, sct.sc.cfg.Warehouse)
   479  					}
   480  
   481  					query := sct.mustQuery("SELECT 1", nil)
   482  					query.Close()
   483  
   484  					if !strings.EqualFold(sct.sc.cfg.Warehouse, newWarehouse) {
   485  						t.Errorf("warehouse should be switched, expected %v, got %v", newWarehouse, sct.sc.cfg.Warehouse)
   486  					}
   487  				})
   488  				t.Run("Role", func(t *testing.T) {
   489  					if strings.EqualFold(sct.sc.cfg.Role, "PUBLIC") {
   490  						t.Errorf("role should not be public for this test")
   491  					}
   492  
   493  					sct.mustExec("USE ROLE public", nil)
   494  
   495  					if !strings.EqualFold(sct.sc.cfg.Role, "PUBLIC") {
   496  						t.Errorf("role should be switched, expected public, got %v", sct.sc.cfg.Role)
   497  					}
   498  
   499  					query := sct.mustQuery("SELECT 1", nil)
   500  					query.Close()
   501  
   502  					if !strings.EqualFold(sct.sc.cfg.Role, "PUBLIC") {
   503  						t.Errorf("role should be switched, expected public, got %v", sct.sc.cfg.Role)
   504  					}
   505  				})
   506  				t.Run("Session param - DATE_OUTPUT_FORMAT", func(t *testing.T) {
   507  					if !strings.EqualFold(*sct.sc.cfg.Params["date_output_format"], "YYYY-MM-DD") {
   508  						t.Errorf("should use default date_output_format, but got: %v", *sct.sc.cfg.Params["date_output_format"])
   509  					}
   510  
   511  					sct.mustExec("ALTER SESSION SET DATE_OUTPUT_FORMAT = 'DD-MM-YYYY'", nil)
   512  					defer sct.mustExec("ALTER SESSION SET DATE_OUTPUT_FORMAT = 'YYYY-MM-DD'", nil)
   513  
   514  					if !strings.EqualFold(*sct.sc.cfg.Params["date_output_format"], "DD-MM-YYYY") {
   515  						t.Errorf("date output format should be switched, expected DD-MM-YYYY, got %v", sct.sc.cfg.Params["date_output_format"])
   516  					}
   517  
   518  					query := sct.mustQuery("SELECT 1", nil)
   519  					query.Close()
   520  
   521  					if !strings.EqualFold(*sct.sc.cfg.Params["date_output_format"], "DD-MM-YYYY") {
   522  						t.Errorf("date output format should be switched, expected DD-MM-YYYY, got %v", sct.sc.cfg.Params["date_output_format"])
   523  					}
   524  				})
   525  			})
   526  		})
   527  	}
   528  }
   529  
   530  func TestConnIsCleanAfterClose(t *testing.T) {
   531  	// We create a new db here to not use the default pool as we can leave it in dirty state.
   532  	t.Skip("Fails, because connection is returned to a pool dirty")
   533  	ctx := context.Background()
   534  	runID := time.Now().UnixMilli()
   535  
   536  	db := openDB(t)
   537  	defer db.Close()
   538  	db.SetMaxOpenConns(1)
   539  
   540  	conn, err := db.Conn(ctx)
   541  	if err != nil {
   542  		t.Fatal(err)
   543  	}
   544  	defer conn.Close()
   545  
   546  	dbt := DBTest{t, conn}
   547  
   548  	dbt.mustExec(forceJSON)
   549  
   550  	var dbName string
   551  	rows1 := dbt.mustQuery("SELECT CURRENT_DATABASE()")
   552  	rows1.Next()
   553  	rows1.Scan(&dbName)
   554  
   555  	newDbName := fmt.Sprintf("test_database_%v", runID)
   556  	dbt.mustExec("CREATE DATABASE " + newDbName)
   557  
   558  	rows1.Close()
   559  	conn.Close()
   560  
   561  	conn2, err := db.Conn(ctx)
   562  	if err != nil {
   563  		t.Fatal(err)
   564  	}
   565  
   566  	dbt2 := DBTest{t, conn2}
   567  
   568  	var dbName2 string
   569  	rows2 := dbt2.mustQuery("SELECT CURRENT_DATABASE()")
   570  	defer rows2.Close()
   571  	rows2.Next()
   572  	rows2.Scan(&dbName2)
   573  
   574  	if !strings.EqualFold(dbName, dbName2) {
   575  		t.Errorf("fresh connection from pool should have original database")
   576  	}
   577  }