* 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.
* -------------------------------------------------------------------------
*
* plan_rbo.c
*
*
* IDENTIFICATION
* src/ogsql/plan/plan_rbo.c
*
* -------------------------------------------------------------------------
*/
#include "plan_rbo.h"
#include "ogsql_verifier.h"
#include "ogsql_func.h"
#include "dml_parser.h"
#include "knl_dc.h"
#include "cbo_base.h"
#include "ogsql_scan.h"
#include "srv_instance.h"
#include "plan_query.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline void sql_set_func_arg_name(expr_node_t *column, expr_node_t *func)
{
expr_tree_t *arg = func->argument;
while (arg != NULL) {
if (arg->root != NULL && arg->root->type == EXPR_NODE_COLUMN &&
arg->root->value.v_col.col == column->value.v_col.col) {
arg->root->word = column->word;
break;
}
arg = arg->next;
}
}
static bool32 rbo_find_column_in_func_args(query_field_t *query_field, knl_index_desc_t *index, uint16 idx_id)
{
knl_icol_info_t *col_info = &index->columns_info[idx_id];
for (uint16 j = 0; j < col_info->arg_count; j++) {
if (col_info->arg_cols[j] == query_field->col_id) {
return OG_TRUE;
}
}
return OG_FALSE;
}
bool32 rbo_find_column_in_func_index(query_field_t *query_field, knl_index_desc_t *index, sql_table_t *table)
{
for (uint16 i = 0; i < index->column_count; i++) {
if (index->columns[i] < DC_VIRTUAL_COL_START) {
if (index->columns[i] == query_field->col_id) {
return OG_TRUE;
}
} else if (rbo_find_column_in_func_args(query_field, index, i)) {
return OG_TRUE;
}
}
return OG_FALSE;
}
bool32 chk_part_key_match_index(dc_entity_t *entity, uint32 part_key_count, knl_index_desc_t *index, uint16 equal_to)
{
for (uint16 i = 0; i < part_key_count; ++i) {
uint16 part_key_col = knl_part_key_column_id(entity, i);
uint16 idx_id = OG_INVALID_ID16;
for (uint16 j = 0; j < index->column_count; j++) {
if (index->columns[j] == part_key_col) {
idx_id = j;
break;
}
}
if (idx_id == OG_INVALID_ID16) {
return OG_FALSE;
}
if (idx_id < equal_to) {
continue;
}
if (equal_to + i != idx_id) {
return OG_FALSE;
}
}
return OG_TRUE;
}
static inline status_t sql_de_adjust_node_type(visit_assist_t *visit_ass, expr_node_t **node)
{
if ((*node)->type == EXPR_NODE_DIRECT_COLUMN) {
(*node)->value.v_col.tab = (uint16)visit_ass->result0;
(*node)->type = EXPR_NODE_COLUMN;
}
return OG_SUCCESS;
}
void rbo_update_column_in_func(sql_stmt_t *stmt, expr_node_t **node, uint32 table_id)
{
visit_assist_t visit_ass;
sql_init_visit_assist(&visit_ass, stmt, NULL);
visit_ass.result0 = table_id;
(void)visit_expr_node(&visit_ass, node, sql_de_adjust_node_type);
}
status_t sql_get_index_col_node(sql_stmt_t *stmt, knl_column_t *knl_col, expr_node_t *column_node, expr_node_t **node,
uint32 table_id, uint32 col_id)
{
if (!KNL_COLUMN_IS_VIRTUAL(knl_col)) {
column_node->value.v_col.ancestor = 0;
column_node->value.v_col.tab = table_id;
column_node->value.v_col.col = (uint16)col_id;
column_node->value.v_col.datatype = knl_col->datatype;
column_node->datatype = knl_col->datatype;
column_node->type = EXPR_NODE_COLUMN;
column_node->unary = UNARY_OPER_NONE;
*node = column_node;
} else {
OG_RETURN_IFERR(
sql_clone_expr_node((void *)stmt, ((expr_tree_t *)knl_col->default_expr)->root, node, sql_stack_alloc));
rbo_update_column_in_func(stmt, node, table_id);
}
return OG_SUCCESS;
}
* \brief Covert a variant into ROWNUM type. When a ROWNUM is in comparison operation,
* we need to convert another operand into rownum type. The default ROWNUM type is
* INT32, however, some users may provides a double type for ROWNUM comparison.
*
*/
static inline status_t var_as_rownum(variant_t *var, og_type_t type)
{
if (type == OG_TYPE_REAL) {
return var_as_real(var);
} else {
return var_as_integer(var);
}
}
#define CONVER_VAR_TO_ROWNUM_TYPE(var, type) \
if (var_as_rownum(var, type) != OG_SUCCESS) { \
return OG_ERROR; \
}
status_t rbo_try_rownum_optmz(sql_stmt_t *stmt, cond_node_t *node, uint32 *max_rownum, bool8 *rnum_pending)
{
return OG_SUCCESS;
}
static inline void rbo_get_opt_full_scan_flag(plan_assist_t *pa, sql_table_t *table, knl_index_desc_t **opt_index,
uint16 *opt_scan_flag, uint8 *opt_index_dsc)
{
*opt_index = NULL;
*opt_scan_flag = *opt_index_dsc = 0;
}
#ifdef __cplusplus
}
#endif