diff --git a/extended_query_builder.go b/extended_query_builder.go
index 34662eb1..e87b5edd 100644
--- a/extended_query_builder.go
+++ b/extended_query_builder.go
@@ -1,7 +1,6 @@
 package pgx
 
 import (
-	"database/sql/driver"
 	"fmt"
 	"reflect"
 
@@ -85,24 +84,7 @@ func (eqb *extendedQueryBuilder) encodeExtendedParamValue(ci *pgtype.ConnInfo, o
 	}
 
 	if dt, ok := ci.DataTypeForOID(oid); ok {
-		if dt.Value != nil {
-			value := dt.Value
-			err := value.Set(arg)
-			if err != nil {
-				{
-					if arg, ok := arg.(driver.Valuer); ok {
-						v, err := callValuerValue(arg)
-						if err != nil {
-							return nil, err
-						}
-						return eqb.encodeExtendedParamValue(ci, oid, formatCode, v)
-					}
-				}
-
-				return nil, err
-			}
-			return eqb.encodeExtendedParamValue(ci, oid, formatCode, value)
-		} else if dt.Codec != nil {
+		if dt.Codec != nil {
 			buf, err := ci.Encode(oid, formatCode, arg, eqb.paramValueBytes)
 			if err != nil {
 				return nil, err
diff --git a/pgtype/pgtype.go b/pgtype/pgtype.go
index 8725aaa0..9a39e3ff 100644
--- a/pgtype/pgtype.go
+++ b/pgtype/pgtype.go
@@ -129,26 +129,6 @@ const (
 	BinaryFormatCode = 1
 )
 
-// Value translates values to and from an internal canonical representation for the type. To actually be usable a type
-// that implements Value should also implement some combination of BinaryDecoder, BinaryEncoder, TextDecoder,
-// and TextEncoder.
-//
-// Operations that update a Value (e.g. Set, DecodeText, DecodeBinary) should entirely replace the value. e.g. Internal
-// slices should be replaced not resized and reused. This allows Get and AssignTo to return a slice directly rather
-// than incur a usually unnecessary copy.
-type Value interface {
-	// Set converts and assigns src to itself. Value takes ownership of src.
-	Set(src interface{}) error
-
-	// Get returns the simplest representation of Value. Get may return a pointer to an internal value but it must never
-	// mutate that value. e.g. If Get returns a []byte Value must never change the contents of the []byte.
-	Get() interface{}
-
-	// AssignTo converts and assigns the Value to dst. AssignTo may a pointer to an internal value but it must never
-	// mutate that value. e.g. If Get returns a []byte Value must never change the contents of the []byte.
-	AssignTo(dst interface{}) error
-}
-
 type Codec interface {
 	// FormatSupported returns true if the format is supported.
 	FormatSupported(int16) bool
@@ -181,12 +161,9 @@ func (e *nullAssignmentError) Error() string {
 }
 
 type DataType struct {
-	Value Value
-
 	Codec Codec
-
-	Name string
-	OID  uint32
+	Name  string
+	OID   uint32
 }
 
 type ConnInfo struct {
@@ -352,10 +329,6 @@ func NewConnInfo() *ConnInfo {
 }
 
 func (ci *ConnInfo) RegisterDataType(t DataType) {
-	if t.Value != nil {
-		t.Value = NewValue(t.Value)
-	}
-
 	ci.oidToDataType[t.OID] = &t
 	ci.nameToDataType[t.Name] = &t
 
@@ -391,12 +364,6 @@ func (ci *ConnInfo) DataTypeForName(name string) (*DataType, bool) {
 func (ci *ConnInfo) buildReflectTypeToDataType() {
 	ci.reflectTypeToDataType = make(map[reflect.Type]*DataType)
 
-	for _, dt := range ci.oidToDataType {
-		if dt.Value != nil {
-			ci.reflectTypeToDataType[reflect.ValueOf(dt.Value).Type()] = dt
-		}
-	}
-
 	for reflectType, name := range ci.reflectTypeToName {
 		if dt, ok := ci.nameToDataType[name]; ok {
 			ci.reflectTypeToDataType[reflectType] = dt
@@ -1091,11 +1058,6 @@ func scanUnknownType(oid uint32, formatCode int16, buf []byte, dest interface{})
 	}
 }
 
-// NewValue returns a new instance of the same type as v.
-func NewValue(v Value) Value {
-	return reflect.New(reflect.ValueOf(v).Elem().Type()).Interface().(Value)
-}
-
 var ErrScanTargetTypeChanged = errors.New("scan target type changed")
 
 func codecScan(codec Codec, ci *ConnInfo, oid uint32, format int16, src []byte, dst interface{}) error {
diff --git a/rows.go b/rows.go
index 620ce5d6..e076ce43 100644
--- a/rows.go
+++ b/rows.go
@@ -246,18 +246,7 @@ func (rows *connRows) Values() ([]interface{}, error) {
 		}
 
 		if dt, ok := rows.connInfo.DataTypeForOID(fd.DataTypeOID); ok {
-			if dt.Value != nil {
-				switch fd.Format {
-				case TextFormatCode:
-					values = append(values, string(buf))
-				case BinaryFormatCode:
-					newBuf := make([]byte, len(buf))
-					copy(newBuf, buf)
-					values = append(values, newBuf)
-				default:
-					rows.fatal(errors.New("Unknown format code"))
-				}
-			} else if dt.Codec != nil {
+			if dt.Codec != nil {
 				value, err := dt.Codec.DecodeValue(rows.connInfo, fd.DataTypeOID, fd.Format, buf)
 				if err != nil {
 					rows.fatal(err)