MaxScale/query_classifier/qc_sqlite/builtin_functions.c
Johan Wikman 482fbe6400 qc: Implement qc_get_function_info for qc_mysqlembedded
MXS-1070

Now both qc_mysqlembedded and qc_sqlite return the same stuff
for the same statement, and both include also operators in
addition to pure functions. Whether that is the right approach,
is still subject to debate.

However, if we want to make it possible to disable e.g. the
use of concat as in "select concat(a) from t", where a is a string,
to prevent the bypassing of the masking filter, then conceptually
it should be possible to prevent "select a+0 from t", where a is an
int, as well.
2017-01-09 09:17:38 +02:00

410 lines
7.2 KiB
C

/*
* @licence@
*/
#include "builtin_functions.h"
#include <stdlib.h>
#include <string.h>
#include <maxscale/debug.h>
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",
"get_lock",
"inet6_aton",
"inet6_ntoa",
"inet_aton",
"inet_ntoa",
"is_free_lock",
"is_ipv4",
"is_ipv4_compat",
"is_ipv4_mapped",
"is_ipv6",
"is_used_lock",
"last_value",
"master_gtid_wait",
"master_pos_wait",
"name_const",
"release_lock",
"sleep",
"uuid",
"uuid_short",
"values",
/*
* 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",
/*
* 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]);
// 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);
unit.inited = true;
}
void finish_builtin_functions()
{
ss_dassert(unit.inited);
unit.inited = false;
}
bool is_builtin_readonly_function(const char* key)
{
ss_dassert(unit.inited);
char* value = bsearch(key, BUILTIN_FUNCTIONS, N_BUILTIN_FUNCTIONS, sizeof(char*), search_compare);
return value ? true : false;
}