package pq

import (
	
	
	
	
	
	
	
	
)

var typeByteSlice = reflect.TypeOf([]byte{})
var typeDriverValuer = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
var typeSQLScanner = reflect.TypeOf((*sql.Scanner)(nil)).Elem()
Array returns the optimal driver.Valuer and sql.Scanner for an array or slice of any dimension. For example: db.Query(`SELECT * FROM t WHERE id = ANY($1)`, pq.Array([]int{235, 401})) var x []sql.NullInt64 db.QueryRow('SELECT ARRAY[235, 401]').Scan(pq.Array(&x)) Scanning multi-dimensional arrays is not supported. Arrays where the lower bound is not one (such as `[0:0]={1}') are not supported.
func ( interface{}) interface {
	driver.Valuer
	sql.Scanner
} {
	switch a := .(type) {
	case []bool:
		return (*BoolArray)(&)
	case []float64:
		return (*Float64Array)(&)
	case []int64:
		return (*Int64Array)(&)
	case []string:
		return (*StringArray)(&)

	case *[]bool:
		return (*BoolArray)()
	case *[]float64:
		return (*Float64Array)()
	case *[]int64:
		return (*Int64Array)()
	case *[]string:
		return (*StringArray)()
	}

	return GenericArray{}
}
ArrayDelimiter may be optionally implemented by driver.Valuer or sql.Scanner to override the array delimiter used by GenericArray.
ArrayDelimiter returns the delimiter character(s) for this element's type.
	ArrayDelimiter() string
}
BoolArray represents a one-dimensional array of the PostgreSQL boolean type.
type BoolArray []bool
Scan implements the sql.Scanner interface.
func ( *BoolArray) ( interface{}) error {
	switch src := .(type) {
	case []byte:
		return .scanBytes()
	case string:
		return .scanBytes([]byte())
	case nil:
		* = nil
		return nil
	}

	return fmt.Errorf("pq: cannot convert %T to BoolArray", )
}

func ( *BoolArray) ( []byte) error {
	,  := scanLinearArray(, []byte{','}, "BoolArray")
	if  != nil {
		return 
	}
	if * != nil && len() == 0 {
		* = (*)[:0]
	} else {
		 := make(BoolArray, len())
		for ,  := range  {
			if len() != 1 {
				return fmt.Errorf("pq: could not parse boolean array index %d: invalid boolean %q", , )
			}
			switch [0] {
			case 't':
				[] = true
			case 'f':
				[] = false
			default:
				return fmt.Errorf("pq: could not parse boolean array index %d: invalid boolean %q", , )
			}
		}
		* = 
	}
	return nil
}
Value implements the driver.Valuer interface.
func ( BoolArray) () (driver.Value, error) {
	if  == nil {
		return nil, nil
	}

There will be exactly two curly brackets, N bytes of values, and N-1 bytes of delimiters.
		 := make([]byte, 1+2*)

		for  := 0;  < ; ++ {
			[2*] = ','
			if [] {
				[1+2*] = 't'
			} else {
				[1+2*] = 'f'
			}
		}

		[0] = '{'
		[2*] = '}'

		return string(), nil
	}

	return "{}", nil
}
ByteaArray represents a one-dimensional array of the PostgreSQL bytea type.
type ByteaArray [][]byte
Scan implements the sql.Scanner interface.
func ( *ByteaArray) ( interface{}) error {
	switch src := .(type) {
	case []byte:
		return .scanBytes()
	case string:
		return .scanBytes([]byte())
	case nil:
		* = nil
		return nil
	}

	return fmt.Errorf("pq: cannot convert %T to ByteaArray", )
}

func ( *ByteaArray) ( []byte) error {
	,  := scanLinearArray(, []byte{','}, "ByteaArray")
	if  != nil {
		return 
	}
	if * != nil && len() == 0 {
		* = (*)[:0]
	} else {
		 := make(ByteaArray, len())
		for ,  := range  {
			[],  = parseBytea()
			if  != nil {
				return fmt.Errorf("could not parse bytea array index %d: %s", , .Error())
			}
		}
		* = 
	}
	return nil
}
Value implements the driver.Valuer interface. It uses the "hex" format which is only supported on PostgreSQL 9.0 or newer.
func ( ByteaArray) () (driver.Value, error) {
	if  == nil {
		return nil, nil
	}

There will be at least two curly brackets, 2*N bytes of quotes, 3*N bytes of hex formatting, and N-1 bytes of delimiters.
		 := 1 + 6*
		for ,  := range  {
			 += hex.EncodedLen(len())
		}

		 := make([]byte, )

		for ,  := 0, ;  < ; ++ {
			 := copy(, `,"\\x`)
			 += hex.Encode([:], [])
			[] = '"'
			 = [+1:]
		}

		[0] = '{'
		[-1] = '}'

		return string(), nil
	}

	return "{}", nil
}
Float64Array represents a one-dimensional array of the PostgreSQL double precision type.
Scan implements the sql.Scanner interface.
func ( *Float64Array) ( interface{}) error {
	switch src := .(type) {
	case []byte:
		return .scanBytes()
	case string:
		return .scanBytes([]byte())
	case nil:
		* = nil
		return nil
	}

	return fmt.Errorf("pq: cannot convert %T to Float64Array", )
}

