Skip to content

Commit 04f5273

Browse files
authored
Merge pull request #791 from ydb-platform/sql-md
fix bindings readme
2 parents 8b280a4 + ec68b0a commit 04f5273

File tree

1 file changed

+61
-33
lines changed

1 file changed

+61
-33
lines changed

SQL.md

Lines changed: 61 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Behind the scene, `database/sql` APIs are implemented using the native interface
1919
* [Over `sql.Conn` object](#retry-conn)
2020
* [Over `sql.Tx`](#retry-tx)
2121
7. [Query args types](#arg-types)
22-
8. [Query binding](#bindings)
22+
8. [Query bindings](#bindings)
2323
9. [Accessing the native driver from `*sql.DB`](#unwrap)
2424
* [Driver with go's 1.18 supports also `*sql.Conn` for unwrapping](#unwrap-cc)
2525
10. [Troubleshooting](#troubleshooting)
@@ -352,7 +352,9 @@ err := retry.DoTx(context.TODO(), db, func(ctx context.Context, tx *sql.Tx) erro
352352

353353
## Query bindings <a name="bindings"></a>
354354

355-
`YQL` is a language with strict types. This means that a query to `YDB` must be written with an explicit declaration of query parameter types using the `DECLARE`keyword. Also, in some cases, the special `PRAGMA` operator can be used to simplify of the full table path prefix. For example, a query to the table `/local/path/to/tables/seasons` might look like this:
355+
YQL is a SQL dialect with YDB specific strict types. This is great for performance and correctness, but sometimes can be a bit dauting to express in a query, especially when then need to be parametrized externally from the application side. For instance, when a YDB query needs to be parametrized, each parameter has name and type provided via `DECLARE` statement.
356+
357+
Also, because YDB tables reside in virtual filesystem-like structure their names can be quite lengthy. There's a `PRAGMA TablePathPrefix` that can scope the rest of the query inside a given prefix, simplifying table names. For example, a query to the table `/local/path/to/tables/seasons` might look like this:
356358

357359
```
358360
DECLARE $title AS Text;
@@ -362,7 +364,7 @@ FROM `/local/path/to/tables/seasons`
362364
WHERE title LIKE $title AND views > $views;
363365
```
364366

365-
Using the `PRAGMA` operator, you can simplify the prefix part in the name of all tables involved in the `YQL`-query:
367+
Using the `PRAGMA` statement, you can simplify the prefix part in the name of all tables involved in the `YQL`-query:
366368

367369
```
368370
PRAGMA TablePathPrefix("/local/path/to/tables/");
@@ -371,15 +373,15 @@ DECLARE $views AS Uint64;
371373
SELECT season_id FROM seasons WHERE title LIKE $title AND views > $views;
372374
```
373375

374-
`database/sql` driver for `YDB` supports query enrichment for:
376+
`database/sql` driver for `YDB` (part of [YDB Go SDK](https://github.com/ydb-platform/ydb-go-sdk)) supports query enrichment for:
375377

376-
* specifying `TablePathPrefix`,
377-
* declaring types of parameters,
378-
* numeric or positional parameters
378+
* specifying **_TablePathPrefix_**
379+
* **_declaring_** types of parameters
380+
* **_numeric_** or **_positional_** parameters
379381

380-
This enrichments of queries can be enabled explicitly on initializing step using connector option `ydb.WithAutoBind(bind)` or connection string parameter `go_query_bind`. By default `database/sql` driver for `YDB` not modifies source queries.
382+
These query enrichments can be enabled explicitly on the initializing step using connector options or connection string parameter `go_auto_bind`. By default `database/sql` driver for `YDB` doesn’t modify queries.
381383

382-
Next example without bindings shows complexity and explicit importing of `ydb-go-sdk` packages:
384+
The following example without bindings demonstrates explicit working with `YDB` types:
383385

384386
```go
385387
import (
@@ -408,7 +410,11 @@ func main() {
408410
}
409411
```
410412

411-
This example can be overwritten to easiest over bindings:
413+
As you can see, this example also required importing of `ydb-go-sdk` packages and working with them directly.
414+
415+
With enabled bindings enrichment, the same result can be achieved much easier:
416+
417+
- with _**connection string_** params:
412418
```go
413419
import (
414420
"context"
@@ -419,27 +425,49 @@ import (
419425

420426
func main() {
421427
var (
422-
ctx = context.TODO()
423-
db = sql.Open("ydb", "grpc://localhost:2136/local?"+
424-
"go_query_bind=table_path_prefix(/local/path/to/my/folder),declare,positional")
425-
426-
// alternate syntax for enabling bindings over connection string params
427-
//
428-
// nativeDriver = ydb.MustOpen(ctx, "grpc://localhost:2136/local")
429-
// db = sql.OpenDB(ydb.MustConnector(nativeDriver,
430-
// ydb.WithTablePathPrefix("/local/path/to/my/folder"), // bind pragma TablePathPrefix
431-
// ydb.WithAutoDeclare(), // bind parameters declare
432-
// ydb.WithPositionalArgs(), // bind positional args
433-
// ))
428+
ctx = context.TODO()
429+
db = sql.Open("ydb",
430+
"grpc://localhost:2136/local?"+
431+
"go_auto_bind="+
432+
"table_path_prefix(/local/path/to/my/folder),"+
433+
"declare,"+
434+
"positional",
435+
)
436+
)
437+
defer db.Close() // cleanup resources
438+
439+
// positional args
440+
row := db.QueryRowContext(ctx, `SELECT ?, ?`, 42, "my string")
441+
```
442+
443+
- with _**connector options**_:
444+
```go
445+
import (
446+
"context"
447+
"database/sql"
448+
449+
"github.com/ydb-platform/ydb-go-sdk/v3"
450+
)
451+
452+
func main() {
453+
var (
454+
ctx = context.TODO()
455+
nativeDriver = ydb.MustOpen(ctx, "grpc://localhost:2136/local")
456+
db = sql.OpenDB(ydb.MustConnector(nativeDriver,
457+
query.TablePathPrefix("/local/path/to/my/folder"), // bind pragma TablePathPrefix
458+
query.Declare(), // bind parameters declare
459+
query.Positional(), // bind positional args
460+
))
434461
)
435-
//defer nativeDriver.Close(ctx) // cleanup resources
462+
defer nativeDriver.Close(ctx) // cleanup resources
436463
defer db.Close()
437464

438465
// positional args
439466
row := db.QueryRowContext(ctx, `SELECT ?, ?`, 42, "my string")
440467
```
441468
442-
The original simple query `SELECT ?, ?` will expand on driver side to the following
469+
The original simple query `SELECT ?, ?` will be expanded on the driver side to the following:
470+
443471
```sql
444472
-- bind TablePathPrefix
445473
PRAGMA TablePathPrefix("/local/path/to/my/folder");
@@ -452,14 +480,14 @@ DECLARE $p1 AS Utf8;
452480
SELECT $p0, $p1
453481
```
454482
455-
This expanded query will send to `YDB` instead of original sql-query.
483+
This expanded query will be sent to `ydbd` server instead of the original one.
456484
457-
Additional examples of query enrichment see in `ydb-go-sdk` documentation:
485+
For additional examples of query enrichment, see `ydb-go-sdk` documentation:
458486
459487
* specifying `TablePathPrefix`:
460488
* using [connection string parameter](https://pkg.go.dev/github.com/ydb-platform/ydb-go-sdk/v3#example-package-DatabaseSQLBindTablePathPrefix)
461489
* using [connector option](https://pkg.go.dev/github.com/ydb-platform/ydb-go-sdk/v3#example-package-DatabaseSQLBindTablePathPrefixOverConnector)
462-
* declares binding:
490+
* declaring bindings:
463491
* using [connection string parameter](https://pkg.go.dev/github.com/ydb-platform/ydb-go-sdk/v3#example-package-DatabaseSQLBindDeclare)
464492
* using [connector option](https://pkg.go.dev/github.com/ydb-platform/ydb-go-sdk/v3#example-package-DatabaseSQLBindDeclareOverConnector)
465493
* positional arguments binding:
@@ -469,16 +497,16 @@ Additional examples of query enrichment see in `ydb-go-sdk` documentation:
469497
* using [connection string parameter](https://pkg.go.dev/github.com/ydb-platform/ydb-go-sdk/v3#example-package-DatabaseSQLBindNumericlArgs)
470498
* using [connector option](https://pkg.go.dev/github.com/ydb-platform/ydb-go-sdk/v3#example-package-DatabaseSQLBindNumericArgsOverConnector)
471499
472-
For a deep understanding of query enrichment see also [unit-tests](https://github.com/ydb-platform/ydb-go-sdk/blob/master/query_bind_test.go).
500+
For a deep understanding of query enrichment see also [unit-tests](https://github.com/ydb-platform/ydb-go-sdk/blob/master/query/bind_test.go).
473501
474-
You can write your own unit-tests for check correct binding of your queries like this:
502+
You can write your own unit tests to check correct binding of your queries like this:
475503
476504
```go
477505
func TestBinding(t *testing.T) {
478-
bindings := testutil.NewBind(
479-
ydb.WithTablePathPrefix("/local/path/to/my/folder"), // bind pragma TablePathPrefix
480-
ydb.WithDeclare(), // bind parameters declare
481-
ydb.WithPositional(), // auto-replace positional args
506+
bindings := query.NewBind(
507+
query.TablePathPrefix("/local/path/to/my/folder"), // bind pragma TablePathPrefix
508+
query.Declare(), // bind parameters declare
509+
query.Positional(), // auto-replace positional args
482510
)
483511
query, params, err := bindings.ToYQL("SELECT ?, ?, ?", 1, uint64(2), "3")
484512
require.NoError(t, err)

0 commit comments

Comments
 (0)