(ctx context.Context, sql string, arguments ...any)
| 488 | } |
| 489 | |
| 490 | func (c *Conn) exec(ctx context.Context, sql string, arguments ...any) (commandTag pgconn.CommandTag, err error) { |
| 491 | mode := c.config.DefaultQueryExecMode |
| 492 | var queryRewriter QueryRewriter |
| 493 | |
| 494 | optionLoop: |
| 495 | for len(arguments) > 0 { |
| 496 | switch arg := arguments[0].(type) { |
| 497 | case QueryExecMode: |
| 498 | mode = arg |
| 499 | arguments = arguments[1:] |
| 500 | case QueryRewriter: |
| 501 | queryRewriter = arg |
| 502 | arguments = arguments[1:] |
| 503 | default: |
| 504 | break optionLoop |
| 505 | } |
| 506 | } |
| 507 | |
| 508 | if queryRewriter != nil { |
| 509 | sql, arguments, err = queryRewriter.RewriteQuery(ctx, c, sql, arguments) |
| 510 | if err != nil { |
| 511 | return pgconn.CommandTag{}, fmt.Errorf("rewrite query failed: %w", err) |
| 512 | } |
| 513 | } |
| 514 | |
| 515 | // Always use simple protocol when there are no arguments. |
| 516 | if len(arguments) == 0 { |
| 517 | mode = QueryExecModeSimpleProtocol |
| 518 | } |
| 519 | |
| 520 | defer func() { |
| 521 | if err != nil { |
| 522 | if sc := c.statementCache; sc != nil { |
| 523 | sc.Invalidate(sql) |
| 524 | } |
| 525 | |
| 526 | if sc := c.descriptionCache; sc != nil { |
| 527 | sc.Invalidate(sql) |
| 528 | } |
| 529 | } |
| 530 | }() |
| 531 | |
| 532 | if sd, ok := c.preparedStatements[sql]; ok { |
| 533 | return c.execPrepared(ctx, sd, arguments) |
| 534 | } |
| 535 | |
| 536 | switch mode { |
| 537 | case QueryExecModeCacheStatement: |
| 538 | if c.statementCache == nil { |
| 539 | return pgconn.CommandTag{}, errDisabledStatementCache |
| 540 | } |
| 541 | sd := c.statementCache.Get(sql) |
| 542 | if sd == nil { |
| 543 | sd, err = c.Prepare(ctx, stmtcache.StatementName(sql), sql) |
| 544 | if err != nil { |
| 545 | return pgconn.CommandTag{}, err |
| 546 | } |
| 547 | c.statementCache.Put(sd) |
no test coverage detected