package pgdialect

import (
	
	
	
	
	

	
	
	
	
)

type Dialect struct {
	tables   *schema.Tables
	features feature.Feature

	appenderMap sync.Map
	scannerMap  sync.Map
}

func () *Dialect {
	 := new(Dialect)
	.tables = schema.NewTables()
	.features = feature.CTE |
		feature.Returning |
		feature.DefaultPlaceholder |
		feature.DoubleColonCast |
		feature.InsertTableAlias |
		feature.DeleteTableAlias |
		feature.TableCascade |
		feature.TableIdentity |
		feature.TableTruncate
	return 
}

func ( *Dialect) (*sql.DB) {}

func ( *Dialect) () dialect.Name {
	return dialect.PG
}

func ( *Dialect) () feature.Feature {
	return .features
}

func ( *Dialect) () *schema.Tables {
	return .tables
}

func ( *Dialect) ( *schema.Table) {
	for ,  := range .FieldMap {
		.onField()
	}
}

func ( *Dialect) ( *schema.Field) {
	.DiscoveredSQLType = fieldSQLType()

	if .AutoIncrement {
		switch .DiscoveredSQLType {
		case sqltype.SmallInt:
			.CreateTableSQLType = pgTypeSmallSerial
		case sqltype.Integer:
			.CreateTableSQLType = pgTypeSerial
		case sqltype.BigInt:
			.CreateTableSQLType = pgTypeBigSerial
		}
	}

	if .Tag.HasOption("array") {
		.Append = arrayAppender(.StructField.Type)
		.Scan = arrayScanner(.StructField.Type)
	}
}

func ( *Dialect) () byte {
	return '"'
}

func ( *Dialect) ( schema.Formatter,  []byte,  interface{}) []byte {
	switch v := .(type) {
	case nil:
		return dialect.AppendNull()
	case bool:
		return dialect.AppendBool(, )
	case int:
		return strconv.AppendInt(, int64(), 10)
	case int32:
		return strconv.AppendInt(, int64(), 10)
	case int64:
		return strconv.AppendInt(, , 10)
	case uint:
		return strconv.AppendInt(, int64(), 10)
	case uint32:
		return strconv.AppendInt(, int64(), 10)
	case uint64:
		return strconv.AppendInt(, int64(), 10)
	case float32:
		return dialect.AppendFloat32(, )
	case float64:
		return dialect.AppendFloat64(, )
	case string:
		return dialect.AppendString(, )
	case time.Time:
		return dialect.AppendTime(, )
	case []byte:
		return dialect.AppendBytes(, )
	case schema.QueryAppender:
		return schema.AppendQueryAppender(, , )
	default:
		 := reflect.ValueOf()
		if .Kind() == reflect.Ptr && .IsNil() {
			return dialect.AppendNull()
		}
		 := .Appender(.Type())
		return (, , )
	}
}

func ( *Dialect) ( reflect.Type) schema.AppenderFunc {
	if ,  := .appenderMap.Load();  {
		return .(schema.AppenderFunc)
	}

	 := schema.Appender(, customAppender)

	if ,  := .appenderMap.LoadOrStore(, );  {
		return .(schema.AppenderFunc)
	}
	return 
}

func ( *Dialect) ( *schema.Field) schema.AppenderFunc {
	return schema.FieldAppender(, )
}

func ( *Dialect) ( reflect.Type) schema.ScannerFunc {
	if ,  := .scannerMap.Load();  {
		return .(schema.ScannerFunc)
	}

	 := scanner()

	if ,  := .scannerMap.LoadOrStore(, );  {
		return .(schema.ScannerFunc)
	}
	return 
}