/* * Copyright (c) 2016 MariaDB Corporation Ab * * Use of this software is governed by the Business Source License included * in the LICENSE.TXT file and at www.mariadb.com/bsl11. * * Change Date: 2020-01-01 * * On the date above, in accordance with the Business Source License, use * of this software will be governed by version 2 or later of the General * Public License. */ #include "builtin_functions.h" #include #include #include static struct { bool inited; } unit = { false }; // The functions have been taken from: // https://mariadb.com/kb/en/mariadb/functions-and-operators/ static const char* BUILTIN_FUNCTIONS[] = { /* * Bit Functions and Operators * https://mariadb.com/kb/en/mariadb/bit-functions-and-operators */ "bit_count", /* * Control Flow Functions * https://mariadb.com/kb/en/mariadb/control-flow-functions/ */ "if", "ifnull", "nullif", /* * Date and Time Functions * https://mariadb.com/kb/en/mariadb/date-and-time-functions/ */ "adddate", "addtime", "convert_tz", "curdate", "current_date", "current_time", "current_timestamp", "curtime", "date", "datediff", "date_add", "date_format", "date_sub", "day", "dayname", "dayofmonth", "dayofweek", "dayofyear", "extract", "from_days", "from_unixtime", "get_format", "hour", "last_day", "localtime", "localtimestamp", "makedate", "maketime", "microsecond", "minute", "month", "monthname", "now", "period_add", "period_diff", "quarter", "second", "sec_to_time", "str_to_date", "subdate", "subtime", "sysdate", "time", "timediff" "timestamp", "timestampadd", "timestampdiff", "time_format", "time_to_sec", "to_days", "to_seconds", "unix_timestamp", "utc_date", "utc_time", "week", "weekday", "weekofyear", "year", "yearweek", /* * Columns Functions * https://mariadb.com/kb/en/mariadb/dynamic-columns-functions/ */ "column_check", "column_exists", "column_get", "column_json", "column_list", /* * Encryption, Hashing and Compression Functions * https://mariadb.com/kb/en/mariadb/encryption-hashing-and-compression-functions/ */ "aes_decrypt", "aes_encrypt", "compress", "decode", "des_decrypt", "des_encrypt", "encode", "encrypt", "md5", "old_password", "password", "sha1", "sha2", "uncompress", "uncompressed_length", /* * Comparison Operators * https://mariadb.com/kb/en/mariadb/comparison-operators/ */ "coalesce", "greatest", "interval", "isnull", "least", /* * Functions and Modifiers for use with GROUP BY * https://mariadb.com/kb/en/mariadb/functions-and-modifiers-for-use-with-group-by/ */ "avg", "bit_and", "bit_or", "bit_xor", "count", "group_concat", "max", "min", "std", "stddev", "stddev_pop", "stddev_samp", "sum", "variance", "var_pop", "var_samp", /* * Geographic Functions * https://mariadb.com/kb/en/mariadb/geographic-functions/ */ // Geometry Constructors // https://mariadb.com/kb/en/mariadb/geometry-constructors/ "geometrycollection", "linestring", "multilinestring", "multipoint", "point", "polygon", "st_buffer", "st_convexhull", "st_intersection", "st_pointonsurface", "st_symdifference", "std_union", // Geometry Properties // https://mariadb.com/kb/en/mariadb/geometry-properties/ // TODO // Geometry Relations // TODO // LineString Properties // TODO // MBR // TODO // Point Propertoes // TODO // Polygon Properties // TODO // WKB // TODO // WKT // https://mariadb.com/kb/en/mariadb/wkt/ "MLineFromText", "MPointFromText", "MPolyFromText", "ST_AsText", "ST_ASWKT", "ST_GeomCollFromText", "ST_GeometryFromText", "ST_LineFromText", "ST_PointFromText", "ST_PolyFromText", // Deprecated "geomfromtext", /* * Information Functions * https://mariadb.com/kb/en/mariadb/information-functions/ */ "benchmark", "binlog_gtid_pos", "charset", "coercibility", "collation", "connection_id", "current_role", "current_user", "database", "decode_histogram", "found_rows", "last_insert_id", "row_count", "schema", "session_user", "system_user", "user", "version", /* * Miscellanesous Functions * https://mariadb.com/kb/en/mariadb/miscellaneous-functions/ */ "default", "inet6_aton", "inet6_ntoa", "inet_aton", "inet_ntoa", "is_ipv4", "is_ipv4_compat", "is_ipv4_mapped", "is_ipv6", "last_value", "master_gtid_wait", "master_pos_wait", "name_const", "sleep", "uuid", "uuid_short", "values", /** * Although conceptually non-updating, we classify these as WRITE as * that will force them to be sent to _master_ outside transactions. * * "get_lock", * "is_free_lock", * "is_used_lock", * "release_lock", */ /* * Numeric Functions * https://mariadb.com/kb/en/mariadb/numeric-functions/ */ "abs", "acos", "asin", "atan", "atan2", "ceil", "ceiling", "conv", "cos", "cot", "crc32", "degrees", "div", "exp", "floor", "greatest", "least", "ln", "log", "log10", "log2", "mod", "oct", "pi", "pow", "power", "radians", "rand", "round", "sign", "sin", "sqrt", "tan", "truncate", /* * String Functions * https://mariadb.com/kb/en/mariadb/string-functions/ */ "ascii", "bin", "bit_length", "cast", "char", "character_length", "char_length", "concat", "concat_ws", "convert", "elt", "export_set", "extractvalue", "field", "find_in_set", "format", "hex", "insert", "instr", "lcase", "left", "length", "like", "load_file", "locate", "lower", "lpad", "ltrim", "make_set", "mid", "octet_length", "ord", "position", "quote", "repeat", "replace", "reverse", "right", "rpad", "rtrim", "soundex", "space", "strcmp", "substr", "substring", "substring_index", "trim", "ucase", "unhex", "updatexml", "upper", "from_base64", "to_base64", "weight_string", /* * Regex functions * https://mariadb.com/kb/en/mariadb/regular-expressions-functions/ */ "regexp", "regexp_instr", "regexp_replace", "regexp_substr", "rlike", /* * http://dev.mysql.com/doc/refman/5.7/en/row-subqueries.html */ "row" }; const size_t N_BUILTIN_FUNCTIONS = sizeof(BUILTIN_FUNCTIONS) / sizeof(BUILTIN_FUNCTIONS[0]); static const char* BUILTIN_10_2_3_FUNCTIONS[] = { // // JSON functions: https://mariadb.com/kb/en/mariadb/json-functions // "json_array", "json_array_append", "json_array_insert", "json_compact", "json_contains", "json_contains_path", "json_depth", "json_detailed", "json_exists", "json_extract", "json_insert", "json_keys", "json_length", "json_loose", "json_merge", "json_object", "json_query", "json_quote", "json_remove" "json_replace", "json_search", "json_set", "json_type", "json_unquote", "json_valid", "json_value", // // Window functions: https://mariadb.com/kb/en/mariadb/window-functions/ // "cume_dist", "dense_rank", "first_value", "lag", "last_value", "lead", "nth_value", "ntile", "percent_rank", "rank", "row_number", }; const size_t N_BUILTIN_10_2_3_FUNCTIONS = sizeof(BUILTIN_10_2_3_FUNCTIONS) / sizeof(BUILTIN_10_2_3_FUNCTIONS[0]); static const char* ORACLE_FUNCTIONS[] = { "nvl", "nvl2" }; const size_t N_ORACLE_FUNCTIONS = sizeof(ORACLE_FUNCTIONS) / sizeof(ORACLE_FUNCTIONS[0]); // NOTE: sort_compare and search_compare are not identical, so don't // NOTE: optimize either of them away. static int sort_compare(const void* key, const void* value) { return strcasecmp(*(const char**) key, *(const char**) value); } static int search_compare(const void* key, const void* value) { return strcasecmp((const char*) key, *(const char**) value); } // // API // void init_builtin_functions() { ss_dassert(!unit.inited); qsort(BUILTIN_FUNCTIONS, N_BUILTIN_FUNCTIONS, sizeof(char*), sort_compare); qsort(BUILTIN_10_2_3_FUNCTIONS, N_BUILTIN_10_2_3_FUNCTIONS, sizeof(char*), sort_compare); qsort(ORACLE_FUNCTIONS, N_ORACLE_FUNCTIONS, sizeof(char*), sort_compare); unit.inited = true; } void finish_builtin_functions() { ss_dassert(unit.inited); unit.inited = false; } bool is_builtin_readonly_function(const char* key, uint32_t major, uint32_t minor, uint32_t patch, bool check_oracle) { ss_dassert(unit.inited); char* value = bsearch(key, BUILTIN_FUNCTIONS, N_BUILTIN_FUNCTIONS, sizeof(char*), search_compare); if (!value) { if ((major > 10) || ((major == 10) && (minor > 2)) || ((major == 10) && (minor == 2) && (patch >= 3))) { value = bsearch(key, BUILTIN_10_2_3_FUNCTIONS, N_BUILTIN_10_2_3_FUNCTIONS, sizeof(char*), search_compare); } } if (!value && check_oracle) { value = bsearch(key, ORACLE_FUNCTIONS, N_ORACLE_FUNCTIONS, sizeof(char*), search_compare); } return value ? true : false; }