diff --git a/query.go b/query.go index c6c8132f..1e2eea11 100644 --- a/query.go +++ b/query.go @@ -287,12 +287,27 @@ func (c *Conn) getRows(sql string, args []interface{}) *connRows { return r } +type QueryResultFormats []int16 + // Query executes sql with args. If there is an error the returned Rows will be returned in an error state. So it is // allowed to ignore the error returned from Query and handle it in Rows. func (c *Conn) Query(ctx context.Context, sql string, args ...interface{}) (Rows, error) { c.lastStmtSent = false // rows = c.getRows(sql, args) + var resultFormats QueryResultFormats + +optionLoop: + for len(args) > 0 { + switch arg := args[0].(type) { + case QueryResultFormats: + resultFormats = arg + args = args[1:] + default: + break optionLoop + } + } + rows := &connRows{ conn: c, startTime: time.Now(), @@ -404,13 +419,15 @@ func (c *Conn) Query(ctx context.Context, sql string, args ...interface{}) (Rows } } - resultFormats := make([]int16, len(ps.FieldDescriptions)) - for i := range resultFormats { - if dt, ok := c.ConnInfo.DataTypeForOID(ps.FieldDescriptions[i].DataType); ok { - if _, ok := dt.Value.(pgtype.BinaryDecoder); ok { - resultFormats[i] = BinaryFormatCode - } else { - resultFormats[i] = TextFormatCode + if resultFormats == nil { + resultFormats = make([]int16, len(ps.FieldDescriptions)) + for i := range resultFormats { + if dt, ok := c.ConnInfo.DataTypeForOID(ps.FieldDescriptions[i].DataType); ok { + if _, ok := dt.Value.(pgtype.BinaryDecoder); ok { + resultFormats[i] = BinaryFormatCode + } else { + resultFormats[i] = TextFormatCode + } } } } diff --git a/stdlib/sql.go b/stdlib/sql.go index d4815d83..eaf1caa7 100644 --- a/stdlib/sql.go +++ b/stdlib/sql.go @@ -254,15 +254,30 @@ func (c *Conn) QueryContext(ctx context.Context, query string, argsV []driver.Na restrictBinaryToDatabaseSqlTypes(ps) return c.queryPreparedContext(ctx, psname, argsV) - } +// func (c *Conn) execParams(ctx context.Context, sql string, argsV []driver.NamedValue) (*pgconn.ResultReader, error) { +// if !c.conn.IsAlive() { +// return nil, driver.ErrBadConn +// } + +// paramValues := make([][]byte, len(argsV)) +// for i := 0;i< len(paramValues); i++ { +// v := argsV[i].Value +// paramValues +// } + +// return c.conn.PgConn().ExecParams(ctx, sql,paramValues, nil, nil, nil) +// } + func (c *Conn) queryPreparedContext(ctx context.Context, name string, argsV []driver.NamedValue) (driver.Rows, error) { if !c.conn.IsAlive() { return nil, driver.ErrBadConn } - args := namedValueToInterface(argsV) + // TODO - don't always use text + args := []interface{}{pgx.QueryResultFormats{0}} + args = append(args, namedValueToInterface(argsV)...) rows, err := c.conn.Query(ctx, name, args...) if err != nil {