* 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.
* -------------------------------------------------------------------------
*
* ple_common.h
*
*
* IDENTIFICATION
* src/ogsql/pl/executor/ple_common.h
*
* -------------------------------------------------------------------------
*/
#ifndef __PLE_COMMON_H__
#define __PLE_COMMON_H__
#include "ast.h"
#include "pl_dc_util.h"
#include "ple_coverage.h"
#include "srv_instance.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct st_ple_var {
plv_decl_t *decl;
variant_t value;
typmode_t exec_type;
variant_t temp;
} ple_var_t;
typedef struct st_ple_variant_array {
uint32 count;
ple_var_t **items;
} ple_varmap_t;
typedef struct ple_stack_anchor {
#ifdef TEST_MEM
uint32 stack_depth;
#endif
uint32 heap_offset;
uint32 push_offset;
} ple_stack_anchor_t;
typedef struct st_ple_block {
pl_line_ctrl_t *entry;
ple_varmap_t var_map;
ple_stack_anchor_t anchor;
pl_exec_exception_t *curr_except;
} ple_block_t;
#define PLE_MAX_BLOCK_DEPTH (PL_MAX_BLOCK_DEPTH * 2)
typedef struct st_ple_block_stack {
ple_block_t *items[PLE_MAX_BLOCK_DEPTH];
uint16 depth;
} ple_block_stack_t;
typedef struct st_trig_executor {
uint32 trig_event;
void *data;
knl_cursor_t *knl_cur;
} trig_executor_t;
typedef struct st_cond_exec_stack {
uint32 depth;
uint32 items[PLE_MAX_BLOCK_DEPTH];
} cond_exec_stack_t;
#define COND_TRUE 1
#define COND_FALSE 0
#define CURR_COND_EXEC_DEPTH(exec) ((exec)->cond_exec.depth)
#define CURR_COND_EXEC(exec) \
(((exec)->cond_exec.depth == 0) ? OG_INVALID_ID32 : (exec)->cond_exec.items[(exec)->cond_exec.depth - 1])
#define PUSH_COND_EXEC(cond, exec) \
do { \
(exec)->cond_exec.items[(exec)->cond_exec.depth] = (cond); \
(exec)->cond_exec.depth++; \
} while (0)
#define POP_COND_EXEC(exec) \
do { \
if ((exec)->cond_exec.depth > 0) { \
(exec)->cond_exec.depth--; \
} \
} while (0)
#define UPDATE_COND_EXEC(cond, exec) \
do { \
if ((exec)->cond_exec.depth > 0) { \
(exec)->cond_exec.items[(exec)->cond_exec.depth - 1] = (cond); \
} \
} while (0)
typedef struct st_selector_exec_stack {
uint32 depth;
variant_t *items[PLE_MAX_BLOCK_DEPTH];
} selector_exec_stack_t;
#define CURR_SELECTOR_EXEC_DEPTH(exec) ((exec)->selector_exec.depth)
#define CURR_SELECTOR_EXEC(exec) \
(((exec)->selector_exec.depth == 0) ? NULL : (exec)->selector_exec.items[(exec)->selector_exec.depth - 1])
#define PUSH_SELECTOR_EXEC(var, exec) \
do { \
(exec)->selector_exec.items[(exec)->selector_exec.depth] = (var); \
(exec)->selector_exec.depth++; \
} while (0)
#define POP_SELECTOR_EXEC(exec) \
do { \
if ((exec)->selector_exec.depth > 0) { \
(exec)->selector_exec.depth--; \
} \
} while (0)
#define UPDATE_SELECTOR_EXEC(var) \
do { \
if (exec->selector_exec.depth > 0) { \
exec->selector_exec.items[exec->selector_exec.depth - 1] = (var); \
} \
} while (0)
typedef struct st_pl_executor {
ple_block_stack_t block_stack;
uint32 stack_base;
pl_entity_t *entity;
pl_line_ctrl_t *curr_line;
pl_line_ctrl_t *start_line;
trig_executor_t *trig_exec;
cond_exec_stack_t cond_exec;
selector_exec_stack_t selector_exec;
source_location_t sql_loc;
union {
uint64 combine64;
struct {
uint32 is_raised : 1;
uint32 sql_executed : 1;
uint32 err_buf_full : 1;
uint32 err_stack_full : 1;
uint32 err_except_acc : 1;
uint32 is_dyncur : 1;
uint32 error_tracked : 1;
uint32 unused : 25;
uint16 err_buf_pos;
uint16 err_stack_pos;
};
};
uint32 recent_rows;
char err_buf[OG_MESSAGE_BUFFER_SIZE];
char err_stack[OG_MESSAGE_BUFFER_SIZE];
pl_exec_exception_t exec_except;
uint32 return_cursor_stmt;
ple_coverage_t *coverage;
sql_stmt_t *dynamic_parent;
union {
galist_t *curr_input;
galist_t *using_values;
};
sql_array_t svpts;
pl_line_begin_t *body;
var_udo_t *obj;
} pl_executor_t;
typedef struct st_vbuf_assist {
sql_stmt_t *stmt;
uint32 id;
uint32 *total_len;
uint32 type;
} vbuf_assist_t;
ple_var_t *ple_get_plvar(pl_executor_t *executor, plv_id_t vid);
variant_t *ple_get_value(sql_stmt_t *stmt, plv_id_t vid);
status_t ple_get_output_plvar(pl_executor_t *exec, pl_into_t *into, ple_var_t **left, uint32 index);
status_t ple_get_dynsql_parent(sql_stmt_t *stmt, sql_stmt_t **parent);
status_t pl_init_sequence(sql_stmt_t *stmt);
status_t ple_init_executor(pl_executor_t *executor, sql_stmt_t *stmt);
status_t ple_prepare_pl_cursors(sql_stmt_t *stmt, bool8 *is_curs_prepare);
status_t ple_begin_auton_rm(session_t *session);
status_t ple_end_auton_rm(session_t *session);
void ple_send_error(sql_stmt_t *stmt);
void ple_set_error(sql_stmt_t *stmt, text_t *user, text_t *name, source_location_t *err_loc);
void ple_update_error_stack(sql_stmt_t *stmt, text_t *user, text_t *name, source_location_t *err_location);
void ple_check_error(sql_stmt_t *stmt);
void ple_update_exec_error(sql_stmt_t *stmt, source_location_t *err_location);
void ple_check_exec_error(sql_stmt_t *stmt, source_location_t *err_location);
void ple_update_func_error(sql_stmt_t *stmt, expr_node_t *node);
#define PLE_RESET_EXEC_ERR(exec) \
do { \
(exec)->err_stack_pos = 0; \
(exec)->err_buf_pos = 0; \
(exec)->err_buf_full = OG_FALSE; \
(exec)->err_stack_full = OG_FALSE; \
(exec)->err_stack[0] = '\0'; \
(exec)->err_buf[0] = '\0'; \
} while (0)
#define PLE_MAX_CURSORS (g_instance->attr.open_cursors)
sql_stmt_t *ple_ref_cursor_get(sql_stmt_t *stmt, pl_cursor_slot_t *ref_cursor);
bool32 sql_is_pl_exec(sql_stmt_t *stmt);
#define PLE_DEFAULT_EXPR(v) (v)->decl->default_expr
#define PLE_CURR_BLOCK(exec) ((exec)->block_stack.items[(exec)->block_stack.depth - 1])
#define PLE_CHECK_NONE 0x0
#define PLE_CHECK_OUT 0x1
#define PLE_CHECK_IN 0x2
#define PLE_SAVE_STMT(stmt) \
ack_sender_t *__sender__ = (stmt)->session->sender; \
sql_audit_t __audit__ = (stmt)->session->sql_audit; \
sql_stmt_t *__stmt__ = (stmt)->session->current_stmt; \
OGSQL_SAVE_STACK(stmt);
#define PLE_RESTORE_STMT(stmt) \
do { \
(stmt)->session->sender = __sender__; \
(stmt)->session->sql_audit = __audit__; \
(stmt)->session->current_stmt = __stmt__; \
OGSQL_RESTORE_STACK(stmt); \
} while (0)
#define PLE_CURSOR_SLOT_GET(v) ((pl_cursor_slot_t *)((v)->value.v_cursor.ref_cursor))
#define PLV_IS_COMPLEX_TYPE(type) \
((type) == PLV_RECORD || (type) == PLV_COLLECTION || (type) == PLV_OBJECT || (type) == PLV_ARRAY)
status_t pl_check_trig_and_udf(sql_stmt_t *stmt);
status_t ple_copy_variant(sql_stmt_t *stmt, variant_t *src, variant_t *dst, typmode_t type);
status_t ple_move_value(sql_stmt_t *stmt, variant_t *right, ple_var_t *left);
void ple_cursor_dec_refcount(sql_stmt_t *stmt, variant_t *dst, bool32 is_free);
status_t ple_calc_object_dft(sql_stmt_t *stmt, plv_object_t *plv_obj, variant_t *value);
status_t ple_calc_record_dft(sql_stmt_t *stmt, plv_record_t *plv_record, variant_t *value);
status_t ple_calc_dft(sql_stmt_t *stmt, ple_var_t *var);
status_t ple_calc_param_dft(sql_stmt_t *stmt, ple_var_t *var);
status_t ple_push_decl_element(sql_stmt_t *stmt, galist_t *decl_list, ple_varmap_t *var_map, bool32 calc_dft);
status_t ple_get_dynsql_using_expr(sql_stmt_t *stmt, uint32 pnid, pl_using_expr_t **using_expr);
status_t ple_get_using_expr_var(sql_stmt_t *stmt, pl_using_expr_t *using_expr, ple_var_t **var, uint32 flag);
status_t ple_get_using_expr_value(sql_stmt_t *stmt, pl_using_expr_t *using_expr, variant_t *res, uint32 flag);
status_t ple_get_dynsql_param_dir(sql_stmt_t *stmt, uint32 id, uint32 *dir);
bool32 ple_get_curr_except(pl_executor_t *exec, pl_exec_exception_t **curr_except);
void ple_save_stack_anchor(sql_stmt_t *stmt, ple_stack_anchor_t *anchor);
status_t ple_push_block(sql_stmt_t *stmt, pl_line_ctrl_t *entry, ple_varmap_t *var_map, ple_stack_anchor_t anchor);
void ple_close_cursor(sql_stmt_t *stmt, pl_cursor_slot_t *ref_cursor);
status_t ple_check_rollback(pl_executor_t *exec, text_t *svpt, source_location_t *loc);
status_t ple_store_savepoint(sql_stmt_t *stmt, pl_executor_t *exec, text_t *svpt);
status_t ple_fork_stmt(sql_stmt_t *stmt, sql_stmt_t **sub_stmt);
status_t ple_fork_executor_core(sql_stmt_t *stmt, sql_stmt_t *sub_stmt);
void ple_pop_block(sql_stmt_t *stmt, pl_executor_t *exec);
void ple_inherit_substmt_error(sql_stmt_t *stmt, sql_stmt_t *sub_stmt);
#ifdef __cplusplus
}
#endif
#endif