func ( *Float64Array) ( []byte) error {
	,  := scanLinearArray(, []byte{','}, "Float64Array")
	if  != nil {
		return 
	}
	if * != nil && len() == 0 {
		* = (*)[:0]
	} else {
		 := make(Float64Array, len())
		for ,  := range  {
			if [],  = strconv.ParseFloat(string(), 64);  != nil {
				return fmt.Errorf("pq: parsing array element index %d: %v", , )
			}
		}
		* = 
	}
	return nil
}
Value implements the driver.Valuer interface.
func ( Float64Array) () (driver.Value, error) {
	if  == nil {
		return nil, nil
	}

There will be at least two curly brackets, N bytes of values, and N-1 bytes of delimiters.
		 := make([]byte, 1, 1+2*)
		[0] = '{'

		 = strconv.AppendFloat(, [0], 'f', -1, 64)
		for  := 1;  < ; ++ {
			 = append(, ',')
			 = strconv.AppendFloat(, [], 'f', -1, 64)
		}

		return string(append(, '}')), nil
	}

	return "{}", nil
}
GenericArray implements the driver.Valuer and sql.Scanner interfaces for an array or slice of any dimension.
type GenericArray struct{ A interface{} }

func (GenericArray) ( reflect.Type) (reflect.Type, func([]byte, reflect.Value) error, string) {
	var  func([]byte, reflect.Value) error
	var  = ","
TODO calculate the assign function for other types TODO repeat this section on the element type of arrays or slices (multidimensional)
	{
dest is always addressable because it is an element of a slice.
			 = func( []byte,  reflect.Value) ( error) {
				 := .Addr().Interface().(sql.Scanner)
				if  == nil {
					 = .Scan(nil)
				} else {
					 = .Scan()
				}
				return
			}
			goto 
		}

		 = func([]byte, reflect.Value) error {
			return fmt.Errorf("pq: scanning to %s is not implemented; only sql.Scanner", )
		}
	}

:

	if ,  := reflect.Zero().Interface().(ArrayDelimiter);  {
		 = .ArrayDelimiter()
	}

	return , , 
}
Scan implements the sql.Scanner interface.
func ( GenericArray) ( interface{}) error {
	 := reflect.ValueOf(.A)
	switch {
	case .Kind() != reflect.Ptr:
		return fmt.Errorf("pq: destination %T is not a pointer to array or slice", .A)
	case .IsNil():
		return fmt.Errorf("pq: destination %T is nil", .A)
	}

	 := .Elem()
	switch .Kind() {
	case reflect.Slice:
	case reflect.Array:
	default:
		return fmt.Errorf("pq: destination %T is not a pointer to array or slice", .A)
	}

	switch src := .(type) {
	case []byte:
		return .scanBytes(, )
	case string:
		return .scanBytes([]byte(), )
	case nil:
		if .Kind() == reflect.Slice {
			.Set(reflect.Zero(.Type()))
			return nil
		}
	}

	return fmt.Errorf("pq: cannot convert %T to %s", , .Type())
}

