// columnSQLType determines the type of a column
// if throughout the whole column values have the same type then this type is
// returned, otherwise the VARCHAR/TEXT type is returned.
// numeric types are coerced into DOUBLE/NUMERIC
164568
func (d *Dataset) columnSQLType(header, dbType string) (string, []interface{}) {
	types := 0
	currentType := ""
	maxString := 0
	values := d.Column(header)
	for _, c := range values {
		switch c.(type) {
		case uint, uint8, uint16, uint32, uint64,
			int, int8, int16, int32, int64,
			float32, float64:
			if currentType != "numeric" {
				currentType = "numeric"
				types++
			}
		case time.Time:
			if currentType != "time" {
				currentType = "time"
				types++
			}
		case string:
			if currentType != "string" {
				currentType = "string"
				types++
			}
			if len(c.(string)) > maxString {
				maxString = len(c.(string))
			}
		}
	}

	if types > 1 {
		return defaults["various."+dbType], values
	}
	switch currentType {
	case "numeric":
		return defaults["numeric."+dbType], values
	case "time":
		return "TIMESTAMP", values
	default:
		if dbType == typePostgres {
			return "TEXT", values
		}
		return "VARCHAR(" + strconv.Itoa(maxString) + ")", values
	}
}
842444
func (d *Dataset) sql(table, dbType string) *Exportable {
	b := newBuffer()

	tableSQL, columnTypes, columnValues := d.createTable(table, dbType)
	b.WriteString(tableSQL)

	reg, _ := regexp.Compile("[']")
	// inserts
	for i := range d.data {
		b.WriteString("INSERT INTO " + table + " VALUES(" + strconv.Itoa(i+1) + ", ")
		for j, col := range d.headers {
			asStr := d.asString(columnValues[col][i])
			if isStringColumn(columnTypes[col]) {
				b.WriteString("'" + reg.ReplaceAllString(asStr, "''") + "'")
			} else if strings.HasPrefix(columnTypes[col], "TIMESTAMP") {
				if dbType == typeMySQL {
					b.WriteString("CONVERT_TZ('" + asStr[:10] + " " + asStr[11:19] + "', '" + asStr[len(asStr)-6:] + "', 'SYSTEM')")
				} else {
					b.WriteString("'" + asStr + "'") // simpler with Postgres
				}
			} else {
				b.WriteString(asStr)
			}
			if j < len(d.headers)-1 {
				b.WriteString(", ")
			}
		}
		b.WriteString(");\n")
	}
	b.WriteString("\nCOMMIT;\n")

	return newExportable(b)
}
336727
func (s *mysql) DataTypeOf(field *StructField) string {
	var dataValue, sqlType, size, additionalType = ParseFieldStructForDialect(field, s)

	// MySQL allows only one auto increment column per table, and it must
	// be a KEY column.
	if _, ok := field.TagSettingsGet("AUTO_INCREMENT"); ok {
		if _, ok = field.TagSettingsGet("INDEX"); !ok && !field.IsPrimaryKey {
			field.TagSettingsDelete("AUTO_INCREMENT")
		}
	}

	if sqlType == "" {
		switch dataValue.Kind() {
		case reflect.Bool:
			sqlType = "boolean"
		case reflect.Int8:
			if s.fieldCanAutoIncrement(field) {
				field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
				sqlType = "tinyint AUTO_INCREMENT"
			} else {
				sqlType = "tinyint"
			}
		case reflect.Int, reflect.Int16, reflect.Int32:
			if s.fieldCanAutoIncrement(field) {
				field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
				sqlType = "int AUTO_INCREMENT"
			} else {
				sqlType = "int"
			}
		case reflect.Uint8:
			if s.fieldCanAutoIncrement(field) {
				field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
				sqlType = "tinyint unsigned AUTO_INCREMENT"
			} else {
				sqlType = "tinyint unsigned"
			}
		case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uintptr:
			if s.fieldCanAutoIncrement(field) {
				field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
				sqlType = "int unsigned AUTO_INCREMENT"
			} else {
				sqlType = "int unsigned"
			}
		case reflect.Int64:
			if s.fieldCanAutoIncrement(field) {
				field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
				sqlType = "bigint AUTO_INCREMENT"
			} else {
				sqlType = "bigint"
			}
		case reflect.Uint64:
			if s.fieldCanAutoIncrement(field) {
				field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
				sqlType = "bigint unsigned AUTO_INCREMENT"
			} else {
				sqlType = "bigint unsigned"
			}
		case reflect.Float32, reflect.Float64:
			sqlType = "double"
		case reflect.String:
			if size > 0 && size < 65532 {
				sqlType = fmt.Sprintf("varchar(%d)", size)
			} else {
				sqlType = "longtext"
			}
		case reflect.Struct:
			if _, ok := dataValue.Interface().(time.Time); ok {
				precision := ""
				if p, ok := field.TagSettingsGet("PRECISION"); ok {
					precision = fmt.Sprintf("(%s)", p)
				}

				if _, ok := field.TagSettingsGet("NOT NULL"); ok || field.IsPrimaryKey {
					sqlType = fmt.Sprintf("timestamp%v", precision)
				} else {
					sqlType = fmt.Sprintf("timestamp%v NULL", precision)
				}
			}
		default:
			if IsByteArrayOrSlice(dataValue) {
				if size > 0 && size < 65532 {
					sqlType = fmt.Sprintf("varbinary(%d)", size)
				} else {
					sqlType = "longblob"
				}
			}
		}
	}

	if sqlType == "" {
		panic(fmt.Sprintf("invalid sql type %s (%s) for mysql", dataValue.Type().Name(), dataValue.Kind().String()))
	}

	if strings.TrimSpace(additionalType) == "" {
		return sqlType
	}
	return fmt.Sprintf("%v %v", sqlType, additionalType)
}
1057552
func (q MultiMatchQuery) Type(matchQueryType string) MultiMatchQuery {
	zero := float32(0.0)
	one := float32(1.0)

	switch strings.ToLower(matchQueryType) {
	default: // best_fields / boolean
		q.matchQueryType = "best_fields"
		q.tieBreaker = &zero
	case "most_fields":
		q.matchQueryType = "most_fields"
		q.tieBreaker = &one
	case "cross_fields":
		q.matchQueryType = "cross_fields"
		q.tieBreaker = &zero
	case "phrase":
		q.matchQueryType = "phrase"
		q.tieBreaker = &zero
	case "phrase_prefix":
		q.matchQueryType = "phrase_prefix"
		q.tieBreaker = &zero
	}
	return q
}
264029
func IsTypeChar(tp byte) bool {
	switch tp {
	case mysql.TypeString, mysql.TypeVarchar:
		return true
	default:
		return false
	}
}
474371
func (rows *mysqlRows) ColumnTypeNullable(i int) (nullable, ok bool) {
	return rows.rs.columns[i].flags&flagNotNULL == 0, true
}
138583
func (adapter *PostgresAdapter) TypeMapping(sqlColumnType types.SQLColumnType) (string, error) {
	if sqlDataType, ok := pgDataTypes[sqlColumnType]; ok {
		return sqlDataType, nil
	}

	return "", fmt.Errorf("datatype %v not recognized", sqlColumnType)
}
468473
func SqTableColumns(db XODB, table string) ([]*SqColumn, error) {
	var err error

	// sql query
	var sqlstr = `PRAGMA table_info(` + table + `)`

	// run query
	XOLog(sqlstr)
	q, err := db.Query(sqlstr, table)
	if err != nil {
		return nil, err
	}
	defer q.Close()

	// load results
	res := []*SqColumn{}
	for q.Next() {
		sc := SqColumn{}

		// scan
		err = q.Scan(&sc.FieldOrdinal, &sc.ColumnName, &sc.DataType, &sc.NotNull, &sc.DefaultValue, &sc.PkColIndex)
		if err != nil {
			return nil, err
		}

		res = append(res, &sc)
	}

	return res, nil
}
812242
func (me *DefaultAdapter) SelectSql(buf *SqlBuilder, cols ColumnList) error {
	buf.Write(me.SelectClause)
	buf.WriteRune(space_rune)
	if len(cols.Columns()) == 0 {
		buf.WriteRune(star_rune)
	} else {
		return me.Literal(buf, cols)
	}
	return nil
}
198476
func (t *TableMap) ColMap(field string) *ColumnMap {
	for _, col := range t.Columns {
		if col.fieldName == field || col.ColumnName == field {
			return col
		}
	}
	panic(fmt.Sprintf("No ColumnMap in table %s type %s with field %s",
		t.TableName, t.gotype.Name(), field))
}
634404
func EvalType(expr Expr, sources Sources, typmap TypeMapper) DataType {
	if typmap == nil {
		typmap = nilTypeMapper{}
	}

	valuer := TypeValuerEval{
		TypeMapper: typmap,
		Sources:    sources,
	}
	typ, _ := valuer.EvalType(expr)
	return typ
}
232609
func (session *Session) Cols(columns ...string) *Session {
	session.Statement.Cols(columns...)
	return session
}
325837
func (d *Database) Columns(src interface{}, includePk bool) ([]string, error) {
	data, err := getFields(reflect.TypeOf(src))
	if err != nil {
		return nil, err
	}

	var names []string
	for _, elt := range data.columns {
		if !includePk && elt == data.pk {
			continue
		}
		names = append(names, elt)
	}

	return names, nil
}
853472
func (q MatchQuery) Type(matchQueryType string) MatchQuery {
	q.matchQueryType = matchQueryType
	return q
}
453568
func (me *DefaultAdapter) SelectDistinctSql(buf *SqlBuilder, cols ColumnList) error {
	buf.Write(me.SelectClause)
	buf.Write(me.DistinctFragment)
	return me.Literal(buf, cols)
}
350963
func (rs *Rows) Columns() ([]string, error) {
	if rs.closed {
		return nil, errors.New("sql: Rows are closed")
	}
	if rs.rowsi == nil {
		return nil, errors.New("sql: no Rows available")
	}
	return rs.rowsi.Columns(), nil
}
1341312
func (cb *ColumnBuilder) VarChar(size int64) *CreateTableBuilder {
	return cb.tableBuilder.appendColumn(&tableColumn{
		name:    cb.name,
		sqlType: fmt.Sprintf("VARCHAR(%v)", size),
	})
}