package pq

import (
	
	
	
	
	
	
	
	
	
	
	

	
)

func ( *parameterStatus,  interface{}) []byte {
	switch v := .(type) {
	case []byte:
		return 
	default:
		return encode(, , oid.T_unknown)
	}
}

func ( *parameterStatus,  interface{},  oid.Oid) []byte {
	switch v := .(type) {
	case int64:
		return strconv.AppendInt(nil, , 10)
	case float64:
		return strconv.AppendFloat(nil, , 'f', -1, 64)
	case []byte:
		if  == oid.T_bytea {
			return encodeBytea(.serverVersion, )
		}

		return 
	case string:
		if  == oid.T_bytea {
			return encodeBytea(.serverVersion, []byte())
		}

		return []byte()
	case bool:
		return strconv.AppendBool(nil, )
	case time.Time:
		return formatTs()

	default:
		errorf("encode: unknown type for %T", )
	}

	panic("not reached")
}

func ( *parameterStatus,  []byte,  oid.Oid,  format) interface{} {
	switch  {
	case formatBinary:
		return binaryDecode(, , )
	case formatText:
		return textDecode(, , )
	default:
		panic("not reached")
	}
}

func ( *parameterStatus,  []byte,  oid.Oid) interface{} {
	switch  {
	case oid.T_bytea:
		return 
	case oid.T_int8:
		return int64(binary.BigEndian.Uint64())
	case oid.T_int4:
		return int64(int32(binary.BigEndian.Uint32()))
	case oid.T_int2:
		return int64(int16(binary.BigEndian.Uint16()))
	case oid.T_uuid:
		,  := decodeUUIDBinary()
		if  != nil {
			panic()
		}
		return 

	default:
		errorf("don't know how to decode binary parameter of type %d", uint32())
	}

	panic("not reached")
}

func ( *parameterStatus,  []byte,  oid.Oid) interface{} {
	switch  {
	case oid.T_char, oid.T_varchar, oid.T_text:
		return string()
	case oid.T_bytea:
		,  := parseBytea()
		if  != nil {
			errorf("%s", )
		}
		return 
	case oid.T_timestamptz:
		return parseTs(.currentLocation, string())
	case oid.T_timestamp, oid.T_date:
		return parseTs(nil, string())
	case oid.T_time:
		return mustParse("15:04:05", , )
	case oid.T_timetz:
		return mustParse("15:04:05-07", , )
	case oid.T_bool:
		return [0] == 't'
	case oid.T_int8, oid.T_int4, oid.T_int2:
		,  := strconv.ParseInt(string(), 10, 64)
		if  != nil {
			errorf("%s", )
		}
		return 
We always use 64 bit parsing, regardless of whether the input text is for a float4 or float8, because clients expect float64s for all float datatypes and returning a 32-bit parsed float64 produces lossy results.
		,  := strconv.ParseFloat(string(), 64)
		if  != nil {
			errorf("%s", )
		}
		return 
	}

	return 
}
appendEncodedText encodes item in text format as required by COPY and appends to buf
func ( *parameterStatus,  []byte,  interface{}) []byte {
	switch v := .(type) {
	case int64:
		return strconv.AppendInt(, , 10)
	case float64:
		return strconv.AppendFloat(, , 'f', -1, 64)
	case []byte:
		 := encodeBytea(.serverVersion, )
		return appendEscapedText(, string())
	case string:
		return appendEscapedText(, )
	case bool:
		return strconv.AppendBool(, )
	case time.Time:
		return append(, formatTs()...)
	case nil:
		return append(, "\\N"...)
	default:
		errorf("encode: unknown type for %T", )
	}

	panic("not reached")
}

func ( []byte,  string) []byte {
	 := false
	 := 0
	var  byte
check if we need to escape
	for  := 0;  < len(); ++ {
		 = []
		if  == '\\' ||  == '\n' ||  == '\r' ||  == '\t' {
			 = true
			 = 
			break
		}
	}
	if ! {
		return append(, ...)
	}
copy till first char to escape, iterate the rest
	 := append(, [:]...)
	for  := ;  < len(); ++ {
		 = []
		switch  {
		case '\\':
			 = append(, '\\', '\\')
		case '\n':
			 = append(, '\\', 'n')
		case '\r':
			 = append(, '\\', 'r')
		case '\t':
			 = append(, '\\', 't')
		default:
			 = append(, )
		}
	}
	return 
}

func ( string,  oid.Oid,  []byte) time.Time {
	 := string()
check for a 30-minute-offset timezone
	if ( == oid.T_timestamptz ||  == oid.T_timetz) &&
		[len()-3] == ':' {
		 += ":00"
	}
	,  := time.Parse(, )
	if  != nil {
		errorf("decode: %s", )
	}
	return 
}