func ( GenericArray) ( []byte,  reflect.Value) error {
	, ,  := .evaluateDestination(.Type().Elem())
	, ,  := parseArray(, []byte())
	if  != nil {
		return 
	}
TODO allow multidimensional

	if len() > 1 {
		return fmt.Errorf("pq: scanning from multidimensional ARRAY%s is not implemented",
			strings.Replace(fmt.Sprint(), " ", "][", -1))
	}
Treat a zero-dimensional array like an array with a single dimension of zero.
	if len() == 0 {
		 = append(, 0)
	}

	for ,  := 0, .Type();  < len(); ,  = +1, .Elem() {
		switch .Kind() {
		case reflect.Slice:
		case reflect.Array:
			if .Len() != [] {
				return fmt.Errorf("pq: cannot convert ARRAY%s to %s",
					strings.Replace(fmt.Sprint(), " ", "][", -1), .Type())
			}
TODO handle multidimensional
		}
	}

	 := reflect.MakeSlice(reflect.SliceOf(), len(), len())
	for ,  := range  {
		if  := (, .Index());  != nil {
			return fmt.Errorf("pq: parsing array element index %d: %v", , )
		}
	}
TODO handle multidimensional

	switch .Kind() {
	case reflect.Slice:
		.Set(.Slice(0, [0]))
	case reflect.Array:
		for  := 0;  < [0]; ++ {
			.Index().Set(.Index())
		}
	}

	return nil
}
Value implements the driver.Valuer interface.
func ( GenericArray) () (driver.Value, error) {
	if .A == nil {
		return nil, nil
	}

	 := reflect.ValueOf(.A)

	switch .Kind() {
	case reflect.Slice:
		if .IsNil() {
			return nil, nil
		}
	case reflect.Array:
	default:
		return nil, fmt.Errorf("pq: Unable to convert %T to array", .A)
	}

There will be at least two curly brackets, N bytes of values, and N-1 bytes of delimiters.
		 := make([]byte, 0, 1+2*)

		, ,  := appendArray(, , )
		return string(), 
	}

	return "{}", nil
}
Int64Array represents a one-dimensional array of the PostgreSQL integer types.
Scan implements the sql.Scanner interface.
func ( *Int64Array) ( interface{}) error {
	switch src := .(type) {
	case []byte:
		return .scanBytes()
	case string:
		return .scanBytes([]byte())
	case nil:
		* = nil
		return nil
	}

	return fmt.Errorf("pq: cannot convert %T to Int64Array", )
}

func ( *Int64Array) ( []byte) error {
	,  := scanLinearArray(, []byte{','}, "Int64Array")
	if  != nil {
		return 
	}
	if * != nil && len() == 0 {
		* = (*)[:0]
	} else {
		 := make(Int64Array, len())
		for ,  := range  {
			if [],  = strconv.ParseInt(string(), 10, 64);  != nil {
				return fmt.Errorf("pq: parsing array element index %d: %v", , )
			}
		}
		* = 
	}
	return nil
}
Value implements the driver.Valuer interface.
func ( Int64Array) () (driver.Value, error) {
	if  == nil {
		return nil, nil
	}

There will be at least two curly brackets, N bytes of values, and N-1 bytes of delimiters.
		 := make([]byte, 1, 1+2*)
		[0] = '{'

		 = strconv.AppendInt(, [0], 10)
		for  := 1;  < ; ++ {
			 = append(, ',')
			 = strconv.AppendInt(, [], 10)
		}

		return string(append(, '}')), nil
	}

	return "{}", nil
}
StringArray represents a one-dimensional array of the PostgreSQL character types.
Scan implements the sql.Scanner interface.
func ( *StringArray) ( interface{}) error {
	switch src := .(type) {
	case []byte:
		return .scanBytes()
	case string:
		return .scanBytes([]byte())
	case nil:
		* = nil
		return nil
	}

	return fmt.Errorf("pq: cannot convert %T to StringArray", )
}

