QueryConn queries a SQL statement in a given connection.
(ctx context.Context, conn *sql.Conn, statement string, queryContext db.QueryContext)
| 227 | |
| 228 | // QueryConn queries a SQL statement in a given connection. |
| 229 | func (d *Driver) QueryConn(ctx context.Context, conn *sql.Conn, statement string, queryContext db.QueryContext) ([]*v1pb.QueryResult, error) { |
| 230 | singleSQLs, err := plsqlparser.SplitSQL(statement) |
| 231 | if err != nil { |
| 232 | return nil, err |
| 233 | } |
| 234 | singleSQLs = base.FilterEmptyStatements(singleSQLs) |
| 235 | if len(singleSQLs) == 0 { |
| 236 | return nil, nil |
| 237 | } |
| 238 | |
| 239 | var results []*v1pb.QueryResult |
| 240 | for _, singleSQL := range singleSQLs { |
| 241 | statement := singleSQL.Text |
| 242 | if queryContext.Explain { |
| 243 | startTime := time.Now() |
| 244 | randNum, err := rand.Int(rand.Reader, big.NewInt(999)) |
| 245 | if err != nil { |
| 246 | return nil, errors.Wrapf(err, "failed to generate random statement ID") |
| 247 | } |
| 248 | randomID := fmt.Sprintf("%d%d", startTime.UnixMilli(), randNum.Int64()) |
| 249 | |
| 250 | if _, err := conn.ExecContext(ctx, fmt.Sprintf("EXPLAIN PLAN SET STATEMENT_ID = '%s' FOR %s", randomID, statement)); err != nil { |
| 251 | return nil, err |
| 252 | } |
| 253 | statement = fmt.Sprintf(`SELECT LPAD(' ', LEVEL-1) || OPERATION || ' (' || OPTIONS || ')' "Operation", OBJECT_NAME "Object", OPTIMIZER "Optimizer", COST "Cost", CARDINALITY "Cardinality", BYTES "Bytes", PARTITION_START "Partition Start", PARTITION_ID "Partition ID", ACCESS_PREDICATES "Access Predicates" FROM PLAN_TABLE START WITH ID = 0 AND statement_id = '%s' CONNECT BY PRIOR ID=PARENT_ID AND statement_id = '%s' ORDER BY id`, randomID, randomID) |
| 254 | } |
| 255 | |
| 256 | if !queryContext.Explain && queryContext.Limit > 0 { |
| 257 | statement = addResultLimit(statement, queryContext.Limit, d.connectionCtx.EngineVersion) |
| 258 | } |
| 259 | |
| 260 | _, allQuery, err := base.ValidateSQLForEditor(storepb.Engine_ORACLE, statement) |
| 261 | if err != nil { |
| 262 | return nil, err |
| 263 | } |
| 264 | startTime := time.Now() |
| 265 | queryResult, err := func() (*v1pb.QueryResult, error) { |
| 266 | if allQuery { |
| 267 | rows, err := conn.QueryContext(ctx, statement) |
| 268 | if err != nil { |
| 269 | return nil, err |
| 270 | } |
| 271 | defer rows.Close() |
| 272 | r, err := util.RowsToQueryResult(rows, makeValueByTypeName, convertValue, queryContext.MaximumSQLResultSize) |
| 273 | if err != nil { |
| 274 | return nil, err |
| 275 | } |
| 276 | if err := rows.Err(); err != nil { |
| 277 | return nil, err |
| 278 | } |
| 279 | return r, nil |
| 280 | } |
| 281 | |
| 282 | sqlResult, err := conn.ExecContext(ctx, statement) |
| 283 | if err != nil { |
| 284 | return nil, err |
| 285 | } |
| 286 | affectedRows, err := sqlResult.RowsAffected() |
nothing calls this directly
no test coverage detected