github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/builtin/unary/infomation_function.go (about) 1 // Copyright 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package unary 16 17 import ( 18 "github.com/matrixorigin/matrixone/pkg/common/moerr" 19 "github.com/matrixorigin/matrixone/pkg/container/types" 20 "github.com/matrixorigin/matrixone/pkg/container/vector" 21 "github.com/matrixorigin/matrixone/pkg/vm/process" 22 ) 23 24 /* 25 These functions get information from the session and system status. 26 */ 27 28 func adapter(vectors []*vector.Vector, 29 proc *process.Process, 30 resultType types.Type, 31 parameterCount int, 32 evaluateMemoryCapacityForJobFunc func(proc *process.Process, params ...interface{}) (int, error), 33 jobFunc func(proc *process.Process, params ...interface{}) (interface{}, error), 34 ) (*vector.Vector, error) { 35 if parameterCount == 0 { 36 //XXX step 1 is not needed now. 37 //step 1: evaluate the capacity for result vector 38 39 //step 2: allocate the memory for the result 40 var svals []string 41 var uvals []uint64 42 var resultSpace interface{} 43 if resultType.IsString() { 44 svals = make([]string, 1) 45 resultSpace = svals 46 } else { 47 uvals = make([]uint64, 1) 48 resultSpace = uvals 49 } 50 //step 3: evaluate the function and get the result 51 result, err := jobFunc(proc, resultSpace) 52 if err != nil { 53 return nil, err 54 } 55 //step 4: fill the result vector 56 if result == nil { 57 return vector.NewConstNull(resultType, 1), nil 58 } else if resultType.IsString() { 59 return vector.NewConstString(resultType, 1, svals[0], proc.Mp()), nil 60 } else { 61 return vector.NewConstFixed(resultType, 1, uvals[0], proc.Mp()), nil 62 } 63 } 64 return nil, moerr.NewInternalError(proc.Ctx, "the parameter is invalid") 65 } 66 67 func evaluateMemoryCapacityForDatabase(proc *process.Process, params ...interface{}) (int, error) { 68 return len(proc.SessionInfo.GetDatabase()), nil 69 } 70 71 func doDatabase(proc *process.Process, params ...interface{}) (interface{}, error) { 72 result := params[0].([]string) 73 result[0] = proc.SessionInfo.GetDatabase() 74 if len(result[0]) == 0 { 75 return nil, nil 76 } 77 return result, nil 78 } 79 80 // Database returns the default (current) database name 81 func Database(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 82 return adapter(vectors, proc, types.T_varchar.ToType(), 83 0, 84 evaluateMemoryCapacityForDatabase, 85 doDatabase) 86 } 87 88 func evaluateMemoryCapacityForUser(proc *process.Process, params ...interface{}) (int, error) { 89 return len(proc.SessionInfo.GetUserHost()), nil 90 } 91 92 func doUser(proc *process.Process, params ...interface{}) (interface{}, error) { 93 result := params[0].([]string) 94 result[0] = proc.SessionInfo.GetUserHost() 95 return result, nil 96 } 97 98 // User returns the user name and host name provided by the client 99 func User(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 100 return adapter(vectors, proc, types.T_varchar.ToType(), 101 0, 102 evaluateMemoryCapacityForUser, 103 doUser) 104 } 105 106 func evaluateMemoryCapacityForConnectionID(proc *process.Process, params ...interface{}) (int, error) { 107 return 8, nil 108 } 109 110 func doConnectionID(proc *process.Process, params ...interface{}) (interface{}, error) { 111 result := params[0].([]uint64) 112 result[0] = proc.SessionInfo.ConnectionID 113 return result, nil 114 } 115 116 // ConnectionID returns the connection ID (thread ID) for the connection 117 func ConnectionID(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 118 return adapter(vectors, proc, types.T_uint64.ToType(), 119 0, 120 evaluateMemoryCapacityForConnectionID, 121 doConnectionID) 122 } 123 124 func evaluateMemoryCapacityForCharset(proc *process.Process, params ...interface{}) (int, error) { 125 return len(proc.SessionInfo.GetCharset()), nil 126 } 127 128 func doCharset(proc *process.Process, params ...interface{}) (interface{}, error) { 129 result := params[0].([]string) 130 result[0] = proc.SessionInfo.GetCharset() 131 return result, nil 132 } 133 134 // Charset returns the character set of the argument 135 func Charset(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 136 //TODO: even the charset has one parameter but 137 //the result is utf8 always. So, we do not process the parameter 138 return adapter(vectors, proc, types.T_varchar.ToType(), 139 0, 140 evaluateMemoryCapacityForCharset, 141 doCharset) 142 } 143 144 func evaluateMemoryCapacityForCurrentRole(proc *process.Process, params ...interface{}) (int, error) { 145 return len(proc.SessionInfo.GetRole()), nil 146 } 147 148 func doCurrentRole(proc *process.Process, params ...interface{}) (interface{}, error) { 149 result := params[0].([]string) 150 role := proc.SessionInfo.GetRole() 151 if len(role) == 0 { 152 return nil, nil 153 } 154 result[0] = role 155 return result, nil 156 } 157 158 // Current_Role returns the current active roles 159 func CurrentRole(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 160 return adapter(vectors, proc, types.T_varchar.ToType(), 161 0, 162 evaluateMemoryCapacityForCurrentRole, 163 doCurrentRole) 164 } 165 166 func evaluateMemoryCapacityForFoundRows(proc *process.Process, params ...interface{}) (int, error) { 167 return 8, nil 168 } 169 170 func doFoundRows(proc *process.Process, params ...interface{}) (interface{}, error) { 171 result := params[0].([]uint64) 172 result[0] = 0 173 return result, nil 174 } 175 176 // For a SELECT with a LIMIT clause, the number of rows that would be returned were there no LIMIT clause 177 func FoundRows(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 178 return adapter(vectors, proc, types.T_uint64.ToType(), 179 0, 180 evaluateMemoryCapacityForFoundRows, 181 doFoundRows) 182 } 183 184 // ICU library version 185 func ICULIBVersion(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 186 return adapter(vectors, proc, types.T_varchar.ToType(), 0, 187 func(proc *process.Process, params ...interface{}) (int, error) { 188 return 0, nil 189 }, 190 func(proc *process.Process, params ...interface{}) (interface{}, error) { 191 result := params[0].([]string) 192 result[0] = "" 193 return result, nil 194 }, 195 ) 196 } 197 198 // Value of the AUTOINCREMENT column for the last INSERT 199 func LastInsertID(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 200 return adapter(vectors, proc, types.T_uint64.ToType(), 0, 201 func(proc *process.Process, params ...interface{}) (int, error) { 202 return 0, nil 203 }, 204 func(proc *process.Process, params ...interface{}) (interface{}, error) { 205 result := params[0].([]uint64) 206 result[0] = proc.SessionInfo.LastInsertID 207 return result, nil 208 }, 209 ) 210 } 211 212 func LastQueryIDWithoutParam(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 213 return adapter(vectors, proc, types.T_varchar.ToType(), 0, 214 func(proc *process.Process, params ...interface{}) (int, error) { 215 return 0, nil 216 }, 217 func(proc *process.Process, params ...interface{}) (interface{}, error) { 218 cnt := int64(len(proc.SessionInfo.QueryId)) 219 if cnt == 0 { 220 return nil, nil 221 } 222 result := params[0].([]string) 223 // LAST_QUERY_ID(-1) returns the most recently-executed query (equivalent to LAST_QUERY_ID()). 224 idx, err := makeQueryIdIdx(-1, cnt, proc) 225 if err != nil { 226 return nil, err 227 } 228 result[0] = proc.SessionInfo.QueryId[idx] 229 return result, nil 230 }, 231 ) 232 } 233 234 func LastQueryID(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 235 return adapter(vectors, proc, types.T_varchar.ToType(), 0, 236 func(proc *process.Process, params ...interface{}) (int, error) { 237 return 0, nil 238 }, 239 func(proc *process.Process, params ...interface{}) (interface{}, error) { 240 cnt := int64(len(proc.SessionInfo.QueryId)) 241 if cnt == 0 { 242 return nil, nil 243 } 244 result := params[0].([]string) 245 loc := vector.MustTCols[int64](vectors[0])[0] 246 idx, err := makeQueryIdIdx(loc, cnt, proc) 247 if err != nil { 248 return nil, err 249 } 250 result[0] = proc.SessionInfo.QueryId[idx] 251 return result, nil 252 }, 253 ) 254 } 255 256 func makeQueryIdIdx(loc, cnt int64, proc *process.Process) (int, error) { 257 // https://docs.snowflake.com/en/sql-reference/functions/last_query_id.html 258 var idx int 259 if loc < 0 { 260 if loc < -cnt { 261 return 0, moerr.NewInvalidInput(proc.Ctx, "index out of range: %d", loc) 262 } 263 idx = int(loc + cnt) 264 } else { 265 if loc > cnt { 266 return 0, moerr.NewInvalidInput(proc.Ctx, "index out of range: %d", loc) 267 } 268 idx = int(loc) 269 } 270 return idx, nil 271 } 272 273 // RolesGraphml returns a GraphML document representing memory role subgraphs 274 func RolesGraphml(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 275 return adapter(vectors, proc, types.T_varchar.ToType(), 0, 276 func(proc *process.Process, params ...interface{}) (int, error) { 277 return 0, nil 278 }, 279 func(proc *process.Process, params ...interface{}) (interface{}, error) { 280 result := params[0].([]string) 281 result[0] = "" 282 return result, nil 283 }, 284 ) 285 } 286 287 // RowCount returns The number of rows updated 288 func RowCount(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 289 return adapter(vectors, proc, types.T_uint64.ToType(), 0, 290 func(proc *process.Process, params ...interface{}) (int, error) { 291 return 0, nil 292 }, 293 func(proc *process.Process, params ...interface{}) (interface{}, error) { 294 result := params[0].([]uint64) 295 result[0] = 0 296 return result, nil 297 }, 298 ) 299 } 300 301 // Return a string that indicates the MySQL server version 302 func Version(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 303 return adapter(vectors, proc, types.T_varchar.ToType(), 0, 304 func(proc *process.Process, params ...interface{}) (int, error) { 305 return len(proc.SessionInfo.GetVersion()), nil 306 }, 307 func(proc *process.Process, params ...interface{}) (interface{}, error) { 308 result := params[0].([]string) 309 result[0] = proc.SessionInfo.GetVersion() 310 return result, nil 311 }, 312 ) 313 } 314 315 // Collation returns the collation of the string argument 316 func Collation(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 317 return adapter(vectors, proc, types.T_varchar.ToType(), 0, 318 func(proc *process.Process, params ...interface{}) (int, error) { 319 return len(proc.SessionInfo.GetCollation()), nil 320 }, 321 func(proc *process.Process, params ...interface{}) (interface{}, error) { 322 result := params[0].([]string) 323 result[0] = proc.SessionInfo.GetCollation() 324 return result, nil 325 }, 326 ) 327 }