github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/registry.go (about) 1 // Copyright 2020-2021 Dolthub, Inc. 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 function 16 17 import ( 18 "math" 19 20 "gopkg.in/src-d/go-errors.v1" 21 22 "github.com/dolthub/go-mysql-server/internal/similartext" 23 "github.com/dolthub/go-mysql-server/sql" 24 "github.com/dolthub/go-mysql-server/sql/expression/function/aggregation" 25 "github.com/dolthub/go-mysql-server/sql/expression/function/aggregation/window" 26 "github.com/dolthub/go-mysql-server/sql/expression/function/json" 27 "github.com/dolthub/go-mysql-server/sql/expression/function/spatial" 28 ) 29 30 // ErrFunctionAlreadyRegistered is thrown when a function is already registered 31 var ErrFunctionAlreadyRegistered = errors.NewKind("function '%s' is already registered") 32 33 // BuiltIns is the set of built-in functions any integrator can use 34 var BuiltIns = []sql.Function{ 35 // elt, find_in_set, insert, load_file, locate 36 sql.Function1{Name: "abs", Fn: NewAbsVal}, 37 sql.Function1{Name: "acos", Fn: NewAcos}, 38 sql.Function1{Name: "any_value", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewAnyValue(e) }}, 39 sql.Function1{Name: "ascii", Fn: NewAscii}, 40 sql.Function1{Name: "asin", Fn: NewAsin}, 41 sql.FunctionN{Name: "atan", Fn: NewAtan}, 42 sql.FunctionN{Name: "atan2", Fn: NewAtan}, 43 sql.Function1{Name: "avg", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewAvg(e) }}, 44 sql.Function1{Name: "bin", Fn: NewBin}, 45 sql.FunctionN{Name: "bin_to_uuid", Fn: NewBinToUUID}, 46 sql.Function1{Name: "bit_and", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewBitAnd(e) }}, 47 sql.Function1{Name: "bit_count", Fn: NewBitCount}, 48 sql.Function1{Name: "bit_length", Fn: NewBitlength}, 49 sql.Function1{Name: "bit_or", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewBitOr(e) }}, 50 sql.Function1{Name: "bit_xor", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewBitXor(e) }}, 51 sql.Function1{Name: "ceil", Fn: NewCeil}, 52 sql.Function1{Name: "ceiling", Fn: NewCeil}, 53 sql.FunctionN{Name: "char", Fn: NewChar}, 54 sql.Function1{Name: "char_length", Fn: NewCharLength}, 55 sql.Function1{Name: "character_length", Fn: NewCharLength}, 56 sql.FunctionN{Name: "coalesce", Fn: NewCoalesce}, 57 sql.Function1{Name: "coercibility", Fn: NewCoercibility}, 58 sql.Function1{Name: "collation", Fn: NewCollation}, 59 sql.FunctionN{Name: "concat", Fn: NewConcat}, 60 sql.FunctionN{Name: "concat_ws", Fn: NewConcatWithSeparator}, 61 sql.NewFunction0("connection_id", NewConnectionID), 62 sql.Function3{Name: "conv", Fn: NewConv}, 63 sql.Function1{Name: "cos", Fn: NewCos}, 64 sql.Function1{Name: "cot", Fn: NewCot}, 65 sql.Function3{Name: "convert_tz", Fn: NewConvertTz}, 66 sql.Function1{Name: "count", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewCount(e) }}, 67 sql.Function1{Name: "crc32", Fn: NewCrc32}, 68 sql.NewFunction0("curdate", NewCurrDate), 69 sql.NewFunction0("current_date", NewCurrentDate), 70 sql.FunctionN{Name: "current_time", Fn: NewCurrTime}, 71 sql.FunctionN{Name: "current_timestamp", Fn: NewNow}, 72 sql.NewFunction0("current_user", NewCurrentUser), 73 sql.FunctionN{Name: "curtime", Fn: NewCurrTime}, 74 sql.Function0{Name: "database", Fn: NewDatabase}, 75 sql.Function1{Name: "date", Fn: NewDate}, 76 sql.FunctionN{Name: "datetime", Fn: NewDatetime}, 77 sql.Function2{Name: "datediff", Fn: NewDateDiff}, 78 sql.FunctionN{Name: "date_add", Fn: NewDateAdd}, 79 sql.Function2{Name: "date_format", Fn: NewDateFormat}, 80 sql.FunctionN{Name: "date_sub", Fn: NewDateSub}, 81 sql.Function1{Name: "day", Fn: NewDay}, 82 sql.Function1{Name: "dayname", Fn: NewDayName}, 83 sql.Function1{Name: "dayofmonth", Fn: NewDay}, 84 sql.Function1{Name: "dayofweek", Fn: NewDayOfWeek}, 85 sql.Function1{Name: "dayofyear", Fn: NewDayOfYear}, 86 sql.Function1{Name: "degrees", Fn: NewDegrees}, 87 sql.FunctionN{Name: "elt", Fn: NewElt}, 88 sql.Function1{Name: "exp", Fn: NewExp}, 89 sql.Function2{Name: "extract", Fn: NewExtract}, 90 sql.FunctionN{Name: "field", Fn: NewField}, 91 sql.Function2{Name: "find_in_set", Fn: NewFindInSet}, 92 sql.Function1{Name: "first", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewFirst(e) }}, 93 sql.Function1{Name: "floor", Fn: NewFloor}, 94 sql.Function0{Name: "found_rows", Fn: NewFoundRows}, 95 sql.FunctionN{Name: "format", Fn: NewFormat}, 96 sql.Function1{Name: "from_base64", Fn: NewFromBase64}, 97 sql.Function1{Name: "from_unixtime", Fn: NewFromUnixtime}, 98 sql.FunctionN{Name: "greatest", Fn: NewGreatest}, 99 sql.Function0{Name: "group_concat", Fn: aggregation.NewEmptyGroupConcat}, 100 sql.Function1{Name: "hex", Fn: NewHex}, 101 sql.Function1{Name: "hour", Fn: NewHour}, 102 sql.Function3{Name: "if", Fn: NewIf}, 103 sql.Function2{Name: "ifnull", Fn: NewIfNull}, 104 sql.Function1{Name: "inet_aton", Fn: NewInetAton}, 105 sql.Function1{Name: "inet_ntoa", Fn: NewInetNtoa}, 106 sql.Function1{Name: "inet6_aton", Fn: NewInet6Aton}, 107 sql.Function1{Name: "inet6_ntoa", Fn: NewInet6Ntoa}, 108 sql.Function2{Name: "instr", Fn: NewInstr}, 109 sql.Function1{Name: "is_binary", Fn: NewIsBinary}, 110 sql.Function1{Name: "is_ipv4", Fn: NewIsIPv4}, 111 sql.Function1{Name: "is_ipv4_compat", Fn: NewIsIPv4Compat}, 112 sql.Function1{Name: "is_ipv4_mapped", Fn: NewIsIPv4Mapped}, 113 sql.Function1{Name: "is_ipv6", Fn: NewIsIPv6}, 114 sql.Function1{Name: "is_uuid", Fn: NewIsUUID}, 115 sql.Function1{Name: "isnull", Fn: NewIsNull}, 116 sql.FunctionN{Name: "json_array", Fn: json.NewJSONArray}, 117 sql.Function1{Name: "json_arrayagg", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewJsonArray(e) }}, 118 sql.Function2{Name: "json_objectagg", Fn: aggregation.NewJSONObjectAgg}, 119 sql.FunctionN{Name: "json_array_append", Fn: json.NewJSONArrayAppend}, 120 sql.FunctionN{Name: "json_array_insert", Fn: json.NewJSONArrayInsert}, 121 sql.FunctionN{Name: "json_contains", Fn: json.NewJSONContains}, 122 sql.FunctionN{Name: "json_contains_path", Fn: json.NewJSONContainsPath}, 123 sql.FunctionN{Name: "json_depth", Fn: json.NewJSONDepth}, 124 sql.FunctionN{Name: "json_extract", Fn: json.NewJSONExtract}, 125 sql.FunctionN{Name: "json_insert", Fn: json.NewJSONInsert}, 126 sql.FunctionN{Name: "json_keys", Fn: json.NewJSONKeys}, 127 sql.FunctionN{Name: "json_length", Fn: json.NewJsonLength}, 128 sql.FunctionN{Name: "json_merge_patch", Fn: json.NewJSONMergePatch}, 129 sql.FunctionN{Name: "json_merge_preserve", Fn: json.NewJSONMergePreserve}, 130 sql.FunctionN{Name: "json_object", Fn: json.NewJSONObject}, 131 sql.FunctionN{Name: "json_overlaps", Fn: json.NewJSONOverlaps}, 132 sql.FunctionN{Name: "json_pretty", Fn: json.NewJSONPretty}, 133 sql.FunctionN{Name: "json_quote", Fn: json.NewJSONQuote}, 134 sql.FunctionN{Name: "json_remove", Fn: json.NewJSONRemove}, 135 sql.FunctionN{Name: "json_replace", Fn: json.NewJSONReplace}, 136 sql.FunctionN{Name: "json_schema_valid", Fn: json.NewJSONSchemaValid}, 137 sql.FunctionN{Name: "json_schema_validation_report", Fn: json.NewJSONSchemaValidationReport}, 138 sql.FunctionN{Name: "json_search", Fn: json.NewJSONSearch}, 139 sql.FunctionN{Name: "json_set", Fn: json.NewJSONSet}, 140 sql.FunctionN{Name: "json_storage_free", Fn: json.NewJSONStorageFree}, 141 sql.FunctionN{Name: "json_storage_size", Fn: json.NewJSONStorageSize}, 142 sql.FunctionN{Name: "json_table", Fn: json.NewJSONTable}, 143 sql.FunctionN{Name: "json_type", Fn: json.NewJSONType}, 144 sql.Function1{Name: "json_unquote", Fn: json.NewJSONUnquote}, 145 sql.FunctionN{Name: "json_valid", Fn: json.NewJSONValid}, 146 sql.FunctionN{Name: "json_value", Fn: json.NewJsonValue}, 147 sql.FunctionN{Name: "lag", Fn: func(e ...sql.Expression) (sql.Expression, error) { return window.NewLag(e...) }}, 148 sql.Function1{Name: "last", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewLast(e) }}, 149 sql.FunctionN{Name: "last_insert_id", Fn: NewLastInsertId}, 150 sql.Function1{Name: "lcase", Fn: NewLower}, 151 sql.FunctionN{Name: "lead", Fn: func(e ...sql.Expression) (sql.Expression, error) { return window.NewLead(e...) }}, 152 sql.FunctionN{Name: "least", Fn: NewLeast}, 153 sql.Function2{Name: "left", Fn: NewLeft}, 154 sql.Function1{Name: "length", Fn: NewLength}, 155 sql.Function1{Name: "ln", Fn: NewLogBaseFunc(float64(math.E))}, 156 sql.Function1{Name: "load_file", Fn: NewLoadFile}, 157 sql.FunctionN{Name: "localtime", Fn: NewNow}, 158 sql.FunctionN{Name: "localtimestamp", Fn: NewNow}, 159 sql.FunctionN{Name: "locate", Fn: NewLocate}, 160 sql.FunctionN{Name: "log", Fn: NewLog}, 161 sql.Function1{Name: "log10", Fn: NewLogBaseFunc(float64(10))}, 162 sql.Function1{Name: "log2", Fn: NewLogBaseFunc(float64(2))}, 163 sql.Function1{Name: "lower", Fn: NewLower}, 164 sql.FunctionN{Name: "lpad", Fn: NewLeftPad}, 165 sql.Function1{Name: "ltrim", Fn: NewLeftTrim}, 166 sql.Function1{Name: "max", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewMax(e) }}, 167 sql.Function1{Name: "md5", Fn: NewMD5}, 168 sql.Function1{Name: "microsecond", Fn: NewMicrosecond}, 169 sql.FunctionN{Name: "mid", Fn: NewSubstring}, 170 sql.Function1{Name: "min", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewMin(e) }}, 171 sql.Function1{Name: "minute", Fn: NewMinute}, 172 sql.FunctionN{Name: "mod", Fn: NewMod}, 173 sql.Function1{Name: "month", Fn: NewMonth}, 174 sql.Function1{Name: "monthname", Fn: NewMonthName}, 175 sql.FunctionN{Name: "now", Fn: NewNow}, 176 sql.Function2{Name: "nullif", Fn: NewNullIf}, 177 sql.Function1{Name: "octet_length", Fn: NewLength}, 178 sql.Function1{Name: "ord", Fn: NewOrd}, 179 sql.Function0{Name: "pi", Fn: NewPi}, 180 sql.Function2{Name: "pow", Fn: NewPower}, 181 sql.Function2{Name: "power", Fn: NewPower}, 182 sql.Function1{Name: "quarter", Fn: NewQuarter}, 183 sql.Function1{Name: "radians", Fn: NewRadians}, 184 sql.FunctionN{Name: "rand", Fn: NewRand}, 185 sql.FunctionN{Name: "regexp_like", Fn: NewRegexpLike}, 186 sql.FunctionN{Name: "regexp_replace", Fn: NewRegexpReplace}, 187 sql.Function2{Name: "repeat", Fn: NewRepeat}, 188 sql.Function3{Name: "replace", Fn: NewReplace}, 189 sql.Function1{Name: "reverse", Fn: NewReverse}, 190 sql.Function2{Name: "right", Fn: NewRight}, 191 sql.FunctionN{Name: "round", Fn: NewRound}, 192 sql.Function0{Name: "row_count", Fn: NewRowCount}, 193 sql.Function0{Name: "row_number", Fn: window.NewRowNumber}, 194 sql.Function0{Name: "percent_rank", Fn: window.NewPercentRank}, 195 sql.Function0{Name: "rank", Fn: window.NewRank}, 196 sql.Function0{Name: "dense_rank", Fn: window.NewDenseRank}, 197 sql.Function1{Name: "first_value", Fn: window.NewFirstValue}, 198 sql.Function1{Name: "last_value", Fn: window.NewLastValue}, 199 sql.FunctionN{Name: "rpad", Fn: NewRightPad}, 200 sql.Function1{Name: "rtrim", Fn: NewRightTrim}, 201 sql.Function0{Name: "schema", Fn: NewDatabase}, 202 sql.Function1{Name: "second", Fn: NewSecond}, 203 sql.Function1{Name: "sha", Fn: NewSHA1}, 204 sql.Function1{Name: "sha1", Fn: NewSHA1}, 205 sql.Function2{Name: "sha2", Fn: NewSHA2}, 206 sql.Function1{Name: "sign", Fn: NewSign}, 207 sql.Function1{Name: "sin", Fn: NewSin}, 208 sql.Function1{Name: "sleep", Fn: NewSleep}, 209 sql.Function1{Name: "soundex", Fn: NewSoundex}, 210 sql.Function1{Name: "sqrt", Fn: NewSqrt}, 211 sql.FunctionN{Name: "str_to_date", Fn: NewStrToDate}, 212 sql.FunctionN{Name: "subdate", Fn: NewSubDate}, 213 sql.Function2{Name: "point", Fn: spatial.NewPoint}, 214 sql.FunctionN{Name: "linestring", Fn: spatial.NewLineString}, 215 sql.FunctionN{Name: "polygon", Fn: spatial.NewPolygon}, 216 sql.FunctionN{Name: "multipoint", Fn: spatial.NewMultiPoint}, 217 sql.FunctionN{Name: "multilinestring", Fn: spatial.NewMultiLineString}, 218 sql.FunctionN{Name: "multipolygon", Fn: spatial.NewMultiPolygon}, 219 sql.FunctionN{Name: "geometrycollection", Fn: spatial.NewGeomColl}, 220 sql.FunctionN{Name: "geomcollection", Fn: spatial.NewGeomColl}, 221 sql.Function1{Name: "space", Fn: NewSpace}, 222 sql.Function1{Name: "st_area", Fn: spatial.NewArea}, 223 sql.Function1{Name: "st_asbinary", Fn: spatial.NewAsWKB}, 224 sql.FunctionN{Name: "st_asgeojson", Fn: spatial.NewAsGeoJSON}, 225 sql.Function1{Name: "st_aswkb", Fn: spatial.NewAsWKB}, 226 sql.Function1{Name: "st_aswkt", Fn: spatial.NewAsWKT}, 227 sql.Function1{Name: "st_astext", Fn: spatial.NewAsWKT}, 228 sql.FunctionN{Name: "st_distance", Fn: spatial.NewDistance}, 229 sql.Function1{Name: "st_dimension", Fn: spatial.NewDimension}, 230 sql.Function2{Name: "st_equal", Fn: spatial.NewSTEquals}, 231 sql.Function1{Name: "st_endpoint", Fn: spatial.NewEndPoint}, 232 sql.FunctionN{Name: "st_geomcollfromtext", Fn: spatial.NewGeomCollFromText}, 233 sql.FunctionN{Name: "st_geomcollfromtxt", Fn: spatial.NewGeomCollFromText}, 234 sql.FunctionN{Name: "st_geomcollfromwkb", Fn: spatial.NewGeomCollFromWKB}, 235 sql.FunctionN{Name: "st_geometrycollectionfromwkb", Fn: spatial.NewGeomCollFromWKB}, 236 sql.FunctionN{Name: "st_geometrycollectionfromtext", Fn: spatial.NewGeomCollFromText}, 237 sql.FunctionN{Name: "st_geomfromgeojson", Fn: spatial.NewGeomFromGeoJSON}, 238 sql.FunctionN{Name: "st_geometryfromtext", Fn: spatial.NewGeomFromText}, 239 sql.FunctionN{Name: "st_geomfromtext", Fn: spatial.NewGeomFromText}, 240 sql.FunctionN{Name: "st_geometryfromwkb", Fn: spatial.NewGeomFromWKB}, 241 sql.FunctionN{Name: "st_geomfromwkb", Fn: spatial.NewGeomFromWKB}, 242 sql.Function1{Name: "st_isclosed", Fn: spatial.NewIsClosed}, 243 sql.Function2{Name: "st_intersects", Fn: spatial.NewIntersects}, 244 sql.FunctionN{Name: "st_length", Fn: spatial.NewSTLength}, 245 sql.FunctionN{Name: "st_longitude", Fn: spatial.NewLongitude}, 246 sql.FunctionN{Name: "st_linefromtext", Fn: spatial.NewLineFromText}, 247 sql.FunctionN{Name: "st_linefromwkb", Fn: spatial.NewLineFromWKB}, 248 sql.FunctionN{Name: "st_linestringfromtext", Fn: spatial.NewLineFromText}, 249 sql.FunctionN{Name: "st_linestringfromwkb", Fn: spatial.NewLineFromWKB}, 250 sql.FunctionN{Name: "st_mlinefromtext", Fn: spatial.NewMLineFromText}, 251 sql.FunctionN{Name: "st_mlinefromwkb", Fn: spatial.NewMLineFromWKB}, 252 sql.FunctionN{Name: "st_multilinestringfromtext", Fn: spatial.NewLineFromText}, 253 sql.FunctionN{Name: "st_multilinestringfromwkb", Fn: spatial.NewMLineFromWKB}, 254 sql.FunctionN{Name: "st_mpointfromtext", Fn: spatial.NewMPointFromText}, 255 sql.FunctionN{Name: "st_mpointfromwkb", Fn: spatial.NewMPointFromWKB}, 256 sql.FunctionN{Name: "st_multipointfromtext", Fn: spatial.NewMPointFromText}, 257 sql.FunctionN{Name: "st_multipointfromwkb", Fn: spatial.NewMPointFromWKB}, 258 sql.FunctionN{Name: "st_mpolyfromwkb", Fn: spatial.NewMPolyFromWKB}, 259 sql.FunctionN{Name: "st_mpolyfromtext", Fn: spatial.NewMPolyFromText}, 260 sql.FunctionN{Name: "st_multipolygonfromwkb", Fn: spatial.NewMPolyFromWKB}, 261 sql.FunctionN{Name: "st_multipolygonfromtext", Fn: spatial.NewMPolyFromText}, 262 sql.FunctionN{Name: "st_perimeter", Fn: spatial.NewPerimeter}, 263 sql.FunctionN{Name: "st_pointfromtext", Fn: spatial.NewPointFromText}, 264 sql.FunctionN{Name: "st_pointfromwkb", Fn: spatial.NewPointFromWKB}, 265 sql.FunctionN{Name: "st_polyfromtext", Fn: spatial.NewPolyFromText}, 266 sql.FunctionN{Name: "st_polyfromwkb", Fn: spatial.NewPolyFromWKB}, 267 sql.FunctionN{Name: "st_polygonfromtext", Fn: spatial.NewPolyFromText}, 268 sql.FunctionN{Name: "st_polygonfromwkb", Fn: spatial.NewPolyFromWKB}, 269 sql.FunctionN{Name: "st_srid", Fn: spatial.NewSRID}, 270 sql.Function1{Name: "st_startpoint", Fn: spatial.NewStartPoint}, 271 sql.Function1{Name: "st_swapxy", Fn: spatial.NewSwapXY}, 272 sql.Function2{Name: "st_within", Fn: spatial.NewWithin}, 273 sql.FunctionN{Name: "st_x", Fn: spatial.NewSTX}, 274 sql.FunctionN{Name: "st_y", Fn: spatial.NewSTY}, 275 sql.Function2{Name: "strcmp", Fn: NewStrCmp}, 276 sql.FunctionN{Name: "substr", Fn: NewSubstring}, 277 sql.FunctionN{Name: "substring", Fn: NewSubstring}, 278 sql.Function3{Name: "substring_index", Fn: NewSubstringIndex}, 279 sql.Function1{Name: "sum", Fn: func(e sql.Expression) sql.Expression { return aggregation.NewSum(e) }}, 280 sql.FunctionN{Name: "sysdate", Fn: NewSysdate}, 281 sql.Function1{Name: "tan", Fn: NewTan}, 282 sql.Function1{Name: "time", Fn: NewTime}, 283 sql.Function2{Name: "time_format", Fn: NewTimeFormat}, 284 sql.Function1{Name: "time_to_sec", Fn: NewTimeToSec}, 285 sql.Function2{Name: "timediff", Fn: NewTimeDiff}, 286 sql.FunctionN{Name: "timestamp", Fn: NewTimestamp}, 287 sql.Function3{Name: "timestampdiff", Fn: NewTimestampDiff}, 288 sql.Function1{Name: "to_base64", Fn: NewToBase64}, 289 sql.Function1{Name: "ucase", Fn: NewUpper}, 290 sql.Function1{Name: "unhex", Fn: NewUnhex}, 291 sql.FunctionN{Name: "unix_timestamp", Fn: NewUnixTimestamp}, 292 sql.Function1{Name: "upper", Fn: NewUpper}, 293 sql.NewFunction0("user", NewUser), 294 sql.FunctionN{Name: "utc_timestamp", Fn: NewUTCTimestamp}, 295 sql.Function0{Name: "uuid", Fn: NewUUIDFunc}, 296 sql.FunctionN{Name: "uuid_to_bin", Fn: NewUUIDToBin}, 297 sql.FunctionN{Name: "week", Fn: NewWeek}, 298 sql.Function1{Name: "values", Fn: NewValues}, 299 sql.Function1{Name: "weekday", Fn: NewWeekday}, 300 sql.Function1{Name: "weekofyear", Fn: NewWeekOfYear}, 301 sql.Function1{Name: "year", Fn: NewYear}, 302 sql.FunctionN{Name: "yearweek", Fn: NewYearWeek}, 303 } 304 305 func GetLockingFuncs(ls *sql.LockSubsystem) []sql.Function { 306 return []sql.Function{ 307 sql.Function2{Name: "get_lock", Fn: CreateNewGetLock(ls)}, 308 sql.Function1{Name: "is_free_lock", Fn: NewIsFreeLock(ls)}, 309 sql.Function1{Name: "is_used_lock", Fn: NewIsUsedLock(ls)}, 310 sql.NewFunction0("release_all_locks", NewReleaseAllLocks(ls)), 311 sql.Function1{Name: "release_lock", Fn: NewReleaseLock(ls)}, 312 } 313 } 314 315 // Registry is used to register functions 316 type Registry map[string]sql.Function 317 318 var _ sql.FunctionProvider = Registry{} 319 320 // NewRegistry creates a new Registry. 321 func NewRegistry() Registry { 322 fr := make(Registry) 323 fr.mustRegister(BuiltIns...) 324 return fr 325 } 326 327 // Register registers functions, returning an error if it's already registered 328 func (r Registry) Register(fn ...sql.Function) error { 329 for _, f := range fn { 330 if _, ok := r[f.FunctionName()]; ok { 331 return ErrFunctionAlreadyRegistered.New(f.FunctionName()) 332 } 333 r[f.FunctionName()] = f 334 } 335 return nil 336 } 337 338 // Function implements sql.FunctionProvider 339 func (r Registry) Function(ctx *sql.Context, name string) (sql.Function, error) { 340 if fn, ok := r[name]; ok { 341 return fn, nil 342 } 343 similar := similartext.FindFromMap(r, name) 344 return nil, sql.ErrFunctionNotFound.New(name + similar) 345 } 346 347 func (r Registry) mustRegister(fn ...sql.Function) { 348 if err := r.Register(fn...); err != nil { 349 panic(err) 350 } 351 }