94 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| package pq
 | |
| 
 | |
| import (
 | |
| 	"math"
 | |
| 	"reflect"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/lib/pq/oid"
 | |
| )
 | |
| 
 | |
| const headerSize = 4
 | |
| 
 | |
| type fieldDesc struct {
 | |
| 	// The object ID of the data type.
 | |
| 	OID oid.Oid
 | |
| 	// The data type size (see pg_type.typlen).
 | |
| 	// Note that negative values denote variable-width types.
 | |
| 	Len int
 | |
| 	// The type modifier (see pg_attribute.atttypmod).
 | |
| 	// The meaning of the modifier is type-specific.
 | |
| 	Mod int
 | |
| }
 | |
| 
 | |
| func (fd fieldDesc) Type() reflect.Type {
 | |
| 	switch fd.OID {
 | |
| 	case oid.T_int8:
 | |
| 		return reflect.TypeOf(int64(0))
 | |
| 	case oid.T_int4:
 | |
| 		return reflect.TypeOf(int32(0))
 | |
| 	case oid.T_int2:
 | |
| 		return reflect.TypeOf(int16(0))
 | |
| 	case oid.T_varchar, oid.T_text:
 | |
| 		return reflect.TypeOf("")
 | |
| 	case oid.T_bool:
 | |
| 		return reflect.TypeOf(false)
 | |
| 	case oid.T_date, oid.T_time, oid.T_timetz, oid.T_timestamp, oid.T_timestamptz:
 | |
| 		return reflect.TypeOf(time.Time{})
 | |
| 	case oid.T_bytea:
 | |
| 		return reflect.TypeOf([]byte(nil))
 | |
| 	default:
 | |
| 		return reflect.TypeOf(new(interface{})).Elem()
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (fd fieldDesc) Name() string {
 | |
| 	return oid.TypeName[fd.OID]
 | |
| }
 | |
| 
 | |
| func (fd fieldDesc) Length() (length int64, ok bool) {
 | |
| 	switch fd.OID {
 | |
| 	case oid.T_text, oid.T_bytea:
 | |
| 		return math.MaxInt64, true
 | |
| 	case oid.T_varchar, oid.T_bpchar:
 | |
| 		return int64(fd.Mod - headerSize), true
 | |
| 	default:
 | |
| 		return 0, false
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (fd fieldDesc) PrecisionScale() (precision, scale int64, ok bool) {
 | |
| 	switch fd.OID {
 | |
| 	case oid.T_numeric, oid.T__numeric:
 | |
| 		mod := fd.Mod - headerSize
 | |
| 		precision = int64((mod >> 16) & 0xffff)
 | |
| 		scale = int64(mod & 0xffff)
 | |
| 		return precision, scale, true
 | |
| 	default:
 | |
| 		return 0, 0, false
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // ColumnTypeScanType returns the value type that can be used to scan types into.
 | |
| func (rs *rows) ColumnTypeScanType(index int) reflect.Type {
 | |
| 	return rs.colTyps[index].Type()
 | |
| }
 | |
| 
 | |
| // ColumnTypeDatabaseTypeName return the database system type name.
 | |
| func (rs *rows) ColumnTypeDatabaseTypeName(index int) string {
 | |
| 	return rs.colTyps[index].Name()
 | |
| }
 | |
| 
 | |
| // ColumnTypeLength returns the length of the column type if the column is a
 | |
| // variable length type. If the column is not a variable length type ok
 | |
| // should return false.
 | |
| func (rs *rows) ColumnTypeLength(index int) (length int64, ok bool) {
 | |
| 	return rs.colTyps[index].Length()
 | |
| }
 | |
| 
 | |
| // ColumnTypePrecisionScale should return the precision and scale for decimal
 | |
| // types. If not applicable, ok should be false.
 | |
| func (rs *rows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
 | |
| 	return rs.colTyps[index].PrecisionScale()
 | |
| }
 |