github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/query/example_test.go (about)

     1  //go:build go1.23
     2  
     3  package query_test
     4  
     5  import (
     6  	"context"
     7  	"errors"
     8  	"fmt"
     9  	"io"
    10  	"time"
    11  
    12  	"github.com/ydb-platform/ydb-go-sdk/v3"
    13  	baseTx "github.com/ydb-platform/ydb-go-sdk/v3/internal/tx"
    14  	"github.com/ydb-platform/ydb-go-sdk/v3/query"
    15  )
    16  
    17  func Example_queryWithMaterializedResult() {
    18  	ctx := context.TODO()
    19  	db, err := ydb.Open(ctx, "grpc://localhost:2136/local")
    20  	if err != nil {
    21  		panic(err)
    22  	}
    23  	defer db.Close(ctx) // cleanup resources
    24  	var (
    25  		id    int32  // required value
    26  		myStr string // optional value
    27  	)
    28  	// Do retry operation on errors with best effort
    29  	materilizedResult, err := db.Query().Query(ctx, // context manage exiting from Do
    30  		`SELECT 42 as id, "my string" as myStr`,
    31  		query.WithIdempotent(),
    32  	)
    33  	if err != nil {
    34  		panic(err)
    35  	}
    36  	defer func() {
    37  		_ = materilizedResult.Close(ctx)
    38  	}()
    39  
    40  	for rs, err := range materilizedResult.ResultSets(ctx) {
    41  		if err != nil {
    42  			panic(err)
    43  		}
    44  		for row, err := range rs.Rows(ctx) {
    45  			if err != nil {
    46  				panic(err)
    47  			}
    48  			err = row.ScanNamed(
    49  				query.Named("id", &id),
    50  				query.Named("myStr", &myStr),
    51  			)
    52  			if err != nil {
    53  				panic(err)
    54  			}
    55  		}
    56  	}
    57  
    58  	fmt.Printf("id=%v, myStr='%s'\n", id, myStr)
    59  }
    60  
    61  func Example_queryWithMaterializedResultSet() {
    62  	ctx := context.TODO()
    63  	db, err := ydb.Open(ctx, "grpc://localhost:2136/local")
    64  	if err != nil {
    65  		panic(err)
    66  	}
    67  	defer db.Close(ctx) // cleanup resources
    68  	var (
    69  		id    int32  // required value
    70  		myStr string // optional value
    71  	)
    72  	// Do retry operation on errors with best effort
    73  	materilizedResultSet, err := db.Query().QueryResultSet(ctx, // context manage exiting from Do
    74  		`SELECT 42 as id, "my string" as myStr`,
    75  		query.WithIdempotent(),
    76  	)
    77  	if err != nil {
    78  		panic(err)
    79  	}
    80  
    81  	for row, err := range materilizedResultSet.Rows(ctx) {
    82  		if err != nil {
    83  			panic(err)
    84  		}
    85  		err = row.ScanNamed(
    86  			query.Named("id", &id),
    87  			query.Named("myStr", &myStr),
    88  		)
    89  		if err != nil {
    90  			panic(err)
    91  		}
    92  	}
    93  
    94  	fmt.Printf("id=%v, myStr='%s'\n", id, myStr)
    95  }
    96  
    97  func Example_queryRow() {
    98  	ctx := context.TODO()
    99  	db, err := ydb.Open(ctx, "grpc://localhost:2136/local")
   100  	if err != nil {
   101  		panic(err)
   102  	}
   103  	defer db.Close(ctx) // cleanup resources
   104  	var (
   105  		id    int32  // required value
   106  		myStr string // optional value
   107  	)
   108  	// Do retry operation on errors with best effort
   109  	row, err := db.Query().QueryRow(ctx, // context manage exiting from Do
   110  		`SELECT 42 as id, "my string" as myStr`,
   111  		query.WithIdempotent(),
   112  	)
   113  	if err != nil {
   114  		panic(err)
   115  	}
   116  
   117  	err = row.ScanNamed(
   118  		query.Named("id", &id),
   119  		query.Named("myStr", &myStr),
   120  	)
   121  	if err != nil {
   122  		panic(err)
   123  	}
   124  
   125  	fmt.Printf("id=%v, myStr='%s'\n", id, myStr)
   126  }
   127  
   128  func Example_explain() {
   129  	ctx := context.TODO()
   130  	db, err := ydb.Open(ctx, "grpc://localhost:2136/local")
   131  	if err != nil {
   132  		panic(err)
   133  	}
   134  	defer db.Close(ctx) // cleanup resources
   135  	var (
   136  		ast  string
   137  		plan string
   138  	)
   139  	err = db.Query().Exec(ctx,
   140  		`SELECT CAST(42 AS Uint32);`,
   141  		query.WithExecMode(query.ExecModeExplain),
   142  		query.WithStatsMode(query.StatsModeNone, func(stats query.Stats) {
   143  			ast = stats.QueryAST()
   144  			plan = stats.QueryPlan()
   145  		}),
   146  		query.WithIdempotent(),
   147  	)
   148  	if err != nil {
   149  		panic(err)
   150  	}
   151  	fmt.Println(plan)
   152  	fmt.Println(ast)
   153  }
   154  
   155  func Example_withoutRangeIterators() {
   156  	ctx := context.TODO()
   157  	db, err := ydb.Open(ctx, "grpc://localhost:2136/local")
   158  	if err != nil {
   159  		panic(err)
   160  	}
   161  	defer db.Close(ctx) // cleanup resources
   162  	var (
   163  		id    int32  // required value
   164  		myStr string // optional value
   165  	)
   166  	materializedResult, err := db.Query().Query(ctx, `SELECT 42 as id, "my string" as myStr`,
   167  		query.WithIdempotent(),
   168  	)
   169  	if err != nil {
   170  		panic(err)
   171  	}
   172  	for {
   173  		rs, err := materializedResult.NextResultSet(ctx)
   174  		if err != nil {
   175  			if errors.Is(err, io.EOF) {
   176  				break
   177  			}
   178  			panic(err)
   179  		}
   180  		for {
   181  			row, err := rs.NextRow(ctx)
   182  			if err != nil {
   183  				if errors.Is(err, io.EOF) {
   184  					break
   185  				}
   186  				panic(err)
   187  			}
   188  			err = row.ScanNamed(
   189  				query.Named("id", &id),
   190  				query.Named("myStr", &myStr),
   191  			)
   192  			if err != nil {
   193  				panic(err)
   194  			}
   195  
   196  			fmt.Printf("id=%v, myStr='%s'\n", id, myStr)
   197  		}
   198  	}
   199  }
   200  
   201  func Example_selectWithParameters() {
   202  	ctx := context.TODO()
   203  	db, err := ydb.Open(ctx, "grpc://localhost:2136/local")
   204  	if err != nil {
   205  		panic(err)
   206  	}
   207  	defer db.Close(ctx) // cleanup resources
   208  	var (
   209  		id    int32  // required value
   210  		myStr string // required value
   211  	)
   212  	// Do retry operation on errors with best effort
   213  	row, err := db.Query().QueryRow(ctx, // context manage exiting from Do
   214  		`SELECT CAST($id AS Uint64) AS id, CAST($myStr AS Text) AS myStr`,
   215  		query.WithParameters(
   216  			ydb.ParamsBuilder().
   217  				Param("$id").Uint64(123).
   218  				Param("$myStr").Text("123").
   219  				Build(),
   220  		),
   221  		query.WithIdempotent(),
   222  	)
   223  	if err != nil {
   224  		panic(err)
   225  	}
   226  
   227  	err = row.ScanNamed(
   228  		query.Named("id", &id),
   229  		query.Named("myStr", &myStr),
   230  	)
   231  	if err != nil {
   232  		panic(err)
   233  	}
   234  
   235  	fmt.Printf("id=%v, myStr='%s'\n", id, myStr)
   236  }
   237  
   238  func Example_resultStats() {
   239  	ctx := context.TODO()
   240  	db, err := ydb.Open(ctx, "grpc://localhost:2136/local")
   241  	if err != nil {
   242  		panic(err)
   243  	}
   244  	defer db.Close(ctx) // cleanup resources
   245  	var (
   246  		id    int32  // required value
   247  		myStr string // required value
   248  	)
   249  	var stats query.Stats
   250  	// Do retry operation on errors with best effort
   251  	row, err := db.Query().QueryRow(ctx, // context manage exiting from Do
   252  		`SELECT CAST($id AS Uint64) AS id, CAST($myStr AS Text) AS myStr`,
   253  		query.WithParameters(
   254  			ydb.ParamsBuilder().
   255  				Param("$id").Uint64(123).
   256  				Param("$myStr").Text("123").
   257  				Build(),
   258  		),
   259  		query.WithStatsMode(query.StatsModeFull, func(s query.Stats) {
   260  			stats = s
   261  		}),
   262  		query.WithIdempotent(),
   263  	)
   264  	if err != nil {
   265  		panic(err)
   266  	}
   267  
   268  	err = row.ScanNamed(
   269  		query.Named("id", &id),
   270  		query.Named("myStr", &myStr),
   271  	)
   272  	if err != nil {
   273  		panic(err)
   274  	}
   275  
   276  	fmt.Printf("id=%v, myStr='%s'\n", id, myStr)
   277  	fmt.Println("Stats:")
   278  	fmt.Printf("- Compilation='%v'\n", stats.Compilation())
   279  	fmt.Printf("- TotalCPUTime='%v'\n", stats.TotalCPUTime())
   280  	fmt.Printf("- ProcessCPUTime='%v'\n", stats.ProcessCPUTime())
   281  	fmt.Printf("- QueryAST='%v'\n", stats.QueryAST())
   282  	fmt.Printf("- QueryPlan='%v'\n", stats.QueryPlan())
   283  	fmt.Println("- Phases:")
   284  	for {
   285  		phase, ok := stats.NextPhase()
   286  		if !ok {
   287  			break
   288  		}
   289  		fmt.Printf("  - CPUTime='%v'\n", phase.CPUTime())
   290  		fmt.Printf("  - Duration='%v'\n", phase.Duration())
   291  		fmt.Printf("  - IsLiteralPhase='%v'\n", phase.IsLiteralPhase())
   292  		fmt.Printf("  - AffectedShards='%v'\n", phase.AffectedShards())
   293  		fmt.Println("  - TableAccesses:")
   294  		for {
   295  			tableAccess, ok := phase.NextTableAccess()
   296  			if !ok {
   297  				break
   298  			}
   299  			fmt.Printf("    - %v\n", tableAccess)
   300  		}
   301  	}
   302  }
   303  
   304  func Example_retryWithSessions() {
   305  	ctx := context.TODO()
   306  	db, err := ydb.Open(ctx, "grpc://localhost:2136/local")
   307  	if err != nil {
   308  		panic(err)
   309  	}
   310  	defer db.Close(ctx) // cleanup resources
   311  	var (
   312  		id    int32  // required value
   313  		myStr string // required value
   314  	)
   315  	// Do retry operation on errors with best effort
   316  	err = db.Query().Do(ctx, func(ctx context.Context, s query.Session) error {
   317  		streamResult, err := s.Query(ctx, // context manage exiting from Do
   318  			`SELECT CAST($id AS Uint64) AS id, CAST($myStr AS Text) AS myStr`,
   319  			query.WithParameters(
   320  				ydb.ParamsBuilder().
   321  					Param("$id").Uint64(123).
   322  					Param("$myStr").Text("123").
   323  					Build(),
   324  			),
   325  		)
   326  		if err != nil {
   327  			panic(err)
   328  		}
   329  		defer func() {
   330  			_ = streamResult.Close(ctx)
   331  		}()
   332  
   333  		for rs, err := range streamResult.ResultSets(ctx) {
   334  			if err != nil {
   335  				return err
   336  			}
   337  			for row, err := range rs.Rows(ctx) {
   338  				if err != nil {
   339  					return err
   340  				}
   341  				err = row.ScanNamed(
   342  					query.Named("id", &id),
   343  					query.Named("myStr", &myStr),
   344  				)
   345  				if err != nil {
   346  					panic(err)
   347  				}
   348  			}
   349  		}
   350  
   351  		return nil
   352  	}, query.WithIdempotent())
   353  	if err != nil {
   354  		panic(err)
   355  	}
   356  
   357  	fmt.Printf("id=%v, myStr='%s'\n", id, myStr)
   358  }
   359  
   360  func Example_retryWithTx() {
   361  	ctx := context.TODO()
   362  	db, err := ydb.Open(ctx, "grpc://localhost:2136/local")
   363  	if err != nil {
   364  		fmt.Printf("failed connect: %v", err)
   365  
   366  		return
   367  	}
   368  	defer db.Close(ctx) // cleanup resources
   369  	var (
   370  		id    int32  // required value
   371  		myStr string // optional value
   372  	)
   373  	// Do retry operation on errors with best effort
   374  	err = db.Query().DoTx(ctx, // context manage exiting from Do
   375  		func(ctx context.Context, tx query.TxActor) (err error) { // retry operation
   376  			res, err := tx.Query(ctx,
   377  				`SELECT 42 as id, "my string" as myStr`,
   378  			)
   379  			if err != nil {
   380  				return err // for auto-retry with driver
   381  			}
   382  			defer func() { _ = res.Close(ctx) }() // cleanup resources
   383  			// for loop with ResultSets available with Go version 1.23+
   384  			for rs, err := range res.ResultSets(ctx) {
   385  				if err != nil {
   386  					return err
   387  				}
   388  				// for loop with ResultSets available with Go version 1.23+
   389  				for row, err := range rs.Rows(ctx) {
   390  					if err != nil {
   391  						return err
   392  					}
   393  					if err = row.ScanNamed(
   394  						query.Named("id", &id),
   395  						query.Named("myStr", &myStr),
   396  					); err != nil {
   397  						return err // generally scan error not retryable, return it for driver check error
   398  					}
   399  				}
   400  			}
   401  
   402  			return nil
   403  		},
   404  		query.WithIdempotent(),
   405  		query.WithTxSettings(query.TxSettings(
   406  			query.WithSnapshotReadOnly(),
   407  		)),
   408  	)
   409  	if err != nil {
   410  		fmt.Printf("unexpected error: %v", err)
   411  	}
   412  	fmt.Printf("id=%v, myStr='%s'\n", id, myStr)
   413  }
   414  
   415  func Example_retryWithLazyTx() {
   416  	ctx := context.TODO()
   417  	db, err := ydb.Open(ctx, "grpc://localhost:2136/local",
   418  		ydb.WithLazyTx(true),
   419  	)
   420  	if err != nil {
   421  		fmt.Printf("failed connect: %v", err)
   422  
   423  		return
   424  	}
   425  	defer db.Close(ctx) // cleanup resources
   426  	var (
   427  		id    int32  // required value
   428  		myStr string // optional value
   429  	)
   430  	// Do retry operation on errors with best effort
   431  	err = db.Query().DoTx(ctx, // context manage exiting from Do
   432  		func(ctx context.Context, tx query.TxActor) (err error) { // retry operation
   433  			res, err := tx.Query(ctx,
   434  				`SELECT 42 as id, "my string" as myStr`,
   435  			)
   436  			if err != nil {
   437  				return err // for auto-retry with driver
   438  			}
   439  			fmt.Printf("txID: expected %q, actual %q", baseTx.LazyTxID, tx.ID())
   440  			defer func() { _ = res.Close(ctx) }() // cleanup resources
   441  			// for loop with ResultSets available with Go version 1.23+
   442  			for rs, err := range res.ResultSets(ctx) {
   443  				if err != nil {
   444  					return err
   445  				}
   446  				// for loop with ResultSets available with Go version 1.23+
   447  				for row, err := range rs.Rows(ctx) {
   448  					if err != nil {
   449  						return err
   450  					}
   451  					if err = row.ScanNamed(
   452  						query.Named("id", &id),
   453  						query.Named("myStr", &myStr),
   454  					); err != nil {
   455  						return err // generally scan error not retryable, return it for driver check error
   456  					}
   457  				}
   458  			}
   459  
   460  			return nil
   461  		},
   462  		query.WithIdempotent(),
   463  		query.WithTxSettings(query.TxSettings(
   464  			query.WithSnapshotReadOnly(),
   465  		)),
   466  	)
   467  	if err != nil {
   468  		fmt.Printf("unexpected error: %v", err)
   469  	}
   470  	fmt.Printf("id=%v, myStr='%s'\n", id, myStr)
   471  }
   472  
   473  func Example_executeScript() {
   474  	ctx := context.TODO()
   475  	db, err := ydb.Open(ctx, "grpc://localhost:2136/local")
   476  	if err != nil {
   477  		panic(err)
   478  	}
   479  	defer db.Close(ctx)                      // cleanup resources
   480  	op, err := db.Query().ExecuteScript(ctx, // context manage exiting from Do
   481  		`SELECT CAST($id AS Uint64) AS id, CAST($myStr AS Text) AS myStr`,
   482  		time.Hour,
   483  		query.WithParameters(
   484  			ydb.ParamsBuilder().
   485  				Param("$id").Uint64(123).
   486  				Param("$myStr").Text("123").
   487  				Build(),
   488  		),
   489  		query.WithIdempotent(),
   490  	)
   491  	if err != nil {
   492  		panic(err)
   493  	}
   494  
   495  	for {
   496  		status, err := db.Operation().Get(ctx, op.ID)
   497  		if err != nil {
   498  			panic(err)
   499  		}
   500  		if status.Ready {
   501  			break
   502  		}
   503  		time.Sleep(time.Second)
   504  	}
   505  
   506  	var nextToken string
   507  	for {
   508  		result, err := db.Query().FetchScriptResults(ctx, op.ID,
   509  			query.WithResultSetIndex(0),
   510  			query.WithRowsLimit(1000),
   511  			query.WithFetchToken(nextToken),
   512  		)
   513  		if err != nil {
   514  			panic(err)
   515  		}
   516  		nextToken = result.NextToken
   517  		for row, err := range result.ResultSet.Rows(ctx) {
   518  			if err != nil {
   519  				panic(err)
   520  			}
   521  			var (
   522  				id    int64
   523  				myStr string
   524  			)
   525  			err = row.Scan(&id, &myStr)
   526  			if err != nil {
   527  				panic(err)
   528  			}
   529  			fmt.Printf("id=%v, myStr='%s'\n", id, myStr)
   530  		}
   531  		if result.NextToken == "" {
   532  			break
   533  		}
   534  	}
   535  }