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 }