* This file is part of the oGRAC project.
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
*
* oGRAC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* set_server.c
*
*
* IDENTIFICATION
* src/server/params/set_server.c
*
* -------------------------------------------------------------------------
*/
#include "srv_module.h"
#include "srv_param.h"
#include "ddl_parser.h"
#include "srv_instance.h"
#include "srv_param_common.h"
#include "knl_spm.h"
#include "dtc_context.h"
#include "srv_device_adpt.h"
#ifdef __cplusplus
extern "C" {
#endif
status_t sql_verify_als_uds_file_path(void *se, void *lex, void *def)
{
knl_alter_sys_def_t *sys_def = (knl_alter_sys_def_t *)def;
word_t word;
if (lex_expected_fetch((lex_t *)lex, &word) != OG_SUCCESS) {
return OG_ERROR;
}
if (word.type != WORD_TYPE_STRING) {
OG_SRC_THROW_ERROR_EX(word.text.loc, ERR_SQL_SYNTAX_ERROR, ", expected string type, but %s found", W2S(&word));
return OG_ERROR;
}
LEX_REMOVE_WRAP(&word);
OG_RETURN_IFERR(cm_text2str((text_t *)&word.text, sys_def->value, OG_PARAM_BUFFER_SIZE));
return verify_uds_file_path((const char *)sys_def->value);
}
status_t sql_verify_als_dss_log_level(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num > OG_MAX_DSS_LOG_LEVEL) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_LARGE, "DSS_LOG_LEVEL", (int64)OG_MAX_DSS_LOG_LEVEL);
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_verify_als_uds_file_permissions(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
return verify_uds_file_permission((uint16)num);
}
status_t sql_verify_als_deadlock_detect_interval(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (!IS_DEADLOCK_INTERVAL_PARAM_VALID(num)) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "_DEADLOCK_DETECT_INTERVAL");
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_verify_als_auto_undo_retention(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_verify_als_bool_only_sys_allowed(void *se, void *lex, void *def)
{
knl_session_t *session = (knl_session_t *)se;
if (session->uid != DB_SYS_USER_ID) {
OG_THROW_ERROR(ERR_INSUFFICIENT_PRIV);
return OG_ERROR;
}
return sql_verify_als_bool(se, lex, def);
}
status_t sql_notify_als_access_dc_enable_bool(void *se, void *item, char *value)
{
g_instance->attr.access_dc_enable = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
status_t sql_notify_als_view_access_dc_bool(void *se, void *item, char *value)
{
g_instance->attr.view_access_dc = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
status_t sql_verify_als_optimized_worker_threads(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num < OG_MIN_OPTIMIZED_WORKER_COUNT || num > OG_MAX_OPTIMIZED_WORKER_COUNT) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "OPTIMIZED_WORKER_THREADS");
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_verify_als_max_worker_threads(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num < OG_MIN_OPTIMIZED_WORKER_COUNT || num > OG_MAX_OPTIMIZED_WORKER_COUNT) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "MAX_WORKER_THREADS");
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_verify_als_agent_shrink_threshold(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num > OG_MAX_SECS_AGENTS_SHRINK) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_LARGE, "WORKER_THREADS_SHRINK_THRESHOLD", (int32)OG_MAX_SECS_AGENTS_SHRINK);
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_verify_als_db_tz(void *se, void *lex, void *def)
{
word_t value;
timezone_info_t dbtz_new;
knl_alter_sys_def_t *sys_def = (knl_alter_sys_def_t *)def;
char param_new_value[TIMEZONE_OFFSET_STRLEN] = { 0 };
text_t normal_tz;
OG_RETURN_IFERR(lex_expected_fetch_string(lex, &value));
sql_remove_quota(&value.text.value);
if (value.text.value.len >= OG_PARAM_BUFFER_SIZE) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_LARGE, sys_def->param, (int64)OG_PARAM_BUFFER_SIZE - 1);
return OG_ERROR;
}
OG_RETURN_IFERR(cm_text2tzoffset(&value.text.value, &dbtz_new));
normal_tz.str = param_new_value;
OG_RETURN_IFERR(cm_tzoffset2text(dbtz_new, &normal_tz));
OG_RETURN_IFERR(cm_text2str(&normal_tz, sys_def->value, OG_PARAM_BUFFER_SIZE));
return OG_SUCCESS;
}
status_t sql_verify_als_reactor_threads(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num == 0 || num > OG_MAX_REACTOR_POOL_COUNT) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "REACTOR_THREADS");
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_verify_super_user_sessions(void *se, void *lex, void *def)
{
uint32 num = 0;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num > OG_MAX_EMERG_SESSIONS) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_LARGE, "SUPER_USER_RESERVED_SESSIONS", (int64)OG_MAX_EMERG_SESSIONS);
return OG_ERROR;
}
if (num < 1) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_SMALL, "SUPER_USER_RESERVED_SESSIONS", (int64)1);
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_verify_normal_emerge_sess_factor(void *se, void *lex, void *def)
{
double num;
word_t word;
knl_alter_sys_def_t *sys_def = (knl_alter_sys_def_t *)def;
if (lex_expected_fetch((lex_t *)lex, &word) != OG_SUCCESS) {
return OG_ERROR;
}
if (word.type == WORD_TYPE_STRING) {
sql_remove_quota(&word.text.value);
}
if (word.type == WORD_TYPE_DQ_STRING) {
cm_trim_text(&word.text.value);
}
if (word.text.len == 0) {
OG_SRC_THROW_ERROR(word.loc, ERR_EMPTY_STRING_NOT_ALLOWED);
return OG_ERROR;
}
if (cm_text2real((text_t *)&word.text, &num)) {
return OG_ERROR;
}
OG_RETURN_IFERR(cm_text2str((text_t *)&word.text, sys_def->value, OG_PARAM_BUFFER_SIZE));
if (num > 1 || num < 0) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "NORMAL_USER_RESERVED_SESSIONS_FACTOR");
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_notify_als_normal_emerge_sess_factor(void *se, void *item, char *value)
{
return cm_str2real(value, &g_instance->kernel.attr.normal_emerge_sess_factor);
}
status_t sql_verify_als_sessions(void *se, void *lex, void *def)
{
uint32 num;
knl_alter_sys_def_t *sys_def = (knl_alter_sys_def_t *)def;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num <= g_instance->kernel.reserved_sessions + g_instance->sql_emerg_pool.max_sessions) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_SMALL, "SESSIONS",
(int64)(g_instance->kernel.reserved_sessions + g_instance->sql_emerg_pool.max_sessions + 1));
return OG_ERROR;
}
if (num > OG_MAX_SESSIONS) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_LARGE, "SESSIONS", (int64)OG_MAX_SESSIONS);
return OG_ERROR;
}
if (num <= g_instance->session_pool.expanded_max_sessions && num >= g_instance->session_pool.max_sessions) {
g_instance->session_pool.max_sessions = num;
return OG_SUCCESS;
}
OG_RETURN_IFERR(sql_parse_scope_clause(sys_def, (lex_t *)lex) != OG_SUCCESS);
if (sys_def->scope != CONFIG_SCOPE_DISK) {
OG_SET_HINT("[NOTICE]%s", "Use SCOPE=PFILE to take effect after reboot.");
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_verify_als_prefetch_rows(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num < 1) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_SMALL, "_PREFETCH_ROWS", (int64)1);
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_notify_als_prefetch_rows(void *se, void *item, char *value)
{
uint32 prefetch_rows = 0;
if (cm_str2uint32(value, &prefetch_rows) != OG_SUCCESS) {
return OG_ERROR;
}
if (prefetch_rows < 1) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_SMALL, "_PREFETCH_ROWS", (int64)1);
return OG_ERROR;
}
g_instance->sql.prefetch_rows = prefetch_rows;
return OG_SUCCESS;
}
status_t sql_notify_als_enable_arr_store_opt(void *se, void *item, char *value)
{
bool32 set_value = (bool32)value[0];
if (g_instance->sql.enable_arr_store_opt && !set_value) {
OG_SET_HINT("[NOTICE]%s", "parameter ARRAY_STORAGE_OPTIMIZATION is TRUE now,"
" and it is forbidden to set back to FALSE, or there is compatible problem for array data");
return OG_ERROR;
}
g_instance->sql.enable_arr_store_opt = set_value;
if (set_value) {
OG_LOG_RUN_WAR("parameter ARRAY_STORAGE_OPTIMIZATION has been setted to TRUE,"
" and it is forbidden to set back to FALSE, or there is compatible problem for array data");
}
return sql_notify_als_bool(se, item, value);
}
status_t sql_verify_json_dyn_buf_size(void *se, void *lex, void *def)
{
return sql_verify_pool_size(lex, def, OG_JSON_MIN_DYN_BUF_SIZE, OG_JSON_MAX_DYN_BUF_SIZE);
}
status_t sql_notify_json_dyn_buf_size(void *se, void *item, char *value)
{
int64 val_int64;
if (cm_str2size(value, &val_int64) != OG_SUCCESS) {
return OG_ERROR;
}
g_instance->sql.json_mpool.max_json_dyn_buf = (uint64)val_int64;
return OG_SUCCESS;
}
status_t sql_verify_als_encryption_alg(void *se, void *lex, void *def)
{
bool32 result = OG_FALSE;
const char *match_words = "SCRAM_SHA256";
knl_alter_sys_def_t *sys_def = (knl_alter_sys_def_t *)def;
if (lex_try_fetch(lex, match_words, &result) != OG_SUCCESS) {
return OG_ERROR;
}
if (!result) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "_ENCRYPTION_ALG");
return OG_ERROR;
}
MEMS_RETURN_IFERR(strcpy_s(sys_def->value, OG_PARAM_BUFFER_SIZE, match_words));
return OG_SUCCESS;
}
status_t sql_verify_als_sys_password(void *se, void *lex, void *def)
{
word_t word;
knl_alter_sys_def_t *sys_def = (knl_alter_sys_def_t *)def;
if (lex_expected_fetch((lex_t *)lex, &word) != OG_SUCCESS) {
return OG_ERROR;
}
if (word.type == WORD_TYPE_STRING) {
sql_remove_quota(&word.text.value);
}
OG_RETURN_IFERR(cm_text2str((text_t *)&word.text, sys_def->value, OG_PARAM_BUFFER_SIZE));
if (word.text.len == OG_KDF2MAXSTRSIZE) {
if (cm_convert_kdf2_scram_sha256(sys_def->value, sys_def->value, OG_PARAM_BUFFER_SIZE) != OG_SUCCESS) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "_SYS_PASSWORD");
return OG_ERROR;
}
} else if (!cm_is_password_valid(sys_def->value)) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "_SYS_PASSWORD");
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_notify_als_sys_password(void *se, void *item, char *value)
{
knl_session_t *session = (knl_session_t *)se;
if (session->uid != DB_SYS_USER_ID) {
OG_THROW_ERROR(ERR_INSUFFICIENT_PRIV);
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_verify_als_encrypt_iteration(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num < OG_KDF2MINITERATION) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_SMALL, "_ENCRYPTION_ITERATION", (int64)OG_KDF2MINITERATION);
return OG_ERROR;
} else if (num > OG_KDF2MAXITERATION) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_LARGE, "_ENCRYPTION_ITERATION", (int64)OG_KDF2MAXITERATION);
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_notify_als_encrypt_iteration(void *se, void *item, char *value)
{
uint32 val;
if (cm_str2uint32(value, &val) != OG_SUCCESS) {
return OG_ERROR;
}
g_instance->kernel.attr.alg_iter = val;
return OG_SUCCESS;
}
status_t sql_verify_als_factor_key(void *se, void *lex, void *def)
{
word_t word;
char buf[OG_AESBLOCKSIZE * 2];
char key_buf[OG_MAX_FACTOR_KEY_STR_LEN + 4];
knl_alter_sys_def_t *sys_def = (knl_alter_sys_def_t *)def;
if (lex_expected_fetch((lex_t *)lex, &word) != OG_SUCCESS) {
return OG_ERROR;
}
OG_RETURN_IFERR(sql_parse_scope_clause(sys_def, (lex_t *)lex));
if (sys_def->scope != CONFIG_SCOPE_BOTH) {
OG_THROW_ERROR(ERR_PARAMETER_NOT_MODIFIABLE, "_FACTOR_KEY");
return OG_ERROR;
}
if (word.type == WORD_TYPE_STRING) {
sql_remove_quota(&word.text.value);
}
OG_RETURN_IFERR(cm_text2str(&word.text.value, key_buf, sizeof(key_buf)));
if (word.text.value.len != OG_MAX_FACTOR_KEY_STR_LEN ||
cm_base64_decode(key_buf, word.text.value.len, (uchar *)buf, sizeof(buf)) == 0) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "_FACTOR_KEY");
return OG_ERROR;
}
return cm_text2str((text_t *)&word.text, sys_def->value, OG_PARAM_BUFFER_SIZE);
}
status_t sql_verify_als_local_key(void *se, void *lex, void *def)
{
word_t word;
char cipher[OG_PASSWORD_BUFFER_SIZE];
char key_buf[OG_MAX_LOCAL_KEY_STR_LEN_DOUBLE + 4];
uint32 cipher_len = sizeof(cipher);
char *factor_key = cm_get_config_value(&g_instance->config, "_FACTOR_KEY");
knl_alter_sys_def_t *sys_def = (knl_alter_sys_def_t *)def;
if (lex_expected_fetch((lex_t *)lex, &word) != OG_SUCCESS) {
cm_reset_error();
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "LOCAL_KEY");
return OG_ERROR;
}
OG_RETURN_IFERR(sql_parse_scope_clause(sys_def, (lex_t *)lex));
if (sys_def->scope != CONFIG_SCOPE_BOTH) {
OG_THROW_ERROR(ERR_PARAMETER_NOT_MODIFIABLE, "LOCAL_KEY");
return OG_ERROR;
}
if (word.type == WORD_TYPE_STRING) {
sql_remove_quota(&word.text.value);
}
OG_RETURN_IFERR(cm_text2str(&word.text.value, key_buf, sizeof(key_buf)));
if (word.text.value.len != OG_MAX_LOCAL_KEY_STR_LEN_DOUBLE || cm_encrypt_passwd(OG_TRUE, (char *)"sys",
SYS_USER_NAME_LEN, cipher, &cipher_len, key_buf, factor_key) != OG_SUCCESS) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "LOCAL_KEY");
return OG_ERROR;
}
return cm_text2str((text_t *)&word.text, sys_def->value, OG_PARAM_BUFFER_SIZE);
}
static status_t srv_update_ssl_key_passwd(char *old_fk, char *old_lk, char *new_fk, char *new_lk)
{
char *old_cipher = NULL;
char temp_plain_buf[OG_ENCRYPTION_SIZE + 1] = { 0 };
uint32 temp_plain_len = OG_ENCRYPTION_SIZE;
char new_cipher_buf[OG_ENCRYPTION_SIZE + 1] = { 0 };
uint32 new_cipher_len = OG_ENCRYPTION_SIZE;
old_cipher = srv_get_param("SSL_KEY_PASSWORD");
if (CM_IS_EMPTY_STR(old_cipher)) {
return OG_SUCCESS;
}
if (cm_decrypt_passwd(OG_TRUE, old_cipher, (uint32)strlen(old_cipher), temp_plain_buf, &temp_plain_len,
old_lk, old_fk) != OG_SUCCESS) {
OG_LOG_DEBUG_ERR("Decrypt ssl key password failed");
MEMS_RETURN_IFERR(memset_sp(temp_plain_buf, sizeof(temp_plain_buf), 0, sizeof(temp_plain_buf)));
return OG_SUCCESS;
}
temp_plain_buf[temp_plain_len] = '\0';
if (cm_encrypt_passwd(OG_TRUE, temp_plain_buf, temp_plain_len, new_cipher_buf, &new_cipher_len,
new_lk, new_fk) != OG_SUCCESS) {
OG_LOG_DEBUG_ERR("Re-encrypt ssl key password failed");
MEMS_RETURN_IFERR(memset_sp(temp_plain_buf, sizeof(temp_plain_buf), 0, sizeof(temp_plain_buf)));
return OG_SUCCESS;
}
MEMS_RETURN_IFERR(memset_sp(temp_plain_buf, sizeof(temp_plain_buf), 0, sizeof(temp_plain_buf)));
if (cm_alter_config(&g_instance->config, "SSL_KEY_PASSWORD", new_cipher_buf, CONFIG_SCOPE_BOTH, OG_TRUE) !=
OG_SUCCESS) {
return OG_ERROR;
}
return OG_SUCCESS;
}
static status_t srv_save_factor_key(const char *factor_key)
{
char file_name1[OG_FILE_NAME_BUFFER_SIZE];
char file_name2[OG_FILE_NAME_BUFFER_SIZE];
PRTS_RETURN_IFERR(snprintf_s(file_name1, OG_FILE_NAME_BUFFER_SIZE, OG_FILE_NAME_BUFFER_SIZE - 1, "%s/dbs/%s",
g_instance->home, OG_FKEY_FILENAME1));
PRTS_RETURN_IFERR(snprintf_s(file_name2, OG_FILE_NAME_BUFFER_SIZE, OG_FILE_NAME_BUFFER_SIZE - 1, "%s/dbs/%s",
g_instance->home, OG_FKEY_FILENAME2));
OG_RETURN_IFERR(srv_save_factor_key_file(file_name1, factor_key));
return srv_save_factor_key_file(file_name2, factor_key);
}
status_t sql_notify_als_factor_key(void *se, void *item, char *value)
{
char new_local_key[OG_MAX_LOCAL_KEY_STR_LEN_DOUBLE + 1];
char *old_factor_key = srv_get_param("_FACTOR_KEY");
char *new_factor_key = value;
char *old_local_key = srv_get_param("LOCAL_KEY");
if (cm_str_equal(old_factor_key, value)) {
return OG_SUCCESS;
}
* new root key FK must has a derived and matched work key LK, LK may be temporary
* for matched the root FK until execute SQL 'alter system set LOCAL_KEY = "XXX"'.
*/
OG_RETURN_IFERR(cm_generate_work_key(new_factor_key, new_local_key, sizeof(new_local_key)));
* firstly update FK, update ssl key passwd(cipher) with new FK assigned by user and LK assigned internally;
* save new FK and LK to config;
* secondly, update srv_update_ssl_key_passwd again, see sql_notify_als_local_key
* finally, ssl key passwd will be encrypted by user
*/
if (srv_update_ssl_key_passwd(old_factor_key, old_local_key, new_factor_key, new_local_key) != OG_SUCCESS) {
OG_THROW_ERROR(ERR_UPDATE_PARAMETER_FAIL, "_FACTOR_KEY", "re-encrypting SSL_KEY_PASSWORD error");
return OG_ERROR;
}
OG_RETURN_IFERR(cm_alter_config(&g_instance->config, "LOCAL_KEY", new_local_key, CONFIG_SCOPE_BOTH, OG_TRUE));
return srv_save_factor_key(new_factor_key);
}
status_t sql_notify_als_local_key(void *se, void *item, char *value)
{
config_item_t *it = (config_item_t *)item;
char *old_key = (it->is_default ? it->default_value : it->value);
char *old_or_new_factor_key = srv_get_param("_FACTOR_KEY");
if (cm_str_equal(old_key, value)) {
return OG_SUCCESS;
}
if (srv_update_ssl_key_passwd(old_or_new_factor_key, old_key, old_or_new_factor_key, value) != OG_SUCCESS) {
OG_THROW_ERROR(ERR_UPDATE_PARAMETER_FAIL, "LOCAL_KEY", "re-encrypting SSL_KEY_PASSWORD error");
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_notify_als_login_as_sysdba(void *se, void *item, char *value)
{
#if defined(_DEBUG) || defined(DEBUG) || defined(DB_DEBUG_VERSION)
g_instance->session_pool.enable_sysdba_login = (bool32)value[0];
#endif
OG_RETURN_IFERR(sql_notify_als_bool(se, item, value));
if (OG_TRUE == GET_ENABLE_SYSDBA_LOGIN) {
if (srv_init_sysdba_privilege() != OG_SUCCESS) {
OG_THROW_ERROR(ERR_PRIVS_NOT_GRANT, "sysdba", "logined user");
return OG_ERROR;
}
} else {
return srv_remove_sysdba_privilege();
}
return OG_SUCCESS;
}
status_t sql_notify_als_sys_remote_login(void *se, void *item, char *value)
{
g_instance->session_pool.enable_sys_remote_login = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
status_t sql_notify_als_sysdba_remote_login(void *se, void *item, char *value)
{
#if defined(_DEBUG) || defined(DEBUG) || defined(DB_DEBUG_VERSION)
g_instance->session_pool.enable_sysdba_remote_login = (bool32)value[0];
#endif
return sql_notify_als_bool(se, item, value);
}
status_t sql_notify_als_commit_on_disconn(void *se, void *item, char *value)
{
g_instance->sql.commit_on_disconn = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
status_t sql_notify_als_max_connect_by_level(void *se, void *item, char *value)
{
return cm_str2uint32(value, &g_instance->sql.max_connect_by_level);
}
status_t sql_verify_als_range_cache(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num < OG_MIN_OPT_THRESHOLD) {
OG_SRC_THROW_ERROR(((lex_t *)lex)->loc, ERR_PARAMETER_TOO_SMALL, "_INDEX_SCAN_RANGE_CACHE",
(int64)OG_MIN_OPT_THRESHOLD);
return OG_ERROR;
}
if (num > OG_MAX_OPT_THRESHOLD) {
OG_SRC_THROW_ERROR(((lex_t *)lex)->loc, ERR_PARAMETER_TOO_LARGE, "_INDEX_SCAN_RANGE_CACHE",
(int64)OG_MAX_OPT_THRESHOLD);
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_notify_als_min_range_cache(void *se, void *item, char *value)
{
return cm_str2uint32(value, &g_instance->sql.index_scan_range_cache);
}
status_t sql_notify_als_vm_view_mtrl(void *se, void *item, char *value)
{
g_instance->sql.vm_view_enabled = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
status_t sql_notify_als_enable_password_cipher(void *se, void *item, char *value)
{
g_instance->sql.enable_password_cipher = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
status_t sql_verify_als_max_allowed_packet(void *se, void *lex, void *def)
{
return sql_verify_pool_size(lex, def, OG_MAX_PACKET_SIZE, OG_MAX_ALLOWED_PACKET_SIZE);
}
status_t sql_notify_als_max_allowed_packet(void *se, void *item, char *value)
{
int64 size = 0;
OG_RETURN_IFERR(cm_str2size(value, &size));
g_instance->attr.max_allowed_packet = (uint32)size;
return OG_SUCCESS;
}
status_t sql_notify_als_parallel_policy(void *se, void *item, char *value)
{
if (g_instance->sql.parallel_policy != (bool32)value[0]) {
g_instance->sql.parallel_policy = (bool32)value[0];
}
return sql_notify_als_onoff(se, item, value);
}
status_t sql_verify_als_interactive_timeout(void *se, void *lex, void *def)
{
uint32 num;
OG_RETURN_IFERR(sql_verify_uint32(lex, def, &num));
if (num == 0) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_SMALL, "INTERACTIVE_TIMEOUT", (int64)1);
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_notify_als_interactive_timeout(void *se, void *item, char *value)
{
uint32 timeout = 0;
OG_RETURN_IFERR(cm_str2uint32(value, &timeout));
g_instance->sql.interactive_timeout = (uint32)timeout;
return OG_SUCCESS;
}
status_t sql_notify_zero_divisor_accepted(void *se, void *item, char *value)
{
#if defined(_DEBUG) || defined(DEBUG) || defined(DB_DEBUG_VERSION)
g_opr_options.div0_accepted = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
#else
OG_THROW_ERROR(ERR_NOT_COMPATIBLE, "ZERO_DIVISOR_ACCEPTED");
return OG_ERROR;
#endif
}
status_t sql_notify_string_as_hex_binary(void *se, void *item, char *value)
{
#if defined(_DEBUG) || defined(DEBUG) || defined(DB_DEBUG_VERSION)
g_instance->sql.string_as_hex_binary = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
#else
OG_THROW_ERROR(ERR_NOT_COMPATIBLE, "STRING_AS_HEX_FOR_BINARY");
return OG_ERROR;
#endif
}
status_t sql_notify_als_enable_err_superposed(void *se, void *item, char *value)
{
g_enable_err_superposed = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
status_t sql_notify_als_unauth_session_expire_time(void *se, void *item, char *value)
{
uint32 val;
if (cm_str2uint32(value, &val) != OG_SUCCESS) {
return OG_ERROR;
}
g_instance->session_pool.unauth_session_expire_time = val;
return OG_SUCCESS;
}
status_t sql_notify_empty_string_null(void *se, void *item, char *value)
{
#if defined(_DEBUG) || defined(DEBUG) || defined(DB_DEBUG_VERSION)
g_instance->sql.enable_empty_string_null = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
#else
OG_THROW_ERROR(ERR_NOT_COMPATIBLE, "EMPTY_STRING_AS_NULL");
return OG_ERROR;
#endif
}
status_t sql_notify_als_master_backup_synctime(void *se, void *item, char *value)
{
uint32 size = 0;
OG_RETURN_IFERR(cm_str2uint32(value, &size));
g_instance->attr.master_slave_difftime = size * MILLISECS_PER_SECOND * MICROSECS_PER_MILLISEC;
return OG_SUCCESS;
}
status_t sql_notify_als_deadlock_detect_interval(void *se, void *item, char *value)
{
uint32 val;
if (cm_str2uint32(value, &val) != OG_SUCCESS) {
return OG_ERROR;
}
g_instance->kernel.attr.deadlock_detect_interval = val;
return OG_SUCCESS;
}
status_t sql_notify_als_auto_undo_retention(void *se, void *item, char *value)
{
uint32 val;
if (cm_str2uint32(value, &val) != OG_SUCCESS) {
return OG_ERROR;
}
g_instance->kernel.attr.auto_undo_retention = val;
if (g_instance->kernel.attr.auto_undo_retention == 0) {
OG_LOG_RUN_INF("_set_undo_retention %u -> %u \n", g_instance->kernel.undo_ctx.retention,
g_instance->kernel.attr.undo_retention_time);
g_instance->kernel.undo_ctx.retention = g_instance->kernel.attr.undo_retention_time;
}
if (g_instance->kernel.attr.auto_undo_retention > g_instance->kernel.attr.undo_retention_time) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_LARGE, "auto_undo_retention", g_instance->kernel.attr.undo_retention_time);
return OG_ERROR;
}
if (g_instance->kernel.attr.auto_undo_retention > g_instance->kernel.undo_ctx.retention) {
OG_LOG_RUN_INF("_set_undo_retention %u -> %u \n", g_instance->kernel.undo_ctx.retention, val);
g_instance->kernel.undo_ctx.retention = g_instance->kernel.attr.auto_undo_retention;
}
return OG_SUCCESS;
}
status_t sql_notify_als_res_recycle_ratio(void *se, void *item, char *value)
{
return cm_str2uint32(value, &g_instance->kernel.attr.res_recycle_ratio);
}
status_t sql_notify_als_create_index_parallelism(void *se, void *item, char *value)
{
return cm_str2uint32(value, &g_instance->kernel.attr.create_index_parallelism);
}
status_t sql_verify_als_sga_core_dump_config(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
cm_reset_error();
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "_SGA_CORE_DUMP_CONFIG");
return OG_ERROR;
}
if (num > OG_MAX_SGA_CORE_DUMP_CONFIG) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "_SGA_CORE_DUMP_CONFIG");
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_notify_als_sga_core_dump_config(void *se, void *item, char *value)
{
return cm_str2uint32(value, &g_instance->attr.core_dump_config);
}
status_t sql_verify_als_job_queue_processes(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num > OG_MAX_JOB_THREADS) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "JOB_THREADS");
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_verify_als_xa_format_id(void *se, void *lex, void *def)
{
knl_alter_sys_def_t *sys_def = (knl_alter_sys_def_t *)def;
OG_THROW_ERROR(ERR_ALTER_READONLY_PARAMETER, sys_def->param);
return OG_ERROR;
}
status_t sql_notify_enable_local_infile(void *se, void *item, char *value)
{
g_instance->attr.enable_local_infile = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
status_t sql_notify_als_enable_permissive_unicode(void *se, void *item, char *value)
{
g_instance->attr.enable_permissive_unicode = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
status_t sql_notify_als_disable_var_peek(void *se, void *item, char *value)
{
g_instance->attr.disable_var_peek = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
static status_t sql_verify_interconnect_port(lex_t *lex, char *portstr, uint32 len)
{
uint32 port_len = 0;
uint32 port_count = 0;
char *port = portstr;
uint16 value;
char *pos = NULL;
uint32 tmp_len = len;
for (pos = portstr; tmp_len > 0; tmp_len--) {
if (*pos != ',') {
port_len++;
pos++;
continue;
}
*pos = '\0';
if (cm_str2uint16(port, &value) != OG_SUCCESS) {
cm_reset_error();
OG_SRC_THROW_ERROR(((lex_t *)lex)->loc, ERR_INVALID_PARAMETER, "port");
return OG_ERROR;
}
if (value < OG_MIN_PORT) {
OG_SRC_THROW_ERROR(((lex_t *)lex)->loc, ERR_PARAMETER_TOO_SMALL, "port", (int64)OG_MIN_PORT);
return OG_ERROR;
}
*pos = ',';
port += (port_len + 1);
port_count++;
port_len = 0;
pos = port;
}
if (port_len > 0) {
if (cm_str2uint16(port, &value) != OG_SUCCESS) {
cm_reset_error();
OG_SRC_THROW_ERROR(((lex_t *)lex)->loc, ERR_INVALID_PARAMETER, "port");
return OG_ERROR;
}
if (value < OG_MIN_PORT) {
OG_SRC_THROW_ERROR(((lex_t *)lex)->loc, ERR_PARAMETER_TOO_SMALL, "port", (int64)OG_MIN_PORT);
return OG_ERROR;
}
}
return OG_SUCCESS;
}
status_t sql_verify_als_interconnect_port(void *se, void *lex, void *def)
{
word_t word;
knl_alter_sys_def_t *sys_def = (knl_alter_sys_def_t *)def;
if (lex_expected_fetch((lex_t *)lex, &word) != OG_SUCCESS) {
return OG_ERROR;
}
if (word.type == WORD_TYPE_STRING) {
sql_remove_quota(&word.text.value);
}
cm_trim_text((text_t *)&word.text);
cm_text2str((text_t *)&word.text, sys_def->value, OG_PARAM_BUFFER_SIZE);
return sql_verify_interconnect_port((lex_t *)lex, sys_def->value, (uint32)strlen(sys_def->value));
}
status_t sql_verify_als_interconnect_type(void *se, void *lex, void *def)
{
OG_THROW_ERROR(ERR_PARAMETER_NOT_MODIFIABLE, "INTERCONNECT_TYPE");
return OG_ERROR;
}
status_t sql_verify_als_remote_access_limit(void *se, void *lex, void *def)
{
uint32 num;
if (sql_verify_uint32(lex, def, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num > OG_REMOTE_ACCESS_LIMIT) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_LARGE, "_REMOTE_ACCESS_LIMIT", (int64)OG_REMOTE_ACCESS_LIMIT);
return OG_ERROR;
}
return OG_SUCCESS;
}
status_t sql_notify_als_mes_elapsed_switch(void *se, void *item, char *value)
{
mes_set_elapsed_switch(value[0]);
return sql_notify_als_bool(se, item, value);
}
status_t sql_notify_als_enable_tx_free_page_list(void *se, void *item, char *value)
{
g_instance->kernel.attr.enable_tx_free_page_list = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
status_t sql_notify_als_enable_rmo_cr(void *se, void *item, char *value)
{
g_dtc->profile.enable_rmo_cr = (bool32)value[0];
return sql_notify_als_bool(se, item, value);
}
status_t sql_notify_als_remote_access_limit(void *se, void *item, char *value)
{
uint32 num;
if (cm_str2uint32(value, &num) != OG_SUCCESS) {
return OG_ERROR;
}
if (num > OG_REMOTE_ACCESS_LIMIT) {
OG_THROW_ERROR(ERR_PARAMETER_TOO_LARGE, "_REMOTE_ACCESS_LIMIT", (int64)OG_REMOTE_ACCESS_LIMIT);
return OG_ERROR;
}
g_dtc->profile.remote_access_limit = num;
return OG_SUCCESS;
}
status_t sql_notify_als_gdv_sess_tmout(void *se, void *item, char *value)
{
return cm_str2uint32(value, &g_dtc->profile.gdv_sql_sess_tmout);
}
status_t sql_verify_als_mes_task_ratio(void *se, void *lex, void *def)
{
double num;
word_t word;
knl_alter_sys_def_t *sys_def = (knl_alter_sys_def_t *)def;
if (lex_expected_fetch((lex_t *)lex, &word) != OG_SUCCESS) {
return OG_ERROR;
}
if (word.type == WORD_TYPE_STRING) {
sql_remove_quota(&word.text.value);
}
if (word.type == WORD_TYPE_DQ_STRING) {
cm_trim_text(&word.text.value);
}
if (word.text.len == 0) {
OG_SRC_THROW_ERROR(word.loc, ERR_EMPTY_STRING_NOT_ALLOWED);
return OG_ERROR;
}
if (cm_text2real((text_t *)&word.text, &num)) {
return OG_ERROR;
}
cm_text2str((text_t *)&word.text, sys_def->value, OG_PARAM_BUFFER_SIZE);
if (num > OG_MES_MAX_TASK_RATIO || num < OG_MES_MIN_TASK_RATIO) {
OG_THROW_ERROR(ERR_INVALID_PARAMETER, "MES_TASK_RATIO");
return OG_ERROR;
}
return OG_SUCCESS;
}
#ifdef __cplusplus
}
#endif