Index: src/libs/zbxserver/expression.c
===================================================================
--- src/libs/zbxserver/expression.c	(revision 30793)
+++ src/libs/zbxserver/expression.c	(working copy)
@@ -26,6 +26,18 @@
 
 static DB_MACROS	*macros = NULL;
 
+typedef struct
+{
+	zbx_uint64_t		triggerid;
+	char			function[FUNCTION_FUNCTION_LEN_MAX];
+	char			parameter[FUNCTION_PARAMETER_LEN_MAX];
+	int			lastchange;
+	char			*value;
+	char			*error;
+	zbx_vector_uint64_t	functionids;
+}
+zbx_func_t;
+
 /******************************************************************************
  *                                                                            *
  * Function: trigger_get_N_functionid                                         *
@@ -771,6 +783,7 @@
 #define ZBX_REQUEST_ITEM_KEY		6
 #define ZBX_REQUEST_ITEM_KEY_ORIG	7
 #define ZBX_REQUEST_PROXY_NAME		8
+#define ZBX_REQUEST_FUNCTION_VALUE	9
 static int	DBget_trigger_value(DB_TRIGGER *trigger, char **replace_to, int N_functionid, int request)
 {
 	const char	*__function_name = "DBget_trigger_value";
@@ -786,7 +799,7 @@
 		goto fail;
 
 	result = DBselect(
-			"select h.hostid,h.host,h.useip,h.ip,h.dns,h.proxy_hostid,i.itemid,i.description,i.key_"
+			"select h.hostid,h.host,h.useip,h.ip,h.dns,h.proxy_hostid,i.itemid,i.description,i.key_,f.function,f.parameter"
 			" from hosts h,items i,functions f"
 			" where h.hostid=i.hostid"
 				" and i.itemid=f.itemid"
@@ -800,9 +813,14 @@
 		item.useip = atoi(row[2]);
 		item.host_ip = row[3];
 		item.host_dns = row[4];
+		ZBX_STR2UINT64(item.itemid, row[6]);
 		item.description = row[7];
 		item.key_orig = row[8];
 		item.key = NULL;
+		zbx_func_t *func = zbx_malloc(NULL, sizeof(zbx_func_t));
+		strscpy(func->function, row[9]);
+		strscpy(func->parameter, row[10]);
+		func->lastchange=time(NULL);
 
 		switch (request)
 		{
@@ -858,6 +876,43 @@
 				else
 					ret = DBget_host_name_by_hostid(proxy_hostid, replace_to);
 				break;
+			case ZBX_REQUEST_FUNCTION_VALUE:
+			{
+				zbx_uint64_t	*itemids = NULL;
+				char		*sql = NULL, value[MAX_BUFFER_LEN];
+				int		sql_alloc = 2 * ZBX_KIBIBYTE, sql_offset = 0, i;
+				sql = zbx_malloc(sql, sql_alloc);
+				itemids = zbx_malloc(itemids, sizeof(zbx_uint64_t));
+				itemids[0] = item.itemid;
+				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
+						49 + sizeof(ZBX_SQL_ITEM_FIELDS) + sizeof(ZBX_SQL_ITEM_TABLES),
+						"select %s,h.status"
+						" from %s"
+						" where i.hostid=h.hostid"
+							" and",
+						ZBX_SQL_ITEM_FIELDS, ZBX_SQL_ITEM_TABLES);
+				DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "i.itemid", itemids, 1);
+
+				zbx_free(itemids);
+
+				result = DBselect("%s", sql);
+
+				zbx_free(sql);
+
+				if (NULL != (row = DBfetch(result)))
+				{
+					DBget_item_from_db(&item, row);
+				}
+				if (SUCCEED != (ret = evaluate_function(value, &item, func->function, func->parameter, func->lastchange)))
+				{
+					*replace_to = zbx_dsprintf(*replace_to, "Evaluation failed for function: {%s:%s.%s(%s)}",
+							item.host_name, item.key, func->function, func->parameter);
+				}
+				else
+					*replace_to = zbx_strdup(*replace_to, value);
+				zbx_free(func);
+				break;
+			}
 		}
 	}
 	DBfree_result(result);
@@ -1634,6 +1689,7 @@
 #define MVAR_HOST_CONN			"{HOST.CONN}"
 #define MVAR_TIME			"{TIME}"
 #define MVAR_ITEM_LASTVALUE		"{ITEM.LASTVALUE}"
+#define MVAR_FUNCTION_LASTVALUE		"{FUNCTION.LASTVALUE}"
 #define MVAR_ITEM_VALUE			"{ITEM.VALUE}"
 #define MVAR_ITEM_ID			"{ITEM.ID}"
 #define MVAR_ITEM_NAME			"{ITEM.NAME}"
@@ -1695,6 +1751,7 @@
 				MVAR_TRIGGER_KEY,
 				MVAR_HOST_CONN, MVAR_HOST_DNS, MVAR_IPADDRESS,
 				MVAR_ITEM_LASTVALUE,
+				MVAR_FUNCTION_LASTVALUE,
 				MVAR_ITEM_VALUE,
 				MVAR_ITEM_LOG_DATE, MVAR_ITEM_LOG_TIME, MVAR_ITEM_LOG_AGE, MVAR_ITEM_LOG_SOURCE,
 				MVAR_ITEM_LOG_SEVERITY, MVAR_ITEM_LOG_NSEVERITY, MVAR_ITEM_LOG_EVENTID,
@@ -1926,6 +1983,9 @@
 							ZBX_REQUEST_HOST_CONN);
 				else if (0 == strcmp(m, MVAR_ITEM_LASTVALUE))
 					ret = DBget_item_lastvalue(&event->trigger, &replace_to, N_functionid);
+				else if (0 == strcmp(m, MVAR_FUNCTION_LASTVALUE)){
+					ret = DBget_trigger_value(&event->trigger, &replace_to, N_functionid, ZBX_REQUEST_FUNCTION_VALUE);
+				}
 				else if (0 == strcmp(m, MVAR_ITEM_VALUE))
 					ret = DBget_item_value(&event->trigger, &replace_to, N_functionid, event->clock);
 				else if (0 == strcmp(m, MVAR_ITEM_LOG_DATE))
@@ -2337,17 +2397,6 @@
 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s() functionids_num:%d", __function_name, functionids->values_num);
 }
 
-typedef struct
-{
-	zbx_uint64_t		triggerid;
-	char			function[FUNCTION_FUNCTION_LEN_MAX];
-	char			parameter[FUNCTION_PARAMETER_LEN_MAX];
-	int			lastchange;
-	char			*value;
-	char			*error;
-	zbx_vector_uint64_t	functionids;
-}
-zbx_func_t;
 
 typedef struct
 {
