MCPcopy Index your code
hub / github.com/bytebase/bytebase / Query

Function Query

backend/plugin/advisor/utils.go:23–138  ·  view source on GitHub ↗

Query runs the EXPLAIN or SELECT statements for advisors.

(ctx context.Context, qCtx QueryContext, connection *sql.DB, engine storepb.Engine, statement string)

Source from the content-addressed store, hash-verified

21
22// Query runs the EXPLAIN or SELECT statements for advisors.
23func Query(ctx context.Context, qCtx QueryContext, connection *sql.DB, engine storepb.Engine, statement string) ([]any, error) {
24 tx, err := connection.BeginTx(ctx, &sql.TxOptions{})
25 if err != nil {
26 return nil, err
27 }
28 defer tx.Rollback()
29
30 if engine == storepb.Engine_POSTGRES && qCtx.TenantMode {
31 const query = `
32 SELECT
33 u.rolname
34 FROM
35 pg_roles AS u JOIN pg_database AS d ON (d.datdba = u.oid)
36 WHERE
37 d.datname = current_database();
38 `
39 var owner string
40 if err := tx.QueryRowContext(ctx, query).Scan(&owner); err != nil {
41 return nil, err
42 }
43 // Use SET SESSION ROLE to match the execution logic in backend/plugin/db/pg/pg.go
44 if _, err := tx.ExecContext(ctx, fmt.Sprintf("SET SESSION ROLE '%s';", owner)); err != nil { // NOSONAR(go:S2077) owner is from pg_roles system catalog, not user input
45 return nil, err
46 }
47 }
48
49 for _, preExec := range qCtx.PreExecutions {
50 if preExec != "" {
51 if _, err := tx.ExecContext(ctx, preExec); err != nil {
52 return nil, errors.Wrapf(err, "failed to execute pre-execution: %s", preExec)
53 }
54 }
55 }
56
57 rows, err := tx.QueryContext(ctx, statement)
58 if err != nil {
59 return nil, err
60 }
61 defer rows.Close()
62
63 columnNames, err := rows.Columns()
64 if err != nil {
65 return nil, err
66 }
67
68 columnTypes, err := rows.ColumnTypes()
69 if err != nil {
70 return nil, err
71 }
72
73 colCount := len(columnTypes)
74
75 var columnTypeNames []string
76 for _, v := range columnTypes {
77 // DatabaseTypeName returns the database system name of the column type.
78 // refer: https://pkg.go.dev/database/sql#ColumnType.DatabaseTypeName
79 columnTypeNames = append(columnTypeNames, strings.ToUpper(v.DatabaseTypeName()))
80 }

Callers 10

handleStmtMethod · 0.92
handleStmtMethod · 0.92
CheckMethod · 0.92
CheckMethod · 0.92
CheckMethod · 0.92
checkAffectedRowsMethod · 0.92
checkDMLDryRunMethod · 0.92
checkInsertMethod · 0.92
explainMethod · 0.92

Calls 5

ScanMethod · 0.80
QueryContextMethod · 0.80
ColumnsMethod · 0.80
CloseMethod · 0.65
NextMethod · 0.45

Tested by

no test coverage detected