github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/tests/integration/database_sql_regression_test.go (about) 1 //go:build integration 2 // +build integration 3 4 package integration 5 6 import ( 7 "context" 8 "database/sql" 9 "errors" 10 "fmt" 11 "math/rand" 12 "testing" 13 "time" 14 15 "github.com/stretchr/testify/require" 16 "github.com/ydb-platform/ydb-go-genproto/protos/Ydb" 17 18 "github.com/ydb-platform/ydb-go-sdk/v3" 19 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors" 20 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xsql/badconn" 21 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xtest" 22 "github.com/ydb-platform/ydb-go-sdk/v3/retry" 23 "github.com/ydb-platform/ydb-go-sdk/v3/table" 24 "github.com/ydb-platform/ydb-go-sdk/v3/table/types" 25 ) 26 27 func TestRegressionCloud109307(t *testing.T) { 28 var ( 29 ctx = xtest.Context(t) 30 scope = newScope(t) 31 db = scope.SQLDriverWithFolder( 32 ydb.WithTablePathPrefix(scope.Folder()), 33 ydb.WithAutoDeclare(), 34 ) 35 ) 36 37 ctx, cancel := context.WithTimeout(ctx, 42*time.Second) 38 defer cancel() 39 40 for i := int64(1); ; i++ { 41 if ctx.Err() != nil { 42 break 43 } 44 45 err := retry.DoTx(ctx, db, func(ctx context.Context, tx *sql.Tx) error { 46 //nolint:gosec 47 if rand.Int31n(3) == 0 { 48 return badconn.Map(xerrors.Operation(xerrors.WithStatusCode(Ydb.StatusIds_BAD_SESSION))) 49 } 50 var rows *sql.Rows 51 rows, err := tx.QueryContext(ctx, `SELECT $i`, sql.Named("i", i)) 52 if err != nil { 53 return err 54 } 55 defer rows.Close() 56 if !rows.Next() { 57 return errors.New("no rows") 58 } 59 var result interface{} 60 if err = rows.Scan(&result); err != nil { 61 return err 62 } 63 if result.(int64)%100 == 0 { 64 t.Logf("result: %+v\n", result) 65 } 66 return rows.Err() 67 }, retry.WithTxOptions(&sql.TxOptions{ 68 Isolation: sql.LevelSnapshot, 69 ReadOnly: true, 70 }), retry.WithIdempotent(true)) 71 if ctx.Err() == nil { 72 require.NoError(t, err) 73 } 74 } 75 } 76 77 func TestRegressionKikimr17104(t *testing.T) { 78 var ( 79 ctx = xtest.Context(t) 80 scope = newScope(t) 81 db = scope.SQLDriverWithFolder( 82 ydb.WithTablePathPrefix(scope.Folder()), 83 ydb.WithAutoDeclare(), 84 ) 85 tableName = t.Name() 86 upsertRowsCount = 100000 87 upsertChecksum uint64 88 ) 89 90 t.Run("data", func(t *testing.T) { 91 t.Run("prepare", func(t *testing.T) { 92 t.Run("scheme", func(t *testing.T) { 93 err := retry.Do(ydb.WithQueryMode(ctx, ydb.SchemeQueryMode), db, 94 func(ctx context.Context, cc *sql.Conn) (err error) { 95 _, err = cc.ExecContext(ctx, 96 fmt.Sprintf("CREATE TABLE %s (val Int32, PRIMARY KEY (val))", tableName), 97 ) 98 if err != nil { 99 return err 100 } 101 return nil 102 }, retry.WithIdempotent(true), 103 ) 104 require.NoError(t, err) 105 }) 106 t.Run("data", func(t *testing.T) { 107 // - upsert data 108 t.Logf("> preparing values to upsert...\n") 109 values := make([]types.Value, 0, upsertRowsCount) 110 for i := 0; i < upsertRowsCount; i++ { 111 upsertChecksum += uint64(i) 112 values = append(values, 113 types.StructValue( 114 types.StructFieldValue("val", types.Int32Value(int32(i))), 115 ), 116 ) 117 } 118 t.Logf("> upsert data\n") 119 err := retry.Do(ydb.WithQueryMode(ctx, ydb.DataQueryMode), db, 120 func(ctx context.Context, cc *sql.Conn) (err error) { 121 _, err = cc.ExecContext(ctx, 122 fmt.Sprintf("UPSERT INTO %s SELECT val FROM AS_TABLE($values);", tableName), 123 table.NewQueryParameters(table.ValueParam("$values", types.ListValue(values...))), 124 ) 125 if err != nil { 126 return err 127 } 128 return nil 129 }, retry.WithIdempotent(true), 130 ) 131 require.NoError(t, err) 132 }) 133 }) 134 t.Run("scan", func(t *testing.T) { 135 t.Run("query", func(t *testing.T) { 136 var ( 137 rowsCount int 138 checkSum uint64 139 ) 140 err := retry.Do(ydb.WithQueryMode(ctx, ydb.ScanQueryMode), db, 141 func(ctx context.Context, cc *sql.Conn) (err error) { 142 var rows *sql.Rows 143 rowsCount = 0 144 checkSum = 0 145 rows, err = cc.QueryContext(ctx, fmt.Sprintf("SELECT val FROM %s", tableName)) 146 if err != nil { 147 return err 148 } 149 for rows.NextResultSet() { 150 for rows.Next() { 151 rowsCount++ 152 var val uint64 153 err = rows.Scan(&val) 154 if err != nil { 155 return err 156 } 157 checkSum += val 158 } 159 } 160 return rows.Err() 161 }, retry.WithIdempotent(true), 162 ) 163 require.NoError(t, err) 164 require.Equal(t, upsertRowsCount, rowsCount) 165 require.Equal(t, upsertChecksum, checkSum) 166 }) 167 }) 168 }) 169 }