* 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_delete_verifier.c
*
*
* IDENTIFICATION
* src/ogsql/verifier/ogsql_delete_verifier.c
*
* -------------------------------------------------------------------------
*/
#include "ogsql_delete_verifier.h"
#include "ogsql_select_verifier.h"
#include "ogsql_table_verifier.h"
#include "dml_parser.h"
#include "base_compiler.h"
#include "ogsql_hint_verifier.h"
#ifdef __cplusplus
extern "C" {
#endif
static status_t sql_verify_oper_object(knl_handle_t session, sql_verifier_t *verf, del_object_t *object,
sql_array_t *tables)
{
bool32 is_found = OG_FALSE;
sql_table_t *table = NULL;
for (uint32 i = 0; i < tables->count; i++) {
table = (sql_table_t *)sql_array_get(tables, i);
if (!sql_search_table_name(table, (text_t *)&object->user, (text_t *)&object->name)) {
continue;
}
if (is_found) {
OG_SRC_THROW_ERROR_EX(object->name.loc, ERR_SQL_SYNTAX_ERROR, "table '%s' ambiguously defined",
T2S((text_t *)&object->name));
return OG_ERROR;
}
OG_RETURN_IFERR(sql_verify_view_insteadof_trig(verf->stmt, table, TRIG_EVENT_DELETE));
if ((table->type != NORMAL_TABLE && table->type != VIEW_AS_TABLE) || table->entry->dc.type > DICT_TYPE_VIEW) {
OG_SRC_THROW_ERROR(object->name.loc, ERR_OPERATIONS_NOT_SUPPORT, "delete table", "view or system table");
return OG_ERROR;
}
if (tables->count > 1 && (table->entry->dc.type != DICT_TYPE_TABLE &&
table->entry->dc.type != DICT_TYPE_TABLE_NOLOGGING && table->entry->dc.type != DICT_TYPE_VIEW)) {
OG_SRC_THROW_ERROR(table->name.loc, ERR_OPERATIONS_NOT_SUPPORT, "multi delete", "temp table");
return OG_ERROR;
}
OG_RETURN_IFERR(sql_verify_table_dml_object(session, verf->stmt, object->name.loc, table->entry->dc, OG_TRUE));
is_found = OG_TRUE;
if (table->type == VIEW_AS_TABLE) {
table->view_dml = OG_TRUE;
}
object->table = table;
}
if (!is_found) {
OG_SRC_THROW_ERROR_EX(object->name.loc, ERR_SQL_SYNTAX_ERROR, "unknown table %s in multi delete",
T2S((text_t *)&object->name));
return OG_ERROR;
}
return OG_SUCCESS;
}
static status_t sql_verify_oper_objects(knl_handle_t session, sql_verifier_t *verf, sql_delete_t *delete_ctx)
{
del_object_t *object = NULL;
for (uint32 i = 0; i < delete_ctx->objects->count; i++) {
object = (del_object_t *)cm_galist_get(delete_ctx->objects, i);
OG_RETURN_IFERR(sql_verify_oper_object(session, verf, object, &delete_ctx->query->tables));
}
return OG_SUCCESS;
}
static status_t sql_verify_delete_return_columns(sql_verifier_t *verf, sql_delete_t *delete_ctx)
{
if (delete_ctx->ret_columns == NULL) {
return OG_SUCCESS;
}
if (delete_ctx->query->tables.count > 1) {
OG_THROW_ERROR(ERR_SQL_SYNTAX_ERROR, "unexpected returning columns occurs");
return OG_ERROR;
}
verf->tables = &delete_ctx->query->tables;
return sql_verify_return_columns(verf, delete_ctx->ret_columns);
}
static status_t sql_verify_delete_context(knl_handle_t session, sql_verifier_t *verf, sql_delete_t *delete_ctx)
{
sql_query_t *query = delete_ctx->query;
SET_NODE_STACK_CURR_QUERY(verf->stmt, query);
OG_RETURN_IFERR(sql_verify_tables(verf, query));
OG_RETURN_IFERR(sql_verify_query_where(verf, query));
OG_RETURN_IFERR(sql_verify_query_joins(verf, query));
OG_RETURN_IFERR(sql_verify_query_order(verf, query, query->sort_items, OG_TRUE));
OG_RETURN_IFERR(sql_verify_oper_objects(session, verf, delete_ctx));
delete_ctx->hint_info = verf->stmt->context->hint_info;
og_hint_verify(verf->stmt, OGSQL_TYPE_DELETE, (void *)delete_ctx);
if (!LIMIT_CLAUSE_OCCUR(&query->limit)) {
cm_galist_reset(query->sort_items);
}
OG_RETURN_IFERR(sql_verify_delete_return_columns(verf, delete_ctx));
SQL_RESTORE_NODE_STACK(verf->stmt);
return OG_SUCCESS;
}
status_t sql_verify_delete(sql_stmt_t *stmt, sql_delete_t *delete_ctx)
{
sql_verifier_t verf = { 0 };
verf.stmt = stmt;
verf.context = stmt->context;
verf.pl_dc_lst = delete_ctx->pl_dc_lst;
verf.do_expr_optmz = OG_TRUE;
plc_get_verify_obj(stmt, &verf);
return sql_verify_delete_context(&stmt->session->knl_session, &verf, delete_ctx);
}
#ifdef __cplusplus
}
#endif