github.com/snowflakedb/gosnowflake@v1.9.0/datatype.go (about)

     1  // Copyright (c) 2017-2022 Snowflake Computing Inc. All rights reserved.
     2  
     3  package gosnowflake
     4  
     5  import (
     6  	"bytes"
     7  	"database/sql"
     8  	"database/sql/driver"
     9  	"fmt"
    10  	"strings"
    11  )
    12  
    13  type snowflakeType int
    14  
    15  const (
    16  	fixedType snowflakeType = iota
    17  	realType
    18  	textType
    19  	dateType
    20  	variantType
    21  	timestampLtzType
    22  	timestampNtzType
    23  	timestampTzType
    24  	objectType
    25  	arrayType
    26  	binaryType
    27  	timeType
    28  	booleanType
    29  	// the following are not snowflake types per se but internal types
    30  	nullType
    31  	sliceType
    32  	changeType
    33  	unSupportedType
    34  )
    35  
    36  var snowflakeToDriverType = map[string]snowflakeType{
    37  	"FIXED":         fixedType,
    38  	"REAL":          realType,
    39  	"TEXT":          textType,
    40  	"DATE":          dateType,
    41  	"VARIANT":       variantType,
    42  	"TIMESTAMP_LTZ": timestampLtzType,
    43  	"TIMESTAMP_NTZ": timestampNtzType,
    44  	"TIMESTAMP_TZ":  timestampTzType,
    45  	"OBJECT":        objectType,
    46  	"ARRAY":         arrayType,
    47  	"BINARY":        binaryType,
    48  	"TIME":          timeType,
    49  	"BOOLEAN":       booleanType,
    50  	"NULL":          nullType,
    51  	"SLICE":         sliceType,
    52  	"CHANGE_TYPE":   changeType,
    53  	"NOT_SUPPORTED": unSupportedType}
    54  
    55  var driverTypeToSnowflake = invertMap(snowflakeToDriverType)
    56  
    57  func invertMap(m map[string]snowflakeType) map[snowflakeType]string {
    58  	inv := make(map[snowflakeType]string)
    59  	for k, v := range m {
    60  		if _, ok := inv[v]; ok {
    61  			panic("failed to create driverTypeToSnowflake map due to duplicated values")
    62  		}
    63  		inv[v] = k
    64  	}
    65  	return inv
    66  }
    67  
    68  func (st snowflakeType) Byte() byte {
    69  	return byte(st)
    70  }
    71  
    72  func (st snowflakeType) String() string {
    73  	return driverTypeToSnowflake[st]
    74  }
    75  
    76  func getSnowflakeType(typ string) snowflakeType {
    77  	return snowflakeToDriverType[strings.ToUpper(typ)]
    78  }
    79  
    80  var (
    81  	// DataTypeFixed is a FIXED datatype.
    82  	DataTypeFixed = []byte{fixedType.Byte()}
    83  	// DataTypeReal is a REAL datatype.
    84  	DataTypeReal = []byte{realType.Byte()}
    85  	// DataTypeText is a TEXT datatype.
    86  	DataTypeText = []byte{textType.Byte()}
    87  	// DataTypeDate is a Date datatype.
    88  	DataTypeDate = []byte{dateType.Byte()}
    89  	// DataTypeVariant is a TEXT datatype.
    90  	DataTypeVariant = []byte{variantType.Byte()}
    91  	// DataTypeTimestampLtz is a TIMESTAMP_LTZ datatype.
    92  	DataTypeTimestampLtz = []byte{timestampLtzType.Byte()}
    93  	// DataTypeTimestampNtz is a TIMESTAMP_NTZ datatype.
    94  	DataTypeTimestampNtz = []byte{timestampNtzType.Byte()}
    95  	// DataTypeTimestampTz is a TIMESTAMP_TZ datatype.
    96  	DataTypeTimestampTz = []byte{timestampTzType.Byte()}
    97  	// DataTypeObject is a OBJECT datatype.
    98  	DataTypeObject = []byte{objectType.Byte()}
    99  	// DataTypeArray is a ARRAY datatype.
   100  	DataTypeArray = []byte{arrayType.Byte()}
   101  	// DataTypeBinary is a BINARY datatype.
   102  	DataTypeBinary = []byte{binaryType.Byte()}
   103  	// DataTypeTime is a TIME datatype.
   104  	DataTypeTime = []byte{timeType.Byte()}
   105  	// DataTypeBoolean is a BOOLEAN datatype.
   106  	DataTypeBoolean = []byte{booleanType.Byte()}
   107  )
   108  
   109  // dataTypeMode returns the subsequent data type in a string representation.
   110  func dataTypeMode(v driver.Value) (tsmode snowflakeType, err error) {
   111  	if bd, ok := v.([]byte); ok {
   112  		switch {
   113  		case bytes.Equal(bd, DataTypeDate):
   114  			tsmode = dateType
   115  		case bytes.Equal(bd, DataTypeTime):
   116  			tsmode = timeType
   117  		case bytes.Equal(bd, DataTypeTimestampLtz):
   118  			tsmode = timestampLtzType
   119  		case bytes.Equal(bd, DataTypeTimestampNtz):
   120  			tsmode = timestampNtzType
   121  		case bytes.Equal(bd, DataTypeTimestampTz):
   122  			tsmode = timestampTzType
   123  		case bytes.Equal(bd, DataTypeBinary):
   124  			tsmode = binaryType
   125  		default:
   126  			return nullType, fmt.Errorf(errMsgInvalidByteArray, v)
   127  		}
   128  	} else {
   129  		return nullType, fmt.Errorf(errMsgInvalidByteArray, v)
   130  	}
   131  	return tsmode, nil
   132  }
   133  
   134  // SnowflakeParameter includes the columns output from SHOW PARAMETER command.
   135  type SnowflakeParameter struct {
   136  	Key                       string
   137  	Value                     string
   138  	Default                   string
   139  	Level                     string
   140  	Description               string
   141  	SetByUser                 string
   142  	SetInJob                  string
   143  	SetOn                     string
   144  	SetByThreadID             string
   145  	SetByThreadName           string
   146  	SetByClass                string
   147  	ParameterComment          string
   148  	Type                      string
   149  	IsExpired                 string
   150  	ExpiresAt                 string
   151  	SetByControllingParameter string
   152  	ActivateVersion           string
   153  	PartialRollout            string
   154  	Unknown                   string // Reserve for added parameter
   155  }
   156  
   157  func populateSnowflakeParameter(colname string, p *SnowflakeParameter) interface{} {
   158  	switch colname {
   159  	case "key":
   160  		return &p.Key
   161  	case "value":
   162  		return &p.Value
   163  	case "default":
   164  		return &p.Default
   165  	case "level":
   166  		return &p.Level
   167  	case "description":
   168  		return &p.Description
   169  	case "set_by_user":
   170  		return &p.SetByUser
   171  	case "set_in_job":
   172  		return &p.SetInJob
   173  	case "set_on":
   174  		return &p.SetOn
   175  	case "set_by_thread_id":
   176  		return &p.SetByThreadID
   177  	case "set_by_thread_name":
   178  		return &p.SetByThreadName
   179  	case "set_by_class":
   180  		return &p.SetByClass
   181  	case "parameter_comment":
   182  		return &p.ParameterComment
   183  	case "type":
   184  		return &p.Type
   185  	case "is_expired":
   186  		return &p.IsExpired
   187  	case "expires_at":
   188  		return &p.ExpiresAt
   189  	case "set_by_controlling_parameter":
   190  		return &p.SetByControllingParameter
   191  	case "activate_version":
   192  		return &p.ActivateVersion
   193  	case "partial_rollout":
   194  		return &p.PartialRollout
   195  	default:
   196  		debugPanicf("unknown type: %v", colname)
   197  		return &p.Unknown
   198  	}
   199  }
   200  
   201  // ScanSnowflakeParameter binds SnowflakeParameter variable with an array of column buffer.
   202  func ScanSnowflakeParameter(rows *sql.Rows) (*SnowflakeParameter, error) {
   203  	var err error
   204  	var columns []string
   205  	columns, err = rows.Columns()
   206  	if err != nil {
   207  		return nil, err
   208  	}
   209  	colNum := len(columns)
   210  	p := SnowflakeParameter{}
   211  	cols := make([]interface{}, colNum)
   212  	for i := 0; i < colNum; i++ {
   213  		cols[i] = populateSnowflakeParameter(columns[i], &p)
   214  	}
   215  	err = rows.Scan(cols...)
   216  	return &p, err
   217  }