From 2b4e684bff2674ebc265398cce01e233f645ffe5 Mon Sep 17 00:00:00 2001 From: Aleksey Myasnikov Date: Mon, 9 Sep 2024 17:43:30 +0300 Subject: [PATCH 1/2] added test and example for explain query --- query/example_test.go | 27 +++++++++++++++++++ tests/integration/query_execute_test.go | 35 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/query/example_test.go b/query/example_test.go index ff95dbcb0..0f2913bf8 100644 --- a/query/example_test.go +++ b/query/example_test.go @@ -124,6 +124,33 @@ func Example_queryRow() { fmt.Printf("id=%v, myStr='%s'\n", id, myStr) } +func Example_explain() { + ctx := context.TODO() + db, err := ydb.Open(ctx, "grpc://localhost:2136/local") + if err != nil { + panic(err) + } + defer db.Close(ctx) // cleanup resources + var ( + ast string + plan string + ) + err = db.Query().Exec(ctx, + `SELECT CAST(42 AS Uint32);`, + query.WithExecMode(query.ExecModeExplain), + query.WithStatsMode(query.StatsModeNone, func(stats query.Stats) { + ast = stats.QueryAST() + plan = stats.QueryPlan() + }), + query.WithIdempotent(), + ) + if err != nil { + panic(err) + } + fmt.Println(plan) + fmt.Println(ast) +} + func Example_withoutRangeIterators() { ctx := context.TODO() db, err := ydb.Open(ctx, "grpc://localhost:2136/local") diff --git a/tests/integration/query_execute_test.go b/tests/integration/query_execute_test.go index abdc34bfe..35822be58 100644 --- a/tests/integration/query_execute_test.go +++ b/tests/integration/query_execute_test.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "os" + "regexp" "testing" "time" @@ -92,6 +93,40 @@ func TestQueryExecute(t *testing.T) { require.True(t, ok) }) }) + t.Run("Explain", func(t *testing.T) { + var ( + ast string + plan string + ) + err := db.Query().Exec(ctx, + `SELECT CAST(42 AS Uint32);`, + query.WithExecMode(query.ExecModeExplain), + query.WithStatsMode(query.StatsModeNone, func(stats query.Stats) { + ast = stats.QueryAST() + plan = stats.QueryPlan() + }), + query.WithIdempotent(), + ) + require.NoError(t, err) + require.EqualValues(t, + `{"Plan":{"Plans":[{"PlanNodeId":2,"Plans":[{"PlanNodeId":1,"Operators":[{"Inputs":[],"Iterator":"[{column0: 42}]","Name":"Iterator"}],"Node Type":"ConstantExpr"}],"Node Type":"ResultSet","PlanNodeType":"ResultSet"}],"Node Type":"Query","PlanNodeType":"Query"},"meta":{"version":"0.2","type":"query"},"tables":[],"SimplifiedPlan":{"PlanNodeId":0,"Plans":[{"PlanNodeId":1,"Node Type":"ResultSet","PlanNodeType":"ResultSet"}],"Node Type":"Query","PlanNodeType":"Query"}}`, + plan, + ) + ast = regexp.MustCompile("\"_id\" '\"(\\w{8}-\\w{8}-\\w{8}-\\w{8})\"").ReplaceAllStringFunc(ast, func(string) string { + return `"_id" '"test-id"` + }) + require.EqualValues(t, + `( +(let $1 (OptionalType (DataType 'Uint32))) +(let $2 '('('"_logical_id" '184) '('"_id" '"test-id") '('"_partition_mode" '"single"))) +(let $3 (DqPhyStage '() (lambda '() (Iterator (AsList (AsStruct '('"column0" (SafeCast (Int32 '"42") $1)))))) $2)) +(let $4 (DqCnResult (TDqOutput $3 '"0") '('"column0"))) +(return (KqpPhysicalQuery '((KqpPhysicalTx '($3) '($4) '() '('('"type" '"generic")))) '((KqpTxResultBinding (ListType (StructType '('"column0" $1))) '"0" '"0")) '('('"type" '"query")))) +) +`, + ast, + ) + }) t.Run("Scan", func(t *testing.T) { var ( p1 string From edd41632dc4436d78d5b46351805216cb84258eb Mon Sep 17 00:00:00 2001 From: Aleksey Myasnikov Date: Mon, 9 Sep 2024 18:09:32 +0300 Subject: [PATCH 2/2] added YDB 24.2 and 24.3 to matrix tests --- tests/integration/query_execute_test.go | 30 ++++++++----------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/tests/integration/query_execute_test.go b/tests/integration/query_execute_test.go index 35822be58..56aed60c2 100644 --- a/tests/integration/query_execute_test.go +++ b/tests/integration/query_execute_test.go @@ -5,9 +5,9 @@ package integration import ( "context" + "encoding/json" "fmt" "os" - "regexp" "testing" "time" @@ -96,36 +96,24 @@ func TestQueryExecute(t *testing.T) { t.Run("Explain", func(t *testing.T) { var ( ast string - plan string + plan map[string]any ) err := db.Query().Exec(ctx, `SELECT CAST(42 AS Uint32);`, query.WithExecMode(query.ExecModeExplain), query.WithStatsMode(query.StatsModeNone, func(stats query.Stats) { ast = stats.QueryAST() - plan = stats.QueryPlan() + err := json.Unmarshal([]byte(stats.QueryPlan()), &plan) + require.NoError(t, err) }), query.WithIdempotent(), ) require.NoError(t, err) - require.EqualValues(t, - `{"Plan":{"Plans":[{"PlanNodeId":2,"Plans":[{"PlanNodeId":1,"Operators":[{"Inputs":[],"Iterator":"[{column0: 42}]","Name":"Iterator"}],"Node Type":"ConstantExpr"}],"Node Type":"ResultSet","PlanNodeType":"ResultSet"}],"Node Type":"Query","PlanNodeType":"Query"},"meta":{"version":"0.2","type":"query"},"tables":[],"SimplifiedPlan":{"PlanNodeId":0,"Plans":[{"PlanNodeId":1,"Node Type":"ResultSet","PlanNodeType":"ResultSet"}],"Node Type":"Query","PlanNodeType":"Query"}}`, - plan, - ) - ast = regexp.MustCompile("\"_id\" '\"(\\w{8}-\\w{8}-\\w{8}-\\w{8})\"").ReplaceAllStringFunc(ast, func(string) string { - return `"_id" '"test-id"` - }) - require.EqualValues(t, - `( -(let $1 (OptionalType (DataType 'Uint32))) -(let $2 '('('"_logical_id" '184) '('"_id" '"test-id") '('"_partition_mode" '"single"))) -(let $3 (DqPhyStage '() (lambda '() (Iterator (AsList (AsStruct '('"column0" (SafeCast (Int32 '"42") $1)))))) $2)) -(let $4 (DqCnResult (TDqOutput $3 '"0") '('"column0"))) -(return (KqpPhysicalQuery '((KqpPhysicalTx '($3) '($4) '() '('('"type" '"generic")))) '((KqpTxResultBinding (ListType (StructType '('"column0" $1))) '"0" '"0")) '('('"type" '"query")))) -) -`, - ast, - ) + for _, key := range []string{"Plan", "tables", "meta"} { + _, has := plan[key] + require.True(t, has, key) + } + require.NotEmpty(t, ast) }) t.Run("Scan", func(t *testing.T) { var (