var errInvalidTimestamp = errors.New("invalid timestamp")

type timestampParser struct {
	err error
}

func ( *timestampParser) ( string,  byte,  int) {
	if .err != nil {
		return
	}
	if +1 > len() {
		.err = errInvalidTimestamp
		return
	}
	if  := [];  !=  && .err == nil {
		.err = fmt.Errorf("expected '%v' at position %v; got '%v'", , , )
	}
}

func ( *timestampParser) ( string,  int,  int) int {
	if .err != nil {
		return 0
	}
	if  < 0 ||  < 0 ||  >  ||  > len() {
		.err = errInvalidTimestamp
		return 0
	}
	,  := strconv.Atoi([:])
	if  != nil {
		if .err == nil {
			.err = fmt.Errorf("expected number; got '%v'", )
		}
		return 0
	}
	return 
}
The location cache caches the time zones typically used by the client.
All connections share the same list of timezones. Benchmarking shows that about 5% speed could be gained by putting the cache in the connection and losing the mutex, at the cost of a small amount of memory and a somewhat significant increase in code complexity.
Returns the cached timezone for the specified offset, creating and caching it if necessary.
func ( *locationCache) ( int) *time.Location {
	.lock.Lock()
	defer .lock.Unlock()

	,  := .cache[]
	if ! {
		 = time.FixedZone("", )
		.cache[] = 
	}

	return 
}

var infinityTsEnabled = false
var infinityTsNegative time.Time
var infinityTsPositive time.Time

const (
	infinityTsEnabledAlready        = "pq: infinity timestamp enabled already"
	infinityTsNegativeMustBeSmaller = "pq: infinity timestamp: negative value must be smaller (before) than positive"
)
EnableInfinityTs controls the handling of Postgres' "-infinity" and "infinity" "timestamp"s. If EnableInfinityTs is not called, "-infinity" and "infinity" will return []byte("-infinity") and []byte("infinity") respectively, and potentially cause error "sql: Scan error on column index 0: unsupported driver -> Scan pair: []uint8 -> *time.Time", when scanning into a time.Time value. Once EnableInfinityTs has been called, all connections created using this driver will decode Postgres' "-infinity" and "infinity" for "timestamp", "timestamp with time zone" and "date" types to the predefined minimum and maximum times, respectively. When encoding time.Time values, any time which equals or precedes the predefined minimum time will be encoded to "-infinity". Any values at or past the maximum time will similarly be encoded to "infinity". If EnableInfinityTs is called with negative >= positive, it will panic. Calling EnableInfinityTs after a connection has been established results in undefined behavior. If EnableInfinityTs is called more than once, it will panic.
* Testing might want to toggle infinityTsEnabled
This is a time function specific to the Postgres default DateStyle setting ("ISO, MDY"), the only one we currently support. This accounts for the discrepancies between the parsing available with time.Parse and the Postgres date formatting quirks.
func ( *time.Location,  string) interface{} {
	switch  {
	case "-infinity":
		if infinityTsEnabled {
			return infinityTsNegative
		}
		return []byte()
	case "infinity":
		if infinityTsEnabled {
			return infinityTsPositive
		}
		return []byte()
	}
	,  := ParseTimestamp(, )
	if  != nil {
		panic()
	}
	return 
}
ParseTimestamp parses Postgres' text format. It returns a time.Time in currentLocation iff that time's offset agrees with the offset sent from the Postgres server. Otherwise, ParseTimestamp returns a time.Time with the fixed offset offset provided by the Postgres server.
func ( *time.Location,  string) (time.Time, error) {
	 := timestampParser{}

this is Gregorian year, not ISO Year In Gregorian system, the year 1 BC is followed by AD 1
	 := .mustAtoi(, 0, )
	 :=  + 3
	 := .mustAtoi(, +1, )
	.expect(, '-', )
	 :=  + 3
	 := .mustAtoi(, +1, )

	 :=  + len("01-01") + 1

	 := strings.HasSuffix(, " BC")
	if  {
		 += 3
	}

	var , ,  int
	if len() >  {
		.expect(, ' ', )
		 :=  + 3
		.expect(, ':', )
		 = .mustAtoi(, +1, )
		 :=  + 3
		.expect(, ':', )
		 = .mustAtoi(, +1, )
		 :=  + 3
		 = .mustAtoi(, +1, )
	}
Three optional (but ordered) sections follow: the fractional seconds, the time zone offset, and the BC designation. We set them up here and adjust the other offsets if the preceding sections exist.

	 := 0
	 := 0

	if  < len() && [] == '.' {
		 :=  + 1
		 := strings.IndexAny([:], "-+ ")
		if  < 0 {
			 = len() - 
		}
		 := .mustAtoi(, , +)
		 =  * (1000000000 / int(math.Pow(10, float64())))

		 +=  + 1
	}
time zone separator is always '-' or '+' (UTC is +00)
		var  int
		switch  := [];  {
		case '-':
			 = -1
		case '+':
			 = +1
		default:
			return time.Time{}, fmt.Errorf("expected '-' or '+' at position %v; got %v", , )
		}
		 := .mustAtoi(, +1, +3)
		 += 3
		var ,  int
		if  < len() && [] == ':' {
			 = .mustAtoi(, +1, +3)
			 += 3
		}
		if  < len() && [] == ':' {
			 = .mustAtoi(, +1, +3)
			 += 3
		}
		 =  * (( * 60 * 60) + ( * 60) + )
	}
	var  int

	if  {
		 = 1 - 
		 += 3
	} else {
		 = 
	}
	if  < len() {
		return time.Time{}, fmt.Errorf("expected end of input, got %v", [:])
	}
	 := time.Date(, time.Month(), ,
		, , , ,
		globalLocationCache.getLocation())