func ( *StringArray) ( []byte) error {
	,  := scanLinearArray(, []byte{','}, "StringArray")
	if  != nil {
		return 
	}
	if * != nil && len() == 0 {
		* = (*)[:0]
	} else {
		 := make(StringArray, len())
		for ,  := range  {
			if [] = string();  == nil {
				return fmt.Errorf("pq: parsing array element index %d: cannot convert nil to string", )
			}
		}
		* = 
	}
	return nil
}
Value implements the driver.Valuer interface.
func ( StringArray) () (driver.Value, error) {
	if  == nil {
		return nil, nil
	}

There will be at least two curly brackets, 2*N bytes of quotes, and N-1 bytes of delimiters.
		 := make([]byte, 1, 1+3*)
		[0] = '{'

		 = appendArrayQuotedBytes(, []byte([0]))
		for  := 1;  < ; ++ {
			 = append(, ',')
			 = appendArrayQuotedBytes(, []byte([]))
		}

		return string(append(, '}')), nil
	}

	return "{}", nil
}
appendArray appends rv to the buffer, returning the extended buffer and the delimiter used between elements. It panics when n <= 0 or rv's Kind is not reflect.Array nor reflect.Slice.
func ( []byte,  reflect.Value,  int) ([]byte, string, error) {
	var  string
	var  error

	 = append(, '{')

	if , ,  = appendArrayElement(, .Index(0));  != nil {
		return , , 
	}

	for  := 1;  < ; ++ {
		 = append(, ...)
		if , ,  = appendArrayElement(, .Index());  != nil {
			return , , 
		}
	}

	return append(, '}'), , nil
}
appendArrayElement appends rv to the buffer, returning the extended buffer and the delimiter to use before the next element. When rv's Kind is neither reflect.Array nor reflect.Slice, it is converted using driver.DefaultParameterConverter and the resulting []byte or string is double-quoted. See http://www.postgresql.org/docs/current/static/arrays.html#ARRAYS-IO
func ( []byte,  reflect.Value) ([]byte, string, error) {
	if  := .Kind();  == reflect.Array ||  == reflect.Slice {
		if  := .Type();  != typeByteSlice && !.Implements(typeDriverValuer) {
			if  := .Len();  > 0 {
				return appendArray(, , )
			}

			return , "", nil
		}
	}

	var  = ","
	var  error
	var  interface{} = .Interface()

	if ,  := .(ArrayDelimiter);  {
		 = .ArrayDelimiter()
	}

	if ,  = driver.DefaultParameterConverter.ConvertValue();  != nil {
		return , , 
	}

	switch v := .(type) {
	case nil:
		return append(, "NULL"...), , nil
	case []byte:
		return appendArrayQuotedBytes(, ), , nil
	case string:
		return appendArrayQuotedBytes(, []byte()), , nil
	}

	,  = appendValue(, )
	return , , 
}

func (,  []byte) []byte {
	 = append(, '"')
	for {
		 := bytes.IndexAny(, `"\`)
		if  < 0 {
			 = append(, ...)
			break
		}
		if  > 0 {
			 = append(, [:]...)
		}
		 = append(, '\\', [])
		 = [+1:]
	}
	return append(, '"')
}

func ( []byte,  driver.Value) ([]byte, error) {
	return append(, encode(nil, , 0)...), nil
}
parseArray extracts the dimensions and elements of an array represented in text format. Only representations emitted by the backend are supported. Notably, whitespace around brackets and delimiters is significant, and NULL is case-sensitive. See http://www.postgresql.org/docs/current/static/arrays.html#ARRAYS-IO
func (,  []byte) ( []int,  [][]byte,  error) {
	var ,  int

	if len() < 1 || [0] != '{' {
		return nil, nil, fmt.Errorf("pq: unable to parse array; expected %q at offset %d", '{', 0)
	}

:
	for  < len() {
		switch [] {
		case '{':
			++
			++
		case '}':
			 = make([][]byte, 0)
			goto 
		default:
			break 
		}
	}
	 = make([]int, )

:
	for  < len() {
		switch [] {
		case '{':
			if  == len() {
				break 
			}
			++
			[-1] = 0
			++
		case '"':
			var  = []byte{}
			var  bool
			for ++;  < len(); ++ {
				if  {
					 = append(, [])
					 = false
				} else {
					switch [] {
					default:
						 = append(, [])
					case '\\':
						 = true
					case '"':
						 = append(, )
						++
						break 
					}
				}
			}
		default:
			for  := ;  < len(); ++ {
				if bytes.HasPrefix([:], ) || [] == '}' {
					 := [:]
					if len() == 0 {
						return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", [], )
					}
					if bytes.Equal(, []byte("NULL")) {
						 = nil
					}
					 = append(, )
					break 
				}
			}
		}
	}

	for  < len() {
		if bytes.HasPrefix([:], ) &&  > 0 {
			[-1]++
			 += len()
			goto 
		} else if [] == '}' &&  > 0 {
			[-1]++
			--
			++
		} else {
			return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", [], )
		}
	}

:
	for  < len() {
		if [] == '}' &&  > 0 {
			--
			++
		} else {
			return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", [], )
		}
	}
	if  > 0 {
		 = fmt.Errorf("pq: unable to parse array; expected %q at offset %d", '}', )
	}
	if  == nil {
		for ,  := range  {
			if (len() % ) != 0 {
				 = fmt.Errorf("pq: multidimensional arrays must have elements with matching dimensions")
			}
		}
	}
	return
}

func (,  []byte,  string) ( [][]byte,  error) {
	, ,  := parseArray(, )
	if  != nil {
		return nil, 
	}
	if len() > 1 {
		return nil, fmt.Errorf("pq: cannot convert ARRAY%s to %s", strings.Replace(fmt.Sprint(), " ", "][", -1), )
	}
	return ,