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  }