Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Vladishev <aleksander.vladishev@zabbix.com>2021-05-07 23:00:15 +0300
committerAlexander Vladishev <aleksander.vladishev@zabbix.com>2021-05-07 23:00:15 +0300
commit1bd328b6178e9817c294aa04f65da11979ecaaad (patch)
tree542a9fbc4375929320672a7c2889a55d1f21405e /include
parentaca053018cb622c056275ef22dc4ad7115203346 (diff)
parentcdc88e47265953fb1483e4abc8fed51e7a269dad (diff)
A.F.I..PS. [ZBXNEXT-6451,ZBXNEXT-6452,ZBXNEXT-6453] implemented new syntax for trigger expressions, calculated and aggregated checks
* commit 'cdc88e47265953fb1483e4abc8fed51e7a269dad': (692 commits) .......... [ZBXNEXT-6452] fixed trigger test data .D........ [ZBXNEXT-6451,ZBXNEXT-6452,ZBXNEXT-6453] added ChangeLog entries .......... [ZBXNEXT-6452] fixed trigger tests A.F....... [ZBXNEXT-6451,ZBXNEXT-6455] updated unit tests for CHistFunctionValidator A.F....... [ZBXNEXT-6451,ZBXNEXT-6455] added filter presence validation in history functions ..F....... [ZBXNEXT-6451,ZBXNEXT-6455] added unit tests for CExpressionValidator A.F....... [ZBXNEXT-6451,ZBXNEXT-6455] added resolving of macros in the filterong expression while testing calculated item A.F....... [ZBXNEXT-6451,ZBXNEXT-6455] added support of standalone user and lld macros in the filtering expressions ........S. [ZBXNEXT-6452] fixed item query filter expression validation A.F....... [ZBXNEXT-6451,ZBXNEXT-6455] fixed misleading messages (unknown function) in expressions, fixed coding style #2 A.F....... [ZBXNEXT-6451,ZBXNEXT-6455] fixed misleading messages (unknown function) in expressions, fixed coding style .......... [ZBXNEXT-6452] fixed makefile .......... [ZBXNEXT-6451,ZBXNEXT-6455] updated unit tests ..F....... [ZBXNEXT-6451,ZBXNEXT-6455] fixed coding style (strict types) A.F....... [ZBXNEXT-6451,ZBXNEXT-6455] updated aggregated function validation in expressions A.F....... [ZBXNEXT-6451,ZBXNEXT-6455] fixed undefined index notice while parsing filter in the query string A.F....... [ZBXNEXT-6451,ZBXNEXT-6455] removed useless options "lldmacros" .......... [ZBXNEXT-6451,ZBXNEXT-6455] updated unit tests .......... [ZBXNEXT-6451,ZBXNEXT-6455] updated unit tests A......... [ZBXNEXT-6451,ZBXNEXT-6455] added support of all value types for function find() ...
Diffstat (limited to 'include')
-rw-r--r--include/common.h69
-rw-r--r--include/db.h21
-rw-r--r--include/dbcache.h23
-rw-r--r--include/preproc.h1
-rw-r--r--include/zbxalgo.h1
-rw-r--r--include/zbxeval.h269
-rw-r--r--include/zbxhistory.h2
-rw-r--r--include/zbxserialize.h15
-rw-r--r--include/zbxserver.h59
-rw-r--r--include/zbxtrends.h4
-rw-r--r--include/zbxtypes.h2
-rw-r--r--include/zbxvariant.h85
12 files changed, 474 insertions, 77 deletions
diff --git a/include/common.h b/include/common.h
index 10c16b69228..e4a604db362 100644
--- a/include/common.h
+++ b/include/common.h
@@ -162,8 +162,8 @@ typedef enum
ITEM_TYPE_INTERNAL = 5,
/* ITEM_TYPE_SNMPv3,*/
ITEM_TYPE_ZABBIX_ACTIVE = 7,
- ITEM_TYPE_AGGREGATE,
- ITEM_TYPE_HTTPTEST,
+/* ITEM_TYPE_AGGREGATE, */
+ ITEM_TYPE_HTTPTEST = 9,
ITEM_TYPE_EXTERNAL,
ITEM_TYPE_DB_MONITOR,
ITEM_TYPE_IPMI,
@@ -1167,6 +1167,7 @@ void zbx_strncpy_alloc(char **str, size_t *alloc_len, size_t *offset, const char
void zbx_strcpy_alloc(char **str, size_t *alloc_len, size_t *offset, const char *src);
void zbx_chrcpy_alloc(char **str, size_t *alloc_len, size_t *offset, char c);
void zbx_str_memcpy_alloc(char **str, size_t *alloc_len, size_t *offset, const char *src, size_t n);
+void zbx_strquote_alloc(char **str, size_t *str_alloc, size_t *str_offset, const char *value_str);
void zbx_strsplit(const char *src, char delimiter, char **left, char **right);
@@ -1439,8 +1440,6 @@ int zbx_strcmp_natural(const char *s1, const char *s2);
#define ZBX_TOKEN_EXPRESSION_MACRO 0x00100
/* additional token flags */
-#define ZBX_TOKEN_TRIGGER 0x0004000
-#define ZBX_TOKEN_NUMERIC 0x0008000
#define ZBX_TOKEN_JSON 0x0010000
#define ZBX_TOKEN_XML 0x0020000
#define ZBX_TOKEN_REGEXP 0x0040000
@@ -1549,10 +1548,18 @@ zbx_token_t;
#define ZBX_TOKEN_SEARCH_BASIC 0x00
#define ZBX_TOKEN_SEARCH_REFERENCES 0x01
#define ZBX_TOKEN_SEARCH_EXPRESSION_MACRO 0x02
+#define ZBX_TOKEN_SEARCH_FUNCTIONID 0x04
typedef int zbx_token_search_t;
int zbx_token_find(const char *expression, int pos, zbx_token_t *token, zbx_token_search_t token_search);
+
+int zbx_token_parse_user_macro(const char *expression, const char *macro, zbx_token_t *token);
+int zbx_token_parse_macro(const char *expression, const char *macro, zbx_token_t *token);
+int zbx_token_parse_objectid(const char *expression, const char *macro, zbx_token_t *token);
+int zbx_token_parse_lld_macro(const char *expression, const char *macro, zbx_token_t *token);
+int zbx_token_parse_nested_macro(const char *expression, const char *macro, zbx_token_t *token);
+
int zbx_strmatch_condition(const char *value, const char *pattern, unsigned char op);
int zbx_expression_next_constant(const char *str, size_t pos, zbx_strloc_t *loc);
@@ -1615,52 +1622,6 @@ char *zbx_expression_extract_constant(const char *src, const zbx_strloc_t *loc);
zbx_log_value_t *zbx_log_value_dup(const zbx_log_value_t *src);
-typedef union
-{
- zbx_uint64_t ui64;
- double dbl;
-
- /* null terminated string */
- char *str;
-
- /* length prefixed (4 bytes) binary data */
- void *bin;
-}
-zbx_variant_data_t;
-
-typedef struct
-{
- unsigned char type;
- zbx_variant_data_t data;
-}
-zbx_variant_t;
-
-#define ZBX_VARIANT_NONE 0
-#define ZBX_VARIANT_STR 1
-#define ZBX_VARIANT_DBL 2
-#define ZBX_VARIANT_UI64 3
-#define ZBX_VARIANT_BIN 4
-
-void zbx_variant_clear(zbx_variant_t *value);
-void zbx_variant_set_none(zbx_variant_t *value);
-void zbx_variant_set_str(zbx_variant_t *value, char *text);
-void zbx_variant_set_dbl(zbx_variant_t *value, double value_dbl);
-void zbx_variant_set_ui64(zbx_variant_t *value, zbx_uint64_t value_ui64);
-void zbx_variant_set_bin(zbx_variant_t *value, void *value_bin);
-void zbx_variant_copy(zbx_variant_t *value, const zbx_variant_t *source);
-int zbx_variant_set_numeric(zbx_variant_t *value, const char *text);
-
-int zbx_variant_convert(zbx_variant_t *value, int type);
-const char *zbx_get_variant_type_desc(unsigned char type);
-const char *zbx_variant_value_desc(const zbx_variant_t *value);
-const char *zbx_variant_type_desc(const zbx_variant_t *value);
-
-int zbx_variant_compare(const zbx_variant_t *value1, const zbx_variant_t *value2);
-
-void *zbx_variant_data_bin_copy(const void *bin);
-void *zbx_variant_data_bin_create(const void *data, zbx_uint32_t size);
-zbx_uint32_t zbx_variant_data_bin_get(const void *bin, void **data);
-
int zbx_validate_value_dbl(double value, int dbl_precision);
void zbx_update_env(double time_now);
@@ -1675,8 +1636,6 @@ char *zbx_create_token(zbx_uint64_t seed);
#define ZBX_PROBLEM_SUPPRESSED_FALSE 0
#define ZBX_PROBLEM_SUPPRESSED_TRUE 1
-int zbx_variant_to_value_type(zbx_variant_t *value, unsigned char value_type, int dbl_precision, char **errmsg);
-
#if defined(_WINDOWS) || defined(__MINGW32__)
#define ZBX_PCRE_RECURSION_LIMIT 2000 /* assume ~1 MB stack and ~500 bytes per recursion */
#endif
@@ -1689,6 +1648,8 @@ int zbx_str_extract(const char *text, size_t len, char **value);
typedef enum
{
ZBX_TIME_UNIT_UNKNOWN,
+ ZBX_TIME_UNIT_SECOND,
+ ZBX_TIME_UNIT_MINUTE,
ZBX_TIME_UNIT_HOUR,
ZBX_TIME_UNIT_DAY,
ZBX_TIME_UNIT_WEEK,
@@ -1737,4 +1698,8 @@ int zbx_check_xml_memory(char *mem, int maxerrlen, char **errmsg);
int zbx_get_report_nextcheck(int now, unsigned char cycle, unsigned char weekdays, int start_time,
const char *tz);
+/* */
+char *zbx_substr(const char *src, size_t left, size_t right);
+char *zbx_substr_unquote(const char *src, size_t left, size_t right);
+
#endif
diff --git a/include/db.h b/include/db.h
index 5338cbc4a24..5a49bec9a06 100644
--- a/include/db.h
+++ b/include/db.h
@@ -24,6 +24,7 @@
#include "zbxalgo.h"
#include "zbxdb.h"
#include "dbschema.h"
+#include "zbxeval.h"
extern char *CONFIG_DBHOST;
extern char *CONFIG_DBNAME;
@@ -208,6 +209,7 @@ struct _DC_TRIGGER;
#define EVENT_NAME_LEN 2048
+#define FUNCTION_NAME_LEN 12
#define FUNCTION_PARAM_LEN 255
#define REPORT_ERROR_LEN 2048
@@ -310,6 +312,11 @@ typedef struct
}
DB_DSERVICE;
+#define ZBX_DB_TRIGGER_EVAL_NONE 0x0000
+#define ZBX_DB_TRIGGER_EVAL_EXPRESSION 0x0001
+#define ZBX_DB_TRIGGER_EVAL_EXPRESSION_USERMACRO 0x0002
+#define ZBX_DB_TRIGGER_EVAL_RECOVERY_EXPRESSION 0x0004
+
typedef struct
{
zbx_uint64_t triggerid;
@@ -326,6 +333,9 @@ typedef struct
unsigned char type;
unsigned char recovery_mode;
unsigned char correlation_mode;
+
+ /* temporary trigger cache for related data */
+ void *cache;
}
DB_TRIGGER;
@@ -789,7 +799,8 @@ void zbx_db_get_events_by_eventids(zbx_vector_uint64_t *eventids, zbx_vector_ptr
void zbx_db_free_event(DB_EVENT *event);
void zbx_db_get_eventid_r_eventid_pairs(zbx_vector_uint64_t *eventids, zbx_vector_uint64_pair_t *event_pairs,
zbx_vector_uint64_t *r_eventids);
-
+void zbx_db_trigger_get_expression(const DB_TRIGGER *trigger, char **expression);
+void zbx_db_trigger_get_recovery_expression(const DB_TRIGGER *trigger, char **expression);
void zbx_db_trigger_clean(DB_TRIGGER *trigger);
typedef struct
@@ -892,4 +903,12 @@ void zbx_load_lld_override_operations(const zbx_vector_uint64_t *overrideids, ch
zbx_vector_ptr_t *ops);
#define ZBX_TIMEZONE_DEFAULT_VALUE "default"
+
+void zbx_db_trigger_get_all_functionids(const DB_TRIGGER *trigger, zbx_vector_uint64_t *functionids);
+void zbx_db_trigger_get_functionids(const DB_TRIGGER *trigger, zbx_vector_uint64_t *functionids);
+int zbx_db_trigger_get_all_hostids(const DB_TRIGGER *trigger, const zbx_vector_uint64_t **hostids);
+int zbx_db_trigger_get_constant(const DB_TRIGGER *trigger, int index, char **out);
+int zbx_db_trigger_get_itemid(const DB_TRIGGER *trigger, int index, zbx_uint64_t *itemid);
+void zbx_db_trigger_get_itemids(const DB_TRIGGER *trigger, zbx_vector_uint64_t *itemids);
+
#endif
diff --git a/include/dbcache.h b/include/dbcache.h
index 6f252b4fd44..d5af39b9fe8 100644
--- a/include/dbcache.h
+++ b/include/dbcache.h
@@ -26,6 +26,7 @@
#include "zbxalgo.h"
#include "zbxjson.h"
#include "memalloc.h"
+#include "zbxeval.h"
#define ZBX_SYNC_DONE 0
#define ZBX_SYNC_MORE 1
@@ -193,6 +194,7 @@ typedef struct
char ssl_key_password_orig[ITEM_SSL_KEY_PASSWORD_LEN_MAX], *ssl_key_password;
char *script_params;
char *error;
+ unsigned char *formula_bin;
}
DC_ITEM;
@@ -229,9 +231,6 @@ typedef struct _DC_TRIGGER
{
zbx_uint64_t triggerid;
char *description;
- char *expression_orig;
- char *recovery_expression_orig;
- /* temporary values, allocated during processing and freed right after */
char *expression;
char *recovery_expression;
@@ -240,6 +239,8 @@ typedef struct _DC_TRIGGER
char *correlation_tag;
char *opdata;
char *event_name;
+ unsigned char *expression_bin;
+ unsigned char *recovery_expression_bin;
zbx_timespec_t timespec;
int lastchange;
unsigned char topoindex;
@@ -255,6 +256,9 @@ typedef struct _DC_TRIGGER
unsigned char flags;
zbx_vector_ptr_t tags;
+
+ zbx_eval_context_t *eval_ctx;
+ zbx_eval_context_t *eval_ctx_r;
}
DC_TRIGGER;
@@ -743,7 +747,6 @@ void DCget_autoregistration_psk(char *psk_identity_buf, size_t psk_identity_buf_
#define ZBX_MACRO_SECRET_MASK "******"
void DCget_user_macro(const zbx_uint64_t *hostids, int hostids_num, const char *macro, char **replace_to);
-char *DCexpression_expand_user_macros(const char *expression);
char *zbx_dc_expand_func_params_user_macros(zbx_uint64_t hostid, const char *params);
int DCinterface_activate(zbx_uint64_t interfaceid, const zbx_timespec_t *ts, zbx_agent_availability_t *in,
@@ -812,7 +815,7 @@ void zbx_dc_correlation_rules_free(zbx_correlation_rules_t *rules);
void zbx_dc_correlation_rules_get(zbx_correlation_rules_t *rules);
void zbx_dc_get_nested_hostgroupids(zbx_uint64_t *groupids, int groupids_num, zbx_vector_uint64_t *nested_groupids);
-void zbx_dc_get_nested_hostgroupids_by_names(zbx_vector_str_t *groups, zbx_vector_uint64_t *nested_groupids);
+void zbx_dc_get_hostids_by_group_name(const char *name, zbx_vector_uint64_t *hostids);
#define ZBX_HC_ITEM_STATUS_NORMAL 0
#define ZBX_HC_ITEM_STATUS_BUSY 1
@@ -967,6 +970,7 @@ int zbx_lld_macro_paths_compare(const void *d1, const void *d2);
void zbx_dc_get_item_tags(zbx_uint64_t itemid, zbx_vector_ptr_t *item_tags);
void zbx_dc_get_item_tags_by_functionids(const zbx_uint64_t *functionids, size_t functionids_num,
zbx_vector_ptr_t *item_tags);
+void zbx_dc_get_item_tags(zbx_uint64_t itemid, zbx_vector_ptr_t *item_tags);
unsigned char zbx_dc_set_macro_env(unsigned char env);
@@ -974,6 +978,9 @@ const char *zbx_dc_get_instanceid(void);
char *zbx_dc_expand_user_macros(const char *text, zbx_uint64_t hostid);
char *zbx_dc_expand_user_macros_in_func_params(const char *params, zbx_uint64_t hostid);
+int zbx_dc_expand_user_macros_len(const char *text, size_t text_len, zbx_uint64_t *hostids, int hostids_num,
+ char **value, char **error);
+
/* diagnostic data */
void zbx_hc_get_diag_stats(zbx_uint64_t *items_num, zbx_uint64_t *values_num);
@@ -984,10 +991,10 @@ typedef struct
{
zbx_uint64_t objectid;
zbx_uint64_t triggerid;
- zbx_function_type_t type;
+ zbx_uint32_t type;
zbx_time_unit_t trend_base;
unsigned char lock; /* 1 if the timer has locked trigger, 0 otherwise */
- int revision; /* function revision */
+ int revision; /* revision */
zbx_timespec_t eval_ts; /* the history time for which trigger must be recalculated */
zbx_timespec_t exec_ts; /* real time when the timer must be executed */
const char *parameter; /* function parameters (for trend functions) */
@@ -1008,4 +1015,6 @@ void zbx_get_host_interfaces_availability(zbx_uint64_t hostid, zbx_agent_availab
int zbx_hc_check_proxy(zbx_uint64_t proxyid);
+void zbx_dc_eval_expand_user_macros(zbx_eval_context_t *ctx);
+
#endif
diff --git a/include/preproc.h b/include/preproc.h
index b9cde38d2a0..81261fdacc9 100644
--- a/include/preproc.h
+++ b/include/preproc.h
@@ -23,6 +23,7 @@
#include "common.h"
#include "module.h"
#include "dbcache.h"
+#include "zbxvariant.h"
/* preprocessing step execution result */
typedef struct
diff --git a/include/zbxalgo.h b/include/zbxalgo.h
index a1c0b377de0..561038d17da 100644
--- a/include/zbxalgo.h
+++ b/include/zbxalgo.h
@@ -330,6 +330,7 @@ ZBX_PTR_VECTOR_DECL(str, char *)
ZBX_PTR_VECTOR_DECL(ptr, void *)
ZBX_VECTOR_DECL(ptr_pair, zbx_ptr_pair_t)
ZBX_VECTOR_DECL(uint64_pair, zbx_uint64_pair_t)
+ZBX_VECTOR_DECL(dbl, double)
/* this function is only for use with zbx_vector_XXX_clear_ext() */
/* and only if the vector does not contain nested allocations */
diff --git a/include/zbxeval.h b/include/zbxeval.h
new file mode 100644
index 00000000000..0a6a0c41b16
--- /dev/null
+++ b/include/zbxeval.h
@@ -0,0 +1,269 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2021 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+#ifndef ZABBIX_ZBXEVAL_H
+#define ZABBIX_ZBXEVAL_H
+
+#include "common.h"
+#include "zbxalgo.h"
+#include "zbxvariant.h"
+
+/*
+ * Token type flags (32 bits):
+ * | 6 bits | 4 bits | 22 bits |
+ * | token class | operator precedence | token type |
+ */
+#define ZBX_EVAL_CLASS_OPERAND (__UINT64_C(0x01) << 26)
+#define ZBX_EVAL_CLASS_OPERATOR1 (__UINT64_C(0x02) << 26)
+#define ZBX_EVAL_CLASS_OPERATOR2 (__UINT64_C(0x04) << 26)
+#define ZBX_EVAL_CLASS_FUNCTION (__UINT64_C(0x08) << 26)
+#define ZBX_EVAL_CLASS_SEPARATOR (__UINT64_C(0x10) << 26)
+#define ZBX_EVAL_CLASS_PROPERTY (__UINT64_C(0x20) << 26)
+#define ZBX_EVAL_CLASS_OPERATOR (ZBX_EVAL_CLASS_OPERATOR1 | ZBX_EVAL_CLASS_OPERATOR2)
+
+#define ZBX_EVAL_BEFORE_OPERAND (ZBX_EVAL_CLASS_OPERATOR | ZBX_EVAL_CLASS_SEPARATOR)
+#define ZBX_EVAL_BEFORE_OPERATOR (ZBX_EVAL_CLASS_OPERAND | ZBX_EVAL_CLASS_PROPERTY)
+
+#define ZBX_EVAL_OP_SET_PRECEDENCE(x) ((x) << 22)
+#define ZBX_EVAL_OP_PRIORITY ZBX_EVAL_OP_SET_PRECEDENCE(0xf)
+
+#define ZBX_EVAL_TOKEN_NOP (0)
+#define ZBX_EVAL_TOKEN_OP_ADD (1 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(4))
+#define ZBX_EVAL_TOKEN_OP_SUB (2 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(4))
+#define ZBX_EVAL_TOKEN_OP_MUL (3 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(3))
+#define ZBX_EVAL_TOKEN_OP_DIV (4 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(3))
+#define ZBX_EVAL_TOKEN_OP_MINUS (5 | ZBX_EVAL_CLASS_OPERATOR1 | ZBX_EVAL_OP_SET_PRECEDENCE(2))
+#define ZBX_EVAL_TOKEN_OP_EQ (6 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(7))
+#define ZBX_EVAL_TOKEN_OP_LT (7 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6))
+#define ZBX_EVAL_TOKEN_OP_GT (8 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6))
+#define ZBX_EVAL_TOKEN_OP_LE (9 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6))
+#define ZBX_EVAL_TOKEN_OP_GE (10 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(6))
+#define ZBX_EVAL_TOKEN_OP_NE (11 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(7))
+#define ZBX_EVAL_TOKEN_OP_AND (12 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(11))
+#define ZBX_EVAL_TOKEN_OP_OR (13 | ZBX_EVAL_CLASS_OPERATOR2 | ZBX_EVAL_OP_SET_PRECEDENCE(12))
+#define ZBX_EVAL_TOKEN_OP_NOT (14 | ZBX_EVAL_CLASS_OPERATOR1 | ZBX_EVAL_OP_SET_PRECEDENCE(2))
+#define ZBX_EVAL_TOKEN_VAR_NUM (15 | ZBX_EVAL_CLASS_OPERAND)
+#define ZBX_EVAL_TOKEN_VAR_STR (16 | ZBX_EVAL_CLASS_OPERAND)
+#define ZBX_EVAL_TOKEN_VAR_MACRO (17 | ZBX_EVAL_CLASS_OPERAND)
+#define ZBX_EVAL_TOKEN_VAR_USERMACRO (18 | ZBX_EVAL_CLASS_OPERAND)
+#define ZBX_EVAL_TOKEN_VAR_LLDMACRO (19 | ZBX_EVAL_CLASS_OPERAND)
+#define ZBX_EVAL_TOKEN_FUNCTIONID (20 | ZBX_EVAL_CLASS_OPERAND)
+#define ZBX_EVAL_TOKEN_FUNCTION (21 | ZBX_EVAL_CLASS_FUNCTION)
+#define ZBX_EVAL_TOKEN_HIST_FUNCTION (22 | ZBX_EVAL_CLASS_FUNCTION)
+#define ZBX_EVAL_TOKEN_GROUP_OPEN (23 | ZBX_EVAL_CLASS_SEPARATOR)
+#define ZBX_EVAL_TOKEN_GROUP_CLOSE (24 | ZBX_EVAL_CLASS_OPERAND)
+#define ZBX_EVAL_TOKEN_COMMA (25 | ZBX_EVAL_CLASS_SEPARATOR)
+#define ZBX_EVAL_TOKEN_ARG_QUERY (26 | ZBX_EVAL_CLASS_OPERAND)
+#define ZBX_EVAL_TOKEN_ARG_PERIOD (27 | ZBX_EVAL_CLASS_OPERAND)
+#define ZBX_EVAL_TOKEN_ARG_NULL (28 | ZBX_EVAL_CLASS_OPERAND)
+#define ZBX_EVAL_TOKEN_PROP_TAG (29 | ZBX_EVAL_CLASS_PROPERTY)
+#define ZBX_EVAL_TOKEN_PROP_GROUP (30 | ZBX_EVAL_CLASS_PROPERTY)
+#define ZBX_EVAL_TOKEN_EXCEPTION (31 | ZBX_EVAL_CLASS_FUNCTION)
+
+/* token parsing rules */
+
+#define ZBX_EVAL_PARSE_MACRO __UINT64_C(0x00000001)
+#define ZBX_EVAL_PARSE_USERMACRO __UINT64_C(0x00000002)
+#define ZBX_EVAL_PARSE_LLDMACRO __UINT64_C(0x00000004)
+#define ZBX_EVAL_PARSE_FUNCTIONID __UINT64_C(0x00000008)
+#define ZBX_EVAL_PARSE_ITEM_QUERY __UINT64_C(0x00000010)
+#define ZBX_EVAL_PARSE_CONST_INDEX __UINT64_C(0x00000020)
+#define ZBX_EVAL_PARSE_COMPOUND_CONST __UINT64_C(0x00000040)
+#define ZBX_EVAL_PARSE_MATH __UINT64_C(0x00000080) /* +, -, *, / */
+#define ZBX_EVAL_PARSE_COMPARE_EQ __UINT64_C(0x00000100) /* =, <> */
+#define ZBX_EVAL_PARSE_COMPARE_SORT __UINT64_C(0x00000200) /* <, <=, >, >= */
+#define ZBX_EVAL_PARSE_LOGIC __UINT64_C(0x00000400) /* or, and, not */
+#define ZBX_EVAL_PARSE_VAR_NUM __UINT64_C(0x00000800) /* number */
+#define ZBX_EVAL_PARSE_VAR_STR __UINT64_C(0x00001000) /* string */
+#define ZBX_EVAL_PARSE_GROUP __UINT64_C(0x00002000) /* (, ) */
+#define ZBX_EVAL_PARSE_FUNCTION_ARGS __UINT64_C(0x00004000)
+#define ZBX_EVAL_PARSE_FUNCTION_NAME __UINT64_C(0x00008000)
+#define ZBX_EVAL_PARSE_PROP_TAG __UINT64_C(0x00010000) /* 'tag' keyword in item query filter */
+#define ZBX_EVAL_PARSE_PROP_GROUP __UINT64_C(0x00020000) /* 'group' keyword in item query filter */
+
+#define ZBX_EVAL_PARSE_FUNCTION (ZBX_EVAL_PARSE_FUNCTION_NAME | ZBX_EVAL_PARSE_FUNCTION_ARGS |\
+ ZBX_EVAL_PARSE_GROUP)
+#define ZBX_EVAL_PARSE_COMPARE (ZBX_EVAL_PARSE_COMPARE_EQ | ZBX_EVAL_PARSE_COMPARE_SORT)
+#define ZBX_EVAL_PARSE_VAR (ZBX_EVAL_PARSE_VAR_NUM | ZBX_EVAL_PARSE_VAR_STR)
+#define ZBX_EVAL_PARSE_PROPERTY (ZBX_EVAL_PARSE_PROP_TAG | ZBX_EVAL_PARSE_PROP_GROUP)
+
+/* expression parsing rules */
+
+#define ZBX_EVAL_PARSE_TRIGGER_EXPRESSSION (ZBX_EVAL_PARSE_MACRO | ZBX_EVAL_PARSE_USERMACRO |\
+ ZBX_EVAL_PARSE_FUNCTIONID | ZBX_EVAL_PARSE_FUNCTION |\
+ ZBX_EVAL_PARSE_MATH | ZBX_EVAL_PARSE_COMPARE |\
+ ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_VAR)
+
+#define ZBX_EVAL_PARSE_CALC_EXPRESSSION (ZBX_EVAL_PARSE_MACRO | ZBX_EVAL_PARSE_USERMACRO |\
+ ZBX_EVAL_PARSE_ITEM_QUERY | ZBX_EVAL_PARSE_FUNCTION |\
+ ZBX_EVAL_PARSE_MATH | ZBX_EVAL_PARSE_COMPARE |\
+ ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_VAR |\
+ ZBX_EVAL_PARSE_COMPOUND_CONST)
+
+#define ZBX_EVAL_PARSE_QUERY_EXPRESSION (ZBX_EVAL_PARSE_USERMACRO | ZBX_EVAL_PARSE_COMPARE_EQ |\
+ ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_GROUP |\
+ ZBX_EVAL_PARSE_VAR_STR | ZBX_EVAL_PARSE_PROPERTY)
+
+#define ZBX_EVAL_PARSE_EXPRESSION_MACRO (ZBX_EVAL_PARSE_MACRO | ZBX_EVAL_PARSE_USERMACRO |\
+ ZBX_EVAL_PARSE_ITEM_QUERY | ZBX_EVAL_PARSE_FUNCTION |\
+ ZBX_EVAL_PARSE_MATH | ZBX_EVAL_PARSE_COMPARE |\
+ ZBX_EVAL_PARSE_LOGIC | ZBX_EVAL_PARSE_VAR |\
+ ZBX_EVAL_PARSE_COMPOUND_CONST)
+/* expression composition rules */
+
+#define ZBX_EVAL_COMPOSE_LLD __UINT64_C(0x01000000)
+#define ZBX_EVAL_COMPOSE_FUNCTIONID __UINT64_C(0x02000000)
+#define ZBX_EVAL_COMPOSE_QUOTE __UINT64_C(0x04000000)
+#define ZBX_EVAL_COMPOSE_MASK_ERROR __UINT64_C(0x08000000)
+
+/* expression evaluation rules */
+
+#define ZBX_EVAL_PROCESS_ERROR __UINT64_C(0x000100000000)
+
+/* composite rules */
+
+#define ZBX_EVAL_TRIGGER_EXPRESSION (ZBX_EVAL_PARSE_TRIGGER_EXPRESSSION | \
+ ZBX_EVAL_PARSE_CONST_INDEX | \
+ ZBX_EVAL_PROCESS_ERROR)
+
+#define ZBX_EVAL_TRIGGER_EXPRESSION_LLD (ZBX_EVAL_PARSE_TRIGGER_EXPRESSSION | \
+ ZBX_EVAL_PARSE_LLDMACRO | \
+ ZBX_EVAL_COMPOSE_LLD | \
+ ZBX_EVAL_COMPOSE_FUNCTIONID)
+
+#define ZBX_EVAL_CALC_EXPRESSION_LLD (ZBX_EVAL_PARSE_CALC_EXPRESSSION | \
+ ZBX_EVAL_PARSE_LLDMACRO | \
+ ZBX_EVAL_COMPOSE_LLD)
+
+#define ZBX_EVAL_EXPRESSION_MACRO_LLD (ZBX_EVAL_PARSE_EXPRESSION_MACRO | \
+ ZBX_EVAL_PARSE_LLDMACRO | \
+ ZBX_EVAL_COMPOSE_LLD)
+
+#define ZBX_EVAL_QUERY_EXPRESSION_LLD (ZBX_EVAL_PARSE_QUERY_EXPRESSION | \
+ ZBX_EVAL_PARSE_LLDMACRO | \
+ ZBX_EVAL_COMPOSE_LLD)
+
+typedef zbx_uint32_t zbx_token_type_t;
+
+/******************************************************************************
+ * *
+ * Typedef: zbx_eval_function_cb_t *
+ * *
+ * Purpose: define callback function to calculate custom functions *
+ * *
+ * Parameters: name - [IN] the function name (not zero terminated) *
+ * len - [IN] the function name length *
+ * args_num - [IN] the number of function arguments *
+ * args - [IN] an array of the function arguments. *
+ * data - [IN] the caller data used for function evaluation *
+ * ts - [IN] the function execution time *
+ * value - [OUT] the function return value *
+ * error - [OUT] the error message if function failed *
+ * *
+ * Return value: SUCCEED - the function was executed successfully *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+typedef int (*zbx_eval_function_cb_t)(const char *name, size_t len, int args_num, const zbx_variant_t *args,
+ void *data, const zbx_timespec_t *ts, zbx_variant_t *value, char **error);
+
+typedef struct
+{
+ zbx_token_type_t type;
+ zbx_uint32_t opt;
+ zbx_strloc_t loc;
+ zbx_variant_t value;
+}
+zbx_eval_token_t;
+
+ZBX_VECTOR_DECL(eval_token, zbx_eval_token_t)
+
+typedef struct
+{
+ const char *expression;
+ zbx_token_type_t last_token_type;
+ zbx_uint32_t const_index;
+ zbx_uint32_t functionid_index;
+ zbx_uint64_t rules;
+ zbx_timespec_t ts;
+ zbx_vector_eval_token_t stack;
+ zbx_vector_eval_token_t ops;
+ zbx_eval_function_cb_t common_func_cb;
+ zbx_eval_function_cb_t history_func_cb;
+ void *data_cb;
+}
+zbx_eval_context_t;
+
+typedef int (*zbx_macro_resolve_func_t)(const char *str, size_t length, zbx_uint64_t *hostids,
+ int hostids_num, char **value, char **error);
+
+int zbx_eval_parse_expression(zbx_eval_context_t *ctx, const char *expression, zbx_uint64_t rules, char **error);
+void zbx_eval_init(zbx_eval_context_t *ctx);
+void zbx_eval_clear(zbx_eval_context_t *ctx);
+int zbx_eval_status(const zbx_eval_context_t *ctx);
+size_t zbx_eval_serialize(const zbx_eval_context_t *ctx, zbx_mem_malloc_func_t malloc_func, unsigned char **data);
+void zbx_eval_deserialize(zbx_eval_context_t *ctx, const char *expression, zbx_uint64_t rules,
+ const unsigned char *data);
+void zbx_eval_compose_expression(const zbx_eval_context_t *ctx, char **expression);
+int zbx_eval_execute(zbx_eval_context_t *ctx, const zbx_timespec_t *ts, zbx_variant_t *value, char **error);
+int zbx_eval_execute_ext(zbx_eval_context_t *ctx, const zbx_timespec_t *ts, zbx_eval_function_cb_t common_func_cb,
+ zbx_eval_function_cb_t history_func_cb, void *data, zbx_variant_t *value, char **error);
+void zbx_eval_get_functionids(zbx_eval_context_t *ctx, zbx_vector_uint64_t *functionids);
+void zbx_eval_get_functionids_ordered(zbx_eval_context_t *ctx, zbx_vector_uint64_t *functionids);
+int zbx_eval_expand_user_macros(const zbx_eval_context_t *ctx, zbx_uint64_t *hostids, int hostids_num,
+ zbx_macro_resolve_func_t resolver_cb, char **error);
+void zbx_eval_set_exception(zbx_eval_context_t *ctx, char *message);
+
+#define ZBX_EVAL_EXTRACT_FUNCTIONID 0x0001
+#define ZBX_EVAL_EXTRACT_VAR_STR 0x0002
+#define ZBX_EVAL_EXTRACT_VAR_MACRO 0x0004
+
+#define ZBX_EVAL_EXCTRACT_ALL (ZBX_EVAL_EXTRACT_FUNCTIONID | ZBX_EVAL_EXTRACT_VAR_STR | ZBX_EVAL_EXTRACT_VAR_MACRO)
+
+zbx_eval_context_t *zbx_eval_deserialize_dyn(const unsigned char *data, const char *expression,
+ zbx_uint64_t mask);
+int zbx_eval_check_timer_functions(const zbx_eval_context_t *ctx);
+void zbx_get_serialized_expression_functionids(const char *expression, const unsigned char *data,
+ zbx_vector_uint64_t *functionids);
+void zbx_eval_get_constant(const zbx_eval_context_t *ctx, int index, char **value);
+void zbx_eval_replace_functionid(zbx_eval_context_t *ctx, zbx_uint64_t old_functionid, zbx_uint64_t new_functionid);
+int zbx_eval_validate_replaced_functionids(zbx_eval_context_t *ctx, char **error);
+void zbx_eval_copy(zbx_eval_context_t *dst, const zbx_eval_context_t *src, const char *expression);
+
+char *zbx_eval_format_function_error(const char *function, const char *host, const char *key,
+ const char *parameter, const char *error);
+
+void zbx_eval_extract_item_refs(zbx_eval_context_t *ctx, zbx_vector_str_t *refs);
+
+
+typedef struct
+{
+ char *host;
+ char *key;
+ char *filter;
+}
+zbx_item_query_t;
+
+size_t zbx_eval_parse_query(const char *str, size_t len, zbx_item_query_t *query);
+void zbx_eval_clear_query(zbx_item_query_t *query);
+
+void zbx_eval_prepare_filter(zbx_eval_context_t *ctx);
+int zbx_eval_get_group_filter(zbx_eval_context_t *ctx, zbx_vector_str_t *groups, char **filter, char **error);
+
+#endif
diff --git a/include/zbxhistory.h b/include/zbxhistory.h
index fb497d6378d..e02bee7568a 100644
--- a/include/zbxhistory.h
+++ b/include/zbxhistory.h
@@ -20,6 +20,7 @@
#ifndef ZABBIX_ZBXHISTORY_H
#define ZABBIX_ZBXHISTORY_H
+#include "zbxvariant.h"
#include "zbxjson.h"
/* the item history value */
@@ -42,6 +43,7 @@ int zbx_history_record_compare_desc_func(const zbx_history_record_t *d1, const z
void zbx_history_value2str(char *buffer, size_t size, const history_value_t *value, int value_type);
char *zbx_history_value2str_dyn(const history_value_t *value, int value_type);
void zbx_history_value_print(char *buffer, size_t size, const history_value_t *value, int value_type);
+void zbx_history_value2variant(const history_value_t *value, unsigned char value_type, zbx_variant_t *var);
/* In most cases zbx_history_record_vector_destroy() function should be used to free the */
/* value vector filled by zbx_vc_get_value* functions. This define simply better */
diff --git a/include/zbxserialize.h b/include/zbxserialize.h
index 77790a312f6..b1ac0250da6 100644
--- a/include/zbxserialize.h
+++ b/include/zbxserialize.h
@@ -33,13 +33,14 @@
#define zbx_serialize_prepare_value(len, value) \
len += (zbx_uint32_t)sizeof(value)
-#define zbx_serialize_uint64(buffer, value) (memcpy(buffer, &value, sizeof(zbx_uint64_t)), sizeof(zbx_uint64_t))
+#define zbx_serialize_uint64(buffer, value) \
+ (memcpy(buffer, (const zbx_uint64_t *)&value, sizeof(zbx_uint64_t)), sizeof(zbx_uint64_t))
-#define zbx_serialize_int(buffer, value) (memcpy(buffer, (int *)&value, sizeof(int)), sizeof(int))
+#define zbx_serialize_int(buffer, value) (memcpy(buffer, (const int *)&value, sizeof(int)), sizeof(int))
-#define zbx_serialize_short(buffer, value) (memcpy(buffer, (short *)&value, sizeof(short)), sizeof(short))
+#define zbx_serialize_short(buffer, value) (memcpy(buffer, (const short *)&value, sizeof(short)), sizeof(short))
-#define zbx_serialize_double(buffer, value) (memcpy(buffer, (double *)&value, sizeof(double)), sizeof(double))
+#define zbx_serialize_double(buffer, value) (memcpy(buffer, (const double *)&value, sizeof(double)), sizeof(double))
#define zbx_serialize_char(buffer, value) (*buffer = (char)value, sizeof(char))
@@ -117,4 +118,10 @@
)
#endif
+
+/* complex serialization/deserialization functions */
+
+zbx_uint32_t zbx_serialize_uint31_compact(unsigned char *ptr, zbx_uint32_t value);
+zbx_uint32_t zbx_deserialize_uint31_compact(const unsigned char *ptr, zbx_uint32_t *value);
+
/* ZABBIX_SERIALIZE_H */
diff --git a/include/zbxserver.h b/include/zbxserver.h
index dd8ae3f6503..77e534feb41 100644
--- a/include/zbxserver.h
+++ b/include/zbxserver.h
@@ -24,6 +24,8 @@
#include "db.h"
#include "dbcache.h"
#include "zbxjson.h"
+#include "zbxvariant.h"
+#include "zbxeval.h"
#define MACRO_TYPE_MESSAGE_NORMAL 0x00000001
#define MACRO_TYPE_MESSAGE_RECOVERY 0x00000002
@@ -49,22 +51,22 @@
#define MACRO_TYPE_ALLOWED_HOSTS 0x00800000
#define MACRO_TYPE_ITEM_TAG 0x01000000
#define MACRO_TYPE_EVENT_NAME 0x02000000 /* event name in trigger configuration */
-#define MACRO_TYPE_EXPRESSION 0x04000000 /* macros in expression macro */
-#define MACRO_TYPE_SCRIPT_PARAMS_FIELD 0x08000000
-#define MACRO_TYPE_SCRIPT_NORMAL 0x10000000
-#define MACRO_TYPE_SCRIPT_RECOVERY 0x20000000
-#define MACRO_TYPE_REPORT 0x40000000
+#define MACRO_TYPE_SCRIPT_PARAMS_FIELD 0x04000000
+#define MACRO_TYPE_SCRIPT_NORMAL 0x08000000
+#define MACRO_TYPE_SCRIPT_RECOVERY 0x10000000
+#define MACRO_TYPE_REPORT 0x20000000
#define MACRO_EXPAND_NO 0
#define MACRO_EXPAND_YES 1
#define STR_CONTAINS_MACROS(str) (NULL != strchr(str, '{'))
-int get_N_functionid(const char *expression, int N_functionid, zbx_uint64_t *functionid, const char **end);
-void get_functionids(zbx_vector_uint64_t *functionids, const char *expression);
-
int evaluate_function(char **value, DC_ITEM *item, const char *function, const char *parameter,
const zbx_timespec_t *ts, char **error);
+int evaluate_function2(zbx_variant_t *value, DC_ITEM *item, const char *function, const char *parameter,
+ const zbx_timespec_t *ts, char **error);
+
+int zbx_is_trigger_function(const char *name, size_t len);
int substitute_simple_macros(const zbx_uint64_t *actionid, const DB_EVENT *event, const DB_EVENT *r_event,
const zbx_uint64_t *userid, const zbx_uint64_t *hostid, const DC_HOST *dc_host, const DC_ITEM *dc_item,
@@ -77,18 +79,49 @@ int substitute_simple_macros_unmasked(const zbx_uint64_t *actionid, const DB_EVE
char *error, int maxerrlen);
void evaluate_expressions(zbx_vector_ptr_t *triggers);
+void prepare_triggers(DC_TRIGGER **triggers, int triggers_num);
void zbx_format_value(char *value, size_t max_len, zbx_uint64_t valuemapid,
const char *units, unsigned char value_type);
void zbx_determine_items_in_expressions(zbx_vector_ptr_t *trigger_order, const zbx_uint64_t *itemids, int item_num);
-void get_trigger_expression_constant(const char *expression, const zbx_token_reference_t *reference,
- char **constant);
+#define ZBX_EXPRESSION_NORMAL 0
+#define ZBX_EXPRESSION_AGGREGATE 1
+
+typedef struct
+{
+ zbx_eval_context_t *ctx;
+ zbx_vector_ptr_t queries;
+ int mode;
+ int one_num;
+ int many_num;
+ zbx_uint64_t hostid;
+
+ /* cache to resolve one item queries */
+ zbx_host_key_t *hostkeys;
+ DC_ITEM *dcitems_hk;
+ int *errcodes_hk;
+
+ /* cache to resolve many item queries */
+ zbx_vector_ptr_t groups;
+ zbx_vector_ptr_t itemtags;
+ zbx_vector_ptr_t dcitem_refs;
+ DC_ITEM *dcitems;
+ int *errcodes;
+ int dcitems_num;
+}
+zbx_expression_eval_t;
+
+void zbx_expression_eval_init(zbx_expression_eval_t *eval, int mode, zbx_eval_context_t *ctx);
+void zbx_expression_eval_clear(zbx_expression_eval_t *eval);
+void zbx_expression_eval_resolve_item_hosts(zbx_expression_eval_t *eval, const DC_ITEM *item);
+void zbx_expression_eval_resolve_trigger_hosts(zbx_expression_eval_t *eval, const DB_TRIGGER *trigger);
+int zbx_expression_eval_execute(zbx_expression_eval_t *eval, const zbx_timespec_t *ts, zbx_variant_t *value,
+ char **error);
/* lld macro context */
#define ZBX_MACRO_ANY (ZBX_TOKEN_LLD_MACRO | ZBX_TOKEN_LLD_FUNC_MACRO | ZBX_TOKEN_USER_MACRO)
-#define ZBX_MACRO_NUMERIC (ZBX_MACRO_ANY | ZBX_TOKEN_NUMERIC)
#define ZBX_MACRO_JSON (ZBX_MACRO_ANY | ZBX_TOKEN_JSON)
#define ZBX_MACRO_XML (ZBX_MACRO_ANY | ZBX_TOKEN_XML)
#define ZBX_MACRO_SIMPLE (ZBX_MACRO_ANY | ZBX_TOKEN_SIMPLE_MACRO)
@@ -112,4 +145,8 @@ void zbx_substitute_item_name_macros(DC_ITEM *dc_item, const char *name, char **
int substitute_macros_in_json_pairs(char **data, const struct zbx_json_parse *jp_row,
const zbx_vector_ptr_t *lld_macro_paths, char *error, int maxerrlen);
int xml_xpath_check(const char *xpath, char *error, size_t errlen);
+
+int zbx_substitute_expression_lld_macros(char **data, zbx_uint64_t rules, const struct zbx_json_parse *jp_row,
+ const zbx_vector_ptr_t *lld_macro_paths, char **error);
+
#endif
diff --git a/include/zbxtrends.h b/include/zbxtrends.h
index a99b587af94..33ed4387d14 100644
--- a/include/zbxtrends.h
+++ b/include/zbxtrends.h
@@ -25,9 +25,9 @@
#include "dbcache.h"
int zbx_trends_parse_base(const char *params, zbx_time_unit_t *base, char **error);
+int zbx_parse_timeshift(time_t from, const char *timeshift, struct tm *tm, char **error);
-int zbx_trends_parse_range(time_t from, const char *period, const char *period_shift, int *start, int *end,
- char **error);
+int zbx_trends_parse_range(time_t from, const char *param, int *start, int *end, char **error);
int zbx_trends_parse_nextcheck(time_t from, const char *period_shift, time_t *nextcheck, char **error);
int zbx_trends_eval_avg(const char *table, zbx_uint64_t itemid, int start, int end, double *value, char **error);
diff --git a/include/zbxtypes.h b/include/zbxtypes.h
index 5182e11e675..0a101530c4e 100644
--- a/include/zbxtypes.h
+++ b/include/zbxtypes.h
@@ -218,4 +218,6 @@ zbx_uint128_t;
#define localtime_r(x, y) localtime_s(y, x)
#endif
+typedef struct zbx_variant zbx_variant_t;
+
#endif
diff --git a/include/zbxvariant.h b/include/zbxvariant.h
new file mode 100644
index 00000000000..bd1d15e2ad9
--- /dev/null
+++ b/include/zbxvariant.h
@@ -0,0 +1,85 @@
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+#ifndef ZABBIX_ZBXVARIANT_H
+#define ZABBIX_ZBXVARIANT_H
+
+#include "common.h"
+#include "zbxalgo.h"
+
+typedef union
+{
+ zbx_uint64_t ui64;
+ double dbl;
+
+ /* null terminated string */
+ char *str;
+
+ /* length prefixed (4 bytes) binary data */
+ void *bin;
+
+ zbx_vector_dbl_t *dbl_vector;
+
+ /* null terminated error message */
+ char *err;
+}
+zbx_variant_data_t;
+
+struct zbx_variant
+{
+ unsigned char type;
+ zbx_variant_data_t data;
+};
+
+#define ZBX_VARIANT_NONE 0
+#define ZBX_VARIANT_STR 1
+#define ZBX_VARIANT_DBL 2
+#define ZBX_VARIANT_UI64 3
+#define ZBX_VARIANT_BIN 4
+#define ZBX_VARIANT_DBL_VECTOR 5
+#define ZBX_VARIANT_ERR 6
+
+void zbx_variant_clear(zbx_variant_t *value);
+void zbx_variant_set_none(zbx_variant_t *value);
+void zbx_variant_set_str(zbx_variant_t *value, char *text);
+void zbx_variant_set_dbl(zbx_variant_t *value, double value_dbl);
+void zbx_variant_set_ui64(zbx_variant_t *value, zbx_uint64_t value_ui64);
+void zbx_variant_set_bin(zbx_variant_t *value, void *value_bin);
+void zbx_variant_set_error(zbx_variant_t *value, char *error);
+void zbx_variant_set_dbl_vector(zbx_variant_t *value, zbx_vector_dbl_t *dbl_vector);
+
+void zbx_variant_copy(zbx_variant_t *value, const zbx_variant_t *source);
+int zbx_variant_set_numeric(zbx_variant_t *value, const char *text);
+
+int zbx_variant_convert(zbx_variant_t *value, int type);
+const char *zbx_get_variant_type_desc(unsigned char type);
+const char *zbx_variant_value_desc(const zbx_variant_t *value);
+const char *zbx_variant_type_desc(const zbx_variant_t *value);
+
+int zbx_variant_compare(const zbx_variant_t *value1, const zbx_variant_t *value2);
+
+void *zbx_variant_data_bin_copy(const void *bin);
+void *zbx_variant_data_bin_create(const void *data, zbx_uint32_t size);
+zbx_uint32_t zbx_variant_data_bin_get(const void *bin, void **data);
+
+int zbx_variant_to_value_type(zbx_variant_t *value, unsigned char value_type, int dbl_precision, char **errmsg);
+
+ZBX_VECTOR_DECL(var, zbx_variant_t)
+
+#endif