QueryConn queries a SQL statement in a given connection.
(ctx context.Context, conn *sql.Conn, statement string, queryContext db.QueryContext)
| 785 | |
| 786 | // QueryConn queries a SQL statement in a given connection. |
| 787 | func (d *Driver) QueryConn(ctx context.Context, conn *sql.Conn, statement string, queryContext db.QueryContext) ([]*v1pb.QueryResult, error) { |
| 788 | singleSQLs, err := pgparser.SplitSQL(statement) |
| 789 | if err != nil { |
| 790 | return nil, err |
| 791 | } |
| 792 | singleSQLs = base.FilterEmptyStatements(singleSQLs) |
| 793 | if len(singleSQLs) == 0 { |
| 794 | return nil, nil |
| 795 | } |
| 796 | |
| 797 | var results []*v1pb.QueryResult |
| 798 | for _, singleSQL := range singleSQLs { |
| 799 | statement := singleSQL.Text |
| 800 | if queryContext.Explain { |
| 801 | statement = fmt.Sprintf("EXPLAIN %s", statement) |
| 802 | } else if queryContext.Limit > 0 { |
| 803 | statement = getStatementWithResultLimit(statement, queryContext.Limit) |
| 804 | } |
| 805 | |
| 806 | _, allQuery, err := base.ValidateSQLForEditor(storepb.Engine_POSTGRES, statement) |
| 807 | if err != nil { |
| 808 | return nil, err |
| 809 | } |
| 810 | |
| 811 | // Sanitize the schema name by escaping any quotes. |
| 812 | safeSchemeName := strings.ReplaceAll(queryContext.Schema, "\"", "\"\"") |
| 813 | |
| 814 | // If the queryContext.Schema is not empty, set the search path for the database connection to the specified schema. |
| 815 | if queryContext.Schema != "" { |
| 816 | if _, err := conn.ExecContext(ctx, fmt.Sprintf(`SET search_path TO "%s";`, safeSchemeName)); err != nil { // NOSONAR(go:S2077) safeSchemeName is sanitized via strings.ReplaceAll above |
| 817 | return nil, err |
| 818 | } |
| 819 | } |
| 820 | |
| 821 | startTime := time.Now() |
| 822 | queryResult, err := func() (*v1pb.QueryResult, error) { |
| 823 | if allQuery { |
| 824 | rows, err := conn.QueryContext(ctx, statement) |
| 825 | if err != nil { |
| 826 | return nil, err |
| 827 | } |
| 828 | defer rows.Close() |
| 829 | r, err := util.RowsToQueryResult(rows, makeValueByTypeName, convertValue, queryContext.MaximumSQLResultSize) |
| 830 | if err != nil { |
| 831 | return nil, err |
| 832 | } |
| 833 | r.Messages = d.PushAndClearMessages() |
| 834 | if err := rows.Err(); err != nil { |
| 835 | return nil, err |
| 836 | } |
| 837 | return r, nil |
| 838 | } |
| 839 | |
| 840 | sqlResult, err := conn.ExecContext(ctx, statement) |
| 841 | if err != nil { |
| 842 | return nil, err |
| 843 | } |
| 844 | affectedRows, err := sqlResult.RowsAffected() |
nothing calls this directly
no test coverage detected