* 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.
* -------------------------------------------------------------------------
*
* ogsql_aggr.h
*
*
* IDENTIFICATION
* src/ogsql/executor/ogsql_aggr.h
*
* -------------------------------------------------------------------------
*/
#ifndef __SQL_AGGR_H__
#define __SQL_AGGR_H__
#include "ogsql_func.h"
#include "dml_executor.h"
#include "var_inc.h"
#include "func_aggr.h"
#include "opr_add.h"
typedef struct st_aggr_dense_rank {
hash_segment_t hash_segment;
hash_table_entry_t table_entry;
} aggr_dense_rank_t;
typedef struct st_aggr_assist {
sql_stmt_t *stmt;
sql_cursor_t *cursor;
expr_node_t *aggr_node;
sql_aggr_type_t aggr_type;
uint64 avg_count;
} aggr_assist_t;
typedef status_t (*aggr_alloc_buf_func_t)(aggr_assist_t *ass, aggr_var_t *aggr_var);
typedef status_t (*aggr_init_var_func_t)(aggr_assist_t *ass, aggr_var_t *aggr_var);
typedef status_t (*aggr_reset_func_t)(aggr_var_t *aggr_var);
typedef status_t (*aggr_proc_func_t)(aggr_assist_t *ass, aggr_var_t *aggr_var, variant_t *value);
typedef status_t (*aggr_calc_func_t)(aggr_assist_t *ass, aggr_var_t *aggr_var);
typedef struct st_aggr_func {
sql_aggr_type_t aggr_type;
aggr_alloc_buf_func_t alloc;
aggr_init_var_func_t init;
aggr_reset_func_t reset;
aggr_proc_func_t invoke;
aggr_calc_func_t calc;
} aggr_func_t;
extern aggr_func_t g_aggr_func_tab[];
static inline aggr_func_t *sql_get_aggr_func(sql_aggr_type_t type)
{
return &g_aggr_func_tab[type];
}
static inline status_t sql_aggr_alloc_buf(aggr_assist_t *ass, aggr_var_t *aggr_var)
{
return (&g_aggr_func_tab[ass->aggr_type])->alloc(ass, aggr_var);
}
static inline status_t sql_aggr_init_var(aggr_assist_t *ass, aggr_var_t *aggr_var)
{
return (&g_aggr_func_tab[ass->aggr_type])->init(ass, aggr_var);
}
static inline status_t sql_aggr_reset(aggr_assist_t *ass, aggr_var_t *aggr_var)
{
return (&g_aggr_func_tab[ass->aggr_type])->reset(aggr_var);
}
static inline status_t sql_aggr_invoke(aggr_assist_t *ass, aggr_var_t *aggr_var, variant_t *value)
{
return (&g_aggr_func_tab[ass->aggr_type])->invoke(ass, aggr_var, value);
}
static inline status_t sql_aggr_calc_value(aggr_assist_t *ass, aggr_var_t *aggr_var)
{
return (&g_aggr_func_tab[ass->aggr_type])->calc(ass, aggr_var);
}
static inline bool32 is_ancestor_res_rowid(expr_node_t *exprn)
{
return NODE_IS_RES_ROWID(exprn) && ROWID_NODE_ANCESTOR(exprn) > 0;
}
#define SQL_INIT_AGGR_ASSIST(ass, _stmt_, _cursor_) \
do { \
(ass)->stmt = (sql_stmt_t *)(_stmt_); \
(ass)->cursor = (sql_cursor_t *)(_cursor_); \
(ass)->aggr_node = NULL; \
(ass)->aggr_type = AGGR_TYPE_NONE; \
(ass)->avg_count = 0; \
} while (0)
void clean_mtrl_seg(sql_stmt_t *stmt, sql_cursor_t *cursor);
status_t sql_aggr_value(aggr_assist_t *ogsql_stmt, uint32 id, variant_t *value);
status_t sql_aggr_get_cntdis_value(sql_stmt_t *stmt, galist_t *cntdis_columns, expr_node_t *aggr_node,
variant_t *value);
status_t sql_execute_aggr(sql_stmt_t *stmt, sql_cursor_t *cursor, plan_node_t *plan);
status_t sql_execute_index_aggr(sql_stmt_t *stmt, sql_cursor_t *cursor, plan_node_t *plan);
status_t sql_init_aggr_values(sql_stmt_t *stmt, sql_cursor_t *cursor, plan_node_t *plan, galist_t *aggrs, uint32 *avgs);
status_t sql_fetch_aggr(sql_stmt_t *stmt, sql_cursor_t *cursor, plan_node_t *plan, bool32 *eof);
status_t sql_exec_aggr(sql_stmt_t *stmt, sql_cursor_t *cursor, galist_t *aggrs, plan_node_t *plan);
status_t sql_exec_aggr_extra(sql_stmt_t *stmt, sql_cursor_t *cursor, galist_t *aggrs, plan_node_t *plan);
status_t sql_compare_sort_row_for_rank(sql_stmt_t *ogsql_stmt, expr_node_t *aggr_node, bool32 *flag);
static inline aggr_var_t *sql_get_aggr_addr(sql_cursor_t *cursor, uint32 id)
{
mtrl_cursor_t *mtrl_cursor = &cursor->mtrl.cursor;
if (mtrl_cursor->type == MTRL_CURSOR_HASH_GROUP || mtrl_cursor->type == MTRL_CURSOR_SORT_GROUP) {
return (aggr_var_t *)(mtrl_cursor->hash_group.aggrs + id * sizeof(aggr_var_t));
} else {
aggr_var_t *vars = (aggr_var_t *)((char *)cursor->aggr_page + sizeof(mtrl_page_t));
return &vars[id];
}
}
#define GET_AGGR_FUNC(aggr_node) ((const sql_func_t *)&g_func_tab[(aggr_node)->value.v_func.func_id])
static inline expr_node_t *sql_get_aggr_node(const sql_func_t *func, expr_node_t *aggr_node)
{
* equivalent to compute aggr values by aggr_node->argument->root, which is more
* efficient than directly starting from aggr_node */
return (func->invoke == sql_func_normal_aggr) ? aggr_node->argument->root : aggr_node;
}
#define AGGR_VALUE_NODE(func, aggr_node) sql_get_aggr_node(func, aggr_node)
static inline char *sql_get_aggr_free_start_addr(sql_cursor_t *cursor)
{
return (char *)((char *)cursor->aggr_page + cursor->aggr_page->free_begin);
}
static inline status_t sql_aggr_sum_value(sql_stmt_t *stmt, variant_t *v_aggr, variant_t *v_add)
{
if (OG_IS_NUMBER_TYPE(v_aggr->type)) {
if (OG_IS_NUMBER_TYPE(v_add->type)) {
return cm_dec_add(&v_aggr->v_dec, &v_add->v_dec, &v_aggr->v_dec);
}
} else if (v_aggr->type == OG_TYPE_BIGINT) {
if (v_add->type == OG_TYPE_INTEGER) {
return opr_bigint_add(v_aggr->v_bigint, (int64)v_add->v_int, &v_aggr->v_bigint);
}
}
return opr_exec(OPER_TYPE_ADD, SESSION_NLS(stmt), v_aggr, v_add, v_aggr);
}
status_t og_sql_aggr_get_value(sql_stmt_t *statement, uint32 id, variant_t *value);
status_t sql_init_aggr_page(sql_stmt_t *stmt, sql_cursor_t *cursor, galist_t *aggrs);
status_t sql_mtrl_aggr(sql_stmt_t *stmt, sql_cursor_t *cursor, plan_node_t *plan, bool32 par_exe_flag);
#endif