package pgdriver

import (
	
	
	
	
	
	
)

const (
	pgBool = 16

	pgInt2 = 21
	pgInt4 = 23
	pgInt8 = 20

	pgFloat4 = 700
	pgFloat8 = 701

	pgText    = 25
	pgVarchar = 1043
	pgBytea   = 17

	pgDate        = 1082
	pgTimestamp   = 1114
	pgTimestamptz = 1184
)

func ( *reader,  int32,  int) (interface{}, error) {
	if  == -1 {
		return nil, nil
	}

	switch  {
	case pgBool:
		return readBoolCol(, )
	case pgInt2:
		return readIntCol(, , 16)
	case pgInt4:
		return readIntCol(, , 32)
	case pgInt8:
		return readIntCol(, , 64)
	case pgFloat4:
		return readFloatCol(, , 32)
	case pgFloat8:
		return readFloatCol(, , 64)
	case pgTimestamp:
		return readTimeCol(, )
	case pgTimestamptz:
		return readTimeCol(, )
	case pgDate:
		// Return a string and let the scanner to convert string to time.Time if necessary.
		return readStringCol(, )
	case pgText, pgVarchar:
		return readStringCol(, )
	case pgBytea:
		return readBytesCol(, )
	}

	 := make([]byte, )
	if ,  := io.ReadFull(, );  != nil {
		return nil, 
	}
	return , nil
}

func ( *reader,  int) (interface{}, error) {
	,  := .ReadTemp()
	if  != nil {
		return nil, 
	}
	return len() == 1 && ([0] == 't' || [0] == '1'), nil
}

func ( *reader,  int,  int) (interface{}, error) {
	if  <= 0 {
		return 0, nil
	}

	,  := .ReadTemp()
	if  != nil {
		return 0, 
	}

	return strconv.ParseInt(bytesToString(), 10, )
}

func ( *reader,  int,  int) (interface{}, error) {
	if  <= 0 {
		return 0, nil
	}

	,  := .ReadTemp()
	if  != nil {
		return 0, 
	}

	return strconv.ParseFloat(bytesToString(), )
}

func ( *reader,  int) (interface{}, error) {
	if  <= 0 {
		return "", nil
	}

	 := make([]byte, )

	if ,  := io.ReadFull(, );  != nil {
		return nil, 
	}

	return bytesToString(), nil
}

func ( *reader,  int) (interface{}, error) {
	if  <= 0 {
		return []byte{}, nil
	}

	,  := .ReadTemp()
	if  != nil {
		return nil, 
	}

	if len() < 2 || [0] != '\\' || [1] != 'x' {
		return nil, fmt.Errorf("pgdriver: can't parse bytea: %q", )
	}
	 = [2:] // Cut off "\x".

	 := make([]byte, hex.DecodedLen(len()))
	if ,  := hex.Decode(, );  != nil {
		return nil, 
	}
	return , nil
}

func ( *reader,  int) (interface{}, error) {
	if  <= 0 {
		return time.Time{}, nil
	}

	,  := .ReadTemp()
	if  != nil {
		return time.Time{}, 
	}

	,  := parseTime(bytesToString())
	if  != nil {
		return time.Time{}, 
	}
	return , nil
}

const (
	dateFormat         = "2006-01-02"
	timeFormat         = "15:04:05.999999999"
	timestampFormat    = "2006-01-02 15:04:05.999999999"
	timestamptzFormat  = "2006-01-02 15:04:05.999999999-07:00:00"
	timestamptzFormat2 = "2006-01-02 15:04:05.999999999-07:00"
	timestamptzFormat3 = "2006-01-02 15:04:05.999999999-07"
)

func ( string) (time.Time, error) {
	switch  := len(); {
	case  < len("15:04:05"):
		return time.Time{}, fmt.Errorf("pgdriver: can't parse time=%q", )
	case  <= len(timeFormat):
		if [2] == ':' {
			return time.ParseInLocation(timeFormat, , time.UTC)
		}
		return time.ParseInLocation(dateFormat, , time.UTC)
	default:
		if [10] == 'T' {
			return time.Parse(time.RFC3339Nano, )
		}
		if  := [-9];  == '+' ||  == '-' {
			return time.Parse(timestamptzFormat, )
		}
		if  := [-6];  == '+' ||  == '-' {
			return time.Parse(timestamptzFormat2, )
		}
		if  := [-3];  == '+' ||  == '-' {
			if strings.HasSuffix(, "+00") {
				 = [:len()-3]
				return time.ParseInLocation(timestampFormat, , time.UTC)
			}
			return time.Parse(timestamptzFormat3, )
		}
		return time.ParseInLocation(timestampFormat, , time.UTC)
	}
}