Set the location of the returned Time based on the session's TimeZone value, but only if the local time zone database agrees with the remote database on the offset.
		 := .In()
		,  := .Zone()
		if  ==  {
			 = 
		}
	}

	return , .err
}
formatTs formats t into a format postgres understands.
func ( time.Time) []byte {
t <= -infinity : ! (t > -infinity)
		if !.After(infinityTsNegative) {
			return []byte("-infinity")
t >= infinity : ! (!t < infinity)
		if !.Before(infinityTsPositive) {
			return []byte("infinity")
		}
	}
	return FormatTimestamp()
}
FormatTimestamp formats t into Postgres' text format for timestamps.
Need to send dates before 0001 A.D. with " BC" suffix, instead of the minus sign preferred by Go. Beware, "0000" in ISO is "1 BC", "-0001" is "2 BC" and so on
	 := false
flip year sign, and add 1, e.g: "0" will be "1", and "-10" will be "11"
		 = .AddDate((-.Year())*2+1, 0, 0)
		 = true
	}
	 := []byte(.Format("2006-01-02 15:04:05.999999999Z07:00"))

	,  := .Zone()
	 %= 60
RFC3339Nano already printed the minus sign
		if  < 0 {
			 = -
		}

		 = append(, ':')
		if  < 10 {
			 = append(, '0')
		}
		 = strconv.AppendInt(, int64(), 10)
	}

	if  {
		 = append(, " BC"...)
	}
	return 
}
Parse a bytea value received from the server. Both "hex" and the legacy "escape" format are supported.
func ( []byte) ( []byte,  error) {
bytea_output = hex
		 = [2:] // trim off leading "\\x"
		 = make([]byte, hex.DecodedLen(len()))
		,  := hex.Decode(, )
		if  != nil {
			return nil, 
		}
bytea_output = escape
		for len() > 0 {
escaped '\\'
				if len() >= 2 && [1] == '\\' {
					 = append(, '\\')
					 = [2:]
					continue
				}
'\\' followed by an octal number
				if len() < 4 {
					return nil, fmt.Errorf("invalid bytea sequence %v", )
				}
				,  := strconv.ParseInt(string([1:4]), 8, 9)
				if  != nil {
					return nil, fmt.Errorf("could not parse bytea value: %s", .Error())
				}
				 = append(, byte())
				 = [4:]
We hit an unescaped, raw byte. Try to read in as many as possible in one go.
				 := bytes.IndexByte(, '\\')
				if  == -1 {
					 = append(, ...)
					break
				}
				 = append(, [:]...)
				 = [:]
			}
		}
	}

	return , nil
}

func ( int,  []byte) ( []byte) {
Use the hex format if we know that the server supports it
		 = make([]byte, 2+hex.EncodedLen(len()))
		[0] = '\\'
		[1] = 'x'
		hex.Encode([2:], )
.. or resort to "escape"
		for ,  := range  {
			if  == '\\' {
				 = append(, '\\', '\\')
			} else if  < 0x20 ||  > 0x7e {
				 = append(, []byte(fmt.Sprintf("\\%03o", ))...)
			} else {
				 = append(, )
			}
		}
	}

	return 
}
NullTime represents a time.Time that may be null. NullTime implements the sql.Scanner interface so it can be used as a scan destination, similar to sql.NullString.
type NullTime struct {
	Time  time.Time
	Valid bool // Valid is true if Time is not NULL
}
Scan implements the Scanner interface.
func ( *NullTime) ( interface{}) error {
	.Time, .Valid = .(time.Time)
	return nil
}
Value implements the driver Valuer interface.
func ( NullTime) () (driver.Value, error) {
	if !.Valid {
		return nil, nil
	}
	return .Time, nil