/*
** Copyright (C) 2001-2025 Zabbix SIA
**
** This program is free software: you can redistribute it and/or modify it under the terms of
** the GNU Affero General Public License as published by the Free Software Foundation, version 3.
**
** 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 Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License along with this program.
** If not, see .
**/
#include "dbupgrade.h"
#include "zbxnum.h"
#include "zbxexpr.h"
#include "zbxalgo.h"
#include "zbxdb.h"
#include "zbxdbschema.h"
#include "zbxstr.h"
/*
* 3.2 development database patches
*/
#ifndef HAVE_SQLITE3
static int DBpatch_3010000(void)
{
return DBdrop_index("history_log", "history_log_2");
}
static int DBpatch_3010001(void)
{
return DBdrop_field("history_log", "id");
}
static int DBpatch_3010002(void)
{
return DBdrop_index("history_text", "history_text_2");
}
static int DBpatch_3010003(void)
{
return DBdrop_field("history_text", "id");
}
static int DBpatch_3010004(void)
{
const zbx_db_field_t field = {"recovery_mode", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
return DBadd_field("triggers", &field);
}
static int DBpatch_3010005(void)
{
const zbx_db_field_t field = {"recovery_expression", "", NULL, NULL, 2048, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0};
return DBadd_field("triggers", &field);
}
static int DBpatch_3010006(void)
{
const zbx_db_table_t table =
{"trigger_tag", "triggertagid", 0,
{
{"triggertagid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"triggerid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"tag", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{"value", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010007(void)
{
return DBcreate_index("trigger_tag", "trigger_tag_1", "triggerid", 0);
}
static int DBpatch_3010008(void)
{
const zbx_db_field_t field = {"triggerid", NULL, "triggers", "triggerid", 0, 0, 0, ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("trigger_tag", 1, &field);
}
static int DBpatch_3010009(void)
{
const zbx_db_table_t table =
{"event_tag", "eventtagid", 0,
{
{"eventtagid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"eventid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"tag", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{"value", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010010(void)
{
return DBcreate_index("event_tag", "event_tag_1", "eventid", 0);
}
static int DBpatch_3010011(void)
{
const zbx_db_field_t field = {"eventid", NULL, "events", "eventid", 0, 0, 0, ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("event_tag", 1, &field);
}
static int DBpatch_3010012(void)
{
const zbx_db_field_t field = {"value2", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0};
return DBadd_field("conditions", &field);
}
static int DBpatch_3010013(void)
{
const zbx_db_field_t field = {"maintenance_mode", "1", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
return DBadd_field("actions", &field);
}
static int DBpatch_3010014(void)
{
const zbx_db_table_t table =
{"problem", "eventid", 0,
{
{"eventid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"source", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0},
{"object", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0},
{"objectid", "0", NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010015(void)
{
return DBcreate_index("problem", "problem_1", "source,object,objectid", 0);
}
static int DBpatch_3010016(void)
{
const zbx_db_field_t field = {"eventid", NULL, "events", "eventid", 0, ZBX_TYPE_ID, ZBX_NOTNULL,
ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("problem", 1, &field);
}
static int DBpatch_3010017(void)
{
const zbx_db_table_t table =
{"event_recovery", "eventid", 0,
{
{"eventid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"r_eventid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010018(void)
{
return DBcreate_index("event_recovery", "event_recovery_1", "r_eventid", 0);
}
static int DBpatch_3010019(void)
{
const zbx_db_field_t field = {"eventid", NULL, "events", "eventid", 0, ZBX_TYPE_ID, ZBX_NOTNULL,
ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("event_recovery", 1, &field);
}
static int DBpatch_3010020(void)
{
const zbx_db_field_t field = {"r_eventid", NULL, "events", "eventid", 0, ZBX_TYPE_ID, ZBX_NOTNULL,
ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("event_recovery", 2, &field);
}
/* DBpatch_3010021 () */
#define ZBX_OPEN_EVENT_WARNING_NUM 10000000
/* problem eventids by triggerid */
typedef struct
{
int source;
int object;
zbx_uint64_t objectid;
zbx_vector_uint64_t eventids;
}
zbx_object_events_t;
/* source events hashset support */
static zbx_hash_t DBpatch_3010021_trigger_events_hash_func(const void *data)
{
const zbx_object_events_t *oe = (const zbx_object_events_t *)data;
zbx_hash_t hash;
hash = ZBX_DEFAULT_UINT64_HASH_FUNC(&oe->objectid);
hash = ZBX_DEFAULT_UINT64_HASH_ALGO(&oe->source, sizeof(oe->source), hash);
hash = ZBX_DEFAULT_UINT64_HASH_ALGO(&oe->object, sizeof(oe->object), hash);
return hash;
}
static int DBpatch_3010021_trigger_events_compare_func(const void *d1, const void *d2)
{
const zbx_object_events_t *oe1 = (const zbx_object_events_t *)d1;
const zbx_object_events_t *oe2 = (const zbx_object_events_t *)d2;
ZBX_RETURN_IF_NOT_EQUAL(oe1->source, oe2->source);
ZBX_RETURN_IF_NOT_EQUAL(oe1->object, oe2->object);
ZBX_RETURN_IF_NOT_EQUAL(oe1->objectid, oe2->objectid);
return 0;
}
/******************************************************************************
* *
* Purpose: set events.r_eventid field with corresponding recovery event id *
* *
* Parameters: events - [IN/OUT] unrecovered events indexed by triggerid *
* eventid - [IN/OUT] the last processed event id *
* *
* Return value: SUCCEED - the operation was completed successfully *
* FAIL - otherwise *
* *
******************************************************************************/
static int DBpatch_3010021_update_event_recovery(zbx_hashset_t *events, zbx_uint64_t *eventid)
{
zbx_db_row_t row;
zbx_db_result_t result;
char *sql = NULL;
size_t sql_alloc = 4096, sql_offset = 0;
int i, value, ret = FAIL;
zbx_object_events_t *object_events, object_events_local;
zbx_db_insert_t db_insert;
sql = (char *)zbx_malloc(NULL, sql_alloc);
/* source: 0 - EVENT_SOURCE_TRIGGERS, 3 - EVENT_SOURCE_INTERNAL */
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
"select source,object,objectid,eventid,value"
" from events"
" where eventid>" ZBX_FS_UI64
" and source in (0,3)"
" order by eventid",
*eventid);
/* process events by 10k large batches */
if (NULL == (result = zbx_db_select_n(sql, 10000)))
goto out;
zbx_db_insert_prepare(&db_insert, "event_recovery", "eventid", "r_eventid", (char *)NULL);
while (NULL != (row = zbx_db_fetch(result)))
{
object_events_local.source = atoi(row[0]);
object_events_local.object = atoi(row[1]);
ZBX_STR2UINT64(object_events_local.objectid, row[2]);
ZBX_STR2UINT64(*eventid, row[3]);
value = atoi(row[4]);
if (NULL == (object_events = (zbx_object_events_t *)zbx_hashset_search(events, &object_events_local)))
{
object_events = (zbx_object_events_t *)zbx_hashset_insert(events, &object_events_local,
sizeof(object_events_local));
zbx_vector_uint64_create(&object_events->eventids);
}
if (1 == value)
{
/* 1 - TRIGGER_VALUE_TRUE (PROBLEM state) */
zbx_vector_uint64_append(&object_events->eventids, *eventid);
if (ZBX_OPEN_EVENT_WARNING_NUM == object_events->eventids.values_num)
{
zabbix_log(LOG_LEVEL_WARNING, "too many open problem events by event source:%d,"
" object:%d and objectid:" ZBX_FS_UI64, object_events->source,
object_events->object, object_events->objectid);
}
}
else
{
/* 0 - TRIGGER_VALUE_FALSE (OK state) */
for (i = 0; i < object_events->eventids.values_num; i++)
zbx_db_insert_add_values(&db_insert, object_events->eventids.values[i], *eventid);
zbx_vector_uint64_clear(&object_events->eventids);
}
}
zbx_db_free_result(result);
ret = zbx_db_insert_execute(&db_insert);
zbx_db_insert_clean(&db_insert);
out:
zbx_free(sql);
return ret;
}
static int DBpatch_3010021(void)
{
int i, ret = FAIL;
zbx_uint64_t eventid = 0, old_eventid;
zbx_db_insert_t db_insert;
zbx_hashset_t events;
zbx_hashset_iter_t iter;
zbx_object_events_t *object_events;
zbx_hashset_create(&events, 1024, DBpatch_3010021_trigger_events_hash_func,
DBpatch_3010021_trigger_events_compare_func);
zbx_db_insert_prepare(&db_insert, "problem", "eventid", "source", "object", "objectid", (char *)NULL);
do
{
old_eventid = eventid;
if (SUCCEED != DBpatch_3010021_update_event_recovery(&events, &eventid))
goto out;
}
while (eventid != old_eventid);
/* generate problems from unrecovered events */
zbx_hashset_iter_reset(&events, &iter);
while (NULL != (object_events = (zbx_object_events_t *)zbx_hashset_iter_next(&iter)))
{
for (i = 0; i < object_events->eventids.values_num; i++)
{
zbx_db_insert_add_values(&db_insert, object_events->eventids.values[i], object_events->source,
object_events->object, object_events->objectid);
}
if (1000 < db_insert.rows.values_num)
{
if (SUCCEED != zbx_db_insert_execute(&db_insert))
goto out;
zbx_db_insert_clean(&db_insert);
zbx_db_insert_prepare(&db_insert, "problem", "eventid", "source", "object", "objectid",
(char *)NULL);
}
zbx_vector_uint64_destroy(&object_events->eventids);
}
if (SUCCEED != zbx_db_insert_execute(&db_insert))
goto out;
ret = SUCCEED;
out:
zbx_db_insert_clean(&db_insert);
zbx_hashset_destroy(&events);
return ret;
}
static int DBpatch_3010022(void)
{
const zbx_db_field_t field = {"recovery", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
return DBadd_field("operations", &field);
}
static int DBpatch_3010023(void)
{
zbx_db_insert_t db_insert, db_insert_msg;
zbx_db_row_t row;
zbx_db_result_t result;
int ret, actions_num;
zbx_uint64_t actionid, operationid;
result = zbx_db_select("select count(*) from actions where recovery_msg=1");
if (NULL == (row = zbx_db_fetch(result)) || 0 == (actions_num = atoi(row[0])))
{
ret = SUCCEED;
goto out;
}
operationid = zbx_db_get_maxid_num("operations", actions_num);
zbx_db_insert_prepare(&db_insert, "operations", "operationid", "actionid", "operationtype", "recovery",
(char *)NULL);
zbx_db_insert_prepare(&db_insert_msg, "opmessage", "operationid", "default_msg", "subject", "message",
(char *)NULL);
zbx_db_free_result(result);
result = zbx_db_select("select actionid,r_shortdata,r_longdata from actions where recovery_msg=1");
while (NULL != (row = zbx_db_fetch(result)))
{
ZBX_STR2UINT64(actionid, row[0]);
/* operationtype: 11 - OPERATION_TYPE_RECOVERY_MESSAGE */
zbx_db_insert_add_values(&db_insert, operationid, actionid, 11, 1);
zbx_db_insert_add_values(&db_insert_msg, operationid, 1, row[1], row[2]);
operationid++;
}
if (SUCCEED == (ret = zbx_db_insert_execute(&db_insert)))
ret = zbx_db_insert_execute(&db_insert_msg);
zbx_db_insert_clean(&db_insert_msg);
zbx_db_insert_clean(&db_insert);
out:
zbx_db_free_result(result);
return ret;
}
/* patch 3010024 */
#define ZBX_3010024_ACTION_NOTHING 0
#define ZBX_3010024_ACTION_DISABLE 1
#define ZBX_3010024_ACTION_CONVERT 2
/******************************************************************************
* *
* Purpose: checks if the action must be disabled or its operations converted *
* to recovery operations *
* *
* Return value: ZBX_3010024_ACTION_NOTHING - do nothing *
* ZBX_3010024_ACTION_DISABLE - disable action *
* ZBX_3010024_ACTION_CONVERT - convert action operations to *
* recovery operations *
* *
* Comments: This function does not analyze expressions so it might ask to *
* disable actions that can't match success event. However correct *
* analysis is not easy to do, so to be safe failure is returned. *
* *
******************************************************************************/
static int DBpatch_3010024_validate_action(zbx_uint64_t actionid, int eventsource, int evaltype, int recovery_msg)
{
zbx_db_row_t row;
zbx_db_result_t result;
int conditiontype, ret = ZBX_3010024_ACTION_DISABLE, value;
/* evaltype: 0 - ZBX_CONDITION_EVAL_TYPE_AND_OR, 1 - ZBX_CONDITION_EVAL_TYPE_AND */
if (evaltype != 0 && evaltype != 1)
return ret;
result = zbx_db_select("select conditiontype,value from conditions where actionid=" ZBX_FS_UI64, actionid);
while (NULL != (row = zbx_db_fetch(result)))
{
conditiontype = atoi(row[0]);
/* eventsource: 0 - EVENT_SOURCE_TRIGGERS, 3 - EVENT_SOURCE_INTERNAL */
if (0 == eventsource)
{
/* conditiontype: 5 - ZBX_CONDITION_TYPE_TRIGGER_VALUE */
if (5 != conditiontype)
continue;
value = atoi(row[1]);
/* condition 'Trigger value = OK' */
if (0 == value)
{
if (ZBX_3010024_ACTION_NOTHING == ret)
{
ret = ZBX_3010024_ACTION_DISABLE;
break;
}
ret = ZBX_3010024_ACTION_CONVERT;
}
/* condition 'Trigger value = PROBLEM' */
if (1 == value)
{
if (ZBX_3010024_ACTION_CONVERT == ret)
{
ret = ZBX_3010024_ACTION_DISABLE;
break;
}
ret = ZBX_3010024_ACTION_NOTHING;
}
}
else if (3 == eventsource)
{
/* conditiontype: 23 - ZBX_CONDITION_TYPE_EVENT_TYPE */
if (23 != conditiontype)
continue;
value = atoi(row[1]);
/* event types: */
/* 1 - Event type: Item in "normal" state */
/* 3 - Low-level discovery rule in "normal" state */
/* 5 - Trigger in "normal" state */
if (1 == value || 3 == value || 5 == value)
{
ret = ZBX_3010024_ACTION_DISABLE;
break;
}
/* event types: */
/* 0 - Event type: Item in "not supported" state */
/* 2 - Low-level discovery rule in "not supported" state */
/* 4 - Trigger in "unknown" state */
if (0 == value || 2 == value || 4 == value)
ret = ZBX_3010024_ACTION_NOTHING;
}
}
zbx_db_free_result(result);
if (ZBX_3010024_ACTION_CONVERT == ret)
{
result = zbx_db_select("select o.operationtype,o.esc_step_from,o.esc_step_to,count(oc.opconditionid)"
" from operations o"
" left join opconditions oc"
" on oc.operationid=o.operationid"
" where o.actionid=" ZBX_FS_UI64
" group by o.operationid,o.operationtype,o.esc_step_from,o.esc_step_to",
actionid);
while (NULL != (row = zbx_db_fetch(result)))
{
/* cannot convert action if: */
/* there are escalation steps that aren't executed at the escalation start */
/* there are conditions defined for action operations */
/* there are operation to send message and action recovery message is enabled */
if (1 != atoi(row[1]) || 0 != atoi(row[3]) || (0 == atoi(row[0]) && 0 != recovery_msg))
{
ret = ZBX_3010024_ACTION_DISABLE;
break;
}
}
zbx_db_free_result(result);
}
return ret;
}
static int DBpatch_3010024(void)
{
zbx_db_row_t row;
zbx_db_result_t result;
zbx_vector_uint64_t actionids_disable, actionids_convert;
int ret, evaltype, eventsource, recovery_msg;
zbx_uint64_t actionid;
zbx_vector_uint64_create(&actionids_disable);
zbx_vector_uint64_create(&actionids_convert);
/* eventsource: 0 - EVENT_SOURCE_TRIGGERS, 3 - EVENT_SOURCE_INTERNAL */
result = zbx_db_select("select actionid,name,eventsource,evaltype,recovery_msg from actions"
" where eventsource in (0,3)");
while (NULL != (row = zbx_db_fetch(result)))
{
ZBX_STR2UINT64(actionid, row[0]);
eventsource = atoi(row[2]);
evaltype = atoi(row[3]);
recovery_msg = atoi(row[4]);
ret = DBpatch_3010024_validate_action(actionid, eventsource, evaltype, recovery_msg);
if (ZBX_3010024_ACTION_DISABLE == ret)
{
zbx_vector_uint64_append(&actionids_disable, actionid);
zabbix_log(LOG_LEVEL_WARNING, "Action \"%s\" will be disabled during database upgrade:"
" conditions might have matched success event which is not supported anymore.",
row[1]);
}
else if (ZBX_3010024_ACTION_CONVERT == ret)
{
zbx_vector_uint64_append(&actionids_convert, actionid);
zabbix_log(LOG_LEVEL_WARNING, "Action \"%s\" operations will be converted to recovery"
" operations during database upgrade.", row[1]);
}
}
zbx_db_free_result(result);
ret = SUCCEED;
if (0 != actionids_disable.values_num || 0 != actionids_convert.values_num)
{
char *sql = NULL;
size_t sql_alloc = 0, sql_offset = 0;
if (0 != actionids_disable.values_num)
{
/* status: 1 - ZBX_ACTION_STATUS_DISABLED */
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update actions set status=1 where");
zbx_db_add_condition_alloc(&sql, &sql_alloc, &sql_offset, "actionid", actionids_disable.values,
actionids_disable.values_num);
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
}
if (0 != actionids_convert.values_num)
{
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update actions"
" set r_shortdata=def_shortdata,"
"r_longdata=def_longdata"
" where");
zbx_db_add_condition_alloc(&sql, &sql_alloc, &sql_offset, "actionid", actionids_convert.values,
actionids_convert.values_num);
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update operations set recovery=1 where");
zbx_db_add_condition_alloc(&sql, &sql_alloc, &sql_offset, "actionid", actionids_convert.values,
actionids_convert.values_num);
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
}
if (ZBX_DB_OK > zbx_db_execute("%s", sql))
ret = FAIL;
zbx_free(sql);
}
zbx_vector_uint64_destroy(&actionids_convert);
zbx_vector_uint64_destroy(&actionids_disable);
return ret;
}
static int DBpatch_3010025(void)
{
return DBdrop_field("actions", "recovery_msg");
}
/* patch 3010026 */
#define ZBX_3010026_TOKEN_UNKNOWN 0
#define ZBX_3010026_TOKEN_OPEN 1
#define ZBX_3010026_TOKEN_CLOSE 2
#define ZBX_3010026_TOKEN_AND 3
#define ZBX_3010026_TOKEN_OR 4
#define ZBX_3010026_TOKEN_VALUE 5
#define ZBX_3010026_TOKEN_END 6
#define ZBX_3010026_PARSE_VALUE 0
#define ZBX_3010026_PARSE_OP 1
/******************************************************************************
* *
* Purpose: get success condition identifiers *
* *
* Parameters: actionid - [IN] the action identifier *
* name - [IN] the action name *
* eventsource - [IN] the action event source *
* conditionids - [OUT] the success condition identifiers *
* *
******************************************************************************/
static void DBpatch_3010026_get_conditionids(zbx_uint64_t actionid, const char *name, int eventsource,
zbx_vector_uint64_t *conditionids)
{
zbx_db_row_t row;
zbx_db_result_t result;
zbx_uint64_t conditionid;
char *condition = NULL;
size_t condition_alloc = 0, condition_offset = 0;
int value;
/* eventsource: 0 - EVENT_SOURCE_TRIGGERS, 3 - EVENT_SOURCE_INTERNAL */
if (0 == eventsource)
{
/* conditiontype: 5 - ZBX_CONDITION_TYPE_TRIGGER_VALUE */
result = zbx_db_select("select conditionid,value from conditions"
" where actionid=" ZBX_FS_UI64
" and conditiontype=5",
actionid);
}
else if (3 == eventsource)
{
/* conditiontype: 23 - ZBX_CONDITION_TYPE_EVENT_TYPE */
result = zbx_db_select("select conditionid,value from conditions"
" where actionid=" ZBX_FS_UI64
" and conditiontype=23"
" and value in ('1', '3', '5')",
actionid);
}
else
return;
while (NULL != (row = zbx_db_fetch(result)))
{
ZBX_STR2UINT64(conditionid, row[0]);
zbx_vector_uint64_append(conditionids, conditionid);
value = atoi(row[1]);
if (0 == eventsource)
{
/* value: 0 - TRIGGER_VALUE_OK, 1 - TRIGGER_VALUE_PROBLEM */
const char *values[] = {"OK", "PROBLEM"};
zbx_snprintf_alloc(&condition, &condition_alloc, &condition_offset, "Trigger value = %s",
values[value]);
}
else
{
/* value: 1 - EVENT_TYPE_ITEM_NORMAL */
/* 3 - EVENT_TYPE_LLDRULE_NORMAL */
/* 5 - *EVENT_TYPE_TRIGGER_NORMAL */
const char *values[] = {NULL, "Item in 'normal' state",
NULL, "Low-level discovery rule in 'normal' state",
NULL, "Trigger in 'normal' state"};
zbx_snprintf_alloc(&condition, &condition_alloc, &condition_offset, "Event type = %s",
values[value]);
}
zabbix_log(LOG_LEVEL_WARNING, "Action \"%s\" condition \"%s\" will be removed during database upgrade:"
" this type of condition is not supported anymore", name, condition);
condition_offset = 0;
}
zbx_free(condition);
zbx_db_free_result(result);
}
/******************************************************************************
* *
* Purpose: skips whitespace characters *
* *
* Parameters: expression - [IN] the expression to process *
* offset - [IN] the starting offset in expression *
* *
* Return value: the position of first non-whitespace character after offset *
* *
******************************************************************************/
static size_t DBpatch_3010026_expression_skip_whitespace(const char *expression, size_t offset)
{
while (' ' == expression[offset])
offset++;
return offset;
}
/******************************************************************************
* *
* Purpose: gets the next expression token starting with offset *
* *
* Parameters: expression - [IN] the expression to process *
* offset - [IN] the starting offset in expression *
* token - [OUT] the token location in expression *
* *
* Return value: the token type (see ZBX_3010026_TOKEN_* defines) *
* *
* Comments: The recognized tokens are '(', ')', 'and', 'or' and '{}'. *
* *
******************************************************************************/
static int DBpatch_3010026_expression_get_token(const char *expression, int offset, zbx_strloc_t *token)
{
int ret = ZBX_3010026_TOKEN_UNKNOWN;
offset = DBpatch_3010026_expression_skip_whitespace(expression, offset);
token->l = offset;
switch (expression[offset])
{
case '\0':
token->r = offset;
ret = ZBX_3010026_TOKEN_END;
break;
case '(':
token->r = offset;
ret = ZBX_3010026_TOKEN_OPEN;
break;
case ')':
token->r = offset;
ret = ZBX_3010026_TOKEN_CLOSE;
break;
case 'o':
if ('r' == expression[offset + 1])
{
token->r = offset + 1;
ret = ZBX_3010026_TOKEN_OR;
}
break;
case 'a':
if ('n' == expression[offset + 1] && 'd' == expression[offset + 2])
{
token->r = offset + 2;
ret = ZBX_3010026_TOKEN_AND;
}
break;
case '{':
while (0 != isdigit(expression[++offset]))
;
if ('}' == expression[offset])
{
token->r = offset;
ret = ZBX_3010026_TOKEN_VALUE;
}
break;
}
return ret;
}
/******************************************************************************
* *
* Purpose: checks if the value does not match any filter value *
* *
* Parameters: expression - [IN] the expression to process *
* value - [IN] the location of value in expression *
* filter - [IN] a list of values to compare *
* *
* Return value: SUCCEED - the value does not match any filter values *
* FAIL - otherwise *
* *
******************************************************************************/
static int DBpatch_3010026_expression_validate_value(const char *expression, zbx_strloc_t *value,
const zbx_vector_str_t *filter)
{
int i;
for (i = 0; i < filter->values_num; i++)
{
if (0 == strncmp(expression + value->l, filter->values[i], value->r - value->l + 1))
return SUCCEED;
}
return FAIL;
}
/******************************************************************************
* *
* Purpose: cuts substring from the expression *
* *
* Parameters: expression - [IN] the expression to process *
* cu - [IN] the substring location *
* *
******************************************************************************/
static void DBpatch_3010026_expression_cut_substring(char *expression, zbx_strloc_t *cut)
{
if (cut->l <= cut->r)
memmove(expression + cut->l, expression + cut->r + 1, strlen(expression + cut->r + 1) + 1);
}
/******************************************************************************
* *
* Purpose: location by the specified offset *
* *
* Parameters: location - [IN] the location to adjust *
* offset - [IN] the offset *
* *
******************************************************************************/
static void DBpatch_3010026_expression_move_location(zbx_strloc_t *location, int offset)
{
location->l += offset;
location->r += offset;
}
/******************************************************************************
* *
* Purpose: removes values specified in filter from the location *
* *
* Parameters: expression - [IN] the expression to process *
* exp_token - [IN] the current location in expression *
* filter - [IN] a list of values *
* *
* Return value: SUCCEED - the expression was processed successfully *
* FAIL - failed to parse expression *
* *
******************************************************************************/
static int DBpatch_3010026_expression_remove_values_impl(char *expression, zbx_strloc_t *exp_token,
const zbx_vector_str_t *filter)
{
zbx_strloc_t token, cut_loc, op_token, value_token;
int token_type, cut_value = 0, state = ZBX_3010026_PARSE_VALUE,
prevop_type = ZBX_3010026_TOKEN_UNKNOWN;
exp_token->r = exp_token->l;
while (ZBX_3010026_TOKEN_UNKNOWN != (token_type =
DBpatch_3010026_expression_get_token(expression, exp_token->r, &token)))
{
/* parse value */
if (ZBX_3010026_PARSE_VALUE == state)
{
state = ZBX_3010026_PARSE_OP;
if (ZBX_3010026_TOKEN_OPEN == token_type)
{
token.l = token.r + 1;
if (FAIL == DBpatch_3010026_expression_remove_values_impl(expression, &token, filter))
return FAIL;
if (')' != expression[token.r])
return FAIL;
if (token.r == DBpatch_3010026_expression_skip_whitespace(expression, token.l))
cut_value = 1;
/* include opening '(' into token */
token.l--;
value_token = token;
exp_token->r = token.r + 1;
continue;
}
else if (ZBX_3010026_TOKEN_VALUE != token_type)
return FAIL;
if (SUCCEED == DBpatch_3010026_expression_validate_value(expression, &token, filter))
cut_value = 1;
value_token = token;
exp_token->r = token.r + 1;
continue;
}
/* parse operator */
state = ZBX_3010026_PARSE_VALUE;
if (1 == cut_value)
{
if (ZBX_3010026_TOKEN_AND == prevop_type || (ZBX_3010026_TOKEN_OR == prevop_type &&
(ZBX_3010026_TOKEN_CLOSE == token_type || ZBX_3010026_TOKEN_END == token_type)))
{
cut_loc.l = op_token.l;
cut_loc.r = value_token.r;
DBpatch_3010026_expression_move_location(&token, -(cut_loc.r - cut_loc.l + 1));
prevop_type = token_type;
op_token = token;
}
else
{
cut_loc.l = value_token.l;
if (ZBX_3010026_TOKEN_CLOSE == token_type || ZBX_3010026_TOKEN_END == token_type)
cut_loc.r = token.l - 1;
else
cut_loc.r = token.r;
DBpatch_3010026_expression_move_location(&token, -(cut_loc.r - cut_loc.l + 1));
}
DBpatch_3010026_expression_cut_substring(expression, &cut_loc);
cut_value = 0;
}
else
{
prevop_type = token_type;
op_token = token;
}
if (ZBX_3010026_TOKEN_CLOSE == token_type || ZBX_3010026_TOKEN_END == token_type)
{
exp_token->r = token.r;
return SUCCEED;
}
if (ZBX_3010026_TOKEN_AND != token_type && ZBX_3010026_TOKEN_OR != token_type)
return FAIL;
exp_token->r = token.r + 1;
}
return FAIL;
}
/******************************************************************************
* *
* Purpose: removes values specified in filter from the location *
* *
* Parameters: expression - [IN] the expression to process *
* filter - [IN] a list of values *
* *
* Return value: SUCCEED - the expression was processed successfully *
* FAIL - failed to parse expression *
* *
******************************************************************************/
static int DBpatch_3010026_expression_remove_values(char *expression, const zbx_vector_str_t *filter)
{
int ret;
zbx_strloc_t token = {0};
if (SUCCEED == (ret = DBpatch_3010026_expression_remove_values_impl(expression, &token, filter)))
zbx_lrtrim(expression, " ");
return ret;
}
static int DBpatch_3010026(void)
{
zbx_db_row_t row;
zbx_db_result_t result;
zbx_vector_uint64_t conditionids, actionids;
int ret = FAIL, evaltype, index, i, eventsource;
zbx_uint64_t actionid;
char *sql = NULL, *formula;
size_t sql_alloc = 0, sql_offset = 0;
zbx_vector_str_t filter;
zbx_vector_uint64_create(&conditionids);
zbx_vector_uint64_create(&actionids);
zbx_vector_str_create(&filter);
result = zbx_db_select("select actionid,eventsource,evaltype,formula,name from actions");
while (NULL != (row = zbx_db_fetch(result)))
{
ZBX_STR2UINT64(actionid, row[0]);
eventsource = atoi(row[1]);
evaltype = atoi(row[2]);
index = conditionids.values_num;
DBpatch_3010026_get_conditionids(actionid, row[4], eventsource, &conditionids);
/* evaltype: 3 - ZBX_CONDITION_EVAL_TYPE_EXPRESSION */
if (3 != evaltype)
continue;
/* no new conditions to remove, process next action */
if (index == conditionids.values_num)
continue;
formula = zbx_strdup(NULL, row[3]);
for (i = index; i < conditionids.values_num; i++)
zbx_vector_str_append(&filter, zbx_dsprintf(NULL, "{" ZBX_FS_UI64 "}", conditionids.values[i]));
if (SUCCEED == DBpatch_3010026_expression_remove_values(formula, &filter))
{
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update actions set formula='%s'"
" where actionid=" ZBX_FS_UI64 ";\n", formula, actionid);
}
zbx_free(formula);
zbx_vector_str_clear_ext(&filter, zbx_str_free);
if (SUCCEED != zbx_db_execute_overflowed_sql(&sql, &sql_alloc, &sql_offset))
goto out;
}
if (ZBX_DB_OK > zbx_db_flush_overflowed_sql(sql, sql_offset))
goto out;
if (0 != conditionids.values_num)
{
sql_offset = 0;
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from conditions where");
zbx_db_add_condition_alloc(&sql, &sql_alloc, &sql_offset, "conditionid", conditionids.values,
conditionids.values_num);
if (ZBX_DB_OK > zbx_db_execute("%s", sql))
goto out;
}
/* reset action evaltype to AND/OR if it has no more conditions left */
zbx_db_free_result(result);
result = zbx_db_select("select a.actionid,a.name,a.evaltype,count(c.conditionid)"
" from actions a"
" left join conditions c"
" on a.actionid=c.actionid"
" group by a.actionid,a.name,a.evaltype");
while (NULL != (row = zbx_db_fetch(result)))
{
/* reset evaltype to AND/OR (0) if action has no more conditions and it's evaltype is not AND/OR */
if (0 == atoi(row[3]) && 0 != atoi(row[2]))
{
ZBX_STR2UINT64(actionid, row[0]);
zbx_vector_uint64_append(&actionids, actionid);
zabbix_log(LOG_LEVEL_WARNING, "Action \"%s\" type of calculation will be changed to And/Or"
" during database upgrade: no action conditions found", row[1]);
}
}
if (0 != actionids.values_num)
{
sql_offset = 0;
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update actions set evaltype=0 where");
zbx_db_add_condition_alloc(&sql, &sql_alloc, &sql_offset, "actionid", actionids.values,
actionids.values_num);
if (ZBX_DB_OK > zbx_db_execute("%s", sql))
goto out;
}
ret = SUCCEED;
out:
zbx_db_free_result(result);
zbx_free(sql);
zbx_vector_str_destroy(&filter);
zbx_vector_uint64_destroy(&actionids);
zbx_vector_uint64_destroy(&conditionids);
return ret;
}
static int DBpatch_3010027(void)
{
const zbx_db_field_t field = {"correlation_mode", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
return DBadd_field("triggers", &field);
}
static int DBpatch_3010028(void)
{
const zbx_db_field_t field = {"correlation_tag", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0};
return DBadd_field("triggers", &field);
}
static int DBpatch_3010029(void)
{
const zbx_db_field_t field = {"clock", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
return DBadd_field("problem", &field);
}
static int DBpatch_3010030(void)
{
const zbx_db_field_t field = {"ns", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
return DBadd_field("problem", &field);
}
static int DBpatch_3010031(void)
{
const zbx_db_field_t field = {"r_eventid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, 0, 0};
return DBadd_field("problem", &field);
}
static int DBpatch_3010032(void)
{
const zbx_db_field_t field = {"r_clock", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
return DBadd_field("problem", &field);
}
static int DBpatch_3010033(void)
{
const zbx_db_field_t field = {"r_ns", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
return DBadd_field("problem", &field);
}
static int DBpatch_3010034(void)
{
return DBcreate_index("problem", "problem_2", "r_clock", 0);
}
static int DBpatch_3010035(void)
{
const zbx_db_field_t field = {"r_eventid", NULL, "events", "eventid", 0, 0, 0, ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("problem", 2, &field);
}
static int DBpatch_3010036(void)
{
const zbx_db_table_t table =
{"problem_tag", "problemtagid", 0,
{
{"problemtagid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"eventid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"tag", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{"value", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010037(void)
{
return DBcreate_index("problem_tag", "problem_tag_1", "eventid", 0);
}
static int DBpatch_3010038(void)
{
return DBcreate_index("problem_tag", "problem_tag_2", "tag,value", 0);
}
static int DBpatch_3010039(void)
{
const zbx_db_field_t field = {"eventid", NULL, "problem", "eventid", 0, 0, 0, ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("problem_tag", 1, &field);
}
static int DBpatch_3010042(void)
{
if (ZBX_DB_OK <= zbx_db_execute("update config set ok_period=%d where ok_period>%d", SEC_PER_DAY, SEC_PER_DAY))
return SUCCEED;
return FAIL;
}
static int DBpatch_3010043(void)
{
if (ZBX_DB_OK <= zbx_db_execute("update config set blink_period=%d where blink_period>%d", SEC_PER_DAY, SEC_PER_DAY))
return SUCCEED;
return FAIL;
}
static int DBpatch_3010044(void)
{
const zbx_db_field_t field = {"correlationid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, 0, 0};
return DBadd_field("problem", &field);
}
static int DBpatch_3010045(void)
{
const zbx_db_field_t field = {"c_eventid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, 0, 0};
return DBadd_field("event_recovery", &field);
}
static int DBpatch_3010046(void)
{
const zbx_db_field_t field = {"correlationid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, 0, 0};
return DBadd_field("event_recovery", &field);
}
static int DBpatch_3010047(void)
{
return DBcreate_index("event_recovery", "event_recovery_2", "c_eventid", 0);
}
static int DBpatch_3010048(void)
{
const zbx_db_field_t field = {"c_eventid", NULL, "events", "eventid", 0, 0, 0, ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("event_recovery", 3, &field);
}
static int DBpatch_3010049(void)
{
const zbx_db_table_t table =
{"correlation", "correlationid", 0,
{
{"correlationid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"name", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{"description", "", NULL, NULL, 255, ZBX_TYPE_TEXT, ZBX_NOTNULL, 0},
{"evaltype", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0},
{"status", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0},
{"formula", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010050(void)
{
return DBcreate_index("correlation", "correlation_1", "status", 0);
}
static int DBpatch_3010051(void)
{
return DBcreate_index("correlation", "correlation_2", "name", 1);
}
static int DBpatch_3010052(void)
{
const zbx_db_table_t table =
{"corr_condition", "corr_conditionid", 0,
{
{"corr_conditionid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"correlationid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"type", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010053(void)
{
return DBcreate_index("corr_condition", "corr_condition_1", "correlationid", 0);
}
static int DBpatch_3010054(void)
{
const zbx_db_field_t field = {"correlationid", NULL, "correlation", "correlationid", 0, 0, 0,
ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("corr_condition", 1, &field);
}
static int DBpatch_3010055(void)
{
const zbx_db_table_t table =
{"corr_condition_tag", "corr_conditionid", 0,
{
{"corr_conditionid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"tag", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010056(void)
{
const zbx_db_field_t field = {"corr_conditionid", NULL, "corr_condition", "corr_conditionid", 0, 0, 0,
ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("corr_condition_tag", 1, &field);
}
static int DBpatch_3010057(void)
{
const zbx_db_table_t table =
{"corr_condition_group", "corr_conditionid", 0,
{
{"corr_conditionid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"operator", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0},
{"groupid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010058(void)
{
return DBcreate_index("corr_condition_group", "corr_condition_group_1", "groupid", 0);
}
static int DBpatch_3010059(void)
{
const zbx_db_field_t field = {"corr_conditionid", NULL, "corr_condition", "corr_conditionid", 0, 0, 0,
ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("corr_condition_group", 1, &field);
}
static int DBpatch_3010060(void)
{
const zbx_db_field_t field = {"groupid", NULL, "groups", "groupid", 0, 0, 0, 0};
return DBadd_foreign_key("corr_condition_group", 2, &field);
}
static int DBpatch_3010061(void)
{
const zbx_db_table_t table =
{"corr_condition_tagpair", "corr_conditionid", 0,
{
{"corr_conditionid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"oldtag", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{"newtag", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010062(void)
{
const zbx_db_field_t field = {"corr_conditionid", NULL, "corr_condition", "corr_conditionid", 0, 0, 0,
ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("corr_condition_tagpair", 1, &field);
}
static int DBpatch_3010063(void)
{
const zbx_db_table_t table =
{"corr_condition_tagvalue", "corr_conditionid", 0,
{
{"corr_conditionid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"tag", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{"operator", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0},
{"value", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010064(void)
{
const zbx_db_field_t field = {"corr_conditionid", NULL, "corr_condition", "corr_conditionid", 0, 0, 0,
ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("corr_condition_tagvalue", 1, &field);
}
static int DBpatch_3010065(void)
{
const zbx_db_table_t table =
{"corr_operation", "corr_operationid", 0,
{
{"corr_operationid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"correlationid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"type", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010066(void)
{
return DBcreate_index("corr_operation", "corr_operation_1", "correlationid", 0);
}
static int DBpatch_3010067(void)
{
const zbx_db_field_t field = {"correlationid", NULL, "correlation", "correlationid", 0, 0, 0,
ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("corr_operation", 1, &field);
}
static int DBpatch_3010068(void)
{
/* state: 0 - TRIGGER_STATE_NORMAL */
/* flags: 2 - ZBX_FLAG_DISCOVERY_PROTOTYPE */
if (ZBX_DB_OK <= zbx_db_execute("update triggers set error='',state=0 where flags=2"))
return SUCCEED;
return FAIL;
}
static int DBpatch_3010069(void)
{
const zbx_db_table_t table =
{"task", "taskid", 0,
{
{"taskid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"type", NULL, NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010070(void)
{
const zbx_db_table_t table =
{"task_close_problem", "taskid", 0,
{
{"taskid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{"acknowledgeid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, ZBX_NOTNULL, 0},
{0}
},
NULL
};
return DBcreate_table(&table);
}
static int DBpatch_3010071(void)
{
const zbx_db_field_t field = {"taskid", NULL, "task", "taskid", 0, 0, 0, ZBX_FK_CASCADE_DELETE};
return DBadd_foreign_key("task_close_problem", 1, &field);
}
static int DBpatch_3010072(void)
{
const zbx_db_field_t field = {"action", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
return DBadd_field("acknowledges", &field);
}
static int DBpatch_3010073(void)
{
const zbx_db_field_t field = {"manual_close", "0", NULL, NULL, 0, ZBX_TYPE_INT, ZBX_NOTNULL, 0};
return DBadd_field("triggers", &field);
}
static int DBpatch_3010074(void)
{
const zbx_db_field_t field = {"userid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, 0, 0};
return DBadd_field("event_recovery", &field);
}
static int DBpatch_3010075(void)
{
const zbx_db_field_t field = {"userid", NULL, NULL, NULL, 0, ZBX_TYPE_ID, 0, 0};
return DBadd_field("problem", &field);
}
static int DBpatch_3010076(void)
{
const char *sql = "delete from profiles where idx in ("
"'web.events.discovery.period',"
"'web.events.filter.state',"
"'web.events.filter.triggerid',"
"'web.events.source',"
"'web.events.timelinefixed',"
"'web.events.trigger.period'"
")";
if (ZBX_DB_OK <= zbx_db_execute("%s", sql))
return SUCCEED;
return FAIL;
}
static int DBpatch_3010077(void)
{
const zbx_db_field_t field = {"name", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0};
return DBmodify_field_type("groups", &field, NULL);
}
static int DBpatch_3010078(void)
{
const zbx_db_field_t field = {"name", "", NULL, NULL, 255, ZBX_TYPE_CHAR, ZBX_NOTNULL, 0};
return DBmodify_field_type("group_prototype", &field, NULL);
}
static int DBpatch_3010079(void)
{
zbx_db_row_t row;
zbx_db_result_t result;
int ret = FAIL;
char *sql = NULL;
size_t sql_alloc = 0, sql_offset = 0;
result = zbx_db_select("select p.eventid,e.clock,e.ns"
" from problem p,events e"
" where p.eventid=e.eventid"
" and p.clock=0");
while (NULL != (row = zbx_db_fetch(result)))
{
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
"update problem set clock=%s,ns=%s where eventid=%s;\n",
row[1], row[2], row[0]);
if (SUCCEED != zbx_db_execute_overflowed_sql(&sql, &sql_alloc, &sql_offset))
goto out;
}
if (ZBX_DB_OK > zbx_db_flush_overflowed_sql(sql, sql_offset))
goto out;
ret = SUCCEED;
out:
zbx_db_free_result(result);
zbx_free(sql);
return ret;
}
#endif
DBPATCH_START(3010)
/* version, duplicates flag, mandatory flag */
DBPATCH_ADD(3010000, 0, 1)
DBPATCH_ADD(3010001, 0, 1)
DBPATCH_ADD(3010002, 0, 1)
DBPATCH_ADD(3010003, 0, 1)
DBPATCH_ADD(3010004, 0, 1)
DBPATCH_ADD(3010005, 0, 1)
DBPATCH_ADD(3010006, 0, 1)
DBPATCH_ADD(3010007, 0, 1)
DBPATCH_ADD(3010008, 0, 1)
DBPATCH_ADD(3010009, 0, 1)
DBPATCH_ADD(3010010, 0, 1)
DBPATCH_ADD(3010011, 0, 1)
DBPATCH_ADD(3010012, 0, 1)
DBPATCH_ADD(3010013, 0, 1)
DBPATCH_ADD(3010014, 0, 1)
DBPATCH_ADD(3010015, 0, 1)
DBPATCH_ADD(3010016, 0, 1)
DBPATCH_ADD(3010017, 0, 1)
DBPATCH_ADD(3010018, 0, 1)
DBPATCH_ADD(3010019, 0, 1)
DBPATCH_ADD(3010020, 0, 1)
DBPATCH_ADD(3010021, 0, 1)
DBPATCH_ADD(3010022, 0, 1)
DBPATCH_ADD(3010023, 0, 1)
DBPATCH_ADD(3010024, 0, 1)
DBPATCH_ADD(3010025, 0, 1)
DBPATCH_ADD(3010026, 0, 1)
DBPATCH_ADD(3010027, 0, 1)
DBPATCH_ADD(3010028, 0, 1)
DBPATCH_ADD(3010029, 0, 1)
DBPATCH_ADD(3010030, 0, 1)
DBPATCH_ADD(3010031, 0, 1)
DBPATCH_ADD(3010032, 0, 1)
DBPATCH_ADD(3010033, 0, 1)
DBPATCH_ADD(3010034, 0, 1)
DBPATCH_ADD(3010035, 0, 1)
DBPATCH_ADD(3010036, 0, 1)
DBPATCH_ADD(3010037, 0, 1)
DBPATCH_ADD(3010038, 0, 1)
DBPATCH_ADD(3010039, 0, 1)
DBPATCH_ADD(3010042, 0, 1)
DBPATCH_ADD(3010043, 0, 1)
DBPATCH_ADD(3010044, 0, 1)
DBPATCH_ADD(3010045, 0, 1)
DBPATCH_ADD(3010046, 0, 1)
DBPATCH_ADD(3010047, 0, 1)
DBPATCH_ADD(3010048, 0, 1)
DBPATCH_ADD(3010049, 0, 1)
DBPATCH_ADD(3010050, 0, 1)
DBPATCH_ADD(3010051, 0, 1)
DBPATCH_ADD(3010052, 0, 1)
DBPATCH_ADD(3010053, 0, 1)
DBPATCH_ADD(3010054, 0, 1)
DBPATCH_ADD(3010055, 0, 1)
DBPATCH_ADD(3010056, 0, 1)
DBPATCH_ADD(3010057, 0, 1)
DBPATCH_ADD(3010058, 0, 1)
DBPATCH_ADD(3010059, 0, 1)
DBPATCH_ADD(3010060, 0, 1)
DBPATCH_ADD(3010061, 0, 1)
DBPATCH_ADD(3010062, 0, 1)
DBPATCH_ADD(3010063, 0, 1)
DBPATCH_ADD(3010064, 0, 1)
DBPATCH_ADD(3010065, 0, 1)
DBPATCH_ADD(3010066, 0, 1)
DBPATCH_ADD(3010067, 0, 1)
DBPATCH_ADD(3010068, 0, 0)
DBPATCH_ADD(3010069, 0, 1)
DBPATCH_ADD(3010070, 0, 1)
DBPATCH_ADD(3010071, 0, 1)
DBPATCH_ADD(3010072, 0, 1)
DBPATCH_ADD(3010073, 0, 1)
DBPATCH_ADD(3010074, 0, 1)
DBPATCH_ADD(3010075, 0, 1)
DBPATCH_ADD(3010076, 0, 0)
DBPATCH_ADD(3010077, 0, 1)
DBPATCH_ADD(3010078, 0, 1)
DBPATCH_ADD(3010079, 0, 1)
DBPATCH_END()