File parse_tree_cl.c¶
File List > cubrid > src > parser > parse_tree_cl.c
Go to the documentation of this file
/*
* Copyright 2008 Search Solution Corporation
* Copyright 2016 CUBRID Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* parse_tree_cl.c - Parser module for the client
*/
#ident "$Id$"
#include "config.h"
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <stddef.h>
#include <float.h>
#include <assert.h>
#include <math.h>
#include "authenticate.h"
#include "db_value_printer.hpp"
#include "porting.h"
#include "parser.h"
#include "parser_message.h"
#include "misc_string.h"
#include "csql_grammar_scan.h"
#include "mem_block.hpp"
#include "memory_alloc.h"
#include "language_support.h"
#include "object_primitive.h"
#include "object_print.h"
#include "optimizer.h"
#include "system_parameter.h"
#include "show_meta.h"
#include "virtual_object.h"
#include "set_object.h"
#include "dbi.h"
#include "string_buffer.hpp"
#include "dbtype.h"
#include "parser_allocator.hpp"
#include "tde.h"
#include "jsp_cl.h"
#include <malloc.h>
#if defined (SUPPRESS_STRLEN_WARNING)
#define strlen(s1) ((int) strlen(s1))
#endif /* defined (SUPPRESS_STRLEN_WARNING) */
#define SAFENUM(node, field) ((node) ? (node)->field : -1)
#define PT_MEMB_BUF_SIZE 100
#define PT_MEMB_PRINTABLE_BUF_SIZE 512
#define PT_MEMB_ERR_BUF_SIZE 256
#define MAX_STRING_SEGMENT_LENGTH 254
#define DONT_PRT_LONG_STRING_LENGTH 256
#define PT_APPLY_WALK(parser, ptr, arg) do { \
if((ptr)) \
{ \
(ptr) = pt_walk_private ((parser), (ptr), (arg)); \
} \
} while (0)
typedef struct pt_lambda_arg PT_LAMBDA_ARG;
struct pt_lambda_arg
{
PT_NODE *name;
PT_NODE *tree;
int type; /* 1: reduce_equality_terms, 0: o/w */
int replace_num;
bool loc_check;
bool dont_replace;
};
typedef struct pt_find_id_info PT_FIND_ID_INFO;
struct pt_find_id_info
{
UINTPTR id;
bool found;
};
typedef struct pt_walk_arg PT_WALK_ARG;
struct pt_walk_arg
{
PT_NODE_WALK_FUNCTION pre_function;
void *pre_argument;
PT_NODE_WALK_FUNCTION post_function;
void *post_argument;
int continue_walk;
};
typedef struct pt_string_block PT_STRING_BLOCK;
struct pt_string_block
{
char *body;
int length;
int size;
};
typedef struct pt_copy_cte_info PT_CTE_COPY_INFO;
struct pt_copy_cte_info
{
PT_NODE *old_cte_node;
PT_NODE *new_cte_node;
PT_CTE_COPY_INFO *next;
};
typedef struct pt_tree_copy_info PT_TREE_COPY_INFO;
struct pt_tree_copy_info
{
PT_CTE_COPY_INFO *cte_structures_list;
};
typedef PT_NODE *(*PARSER_INIT_NODE_FUNC) (PT_NODE *);
typedef PARSER_VARCHAR *(*PARSER_PRINT_NODE_FUNC) (PARSER_CONTEXT * parser, PT_NODE * node);
typedef PT_NODE *(*PARSER_APPLY_NODE_FUNC) (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PARSER_INIT_NODE_FUNC *pt_init_f = NULL;
static PARSER_PRINT_NODE_FUNC *pt_print_f = NULL;
static PARSER_APPLY_NODE_FUNC *pt_apply_f = NULL;
PARSER_CONTEXT *parent_parser = NULL;
static void strcat_with_realloc (PT_STRING_BLOCK * sb, const char *tail);
static PT_NODE *pt_lambda_check_reduce_eq (PARSER_CONTEXT * parser, PT_NODE * tree_or_name, void *void_arg,
int *continue_walk);
static PT_NODE *pt_lambda_node (PARSER_CONTEXT * parser, PT_NODE * tree_or_name, void *void_arg, int *continue_walk);
static PT_NODE *pt_lambda_node_pre (PARSER_CONTEXT * parser, PT_NODE * tree_or_name, void *void_arg,
int *continue_walk);
static PT_NODE *pt_find_id_node (PARSER_CONTEXT * parser, PT_NODE * tree, void *void_arg, int *continue_walk);
static PT_NODE *copy_node_in_tree_pre (PARSER_CONTEXT * parser, PT_NODE * old_node, void *arg, int *continue_walk);
static PT_NODE *copy_node_in_tree_post (PARSER_CONTEXT * parser, PT_NODE * new_node, void *arg, int *continue_walk);
static PT_NODE *free_node_in_tree_pre (PARSER_CONTEXT * parser, PT_NODE * node, void *arg, int *continue_walk);
static PT_NODE *free_node_in_tree_post (PARSER_CONTEXT * parser, PT_NODE * node, void *arg, int *continue_walk);
static PT_NODE *pt_walk_private (PARSER_CONTEXT * parser, PT_NODE * node, void *void_arg);
static const char *pt_show_event_type (PT_EVENT_TYPE p);
static DB_CURRENCY pt_currency_to_db (const PT_CURRENCY t);
static PARSER_VARCHAR *pt_append_quoted_string (const PARSER_CONTEXT * parser, PARSER_VARCHAR * buf, const char *str,
size_t str_length);
static PARSER_VARCHAR *pt_append_string_prefix (const PARSER_CONTEXT * parser, PARSER_VARCHAR * buf,
const PT_NODE * value);
static bool pt_is_nested_expr (const PT_NODE * node);
static bool pt_function_is_allowed_as_function_index (const PT_NODE * func);
static bool pt_expr_is_allowed_as_function_index (const PT_NODE * expr);
static void pt_init_apply_f (void);
static void pt_init_init_f (void);
static void pt_init_print_f (void);
/*
* Note :
* When adding new functions, be sure to add to ALL 4 function types and
* ALL 4 function vectors. (apply, init, print, tree_print
*/
static PT_NODE *pt_apply_alter_serial (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_alter_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_attach (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_auto_increment (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_create_serial (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_create_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_drop_serial (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_drop_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_evaluate (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_event_object (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_event_spec (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_event_target (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_execute_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_get_opt_lvl (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_get_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_get_xaction (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_isolation_lvl (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_partition (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_parts (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_remove_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_savepoint (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_scope (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_set_opt_lvl (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_set_sys_params (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_set_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_set_xaction (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_sp_parameter (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_create_stored_procedure (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_stored_procedure (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_prepare (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_timeout (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_trigger_action (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_trigger_spec_list (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_alter_index (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_alter (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_alter_user (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_attr_def (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_attr_ordering (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_auth_cmd (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_check_option (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_commit_work (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_constraint (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_create_entity (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_create_index (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_update_histogram (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_create_user (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_data_default (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_datatype (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_delete (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_difference (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_dot (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_drop_index (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_drop (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_drop_user (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_drop_variable (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_error_msg (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_expr (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_file_path (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_function (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_get_stats (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_grant (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_host_var (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_insert (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_intersection (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_method_call (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_method_def (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_name (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_named_arg (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_node_list (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_pointer (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_prepare_to_commit (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_rename (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_rename_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_resolution (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_revoke (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_rollback_work (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_select (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_set_names (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_set_timezone (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_set_session_variables (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_drop_session_variables (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_showstmt (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_sort_spec (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_spec (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_table_option (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_truncate (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_do (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_union_stmt (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_update (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_update_stats (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_value (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_merge (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_tuple_value (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_query_trace (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_insert_value (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_kill (PARSER_CONTEXT * parser, PT_NODE * P, void *arg);
static PT_NODE *pt_apply_vacuum (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_with_clause (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_cte (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_json_table (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_json_table_node (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_json_table_column (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_dblink_table (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_create_server (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_drop_server (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_rename_server (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_alter_server (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_alter_synonym (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_create_synonym (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_drop_synonym (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_rename_synonym (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PT_NODE *pt_apply_sp_body (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PARSER_APPLY_NODE_FUNC pt_apply_func_array[PT_NODE_NUMBER];
static PT_NODE *pt_init_alter_trigger (PT_NODE * p);
static PT_NODE *pt_init_get_opt_lvl (PT_NODE * p);
static PT_NODE *pt_init_isolation_lvl (PT_NODE * p);
static PT_NODE *pt_init_set_opt_lvl (PT_NODE * p);
static PT_NODE *pt_init_attr_def (PT_NODE * p);
static PT_NODE *pt_init_auth_cmd (PT_NODE * p);
static PT_NODE *pt_init_constraint (PT_NODE * node);
static PT_NODE *pt_init_create_entity (PT_NODE * p);
static PT_NODE *pt_init_create_index (PT_NODE * p);
static PT_NODE *pt_init_data_default (PT_NODE * p);
static PT_NODE *pt_init_datatype (PT_NODE * p);
static PT_NODE *pt_init_delete (PT_NODE * p);
static PT_NODE *pt_init_difference (PT_NODE * p);
static PT_NODE *pt_init_expr (PT_NODE * p);
static PT_NODE *pt_init_function (PT_NODE * p);
static PT_NODE *pt_init_grant (PT_NODE * p);
static PT_NODE *pt_init_insert (PT_NODE * p);
static PT_NODE *pt_init_intersection (PT_NODE * p);
static PT_NODE *pt_init_method_def (PT_NODE * p);
static PT_NODE *pt_init_name (PT_NODE * p);
static PT_NODE *pt_init_node_list (PT_NODE * p);
static PT_NODE *pt_init_pointer (PT_NODE * node);
static PT_NODE *pt_init_resolution (PT_NODE * p);
static PT_NODE *pt_init_select (PT_NODE * p);
static PT_NODE *pt_init_showstmt (PT_NODE * p);
static PT_NODE *pt_init_sort_spec (PT_NODE * p);
static PT_NODE *pt_init_spec (PT_NODE * p);
static PT_NODE *pt_init_table_option (PT_NODE * p);
static PT_NODE *pt_init_union_stmt (PT_NODE * p);
static PT_NODE *pt_init_update (PT_NODE * p);
static PT_NODE *pt_init_value (PT_NODE * p);
static PT_NODE *pt_init_merge (PT_NODE * p);
static PT_NODE *pt_init_tuple_value (PT_NODE * p);
static PT_NODE *pt_init_query_trace (PT_NODE * p);
static PT_NODE *pt_init_insert_value (PT_NODE * p);
static PT_NODE *pt_init_kill (PT_NODE * p);
static PT_NODE *pt_init_vacuum (PT_NODE * p);
static PT_NODE *pt_init_json_table_column (PT_NODE * p);
static PARSER_INIT_NODE_FUNC pt_init_func_array[PT_NODE_NUMBER];
static PARSER_VARCHAR *pt_print_alter_index (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_alter (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_alter_serial (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_alter_stored_procedure (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_alter_trigger (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_alter_user (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_attach (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_attr_def (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_attr_ordering (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_auth_cmd (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_auto_increment (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_check_option (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_commit_work (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_constraint (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_col_def_constraint (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_create_entity (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_create_index (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_analyze_histogram (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_show_histogram (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_create_serial (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_create_stored_procedure (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_create_trigger (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_create_user (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_data_default (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_datatype (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_delete (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_difference (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_dot (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_drop_index (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_drop (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_drop_serial (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_drop_stored_procedure (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_drop_trigger (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_drop_user (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_drop_variable (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_error_msg (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_evaluate (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_event_object (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_event_spec (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_event_target (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_execute_trigger (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_expr (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_file_path (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_function (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_get_opt_lvl (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_get_stats (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_get_trigger (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_get_xaction (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_grant (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_host_var (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_insert (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_intersection (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_isolation_lvl (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_method_call (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_method_def (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_name (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_named_arg (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_node_list (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_partition (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_parts (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_pointer (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_prepare_to_commit (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_remove_trigger (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_rename (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_rename_trigger (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_resolution (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_revoke (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_rollback_work (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_savepoint (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_scope (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_select (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_set_names (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_set_timezone (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_set_session_variables (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_drop_session_variables (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_set_opt_lvl (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_set_sys_params (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_set_trigger (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_set_xaction (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_showstmt (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_sort_spec (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_spec (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_sp_parameter (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_table_option (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_timeout (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_trigger_action (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_trigger_spec_list (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_truncate (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_do (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_union_stmt (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_update (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_update_stats (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_value (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_session_variables (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_merge (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_index_columns (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_tuple_value (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_query_trace (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_insert_value (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_vacuum (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_with_clause (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_cte (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_json_table (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_json_table_node (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_json_table_columns (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_dblink_table (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_dblink_table_dml (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_create_server (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_drop_server (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_rename_server (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_alter_server (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_alter_synonym (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_create_synonym (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_drop_synonym (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_rename_synonym (PARSER_CONTEXT * parser, PT_NODE * p);
static PARSER_VARCHAR *pt_print_sp_body (PARSER_CONTEXT * parser, PT_NODE * p);
#if defined(ENABLE_UNUSED_FUNCTION)
static PT_NODE *pt_apply_use (PARSER_CONTEXT * parser, PT_NODE * p, void *arg);
static PARSER_VARCHAR *pt_print_use (PARSER_CONTEXT * parser, PT_NODE * p);
#endif
static int parser_print_user (char *user_text, int len);
static void pt_clean_tree_copy_info (PT_TREE_COPY_INFO * tree_copy_info);
static const char *pt_json_table_column_behavior_to_string (const json_table_column_behavior_type & behavior_type);
static PARSER_VARCHAR *pt_print_json_table_column_error_or_empty_behavior (PARSER_CONTEXT * parser,
PARSER_VARCHAR * pstr,
const struct json_table_column_behavior
&column_behavior);
static PARSER_VARCHAR *pt_print_json_table_column_info (PARSER_CONTEXT * parser, PT_NODE * p, PARSER_VARCHAR * pstr);
static PARSER_PRINT_NODE_FUNC pt_print_func_array[PT_NODE_NUMBER];
extern "C"
{
extern char *g_query_string;
extern int g_query_string_len;
}
/*
* strcat_with_realloc () -
* return:
* PT_STRING_BLOCK(in/out):
* tail(in):
*/
static void
strcat_with_realloc (PT_STRING_BLOCK * sb, const char *tail)
{
char *cp = sb->body;
int margin = 32;
if (sb->size - sb->length < strlen (tail) + margin)
{
sb->size = (sb->size + strlen (tail) + margin) * 2;
sb->body = (char *) realloc (sb->body, sb->size);
cp = sb->body;
}
strcat (cp, tail);
sb->length = sb->length + strlen (tail);
}
/*
* pt_lambda_check_reduce_eq () -
* return:
* parser(in):
* tree_or_name(in/out):
* void_arg(in):
* continue_walk(in/out):
*/
static PT_NODE *
pt_lambda_check_reduce_eq (PARSER_CONTEXT * parser, PT_NODE * tree_or_name, void *void_arg, int *continue_walk)
{
PT_LAMBDA_ARG *lambda_arg = (PT_LAMBDA_ARG *) void_arg;
PT_NODE *arg1, *tree, *name;
if (!tree_or_name)
{
return tree_or_name;
}
switch (tree_or_name->node_type)
{
case PT_DOT_:
arg1 = tree_or_name->info.dot.arg1;
if (arg1 && arg1->node_type == PT_NAME)
{
PT_NAME_INFO_SET_FLAG (arg1, PT_NAME_INFO_DOT_SPEC);
}
break;
case PT_METHOD_CALL:
/* can not replace target_class as like: WHERE glo = :gx and data_seek(100) on glo > 0 -> WHERE glo = :gx and
* data_seek(100) on :gx > 0 */
*continue_walk = PT_LIST_WALK; /* don't dive into */
break;
case PT_EXPR:
tree = lambda_arg->tree;
name = lambda_arg->name;
/* check for variable string type */
if (tree->type_enum == PT_TYPE_VARCHAR || tree->type_enum == PT_TYPE_VARBIT)
{
switch (tree_or_name->info.expr.op)
{
case PT_BIT_LENGTH:
case PT_OCTET_LENGTH:
case PT_CHAR_LENGTH:
*continue_walk = PT_LIST_WALK; /* don't dive into */
break;
case PT_CAST:
if (PT_HAS_COLLATION (name->type_enum) && tree_or_name->info.expr.op == PT_CAST
&& PT_HAS_COLLATION (tree_or_name->type_enum)
&& pt_name_equal (parser, name, tree_or_name->info.expr.arg1))
{
int cast_coll = LANG_SYS_COLLATION;
int name_coll = LANG_SYS_COLLATION;
name_coll = PT_GET_COLLATION_MODIFIER (name);
if (!PT_HAS_COLLATION_MODIFIER (name) && name->data_type != NULL)
{
name_coll = name->data_type->info.data_type.collation_id;
}
if (PT_EXPR_INFO_IS_FLAGED (tree_or_name, PT_EXPR_INFO_CAST_COLL_MODIFIER))
{
cast_coll = PT_GET_COLLATION_MODIFIER (tree_or_name);
}
else if (tree_or_name->data_type != NULL)
{
cast_coll = tree_or_name->data_type->info.data_type.collation_id;
}
if (cast_coll != name_coll)
{
/* predicate evaluates with different collation */
*continue_walk = PT_LIST_WALK; /* don't dive into */
}
}
default:
break;
}
}
break;
default:
break;
}
return tree_or_name;
}
/*
* pt_lambda_node_pre () - check query node type
* return:
* parser(in):
* tree_or_name(in/out):
* void_arg(in/out):
* continue_walk(in/out):
*/
static PT_NODE *
pt_lambda_node_pre (PARSER_CONTEXT * parser, PT_NODE * tree_or_name, void *void_arg, int *continue_walk)
{
if (!tree_or_name)
{
return tree_or_name;
}
if (PT_IS_QUERY_NODE_TYPE (tree_or_name->node_type))
{
*continue_walk = PT_LIST_WALK;
}
else
{
*continue_walk = PT_CONTINUE_WALK;
}
return tree_or_name;
}
/*
* pt_lambda_node () - applies the lambda test to the node passed to it,
* and conditionally substitutes a copy of its corresponding tree
* return:
* parser(in):
* tree_or_name(in/out):
* void_arg(in/out):
* continue_walk(in/out):
*/
static PT_NODE *
pt_lambda_node (PARSER_CONTEXT * parser, PT_NODE * tree_or_name, void *void_arg, int *continue_walk)
{
PT_LAMBDA_ARG *lambda_arg = (PT_LAMBDA_ARG *) void_arg;
PT_NODE *name_node, *lambda_name, *result, *next, *temp;
*continue_walk = PT_CONTINUE_WALK;
if (!tree_or_name)
{
return tree_or_name;
}
if (tree_or_name->node_type == PT_FUNCTION)
{
switch (tree_or_name->info.function.function_type)
{
case F_SET:
case F_MULTISET:
case F_SEQUENCE:
if (lambda_arg->replace_num > 0)
{
/* check normal func data_type 1: reduce_equality_terms - check normal func data_type */
if (lambda_arg->type == 1)
{
/* at here, do clear. later is updated in pt_semantic_type */
tree_or_name->info.function.is_type_checked = false;
}
lambda_arg->replace_num = 0;
}
break;
default:
break;
}
return tree_or_name;
}
name_node = tree_or_name;
lambda_name = lambda_arg->name;
while (name_node->node_type == PT_DOT_ && lambda_name->node_type == PT_DOT_)
{
name_node = name_node->info.dot.arg2;
lambda_name = lambda_name->info.dot.arg2;
}
/* change orderby_num() to groupby_num() */
if (tree_or_name->node_type == PT_EXPR && tree_or_name->info.expr.op == PT_ORDERBY_NUM)
{
if (lambda_name->node_type == PT_EXPR && lambda_name->info.expr.op == PT_ORDERBY_NUM)
{ /* found match */
/* replace 'tree_or_name' node with 'lambda_arg->tree' */
next = tree_or_name->next;
result = parser_copy_tree_list (parser, lambda_arg->tree);
parser_free_node (parser, tree_or_name);
for (temp = result; temp->next; temp = temp->next)
{
;
}
temp->next = next;
lambda_arg->replace_num++;
return result;
}
}
/* change inst_num() to orderby_num() */
if (PT_IS_INSTNUM (tree_or_name) && PT_IS_INSTNUM (lambda_name))
{
/* found match */
/* replace 'tree_or_name' node with 'lambda_arg->tree' */
next = tree_or_name->next;
result = parser_copy_tree_list (parser, lambda_arg->tree);
parser_free_node (parser, tree_or_name);
for (temp = result; temp->next; temp = temp->next)
{
;
}
temp->next = next;
lambda_arg->replace_num++;
return result;
}
if (name_node->node_type != PT_NAME || lambda_name->node_type != PT_NAME)
{
return tree_or_name;
}
if (PT_NAME_INFO_IS_FLAGED (name_node, PT_NAME_INFO_DOT_SPEC))
{
/* never rewrites a path expression (e.g, oid = ? and oid.i = 1) */
return tree_or_name;
}
if (lambda_arg->loc_check == true
&& (name_node->info.name.location == 0 || (name_node->info.name.location != lambda_name->info.name.location)))
{
/* WHERE condition or different ON location */
return tree_or_name;
}
if (pt_name_equal (parser, name_node, lambda_name))
{
if (lambda_arg->dont_replace)
{ /* don't replace, only marking */
temp = pt_get_end_path_node (tree_or_name);
if (temp->node_type == PT_NAME)
{
PT_NAME_INFO_SET_FLAG (temp, PT_NAME_INFO_CONSTANT);
temp->info.name.constant_value = parser_copy_tree (parser, lambda_arg->tree);
}
return tree_or_name;
}
/* replace 'tree_or_name' node with 'lambda_arg->tree' */
next = tree_or_name->next;
result = parser_copy_tree_list (parser, lambda_arg->tree);
parser_free_node (parser, tree_or_name);
for (temp = result; temp->next; temp = temp->next)
{
;
}
temp->next = next;
lambda_arg->replace_num++;
}
else
{ /* did not match */
result = tree_or_name;
}
return result;
}
/*
* pt_find_id_node () - tests names id equality
* return:
* parser(in):
* tree(in):
* void_arg(in/out):
* continue_walk(in/out):
*/
static PT_NODE *
pt_find_id_node (PARSER_CONTEXT * parser, PT_NODE * tree, void *void_arg, int *continue_walk)
{
PT_FIND_ID_INFO *info = (PT_FIND_ID_INFO *) void_arg;
if (tree->node_type == PT_NAME)
{
if (tree->info.name.spec_id == info->id)
{
info->found = true;
*continue_walk = PT_STOP_WALK;
}
}
return tree;
}
/*
* copy_node_in_tree_pre () - copies exactly a node passed to it, and returns
* a pointer to the copy. It is eligible for a walk "pre" function
* return:
* parser(in):
* old_node(in):
* arg(in):
* continue_walk(in):
*/
static PT_NODE *
copy_node_in_tree_pre (PARSER_CONTEXT * parser, PT_NODE * old_node, void *arg, int *continue_walk)
{
PT_NODE *new_node;
PT_TREE_COPY_INFO *tree_copy_info = (PT_TREE_COPY_INFO *) arg;
new_node = parser_new_node (parser, old_node->node_type);
if (new_node == NULL)
{
PT_INTERNAL_ERROR (parser, "allocate new node");
return NULL;
}
*new_node = *old_node;
/* if node is copied from another parser context, deepcopy string contents */
if (old_node->parser_id != parser->id)
{
if (new_node->node_type == PT_NAME)
{
new_node->info.name.original = pt_append_string (parser, NULL, old_node->info.name.original);
new_node->info.name.resolved = pt_append_string (parser, NULL, old_node->info.name.resolved);
}
else if (new_node->node_type == PT_VALUE)
{
if (new_node->info.value.text)
{
new_node->info.value.text = pt_append_string (parser, NULL, old_node->info.value.text);
}
}
}
/* if we are operating in a context of db_values, copy it too */
if (new_node->node_type == PT_VALUE && new_node->info.value.db_value_is_in_workspace
&& new_node->info.value.db_value_is_initialized)
{
if (db_value_clone (&old_node->info.value.db_value, &new_node->info.value.db_value) < 0)
{
PT_ERRORc (parser, new_node, er_msg ());
}
else
{
new_node->info.value.db_value_is_in_workspace = 1;
}
}
if (new_node->node_type == PT_JSON_TABLE_COLUMN)
{
PT_JSON_TABLE_COLUMN_INFO *old_col = &old_node->info.json_table_column_info;
PT_JSON_TABLE_COLUMN_INFO *new_col = &new_node->info.json_table_column_info;
new_col->on_empty.m_default_value = db_value_copy (old_col->on_empty.m_default_value);
new_col->on_error.m_default_value = db_value_copy (old_col->on_error.m_default_value);
}
new_node->parser_id = parser->id;
/* handle CTE copy so that the CTE pointers will be updated to point to new_node */
if (old_node->node_type == PT_CTE)
{
/* the pair old_node and new_node addresses is added to copy_tree_info */
PT_CTE_COPY_INFO *curr_cte_copy_info;
curr_cte_copy_info = (PT_CTE_COPY_INFO *) malloc (sizeof (PT_CTE_COPY_INFO));
if (curr_cte_copy_info == NULL)
{
PT_INTERNAL_ERROR (parser, "allocate new node");
return NULL;
}
curr_cte_copy_info->old_cte_node = old_node;
curr_cte_copy_info->new_cte_node = new_node;
/* pair is added conveniently at the beginning of the list */
curr_cte_copy_info->next = tree_copy_info->cte_structures_list;
tree_copy_info->cte_structures_list = curr_cte_copy_info;
}
return new_node;
}
/*
* copy_node_in_tree_post () - post function of copy tree
*
* return:
* parser(in):
* new_node(in):
* arg(in):
* continue_walk(in):
*/
static PT_NODE *
copy_node_in_tree_post (PARSER_CONTEXT * parser, PT_NODE * new_node, void *arg, int *continue_walk)
{
PT_TREE_COPY_INFO *tree_copy_info = (PT_TREE_COPY_INFO *) arg;
if (new_node->node_type == PT_SPEC && PT_SPEC_IS_CTE (new_node))
{
/* the new cte_pointer may have to point to a new cte; it depends if the copied tree includes the CTE too
* (should be in cte_structures_list) */
PT_NODE *cte_pointer = new_node->info.spec.cte_pointer;
PT_CTE_COPY_INFO *cte_info_it;
assert (cte_pointer->info.pointer.node->node_type == PT_CTE);
for (cte_info_it = tree_copy_info->cte_structures_list; cte_info_it != NULL; cte_info_it = cte_info_it->next)
{
if (cte_info_it->old_cte_node == cte_pointer->info.pointer.node)
{
break;
}
}
if (cte_info_it != NULL)
{
/* the old value of the pointer was found in the list; update the pointer to the new cte address */
cte_pointer->info.pointer.node = cte_info_it->new_cte_node;
}
}
return new_node;
}
/*
* pt_walk_private () - implements the higher order tree walk routine parser_walk_tree
* return:
* parser(in):
* node(in/out):
* void_arg(in/out):
*/
static PT_NODE *
pt_walk_private (PARSER_CONTEXT * parser, PT_NODE * node, void *void_arg)
{
PT_WALK_ARG *walk = (PT_WALK_ARG *) void_arg;
PT_NODE_TYPE node_type;
PARSER_APPLY_NODE_FUNC apply;
int save_continue;
assert (node != NULL);
if (walk->pre_function)
{
node = (*walk->pre_function) (parser, node, walk->pre_argument, &(walk->continue_walk));
if (!node)
{
return NULL;
}
}
if (walk->continue_walk != PT_STOP_WALK)
{
/* walking leaves may write over this. */
save_continue = walk->continue_walk;
/* visit sub-trees */
if (save_continue == PT_CONTINUE_WALK || save_continue == PT_LEAF_WALK)
{
/* this is an optimization to remove a procedure call per node from the recursion path. It is the same as
* calling pt_apply. */
node_type = node->node_type;
assert (node_type >= PT_NODE_NONE);
if (node_type == PT_NODE_NONE)
{
assert (pt_has_error (parser));
return NULL;
}
if (node_type >= PT_LAST_NODE_NUMBER || !(apply = pt_apply_f[node_type]))
{
return NULL;
}
(*apply) (parser, node, walk);
PT_APPLY_WALK (parser, node->data_type, walk);
}
/* visit rest of list first, follow 'or_next' list */
if (save_continue == PT_CONTINUE_WALK || save_continue == PT_LEAF_WALK || save_continue == PT_LIST_WALK)
{
PT_APPLY_WALK (parser, node->or_next, walk);
}
/* then, follow 'next' list */
if (save_continue == PT_CONTINUE_WALK || save_continue == PT_LIST_WALK)
{
PT_APPLY_WALK (parser, node->next, walk);
}
if (walk->continue_walk != PT_STOP_WALK)
{
walk->continue_walk = save_continue;
}
}
/* and visit this node again */
if (walk->post_function)
{
node = (*walk->post_function) (parser, node, walk->post_argument, &(walk->continue_walk));
}
return node;
}
/*
* parser_walk_leaves () - like parser_walk_tree, but begins at the leaves of
* the node passed in
* return:
* parser(in):
* node(in):
* pre_function(in):
* pre_argument(in):
* post_function(in):
* post_argument(in):
*/
PT_NODE *
parser_walk_leaves (PARSER_CONTEXT * parser, PT_NODE * node, PT_NODE_WALK_FUNCTION pre_function, void *pre_argument,
PT_NODE_WALK_FUNCTION post_function, void *post_argument)
{
PARSER_APPLY_NODE_FUNC apply;
PT_NODE_TYPE node_type;
PT_WALK_ARG walk_argument;
PT_NODE *walk;
walk_argument.continue_walk = PT_CONTINUE_WALK;
walk_argument.pre_function = pre_function;
walk_argument.pre_argument = pre_argument;
walk_argument.post_function = post_function;
walk_argument.post_argument = post_argument;
for (walk = node; walk; walk = walk->or_next)
{
node_type = walk->node_type;
if (node_type >= PT_LAST_NODE_NUMBER || !(apply = pt_apply_f[node_type]))
{
return NULL;
}
(*apply) (parser, walk, &walk_argument);
PT_APPLY_WALK (parser, walk->data_type, &walk_argument);
}
return node;
}
/*
* parser_walk_tree () - walks a tree and applies pre and post visit routines
* to each node in the tree. A pre function may prune
* the search by returning a false (0) in the continue argument
* return:
* parser(in):
* node(in):
* pre_function(in):
* pre_argument(in):
* post_function(in):
* post_argument(in):
*/
PT_NODE *
parser_walk_tree (PARSER_CONTEXT * parser, PT_NODE * node, PT_NODE_WALK_FUNCTION pre_function, void *pre_argument,
PT_NODE_WALK_FUNCTION post_function, void *post_argument)
{
if (node == NULL)
{
return NULL;
}
PT_WALK_ARG walk_argument;
walk_argument.continue_walk = PT_CONTINUE_WALK;
walk_argument.pre_function = pre_function;
walk_argument.pre_argument = pre_argument;
walk_argument.post_function = post_function;
walk_argument.post_argument = post_argument;
PT_APPLY_WALK (parser, node, &walk_argument);
return node;
}
/*
* pt_continue_walk () - Re-enabled the tree walk after a portion was "pruned"
* return:
* parser(in):
* tree(in):
* arg(in):
* continue_walk(in/out):
*/
PT_NODE *
pt_continue_walk (PARSER_CONTEXT * parser, PT_NODE * tree, void *arg, int *continue_walk)
{
*continue_walk = PT_CONTINUE_WALK;
return tree;
}
/*
* pt_lambda_with_arg () - walks a tree and modifies it in place to replace
* name nodes with copies of a corresponding tree
* type 1 : for reduce_eq_term, type 2 : don't walk into subquery
* return:
* parser(in):
* tree_with_names(in):
* name_node(in):
* corresponding_tree(in):
* loc_check(in):
* type(in):
* dont_replace(in):
*/
PT_NODE *
pt_lambda_with_arg (PARSER_CONTEXT * parser, PT_NODE * tree_with_names, PT_NODE * name_node,
PT_NODE * corresponding_tree, bool loc_check, int type, bool dont_replace)
{
PT_LAMBDA_ARG lambda_arg;
PT_NODE *tree;
int save_paren_type = 0;
bool arg_ok;
arg_ok = false;
if (name_node->node_type == PT_NAME || name_node->node_type == PT_DOT_)
{
arg_ok = true;
}
else if (name_node->node_type == PT_EXPR && name_node->info.expr.op == PT_ORDERBY_NUM)
{
if (corresponding_tree)
{
if ((corresponding_tree->node_type == PT_FUNCTION
&& corresponding_tree->info.function.function_type == PT_GROUPBY_NUM)
|| (corresponding_tree->node_type == PT_EXPR && corresponding_tree->info.expr.op == PT_INST_NUM))
{
/* change orderby_num() to groupby_num() */
/* change orderby_num() to inst_num() */
arg_ok = true;
}
}
}
else if (name_node->node_type == PT_EXPR && name_node->info.expr.op == PT_INST_NUM)
{
/* change inst_num() to orderby_num() */
if (corresponding_tree)
{
if (corresponding_tree->node_type == PT_EXPR && corresponding_tree->info.expr.op == PT_ORDERBY_NUM)
{
arg_ok = true;
}
}
}
if (arg_ok != true)
{
PT_INTERNAL_ERROR (parser, "lambda");
return tree_with_names;
}
lambda_arg.type = type;
lambda_arg.name = name_node;
lambda_arg.tree = corresponding_tree;
lambda_arg.loc_check = loc_check;
lambda_arg.dont_replace = dont_replace;
lambda_arg.replace_num = 0;
if (corresponding_tree && corresponding_tree->node_type == PT_EXPR)
{
/* make sure it will print with proper precedance. we don't want to replace "name" with "1+2" in 4*name, and get
* 4*1+2. It should be 4*(1+2) instead. */
save_paren_type = corresponding_tree->info.expr.paren_type;
corresponding_tree->info.expr.paren_type = 1;
}
tree =
parser_walk_tree (parser, tree_with_names,
((type == 1) ? pt_lambda_check_reduce_eq : (type == 2) ? pt_lambda_node_pre : NULL), &lambda_arg,
pt_lambda_node, &lambda_arg);
if (corresponding_tree && corresponding_tree->node_type == PT_EXPR)
{
corresponding_tree->info.expr.paren_type = save_paren_type;
}
return tree;
}
/*
* pt_lambda () -
* return:
* parser(in):
* tree_with_names(in):
* name_node(in):
* corresponding_tree(in):
*/
PT_NODE *
pt_lambda (PARSER_CONTEXT * parser, PT_NODE * tree_with_names, PT_NODE * name_node, PT_NODE * corresponding_tree)
{
return pt_lambda_with_arg (parser, tree_with_names, name_node, corresponding_tree, false, 0, false);
}
/*
* pt_find_id () - walks a tree looking for a name of the given id family
* return:
* parser(in):
* tree_with_names(in):
* id(in):
*/
UINTPTR
pt_find_id (PARSER_CONTEXT * parser, PT_NODE * tree_with_names, UINTPTR id)
{
PT_FIND_ID_INFO info;
info.id = id;
info.found = false;
parser_walk_tree (parser, tree_with_names, pt_find_id_node, &info, NULL, NULL);
return info.found;
}
/*
* parser_copy_tree () - copies a parse tree without and modifying it
* return:
* parser(in):
* in_tree(in):
*/
PT_NODE *
parser_copy_tree (PARSER_CONTEXT * parser, const PT_NODE * tree)
{
PT_NODE *copy = NULL;
if (tree)
{
PT_NODE *temp, *save;
PT_TREE_COPY_INFO tree_copy_info;
tree_copy_info.cte_structures_list = NULL;
temp = (PT_NODE *) tree;
save = temp->next;
temp->next = NULL;
copy = parser_walk_tree (parser, temp, copy_node_in_tree_pre, &tree_copy_info, copy_node_in_tree_post,
&tree_copy_info);
temp->next = save;
pt_clean_tree_copy_info (&tree_copy_info);
}
return copy;
}
/*
* parser_copy_tree_list () - copies a parse tree without and modifing it.
* It includes the rest of the list pointed to by tree
* return:
* parser(in):
* tree(in):
*/
PT_NODE *
parser_copy_tree_list (PARSER_CONTEXT * parser, PT_NODE * tree)
{
if (tree)
{
PT_TREE_COPY_INFO tree_copy_info;
tree_copy_info.cte_structures_list = NULL;
tree = parser_walk_tree (parser, tree, copy_node_in_tree_pre, &tree_copy_info, copy_node_in_tree_post,
&tree_copy_info);
pt_clean_tree_copy_info (&tree_copy_info);
}
return tree;
}
/*
* parser_get_tree_list_diff () - get the difference list1 minus list2
* return: a PT_NODE_POINTER list to the nodes in difference
* list1(in): the first tree list
* list2(in): the second tree list
*/
PT_NODE *
parser_get_tree_list_diff (PARSER_CONTEXT * parser, PT_NODE * list1, PT_NODE * list2)
{
PT_NODE *res_list, *save_node1, *save_node2, *node1, *node2;
if (list1 == NULL)
{
return NULL;
}
if (list2 == NULL)
{
return pt_point (parser, list1);
}
res_list = NULL;
for (node1 = list1; node1; node1 = node1->next)
{
save_node1 = node1;
CAST_POINTER_TO_NODE (node1);
for (node2 = list2; node2; node2 = node2->next)
{
save_node2 = node2;
CAST_POINTER_TO_NODE (node2);
if (node1 == node2)
{
node2 = save_node2;
break;
}
node2 = save_node2;
}
if (node2 == NULL)
{
res_list = parser_append_node (pt_point (parser, node1), res_list);
}
node1 = save_node1;
}
return res_list;
}
/*
* pt_point () - points a parse tree node without and modifing it
* return:
* parser(in):
* in_tree(in):
*/
PT_NODE *
pt_point (PARSER_CONTEXT * parser, const PT_NODE * in_tree)
{
PT_NODE *tree, *pointer;
if (!in_tree)
{
return NULL;
}
/* unconst */
tree = (PT_NODE *) in_tree;
CAST_POINTER_TO_NODE (tree);
pointer = parser_new_node (parser, PT_NODE_POINTER);
if (!pointer)
{
return NULL;
}
/* set original node pointer */
pointer->info.pointer.node = tree;
/* set line/column number as that of original node pointer; this is used at error print routine */
pointer->line_number = tree->line_number;
pointer->column_number = tree->column_number;
return pointer;
}
/*
* pt_point_l () - points a parse tree node without and modifing it.
* It includes the rest of the list pointed to by tree
* return:
* parser(in):
* in_tree(in):
*/
PT_NODE *
pt_point_l (PARSER_CONTEXT * parser, const PT_NODE * in_tree)
{
PT_NODE *tree, *node, *pointer, *list;
if (!in_tree)
{
return NULL;
}
/* unconst */
tree = (PT_NODE *) in_tree;
list = NULL;
for (node = tree; node; node = node->next)
{
if (node->flag.is_hidden_column)
{
continue;
}
pointer = pt_point (parser, node);
if (!pointer)
{
goto exit_on_error;
}
list = parser_append_node (pointer, list);
}
return list;
exit_on_error:
while (list)
{
node = list;
list = list->next;
node->next = NULL; /* cut-off link */
parser_free_tree (parser, node);
}
return NULL;
}
/*
* pt_point_ref () - creates a reference PT_NODE_POINTER
* return: pointer PT_NODE
* parser(in): parser context
* node(in): node to point to
*/
PT_NODE *
pt_point_ref (PARSER_CONTEXT * parser, const PT_NODE * node)
{
PT_NODE *ret = pt_point (parser, node);
if (ret != NULL)
{
ret->info.pointer.type = PT_POINTER_REF;
}
return ret;
}
/*
* pt_pointer_stack_push () - push a new PT_NODE_POINTER, pointing to node, on a
* stack of similar pointers
* returns: stack base
* parser(in): parser context
* stack(in): base of stack or NULL for new stack
* node(in): node to be pointed to by new stack entry
*/
PT_NODE *
pt_pointer_stack_push (PARSER_CONTEXT * parser, PT_NODE * stack, PT_NODE * node)
{
PT_NODE *new_top = pt_point (parser, node);
PT_NODE *list = stack;
if (new_top == NULL)
{
PT_ERRORm (parser, node, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_OUT_OF_MEMORY);
return stack;
}
while (list != NULL && list->next != NULL)
{
list = list->next;
}
if (list)
{
list->next = new_top;
return stack;
}
else
{
return new_top;
}
}
/*
* pt_pointer_stack_pop () - push a new PT_NODE_POINTER, pointing to node, on a
* stack of similar pointers
* returns: new stack base
* parser(in): parser context
* stack(in): base of stack
* node(out): popped node
*/
PT_NODE *
pt_pointer_stack_pop (PARSER_CONTEXT * parser, PT_NODE * stack, PT_NODE ** node)
{
PT_NODE *new_top = NULL;
PT_NODE *list = stack;
if (stack == NULL)
{
PT_INTERNAL_ERROR (parser, "pop operation on empty PT_NODE_POINTER stack");
return NULL;
}
while (list != NULL && list->next != NULL)
{
new_top = list;
list = list->next;
}
if (node != NULL)
{
*node = list->info.pointer.node;
}
list->info.pointer.node = NULL;
parser_free_tree (parser, list);
if (new_top)
{
new_top->next = NULL;
return stack;
}
else
{
return NULL;
}
}
/*
* free_node_in_tree_pre () - checks a pointer nodes for a recursive walk
* return:
* parser(in):
* node(in/out):
* arg(in):
* continue_walk(in):
*/
static PT_NODE *
free_node_in_tree_pre (PARSER_CONTEXT * parser, PT_NODE * node, void *arg, int *continue_walk)
{
if (node->node_type == PT_NODE_POINTER)
{
/* do must not free original node; cut-off link to original node */
node->info.pointer.node = NULL;
}
return node;
}
/*
* free_node_in_tree_post () - frees a node for a recursive walk
* return:
* parser(in):
* node(in):
* arg(in):
* continue_walk(in):
*/
static PT_NODE *
free_node_in_tree_post (PARSER_CONTEXT * parser, PT_NODE * node, void *arg, int *continue_walk)
{
parser_free_node (parser, node);
return NULL;
}
/*
* parser_free_tree () -
* return:
* parser(in):
* tree(in):
*/
void
parser_free_tree (PARSER_CONTEXT * parser, PT_NODE * tree)
{
(void) parser_walk_tree (parser, tree, free_node_in_tree_pre, NULL, free_node_in_tree_post, NULL);
}
/*
* parser_free_subtrees () - free subtrees
* return:
* parser(in):
* tree(in):
*/
void
parser_free_subtrees (PARSER_CONTEXT * parser, PT_NODE * tree)
{
(void) parser_walk_leaves (parser, tree, free_node_in_tree_pre, NULL, free_node_in_tree_post, NULL);
}
// clear node resources and all subtrees
void
parser_clear_node (PARSER_CONTEXT * parser, PT_NODE * node)
{
parser_free_subtrees (parser, node);
parser_free_node_resources (node);
}
/*
* pt_internal_error () - report an internal system error
* return:
* parser(in): the parser context
* file(in): source file name
* line(in): at which line in the source
* what(in): a note about the internal system error
*/
void *
pt_internal_error (PARSER_CONTEXT * parser, const char *file, int line, const char *what)
{
PT_NODE node;
node.line_number = 0;
node.column_number = 0;
node.buffer_pos = -1;
if (parser && !pt_has_error (parser))
{
parser->flag.has_internal_error = 1;
pt_frob_error (parser, &node, "System error (%s) in %s (line: %d)", what, file, line);
}
return NULL;
}
#if defined (ENABLE_UNUSED_FUNCTION)
/*
* pt_void_internal_error () - wrapper for pt_internal_error
* return:
* parser(in):
* file(in):
* line(in):
* what(in):
*/
void
pt_void_internal_error (PARSER_CONTEXT * parser, const char *file, int line, const char *what)
{
pt_internal_error (parser, file, line, what);
}
#endif
/*
* fgetin() - get input from users file
* return: -1 on EOF
* p(in):
*/
static int
fgetin (PARSER_CONTEXT * p)
{
int c;
c = fgetc (p->file);
if (c == EOF)
{
return -1;
}
else
{
return c;
}
}
/*
* buffgetin() - get input from users buffer
* return: -1 on end
* p(in):
*/
static int
buffgetin (PARSER_CONTEXT * p)
{
int c;
c = *((const unsigned char *) p->buffer);
if (!c)
{
c = -1;
}
else
{
(p->buffer)++;
}
return c;
}
#if defined (ENABLE_UNUSED_FUNCTION)
/*
* binarygetin() -
* return:
* p(in):
*/
static int
binarygetin (PARSER_CONTEXT * p)
{
int c = -1;
if (p->input_buffer_position >= p->input_buffer_length)
{
c = -1;
}
else
{
c = (const unsigned char) p->buffer[p->input_buffer_position++];
}
return c;
}
#endif
/*
* pt_push() - push a node onto this parser's stack
* return: 1 if all OK, 0 otherwise
* parser(in/out): the parser context
* node(in): a PT_NODE
*/
int
pt_push (PARSER_CONTEXT * parser, PT_NODE * node)
{
#define INITIAL_EXTENT 512
#define DELTA 512
int new_siz, old_siz;
PT_NODE **new_stk;
if (!parser || !node)
{
return 0;
}
/* make sure there is space in the node_stack */
if (parser->stack_top + 1 >= parser->stack_size)
{
/* expand the node_stack */
old_siz = parser->stack_size;
new_siz = (old_siz <= 0) ? INITIAL_EXTENT : old_siz + DELTA;
new_stk = (PT_NODE **) parser_alloc (parser, new_siz * sizeof (PT_NODE *));
if (!new_stk)
{
return 0;
}
parser->stack_size = new_siz;
/* copy contents of old node_stack to the new node_stack */
if (parser->node_stack)
{
memmove (new_stk, parser->node_stack, parser->stack_top * sizeof (PT_NODE *));
}
/* the old node_stack will be freed later by parser_free_parser */
parser->node_stack = new_stk;
}
/* push new node onto the stack */
parser->node_stack[parser->stack_top++] = node;
return 1;
}
/*
* pt_pop() - pop and return node from top of stack
* return: the top node on the stack or NULL
* parser(in): the parser context
*/
PT_NODE *
pt_pop (PARSER_CONTEXT * parser)
{
if (!parser || !parser->node_stack)
{
return NULL;
}
/* guard against stack underflow */
if (parser->stack_top <= 0)
{
return NULL;
}
return parser->node_stack[--parser->stack_top];
}
/*
* pt_top() - return top of stack
* return: the top node on the stack or NULL
* parser(in): the parser context
*/
PT_NODE *
pt_top (PARSER_CONTEXT * parser)
{
if (!parser || !parser->node_stack)
{
return NULL;
}
/* guard against stack underflow */
if (parser->stack_top <= 0)
{
return NULL;
}
return parser->node_stack[parser->stack_top - 1];
}
/*
* parser_parse_string_use_sys_charset () - Parses a string and generates
* parse tree. String constants will
* use system charset if no charset
* is specified.
*
* return : Parse tree.
* parser (in) : Parser context.
* buffer (in) : Query string.
*
* NOTE: This function should be used instead of parser_parse_string () if the
* query string may contain string constants.
*/
PT_NODE **
parser_parse_string_use_sys_charset (PARSER_CONTEXT * parser, const char *buffer)
{
PT_NODE **result = NULL;
lang_set_parser_use_client_charset (false);
result = parser_parse_string (parser, buffer);
lang_set_parser_use_client_charset (true);
return result;
}
/*
* parser_parse_string() - reset and initialize the parser
* return:
* parser(in/out): the parser context
* buffer(in):
*/
PT_NODE **
parser_parse_string (PARSER_CONTEXT * parser, const char *buffer)
{
return parser_parse_string_with_escapes (parser, buffer, true);
}
/*
* parser_parse_string_with_escapes() - reset and initialize the parser
* return:
* parser(in/out): the parser context
* buffer(in):
*/
PT_NODE **
parser_parse_string_with_escapes (PARSER_CONTEXT * parser, const char *buffer, const bool strings_have_no_escapes)
{
PT_NODE **tree;
if (!parser)
{
return 0;
}
parser->buffer = buffer;
parser->original_buffer = buffer;
parser->next_byte = buffgetin;
if (LANG_VARIABLE_CHARSET (lang_charset ()))
{
parser->next_char = dbcs_get_next;
parser->casecmp = intl_identifier_casecmp;
}
else
{
parser->next_char = buffgetin;
/* It would be a nice optimization to use strcasecmp if we are doing a Latin 8 bit character set. Unfortunately,
* strcasesmp is braindamaged about 8 bit ascii, so this is not a safe optimization. Perhaps
* intl_identifier_casecmp can be further optimized for the single byte character case. */
parser->casecmp = intl_identifier_casecmp;
}
parser->flag.strings_have_no_escapes = strings_have_no_escapes ? 1 : 0;
parser->flag.dont_collect_exec_stats = 0;
if (prm_get_bool_value (PRM_ID_QUERY_TRACE) == true)
{
parser->query_trace = true;
}
else
{
parser->query_trace = false;
}
parser->num_plan_trace = 0;
/* reset parser node stack and line/column info */
parser->stack_top = 0;
parser->line = 1;
parser->column = 0;
/* set up an environment for longjump to return to if there is an out of memory error in pt_memory.c. DO NOT RETURN
* unless PT_CLEAR_JMP_ENV is called to clear the environment. */
PT_SET_JMP_ENV (parser);
tree = parser_main (parser);
PT_CLEAR_JMP_ENV (parser);
return tree;
}
#if defined (ENABLE_UNUSED_FUNCTION)
/*
* parser_parse_binary() - reset and initialize the parser
* return:
* parser(in/out): the parser context
* buffer(in):
* size(in) : buffer length
*/
PT_NODE **
parser_parse_binary (PARSER_CONTEXT * parser, const char *buffer, size_t size)
{
PT_NODE **tree;
if (!parser)
return 0;
parser->buffer = buffer;
parser->next_byte = binarygetin;
if (LANG_VARIABLE_CHARSET (lang_charset ()))
{
parser->next_char = dbcs_get_next;
parser->casecmp = intl_identifier_casecmp;
}
else
{
parser->next_char = binarygetin;
parser->casecmp = intl_identifier_casecmp;
}
parser->input_buffer_length = size;
parser->input_buffer_position = 0;
/* reset parser node stack and line/column info */
parser->stack_top = 0;
parser->line = 1;
parser->column = 0;
/* set up an environment for longjump to return to if there is an out of memory error in pt_memory.c. DO NOT RETURN
* unless PT_CLEAR_JMP_ENV is called to clear the environment. */
PT_SET_JMP_ENV (parser);
tree = parser_main (parser);
PT_CLEAR_JMP_ENV (parser);
return tree;
}
#endif
/*
* parser_parse_file() - reset and initialize the parser
* parser(in/out): the parser context
* file(in):
*/
PT_NODE **
parser_parse_file (PARSER_CONTEXT * parser, FILE * file)
{
PT_NODE **tree;
if (!parser)
{
return 0;
}
parser->file = file;
parser->next_byte = fgetin;
if (LANG_VARIABLE_CHARSET (lang_charset ()))
{
parser->next_char = dbcs_get_next;
parser->casecmp = intl_identifier_casecmp;
}
else
{
parser->next_char = fgetin;
parser->casecmp = intl_identifier_casecmp;
}
parser->flag.strings_have_no_escapes = 0;
parser->flag.is_in_and_list = 0;
parser->flag.dont_collect_exec_stats = 0;
if (prm_get_bool_value (PRM_ID_QUERY_TRACE) == true)
{
parser->query_trace = true;
}
else
{
parser->query_trace = false;
}
parser->num_plan_trace = 0;
/* reset parser node stack and line/column info */
parser->stack_top = 0;
parser->line = 1;
parser->column = 0;
/* set up an environment for longjump to return to if there is an out of memory error in pt_memory.c. DO NOT RETURN
* unless PT_CLEAR_JMP_ENV is called to clear the environment. */
PT_SET_JMP_ENV (parser);
tree = parser_main (parser);
PT_CLEAR_JMP_ENV (parser);
return tree;
}
/*
* pt_init_one_statement_parser() -
* return:
* parser(in/out):
* file(in):
*/
PT_NODE **
pt_init_one_statement_parser (PARSER_CONTEXT * parser, FILE * file)
{
if (!parser)
{
return 0;
}
parser->file = file;
parser->next_byte = fgetin;
if (LANG_VARIABLE_CHARSET (lang_charset ()))
{
parser->next_char = dbcs_get_next;
parser->casecmp = intl_identifier_casecmp;
}
else
{
parser->next_char = fgetin;
parser->casecmp = intl_identifier_casecmp;
}
/* reset parser node stack and line/column info */
parser->stack_top = 0;
parser->line = 1;
parser->column = 0;
{
parser_output_host_index = parser_input_host_index = 0;
this_parser = parser;
dbcs_start_input ();
}
return 0;
}
/*
* pt_record_error() - creates a new PT_ZZ_ERROR_MSG node appends it
* to parser->error_msgs
* return: none
* parser(in/out): pointer to parser structure
* stmt_no(in): source statement where error was detected
* line_no(in): source line number where error was detected
* col_no(in): source column number where error was detected
* msg(in): a helpful explanation of the error
*/
void
pt_record_error (PARSER_CONTEXT * parser, int stmt_no, int line_no, int col_no, const char *msg, const char *context)
{
char *context_copy;
char buf[MAX_PRINT_ERROR_CONTEXT_LENGTH + 1];
PT_NODE *node;
node = parser_new_node (parser, PT_ZZ_ERROR_MSG);
if (node == NULL)
{
PT_INTERNAL_ERROR (parser, "allocate new node");
return;
}
node->info.error_msg.statement_number = stmt_no;
node->line_number = line_no;
node->column_number = col_no;
node->info.error_msg.error_message = NULL;
if (context != NULL)
{
char *before_context_str = msgcat_message (MSGCAT_CATALOG_CUBRID,
MSGCAT_SET_PARSER_SYNTAX,
MSGCAT_SYNTAX_BEFORE_CONTEXT);
char *before_end_of_stmt_str = msgcat_message (MSGCAT_CATALOG_CUBRID, MSGCAT_SET_PARSER_SYNTAX,
MSGCAT_SYNTAX_BEFORE_END_OF_STMT);
/* size of constant string "before ' '\n" to be printed along with the actual context - do not count format
* parameter "%1$s", of size 4 */
int before_context_len = strlen (before_context_str) - 4;
int context_len = strlen (context);
int end_of_statement = 0;
int str_len = 0;
char *s = NULL;
if (context_len > MAX_PRINT_ERROR_CONTEXT_LENGTH)
{
context_len = MAX_PRINT_ERROR_CONTEXT_LENGTH;
memset (buf, 0, MAX_PRINT_ERROR_CONTEXT_LENGTH + 1);
memcpy (buf, context, MAX_PRINT_ERROR_CONTEXT_LENGTH - 3);
strcpy (buf + MAX_PRINT_ERROR_CONTEXT_LENGTH - 3, "...");
context_copy = buf;
}
else
{
context_copy = (char *) context;
}
if ((context_len == 0) || ((context_len == 1) && (*context_copy <= 32)))
{
end_of_statement = 1;
/* size of constant string "before END OF STATEMENT\n" */
str_len = strlen (before_end_of_stmt_str);
}
else
{
str_len = context_len + before_context_len;
}
/* parser_allocate_string_buffer() returns the start pointer of the string buffer. It is guaranteed that the
* length of the buffer 's' is equal to 'str_len + 1'. */
s = (char *) parser_allocate_string_buffer (parser, str_len, sizeof (char));
if (s == NULL)
{
PT_INTERNAL_ERROR (parser, "insufficient memory");
return;
}
if (end_of_statement == 0)
{
/* snprintf will assign the NULL-terminator('\0') to s[str_len]. */
snprintf (s, str_len + 1, before_context_str, context_copy);
if (s[str_len - 3] == '\n')
{
s[str_len - 3] = ' ';
}
}
else
{
strcpy (s, before_end_of_stmt_str);
}
node->info.error_msg.error_message = s;
}
node->info.error_msg.error_message = pt_append_string (parser, node->info.error_msg.error_message, msg);
if (pt_has_error (parser))
{
parser->error_msgs = parser_append_node (node, parser->error_msgs);
}
else
{
parser->error_msgs = node;
}
}
/*
* pt_frob_warning() - creates a new PT_ZZ_ERROR_MSG node appends it
* to parser->error_msgs
* return: none
* parser(in/out): pointer to parser structure
* stmt(in): pointer to a PT_NODE with interesting line and column info in it
* fmt(in): printf-style format string
*
* Note :
* helper function for PT_WARNING macro
*/
void
pt_frob_warning (PARSER_CONTEXT * parser, const PT_NODE * stmt, const char *fmt, ...)
{
va_list ap;
char *old_buf = parser->error_buffer;
va_start (ap, fmt);
vasprintf (&parser->error_buffer, fmt, ap);
va_end (ap);
if (old_buf && parser->error_buffer != old_buf)
{
free (old_buf);
}
pt_record_warning (parser, parser->statement_number, SAFENUM (stmt, line_number), SAFENUM (stmt, column_number),
parser->error_buffer);
}
/*
* pt_frob_error() - creates a new PT_ZZ_ERROR_MSG node appends it
* to parser->error_msgs
* return: none
* parser(in/out): pointer to parser structure
* stmt(in): pointer to a PT_NODE with interesting line and column info in it
* fmt(in): printf-style format string
*
* Note :
* helper function for PT_ERROR macro
*/
void
pt_frob_error (PARSER_CONTEXT * parser, const PT_NODE * stmt, const char *fmt, ...)
{
va_list ap;
const char *context = NULL;
char *old_buf = parser->error_buffer;
va_start (ap, fmt);
vasprintf (&parser->error_buffer, fmt, ap);
va_end (ap);
if (old_buf && parser->error_buffer != old_buf)
{
free (old_buf);
}
if (parser->original_buffer != NULL && stmt != NULL && stmt->buffer_pos != -1)
{
if (strlen (parser->original_buffer) <= stmt->buffer_pos)
{
/* node probably copied from another parser context */
context = NULL;
}
else
{
context = parser->original_buffer + stmt->buffer_pos;
}
}
pt_record_error (parser, parser->statement_number, SAFENUM (stmt, line_number), SAFENUM (stmt, column_number),
parser->error_buffer, context);
}
/*
* pt_get_errors() - returns PT_NODE list or NULL
* return: PT_NODE list if any or NULL
* parser(in): parser context used in query compilation
*/
PT_NODE *
pt_get_errors (PARSER_CONTEXT * parser)
{
if (parser == NULL)
{
return NULL;
}
return parser->error_msgs;
}
/*
* pt_get_next_error() - yield next query compilation error
* return: PT_NODE pointer if there are more errors,
* NULL otherwise.
* errors(in): iterator of query compilation errors
* stmt_no(out): source statement where error was detected
* line_no(out): source line number where error was detected
* col_no(out): source column number where error was detected
* e_msg(out): an explanation of the error
*/
PT_NODE *
pt_get_next_error (PT_NODE * errors, int *stmt_no, int *line_no, int *col_no, const char **msg)
{
if (!errors || errors->node_type != PT_ZZ_ERROR_MSG)
{
return NULL;
}
else
{
*stmt_no = errors->info.error_msg.statement_number;
*line_no = errors->line_number;
*col_no = errors->column_number;
*msg = errors->info.error_msg.error_message;
return errors->next;
}
}
/*
* parser_new_node() -
* return:
* parser(in):
* n(in):
*/
PT_NODE *
parser_new_node (PARSER_CONTEXT * parser, PT_NODE_TYPE node_type)
{
PT_NODE *node;
node = parser_create_node (parser);
if (node)
{
parser_init_node (node, node_type);
pt_parser_line_col (node);
node->sql_user_text = g_query_string;
node->sql_user_text_len = g_query_string_len;
}
return node;
}
/*
* parser_init_node() - initialize a node (Used when initializing the node for the first time after creation)
* return:
* node(in/out):
*/
PT_NODE *
parser_init_node (PT_NODE * node, PT_NODE_TYPE node_type)
{
assert (node != NULL);
assert (node_type < PT_LAST_NODE_NUMBER);
int parser_id = node->parser_id;
memset (node, 0x00, sizeof (PT_NODE));
node->buffer_pos = -1;
node->type_enum = PT_TYPE_NONE;
node->parser_id = parser_id;
node->node_type = node_type;
if (pt_init_f[node_type])
{
node = (pt_init_f[node_type]) (node);
}
return node;
}
/*
* parser_reinit_node() - initialize a node (Used when re-initializing an existing Node while in use)
* return:
* node(in/out):
*/
PT_NODE *
parser_reinit_node (PT_NODE * node)
{
if (node)
{
assert (node->node_type < PT_LAST_NODE_NUMBER);
/* don't write over node_type, parser_id, sql_user_text, sql_user_text_len, cache_time */
int parser_id = node->parser_id;
PT_NODE_TYPE node_type = node->node_type;
char *sql_user_text = node->sql_user_text;
int sql_user_text_len = node->sql_user_text_len;
int line_number = node->line_number;
int column_number = node->column_number;
CACHE_TIME cache_time = node->cache_time;
memset (node, 0x00, sizeof (PT_NODE));
node->buffer_pos = -1;
node->type_enum = PT_TYPE_NONE;
node->parser_id = parser_id;
node->node_type = node_type;
node->sql_user_text = sql_user_text;
node->sql_user_text_len = sql_user_text_len;
node->line_number = line_number;
node->column_number = column_number;
node->cache_time = cache_time;
if (pt_init_f[node->node_type])
{
node = (pt_init_f[node->node_type]) (node);
}
}
return node;
}
/*
* pt_print_bytes_alias() -
* return:
* parser(in):
* node(in):
*/
PARSER_VARCHAR *
pt_print_bytes_alias (PARSER_CONTEXT * parser, const PT_NODE * node)
{
if (!node)
{
return NULL;
}
if (node->alias_print)
{
return pt_append_name (parser, NULL, node->alias_print);
}
else
{
return pt_print_bytes (parser, node);
}
}
/*
* pt_print_bytes() -
* return:
* parser(in):
* node(in):
*/
PARSER_VARCHAR *
pt_print_bytes (PARSER_CONTEXT * parser, const PT_NODE * node)
{
PT_NODE_TYPE t;
PARSER_PRINT_NODE_FUNC f;
PARSER_VARCHAR *result = NULL;
if (!node)
{
return NULL;
}
CAST_POINTER_TO_NODE (node);
if (node->flag.is_cnf_start && !parser->flag.is_in_and_list)
{
return pt_print_and_list (parser, node);
}
t = node->node_type;
if (t >= PT_LAST_NODE_NUMBER || !(f = pt_print_f[t]))
{
return NULL;
}
/* avoid recursion */
if (parser->flag.is_in_and_list)
{
parser->flag.is_in_and_list = 0;
result = f (parser, (PT_NODE *) node);
parser->flag.is_in_and_list = 1;
return result;
}
else
{
return f (parser, (PT_NODE *) node);
}
}
/*
* pt_print_bytes_l() - PRINT equivalent text for lists
* return:
* parser(in):
* p(in):
*/
PARSER_VARCHAR *
pt_print_bytes_l (PARSER_CONTEXT * parser, const PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r, *prev;
PT_STRING_BLOCK sb;
sb.body = NULL;
sb.length = 0;
sb.size = 1024;
if (!p)
{
return NULL;
}
prev = pt_print_bytes (parser, p);
if (p->flag.is_cnf_start)
{
return prev;
}
sb.body = (char *) malloc (sb.size);
if (sb.body == NULL)
{
return NULL;
}
sb.body[0] = 0;
if (prev)
{
strcat_with_realloc (&sb, (const char *) prev->bytes);
}
while (p->next)
{ /* print in the original order ... */
p = p->next;
r = pt_print_bytes (parser, p);
if (r)
{
if (prev)
{
strcat_with_realloc (&sb, ", ");
}
strcat_with_realloc (&sb, (const char *) r->bytes);
prev = r;
}
if (0 < parser->max_print_len && parser->max_print_len < sb.length)
{
/* to help early break */
break;
}
}
if (sb.length > 0)
{
q = pt_append_nulstring (parser, q, sb.body);
}
free (sb.body);
return q;
}
/*
* pt_print_bytes_spec_list() -
* return:
* parser(in):
* p(in):
*/
PARSER_VARCHAR *
pt_print_bytes_spec_list (PARSER_CONTEXT * parser, const PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r;
if (!p)
{
return 0;
}
q = pt_print_bytes (parser, p);
while (p->next)
{ /* print in the original order ... */
p = p->next;
r = pt_print_bytes (parser, p);
if (p->node_type == PT_SPEC)
{
switch (p->info.spec.join_type)
{
case PT_JOIN_NONE:
q = pt_append_bytes (parser, q, ", ", 2);
break;
case PT_JOIN_CROSS:
/* case PT_JOIN_NATURAL: -- does not support */
case PT_JOIN_INNER:
case PT_JOIN_LEFT_OUTER:
case PT_JOIN_RIGHT_OUTER:
case PT_JOIN_FULL_OUTER:
break;
/* case PT_JOIN_UNION: -- does not support */
default:
q = pt_append_bytes (parser, q, ", ", 2);
break;
}
}
else
{
q = pt_append_bytes (parser, q, ", ", 2);
}
q = pt_append_varchar (parser, q, r);
}
return q;
}
/*
* pt_print_node_value () -
* return: const sql string customized
* parser(in):
* val(in):
*/
PARSER_VARCHAR *
pt_print_node_value (PARSER_CONTEXT * parser, const PT_NODE * val)
{
PARSER_VARCHAR *q = NULL;
DB_VALUE *db_val, new_db_val;
DB_TYPE db_typ;
int error = NO_ERROR;
SETOBJ *setobj;
if (val->node_type != PT_VALUE && val->node_type != PT_HOST_VAR
&& (val->node_type != PT_NAME || val->info.name.meta_class != PT_PARAMETER))
{
return NULL;
}
if (parser->custom_print & PT_PRINT_ORIGINAL_BEFORE_CONST_FOLDING && val->expr_before_const_folding != NULL)
{
return val->expr_before_const_folding;
}
db_val = pt_value_to_db (parser, (PT_NODE *) val);
if (!db_val)
{
return NULL;
}
db_typ = DB_VALUE_DOMAIN_TYPE (db_val);
if (val->type_enum == PT_TYPE_OBJECT)
{
switch (db_typ)
{
case DB_TYPE_OBJECT:
vid_get_keys (db_get_object (db_val), &new_db_val);
db_val = &new_db_val;
break;
case DB_TYPE_VOBJ:
/* don't want a clone of the db_value, so use lower level functions */
error = set_get_setobj (db_get_set (db_val), &setobj, 0);
if (error >= 0)
{
error = setobj_get_element_ptr (setobj, 2, &db_val);
}
break;
default:
break;
}
if (error < 0)
{
PT_ERRORc (parser, val, er_msg ());
}
if (db_val)
{
db_typ = DB_VALUE_DOMAIN_TYPE (db_val);
}
}
q = pt_print_db_value (parser, db_val);
return q;
}
/*
* pt_print_db_value () -
* return: const sql string customized
* parser(in):
* val(in):
*/
PARSER_VARCHAR *
pt_print_db_value (PARSER_CONTEXT * parser, const struct db_value * val)
{
PARSER_VARCHAR *temp = NULL, *result = NULL;
int i, size = 0;
DB_VALUE element;
int error = NO_ERROR;
unsigned int save_custom = parser->custom_print;
parser_block_allocator alloc (parser);
string_buffer sb (alloc);
db_value_printer printer (sb);
if (val == NULL)
{
return NULL;
}
/* set custom_print here so describe_data() will know to pad bit strings to full bytes */
parser->custom_print = parser->custom_print | PT_PAD_BYTE;
switch (DB_VALUE_TYPE (val))
{
case DB_TYPE_SET:
case DB_TYPE_MULTISET:
sb ("%s", pt_show_type_enum (pt_db_to_type_enum (DB_VALUE_TYPE (val))));
[[fallthrough]];
case DB_TYPE_SEQUENCE:
sb ("{");
size = db_set_size (db_get_set ((DB_VALUE *) val));
if (size > 0)
{
error = db_set_get (db_get_set ((DB_VALUE *) val), 0, &element);
printer.describe_value (&element);
for (i = 1; i < size; i++)
{
error = db_set_get (db_get_set ((DB_VALUE *) val), i, &element);
sb (", ");
printer.describe_value (&element);
}
}
sb ("}");
break;
case DB_TYPE_OBJECT:
/* no printable representation!, should not get here */
sb ("NULL");
break;
case DB_TYPE_MONETARY:
/* This is handled explicitly because describe_value will add a currency symbol, and it isn't needed here. */
printer.describe_money (db_get_monetary ((DB_VALUE *) val));
break;
case DB_TYPE_BIT:
case DB_TYPE_VARBIT:
/* csql & everyone else get X'some_hex_string' */
printer.describe_value (val);
break;
case DB_TYPE_DATE:
/* csql & everyone else want DATE'mm/dd/yyyy' */
printer.describe_value (val);
break;
case DB_TYPE_TIME:
/* csql & everyone else get time 'hh:mi:ss' */
printer.describe_value (val);
break;
case DB_TYPE_TIMESTAMP:
case DB_TYPE_TIMESTAMPTZ:
case DB_TYPE_TIMESTAMPLTZ:
/* everyone else gets csql's utime format */
printer.describe_value (val);
break;
case DB_TYPE_DATETIME:
case DB_TYPE_DATETIMETZ:
case DB_TYPE_DATETIMELTZ:
/* everyone else gets csql's utime format */
printer.describe_value (val);
break;
default:
printer.describe_value (val);
break;
}
/* restore custom print */
parser->custom_print = save_custom;
result = pt_append_nulstring (parser, NULL, sb.get_buffer ());
return result;
}
/*
* pt_print_alias() -
* return:
* parser(in):
* node(in):
*/
char *
pt_print_alias (PARSER_CONTEXT * parser, const PT_NODE * node)
{
PARSER_VARCHAR *string;
string = pt_print_bytes_alias (parser, node);
if (string)
{
return (char *) string->bytes;
}
return NULL;
}
static PARSER_VARCHAR *
pt_conv_server_2_hash_text (PARSER_CONTEXT * parser)
{
unsigned int hash1 = 5381;
unsigned int hash2 = 5381;
unsigned char *s, *ps;
char buf[64];
assert (parser->dblink_server_text != NULL);
assert (parser->dblink_server_text->bytes != NULL);
ps = parser->dblink_server_text->bytes;
if (!ps || *ps == '\0')
{
return NULL;
}
// original
for (s = ps; *s; ++s)
{
hash1 = ((hash1 << 5) + hash1) + *s; /* hash * 33 + c */
}
// reverse
for (s--; s >= ps; s--)
{
hash2 = ((hash2 << 5) - hash2) + *s; /* hash * 31 + c */
}
sprintf (buf, "%u,%u", hash1, hash2);
return pt_append_nulstring (parser, NULL, buf);
}
/*
* parser_print_tree() -
* return:
* parser(in):
* node(in):
*/
char *
parser_print_tree (PARSER_CONTEXT * parser, const PT_NODE * node)
{
#define PT_QUERY_STRING_USER_TEXT ( \
5 /* user= */ \
+ 6 /* volid| (values up to 16384) */ \
+ 11 /* pageid| (values up to 2147483647) */ \
+ 5 /* slotid (values up to 16384) */ \
+ 1 /* \0 */)
PARSER_VARCHAR *string;
char user_text_buffer[PT_QUERY_STRING_USER_TEXT];
assert (parser->dblink_server_text == NULL);
string = pt_print_bytes (parser, node);
if (string)
{
if ((parser->custom_print & PT_PRINT_DIFFERENT_SYSTEM_PARAMETERS) != 0)
{
char *str = sysprm_print_parameters_for_qry_string ();
string = pt_append_nulstring (parser, string, "?");
string = pt_append_nulstring (parser, string, str);
free_and_init (str);
}
if ((parser->custom_print & PT_PRINT_USER) != 0)
{
/* Print user text. */
if (parser_print_user (user_text_buffer, PT_QUERY_STRING_USER_TEXT) > 0)
{
string = pt_append_nulstring (parser, string, user_text_buffer);
}
}
if ((parser->custom_print & PT_PRINT_HOST_VAR_COUNT) != 0)
{
char host_var_count[12];
if ((node->info.query.is_subquery == PT_IS_SUBQUERY || node->info.query.is_subquery == PT_IS_UNION_QUERY
|| node->info.query.is_subquery == PT_IS_UNION_SUBQUERY
|| node->info.query.is_subquery == PT_IS_CTE_NON_REC_SUBQUERY) && node->info.query.correlation_level == 0
&& (node->info.query.hint & PT_HINT_QUERY_CACHE))
{
/*
* This condition is identical to the one used in do_prepare_subquery_pre function to call do_prepare_subquery.
* Both functions must maintain the same condition to ensure consistency.
* Be careful not to modify only one of them.
*/
snprintf (host_var_count, sizeof (host_var_count), "%d", parser->host_var_count);
}
else
{
snprintf (host_var_count, sizeof (host_var_count), "%d",
parser->host_var_count + parser->auto_param_count);
}
string = pt_append_nulstring (parser, string, ";bind_var_cnt=");
string = pt_append_nulstring (parser, string, host_var_count);
}
if ((parser->custom_print & PT_PRINT_DBLINK_INFO) && parser->dblink_server_text)
{
string = pt_append_nulstring (parser, string, ";remote={");
string = pt_append_varchar (parser, string, pt_conv_server_2_hash_text (parser));
string = pt_append_bytes (parser, string, "}", 1);
parser->dblink_server_text = NULL;
}
return (char *) string->bytes;
}
return NULL;
#undef PT_QUERY_STRING_USER_TEXT
}
/*
* parser_print_user () - Create a text to include user in query string.
*
* return : Size of user text.
* user_text (in) : User text.
* len (in) : Size of buffer.
*/
static int
parser_print_user (char *user_text, int len)
{
char *p = user_text;
OID *oid = ws_identifier (db_get_user ());
memset (user_text, 0, len);
if (oid == NULL)
{
return 0;
}
return snprintf (p, len - 1, "user=%d|%d|%d", oid->volid, oid->pageid, oid->slotid);
}
/*
* parser_print_tree_with_quotes() -
* return:
* parser(in):
* node(in):
*/
char *
parser_print_tree_with_quotes (PARSER_CONTEXT * parser, const PT_NODE * node)
{
PARSER_VARCHAR *string;
unsigned int save_custom;
save_custom = parser->custom_print;
parser->custom_print |= PT_PRINT_QUOTES;
string = pt_print_bytes (parser, node);
parser->custom_print = save_custom;
if (string)
{
return (char *) string->bytes;
}
return NULL;
}
/*
* parser_print_function_index_expr () - prints function index candidate
* expressions
*
* return: printed expression as char *
* parser: parser context
* expr: candidate expression for function index
*
* NOTE: PT_NAME nodes will not print info.name.resolved, they will use
* the original table name in order to match the expression with
* the function based index
*/
char *
parser_print_function_index_expr (PARSER_CONTEXT * parser, const PT_NODE * expr)
{
unsigned int save_custom = parser->custom_print;
char *result;
assert (expr && PT_IS_EXPR_NODE (expr));
parser->custom_print |= PT_FORCE_ORIGINAL_TABLE_NAME | PT_CHARSET_COLLATE_FULL;
result = parser_print_tree_with_quotes (parser, expr);
parser->custom_print = save_custom;
return result;
}
/*
* parser_print_tree_list() -
* return:
* parser(in):
* node(in):
*/
char *
parser_print_tree_list (PARSER_CONTEXT * parser, const PT_NODE * node)
{
PARSER_VARCHAR *string;
string = pt_print_bytes_l (parser, node);
if (string)
{
return (char *) string->bytes;
}
return NULL;
}
/*
* pt_print_and_list() - PRINT equivalent text for CNF predicate lists
* return:
* parser(in):
* p(in):
*/
PARSER_VARCHAR *
pt_print_and_list (PARSER_CONTEXT * parser, const PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
const PT_NODE *n;
if (!p)
{
return NULL;
}
parser->flag.is_in_and_list = 1;
for (n = p; n; n = n->next)
{ /* print in the original order ... */
r1 = pt_print_bytes (parser, n);
if (n->node_type == PT_EXPR && !n->info.expr.paren_type && n->or_next)
{
/* found non-parenthesis OR */
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
else
{
q = pt_append_varchar (parser, q, r1);
}
if (n->next)
{
q = pt_append_nulstring (parser, q, " and ");
}
}
parser->flag.is_in_and_list = 0;
return q;
}
/*
* pt_print_query_spec_no_list() - prints query specifications
* with NA placeholders
* return:
* parser(in):
* node(in):
*/
char *
pt_print_query_spec_no_list (PARSER_CONTEXT * parser, const PT_NODE * node)
{
unsigned int save_custom = parser->custom_print;
char *result;
parser->custom_print |= PT_SUPPRESS_SELECT_LIST | PT_SUPPRESS_INTO | PT_CHARSET_COLLATE_FULL;
result = parser_print_tree_with_quotes (parser, node);
parser->custom_print = save_custom;
return result;
}
/*
* pt_short_print() - Short print (for error messages)
* return:
* parser(in):
* node(in):
*/
char *
pt_short_print (PARSER_CONTEXT * parser, const PT_NODE * node)
{
char *str;
const int max_print_len = 64;
parser->max_print_len = max_print_len;
str = parser_print_tree (parser, node);
if (str == NULL)
{
goto end;
}
if (strlen (str) > max_print_len)
{
strcpy (str + 60, "...");
}
end:
parser->max_print_len = 0; /* restore */
return str;
}
/*
* pt_short_print_l() -
* return:
* parser(in):
* node(in):
*/
char *
pt_short_print_l (PARSER_CONTEXT * parser, const PT_NODE * node)
{
char *str;
const int max_print_len = 64;
parser->max_print_len = max_print_len;
str = parser_print_tree_list (parser, node);
if (str == NULL)
{
goto end;
}
if (strlen (str) > max_print_len)
{
strcpy (str + 60, "...");
}
end:
parser->max_print_len = 0; /* restore */
return str;
}
/*
* pt_show_node_type() -
* return: English name of the node type (for debugging)
* node(in):
*/
const char *
pt_show_node_type (PT_NODE * node)
{
if (!node)
{
return "null_pointer";
}
switch (node->node_type)
{
case PT_ALTER:
return "ALTER";
case PT_ALTER_INDEX:
return "ALTER_INDEX";
case PT_ALTER_USER:
return "ALTER_USER";
case PT_ALTER_TRIGGER:
return "ALTER_TRIGGER";
case PT_2PC_ATTACH:
return "ATTACH";
case PT_ATTR_DEF:
return "ATTR_DEF";
case PT_ATTR_ORDERING:
return "ATTR_ORDERING";
case PT_AUTH_CMD:
return "AUTH CMD";
case PT_COMMIT_WORK:
return "COMMIT_WORK";
case PT_CREATE_ENTITY:
return "CREATE_ENTITY";
case PT_CREATE_INDEX:
return "CREATE_INDEX";
case PT_UPDATE_HISTOGRAM:
return "update_histogram";
case PT_SHOW_HISTOGRAM:
return "show histogram";
case PT_DROP_HISTOGRAM:
return "DROP_HISTOGRAM";
case PT_CREATE_USER:
return "CREATE_USER";
case PT_CREATE_TRIGGER:
return "CREATE_TRIGGER";
case PT_DATA_DEFAULT:
return "DATA_DEFAULT";
case PT_DATA_TYPE:
return "DATA_TYPE";
case PT_DELETE:
return "DELETE";
case PT_DIFFERENCE:
return "DIFFERENCE";
case PT_DOT_:
return "DOT_";
case PT_DROP:
return "DROP";
case PT_DROP_INDEX:
return "DROP_INDEX";
case PT_DROP_USER:
return "DROP_USER";
case PT_DROP_TRIGGER:
return "DROP TRIGGER";
case PT_EVENT_OBJECT:
return "EVENT_OBJECT";
case PT_EVENT_SPEC:
return "EVENT_SPEC";
case PT_EVENT_TARGET:
return "EVENT_TARGET";
case PT_EXECUTE_TRIGGER:
return "EXECUTE_TRIGGER";
case PT_EXPR:
return "EXPR";
case PT_FILE_PATH:
return "FILE_PATH";
case PT_FUNCTION:
return "FUNCTION";
case PT_GET_OPT_LVL:
return "GET OPT LEVEL";
case PT_GET_XACTION:
return "GET TRANSACTION";
case PT_GRANT:
return "GRANT";
case PT_HOST_VAR:
return "HOST_VAR";
case PT_INSERT:
return "INSERT";
case PT_INTERSECTION:
return "INTERSECTION";
case PT_ISOLATION_LVL:
return "ISOLATION LEVEL";
case PT_MERGE:
return "MERGE";
case PT_METHOD_CALL:
return "METHOD CALL";
case PT_METHOD_DEF:
return "METHOD_DEF";
case PT_NAME:
return "NAME";
case PT_NAMED_ARG:
return "NAMED_ARG";
case PT_PREPARE_TO_COMMIT:
return "PREPARE TO COMMIT";
case PT_PREPARE_STATEMENT:
return "PREPARE";
case PT_EXECUTE_PREPARE:
return "EXECUTE";
case PT_DEALLOCATE_PREPARE:
return "DROP";
case PT_REMOVE_TRIGGER:
return "REMOVE_TRIGGER";
case PT_RENAME:
return "RENAME";
case PT_RESOLUTION:
return "RESOLUTION";
case PT_REVOKE:
return "REVOKE";
case PT_ROLLBACK_WORK:
return "ROLLBACK_WORK";
case PT_SAVEPOINT:
return "SAVEPOINT";
case PT_SELECT:
return "SELECT";
case PT_SET_NAMES:
return "SET NAMES";
case PT_SET_TIMEZONE:
return "SET TIMEZONE";
case PT_SET_OPT_LVL:
return "SET OPT LVL";
case PT_SET_SYS_PARAMS:
return "SET SYSTEM PARAMETERS";
case PT_SET_XACTION:
return "SET TRANSACTION";
case PT_SHOWSTMT:
return "SHOW";
case PT_SORT_SPEC:
return "SORT_SPEC";
case PT_SPEC:
return "SPEC";
case PT_TIMEOUT:
return "TIMEOUT";
case PT_TRIGGER_ACTION:
return "TRIGGER_ACTION";
case PT_TRIGGER_SPEC_LIST:
return "TRIGGER_SPEC_LIST";
case PT_TRUNCATE:
return "TRUNCATE";
case PT_DO:
return "DO";
case PT_UNION:
return "UNION";
case PT_UPDATE:
return "UPDATE";
case PT_UPDATE_STATS:
return "UPDATE_STATS";
case PT_GET_STATS:
return "GET_STATS";
#if defined (ENABLE_UNUSED_FUNCTION)
case PT_USE:
return "USE";
#endif
case PT_VALUE:
return "VALUE";
case PT_CONSTRAINT:
return "CONSTRAINT";
case PT_PARTITION:
return "PARTITION";
case PT_PARTS:
return "PARTS";
case PT_NODE_LIST:
return "NODE_LIST";
case PT_VACUUM:
return "VACUUM";
case PT_WITH_CLAUSE:
return "WITH";
case PT_CTE:
return "CTE";
case PT_DBLINK_TABLE:
return "DBLINK";
case PT_DBLINK_TABLE_DML:
return "DBLINK_DML";
case PT_CREATE_SERVER:
return "CREATE_SERVER";
case PT_DROP_SERVER:
return "DROP_SERVER";
case PT_RENAME_SERVER:
return "RENAME_SERVER";
case PT_ALTER_SERVER:
return "ALTER_SERVER";
default:
return "NODE: type unknown";
}
}
/*
* parser_append_node() -
* return:
* node(in/out):
* list(in):
*/
PT_NODE *
parser_append_node (PT_NODE * node, PT_NODE * list)
{
if (list)
{
PT_NODE *tail;
tail = list;
while (tail->next)
{
tail = tail->next;
}
tail->next = node;
}
else
{
list = node;
}
return list;
}
/*
* parser_append_previous_node() -
* return:
* node(in):
* list(in):
*/
PT_NODE *
parser_append_previous_node (PT_NODE * node, PT_NODE * list)
{
if (list)
{
node->next = list;
list = node;
}
else
{
list = node;
}
return list;
}
/*
* parser_append_node_or() -
* return:
* node(in/out):
* list(in):
*/
PT_NODE *
parser_append_node_or (PT_NODE * node, PT_NODE * list)
{
if (list)
{
PT_NODE *tail;
tail = list;
while (tail->or_next)
{
tail = tail->or_next;
}
tail->or_next = node;
}
else
{
list = node;
}
return list;
}
/*
* pt_length_of_list() -
* return:
* list(in):
*/
int
pt_length_of_list (const PT_NODE * list)
{
int len;
for (len = 0; list; len++)
{
list = list->next;
}
return len;
}
/*
* pt_length_of_select_list() -
* return:
* list(in):
* hidden_col(in):
*/
int
pt_length_of_select_list (PT_NODE * list, int hidden_col)
{
int len;
if (hidden_col == INCLUDE_HIDDEN_COLUMNS)
{
for (len = 0; list; len++)
{
list = list->next;
}
return len;
}
else
{ /* EXCLUDE_HIDDEN_COLUMNS */
for (len = 0; list; list = list->next)
{
if (list->flag.is_hidden_column)
{
/* skip hidden column */
continue;
}
len++;
}
return len;
}
}
/*
* pt_get_node_from_list - get node from list, based on index
* return: the node at position specified by index or NULL
* list(in): node list
* index(in): index of requested node
*/
PT_NODE *
pt_get_node_from_list (PT_NODE * list, int index)
{
if (list == NULL || index < 0)
{
return NULL;
}
while (list && index > 0)
{
list = list->next;
index--;
}
return list;
}
/*
* pt_show_misc_type() - English name of the node type (for debugging)
* return:
* c(in):
*/
const char *
pt_show_misc_type (PT_MISC_TYPE p)
{
switch (p)
{
case PT_MISC_DUMMY:
return "";
case PT_ACTIVE:
return "active";
case PT_INACTIVE:
return "inactive";
case PT_AFTER:
return "after";
case PT_BEFORE:
return "before";
case PT_DEFERRED:
return "deferred";
case PT_INVALIDATE_XACTION:
return "invalidate transaction";
case PT_PRINT:
return "print";
case PT_REJECT:
return "reject";
case PT_ALL:
return "all";
case PT_ONLY:
return "only";
case PT_DISTINCT:
return "distinct";
case PT_SHARED:
return "shared";
case PT_DEFAULT:
return "default";
case PT_ASC:
return "asc";
case PT_DESC:
return "desc";
case PT_GRANT_OPTION:
return "with grant option";
case PT_NO_GRANT_OPTION:
return "with no grant option";
case PT_CLASS:
return "class";
case PT_VCLASS:
return "vclass";
case PT_NORMAL:
return "";
case PT_META_CLASS:
return "class";
case PT_META_ATTR:
return "class";
case PT_IS_SUBQUERY:
case PT_IS_SUBINSERT:
case PT_IS_VALUE:
return "";
case PT_ATTRIBUTE:
return "attribute";
case PT_METHOD:
return "method";
case PT_FUNCTION_RENAME:
return "function";
case PT_FILE_RENAME:
return "file";
case PT_NO_ISOLATION_LEVEL:
return "no isolation level";
case PT_SERIALIZABLE:
return "serializable";
case PT_REPEATABLE_READ:
return "repeatable read";
case PT_READ_COMMITTED:
return "read committed";
case PT_ISOLATION_LEVEL:
return "isolation level";
case PT_LOCK_TIMEOUT:
return "lock timeout";
case PT_CHAR_STRING:
return "";
case PT_BIT_STRING:
return "";
case PT_HEX_STRING:
return "";
case PT_MATCH_REGULAR:
return "";
case PT_MATCH_FULL:
return "match full";
case PT_MATCH_PARTIAL:
return "match partial";
case PT_RULE_CASCADE:
return "cascade";
case PT_RULE_RESTRICT:
return "restrict";
case PT_RULE_SET_NULL:
return "set null";
case PT_RULE_NO_ACTION:
return "no action";
case PT_TRIGGER_TRACE:
return "trace";
case PT_TRIGGER_DEPTH:
return "depth";
case PT_YEAR:
return "year";
case PT_MONTH:
return "month";
case PT_DAY:
return "day";
case PT_HOUR:
return "hour";
case PT_MINUTE:
return "minute";
case PT_SECOND:
return "second";
case PT_MILLISECOND:
return "millisecond";
case PT_SIMPLE_CASE:
return "simple case";
case PT_SEARCHED_CASE:
return "searched case";
case PT_OPT_LVL:
return "level";
case PT_OPT_COST:
return "cost";
case PT_SP_FUNCTION:
return "function";
case PT_SP_PROCEDURE:
return "procedure";
case PT_NOPUT:
return "";
case PT_INPUT:
return "";
case PT_OUTPUT:
return "out";
case PT_INPUTOUTPUT:
return "inout";
case PT_CONSTRAINT_NAME:
return "constraint";
case PT_INDEX_NAME:
return "index";
case PT_TRACE_ON:
return "on";
case PT_TRACE_OFF:
return "off";
case PT_TRACE_FORMAT_TEXT:
return "text";
case PT_TRACE_FORMAT_JSON:
return "json";
case PT_PRIVATE:
return "private";
case PT_PUBLIC:
return "public";
case PT_SYNONYM:
return "synonym";
default:
return "MISC_TYPE: type unknown";
}
}
/*
* pt_show_binopcode() -
* return:
* n(in):
*/
const char *
pt_show_binopcode (PT_OP_TYPE n)
{
switch (n)
{
case PT_FUNCTION_HOLDER:
assert (false);
return "";
case PT_AND:
return " and ";
case PT_OR:
return " or ";
case PT_NOT:
return " not ";
case PT_XOR:
return " xor ";
case PT_BETWEEN:
return " between ";
case PT_NOT_BETWEEN:
return " not between ";
case PT_BETWEEN_AND:
return " and ";
case PT_BETWEEN_GE_LE:
return " ge_le ";
case PT_BETWEEN_GE_LT:
return " ge_lt ";
case PT_BETWEEN_GT_LE:
return " gt_le ";
case PT_BETWEEN_GT_LT:
return " gt_lt ";
case PT_BETWEEN_EQ_NA:
return " = ";
case PT_BETWEEN_INF_LE:
return " inf_le ";
case PT_BETWEEN_INF_LT:
return " inf_lt ";
case PT_BETWEEN_GE_INF:
return " ge_inf ";
case PT_BETWEEN_GT_INF:
return " gt_inf ";
case PT_RANGE:
return " range ";
case PT_LIKE:
return " like ";
case PT_NOT_LIKE:
return " not like ";
case PT_LIKE_ESCAPE:
return " escape ";
case PT_RLIKE:
return " regexp ";
case PT_NOT_RLIKE:
return " not regexp ";
case PT_RLIKE_BINARY:
return " regexp binary ";
case PT_NOT_RLIKE_BINARY:
return " not regexp binary ";
case PT_IS_IN:
return " in ";
case PT_IS:
return " is ";
case PT_IS_NOT:
return " is not ";
case PT_IS_NOT_IN:
return " not in ";
case PT_IS_NULL:
return " is null ";
case PT_IS_NOT_NULL:
return " is not null ";
case PT_EXISTS:
return " exists ";
case PT_EQ_SOME:
return "= any ";
case PT_EQ_ALL:
return "= all ";
case PT_EQ:
return "=";
case PT_NULLSAFE_EQ:
return "<=>";
case PT_NE_SOME:
return "<> any ";
case PT_NE_ALL:
return "<> all ";
case PT_NE:
return "<>";
case PT_GE_SOME:
return ">= any ";
case PT_GE_ALL:
return ">= all ";
case PT_GE:
return ">=";
case PT_GT_SOME:
return "> any ";
case PT_GT_ALL:
return "> all ";
case PT_GT:
return ">";
case PT_LT_SOME:
return "< any ";
case PT_LT_ALL:
return "< all ";
case PT_LT:
return "<";
case PT_LE_SOME:
return "<= any ";
case PT_LE_ALL:
return "<= all ";
case PT_LE:
return "<=";
case PT_SETEQ:
return " seteq ";
case PT_SETNEQ:
return " setneq ";
case PT_SUBSET:
return " subset ";
case PT_SUBSETEQ:
return " subseteq ";
case PT_SUPERSET:
return " superset ";
case PT_SUPERSETEQ:
return " superseteq ";
case PT_BIT_NOT:
return "~";
case PT_BIT_AND:
return "&";
case PT_BIT_OR:
return "|";
case PT_BIT_XOR:
return "^";
case PT_BITSHIFT_LEFT:
return "<<";
case PT_BITSHIFT_RIGHT:
return ">>";
case PT_DIV:
return " div ";
case PT_MOD:
return " mod ";
case PT_BIT_COUNT:
return "bit_count ";
case PT_PLUS:
return "+";
case PT_MINUS:
return "-";
case PT_TIMES:
return "*";
case PT_DIVIDE:
return "/";
case PT_UNARY_MINUS:
return "-";
case PT_PRIOR:
return "prior ";
case PT_CONNECT_BY_ROOT:
return "connect_by_root ";
case PT_QPRIOR:
return "prior ";
case PT_ASSIGN:
return "=";
case PT_MODULUS:
return "mod ";
case PT_RAND:
return "rand ";
case PT_DRAND:
return "drand ";
case PT_RANDOM:
return "random ";
case PT_DRANDOM:
return "drandom ";
case PT_FLOOR:
return "floor ";
case PT_CEIL:
return "ceil ";
case PT_SIGN:
return "sign ";
case PT_POWER:
return "power ";
case PT_ROUND:
return "round ";
case PT_LOG:
return "log ";
case PT_EXP:
return "exp ";
case PT_SQRT:
return "sqrt ";
case PT_TRUNC:
return "trunc ";
case PT_ABS:
return "abs ";
case PT_CHR:
return "chr ";
case PT_INSTR:
return "instr ";
case PT_LEAST:
return "least ";
case PT_GREATEST:
return "greatest ";
case PT_POSITION:
return "position ";
case PT_FINDINSET:
return "find_in_set ";
case PT_SUBSTRING:
return "substring ";
case PT_SUBSTRING_INDEX:
return "substring_index ";
case PT_OCTET_LENGTH:
return "octet_length ";
case PT_BIT_LENGTH:
return "bit_length ";
case PT_CHAR_LENGTH:
return "char_length ";
case PT_IF:
return "if ";
case PT_IFNULL:
return "ifnull ";
case PT_ISNULL:
return "isnull ";
case PT_DEGREES:
return "degrees ";
case PT_RADIANS:
return "radians ";
case PT_PI:
return "pi ";
case PT_ACOS:
return "acos ";
case PT_ASIN:
return "asin ";
case PT_ATAN:
return "atan ";
case PT_ATAN2:
return "atan2 ";
case PT_SIN:
return "sin ";
case PT_COS:
return "cos ";
case PT_COT:
return "cot ";
case PT_TAN:
return "tan ";
case PT_LN:
return "ln ";
case PT_LOG2:
return "log2 ";
case PT_LOG10:
return "log10 ";
case PT_FORMAT:
return "format ";
case PT_DATE_ADD:
return "date_add ";
case PT_ADDDATE:
return "adddate ";
case PT_DATE_SUB:
return "date_sub ";
case PT_SUBDATE:
return "subdate ";
case PT_DATE_FORMAT:
return "date_format ";
case PT_STR_TO_DATE:
return "str_to_date ";
case PT_TIME_FORMAT:
return "time_format ";
case PT_DATEF:
return "date ";
case PT_TIMEF:
return "time ";
case PT_DATEDIFF:
return "datediff ";
case PT_TIMEDIFF:
return "timediff ";
case PT_CONCAT:
return "concat ";
case PT_CONCAT_WS:
return "concat_ws ";
case PT_FIELD:
return "field ";
case PT_LEFT:
return "left ";
case PT_RIGHT:
return "right ";
case PT_LOCATE:
return "locate ";
case PT_MID:
return "mid ";
case PT_STRCMP:
return "strcmp ";
case PT_REVERSE:
return "reverse ";
case PT_DISK_SIZE:
return "disk_size ";
case PT_LIKE_LOWER_BOUND:
return "like_match_lower_bound ";
case PT_LIKE_UPPER_BOUND:
return "like_match_upper_bound ";
case PT_LOWER:
return "lower ";
case PT_UPPER:
return "upper ";
case PT_HEX:
return "hex ";
case PT_ASCII:
return "ascii ";
case PT_CONV:
return "conv ";
case PT_MD5:
return "md5 ";
case PT_AES_ENCRYPT:
return "aes_encrypt ";
case PT_AES_DECRYPT:
return "aes_decrypt ";
case PT_SHA_ONE:
return "sha1 ";
case PT_SHA_TWO:
return "sha2 ";
case PT_TO_BASE64:
return "to_base64 ";
case PT_FROM_BASE64:
return "from_base64 ";
case PT_BIN:
return "bin ";
case PT_TRIM:
return "trim ";
case PT_LTRIM:
return "ltrim ";
case PT_RTRIM:
return "rtrim ";
case PT_LPAD:
return "lpad ";
case PT_RPAD:
return "rpad ";
case PT_REPEAT:
return "repeat ";
case PT_SPACE:
return "space ";
case PT_REPLACE:
return "replace ";
case PT_TRANSLATE:
return "translate ";
case PT_SYS_CONNECT_BY_PATH:
return "sys_connect_by_path ";
case PT_ADD_MONTHS:
return "add_months ";
case PT_LAST_DAY:
return "last_day ";
case PT_MONTHS_BETWEEN:
return "months_between ";
case PT_SYS_DATE:
return "sys_date ";
case PT_CURRENT_DATE:
return "current_date ";
case PT_SYS_TIME:
return "sys_time ";
case PT_CURRENT_TIME:
return "current_time ";
case PT_SYS_TIMESTAMP:
return "sys_timestamp ";
case PT_CURRENT_TIMESTAMP:
return "current_timestamp ";
case PT_SYS_DATETIME:
return "sys_datetime ";
case PT_CURRENT_DATETIME:
return "current_datetime ";
case PT_UTC_TIME:
return "utc_time ";
case PT_UTC_DATE:
return "utc_date ";
case PT_TO_CHAR:
return "to_char ";
case PT_TO_DATE:
return "to_date ";
case PT_TO_TIME:
return "to_time ";
case PT_TO_TIMESTAMP:
return "to_timestamp ";
case PT_TIMESTAMP:
return "timestamp ";
case PT_YEARF:
return "year ";
case PT_MONTHF:
return "month ";
case PT_DAYF:
return "day ";
case PT_DAYOFMONTH:
return "dayofmonth ";
case PT_HOURF:
return "hour ";
case PT_MINUTEF:
return "minute ";
case PT_SECONDF:
return "second ";
case PT_UNIX_TIMESTAMP:
return "unix_timestamp ";
case PT_FROM_UNIXTIME:
return "from_unixtime ";
case PT_QUARTERF:
return "quarter ";
case PT_WEEKDAY:
return "weekday ";
case PT_DAYOFWEEK:
return "dayofweek ";
case PT_DAYOFYEAR:
return "dayofyear ";
case PT_TODAYS:
return "to_days ";
case PT_FROMDAYS:
return "from_days ";
case PT_TIMETOSEC:
return "time_to_sec ";
case PT_SECTOTIME:
return "sec_to_time ";
case PT_MAKEDATE:
return "makedate ";
case PT_MAKETIME:
return "maketime ";
case PT_ADDTIME:
return "addtime ";
case PT_WEEKF:
return "week ";
case PT_SCHEMA:
return "schema ";
case PT_DATABASE:
return "database ";
case PT_VERSION:
return "version ";
case PT_TO_DATETIME:
return "to_datetime ";
case PT_TO_NUMBER:
return "to_number ";
case PT_CURRENT_VALUE:
return "serial_current_value ";
case PT_NEXT_VALUE:
return "serial_next_value ";
case PT_EXTRACT:
return "extract ";
case PT_CAST:
return "cast ";
case PT_CASE:
return "case ";
case PT_INST_NUM:
return "inst_num ";
case PT_ROWNUM:
return "rownum ";
case PT_ORDERBY_NUM:
return "orderby_num";
case PT_CONNECT_BY_ISCYCLE:
return "connect_by_iscycle ";
case PT_CONNECT_BY_ISLEAF:
return "connect_by_isleaf ";
case PT_LEVEL:
return "level ";
case PT_CURRENT_USER:
return "current_user ";
case PT_LOCAL_TRANSACTION_ID:
return "local_transaction_id ";
case PT_STRCAT:
return "||";
case PT_NULLIF:
return "nullif ";
case PT_COALESCE:
return "coalesce ";
case PT_NVL:
return "nvl ";
case PT_NVL2:
return "nvl2 ";
case PT_DECODE:
return "decode ";
case PT_INCR:
return "incr ";
case PT_DECR:
return "decr ";
case PT_USER:
return "user ";
case PT_ROW_COUNT:
return "row_count ";
case PT_LAST_INSERT_ID:
return "last_insert_id ";
case PT_DEFAULTF:
return "default ";
case PT_LIST_DBS:
return "list_dbs ";
case PT_SYS_GUID:
return "sys_guid ";
case PT_OID_OF_DUPLICATE_KEY:
return "oid_of_duplicate_key ";
case PT_BIT_TO_BLOB:
return "bit_to_blob";
case PT_CHAR_TO_BLOB:
return "char_to_blob";
case PT_BLOB_TO_BIT:
return "blob_to_bit";
case PT_CHAR_TO_CLOB:
return "char_to_clob";
case PT_CLOB_TO_CHAR:
return "clob_to_char";
case PT_BLOB_FROM_FILE:
return "blob_from_file";
case PT_CLOB_FROM_FILE:
return "clob_from_file";
case PT_BLOB_LENGTH:
return "blob_length";
case PT_CLOB_LENGTH:
return "clob_length";
case PT_TYPEOF:
return "typeof ";
case PT_INDEX_CARDINALITY:
return "index_cardinality ";
case PT_ESTIMATED_TABLE_ROWS:
return "estimated_table_rows";
case PT_ESTIMATED_AVG_ROW_LENGTH:
return "estimated_avg_row_length";
case PT_ESTIMATED_DATA_LENGTH:
return "estimated_data_length";
case PT_ESTIMATED_DATA_FREE:
return "estimated_data_free";
case PT_EVALUATE_VARIABLE:
return "evaluate_variable";
case PT_DEFINE_VARIABLE:
return "define_variable";
case PT_EXEC_STATS:
return "exec_stats";
case PT_TO_ENUMERATION_VALUE:
return "to_enumeration_value";
case PT_INET_ATON:
return "inet_aton ";
case PT_INET_NTOA:
return "inet_ntoa ";
case PT_CHARSET:
return "charset ";
case PT_COERCIBILITY:
return "coercibility ";
case PT_COLLATION:
return "collation ";
case PT_WIDTH_BUCKET:
return "width_bucket";
case PT_TRACE_STATS:
return "trace_stats";
case PT_INDEX_PREFIX:
return "index_prefix ";
case PT_SLEEP:
return "sleep ";
case PT_DBTIMEZONE:
return "dbtimezone";
case PT_SESSIONTIMEZONE:
return "sessiontimezone";
case PT_TZ_OFFSET:
return "tz_offset";
case PT_NEW_TIME:
return "new_time ";
case PT_FROM_TZ:
return "from_tz ";
case PT_TO_DATETIME_TZ:
return "to_datetime_tz ";
case PT_TO_TIMESTAMP_TZ:
return "to_timestamp_tz ";
case PT_UTC_TIMESTAMP:
return "utc_timestamp ";
case PT_CRC32:
return "crc32 ";
case PT_SCHEMA_DEF:
return "schema_def";
case PT_CONV_TZ:
return "conv_tz";
case PT_COLLECTION_TO_STRING:
return "collection_to_string";
default:
assert (false);
return "unknown opcode";
}
}
/*
* pt_show_priv() -
* return:
* t(in):
*/
const char *
pt_show_priv (PT_PRIV_TYPE t)
{
switch (t)
{
case PT_NO_PRIV:
return "no";
case PT_ADD_PRIV:
return "add";
case PT_ALL_PRIV:
return "all";
case PT_ALTER_PRIV:
return "alter";
case PT_DELETE_PRIV:
return "delete";
case PT_DROP_PRIV:
return "drop";
case PT_EXECUTE_PRIV:
return "execute";
case PT_EXECUTE_PROCEDURE_PRIV:
return "execute on procedure";
case PT_INDEX_PRIV:
return "index";
case PT_INSERT_PRIV:
return "insert";
case PT_REFERENCES_PRIV:
return "references";
case PT_SELECT_PRIV:
return "select";
case PT_UPDATE_PRIV:
return "update";
default:
return "unknown privilege";
}
}
/*
* pt_show_type_enum() -
* return:
* t(in):
*/
const char *
pt_show_type_enum (PT_TYPE_ENUM t)
{
if (t <= PT_TYPE_NONE || t >= PT_TYPE_MAX)
{
return "unknown data type";
}
switch (t)
{
case PT_TYPE_NONE:
return "none";
/* treat PT_TYPE__LOGICAL as PT_TYPE_INTEGER */
case PT_TYPE_LOGICAL:
case PT_TYPE_INTEGER:
return "integer";
case PT_TYPE_BIGINT:
return "bigint";
case PT_TYPE_SMALLINT:
return "smallint";
case PT_TYPE_NUMERIC:
return "numeric";
case PT_TYPE_FLOAT:
return "float";
case PT_TYPE_DOUBLE:
return "double";
case PT_TYPE_DATE:
return "date";
case PT_TYPE_TIME:
return "time";
case PT_TYPE_TIMESTAMP:
return "timestamp";
case PT_TYPE_TIMESTAMPTZ:
return "timestamptz";
case PT_TYPE_TIMESTAMPLTZ:
return "timestampltz";
case PT_TYPE_DATETIME:
return "datetime";
case PT_TYPE_DATETIMETZ:
return "datetimetz";
case PT_TYPE_DATETIMELTZ:
return "datetimeltz";
case PT_TYPE_CHAR:
return "char";
case PT_TYPE_VARCHAR:
return "varchar";
case PT_TYPE_BIT:
return "bit";
case PT_TYPE_VARBIT:
return "bit varying";
case PT_TYPE_MONETARY:
return "monetary";
case PT_TYPE_JSON:
return "json";
case PT_TYPE_MAYBE:
return "uncertain";
case PT_TYPE_NA:
return "na";
case PT_TYPE_NULL:
return "null";
case PT_TYPE_STAR:
return "*";
case PT_TYPE_OBJECT:
return "object";
case PT_TYPE_SET:
return "set";
case PT_TYPE_MULTISET:
return "multiset";
case PT_TYPE_SEQUENCE:
return "sequence";
case PT_TYPE_RESULTSET:
return "cursor";
case PT_TYPE_COMPOUND:
return "unknown";
case PT_TYPE_BLOB:
return "blob";
case PT_TYPE_CLOB:
return "clob";
case PT_TYPE_ELO:
return "*elo*";
case PT_TYPE_ENUMERATION:
return "enum";
case PT_TYPE_MAX:
default:
return "unknown";
}
return "unknown"; /* make the compiler happy */
}
#if defined (ENABLE_UNUSED_FUNCTION)
/*
* pt_show_alter() -
* return:
* c(in):
*/
const char *
pt_show_alter (PT_ALTER_CODE c)
{
switch (c)
{
case PT_ADD_QUERY:
return "ADD QUERY";
case PT_DROP_QUERY:
return "DROP QUERY";
case PT_MODIFY_QUERY:
return "CHANGE QUERY";
case PT_RESET_QUERY:
return "RESET QUERY";
case PT_ADD_ATTR_MTHD:
return "ADD ATTR/MTHD";
case PT_DROP_ATTR_MTHD:
return "DROP ATTR/MTHD";
case PT_MODIFY_ATTR_MTHD:
return "CHANGE ATTR/MTHD";
case PT_RENAME_ATTR_MTHD:
return "RENAME ATTR/MTHD";
case PT_ADD_SUPCLASS:
return "ADD SUPCLASS";
case PT_DROP_SUPCLASS:
return "DROP SUPCLASS";
case PT_DROP_RESOLUTION:
return "DROP RESOLUTION";
case PT_RENAME_RESOLUTION:
return "RENAME RESOLUTION";
case PT_DROP_CONSTRAINT:
return "DROP CONSTRAINT";
case PT_APPLY_PARTITION:
return "APPLY PARTITION";
case PT_REMOVE_PARTITION:
return "REMOVE PARTITION";
case PT_ANALYZE_PARTITION:
return "ANALYZE PARTITION";
case PT_DROP_PARTITION:
return "DROP PARTITION";
case PT_ADD_PARTITION:
return "ADD PARTITION";
case PT_ADD_HASHPARTITION:
return "ADD HASH PARTITION";
case PT_REORG_PARTITION:
return "REORGANIZE PARTITION";
case PT_COALESCE_PARTITION:
return "COALESCE PARTITION";
case PT_PROMOTE_PARTITION:
return "PROMOTE PARTITION";
case PT_MODIFY_DEFAULT:
return "CHANGE DEFAULT";
case PT_RENAME_ENTITY:
return "RENAME ENTITY";
case PT_ALTER_DEFAULT:
return "ALTER SET DEFAULT";
case PT_DROP_INDEX_CLAUSE:
return "DROP INDEX";
case PT_DROP_PRIMARY_CLAUSE:
return "DROP PRIMARY KEY";
case PT_DROP_FK_CLAUSE:
return "DROP FOREIGN KEY";
default:
return "unknown alter code";
}
}
#endif
/*
* pt_show_partition_type() -
* return:
* t(in):
*/
const char *
pt_show_partition_type (PT_PARTITION_TYPE t)
{
switch (t)
{
case PT_PARTITION_HASH:
return "hash";
case PT_PARTITION_RANGE:
return "range";
case PT_PARTITION_LIST:
return "list";
default:
return "unknown partition type";
}
}
/*
* pt_gather_constraints() - Moves explicit and synthesized constraints from
* the attribute definition list out into the constraint_list member
* and into the create_index member
* return: pointer to modified node or NULL
* parser(in): pointer to parser structure
* node(in): pointer to CREATE_ENTITY or ALTER node to be modified
*/
PT_NODE *
pt_gather_constraints (PARSER_CONTEXT * parser, PT_NODE * node)
{
PT_NODE **constraint_list_p = NULL;
PT_NODE **create_index_list_p = NULL;
PT_NODE **attr_list_p = NULL;
PT_NODE **class_attr_list_p = NULL;
PT_NODE *next = NULL, *tmp = NULL;
switch (node->node_type)
{
case PT_CREATE_ENTITY:
constraint_list_p = &node->info.create_entity.constraint_list;
create_index_list_p = &node->info.create_entity.create_index;
attr_list_p = &node->info.create_entity.attr_def_list;
class_attr_list_p = &node->info.create_entity.class_attr_def_list;
break;
case PT_ALTER:
if (node->info.alter.code == PT_ADD_ATTR_MTHD || node->info.alter.code == PT_MODIFY_ATTR_MTHD
|| node->info.alter.code == PT_CHANGE_ATTR)
{
constraint_list_p = &node->info.alter.constraint_list;
create_index_list_p = &node->info.alter.create_index;
attr_list_p = &node->info.alter.alter_clause.attr_mthd.attr_def_list;
class_attr_list_p = NULL;
}
break;
default:
PT_INTERNAL_ERROR (parser, "bad node type");
goto error;
}
if (attr_list_p != NULL)
{
next = *attr_list_p;
while (next)
{
switch (next->node_type)
{
case PT_CONSTRAINT:
/*
* We need to cut this entry out of the attr_def list and
* append it to the constraint list. This uses the
* standard indirect update technique for modifying a
* singly-linked list.
*/
tmp = next;
*attr_list_p = next = tmp->next;
tmp->next = NULL;
*constraint_list_p = parser_append_node (tmp, *constraint_list_p);
break;
case PT_CREATE_INDEX:
tmp = next;
*attr_list_p = next = tmp->next;
tmp->next = NULL;
*create_index_list_p = parser_append_node (tmp, *create_index_list_p);
break;
default:
attr_list_p = &next->next;
next = next->next;
break;
}
}
}
if (class_attr_list_p != NULL)
{
next = *class_attr_list_p;
while (next)
{
switch (next->node_type)
{
case PT_CONSTRAINT:
/*
* We need to cut this entry out of the class_attr_def list
* and append it to the constraint list. This uses the
* standard indirect update technique for modifying a
* singly-linked list.
*/
tmp = next;
*class_attr_list_p = next = tmp->next;
tmp->next = NULL;
*constraint_list_p = parser_append_node (tmp, *constraint_list_p);
break;
default:
class_attr_list_p = &next->next;
next = next->next;
break;
}
}
}
return node;
error:
return NULL;
}
/*
* pt_get_subquery_list() - simple implementation of pt_get_select_list
* return:
* node(in):
*/
PT_NODE *
pt_get_subquery_list (PT_NODE * node)
{
PT_NODE *col, *list;
while (node)
{
switch (node->node_type)
{
case PT_SELECT:
list = node->info.query.q.select.list;
if (PT_IS_VALUE_QUERY (node))
{
assert (list != NULL);
node = list->info.node_list.list;
}
else
{
node = list;
}
if (node && node->node_type == PT_VALUE && node->type_enum == PT_TYPE_STAR)
{
/* found "*" */
node = NULL;
}
for (col = node; col; col = col->next)
{
if (col->node_type == PT_NAME && col->type_enum == PT_TYPE_STAR)
{
/* fond "classname.*" */
node = NULL;
break;
}
}
return node;
case PT_UNION:
case PT_INTERSECTION:
case PT_DIFFERENCE:
node = node->info.query.q.union_.arg1;
break;
default:
node = NULL;
break;
}
}
return node;
}
/*
* pt_get_expression_count() -
* return:
* node(in):
*/
int
pt_get_expression_count (PT_NODE * node)
{
int count;
PT_NODE *list;
count = -1;
if (node)
{
if (node->node_type == PT_VALUE && pt_is_set_type (node))
{
count = pt_length_of_list (node->info.value.data_value.set);
}
else if (PT_IS_QUERY_NODE_TYPE (node->node_type))
{
list = pt_get_subquery_list (node);
if (!list)
{
/* in case of error or found "*" */
return count;
}
else if (list->next == NULL)
{ /* single column */
if (pt_is_set_type (list))
{
if (list->node_type == PT_VALUE)
{
count = pt_length_of_list (list->info.value.data_value.set);
}
else if (list->node_type == PT_FUNCTION)
{
count = pt_length_of_list (list->info.function.arg_list);
}
}
else
{
count = 1;
}
}
else
{
count = pt_length_of_select_list (list, EXCLUDE_HIDDEN_COLUMNS);
}
}
else
{
count = 0;
for (list = node; list; list = list->next)
{
count++;
}
}
}
return count;
}
/*
* pt_select_list_to_one_col() -
* return:
* parser(in):
* node(in):
* do_one(in):
*/
void
pt_select_list_to_one_col (PARSER_CONTEXT * parser, PT_NODE * node, bool do_one)
{
PT_NODE *val, *col, *list, *next;
bool do_rewrite;
if (!node)
{
return;
}
switch (node->node_type)
{
case PT_SELECT:
list = node->info.query.q.select.list;
if (do_one == true)
{
do_rewrite = false; /* init */
if (node->info.query.orderby_for)
{
do_rewrite = true; /* give up */
}
else if (node->info.query.order_by && node->info.query.limit)
{
do_rewrite = true;
}
else
{
for (col = list; col && do_rewrite != true; col = col->next)
{
/* check orderby_num() exists */
if (col->node_type == PT_EXPR && col->info.expr.op == PT_ORDERBY_NUM)
{
do_rewrite = true; /* break */
}
}
}
/* change node as select of query-derived table */
if (do_rewrite)
{
PT_NODE *derived, *from, *range_var, *spec;
int i;
char buf[20];
/* reset single tuple mark and move to derived */
node->info.query.flag.single_tuple = 0;
derived = parser_copy_tree (parser, node);
parser_reinit_node (node);
/* new range var */
from = derived->info.query.q.select.from;
if ((range_var = from->info.spec.range_var) == NULL)
{
/* set line number to range name */
range_var = pt_name (parser, "av3491");
}
spec = parser_new_node (parser, PT_SPEC);
if (spec == NULL)
{
PT_INTERNAL_ERROR (parser, "allocate new node");
return;
}
spec->info.spec.derived_table = derived;
spec->info.spec.derived_table_type = PT_IS_SUBQUERY;
spec->info.spec.range_var = range_var;
/* new as attr list */
for (spec->info.spec.as_attr_list = NULL, i = 1, col = list; col; i++, col = col->next)
{
PT_NODE *att;
sprintf (buf, "av_%d", i);
att = pt_name (parser, pt_append_string (parser, NULL, buf));
if (att)
{
PT_NAME_INFO_SET_FLAG (att, PT_NAME_GENERATED_DERIVED_SPEC);
}
spec->info.spec.as_attr_list = parser_append_node (att, spec->info.spec.as_attr_list);
}
node->info.query.q.select.list = parser_copy_tree_list (parser, spec->info.spec.as_attr_list);
node->info.query.q.select.from = spec;
}
else
{
/* remove unnecessary ORDER BY clause */
if (node->info.query.order_by && !node->info.query.q.select.connect_by)
{
parser_free_tree (parser, node->info.query.order_by);
node->info.query.order_by = NULL;
}
}
/* create parentheses expr set value */
val = parser_new_node (parser, PT_VALUE);
if (val)
{
val->info.value.data_value.set = node->info.query.q.select.list;
val->type_enum = PT_TYPE_SEQUENCE;
}
node->info.query.q.select.list = val;
}
else
{
if (pt_length_of_select_list (list, EXCLUDE_HIDDEN_COLUMNS) == 1 && pt_is_set_type (list))
{ /* one column */
col = list;
next = list->next; /* save hidden column */
col->next = NULL;
if (list->node_type == PT_VALUE)
{
list = col->info.value.data_value.set;
col->info.value.data_value.set = NULL;
parser_free_tree (parser, col);
}
else if (list->node_type == PT_FUNCTION)
{
list = col->info.function.arg_list;
col->info.function.arg_list = NULL;
parser_free_tree (parser, col);
}
else
{
list = col;
}
/* restore hidden columns */
node->info.query.q.select.list = parser_append_node (next, list);
}
}
break;
case PT_UNION:
case PT_INTERSECTION:
case PT_DIFFERENCE:
pt_select_list_to_one_col (parser, node->info.query.q.union_.arg1, do_one);
pt_select_list_to_one_col (parser, node->info.query.q.union_.arg2, do_one);
/* since the select_list was rebuilt, free the select list of the union node and pt_get_select_list() will
* reestablish it. */
parser_free_tree (parser, node->info.query.q.union_.select_list);
node->info.query.q.union_.select_list = NULL;
break;
default:
break;
}
return;
}
/*
* pt_check_set_count_set() -
* return: 1 for noerror, 0 for error
* parser(in):
* arg1(in):
* arg2(in):
*/
int
pt_check_set_count_set (PARSER_CONTEXT * parser, PT_NODE * arg1, PT_NODE * arg2)
{
PT_NODE *e1, *e2;
bool e1_is_expr_set, e2_is_expr_set;
int e1_cnt, e2_cnt, rc;
rc = 1; /* set as NO_ERROR */
if (arg1->node_type != PT_VALUE || !pt_is_set_type (arg1) || arg2->node_type != PT_VALUE || !pt_is_set_type (arg2))
{
return rc; /* give up */
}
/* get elements */
e1 = arg1->info.value.data_value.set;
e2 = arg2->info.value.data_value.set;
for (; e1 && e2; e1 = e1->next, e2 = e2->next)
{
e1_is_expr_set = e2_is_expr_set = false; /* init */
if (e1->node_type == PT_VALUE && pt_is_set_type (e1))
{
e1_is_expr_set = true;
}
if (e2->node_type == PT_VALUE && pt_is_set_type (e2))
{
e2_is_expr_set = true;
}
if (e1_is_expr_set == e2_is_expr_set)
{
if (e1_is_expr_set == true)
{
/* do recursion */
if (!pt_check_set_count_set (parser, e1, e2))
{
rc = 0; /* error */
}
}
else
{
if (!rc)
{
/* already check this expression */
continue;
}
/* expression number check */
e1_cnt = pt_get_expression_count (e1);
e2_cnt = pt_get_expression_count (e2);
if (e1_cnt > 0 && e2_cnt > 0 && e1_cnt != e2_cnt)
{
PT_ERRORmf2 (parser, e2, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_ATT_CNT_COL_CNT_NE, e1_cnt,
e2_cnt);
rc = 0; /* error */
}
}
}
else
{
/* unknown error */
PT_ERROR (parser, e2, "check syntax at = or <>.");
rc = 0; /* error */
}
} /* for */
if ((e1 || e2) && rc)
{
/* unknown error */
PT_ERROR (parser, e2, "check syntax at = or <>.");
rc = 0; /* error */
}
return rc;
}
/*
* pt_rewrite_set_eq_set() -
* return:
* parser(in):
* exp(in):
*/
PT_NODE *
pt_rewrite_set_eq_set (PARSER_CONTEXT * parser, PT_NODE * exp)
{
PT_NODE *p = NULL, *rhs = NULL;
PT_NODE *arg1, *arg2, *e1, *e2, *e1_next, *e2_next, *lhs, *tmp;
bool e1_is_expr_set, e2_is_expr_set;
if (exp == NULL)
{
return NULL;
}
arg1 = exp->info.expr.arg1;
arg2 = exp->info.expr.arg2;
if (arg1->node_type != PT_VALUE || !pt_is_set_type (arg1) || arg2->node_type != PT_VALUE || !pt_is_set_type (arg2))
{
return exp; /* give up */
}
/* get elements and cut-off link */
e1 = arg1->info.value.data_value.set;
arg1->info.value.data_value.set = NULL;
e2 = arg2->info.value.data_value.set;
arg2->info.value.data_value.set = NULL;
/* save and cut-off link */
e1_next = e1->next;
e1->next = NULL;
e2_next = e2->next;
e2->next = NULL;
e1_is_expr_set = e2_is_expr_set = false; /* init */
if (e1->node_type == PT_VALUE && pt_is_set_type (e1))
{
e1_is_expr_set = true;
}
if (e2->node_type == PT_VALUE && pt_is_set_type (e2))
{
e2_is_expr_set = true;
}
if (e1_is_expr_set == e2_is_expr_set)
{
if (e1_is_expr_set == true)
{
/* create temporary expr */
tmp = parser_copy_tree (parser, exp);
tmp->info.expr.arg1->info.value.data_value.set = e1->info.value.data_value.set;
e1->info.value.data_value.set = NULL;
tmp->info.expr.arg2->info.value.data_value.set = e2->info.value.data_value.set;
e2->info.value.data_value.set = NULL;
/* do recursion */
p = pt_rewrite_set_eq_set (parser, tmp);
/* free old elements */
parser_free_tree (parser, e1);
parser_free_tree (parser, e2);
}
else
{
/* create new root node of predicate tree */
p = parser_new_node (parser, PT_EXPR);
if (p == NULL)
{
PT_INTERNAL_ERROR (parser, "allocate new node");
return NULL;
}
p->info.expr.op = PT_EQ;
p->info.expr.arg1 = e1;
p->info.expr.arg2 = e2;
p->type_enum = PT_TYPE_LOGICAL;
}
}
else
{ /* error */
PT_ERRORf (parser, exp, "check syntax at %s", pt_show_binopcode (PT_EQ));
/* free old elements */
parser_free_tree (parser, e1);
parser_free_tree (parser, e2);
}
pt_push (parser, p);
/* create child nodes */
for (e1 = e1_next, e2 = e2_next; e1 && e2; e1 = e1_next, e2 = e2_next)
{
/* save and cut-off link */
e1_next = e1->next;
e1->next = NULL;
e2_next = e2->next;
e2->next = NULL;
lhs = pt_pop (parser);
/* create '=' expr node */
e1_is_expr_set = e2_is_expr_set = false; /* init */
if (e1->node_type == PT_VALUE && pt_is_set_type (e1))
{
e1_is_expr_set = true;
}
if (e2->node_type == PT_VALUE && pt_is_set_type (e2))
{
e2_is_expr_set = true;
}
if (e1_is_expr_set == e2_is_expr_set)
{
if (e1_is_expr_set == true)
{
/* create temporary expr */
tmp = parser_copy_tree (parser, exp);
tmp->info.expr.arg1->info.value.data_value.set = e1->info.value.data_value.set;
e1->info.value.data_value.set = NULL;
tmp->info.expr.arg2->info.value.data_value.set = e2->info.value.data_value.set;
e2->info.value.data_value.set = NULL;
/* do recursion */
rhs = pt_rewrite_set_eq_set (parser, tmp);
/* free old elements */
parser_free_tree (parser, e1);
parser_free_tree (parser, e2);
}
else
{
/* create new child node */
rhs = parser_new_node (parser, PT_EXPR);
if (rhs == NULL)
{
PT_INTERNAL_ERROR (parser, "allocate new node");
return NULL;
}
rhs->info.expr.op = PT_EQ;
rhs->info.expr.arg1 = e1;
rhs->info.expr.arg2 = e2;
rhs->type_enum = PT_TYPE_LOGICAL;
}
}
else
{ /* error */
PT_ERRORf (parser, exp, "check syntax at %s", pt_show_binopcode (PT_EQ));
/* free old elements */
parser_free_tree (parser, e1);
parser_free_tree (parser, e2);
}
/* create 'and' node */
p = parser_new_node (parser, PT_EXPR);
if (p == NULL)
{
PT_INTERNAL_ERROR (parser, "allocate new node");
return NULL;
}
p->info.expr.op = PT_AND;
p->info.expr.arg1 = lhs;
p->info.expr.arg2 = rhs;
p->info.expr.arg3 = NULL;
p->type_enum = PT_TYPE_LOGICAL;
pt_push (parser, p);
}
/* expression count check */
if (e1 || e2)
{
PT_ERRORf (parser, exp, "check syntax at %s, different number of elements in expression.",
pt_show_binopcode (PT_EQ));
}
p = pt_pop (parser);
if (p == NULL)
{
return NULL;
}
/* bound with parentheses */
p->info.expr.paren_type = 1;
/* free old exp, arg1, arg2 node */
if (exp)
{
arg1->info.value.data_value.set = NULL;
arg2->info.value.data_value.set = NULL;
parser_free_tree (parser, exp);
}
return p;
}
/*
* pt_init_apply_f () - initialize function vector(called by parser_walk_tree...)
* return: none
*/
static void
pt_init_apply_f (void)
{
pt_apply_func_array[PT_ALTER] = pt_apply_alter;
pt_apply_func_array[PT_ALTER_INDEX] = pt_apply_alter_index;
pt_apply_func_array[PT_ALTER_USER] = pt_apply_alter_user;
pt_apply_func_array[PT_ALTER_SERIAL] = pt_apply_alter_serial;
pt_apply_func_array[PT_ALTER_TRIGGER] = pt_apply_alter_trigger;
pt_apply_func_array[PT_2PC_ATTACH] = pt_apply_attach;
pt_apply_func_array[PT_ATTR_DEF] = pt_apply_attr_def;
pt_apply_func_array[PT_ATTR_ORDERING] = pt_apply_attr_ordering;
pt_apply_func_array[PT_AUTH_CMD] = pt_apply_auth_cmd;
pt_apply_func_array[PT_CHECK_OPTION] = pt_apply_check_option;
pt_apply_func_array[PT_COMMIT_WORK] = pt_apply_commit_work;
pt_apply_func_array[PT_CREATE_ENTITY] = pt_apply_create_entity;
pt_apply_func_array[PT_CREATE_INDEX] = pt_apply_create_index;
pt_apply_func_array[PT_UPDATE_HISTOGRAM] = pt_apply_update_histogram;
pt_apply_func_array[PT_DROP_HISTOGRAM] = pt_apply_update_histogram;
pt_apply_func_array[PT_SHOW_HISTOGRAM] = pt_apply_update_histogram;
pt_apply_func_array[PT_CREATE_USER] = pt_apply_create_user;
pt_apply_func_array[PT_CREATE_TRIGGER] = pt_apply_create_trigger;
pt_apply_func_array[PT_CREATE_SERIAL] = pt_apply_create_serial;
pt_apply_func_array[PT_DATA_DEFAULT] = pt_apply_data_default;
pt_apply_func_array[PT_DATA_TYPE] = pt_apply_datatype;
pt_apply_func_array[PT_DELETE] = pt_apply_delete;
pt_apply_func_array[PT_DIFFERENCE] = pt_apply_difference;
pt_apply_func_array[PT_DOT_] = pt_apply_dot;
pt_apply_func_array[PT_DROP] = pt_apply_drop;
pt_apply_func_array[PT_DROP_INDEX] = pt_apply_drop_index;
pt_apply_func_array[PT_DROP_USER] = pt_apply_drop_user;
pt_apply_func_array[PT_DROP_TRIGGER] = pt_apply_drop_trigger;
pt_apply_func_array[PT_DROP_SERIAL] = pt_apply_drop_serial;
pt_apply_func_array[PT_DROP_VARIABLE] = pt_apply_drop_variable;
pt_apply_func_array[PT_SPEC] = pt_apply_spec;
pt_apply_func_array[PT_EVALUATE] = pt_apply_evaluate;
pt_apply_func_array[PT_EVENT_OBJECT] = pt_apply_event_object;
pt_apply_func_array[PT_EVENT_SPEC] = pt_apply_event_spec;
pt_apply_func_array[PT_EVENT_TARGET] = pt_apply_event_target;
pt_apply_func_array[PT_EXECUTE_TRIGGER] = pt_apply_execute_trigger;
pt_apply_func_array[PT_EXPR] = pt_apply_expr;
pt_apply_func_array[PT_FILE_PATH] = pt_apply_file_path;
pt_apply_func_array[PT_FUNCTION] = pt_apply_function;
pt_apply_func_array[PT_GET_OPT_LVL] = pt_apply_get_opt_lvl;
pt_apply_func_array[PT_GET_TRIGGER] = pt_apply_get_trigger;
pt_apply_func_array[PT_GET_XACTION] = pt_apply_get_xaction;
pt_apply_func_array[PT_GRANT] = pt_apply_grant;
pt_apply_func_array[PT_HOST_VAR] = pt_apply_host_var;
pt_apply_func_array[PT_INSERT] = pt_apply_insert;
pt_apply_func_array[PT_INTERSECTION] = pt_apply_intersection;
pt_apply_func_array[PT_AUTO_INCREMENT] = pt_apply_auto_increment;
pt_apply_func_array[PT_ISOLATION_LVL] = pt_apply_isolation_lvl;
pt_apply_func_array[PT_METHOD_CALL] = pt_apply_method_call;
pt_apply_func_array[PT_METHOD_DEF] = pt_apply_method_def;
pt_apply_func_array[PT_NAME] = pt_apply_name;
pt_apply_func_array[PT_NAMED_ARG] = pt_apply_named_arg;
pt_apply_func_array[PT_PREPARE_TO_COMMIT] = pt_apply_prepare_to_commit;
pt_apply_func_array[PT_REMOVE_TRIGGER] = pt_apply_remove_trigger;
pt_apply_func_array[PT_RENAME] = pt_apply_rename;
pt_apply_func_array[PT_RENAME_TRIGGER] = pt_apply_rename_trigger;
pt_apply_func_array[PT_RESOLUTION] = pt_apply_resolution;
pt_apply_func_array[PT_REVOKE] = pt_apply_revoke;
pt_apply_func_array[PT_ROLLBACK_WORK] = pt_apply_rollback_work;
pt_apply_func_array[PT_SAVEPOINT] = pt_apply_savepoint;
pt_apply_func_array[PT_SCOPE] = pt_apply_scope;
pt_apply_func_array[PT_SELECT] = pt_apply_select;
pt_apply_func_array[PT_SET_NAMES] = pt_apply_set_names;
pt_apply_func_array[PT_SET_TIMEZONE] = pt_apply_set_timezone;
pt_apply_func_array[PT_SET_OPT_LVL] = pt_apply_set_opt_lvl;
pt_apply_func_array[PT_SET_SYS_PARAMS] = pt_apply_set_sys_params;
pt_apply_func_array[PT_SET_TRIGGER] = pt_apply_set_trigger;
pt_apply_func_array[PT_SET_XACTION] = pt_apply_set_xaction;
pt_apply_func_array[PT_SHOWSTMT] = pt_apply_showstmt;
pt_apply_func_array[PT_SORT_SPEC] = pt_apply_sort_spec;
pt_apply_func_array[PT_TIMEOUT] = pt_apply_timeout;
pt_apply_func_array[PT_TRIGGER_ACTION] = pt_apply_trigger_action;
pt_apply_func_array[PT_TRIGGER_SPEC_LIST] = pt_apply_trigger_spec_list;
pt_apply_func_array[PT_UNION] = pt_apply_union_stmt;
pt_apply_func_array[PT_UPDATE] = pt_apply_update;
pt_apply_func_array[PT_UPDATE_STATS] = pt_apply_update_stats;
pt_apply_func_array[PT_GET_STATS] = pt_apply_get_stats;
#if defined (ENABLE_UNUSED_FUNCTION)
pt_apply_func_array[PT_USE] = pt_apply_use;
#endif
pt_apply_func_array[PT_VALUE] = pt_apply_value;
pt_apply_func_array[PT_ZZ_ERROR_MSG] = pt_apply_error_msg;
pt_apply_func_array[PT_CONSTRAINT] = pt_apply_constraint;
pt_apply_func_array[PT_NODE_POINTER] = pt_apply_pointer;
pt_apply_func_array[PT_CREATE_STORED_PROCEDURE] = pt_apply_create_stored_procedure;
pt_apply_func_array[PT_ALTER_STORED_PROCEDURE] = pt_apply_stored_procedure;
pt_apply_func_array[PT_DROP_STORED_PROCEDURE] = pt_apply_stored_procedure;
pt_apply_func_array[PT_PREPARE_STATEMENT] = pt_apply_prepare;
pt_apply_func_array[PT_EXECUTE_PREPARE] = pt_apply_prepare;
pt_apply_func_array[PT_DEALLOCATE_PREPARE] = pt_apply_prepare;
pt_apply_func_array[PT_TRUNCATE] = pt_apply_truncate;
pt_apply_func_array[PT_DO] = pt_apply_do;
pt_apply_func_array[PT_SP_PARAMETERS] = pt_apply_sp_parameter;
pt_apply_func_array[PT_PARTITION] = pt_apply_partition;
pt_apply_func_array[PT_PARTS] = pt_apply_parts;
pt_apply_func_array[PT_NODE_LIST] = pt_apply_node_list;
pt_apply_func_array[PT_TABLE_OPTION] = pt_apply_table_option;
pt_apply_func_array[PT_SET_SESSION_VARIABLES] = pt_apply_set_session_variables;
pt_apply_func_array[PT_DROP_SESSION_VARIABLES] = pt_apply_drop_session_variables;
pt_apply_func_array[PT_MERGE] = pt_apply_merge;
pt_apply_func_array[PT_TUPLE_VALUE] = pt_apply_tuple_value;
pt_apply_func_array[PT_QUERY_TRACE] = pt_apply_query_trace;
pt_apply_func_array[PT_INSERT_VALUE] = pt_apply_insert_value;
pt_apply_func_array[PT_KILL_STMT] = pt_apply_kill;
pt_apply_func_array[PT_VACUUM] = pt_apply_vacuum;
pt_apply_func_array[PT_WITH_CLAUSE] = pt_apply_with_clause;
pt_apply_func_array[PT_CTE] = pt_apply_cte;
pt_apply_func_array[PT_JSON_TABLE] = pt_apply_json_table;
pt_apply_func_array[PT_JSON_TABLE_NODE] = pt_apply_json_table_node;
pt_apply_func_array[PT_JSON_TABLE_COLUMN] = pt_apply_json_table_column;
pt_apply_func_array[PT_DBLINK_TABLE] = pt_apply_dblink_table;
pt_apply_func_array[PT_DBLINK_TABLE_DML] = pt_apply_dblink_table;
pt_apply_func_array[PT_CREATE_SERVER] = pt_apply_create_server;
pt_apply_func_array[PT_DROP_SERVER] = pt_apply_drop_server;
pt_apply_func_array[PT_RENAME_SERVER] = pt_apply_rename_server;
pt_apply_func_array[PT_ALTER_SERVER] = pt_apply_alter_server;
pt_apply_func_array[PT_ALTER_SYNONYM] = pt_apply_alter_synonym;
pt_apply_func_array[PT_CREATE_SYNONYM] = pt_apply_create_synonym;
pt_apply_func_array[PT_DROP_SYNONYM] = pt_apply_drop_synonym;
pt_apply_func_array[PT_RENAME_SYNONYM] = pt_apply_rename_synonym;
pt_apply_func_array[PT_SP_BODY] = pt_apply_sp_body;
pt_apply_f = pt_apply_func_array;
}
/*
* pt_init_init_f () - initialize function vector(called by parser_new_node...)
* return: none
*/
static void
pt_init_init_f (void)
{
#define pt_init_func_null_function ((PARSER_INIT_NODE_FUNC)(NULL))
/* Notice:
* To initialize for any member variable of PT_STATEMENT_INFO to a non-zero value,
* define a init function and assign a value for the member variable
*/
pt_init_func_array[PT_ALTER] = pt_init_func_null_function;
pt_init_func_array[PT_ALTER_INDEX] = pt_init_func_null_function;
pt_init_func_array[PT_ALTER_USER] = pt_init_func_null_function;
pt_init_func_array[PT_ALTER_TRIGGER] = pt_init_alter_trigger;
pt_init_func_array[PT_ALTER_SERIAL] = pt_init_func_null_function;
pt_init_func_array[PT_2PC_ATTACH] = pt_init_func_null_function;
pt_init_func_array[PT_ATTR_DEF] = pt_init_attr_def;
pt_init_func_array[PT_ATTR_ORDERING] = pt_init_func_null_function;
pt_init_func_array[PT_AUTH_CMD] = pt_init_auth_cmd;
pt_init_func_array[PT_CHECK_OPTION] = pt_init_func_null_function;
pt_init_func_array[PT_COMMIT_WORK] = pt_init_func_null_function;
pt_init_func_array[PT_CREATE_ENTITY] = pt_init_create_entity;
pt_init_func_array[PT_CREATE_INDEX] = pt_init_create_index;
pt_init_func_array[PT_UPDATE_HISTOGRAM] = pt_init_func_null_function;
pt_init_func_array[PT_DROP_HISTOGRAM] = pt_init_func_null_function;
pt_init_func_array[PT_SHOW_HISTOGRAM] = pt_init_func_null_function;
pt_init_func_array[PT_CREATE_USER] = pt_init_func_null_function;
pt_init_func_array[PT_CREATE_TRIGGER] = pt_init_func_null_function;
pt_init_func_array[PT_CREATE_SERIAL] = pt_init_func_null_function;
pt_init_func_array[PT_DATA_DEFAULT] = pt_init_data_default;
pt_init_func_array[PT_DATA_TYPE] = pt_init_datatype;
pt_init_func_array[PT_DELETE] = pt_init_delete;
pt_init_func_array[PT_DIFFERENCE] = pt_init_difference;
pt_init_func_array[PT_DOT_] = pt_init_func_null_function;
pt_init_func_array[PT_DROP] = pt_init_func_null_function;
pt_init_func_array[PT_DROP_INDEX] = pt_init_func_null_function;
pt_init_func_array[PT_DROP_USER] = pt_init_func_null_function;
pt_init_func_array[PT_DROP_TRIGGER] = pt_init_func_null_function;
pt_init_func_array[PT_DROP_SERIAL] = pt_init_func_null_function;
pt_init_func_array[PT_DROP_VARIABLE] = pt_init_func_null_function;
pt_init_func_array[PT_SPEC] = pt_init_spec;
pt_init_func_array[PT_EVALUATE] = pt_init_func_null_function;
pt_init_func_array[PT_EVENT_OBJECT] = pt_init_func_null_function;
pt_init_func_array[PT_EVENT_SPEC] = pt_init_func_null_function;
pt_init_func_array[PT_EVENT_TARGET] = pt_init_func_null_function;
pt_init_func_array[PT_EXECUTE_TRIGGER] = pt_init_func_null_function;
pt_init_func_array[PT_EXPR] = pt_init_expr;
pt_init_func_array[PT_FILE_PATH] = pt_init_func_null_function;
pt_init_func_array[PT_FUNCTION] = pt_init_function;
pt_init_func_array[PT_GET_OPT_LVL] = pt_init_get_opt_lvl;
pt_init_func_array[PT_GET_TRIGGER] = pt_init_func_null_function;
pt_init_func_array[PT_GET_XACTION] = pt_init_func_null_function;
pt_init_func_array[PT_GRANT] = pt_init_grant;
pt_init_func_array[PT_HOST_VAR] = pt_init_func_null_function;
pt_init_func_array[PT_INSERT] = pt_init_insert;
pt_init_func_array[PT_INTERSECTION] = pt_init_intersection;
pt_init_func_array[PT_AUTO_INCREMENT] = pt_init_func_null_function;
pt_init_func_array[PT_ISOLATION_LVL] = pt_init_isolation_lvl;
pt_init_func_array[PT_METHOD_CALL] = pt_init_func_null_function;
pt_init_func_array[PT_METHOD_DEF] = pt_init_method_def;
pt_init_func_array[PT_NAME] = pt_init_name;
pt_init_func_array[PT_NAMED_ARG] = pt_init_func_null_function;
pt_init_func_array[PT_PREPARE_TO_COMMIT] = pt_init_func_null_function;
pt_init_func_array[PT_REMOVE_TRIGGER] = pt_init_func_null_function;
pt_init_func_array[PT_RENAME] = pt_init_func_null_function;
pt_init_func_array[PT_RENAME_TRIGGER] = pt_init_func_null_function;
pt_init_func_array[PT_RESOLUTION] = pt_init_resolution;
pt_init_func_array[PT_REVOKE] = pt_init_func_null_function;
pt_init_func_array[PT_ROLLBACK_WORK] = pt_init_func_null_function;
pt_init_func_array[PT_SAVEPOINT] = pt_init_func_null_function;
pt_init_func_array[PT_SCOPE] = pt_init_func_null_function;
pt_init_func_array[PT_SELECT] = pt_init_select;
pt_init_func_array[PT_SET_NAMES] = pt_init_func_null_function;
pt_init_func_array[PT_SET_TIMEZONE] = pt_init_func_null_function;
pt_init_func_array[PT_SET_OPT_LVL] = pt_init_set_opt_lvl;
pt_init_func_array[PT_SET_SYS_PARAMS] = pt_init_func_null_function;
pt_init_func_array[PT_SET_TRIGGER] = pt_init_func_null_function;
pt_init_func_array[PT_SET_XACTION] = pt_init_func_null_function;
pt_init_func_array[PT_SHOWSTMT] = pt_init_showstmt;
pt_init_func_array[PT_SORT_SPEC] = pt_init_sort_spec;
pt_init_func_array[PT_TIMEOUT] = pt_init_func_null_function;
pt_init_func_array[PT_TRIGGER_ACTION] = pt_init_func_null_function;
pt_init_func_array[PT_TRIGGER_SPEC_LIST] = pt_init_func_null_function;
pt_init_func_array[PT_UNION] = pt_init_union_stmt;
pt_init_func_array[PT_UPDATE] = pt_init_update;
pt_init_func_array[PT_UPDATE_STATS] = pt_init_func_null_function;
pt_init_func_array[PT_GET_STATS] = pt_init_func_null_function;
#if defined (ENABLE_UNUSED_FUNCTION)
pt_init_func_array[PT_USE] = pt_init_func_null_function;
#endif
pt_init_func_array[PT_VALUE] = pt_init_value;
pt_init_func_array[PT_ZZ_ERROR_MSG] = pt_init_func_null_function;
pt_init_func_array[PT_CONSTRAINT] = pt_init_constraint;
pt_init_func_array[PT_NODE_POINTER] = pt_init_pointer;
pt_init_func_array[PT_CREATE_STORED_PROCEDURE] = pt_init_func_null_function;
pt_init_func_array[PT_ALTER_STORED_PROCEDURE] = pt_init_func_null_function;
pt_init_func_array[PT_DROP_STORED_PROCEDURE] = pt_init_func_null_function;
pt_init_func_array[PT_PREPARE_STATEMENT] = pt_init_func_null_function;
pt_init_func_array[PT_EXECUTE_PREPARE] = pt_init_func_null_function;
pt_init_func_array[PT_DEALLOCATE_PREPARE] = pt_init_func_null_function;
pt_init_func_array[PT_TRUNCATE] = pt_init_func_null_function;
pt_init_func_array[PT_DO] = pt_init_func_null_function;
pt_init_func_array[PT_SP_PARAMETERS] = pt_init_func_null_function;
pt_init_func_array[PT_PARTITION] = pt_init_func_null_function;
pt_init_func_array[PT_PARTS] = pt_init_func_null_function;
pt_init_func_array[PT_NODE_LIST] = pt_init_node_list;
pt_init_func_array[PT_TABLE_OPTION] = pt_init_table_option;
pt_init_func_array[PT_SET_SESSION_VARIABLES] = pt_init_func_null_function;
pt_init_func_array[PT_DROP_SESSION_VARIABLES] = pt_init_func_null_function;
pt_init_func_array[PT_MERGE] = pt_init_merge;
pt_init_func_array[PT_TUPLE_VALUE] = pt_init_tuple_value;
pt_init_func_array[PT_QUERY_TRACE] = pt_init_query_trace;
pt_init_func_array[PT_INSERT_VALUE] = pt_init_insert_value;
pt_init_func_array[PT_KILL_STMT] = pt_init_kill;
pt_init_func_array[PT_VACUUM] = pt_init_vacuum;
pt_init_func_array[PT_WITH_CLAUSE] = pt_init_func_null_function;
pt_init_func_array[PT_CTE] = pt_init_func_null_function;
pt_init_func_array[PT_JSON_TABLE] = pt_init_func_null_function;
pt_init_func_array[PT_JSON_TABLE_NODE] = pt_init_func_null_function;
pt_init_func_array[PT_JSON_TABLE_COLUMN] = pt_init_json_table_column;
pt_init_func_array[PT_DBLINK_TABLE] = pt_init_func_null_function;
pt_init_func_array[PT_DBLINK_TABLE_DML] = pt_init_func_null_function;
pt_init_func_array[PT_CREATE_SERVER] = pt_init_func_null_function;
pt_init_func_array[PT_DROP_SERVER] = pt_init_func_null_function;
pt_init_func_array[PT_RENAME_SERVER] = pt_init_func_null_function;
pt_init_func_array[PT_ALTER_SERVER] = pt_init_func_null_function;
pt_init_func_array[PT_ALTER_SYNONYM] = pt_init_func_null_function;
pt_init_func_array[PT_CREATE_SYNONYM] = pt_init_func_null_function;
pt_init_func_array[PT_DROP_SYNONYM] = pt_init_func_null_function;
pt_init_func_array[PT_RENAME_SYNONYM] = pt_init_func_null_function;
pt_init_func_array[PT_SP_BODY] = pt_init_func_null_function;
pt_init_f = pt_init_func_array;
}
/*
* pt_init_print_f () - initialize function vector(called by pt_tree_print...)
* return: none
*/
static void
pt_init_print_f (void)
{
pt_print_func_array[PT_ALTER] = pt_print_alter;
pt_print_func_array[PT_ALTER_INDEX] = pt_print_alter_index;
pt_print_func_array[PT_ALTER_USER] = pt_print_alter_user;
pt_print_func_array[PT_ALTER_TRIGGER] = pt_print_alter_trigger;
pt_print_func_array[PT_ALTER_SERIAL] = pt_print_alter_serial;
pt_print_func_array[PT_2PC_ATTACH] = pt_print_attach;
pt_print_func_array[PT_ATTR_DEF] = pt_print_attr_def;
pt_print_func_array[PT_ATTR_ORDERING] = pt_print_attr_ordering;
pt_print_func_array[PT_AUTH_CMD] = pt_print_auth_cmd;
pt_print_func_array[PT_CHECK_OPTION] = pt_print_check_option;
pt_print_func_array[PT_COMMIT_WORK] = pt_print_commit_work;
pt_print_func_array[PT_CREATE_ENTITY] = pt_print_create_entity;
pt_print_func_array[PT_CREATE_INDEX] = pt_print_create_index;
pt_print_func_array[PT_UPDATE_HISTOGRAM] = pt_print_analyze_histogram;
pt_print_func_array[PT_DROP_HISTOGRAM] = pt_print_analyze_histogram;
pt_print_func_array[PT_SHOW_HISTOGRAM] = pt_print_show_histogram;
pt_print_func_array[PT_CREATE_USER] = pt_print_create_user;
pt_print_func_array[PT_CREATE_TRIGGER] = pt_print_create_trigger;
pt_print_func_array[PT_CREATE_SERIAL] = pt_print_create_serial;
pt_print_func_array[PT_DATA_DEFAULT] = pt_print_data_default;
pt_print_func_array[PT_DATA_TYPE] = pt_print_datatype;
pt_print_func_array[PT_DELETE] = pt_print_delete;
pt_print_func_array[PT_DIFFERENCE] = pt_print_difference;
pt_print_func_array[PT_DOT_] = pt_print_dot;
pt_print_func_array[PT_DROP] = pt_print_drop;
pt_print_func_array[PT_DROP_INDEX] = pt_print_drop_index;
pt_print_func_array[PT_DROP_USER] = pt_print_drop_user;
pt_print_func_array[PT_DROP_TRIGGER] = pt_print_drop_trigger;
pt_print_func_array[PT_DROP_SERIAL] = pt_print_drop_serial;
pt_print_func_array[PT_DROP_VARIABLE] = pt_print_drop_variable;
pt_print_func_array[PT_SPEC] = pt_print_spec;
pt_print_func_array[PT_EVALUATE] = pt_print_evaluate;
pt_print_func_array[PT_EVENT_OBJECT] = pt_print_event_object;
pt_print_func_array[PT_EVENT_SPEC] = pt_print_event_spec;
pt_print_func_array[PT_EVENT_TARGET] = pt_print_event_target;
pt_print_func_array[PT_EXECUTE_TRIGGER] = pt_print_execute_trigger;
pt_print_func_array[PT_EXPR] = pt_print_expr;
pt_print_func_array[PT_FILE_PATH] = pt_print_file_path;
pt_print_func_array[PT_FUNCTION] = pt_print_function;
pt_print_func_array[PT_GET_OPT_LVL] = pt_print_get_opt_lvl;
pt_print_func_array[PT_GET_TRIGGER] = pt_print_get_trigger;
pt_print_func_array[PT_GET_XACTION] = pt_print_get_xaction;
pt_print_func_array[PT_GRANT] = pt_print_grant;
pt_print_func_array[PT_HOST_VAR] = pt_print_host_var;
pt_print_func_array[PT_INSERT] = pt_print_insert;
pt_print_func_array[PT_INTERSECTION] = pt_print_intersection;
pt_print_func_array[PT_AUTO_INCREMENT] = pt_print_auto_increment;
pt_print_func_array[PT_ISOLATION_LVL] = pt_print_isolation_lvl;
pt_print_func_array[PT_METHOD_CALL] = pt_print_method_call;
pt_print_func_array[PT_METHOD_DEF] = pt_print_method_def;
pt_print_func_array[PT_NAME] = pt_print_name;
pt_print_func_array[PT_NAMED_ARG] = pt_print_named_arg;
pt_print_func_array[PT_PREPARE_TO_COMMIT] = pt_print_prepare_to_commit;
pt_print_func_array[PT_REMOVE_TRIGGER] = pt_print_remove_trigger;
pt_print_func_array[PT_RENAME] = pt_print_rename;
pt_print_func_array[PT_RENAME_TRIGGER] = pt_print_rename_trigger;
pt_print_func_array[PT_RESOLUTION] = pt_print_resolution;
pt_print_func_array[PT_REVOKE] = pt_print_revoke;
pt_print_func_array[PT_ROLLBACK_WORK] = pt_print_rollback_work;
pt_print_func_array[PT_SAVEPOINT] = pt_print_savepoint;
pt_print_func_array[PT_SCOPE] = pt_print_scope;
pt_print_func_array[PT_SELECT] = pt_print_select;
pt_print_func_array[PT_SET_NAMES] = pt_print_set_names;
pt_print_func_array[PT_SET_TIMEZONE] = pt_print_set_timezone;
pt_print_func_array[PT_SET_OPT_LVL] = pt_print_set_opt_lvl;
pt_print_func_array[PT_SET_SYS_PARAMS] = pt_print_set_sys_params;
pt_print_func_array[PT_SET_TRIGGER] = pt_print_set_trigger;
pt_print_func_array[PT_SET_XACTION] = pt_print_set_xaction;
pt_print_func_array[PT_SHOWSTMT] = pt_print_showstmt;
pt_print_func_array[PT_SORT_SPEC] = pt_print_sort_spec;
pt_print_func_array[PT_TIMEOUT] = pt_print_timeout;
pt_print_func_array[PT_TRIGGER_ACTION] = pt_print_trigger_action;
pt_print_func_array[PT_TRIGGER_SPEC_LIST] = pt_print_trigger_spec_list;
pt_print_func_array[PT_UNION] = pt_print_union_stmt;
pt_print_func_array[PT_UPDATE] = pt_print_update;
pt_print_func_array[PT_UPDATE_STATS] = pt_print_update_stats;
pt_print_func_array[PT_GET_STATS] = pt_print_get_stats;
#if defined (ENABLE_UNUSED_FUNCTION)
pt_print_func_array[PT_USE] = pt_print_use;
#endif
pt_print_func_array[PT_VALUE] = pt_print_value;
pt_print_func_array[PT_ZZ_ERROR_MSG] = pt_print_error_msg;
pt_print_func_array[PT_CONSTRAINT] = pt_print_constraint;
pt_print_func_array[PT_NODE_POINTER] = pt_print_pointer;
pt_print_func_array[PT_CREATE_STORED_PROCEDURE] = pt_print_create_stored_procedure;
pt_print_func_array[PT_ALTER_STORED_PROCEDURE] = pt_print_alter_stored_procedure;
pt_print_func_array[PT_DROP_STORED_PROCEDURE] = pt_print_drop_stored_procedure;
pt_print_func_array[PT_PREPARE_STATEMENT] = NULL; /* prepared statements should never need to be printed */
pt_print_func_array[PT_EXECUTE_PREPARE] = NULL;
pt_print_func_array[PT_DEALLOCATE_PREPARE] = NULL;
pt_print_func_array[PT_TRUNCATE] = pt_print_truncate;
pt_print_func_array[PT_DO] = pt_print_do;
pt_print_func_array[PT_SP_PARAMETERS] = pt_print_sp_parameter;
pt_print_func_array[PT_PARTITION] = pt_print_partition;
pt_print_func_array[PT_PARTS] = pt_print_parts;
pt_print_func_array[PT_NODE_LIST] = pt_print_node_list;
pt_print_func_array[PT_TABLE_OPTION] = pt_print_table_option;
pt_print_func_array[PT_SET_SESSION_VARIABLES] = pt_print_set_session_variables;
pt_print_func_array[PT_DROP_SESSION_VARIABLES] = pt_print_drop_session_variables;
pt_print_func_array[PT_MERGE] = pt_print_merge;
pt_print_func_array[PT_TUPLE_VALUE] = pt_print_tuple_value;
pt_print_func_array[PT_QUERY_TRACE] = pt_print_query_trace;
pt_print_func_array[PT_INSERT_VALUE] = pt_print_insert_value;
pt_print_func_array[PT_VACUUM] = pt_print_vacuum;
pt_print_func_array[PT_WITH_CLAUSE] = pt_print_with_clause;
pt_print_func_array[PT_CTE] = pt_print_cte;
pt_print_func_array[PT_JSON_TABLE] = pt_print_json_table;
pt_print_func_array[PT_JSON_TABLE_NODE] = pt_print_json_table_node;
pt_print_func_array[PT_JSON_TABLE_COLUMN] = pt_print_json_table_columns;
pt_print_func_array[PT_DBLINK_TABLE] = pt_print_dblink_table;
pt_print_func_array[PT_DBLINK_TABLE_DML] = pt_print_dblink_table_dml;
pt_print_func_array[PT_CREATE_SERVER] = pt_print_create_server;
pt_print_func_array[PT_DROP_SERVER] = pt_print_drop_server;
pt_print_func_array[PT_RENAME_SERVER] = pt_print_rename_server;
pt_print_func_array[PT_ALTER_SERVER] = pt_print_alter_server;
pt_print_func_array[PT_ALTER_SYNONYM] = pt_print_alter_synonym;
pt_print_func_array[PT_CREATE_SYNONYM] = pt_print_create_synonym;
pt_print_func_array[PT_DROP_SYNONYM] = pt_print_drop_synonym;
pt_print_func_array[PT_RENAME_SYNONYM] = pt_print_rename_synonym;
pt_print_func_array[PT_SP_BODY] = pt_print_sp_body;
pt_print_f = pt_print_func_array;
}
/*
* pt_init_node () - initialize node by calling init function identified by node type
* return: void
* node(in) : pt node
* node_type(in) : node type
*/
void
pt_init_node (PT_NODE * node, PT_NODE_TYPE node_type)
{
/* There is only one path where this function is called.
* Also, node_type is fixed to PT_DOT_.
*/
assert (node_type < PT_LAST_NODE_NUMBER);
assert (pt_init_f != NULL);
if (!node)
{
return;
}
memset (&(node->info), 0x00, sizeof (node->info));
if (pt_init_f[node_type])
{
(pt_init_f[node_type]) (node);
}
node->node_type = node_type;
}
/*
* pt_append_name () - if the given string is not a keyword and has no
* non-alpha characters, append it. Otherwise, append it within double quotes
* return:
* parser(in):
* string(out):
* name(in):
*/
PARSER_VARCHAR *
pt_append_name (const PARSER_CONTEXT * parser, PARSER_VARCHAR * string, const char *name)
{
if ((!(parser->custom_print & (PT_SUPPRESS_QUOTES | PT_PRINT_SUPPRESS_FOR_DBLINK))
&& (pt_is_keyword (name) || lang_check_identifier (name, strlen (name)) != true))
|| parser->custom_print & PT_PRINT_QUOTES)
{
string = pt_append_nulstring (parser, string, "[");
if (parser->custom_print & PT_PRINT_LOWER)
{
char lcase_name[DB_MAX_IDENTIFIER_LENGTH];
intl_identifier_lower (name, lcase_name);
string = pt_append_nulstring (parser, string, lcase_name);
}
else
{
string = pt_append_nulstring (parser, string, name);
}
string = pt_append_nulstring (parser, string, "]");
}
else
{
string = pt_append_nulstring (parser, string, name);
}
return string;
}
/*
* pt_append_quoted_string () - Quote and append a string,
* breaking it into pieces if necessary
* return:
* parser(in):
* buf(out):
* str(in):
* str_length(in):
*
* Note :
* Keep track of how many characters we've written out, and break
* the string into juxtaposed string lits if we exceed some
* maximum. This is a concession to parsers that have smallish
* token accumulation buffers.
* MAX_STRING_SEGMENT_LENGTH is the maximum number of characters
* that will be put between two single quotes.
*
*/
static PARSER_VARCHAR *
pt_append_quoted_string (const PARSER_CONTEXT * parser, PARSER_VARCHAR * buf, const char *str, size_t str_length)
{
size_t i;
size_t out_length;
out_length = 0;
buf = pt_append_nulstring (parser, buf, "'");
if (str)
{
for (i = 0; i < str_length; i++)
{
if (str[i] == '\'')
{
buf = pt_append_bytes (parser, buf, "'", 1);
out_length++;
}
buf = pt_append_bytes (parser, buf, &str[i], 1);
out_length++;
if (out_length >= MAX_STRING_SEGMENT_LENGTH)
{
buf = pt_append_nulstring (parser, buf, "' '");
out_length = 0;
}
}
}
buf = pt_append_nulstring (parser, buf, "'");
return buf;
}
/*
* pt_append_string_prefix () - Print out any necessary string prefix modifier
* (e.g., 'B' or 'X')
* return:
* parser(in):
* buf(out):
* value(in):
*/
static PARSER_VARCHAR *
pt_append_string_prefix (const PARSER_CONTEXT * parser, PARSER_VARCHAR * buf, const PT_NODE * value)
{
char prefix[2];
if (value->info.value.string_type != ' ')
{
prefix[0] = value->info.value.string_type;
prefix[1] = '\0';
buf = pt_append_nulstring (parser, buf, prefix);
}
return buf;
}
/*
* pt_currency_to_db () - return DB_CURRENCY equivalent of PT_CURRENCY t
* return:
* t(in):
*/
static DB_CURRENCY
pt_currency_to_db (const PT_CURRENCY t)
{
switch (t)
{
case PT_CURRENCY_DOLLAR:
return DB_CURRENCY_DOLLAR;
case PT_CURRENCY_YEN:
return DB_CURRENCY_YEN;
case PT_CURRENCY_BRITISH_POUND:
return DB_CURRENCY_BRITISH_POUND;
case PT_CURRENCY_WON:
return DB_CURRENCY_WON;
case PT_CURRENCY_TL:
return DB_CURRENCY_TL;
case PT_CURRENCY_CAMBODIAN_RIEL:
return DB_CURRENCY_CAMBODIAN_RIEL;
case PT_CURRENCY_CHINESE_RENMINBI:
return DB_CURRENCY_CHINESE_RENMINBI;
case PT_CURRENCY_INDIAN_RUPEE:
return DB_CURRENCY_INDIAN_RUPEE;
case PT_CURRENCY_RUSSIAN_RUBLE:
return DB_CURRENCY_RUSSIAN_RUBLE;
case PT_CURRENCY_AUSTRALIAN_DOLLAR:
return DB_CURRENCY_AUSTRALIAN_DOLLAR;
case PT_CURRENCY_CANADIAN_DOLLAR:
return DB_CURRENCY_CANADIAN_DOLLAR;
case PT_CURRENCY_BRASILIAN_REAL:
return DB_CURRENCY_BRASILIAN_REAL;
case PT_CURRENCY_ROMANIAN_LEU:
return DB_CURRENCY_ROMANIAN_LEU;
case PT_CURRENCY_EURO:
return DB_CURRENCY_EURO;
case PT_CURRENCY_SWISS_FRANC:
return DB_CURRENCY_SWISS_FRANC;
case PT_CURRENCY_DANISH_KRONE:
return DB_CURRENCY_DANISH_KRONE;
case PT_CURRENCY_NORWEGIAN_KRONE:
return DB_CURRENCY_NORWEGIAN_KRONE;
case PT_CURRENCY_BULGARIAN_LEV:
return DB_CURRENCY_BULGARIAN_LEV;
case PT_CURRENCY_VIETNAMESE_DONG:
return DB_CURRENCY_VIETNAMESE_DONG;
case PT_CURRENCY_CZECH_KORUNA:
return DB_CURRENCY_CZECH_KORUNA;
case PT_CURRENCY_POLISH_ZLOTY:
return DB_CURRENCY_POLISH_ZLOTY;
case PT_CURRENCY_SWEDISH_KRONA:
return DB_CURRENCY_SWEDISH_KRONA;
case PT_CURRENCY_CROATIAN_KUNA:
return DB_CURRENCY_CROATIAN_KUNA;
case PT_CURRENCY_SERBIAN_DINAR:
return DB_CURRENCY_SERBIAN_DINAR;
default:
return DB_CURRENCY_NULL;
}
}
/*
* pt_show_event_type () -
* return:
* p(in):
*/
static const char *
pt_show_event_type (PT_EVENT_TYPE p)
{
switch (p)
{
case PT_EV_INSERT:
return " insert ";
case PT_EV_STMT_INSERT:
return " statement insert ";
case PT_EV_DELETE:
return " delete ";
case PT_EV_STMT_DELETE:
return " statement delete ";
case PT_EV_UPDATE:
return " update ";
case PT_EV_STMT_UPDATE:
return " statement update ";
case PT_EV_COMMIT:
return " commit ";
case PT_EV_ROLLBACK:
return " rollback ";
default:
return " unknown trigger event type ";
}
}
/*
* pt_apply_alter () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_alter (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.alter.entity_name, arg);
PT_APPLY_WALK (parser, p->info.alter.super.sup_class_list, arg);
PT_APPLY_WALK (parser, p->info.alter.super.resolution_list, arg);
switch (p->info.alter.code)
{
default:
break;
case PT_ADD_QUERY:
case PT_DROP_QUERY:
case PT_MODIFY_QUERY:
case PT_RESET_QUERY:
PT_APPLY_WALK (parser, p->info.alter.alter_clause.query.query, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.query.query_no_list, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.query.attr_def_list, arg);
break;
case PT_ADD_ATTR_MTHD:
case PT_DROP_ATTR_MTHD:
case PT_MODIFY_ATTR_MTHD:
case PT_CHANGE_ATTR:
PT_APPLY_WALK (parser, p->info.alter.alter_clause.attr_mthd.attr_def_list, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.attr_mthd.attr_old_name, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.attr_mthd.attr_mthd_name_list, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.attr_mthd.mthd_def_list, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.attr_mthd.mthd_file_list, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.attr_mthd.mthd_name_list, arg);
break;
case PT_RENAME_ATTR_MTHD:
case PT_RENAME_ENTITY:
PT_APPLY_WALK (parser, p->info.alter.alter_clause.rename.old_name, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.rename.new_name, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.rename.mthd_name, arg);
break;
#if defined (ENABLE_RENAME_CONSTRAINT)
case PT_RENAME_CONSTRAINT:
case PT_RENAME_INDEX:
PT_APPLY_WALK (parser, p->info.alter.alter_clause.rename.old_name, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.rename.new_name, arg);
break;
#endif
case PT_MODIFY_DEFAULT:
case PT_ALTER_DEFAULT:
PT_APPLY_WALK (parser, p->info.alter.alter_clause.ch_attr_def.attr_name_list, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.ch_attr_def.data_default_list, arg);
break;
/* TODO merge all the *_PARTITION cases below into a single case if it is safe to do so. */
case PT_APPLY_PARTITION:
PT_APPLY_WALK (parser, p->info.alter.alter_clause.partition.info, arg);
break;
case PT_DROP_PARTITION:
case PT_ANALYZE_PARTITION:
case PT_PROMOTE_PARTITION:
PT_APPLY_WALK (parser, p->info.alter.alter_clause.partition.name_list, arg);
break;
case PT_REMOVE_PARTITION:
break;
case PT_ADD_PARTITION:
PT_APPLY_WALK (parser, p->info.alter.alter_clause.partition.parts, arg);
break;
case PT_ADD_HASHPARTITION:
case PT_COALESCE_PARTITION:
PT_APPLY_WALK (parser, p->info.alter.alter_clause.partition.size, arg);
break;
case PT_REORG_PARTITION:
PT_APPLY_WALK (parser, p->info.alter.alter_clause.partition.name_list, arg);
PT_APPLY_WALK (parser, p->info.alter.alter_clause.partition.parts, arg);
break;
}
PT_APPLY_WALK (parser, p->info.alter.constraint_list, arg);
PT_APPLY_WALK (parser, p->info.alter.create_index, arg);
PT_APPLY_WALK (parser, p->info.alter.internal_stmts, arg);
return p;
}
/*
* pt_print_alter_one_clause () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_alter_one_clause (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1 = NULL, *r2 = NULL;
PT_NODE *names = NULL, *defaults = NULL, *attrs = NULL;
bool close_parenthesis = false;
unsigned int save_custom;
switch (p->info.alter.code)
{
default:
break;
case PT_CHANGE_OWNER:
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.user.user_name);
q = pt_append_nulstring (parser, q, " owner to ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_CHANGE_TABLE_COMMENT:
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.comment.tbl_comment);
q = pt_append_nulstring (parser, q, " comment = ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_CHANGE_COLLATION:
if (p->info.alter.alter_clause.collation.charset != -1)
{
q = pt_append_nulstring (parser, q, " charset ");
q = pt_append_nulstring (parser, q, lang_get_codeset_name (p->info.alter.alter_clause.collation.charset));
}
if (p->info.alter.alter_clause.collation.collation_id != -1)
{
q = pt_append_nulstring (parser, q, " collate ");
q =
pt_append_nulstring (parser, q,
lang_get_collation_name (p->info.alter.alter_clause.collation.collation_id));
}
break;
case PT_ADD_QUERY:
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.query.query);
q = pt_append_nulstring (parser, q, " add query ");
q = pt_append_varchar (parser, q, r1);
if (p->info.alter.alter_clause.query.view_comment != NULL)
{
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.query.view_comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_DROP_QUERY:
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.query.query_no_list);
q = pt_append_nulstring (parser, q, " drop query ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_MODIFY_QUERY:
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.query.query_no_list);
r2 = pt_print_bytes_l (parser, p->info.alter.alter_clause.query.query);
q = pt_append_nulstring (parser, q, " change query ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_varchar (parser, q, r2);
if (p->info.alter.alter_clause.query.view_comment != NULL)
{
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.query.view_comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_RESET_QUERY:
/* alias print should be enable for "alter view ..." e.g. When PT_PRINT_ALIAS disabled "alter view w as select
* sqrt(2) as root;" is printed as "alter view w as select sqrt(2)" which should be "alter view w as select
* sqrt(2) as root" */
save_custom = parser->custom_print;
parser->custom_print |= PT_PRINT_ALIAS;
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.query.query);
q = pt_append_nulstring (parser, q, " as ");
q = pt_append_varchar (parser, q, r1);
parser->custom_print = save_custom;
if (p->info.alter.alter_clause.query.view_comment != NULL)
{
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.query.view_comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_ADD_ATTR_MTHD:
q = pt_append_nulstring (parser, q, " add ");
close_parenthesis = false;
attrs = p->info.alter.alter_clause.attr_mthd.attr_def_list;
if (attrs)
{
if (attrs->info.attr_def.attr_type == PT_META_ATTR)
{
q = pt_append_nulstring (parser, q, "class ");
parser->custom_print = (parser->custom_print | PT_SUPPRESS_META_ATTR_CLASS);
}
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.attr_mthd.attr_def_list);
q = pt_append_nulstring (parser, q, "attribute (");
close_parenthesis = true;
q = pt_append_varchar (parser, q, r1);
if (attrs->info.attr_def.attr_type == PT_META_ATTR)
{
parser->custom_print = (parser->custom_print & ~PT_SUPPRESS_META_ATTR_CLASS);
}
}
if (p->info.alter.constraint_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.constraint_list);
if (r1)
{
if (close_parenthesis)
{
q = pt_append_nulstring (parser, q, ", ");
}
else
{
q = pt_append_nulstring (parser, q, "(");
close_parenthesis = true;
}
q = pt_append_varchar (parser, q, r1);
}
}
if (close_parenthesis)
{
q = pt_append_nulstring (parser, q, ")");
}
if (p->info.alter.alter_clause.attr_mthd.mthd_def_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.attr_mthd.mthd_def_list);
q = pt_append_nulstring (parser, q, " method ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.alter.alter_clause.attr_mthd.mthd_file_list)
{
r2 = pt_print_bytes_l (parser, p->info.alter.alter_clause.attr_mthd.mthd_file_list);
q = pt_append_nulstring (parser, q, " file ");
q = pt_append_varchar (parser, q, r2);
}
break;
case PT_DROP_ATTR_MTHD:
q = pt_append_nulstring (parser, q, " drop ");
names = p->info.alter.alter_clause.attr_mthd.attr_mthd_name_list;
while (names)
{
r1 = pt_print_bytes (parser, names);
if (names->info.name.meta_class == PT_META_ATTR)
{
q = pt_append_nulstring (parser, q, " class ");
}
q = pt_append_varchar (parser, q, r1);
names = names->next;
if (names != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
}
}
names = p->info.alter.alter_clause.attr_mthd.mthd_file_list;
if (names)
{
r2 = pt_print_bytes_l (parser, names);
q = pt_append_nulstring (parser, q, " file ");
q = pt_append_varchar (parser, q, r2);
}
break;
case PT_CHANGE_ATTR:
{
/* only one attibute per alter clause should be allowed : <attr_old_name> and <attr_def_list> should have at
* most one element */
if (p->info.alter.alter_clause.attr_mthd.attr_old_name != NULL)
{
q = pt_append_nulstring (parser, q, " change");
names = p->info.alter.alter_clause.attr_mthd.attr_old_name;
}
else
{
q = pt_append_nulstring (parser, q, " modify");
names = NULL;
}
attrs = p->info.alter.alter_clause.attr_mthd.attr_def_list;
assert (attrs != NULL);
if (attrs->info.attr_def.attr_type == PT_META_ATTR)
{
q = pt_append_nulstring (parser, q, " class");
}
q = pt_append_nulstring (parser, q, " attribute ");
if (names != NULL)
{
assert (names->next == NULL);
r2 = pt_print_bytes (parser, names);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, " ");
}
assert (attrs->next == NULL);
/* ordering is last in <CHANGE> syntax context, suppress in this print */
if (attrs->info.attr_def.ordering_info != NULL)
{
parser->custom_print |= PT_SUPPRESS_ORDERING;
}
if (attrs->info.attr_def.attr_type == PT_META_ATTR)
{
parser->custom_print |= PT_SUPPRESS_META_ATTR_CLASS;
}
assert (attrs->info.attr_def.attr_type != PT_CLASS);
r1 = pt_print_bytes (parser, attrs);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ");
if (attrs->info.attr_def.ordering_info != NULL)
{
parser->custom_print &= ~PT_SUPPRESS_ORDERING;
}
if (attrs->info.attr_def.attr_type == PT_META_ATTR)
{
parser->custom_print &= ~PT_SUPPRESS_META_ATTR_CLASS;
}
if (p->info.alter.constraint_list != NULL)
{
PT_NODE *c_node = p->info.alter.constraint_list;
r1 = pt_print_col_def_constraint (parser, c_node);
while (c_node->next != NULL)
{ /* print in the original order ... */
c_node = c_node->next;
r2 = pt_print_col_def_constraint (parser, c_node);
if (r2 != NULL)
{
r1 = pt_append_varchar (parser, r1, r2);
}
}
if (r1)
{
assert (attrs != NULL);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ");
}
}
if (attrs->info.attr_def.ordering_info != NULL)
{
r1 = pt_print_bytes (parser, attrs->info.attr_def.ordering_info);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ");
}
}
break;
case PT_MODIFY_ATTR_MTHD:
q = pt_append_nulstring (parser, q, " change ");
attrs = p->info.alter.alter_clause.attr_mthd.attr_def_list;
if (attrs)
{
if (attrs->info.attr_def.attr_type == PT_META_ATTR)
{
q = pt_append_nulstring (parser, q, "class ");
parser->custom_print = (parser->custom_print | PT_SUPPRESS_META_ATTR_CLASS);
}
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.attr_mthd.attr_def_list);
q = pt_append_nulstring (parser, q, "attribute (");
q = pt_append_varchar (parser, q, r1);
if (attrs->info.attr_def.attr_type == PT_META_ATTR)
{
parser->custom_print = (parser->custom_print & ~PT_SUPPRESS_META_ATTR_CLASS);
}
}
if (p->info.alter.constraint_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.constraint_list);
if (r1)
{
if (attrs)
{
q = pt_append_nulstring (parser, q, ", ");
}
else
{
q = pt_append_nulstring (parser, q, "(");
}
q = pt_append_varchar (parser, q, r1);
}
}
if (p->info.alter.constraint_list || attrs)
{
q = pt_append_nulstring (parser, q, ")");
}
if (p->info.alter.alter_clause.attr_mthd.mthd_def_list)
{
r2 = pt_print_bytes_l (parser, p->info.alter.alter_clause.attr_mthd.mthd_def_list);
q = pt_append_nulstring (parser, q, " method ");
q = pt_append_varchar (parser, q, r2);
}
break;
case PT_RENAME_ENTITY:
q = pt_append_nulstring (parser, q, " rename to ");
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.rename.new_name);
q = pt_append_varchar (parser, q, r1);
break;
#if defined (ENABLE_RENAME_CONSTRAINT)
case PT_RENAME_CONSTRAINT:
case PT_RENAME_INDEX:
q = pt_append_nulstring (parser, q, " rename ");
q = pt_append_nulstring (parser, q, pt_show_misc_type (p->info.alter.alter_clause.rename.element_type));
q = pt_append_nulstring (parser, q, " ");
switch (p->info.alter.alter_clause.rename.element_type)
{
default:
break;
case PT_CONSTRAINT_NAME:
case PT_INDEX_NAME:
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.rename.old_name);
r2 = pt_print_bytes (parser, p->info.alter.alter_clause.rename.new_name);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " to ");
q = pt_append_varchar (parser, q, r2);
break;
}
break;
#endif
case PT_RENAME_ATTR_MTHD:
q = pt_append_nulstring (parser, q, " rename ");
q = pt_append_nulstring (parser, q, pt_show_misc_type (p->info.alter.alter_clause.rename.element_type));
q = pt_append_nulstring (parser, q, " ");
switch (p->info.alter.alter_clause.rename.element_type)
{
default:
break;
case PT_ATTRIBUTE:
case PT_METHOD:
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.rename.old_name);
q = pt_append_nulstring (parser, q, pt_show_misc_type (p->info.alter.alter_clause.rename.meta));
q = pt_append_nulstring (parser, q, " ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_FUNCTION_RENAME:
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.rename.old_name);
r2 = pt_print_bytes (parser, p->info.alter.alter_clause.rename.mthd_name);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " of ");
q = pt_append_nulstring (parser, q, pt_show_misc_type (p->info.alter.alter_clause.rename.meta));
q = pt_append_nulstring (parser, q, " ");
q = pt_append_varchar (parser, q, r2);
[[fallthrough]];
case PT_FILE_RENAME:
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.rename.old_name);
q = pt_append_varchar (parser, q, r1);
break;
}
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.rename.new_name);
q = pt_append_nulstring (parser, q, " as ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_MODIFY_DEFAULT:
q = pt_append_nulstring (parser, q, " change ");
names = p->info.alter.alter_clause.ch_attr_def.attr_name_list;
defaults = p->info.alter.alter_clause.ch_attr_def.data_default_list;
while (names && defaults)
{
r1 = pt_print_bytes (parser, names);
r2 = pt_print_bytes (parser, defaults);
if (names->info.name.meta_class == PT_META_ATTR)
{
q = pt_append_nulstring (parser, q, "class ");
}
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " default ");
q = pt_append_varchar (parser, q, r2);
names = names->next;
defaults = defaults->next;
if (names != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
}
}
break;
case PT_ALTER_DEFAULT:
q = pt_append_nulstring (parser, q, " alter ");
names = p->info.alter.alter_clause.ch_attr_def.attr_name_list;
defaults = p->info.alter.alter_clause.ch_attr_def.data_default_list;
assert (names->next == NULL && defaults->next == NULL);
if (names->info.name.meta_class == PT_META_ATTR)
{
q = pt_append_nulstring (parser, q, "class attribute ");
}
else
{
q = pt_append_nulstring (parser, q, "column ");
}
r1 = pt_print_bytes (parser, names);
r2 = pt_print_bytes (parser, defaults);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " set ");
q = pt_append_varchar (parser, q, r2);
break;
case PT_ADD_SUPCLASS:
r1 = pt_print_bytes_l (parser, p->info.alter.super.sup_class_list);
q = pt_append_nulstring (parser, q, " add superclass ");
q = pt_append_varchar (parser, q, r1);
if (p->info.alter.super.resolution_list)
{
r2 = pt_print_bytes_l (parser, p->info.alter.super.resolution_list);
q = pt_append_nulstring (parser, q, " inherit ");
q = pt_append_varchar (parser, q, r2);
}
break;
case PT_DROP_SUPCLASS:
if (p->info.alter.super.sup_class_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.super.sup_class_list);
q = pt_append_nulstring (parser, q, " drop superclass ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_DROP_RESOLUTION:
if (p->info.alter.super.resolution_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.super.resolution_list);
q = pt_append_nulstring (parser, q, " drop inherit ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_RENAME_RESOLUTION:
if (p->info.alter.super.resolution_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.super.resolution_list);
q = pt_append_nulstring (parser, q, " inherit ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_DROP_CONSTRAINT:
if (p->info.alter.constraint_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.constraint_list);
q = pt_append_nulstring (parser, q, " drop constraint ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_DROP_INDEX_CLAUSE:
if (p->info.alter.constraint_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.constraint_list);
q = pt_append_nulstring (parser, q, " drop ");
if (p->info.alter.alter_clause.index.reverse)
{
q = pt_append_nulstring (parser, q, "reverse ");
}
if (p->info.alter.alter_clause.index.unique)
{
q = pt_append_nulstring (parser, q, "unique ");
}
q = pt_append_nulstring (parser, q, "index ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_DROP_PRIMARY_CLAUSE:
q = pt_append_nulstring (parser, q, " drop primary key");
break;
case PT_DROP_FK_CLAUSE:
if (p->info.alter.constraint_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.constraint_list);
q = pt_append_nulstring (parser, q, " drop foreign key ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_APPLY_PARTITION:
if (p->info.alter.alter_clause.partition.info)
{
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.partition.info);
q = pt_append_nulstring (parser, q, " partition by ");
q = pt_append_varchar (parser, q, r1);
parser->custom_print = save_custom;
}
break;
case PT_REMOVE_PARTITION:
q = pt_append_nulstring (parser, q, " remove partitioning ");
break;
case PT_REORG_PARTITION:
if (p->info.alter.alter_clause.partition.name_list)
{
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.partition.name_list);
q = pt_append_nulstring (parser, q, " reorganize partition ");
q = pt_append_varchar (parser, q, r1);
if (p->info.alter.alter_clause.partition.parts)
{
r2 = pt_print_bytes_l (parser, p->info.alter.alter_clause.partition.parts);
q = pt_append_nulstring (parser, q, " into ( ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, " ) ");
}
parser->custom_print = save_custom;
}
break;
case PT_ANALYZE_PARTITION:
q = pt_append_nulstring (parser, q, " analyze partition ");
if (p->info.alter.alter_clause.partition.name_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.partition.name_list);
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_COALESCE_PARTITION:
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.partition.size);
q = pt_append_nulstring (parser, q, " coalesce partition ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_DROP_PARTITION:
if (p->info.alter.alter_clause.partition.name_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.partition.name_list);
q = pt_append_nulstring (parser, q, " drop partition ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_ADD_PARTITION:
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.partition.parts);
q = pt_append_nulstring (parser, q, " add partition ( ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ) ");
break;
case PT_ADD_HASHPARTITION:
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.partition.size);
q = pt_append_nulstring (parser, q, " add partition partitions ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_PROMOTE_PARTITION:
if (p->info.alter.alter_clause.partition.name_list)
{
r1 = pt_print_bytes_l (parser, p->info.alter.alter_clause.partition.name_list);
q = pt_append_nulstring (parser, q, " promote partition ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_CHANGE_AUTO_INCREMENT:
r1 = pt_print_bytes (parser, p->info.alter.alter_clause.auto_increment.start_value);
q = pt_append_nulstring (parser, q, " auto_increment = ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_ADD_INDEX_CLAUSE:
q = pt_append_nulstring (parser, q, " add ");
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_INDEX;
r1 = pt_print_bytes_l (parser, p->info.alter.create_index);
parser->custom_print = save_custom;
if (r1)
{
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
break;
}
if (p->info.alter.super.resolution_list && p->info.alter.code != PT_ADD_SUPCLASS
&& p->info.alter.code != PT_DROP_RESOLUTION && p->info.alter.code != PT_RENAME_RESOLUTION)
{
r1 = pt_print_bytes_l (parser, p->info.alter.super.resolution_list);
q = pt_append_nulstring (parser, q, " inherit ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/*
* pt_print_alter () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_alter (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1 = NULL;
PT_NODE *crt_clause = NULL;
/* ALTER VCLASS XYZ ... */
r1 = pt_print_bytes (parser, p->info.alter.entity_name);
q = pt_append_nulstring (parser, q, "alter ");
if (p->info.alter.hint != PT_HINT_NONE)
{
q = pt_append_nulstring (parser, q, "/*+ ");
if (p->info.alter.hint == PT_HINT_SKIP_UPDATE_NULL)
{
q = pt_append_nulstring (parser, q, "SKIP_UPDATE_NULL");
}
q = pt_append_nulstring (parser, q, " */ ");
}
q = pt_append_nulstring (parser, q, pt_show_misc_type (p->info.alter.entity_type));
q = pt_append_nulstring (parser, q, " ");
q = pt_append_varchar (parser, q, r1);
for (crt_clause = p; crt_clause != NULL; crt_clause = crt_clause->next)
{
r1 = pt_print_alter_one_clause (parser, crt_clause);
q = pt_append_varchar (parser, q, r1);
if (crt_clause->next != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
}
}
return q;
}
/* ALTER_INDEX */
/*
* pt_apply_alter_index () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_alter_index (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.index.indexed_class, arg);
PT_APPLY_WALK (parser, p->info.index.column_names, arg);
PT_APPLY_WALK (parser, p->info.index.where, arg);
PT_APPLY_WALK (parser, p->info.index.function_expr, arg);
return p;
}
/*
* pt_print_alter_index () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_alter_index (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1, *comment;
unsigned int saved_cp = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes (parser, p->info.index.indexed_class);
parser->custom_print = saved_cp;
b = pt_append_nulstring (parser, b, "alter");
if (p->info.index.reverse)
{
b = pt_append_nulstring (parser, b, " reverse");
}
if (p->info.index.unique)
{
b = pt_append_nulstring (parser, b, " unique");
}
b = pt_append_nulstring (parser, b, " index ");
if (p->info.index.index_name)
{
const char *index_name = p->info.index.index_name->info.name.original;
b = pt_append_bytes (parser, b, index_name, strlen (index_name));
}
assert (r1 != NULL);
b = pt_append_nulstring (parser, b, " on ");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, " ");
#if defined (ENABLE_RENAME_CONSTRAINT)
if (p->info.index.code == PT_RENAME_INDEX)
{
b = pt_append_nulstring (parser, b, "rename to ");
if (p->info.index.new_name)
{
const char *new_name = p->info.index.new_name->info.name.original;
b = pt_append_bytes (parser, b, new_name, strlen (new_name));
}
}
#endif
if (p->info.index.index_status == SM_INVISIBLE_INDEX)
{
b = pt_append_nulstring (parser, b, " INVISIBLE ");
}
else if (p->info.index.index_status == SM_NORMAL_INDEX)
{
b = pt_append_nulstring (parser, b, " VISIBLE ");
}
if (p->info.index.comment != NULL)
{
comment = pt_print_bytes (parser, p->info.index.comment);
b = pt_append_nulstring (parser, b, " comment ");
b = pt_append_varchar (parser, b, comment);
b = pt_append_nulstring (parser, b, " ");
}
if (p->info.index.code == PT_REBUILD_INDEX)
{
b = pt_append_nulstring (parser, b, "rebuild");
}
return b;
}
/* ALTER_USER */
/*
* pt_apply_alter_user () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_alter_user (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.alter_user.user_name, arg);
PT_APPLY_WALK (parser, p->info.alter_user.password, arg);
PT_APPLY_WALK (parser, p->info.alter_user.members, arg);
return p;
}
/*
* pt_print_alter_user () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_alter_user (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1;
r1 = pt_print_bytes (parser, p->info.alter_user.user_name);
b = pt_append_nulstring (parser, b, "alter user ");
b = pt_append_varchar (parser, b, r1);
if (p->info.alter_user.password != NULL)
{
r1 = pt_print_bytes (parser, p->info.alter_user.password);
b = pt_append_nulstring (parser, b, " password ");
b = pt_append_varchar (parser, b, r1);
}
if (p->info.alter_user.members != NULL)
{
if (p->info.alter_user.code == PT_ADD_MEMBERS)
{
r1 = pt_print_bytes (parser, p->info.alter_user.members);
b = pt_append_nulstring (parser, b, " add members ");
b = pt_append_varchar (parser, b, r1);
}
else if (p->info.alter_user.code == PT_DROP_MEMBERS)
{
r1 = pt_print_bytes (parser, p->info.alter_user.members);
b = pt_append_nulstring (parser, b, " drop members ");
b = pt_append_varchar (parser, b, r1);
}
else
{
assert (false);
}
}
if (p->info.alter_user.comment != NULL)
{
r1 = pt_print_bytes (parser, p->info.alter_user.comment);
b = pt_append_nulstring (parser, b, " comment ");
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/* ALTER_TRIGGER */
/*
* pt_apply_alter_trigger () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_alter_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.alter_trigger.trigger_spec_list, arg);
PT_APPLY_WALK (parser, p->info.alter_trigger.trigger_priority, arg);
return p;
}
/*
* pt_init_alter_trigger () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_alter_trigger (PT_NODE * p)
{
p->info.alter_trigger.trigger_status = PT_MISC_DUMMY;
return (p);
}
/*
* pt_print_alter_trigger () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_alter_trigger (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
r1 = pt_print_bytes_l (parser, p->info.alter_trigger.trigger_spec_list);
b = pt_append_nulstring (parser, b, "alter trigger ");
b = pt_append_varchar (parser, b, r1);
if (p->info.alter_trigger.trigger_owner != NULL)
{
r1 = pt_print_bytes (parser, p->info.alter_trigger.trigger_owner);
b = pt_append_nulstring (parser, b, " owner to ");
b = pt_append_varchar (parser, b, r1);
}
else if (p->info.alter_trigger.trigger_priority)
{
r1 = pt_print_bytes (parser, p->info.alter_trigger.trigger_priority);
b = pt_append_nulstring (parser, b, " priority ");
b = pt_append_varchar (parser, b, r1);
}
else if (p->info.alter_trigger.trigger_status == PT_ACTIVE || p->info.alter_trigger.trigger_status == PT_INACTIVE)
{
b = pt_append_nulstring (parser, b, " status ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.alter_trigger.trigger_status));
}
if (p->info.alter_trigger.comment != NULL)
{
b = pt_append_nulstring (parser, b, " comment ");
r1 = pt_print_bytes (parser, p->info.alter_trigger.comment);
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/* ATTACH */
/*
* pt_apply_attach () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_attach (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/*
* pt_print_attach () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_attach (PARSER_CONTEXT * parser, PT_NODE * p)
{
char s[PT_MEMB_BUF_SIZE];
sprintf (s, "attach %d ", p->info.attach.trans_id);
return pt_append_nulstring (parser, NULL, s);
}
/* ATTR_DEF */
/*
* pt_apply_attr_def () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_attr_def (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.attr_def.attr_name, arg);
PT_APPLY_WALK (parser, p->info.attr_def.data_default, arg);
PT_APPLY_WALK (parser, p->info.attr_def.auto_increment, arg);
PT_APPLY_WALK (parser, p->info.attr_def.ordering_info, arg);
return p;
}
/*
* pt_init_attr_def () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_attr_def (PT_NODE * p)
{
p->info.attr_def.attr_type = PT_NORMAL;
return p;
}
/*
* pt_print_attr_def () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_attr_def (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
char s[PT_MEMB_BUF_SIZE];
if (!(parser->custom_print & PT_SUPPRESS_META_ATTR_CLASS) && p->info.attr_def.attr_type == PT_META_ATTR)
{
q = pt_append_nulstring (parser, q, " class ");
}
r1 = pt_print_bytes (parser, p->info.attr_def.attr_name);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ");
switch (p->type_enum)
{
case PT_TYPE_OBJECT:
if (p->data_type)
{
r1 = pt_print_bytes (parser, p->data_type);
q = pt_append_varchar (parser, q, r1);
}
else
{
q = pt_append_nulstring (parser, q, "object");
}
break;
case PT_TYPE_NUMERIC:
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
if (p->data_type)
{
/* only show non-default parameter */
if (p->data_type->info.data_type.precision != DB_DEFAULT_NUMERIC_PRECISION
|| p->data_type->info.data_type.dec_precision != DB_DEFAULT_NUMERIC_SCALE)
{
sprintf (s, "(%d,%d)", p->data_type->info.data_type.precision,
p->data_type->info.data_type.dec_precision);
q = pt_append_nulstring (parser, q, s);
}
}
break;
case PT_TYPE_CHAR:
case PT_TYPE_VARCHAR:
case PT_TYPE_BIT:
case PT_TYPE_VARBIT:
case PT_TYPE_FLOAT:
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
if (p->data_type)
{
bool show_precision;
int precision;
precision = p->data_type->info.data_type.precision;
switch (p->type_enum)
{
case PT_TYPE_CHAR:
case PT_TYPE_BIT:
/* fixed data type: always show parameter */
show_precision = true;
break;
default:
/* variable data type: only show non-maximum(i.e., default) parameter */
if (precision == TP_FLOATING_PRECISION_VALUE)
{
show_precision = false;
}
else if (p->type_enum == PT_TYPE_VARCHAR)
{
show_precision = (precision != DB_MAX_VARCHAR_PRECISION);
}
else if (p->type_enum == PT_TYPE_VARBIT)
{
show_precision = (precision != DB_MAX_VARBIT_PRECISION);
}
else
{
show_precision = (precision != 7);
}
break;
}
if (show_precision == true)
{
sprintf (s, "(%d)", precision);
q = pt_append_nulstring (parser, q, s);
}
}
break;
case PT_TYPE_INTEGER:
case PT_TYPE_SMALLINT:
case PT_TYPE_BIGINT:
case PT_TYPE_DOUBLE:
case PT_TYPE_MONETARY:
case PT_TYPE_DATE:
case PT_TYPE_TIME:
case PT_TYPE_TIMESTAMP:
case PT_TYPE_TIMESTAMPTZ:
case PT_TYPE_TIMESTAMPLTZ:
case PT_TYPE_DATETIME:
case PT_TYPE_DATETIMETZ:
case PT_TYPE_DATETIMELTZ:
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
break;
case PT_TYPE_NONE:
/* no type is a blank attr def, as in view creation */
break;
case PT_TYPE_ENUMERATION:
/* print only elements of the ENUMERATION */
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
q = pt_append_nulstring (parser, q, "(");
if (p->data_type != NULL)
{
r1 = pt_print_bytes_l (parser, p->data_type->info.data_type.enumeration);
}
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
default:
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
if (p->data_type)
{
r1 = pt_print_bytes_l (parser, p->data_type);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
break;
}
/* collation must be the first to be printed after type, precision */
if (PT_HAS_COLLATION (p->type_enum) && p->data_type != NULL
&& (p->data_type->info.data_type.has_coll_spec || p->data_type->info.data_type.has_cs_spec))
{
sprintf (s, " collate %s", lang_get_collation_name (p->data_type->info.data_type.collation_id));
q = pt_append_nulstring (parser, q, s);
}
if (p->info.attr_def.attr_invisible == PT_ATTR_INVISIBLE)
{
q = pt_append_nulstring (parser, q, " invisible ");
}
if (p->info.attr_def.data_default)
{
r1 = pt_print_bytes (parser, p->info.attr_def.data_default);
q = pt_append_varchar (parser, q, r1);
}
if (p->info.attr_def.on_update != DB_DEFAULT_NONE)
{
const char *c = db_default_expression_string (p->info.attr_def.on_update);
q = pt_append_nulstring (parser, q, " on update ");
q = pt_append_nulstring (parser, q, c);
q = pt_append_nulstring (parser, q, " ");
}
if (p->info.attr_def.auto_increment)
{
r1 = pt_print_bytes (parser, p->info.attr_def.auto_increment);
q = pt_append_varchar (parser, q, r1);
}
/* The constraint information is no longer available in the attribute branch of the parse tree. For now we'll just
* comment this section out. If we really want to print out this information, we'll have to search the constraint
* branch of the parse tree to get it. if (p->info.attr_def.constrain_unique) q=pt_append_nulstring(parser, q, "
* unique "); */
if (p->info.attr_def.constrain_not_null)
{
q = pt_append_nulstring (parser, q, " not null ");
}
if (p->info.attr_def.comment != NULL)
{
r1 = pt_print_bytes (parser, p->info.attr_def.comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
if (!(parser->custom_print & PT_SUPPRESS_ORDERING) && p->info.attr_def.ordering_info)
{
r1 = pt_print_bytes (parser, p->info.attr_def.ordering_info);
q = pt_append_nulstring (parser, q, " ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ");
}
return q;
}
/* ATTR_ORDERING */
/*
* pt_apply_attr_ordering () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_attr_ordering (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.attr_ordering.after, arg);
return p;
}
/*
* pt_print_attr_ordering () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_attr_ordering (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1 = NULL;
if (p->info.attr_ordering.first)
{
q = pt_append_nulstring (parser, q, "first");
}
else
{
r1 = pt_print_bytes (parser, p->info.attr_ordering.after);
q = pt_append_nulstring (parser, q, "after ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* AUTH_CMD */
/*
* pt_apply_auth_cmd () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_auth_cmd (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.auth_cmd.attr_mthd_list, arg);
return p;
}
/*
* pt_init_auth_cmd () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_auth_cmd (PT_NODE * p)
{
p->info.auth_cmd.auth_cmd = PT_NO_PRIV;
return (p);
}
/*
* pt_print_auth_cmd () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_auth_cmd (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
q = pt_append_nulstring (parser, q, pt_show_priv (p->info.auth_cmd.auth_cmd));
if (p->info.auth_cmd.attr_mthd_list)
{
r1 = pt_print_bytes_l (parser, p->info.auth_cmd.attr_mthd_list);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
return q;
}
/* CHECK_OPTION */
/*
* pt_apply_check_option () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_check_option (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.check_option.expr, arg);
return p;
}
/*
* pt_print_check_option () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_check_option (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL;
q = pt_print_and_list (parser, p->info.check_option.expr);
return q;
}
/* COMMIT_WORK */
/*
* pt_apply_commit_work () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_commit_work (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/*
* pt_print_commit_work () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_commit_work (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL;
q = pt_append_nulstring (parser, q, "commit work");
if (p->info.commit_work.retain_lock)
{
q = pt_append_nulstring (parser, q, " retain lock");
}
return q;
}
/* CREATE_ENTITY */
/*
* pt_apply_create_entity () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_create_entity (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.create_entity.entity_name, arg);
PT_APPLY_WALK (parser, p->info.create_entity.supclass_list, arg);
PT_APPLY_WALK (parser, p->info.create_entity.class_attr_def_list, arg);
PT_APPLY_WALK (parser, p->info.create_entity.attr_def_list, arg);
PT_APPLY_WALK (parser, p->info.create_entity.method_def_list, arg);
PT_APPLY_WALK (parser, p->info.create_entity.method_file_list, arg);
PT_APPLY_WALK (parser, p->info.create_entity.resolution_list, arg);
PT_APPLY_WALK (parser, p->info.create_entity.as_query_list, arg);
PT_APPLY_WALK (parser, p->info.create_entity.object_id_list, arg);
PT_APPLY_WALK (parser, p->info.create_entity.update, arg);
PT_APPLY_WALK (parser, p->info.create_entity.constraint_list, arg);
PT_APPLY_WALK (parser, p->info.create_entity.create_index, arg);
PT_APPLY_WALK (parser, p->info.create_entity.partition_info, arg);
PT_APPLY_WALK (parser, p->info.create_entity.internal_stmts, arg);
PT_APPLY_WALK (parser, p->info.create_entity.create_like, arg);
PT_APPLY_WALK (parser, p->info.create_entity.create_select, arg);
return p;
}
/*
* pt_init_create_entity () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_create_entity (PT_NODE * p)
{
p->info.create_entity.entity_type = (PT_MISC_TYPE) 0;
p->info.create_entity.create_select_action = PT_CREATE_SELECT_NO_ACTION;
return p;
}
/*
* pt_print_create_entity () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_create_entity (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
unsigned int save_custom;
PT_MISC_TYPE view_check_option;
r1 = pt_print_bytes (parser, p->info.create_entity.entity_name);
q = pt_append_nulstring (parser, q, "create ");
if (p->info.create_entity.or_replace)
{
q = pt_append_nulstring (parser, q, "or replace ");
}
q = pt_append_nulstring (parser, q, pt_show_misc_type (p->info.create_entity.entity_type));
q = pt_append_nulstring (parser, q, " ");
if (p->info.create_entity.if_not_exists)
{
q = pt_append_nulstring (parser, q, "if not exists ");
}
q = pt_append_varchar (parser, q, r1);
if (p->info.create_entity.create_like)
{
r1 = pt_print_bytes (parser, p->info.create_entity.create_like);
q = pt_append_nulstring (parser, q, " like ");
q = pt_append_varchar (parser, q, r1);
return q;
}
if (p->info.create_entity.supclass_list)
{
r1 = pt_print_bytes_l (parser, p->info.create_entity.supclass_list);
q = pt_append_nulstring (parser, q, " under ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.create_entity.class_attr_def_list)
{
save_custom = parser->custom_print;
parser->custom_print |= (PT_SUPPRESS_RESOLVED | PT_SUPPRESS_META_ATTR_CLASS);
r1 = pt_print_bytes_l (parser, p->info.create_entity.class_attr_def_list);
q = pt_append_nulstring (parser, q, " class attribute ( ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ) ");
parser->custom_print = save_custom;
}
if (p->info.create_entity.attr_def_list || p->info.create_entity.constraint_list
|| p->info.create_entity.create_index)
{
PT_NODE *constraint;
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes_l (parser, p->info.create_entity.attr_def_list);
parser->custom_print = save_custom;
q = pt_append_nulstring (parser, q, " ( ");
q = pt_append_varchar (parser, q, r1);
/* Don't print out not-null constraints */
constraint = p->info.create_entity.constraint_list;
while (constraint
&& (constraint->info.constraint.type == PT_CONSTRAIN_NULL
|| constraint->info.constraint.type == PT_CONSTRAIN_NOT_NULL))
{
constraint = constraint->next;
}
if (p->info.create_entity.attr_def_list && constraint)
{
q = pt_append_nulstring (parser, q, ", ");
}
if (constraint)
{
r1 = pt_print_bytes (parser, constraint);
q = pt_append_varchar (parser, q, r1);
constraint = constraint->next;
while (constraint)
{
/* keep skipping NOT_NULL constraints */
while (constraint
&& (constraint->info.constraint.type == PT_CONSTRAIN_NULL
|| constraint->info.constraint.type == PT_CONSTRAIN_NOT_NULL))
{
constraint = constraint->next;
}
if (constraint)
{
/* Have a list */
r1 = pt_print_bytes (parser, constraint);
q = pt_append_bytes (parser, q, ", ", 2);
q = pt_append_varchar (parser, q, r1);
constraint = constraint->next;
}
}
}
if (p->info.create_entity.create_index)
{
if (p->info.create_entity.attr_def_list || p->info.create_entity.constraint_list)
{
q = pt_append_nulstring (parser, q, ", ");
}
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_INDEX;
r1 = pt_print_bytes_l (parser, p->info.create_entity.create_index);
parser->custom_print = save_custom;
if (r1)
{
q = pt_append_varchar (parser, q, r1);
}
}
q = pt_append_nulstring (parser, q, " ) ");
}
if (p->info.create_entity.object_id_list)
{
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes_l (parser, p->info.create_entity.object_id_list);
parser->custom_print = save_custom;
q = pt_append_nulstring (parser, q, " object_id ( ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ) ");
}
if (p->info.create_entity.table_option_list)
{
r1 = pt_print_bytes_l (parser, p->info.create_entity.table_option_list);
q = pt_append_nulstring (parser, q, " ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ");
}
if (p->info.create_entity.method_def_list)
{
r1 = pt_print_bytes_l (parser, p->info.create_entity.method_def_list);
q = pt_append_nulstring (parser, q, " method ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.create_entity.method_file_list)
{
r1 = pt_print_bytes_l (parser, p->info.create_entity.method_file_list);
q = pt_append_nulstring (parser, q, " file ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.create_entity.resolution_list)
{
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes_l (parser, p->info.create_entity.resolution_list);
parser->custom_print = save_custom;
q = pt_append_nulstring (parser, q, " inherit ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.create_entity.as_query_list)
{
save_custom = parser->custom_print;
parser->custom_print |= PT_PRINT_ALIAS;
r1 = pt_print_bytes_l (parser, p->info.create_entity.as_query_list);
q = pt_append_nulstring (parser, q, " as ");
q = pt_append_varchar (parser, q, r1);
parser->custom_print = save_custom;
}
view_check_option = p->info.create_entity.with_check_option;
if (view_check_option == PT_LOCAL)
{
q = pt_append_nulstring (parser, q, " with local check option");
}
else if (view_check_option == PT_CASCADED)
{
q = pt_append_nulstring (parser, q, " with cascaded check option");
}
if (p->info.create_entity.entity_type == PT_VCLASS)
{
if (p->info.create_entity.vclass_comment != NULL)
{
q = pt_append_nulstring (parser, q, " comment ");
r1 = pt_print_bytes (parser, p->info.create_entity.vclass_comment);
q = pt_append_varchar (parser, q, r1);
}
}
/* this is out of date */
if (p->info.create_entity.update)
{
r1 = pt_print_bytes_l (parser, p->info.create_entity.update);
q = pt_append_nulstring (parser, q, " update ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.create_entity.entity_type == PT_VCLASS)
{
/* the ';' is not strictly speaking ANSI */
q = pt_append_nulstring (parser, q, ";");
}
if (p->info.create_entity.partition_info)
{
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes_l (parser, p->info.create_entity.partition_info);
q = pt_append_nulstring (parser, q, " partition by ");
q = pt_append_varchar (parser, q, r1);
parser->custom_print = save_custom;
}
if (p->info.create_entity.create_select)
{
save_custom = parser->custom_print;
parser->custom_print |= PT_PRINT_ALIAS;
r1 = pt_print_bytes (parser, p->info.create_entity.create_select);
if (p->info.create_entity.create_select_action == PT_CREATE_SELECT_REPLACE)
{
q = pt_append_nulstring (parser, q, " replace");
}
else if (p->info.create_entity.create_select_action == PT_CREATE_SELECT_IGNORE)
{
q = pt_append_nulstring (parser, q, " ignore");
}
q = pt_append_nulstring (parser, q, " as ");
q = pt_append_varchar (parser, q, r1);
parser->custom_print = save_custom;
}
return q;
}
/*
* pt_apply_update_histogram () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_update_histogram (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.histogram.target_table_spec, arg);
PT_APPLY_WALK (parser, p->info.histogram.target_columns, arg);
return p;
}
/*
* pt_print_update_histogram () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PARSER_VARCHAR *
pt_print_analyze_histogram (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *tbl = 0, *cl = 0;
unsigned int saved_cp = parser->custom_print;
PT_NODE *target_columns;
b = pt_append_nulstring (parser, b, "analyze table ");
if (p->info.histogram.target_table_spec)
{
tbl = pt_print_bytes (parser, p->info.histogram.target_table_spec);
}
b = pt_append_varchar (parser, b, tbl);
if (p->node_type == PT_UPDATE_HISTOGRAM)
{
b = pt_append_nulstring (parser, b, " update histogram");
}
else if (p->node_type == PT_DROP_HISTOGRAM)
{
b = pt_append_nulstring (parser, b, " drop histogram");
}
b = pt_append_nulstring (parser, b, " on ");
if (p->info.histogram.target_columns)
{
target_columns = p->info.histogram.target_columns;
cl = pt_print_bytes_l (parser, target_columns);
}
b = pt_append_nulstring (parser, b, " (");
b = pt_append_varchar (parser, b, cl);
b = pt_append_nulstring (parser, b, ") ");
parser->custom_print = saved_cp;
return b;
}
/*
* pt_print_show_histogram () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PARSER_VARCHAR *
pt_print_show_histogram (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *tbl = 0, *cl = 0;
unsigned int saved_cp = parser->custom_print;
PT_NODE *target_columns;
b = pt_append_nulstring (parser, b, "show histogram ");
if (p->info.histogram.target_table_spec)
{
tbl = pt_print_bytes (parser, p->info.histogram.target_table_spec);
}
b = pt_append_varchar (parser, b, tbl);
b = pt_append_nulstring (parser, b, " on ");
if (p->info.histogram.target_columns)
{
target_columns = p->info.histogram.target_columns;
cl = pt_print_bytes_l (parser, target_columns);
}
b = pt_append_nulstring (parser, b, " (");
b = pt_append_varchar (parser, b, cl);
b = pt_append_nulstring (parser, b, ") ");
parser->custom_print = saved_cp;
return b;
}
/* CREATE_INDEX */
/*
* pt_apply_create_index () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_create_index (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.index.indexed_class, arg);
PT_APPLY_WALK (parser, p->info.index.column_names, arg);
PT_APPLY_WALK (parser, p->info.index.index_name, arg);
PT_APPLY_WALK (parser, p->info.index.prefix_length, arg);
PT_APPLY_WALK (parser, p->info.index.where, arg);
PT_APPLY_WALK (parser, p->info.index.function_expr, arg);
return p;
}
/*
* pt_init_create_index () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_create_index (PT_NODE * p)
{
p->info.index.func_pos = -1;
return p;
}
/*
* pt_print_create_index () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_create_index (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1 = 0, *r2 = 0, *r3 = 0, *r4 = 0;
unsigned int saved_cp = parser->custom_print;
PT_NODE *sort_spec, *prefix_length;
PARSER_VARCHAR *comment = NULL;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
if (!(parser->custom_print & PT_SUPPRESS_INDEX))
{
r1 = pt_print_bytes (parser, p->info.index.indexed_class);
b = pt_append_nulstring (parser, b, "create");
}
if (p->info.index.reverse)
{
b = pt_append_nulstring (parser, b, " reverse");
}
if (p->info.index.unique)
{
b = pt_append_nulstring (parser, b, " unique");
}
b = pt_append_nulstring (parser, b, " index");
if (p->info.index.index_name)
{
const char *index_name = p->info.index.index_name->info.name.original;
b = pt_append_nulstring (parser, b, " [");
b = pt_append_bytes (parser, b, index_name, strlen (index_name));
b = pt_append_nulstring (parser, b, "]");
}
if (!(parser->custom_print & PT_SUPPRESS_INDEX))
{
b = pt_append_nulstring (parser, b, " on ");
b = pt_append_varchar (parser, b, r1);
}
/* if use prefix_length, the length of sort_spec must be 1 */
prefix_length = p->info.index.prefix_length;
if (prefix_length != NULL)
{
sort_spec = p->info.index.column_names;
assert (sort_spec != NULL);
/* sort_spec */
r3 = pt_print_bytes (parser, sort_spec->info.sort_spec.expr);
r2 = pt_append_varchar (parser, r2, r3);
/* prefix_length */
r3 = pt_print_bytes (parser, prefix_length);
r2 = pt_append_nulstring (parser, r2, " (");
r2 = pt_append_varchar (parser, r2, r3);
r2 = pt_append_nulstring (parser, r2, ") ");
if (sort_spec->info.sort_spec.asc_or_desc == PT_DESC)
{
r2 = pt_append_nulstring (parser, r2, " desc ");
}
}
else
{
r2 = pt_print_index_columns (parser, p);
}
b = pt_append_nulstring (parser, b, " (");
b = pt_append_varchar (parser, b, r2);
b = pt_append_nulstring (parser, b, ") ");
if (p->info.index.where != NULL)
{
r4 = pt_print_and_list (parser, p->info.index.where);
b = pt_append_nulstring (parser, b, " where ");
b = pt_append_varchar (parser, b, r4);
}
if (p->info.index.unique == false)
{
char buf[64] = { 0x00, };
if (p->info.index.deduplicate_level == DEDUPLICATE_OPTION_AUTO)
{
/* Do not print level */ ;
}
else if (p->info.index.deduplicate_level != DEDUPLICATE_KEY_LEVEL_OFF)
{
dk_print_deduplicate_key_info (buf, sizeof (buf), p->info.index.deduplicate_level);
}
if (buf[0])
{
b = pt_append_nulstring (parser, b, " WITH ");
b = pt_append_nulstring (parser, b, buf);
if (p->info.index.index_status == SM_ONLINE_INDEX_BUILDING_IN_PROGRESS)
{
b = pt_append_nulstring (parser, b, ", ONLINE ");
}
}
else if (p->info.index.index_status == SM_ONLINE_INDEX_BUILDING_IN_PROGRESS)
{
b = pt_append_nulstring (parser, b, " WITH ONLINE ");
}
}
else
{
if (p->info.index.index_status == SM_ONLINE_INDEX_BUILDING_IN_PROGRESS)
{
b = pt_append_nulstring (parser, b, " WITH ONLINE ");
}
}
if (p->info.index.index_status == SM_INVISIBLE_INDEX)
{
b = pt_append_nulstring (parser, b, " INVISIBLE ");
}
if (p->info.index.comment != NULL)
{
comment = pt_print_bytes (parser, p->info.index.comment);
b = pt_append_nulstring (parser, b, " comment ");
b = pt_append_varchar (parser, b, comment);
}
parser->custom_print = saved_cp;
return b;
}
/* CREATE_USER */
/*
* pt_apply_create_user () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_create_user (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.create_user.user_name, arg);
PT_APPLY_WALK (parser, p->info.create_user.password, arg);
PT_APPLY_WALK (parser, p->info.create_user.groups, arg);
PT_APPLY_WALK (parser, p->info.create_user.members, arg);
return p;
}
/*
* pt_print_create_user () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_create_user (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1;
r1 = pt_print_bytes (parser, p->info.create_user.user_name);
b = pt_append_nulstring (parser, b, "create user ");
b = pt_append_varchar (parser, b, r1);
if (p->info.create_user.password)
{
r1 = pt_print_bytes (parser, p->info.create_user.password);
b = pt_append_nulstring (parser, b, " password ");
b = pt_append_varchar (parser, b, r1);
}
if (p->info.create_user.groups)
{
r1 = pt_print_bytes (parser, p->info.create_user.groups);
b = pt_append_nulstring (parser, b, " groups ");
b = pt_append_varchar (parser, b, r1);
}
if (p->info.create_user.members)
{
r1 = pt_print_bytes (parser, p->info.create_user.members);
b = pt_append_nulstring (parser, b, " members ");
b = pt_append_varchar (parser, b, r1);
}
if (p->info.create_user.comment != NULL)
{
r1 = pt_print_bytes (parser, p->info.create_user.comment);
b = pt_append_nulstring (parser, b, " comment ");
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/* CREATE_TRIGGER */
/*
* pt_apply_create_trigger () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_create_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.create_trigger.trigger_name, arg);
PT_APPLY_WALK (parser, p->info.create_trigger.trigger_priority, arg);
PT_APPLY_WALK (parser, p->info.create_trigger.trigger_event, arg);
PT_APPLY_WALK (parser, p->info.create_trigger.trigger_reference, arg);
PT_APPLY_WALK (parser, p->info.create_trigger.trigger_condition, arg);
PT_APPLY_WALK (parser, p->info.create_trigger.trigger_action, arg);
return p;
}
/*
* pt_print_create_trigger () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_create_trigger (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
r1 = pt_print_bytes (parser, p->info.create_trigger.trigger_name);
q = pt_append_nulstring (parser, q, "create trigger ");
q = pt_append_varchar (parser, q, r1);
if (p->info.create_trigger.trigger_status != PT_MISC_DUMMY)
{
q = pt_append_nulstring (parser, q, " status ");
q = pt_append_nulstring (parser, q, pt_show_misc_type (p->info.create_trigger.trigger_status));
}
q = pt_append_nulstring (parser, q, " ");
if (p->info.create_trigger.trigger_priority)
{
r1 = pt_print_bytes (parser, p->info.create_trigger.trigger_priority);
q = pt_append_nulstring (parser, q, " priority ");
q = pt_append_varchar (parser, q, r1);
}
r1 = pt_print_bytes (parser, p->info.create_trigger.trigger_event);
q = pt_append_nulstring (parser, q, " ");
q = pt_append_nulstring (parser, q, pt_show_misc_type (p->info.create_trigger.condition_time));
q = pt_append_nulstring (parser, q, " ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ");
if (p->info.create_trigger.trigger_condition)
{
r1 = pt_print_bytes (parser, p->info.create_trigger.trigger_condition);
q = pt_append_nulstring (parser, q, "if ");
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, " execute ");
if (p->info.create_trigger.action_time != PT_MISC_DUMMY)
{
q = pt_append_nulstring (parser, q, pt_show_misc_type (p->info.create_trigger.action_time));
q = pt_append_nulstring (parser, q, " ");
}
r1 = pt_print_bytes (parser, p->info.create_trigger.trigger_action);
q = pt_append_varchar (parser, q, r1);
if (p->info.create_trigger.comment != NULL)
{
r1 = pt_print_bytes (parser, p->info.create_trigger.comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/*
* pt_apply_create_stored_procedure () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_create_stored_procedure (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.sp.name, arg);
PT_APPLY_WALK (parser, p->info.sp.param_list, arg);
PT_APPLY_WALK (parser, p->info.sp.ret_data_type, arg);
return p;
}
/*
* pt_apply_stored_procedure () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_stored_procedure (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.sp.name, arg);
return p;
}
/*
* pt_print_create_stored_procedure () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_create_stored_procedure (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1, *r2, *r3;
if (parser->flag.is_unloading_plcsql_def)
{
q = pt_append_nulstring (parser, q, "CREATE OR REPLACE ");
q = pt_append_nulstring (parser, q, (p->info.sp.type == PT_SP_PROCEDURE) ? "PROCEDURE" : "FUNCTION");
}
else
{
q = pt_append_nulstring (parser, q, "create ");
if (p->info.sp.or_replace)
{
q = pt_append_nulstring (parser, q, "or replace ");
}
q = pt_append_nulstring (parser, q, pt_show_misc_type (p->info.sp.type));
}
q = pt_append_nulstring (parser, q, " ");
r1 = pt_print_bytes (parser, p->info.sp.name);
q = pt_append_varchar (parser, q, r1);
r2 = pt_print_bytes_l (parser, p->info.sp.param_list);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
if (p->info.sp.type == PT_SP_FUNCTION)
{
q = pt_append_nulstring (parser, q, parser->flag.is_unloading_plcsql_def ? " RETURN " : " return ");
if (p->info.sp.ret_data_type)
{
q = pt_append_varchar (parser, q, pt_print_bytes (parser, p->info.sp.ret_data_type));
}
else
{
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->info.sp.ret_type));
}
}
if (parser->flag.is_unloading_plcsql_def)
{
if (p->info.sp.auth_id == PT_AUTHID_OWNER)
{
q = pt_append_nulstring (parser, q, " AUTHID OWNER");
}
else
{
q = pt_append_nulstring (parser, q, " AUTHID CALLER");
}
if (p->info.sp.dtrm_type == PT_DETERMINISTIC)
{
q = pt_append_nulstring (parser, q, " DETERMINISTIC");
}
}
else
{
if (p->info.sp.auth_id == PT_AUTHID_OWNER)
{
q = pt_append_nulstring (parser, q, " authid owner");
}
else
{
q = pt_append_nulstring (parser, q, " authid caller");
}
if (p->info.sp.dtrm_type == PT_DETERMINISTIC)
{
q = pt_append_nulstring (parser, q, " deterministic");
}
}
r3 = pt_print_bytes (parser, p->info.sp.body);
q = pt_append_varchar (parser, q, r3);
// CBRD-26513 : do not print comment when unloading plcsql definition
if (p->info.sp.comment != NULL && !parser->flag.is_unloading_plcsql_def)
{
r1 = pt_print_bytes (parser, p->info.sp.comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/*
* pt_print_drop_stored_procedure () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_drop_stored_procedure (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
r1 = pt_print_bytes_l (parser, p->info.sp.name);
q = pt_append_nulstring (parser, q, "drop ");
q = pt_append_nulstring (parser, q, pt_show_misc_type (p->info.sp.type));
q = pt_append_nulstring (parser, q, " ");
q = pt_append_varchar (parser, q, r1);
return q;
}
/* PREPARE */
/*
* pt_apply_prepare () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_prepare (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/* TRUNCATE ENTITY */
/*
* pt_apply_truncate () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_truncate (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.truncate.spec, arg);
return p;
}
/*
* pt_print_truncate () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_truncate (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
unsigned int save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes_l (parser, p->info.truncate.spec);
parser->custom_print = save_custom;
q = pt_append_nulstring (parser, q, "truncate ");
q = pt_append_varchar (parser, q, r1);
if (p->info.truncate.is_cascade)
{
q = pt_append_nulstring (parser, q, " cascade");
}
return q;
}
/* TABLE OPTION */
/*
* pt_apply_table_option () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_table_option (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.table_option.val, arg);
return p;
}
/*
* pt_init_table_option () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_table_option (PT_NODE * p)
{
p->info.table_option.option = PT_TABLE_OPTION_NONE;
return p;
}
/*
* pt_print_table_option () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_table_option (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1 = NULL;
const char *tde_algo_name;
switch (p->info.table_option.option)
{
case PT_TABLE_OPTION_REUSE_OID:
q = pt_append_nulstring (parser, q, "reuse_oid");
break;
case PT_TABLE_OPTION_DONT_REUSE_OID:
q = pt_append_nulstring (parser, q, "dont_reuse_oid");
break;
case PT_TABLE_OPTION_AUTO_INCREMENT:
q = pt_append_nulstring (parser, q, "auto_increment = ");
break;
case PT_TABLE_OPTION_CHARSET:
q = pt_append_nulstring (parser, q, "charset ");
break;
case PT_TABLE_OPTION_COLLATION:
q = pt_append_nulstring (parser, q, "collate ");
break;
case PT_TABLE_OPTION_COMMENT:
q = pt_append_nulstring (parser, q, "comment = ");
break;
case PT_TABLE_OPTION_ENCRYPT:
q = pt_append_nulstring (parser, q, "encrypt = ");
break;
default:
break;
}
if (p->info.table_option.val != NULL)
{
if (p->info.table_option.option == PT_TABLE_OPTION_CHARSET
|| p->info.table_option.option == PT_TABLE_OPTION_COLLATION)
{
/* print as unquoted string */
assert (p->info.table_option.val != NULL);
assert (p->info.table_option.val->node_type == PT_VALUE);
assert (PT_IS_SIMPLE_CHAR_STRING_TYPE (p->info.table_option.val->type_enum));
r1 = p->info.table_option.val->info.value.data_value.str;
assert (r1 != NULL);
}
else if (p->info.table_option.option == PT_TABLE_OPTION_ENCRYPT)
{
assert (p->info.table_option.val != NULL);
assert (p->info.table_option.val->node_type == PT_VALUE);
assert (p->info.table_option.val->type_enum == PT_TYPE_INTEGER);
tde_algo_name = tde_get_algorithm_name ((TDE_ALGORITHM) p->info.table_option.val->info.value.data_value.i);
if (tde_algo_name != NULL)
{
r1 = pt_append_bytes (parser, r1, tde_algo_name, strlen (tde_algo_name));
}
}
else
{
r1 = pt_print_bytes_l (parser, p->info.table_option.val);
}
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* DO */
/*
* pt_apply_do () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_do (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.do_.expr, arg);
return p;
}
/*
* pt_print_do () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_do (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
unsigned int save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes_l (parser, p->info.do_.expr);
parser->custom_print = save_custom;
q = pt_append_nulstring (parser, q, "do ");
q = pt_append_varchar (parser, q, r1);
return q;
}
/*
* pt_apply_sp_parameter () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_sp_parameter (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/*
* pt_print_sp_parameter () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_sp_parameter (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
r1 = pt_print_bytes (parser, p->info.sp_param.name);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ");
q = pt_append_nulstring (parser, q, parser->flag.is_unloading_plcsql_def ?
(p->info.sp_param.mode == PT_INPUT || p->info.sp_param.mode == PT_NOPUT) ?
"IN" : p->info.sp_param.mode == PT_OUTPUT ?
"OUT" : "INOUT" : pt_show_misc_type (p->info.sp_param.mode));
q = pt_append_nulstring (parser, q, " ");
if (p->data_type)
{
q = pt_append_varchar (parser, q, pt_print_bytes (parser, p->data_type));
}
else
{
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
}
if (p->info.sp_param.default_value != NULL)
{
r1 = pt_print_bytes (parser, p->info.sp_param.default_value);
q = pt_append_varchar (parser, q, r1);
}
if (p->info.sp_param.comment != NULL)
{
r1 = pt_print_bytes (parser, p->info.sp_param.comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/*
* pt_apply_sp_body () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_sp_body (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/*
* pt_print_sp_parameter () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_sp_body (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1 = NULL;
q = pt_append_nulstring (parser, q, parser->flag.is_unloading_plcsql_def ? " AS\n" : " as ");
if (p->info.sp_body.lang == SP_LANG_PLCSQL)
{
r1 = pt_append_varchar (parser, r1, p->info.sp_body.impl->info.value.data_value.str);
}
else
/* (p->info.sp_body.lang == SP_LANG_JAVA) */
{
q = pt_append_nulstring (parser, q, "language java name ");
r1 = pt_print_bytes (parser, p->info.sp_body.decl);
}
q = pt_append_varchar (parser, q, r1);
return q;
}
/* PARTITION */
/*
* pt_apply_partition () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_partition (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.partition.expr, arg);
if (p->info.partition.type == PT_PARTITION_HASH)
{
PT_APPLY_WALK (parser, p->info.partition.hashsize, arg);
}
else
{
PT_APPLY_WALK (parser, p->info.partition.parts, arg);
}
return p;
}
/*
* pt_print_partition () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_partition (PARSER_CONTEXT * parser, PT_NODE * p)
{
char buf[PT_MEMB_BUF_SIZE];
PARSER_VARCHAR *q = NULL, *r1, *r2;
r1 = pt_print_bytes (parser, p->info.partition.expr);
if (p->info.partition.type == PT_PARTITION_HASH)
{
r2 = pt_print_bytes_l (parser, p->info.partition.hashsize);
}
else
{
r2 = pt_print_bytes_l (parser, p->info.partition.parts);
}
sprintf (buf, " %s ( ", pt_show_partition_type (p->info.partition.type));
q = pt_append_nulstring (parser, q, buf);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " ) ");
if (p->info.partition.type == PT_PARTITION_HASH)
{
q = pt_append_nulstring (parser, q, " partitions ");
q = pt_append_varchar (parser, q, r2);
}
else
{
q = pt_append_nulstring (parser, q, " ( ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, " ) ");
}
return q;
}
/*
* pt_apply_parts () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_parts (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.parts.name, arg);
PT_APPLY_WALK (parser, p->info.parts.values, arg);
return p;
}
/*
* pt_print_parts () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_parts (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1, *r2;
PARSER_VARCHAR *comment = NULL;
unsigned int save_custom;
r1 = pt_print_bytes (parser, p->info.parts.name);
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_BIGINT_CAST;
r2 = pt_print_bytes_l (parser, p->info.parts.values);
parser->custom_print = save_custom;
q = pt_append_nulstring (parser, q, " partition ");
q = pt_append_varchar (parser, q, r1);
if (p->info.parts.type == PT_PARTITION_LIST)
{
q = pt_append_nulstring (parser, q, " values in ( ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, " ) ");
}
else
{
q = pt_append_nulstring (parser, q, " values less than");
if (r2 != NULL)
{
q = pt_append_nulstring (parser, q, " ( ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, " ) ");
}
else
{
q = pt_append_nulstring (parser, q, " maxvalue ");
}
}
if (p->info.parts.comment != NULL)
{
comment = pt_print_bytes (parser, p->info.parts.comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, comment);
}
return q;
}
/*
* pt_print_create_serial () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_create_serial (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
r1 = pt_print_bytes (parser, p->info.serial.serial_name);
q = pt_append_nulstring (parser, q, "create serial ");
q = pt_append_varchar (parser, q, r1);
if (p->info.serial.start_val)
{
r1 = pt_print_bytes (parser, p->info.serial.start_val);
q = pt_append_nulstring (parser, q, " start with ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.serial.increment_val)
{
r1 = pt_print_bytes (parser, p->info.serial.increment_val);
q = pt_append_nulstring (parser, q, " increment by ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.serial.min_val)
{
r1 = pt_print_bytes (parser, p->info.serial.min_val);
q = pt_append_nulstring (parser, q, " minvalue ");
q = pt_append_varchar (parser, q, r1);
}
else if (p->info.serial.no_min == 1)
{
q = pt_append_nulstring (parser, q, " nominvalue ");
}
if (p->info.serial.max_val)
{
r1 = pt_print_bytes (parser, p->info.serial.max_val);
q = pt_append_nulstring (parser, q, " maxvalue ");
q = pt_append_varchar (parser, q, r1);
}
else if (p->info.serial.no_max == 1)
{
q = pt_append_nulstring (parser, q, " nomaxvalue ");
}
if (p->info.serial.cyclic)
{
q = pt_append_nulstring (parser, q, " cycle ");
}
else if (p->info.serial.no_cyclic == 1)
{
q = pt_append_nulstring (parser, q, " nocycle ");
}
if (p->info.serial.cached_num_val && p->info.serial.no_cache != 1)
{
r1 = pt_print_bytes (parser, p->info.serial.cached_num_val);
q = pt_append_nulstring (parser, q, " cache ");
q = pt_append_varchar (parser, q, r1);
}
else if (p->info.serial.no_cache != 0)
{
q = pt_append_nulstring (parser, q, " nocache ");
}
if (p->info.serial.comment != NULL)
{
r1 = pt_print_bytes (parser, p->info.serial.comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/*
* pt_print_alter_serial () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_alter_serial (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
r1 = pt_print_bytes (parser, p->info.serial.serial_name);
q = pt_append_nulstring (parser, q, "alter serial ");
q = pt_append_varchar (parser, q, r1);
switch (p->info.serial.code)
{
case PT_SERIAL_OPTION:
if (p->info.serial.start_val != NULL)
{
r1 = pt_print_bytes (parser, p->info.serial.start_val);
q = pt_append_nulstring (parser, q, " start with ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.serial.increment_val)
{
r1 = pt_print_bytes (parser, p->info.serial.increment_val);
q = pt_append_nulstring (parser, q, " increment by ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.serial.min_val)
{
r1 = pt_print_bytes (parser, p->info.serial.min_val);
q = pt_append_nulstring (parser, q, " minvalue ");
q = pt_append_varchar (parser, q, r1);
}
else if (p->info.serial.no_min == 1)
{
q = pt_append_nulstring (parser, q, " nomaxvalue ");
}
if (p->info.serial.max_val)
{
r1 = pt_print_bytes (parser, p->info.serial.max_val);
q = pt_append_nulstring (parser, q, " maxvalue ");
q = pt_append_varchar (parser, q, r1);
}
else if (p->info.serial.no_max == 1)
{
q = pt_append_nulstring (parser, q, " nomaxvalue ");
}
if (p->info.serial.cyclic)
{
q = pt_append_nulstring (parser, q, " cycle ");
}
else if (p->info.serial.no_cyclic == 1)
{
q = pt_append_nulstring (parser, q, " nocycle ");
}
if (p->info.serial.cached_num_val && p->info.serial.no_cache != 1)
{
r1 = pt_print_bytes (parser, p->info.serial.cached_num_val);
q = pt_append_nulstring (parser, q, " cache ");
q = pt_append_varchar (parser, q, r1);
}
else if (p->info.serial.no_cache != 0)
{
q = pt_append_nulstring (parser, q, " nocache ");
}
if (p->info.serial.comment != NULL)
{
r1 = pt_print_bytes (parser, p->info.serial.comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
break;
case PT_CHANGE_OWNER:
if (p->info.serial.owner_name != NULL)
{
r1 = pt_print_bytes (parser, p->info.serial.owner_name);
q = pt_append_nulstring (parser, q, " owner to ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.serial.comment != NULL)
{
r1 = pt_print_bytes (parser, p->info.serial.comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
break;
default:
assert (false);
break;
}
return q;
}
/*
* pt_print_alter_stored_procedure () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_alter_stored_procedure (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
PT_STORED_PROC_INFO *sp_info;
assert (p != NULL);
sp_info = &(p->info.sp);
r1 = pt_print_bytes_l (parser, sp_info->name);
q = pt_append_nulstring (parser, q, "alter");
if (sp_info->type == PT_SP_PROCEDURE)
{
q = pt_append_nulstring (parser, q, " procedure ");
}
else
{
q = pt_append_nulstring (parser, q, " function ");
}
q = pt_append_varchar (parser, q, r1);
if (sp_info->owner != NULL)
{
q = pt_append_nulstring (parser, q, " owner to ");
r1 = pt_print_bytes_l (parser, sp_info->owner);
q = pt_append_varchar (parser, q, r1);
}
if (sp_info->recompile == 1)
{
q = pt_append_nulstring (parser, q, " recompile ");
}
if (sp_info->comment != NULL)
{
r1 = pt_print_bytes (parser, sp_info->comment);
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/*
* pt_print_drop_serial () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_drop_serial (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
r1 = pt_print_bytes (parser, p->info.serial.serial_name);
q = pt_append_nulstring (parser, q, "drop serial ");
if (p->info.serial.if_exists)
{
q = pt_append_nulstring (parser, q, "if exists ");
}
q = pt_append_varchar (parser, q, r1);
return q;
}
/*
* pt_apply_create_serial () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_create_serial (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.serial.serial_name, arg);
PT_APPLY_WALK (parser, p->info.serial.start_val, arg);
PT_APPLY_WALK (parser, p->info.serial.increment_val, arg);
PT_APPLY_WALK (parser, p->info.serial.min_val, arg);
PT_APPLY_WALK (parser, p->info.serial.max_val, arg);
return p;
}
/*
* pt_apply_alter_serial () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_alter_serial (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.serial.serial_name, arg);
PT_APPLY_WALK (parser, p->info.serial.increment_val, arg);
PT_APPLY_WALK (parser, p->info.serial.min_val, arg);
PT_APPLY_WALK (parser, p->info.serial.max_val, arg);
PT_APPLY_WALK (parser, p->info.serial.owner_name, arg);
return p;
}
/*
* pt_apply_drop_serial () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_drop_serial (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.serial.serial_name, arg);
return p;
}
/* DATA_DEFAULT */
/*
* pt_apply_data_default () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_data_default (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.data_default.default_value, arg);
return p;
}
/*
* pt_init_data_default () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_data_default (PT_NODE * p)
{
p->info.data_default.default_value = (PT_NODE *) 0;
p->info.data_default.shared = (PT_MISC_TYPE) 0;
p->info.data_default.default_expr_type = DB_DEFAULT_NONE;
return p;
}
/*
* pt_print_data_default () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_data_default (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
if (p->info.data_default.shared == PT_SHARED)
{
q = pt_append_nulstring (parser, q, " shared ");
}
else if (p->info.data_default.shared == PT_DEFAULT)
{
q = pt_append_nulstring (parser, q, " default ");
}
r1 = pt_print_bytes (parser, p->info.data_default.default_value);
if (p->info.data_default.default_value && PT_IS_QUERY_NODE_TYPE (p->info.data_default.default_value->node_type))
{
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
else
{
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* DATA_TYPE */
/*
* pt_apply_datatype () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_datatype (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.data_type.entity, arg);
PT_APPLY_WALK (parser, p->info.data_type.table_column, arg);
PT_APPLY_WALK (parser, p->info.data_type.enumeration, arg);
return p;
}
/*
* pt_init_datatype () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_datatype (PT_NODE * p)
{
p->info.data_type.units = (int) LANG_COERCIBLE_CODESET;
p->info.data_type.collation_id = LANG_COERCIBLE_COLL;
p->info.data_type.collation_flag = TP_DOMAIN_COLL_NORMAL;
return p;
}
/*
* pt_print_datatype () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_datatype (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL;
PARSER_VARCHAR *r1 = NULL;
char buf[PT_MEMB_BUF_SIZE];
bool show_collation = false;
switch (p->type_enum)
{
case PT_TYPE_OBJECT:
r1 = pt_print_bytes (parser, p->info.data_type.entity);
if (p->info.data_type.entity)
{
q = pt_append_varchar (parser, q, r1);
}
else
{
q = pt_append_nulstring (parser, q, "object");
}
break;
case PT_TYPE_NUMERIC:
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
if (p->info.data_type.precision != DB_DEFAULT_NUMERIC_PRECISION
|| p->info.data_type.dec_precision != DB_DEFAULT_NUMERIC_SCALE)
{
sprintf (buf, "(%d,%d)", p->info.data_type.precision, p->info.data_type.dec_precision);
q = pt_append_nulstring (parser, q, buf);
}
break;
case PT_TYPE_CHAR:
case PT_TYPE_VARCHAR:
if (parser->flag.is_unloading_plcsql_def)
{
switch (p->type_enum)
{
case PT_TYPE_CHAR:
q = pt_append_nulstring (parser, q, "character");
break;
case PT_TYPE_VARCHAR:
q = pt_append_nulstring (parser, q, "character varying");
break;
default:
assert (false);
}
break;
}
show_collation = true;
[[fallthrough]];
case PT_TYPE_BIT:
case PT_TYPE_VARBIT:
case PT_TYPE_FLOAT:
{
bool show_precision;
int precision;
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
precision = p->info.data_type.precision;
switch (p->type_enum)
{
case PT_TYPE_CHAR:
case PT_TYPE_BIT:
/* fixed data type: always show parameter */
show_precision = true;
break;
default:
/* variable data type: only show non-maximum(i.e., default) parameter */
if (precision == TP_FLOATING_PRECISION_VALUE)
{
show_precision = false;
}
else if (p->type_enum == PT_TYPE_VARCHAR)
{
show_precision = (precision != DB_MAX_VARCHAR_PRECISION);
}
else if (p->type_enum == PT_TYPE_VARBIT)
{
show_precision = (precision != DB_MAX_VARBIT_PRECISION);
}
else
{
show_precision = (precision != 7);
}
break;
}
if (show_precision == true)
{
sprintf (buf, "(%d)", precision);
q = pt_append_nulstring (parser, q, buf);
}
}
break;
case PT_TYPE_DOUBLE:
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
break;
case PT_TYPE_ENUMERATION:
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
q = pt_append_nulstring (parser, q, "(");
r1 = pt_print_bytes_l (parser, p->info.data_type.enumeration);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
show_collation = true;
break;
case PT_TYPE_SET:
case PT_TYPE_MULTISET:
case PT_TYPE_SEQUENCE:
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
/* not to print data_type node for SET data types with empty domain */
if (p->data_type && p->data_type->info.data_type.precision != TP_FLOATING_PRECISION_VALUE)
{
r1 = pt_print_bytes_l (parser, p->data_type);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_TYPE_TABLE_COLUMN:
r1 = pt_print_bytes (parser, p->info.data_type.table_column);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, "%type");
break;
default:
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
if (p->data_type)
{
r1 = pt_print_bytes_l (parser, p->data_type);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
}
if (show_collation && p->info.data_type.collation_id != LANG_SYS_COLLATION)
{
sprintf (buf, " collate %s", lang_get_collation_name (p->info.data_type.collation_id));
q = pt_append_nulstring (parser, q, buf);
}
return q;
}
/* DELETE */
/*
* pt_apply_delete () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_delete (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.delete_.with, arg);
PT_APPLY_WALK (parser, p->info.delete_.target_classes, arg);
PT_APPLY_WALK (parser, p->info.delete_.spec, arg);
PT_APPLY_WALK (parser, p->info.delete_.search_cond, arg);
PT_APPLY_WALK (parser, p->info.delete_.using_index, arg);
PT_APPLY_WALK (parser, p->info.delete_.cursor_name, arg);
PT_APPLY_WALK (parser, p->info.delete_.internal_stmts, arg);
PT_APPLY_WALK (parser, p->info.delete_.waitsecs_hint, arg);
PT_APPLY_WALK (parser, p->info.delete_.leading_hint, arg);
PT_APPLY_WALK (parser, p->info.delete_.use_nl_hint, arg);
PT_APPLY_WALK (parser, p->info.delete_.use_idx_hint, arg);
PT_APPLY_WALK (parser, p->info.delete_.use_merge_hint, arg);
PT_APPLY_WALK (parser, p->info.delete_.no_use_hash_hint, arg);
PT_APPLY_WALK (parser, p->info.delete_.use_hash_hint, arg);
PT_APPLY_WALK (parser, p->info.delete_.limit, arg);
return p;
}
/*
* pt_init_delete () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_delete (PT_NODE * p)
{
p->info.delete_.hint = PT_HINT_NONE;
return p;
}
/*
* pt_print_delete () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_delete (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1, *r2;
r1 = pt_print_bytes_l (parser, p->info.delete_.target_classes);
r2 = pt_print_bytes_spec_list (parser, p->info.delete_.spec);
if (p->info.delete_.with != NULL)
{
r1 = pt_print_bytes_l (parser, p->info.delete_.with);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, "delete");
if (p->info.delete_.hint != PT_HINT_NONE)
{
q = pt_append_nulstring (parser, q, " /*+");
if (p->info.delete_.hint & PT_HINT_LK_TIMEOUT && p->info.delete_.waitsecs_hint)
{
q = pt_append_nulstring (parser, q, " LOCK_TIMEOUT(");
r1 = pt_print_bytes (parser, p->info.delete_.waitsecs_hint);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
if (p->info.delete_.hint & PT_HINT_NO_LOGGING)
{
q = pt_append_nulstring (parser, q, " NO_LOGGING");
}
if (p->info.delete_.hint & PT_HINT_ORDERED)
{
/* force join left-to-right */
q = pt_append_nulstring (parser, q, " ORDERED ");
}
if (p->info.delete_.hint & PT_HINT_LEADING)
{
/* force join left-to-right */
q = pt_append_nulstring (parser, q, " LEADING");
if (p->info.delete_.leading_hint)
{
r1 = pt_print_bytes_l (parser, p->info.delete_.leading_hint);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.delete_.hint & PT_HINT_USE_NL)
{
/* force nl-join */
q = pt_append_nulstring (parser, q, " USE_NL");
if (p->info.delete_.use_nl_hint)
{
r1 = pt_print_bytes_l (parser, p->info.delete_.use_nl_hint);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.delete_.hint & PT_HINT_USE_IDX)
{
/* force idx-join */
q = pt_append_nulstring (parser, q, " USE_IDX");
if (p->info.delete_.use_idx_hint)
{
r1 = pt_print_bytes_l (parser, p->info.delete_.use_idx_hint);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.delete_.hint & PT_HINT_USE_MERGE)
{
/* force merge-join */
q = pt_append_nulstring (parser, q, " USE_MERGE");
if (p->info.delete_.use_merge_hint)
{
r1 = pt_print_bytes_l (parser, p->info.delete_.use_merge_hint);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.delete_.hint & PT_HINT_NO_USE_HASH)
{
/* disable hash-join */
q = pt_append_nulstring (parser, q, " NO_USE_HASH");
if (p->info.delete_.no_use_hash_hint)
{
r1 = pt_print_bytes_l (parser, p->info.delete_.no_use_hash_hint);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.delete_.hint & PT_HINT_USE_HASH)
{
/* force hash-join */
q = pt_append_nulstring (parser, q, " USE_HASH");
if (p->info.delete_.use_hash_hint)
{
r1 = pt_print_bytes_l (parser, p->info.delete_.use_hash_hint);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.delete_.hint & PT_HINT_USE_IDX_DESC)
{
q = pt_append_nulstring (parser, q, " USE_DESC_IDX ");
}
if (p->info.delete_.hint & PT_HINT_NO_COVERING_IDX)
{
q = pt_append_nulstring (parser, q, " NO_COVERING_IDX ");
}
if (p->info.delete_.hint & PT_HINT_NO_IDX_DESC)
{
q = pt_append_nulstring (parser, q, " NO_DESC_IDX ");
}
if (p->info.delete_.hint & PT_HINT_NO_MULTI_RANGE_OPT)
{
q = pt_append_nulstring (parser, q, " NO_MULTI_RANGE_OPT ");
}
if (p->info.delete_.hint & PT_HINT_NO_SORT_LIMIT)
{
q = pt_append_nulstring (parser, q, " NO_SORT_LIMIT ");
}
if (p->info.delete_.hint & PT_HINT_USE_SBR)
{
q = pt_append_nulstring (parser, q, " USE_SBR ");
}
if (p->info.delete_.hint & PT_HINT_NO_SUPPLEMENTAL_LOG)
{
q = pt_append_nulstring (parser, q, " NO_SUPPLEMENTAL_LOG ");
}
if (p->info.delete_.hint & PT_HINT_NO_PARALLEL_HASH_JOIN)
{
q = pt_append_nulstring (parser, q, "NO_PARALLEL_HASH_JOIN ");
}
q = pt_append_nulstring (parser, q, " */");
}
if (r1)
{
/* DELETE without target FROM ... for dblink's other DBMS */
if (parser->custom_print & PT_PRINT_SUPPRESS_FOR_DBLINK)
{
if (p->info.delete_.spec->next)
{
q = pt_append_nulstring (parser, q, " ");
q = pt_append_varchar (parser, q, r1);
}
}
else
{
q = pt_append_nulstring (parser, q, " ");
q = pt_append_varchar (parser, q, r1);
}
}
q = pt_append_nulstring (parser, q, " from ");
q = pt_append_varchar (parser, q, r2);
if (p->info.delete_.search_cond)
{
r1 = pt_print_and_list (parser, p->info.delete_.search_cond);
q = pt_append_nulstring (parser, q, " where ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.delete_.using_index)
{
if (p->info.delete_.using_index->info.name.original == NULL)
{
if (p->info.delete_.using_index->info.name.resolved == NULL)
{
q = pt_append_nulstring (parser, q, " using index none");
}
else
{
if (p->info.delete_.using_index->etc == (void *) PT_IDX_HINT_CLASS_NONE)
{
r1 = pt_print_bytes_l (parser, p->info.delete_.using_index);
q = pt_append_nulstring (parser, q, " using index ");
q = pt_append_varchar (parser, q, r1);
}
else
{
r1 = pt_print_bytes_l (parser, p->info.delete_.using_index->next);
q = pt_append_nulstring (parser, q, " using index all except ");
q = pt_append_varchar (parser, q, r1);
}
}
}
else
{
r1 = pt_print_bytes_l (parser, p->info.delete_.using_index);
q = pt_append_nulstring (parser, q, " using index ");
q = pt_append_varchar (parser, q, r1);
}
}
if (p->info.delete_.limit && p->info.delete_.rewrite_limit)
{
r1 = pt_print_bytes_l (parser, p->info.delete_.limit);
q = pt_append_nulstring (parser, q, " limit ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* DIFFERENCE */
/*
* pt_apply_difference () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_difference (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.query.with, arg);
PT_APPLY_WALK (parser, p->info.query.q.union_.arg1, arg);
PT_APPLY_WALK (parser, p->info.query.q.union_.arg2, arg);
PT_APPLY_WALK (parser, p->info.query.into_list, arg);
PT_APPLY_WALK (parser, p->info.query.order_by, arg);
PT_APPLY_WALK (parser, p->info.query.orderby_for, arg);
return p;
}
/*
* pt_init_difference () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_difference (PT_NODE * p)
{
p->info.query.all_distinct = PT_ALL;
p->info.query.hint = PT_HINT_NONE;
p->info.query.scan_op_type = S_SELECT;
return p;
}
/*
* pt_print_difference () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_difference (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
if (p->info.query.with != NULL)
{
r1 = pt_print_bytes_l (parser, p->info.query.with);
q = pt_append_varchar (parser, q, r1);
}
r1 = pt_print_bytes (parser, p->info.query.q.union_.arg1);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " except ");
if (p->info.query.all_distinct == PT_ALL)
{
q = pt_append_nulstring (parser, q, "all ");
}
r1 = pt_print_bytes (parser, p->info.query.q.union_.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
if (p->info.query.order_by)
{
r1 = pt_print_bytes_l (parser, p->info.query.order_by);
q = pt_append_nulstring (parser, q, " order by ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.orderby_for)
{
r1 = pt_print_bytes_l (parser, p->info.query.orderby_for);
q = pt_append_nulstring (parser, q, " for ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.limit && p->info.query.flag.rewrite_limit)
{
r1 = pt_print_bytes_l (parser, p->info.query.limit);
q = pt_append_nulstring (parser, q, " limit ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* DOT */
/*
* pt_apply_dot () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_dot (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.dot.arg1, arg);
PT_APPLY_WALK (parser, p->info.dot.arg2, arg);
PT_APPLY_WALK (parser, p->info.dot.selector, arg);
return p;
}
/*
* pt_print_dot () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_dot (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1, *r2;
r1 = pt_print_bytes (parser, p->info.dot.arg1);
r2 = pt_print_bytes (parser, p->info.dot.arg2);
b = pt_append_varchar (parser, b, r1);
if (r2)
{
b = pt_append_nulstring (parser, b, ".");
b = pt_append_varchar (parser, b, r2);
}
if ((parser->custom_print & PT_PRINT_ALIAS) && p->alias_print != NULL)
{
b = pt_append_nulstring (parser, b, " as [");
b = pt_append_nulstring (parser, b, p->alias_print);
b = pt_append_nulstring (parser, b, "]");
}
return b;
}
/* DROP_ENTITY (not ALTER or VIEW ) */
/*
* pt_apply_drop () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_drop (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.drop.spec_list, arg);
PT_APPLY_WALK (parser, p->info.drop.internal_stmts, arg);
return p;
}
/*
* pt_print_drop () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_drop (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
unsigned int save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes_l (parser, p->info.drop.spec_list);
parser->custom_print = save_custom;
q = pt_append_nulstring (parser, q, "drop ");
if (p->info.drop.if_exists)
{
q = pt_append_nulstring (parser, q, "if exists ");
}
q = pt_append_varchar (parser, q, r1);
if (p->info.drop.is_cascade_constraints)
{
q = pt_append_nulstring (parser, q, " cascade constraints");
}
return q;
}
/* DROP_INDEX */
/*
* pt_apply_drop_index () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_drop_index (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.index.indexed_class, arg);
PT_APPLY_WALK (parser, p->info.index.column_names, arg);
PT_APPLY_WALK (parser, p->info.index.where, arg);
PT_APPLY_WALK (parser, p->info.index.function_expr, arg);
return p;
}
/*
* pt_print_drop_index () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_drop_index (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1, *r2, *r3;
const char *index_name = NULL;
unsigned int saved_cp = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes (parser, p->info.index.indexed_class);
r2 = pt_print_index_columns (parser, p);
parser->custom_print = saved_cp;
b = pt_append_nulstring (parser, b, "drop");
if (p->info.index.reverse)
{
b = pt_append_nulstring (parser, b, " reverse");
}
if (p->info.index.unique)
{
b = pt_append_nulstring (parser, b, " unique");
}
b = pt_append_nulstring (parser, b, " index ");
if (p->info.index.index_name)
{
index_name = p->info.index.index_name->info.name.original;
b = pt_append_bytes (parser, b, index_name, strlen (index_name));
}
assert (r1 != NULL);
b = pt_append_nulstring (parser, b, (index_name ? " on " : "on "));
b = pt_append_varchar (parser, b, r1);
if (r2)
{
b = pt_append_nulstring (parser, b, " (");
b = pt_append_varchar (parser, b, r2);
b = pt_append_nulstring (parser, b, ") ");
}
if (p->info.index.where)
{
r3 = pt_print_and_list (parser, p->info.index.where);
b = pt_append_nulstring (parser, b, " where ");
b = pt_append_varchar (parser, b, r3);
}
return b;
}
/* DROP_USER */
/*
* pt_apply_drop_user () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_drop_user (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.drop_user.user_name, arg);
return p;
}
/*
* pt_print_drop_user () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_drop_user (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1;
r1 = pt_print_bytes (parser, p->info.drop_user.user_name);
b = pt_append_nulstring (parser, b, "drop user ");
b = pt_append_varchar (parser, b, r1);
return b;
}
/* DROP_TRIGGER */
/*
* pt_apply_drop_trigger () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_drop_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.drop_trigger.trigger_spec_list, arg);
return p;
}
/*
* pt_print_drop_trigger () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_drop_trigger (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
r1 = pt_print_bytes_l (parser, p->info.drop_trigger.trigger_spec_list);
b = pt_append_nulstring (parser, b, "drop trigger ");
b = pt_append_varchar (parser, b, r1);
return b;
}
/* DROP_VARIABLE */
/*
* pt_apply_drop_variable () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_drop_variable (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.drop_variable.var_names, arg);
return p;
}
/*
* pt_print_drop_variable () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_drop_variable (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1;
r1 = pt_print_bytes_l (parser, p->info.drop_variable.var_names);
b = pt_append_nulstring (parser, b, "drop variable ");
b = pt_append_varchar (parser, b, r1);
return b;
}
/* SPEC */
/*
* pt_apply_spec () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_spec (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.spec.entity_name, arg);
PT_APPLY_WALK (parser, p->info.spec.remote_server_name, arg);
PT_APPLY_WALK (parser, p->info.spec.cte_name, arg);
PT_APPLY_WALK (parser, p->info.spec.cte_pointer, arg);
PT_APPLY_WALK (parser, p->info.spec.except_list, arg);
PT_APPLY_WALK (parser, p->info.spec.derived_table, arg);
PT_APPLY_WALK (parser, p->info.spec.range_var, arg);
PT_APPLY_WALK (parser, p->info.spec.as_attr_list, arg);
PT_APPLY_WALK (parser, p->info.spec.referenced_attrs, arg);
PT_APPLY_WALK (parser, p->info.spec.path_entities, arg);
PT_APPLY_WALK (parser, p->info.spec.path_conjuncts, arg);
PT_APPLY_WALK (parser, p->info.spec.flat_entity_list, arg);
PT_APPLY_WALK (parser, p->info.spec.method_list, arg);
PT_APPLY_WALK (parser, p->info.spec.on_cond, arg);
PT_APPLY_WALK (parser, p->info.spec.partition, arg);
/* PT_APPLY_WALK (parser, p->info.spec.using_cond, arg); -- does not support named columns join */
return p;
}
/*
* pt_init_spec () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_spec (PT_NODE * p)
{
p->info.spec.only_all = PT_ONLY;
p->info.spec.location = -1;
p->info.spec.join_type = PT_JOIN_NONE;
p->info.spec.auth_bypass_mask = DB_AUTH_NONE;
return p;
}
/*
* pt_print_spec () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_spec (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
unsigned int save_custom;
if (p->info.spec.natural)
{
q = pt_append_nulstring (parser, q, " natural ");
}
switch (p->info.spec.join_type)
{
case PT_JOIN_NONE:
break;
case PT_JOIN_CROSS:
q = pt_append_nulstring (parser, q, " cross join ");
break;
/* case PT_JOIN_NATURAL: -- does not support */
case PT_JOIN_INNER:
q = pt_append_nulstring (parser, q, " inner join ");
break;
case PT_JOIN_LEFT_OUTER:
q = pt_append_nulstring (parser, q, " left outer join ");
break;
case PT_JOIN_RIGHT_OUTER:
q = pt_append_nulstring (parser, q, " right outer join ");
break;
case PT_JOIN_FULL_OUTER: /* not used */
q = pt_append_nulstring (parser, q, " full outer join ");
break;
/* case PT_JOIN_UNION: -- does not support */
default:
break;
}
/* check if a partition pruned SPEC */
if (PT_SPEC_IS_ENTITY (p) && p->flag.partition_pruned)
{
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
q = pt_append_nulstring (parser, q, "(");
r1 = pt_print_bytes_l (parser, p->info.spec.flat_entity_list);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
parser->custom_print = save_custom;
}
/* check if a sublist */
else if (PT_SPEC_IS_ENTITY (p) && p->info.spec.entity_name->next)
{
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
q = pt_append_nulstring (parser, q, "(");
r1 = pt_print_bytes_l (parser, p->info.spec.entity_name);
q = pt_append_varchar (parser, q, r1);
if (p->info.spec.remote_server_name && !(parser->custom_print & PT_PRINT_SUPPRESS_SERVER_NAME))
{
q = pt_append_nulstring (parser, q, "@");
if (p->info.spec.remote_server_name->next)
{
q = pt_append_varchar (parser, q, pt_print_bytes (parser, p->info.spec.remote_server_name->next));
q = pt_append_nulstring (parser, q, ".");
}
q = pt_append_varchar (parser, q, pt_print_bytes (parser, p->info.spec.remote_server_name));
}
q = pt_append_nulstring (parser, q, ")");
parser->custom_print = save_custom;
}
/* else is a single class entity spec */
else if (PT_SPEC_IS_ENTITY (p))
{
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_META_ATTR_CLASS;
if (p->info.spec.meta_class == PT_META_CLASS)
{
q = pt_append_nulstring (parser, q, " class ");
}
else if (p->info.spec.only_all == PT_ALL)
{
q = pt_append_nulstring (parser, q, " all ");
}
r1 = pt_print_bytes (parser, p->info.spec.entity_name);
q = pt_append_varchar (parser, q, r1);
if (p->info.spec.remote_server_name && !(parser->custom_print & PT_PRINT_SUPPRESS_SERVER_NAME))
{
q = pt_append_nulstring (parser, q, "@");
if (p->info.spec.remote_server_name->next)
{
q = pt_append_varchar (parser, q, pt_print_bytes (parser, p->info.spec.remote_server_name->next));
q = pt_append_nulstring (parser, q, ".");
}
r1 = pt_print_bytes (parser, p->info.spec.remote_server_name);
q = pt_append_varchar (parser, q, r1);
}
if (p->info.spec.partition)
{
q = pt_append_nulstring (parser, q, " PARTITION (");
r1 = pt_print_bytes (parser, p->info.spec.partition);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
parser->custom_print = save_custom;
if (p->info.spec.except_list)
{
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
q = pt_append_nulstring (parser, q, " (except ");
r1 = pt_print_bytes_l (parser, p->info.spec.except_list);
q = pt_append_varchar (parser, q, r1);
parser->custom_print = save_custom;
q = pt_append_nulstring (parser, q, ")");
}
}
else if (PT_SPEC_IS_DERIVED (p))
{ /* should be a derived table */
if (p->info.spec.derived_table_type == PT_IS_SET_EXPR)
{
q = pt_append_nulstring (parser, q, "table");
}
r1 = pt_print_bytes_l (parser, p->info.spec.derived_table);
if (r1 != NULL)
{
if (p->info.spec.derived_table_type == PT_IS_SUBQUERY && r1->bytes[0] == '('
&& r1->bytes[r1->length - 1] == ')')
{
/* skip unnecessary nested parenthesis of derived-query */
q = pt_append_varchar (parser, q, r1);
}
else if (p->info.spec.derived_table_type == PT_DERIVED_JSON_TABLE)
{
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
unsigned int alias_print_flag = (parser->custom_print & PT_PRINT_ALIAS);
q = pt_append_nulstring (parser, q, " as ");
parser->custom_print &= ~PT_PRINT_ALIAS;
r1 = pt_print_bytes (parser, p->info.spec.range_var);
q = pt_append_varchar (parser, q, r1);
parser->custom_print |= alias_print_flag;
q = pt_append_nulstring (parser, q, ")");
}
else if (p->info.spec.derived_table_type == PT_DERIVED_DBLINK_TABLE)
{
q = pt_append_varchar (parser, q, r1);
unsigned int alias_print_flag = (parser->custom_print & PT_PRINT_ALIAS);
q = pt_append_nulstring (parser, q, " as ");
parser->custom_print &= ~PT_PRINT_ALIAS;
r1 = pt_print_bytes (parser, p->info.spec.range_var);
q = pt_append_varchar (parser, q, r1);
parser->custom_print |= alias_print_flag;
q = pt_append_nulstring (parser, q, "(");
if (parser->custom_print & PT_SUPPRESS_RESOLVED)
{
r1 = pt_print_bytes_l (parser, p->info.spec.derived_table->info.dblink_table.cols);
}
else
{
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes_l (parser, p->info.spec.derived_table->info.dblink_table.cols);
parser->custom_print &= ~PT_SUPPRESS_RESOLVED;
}
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
return q;
}
else
{
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
}
}
if (!(parser->custom_print & PT_SUPPRESS_RESOLVED) && (p->info.spec.derived_table_type != PT_DERIVED_JSON_TABLE))
{
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_META_ATTR_CLASS;
parser->custom_print &= ~PT_PRINT_ALIAS;
if (p->info.spec.range_var && p->info.spec.range_var->info.name.original
&& p->info.spec.range_var->info.name.original[0])
{
bool insert_with_use_sbr = false;
if (parser->custom_print & PT_PRINT_ORIGINAL_BEFORE_CONST_FOLDING)
{
PT_NODE *cur_stmt = NULL;
for (int i = 0; i < parser->statement_number; i++)
{
if (parser->statements[i] != NULL)
{
cur_stmt = parser->statements[i];
break;
}
}
if (cur_stmt->info.insert.hint & PT_HINT_USE_SBR)
{
insert_with_use_sbr = true;
}
}
if (!insert_with_use_sbr)
{
if (PT_SPEC_CTE_POINTER (p) != NULL)
{
r1 = pt_print_bytes (parser, p->info.spec.cte_name);
q = pt_append_varchar (parser, q, r1);
}
r1 = pt_print_bytes (parser, p->info.spec.range_var);
q = pt_append_nulstring (parser, q, " ");
q = pt_append_varchar (parser, q, r1);
}
}
parser->custom_print = save_custom;
}
if (p->info.spec.as_attr_list && !PT_SPEC_IS_CTE (p) && (p->info.spec.derived_table_type != PT_DERIVED_JSON_TABLE))
{
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r1 = pt_print_bytes_l (parser, p->info.spec.as_attr_list);
q = pt_append_nulstring (parser, q, " (");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
parser->custom_print = save_custom;
}
if (p->info.spec.on_cond)
{
r1 = pt_print_and_list (parser, p->info.spec.on_cond);
q = pt_append_nulstring (parser, q, " on ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.spec.using_cond)
{
r1 = pt_print_and_list (parser, p->info.spec.using_cond);
q = pt_append_nulstring (parser, q, " using ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
#if defined (ENABLE_UNUSED_FUNCTION)
/*
* pt_print_class_name () - prints a class name from an entity_spec for
* error messages. prints only the first entity_spec and omits its range var
* return:
* parser(in):
* p(in):
*/
PARSER_VARCHAR *
pt_print_class_name (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
/* check if a sublist */
if (p->info.spec.entity_name && p->info.spec.entity_name->next)
{
r1 = pt_print_bytes (parser, p->info.spec.entity_name);
q = pt_append_varchar (parser, q, r1);
}
/* else is a single class entity spec */
else if (p->info.spec.entity_name)
{
if (p->info.spec.meta_class == PT_META_CLASS)
{
q = pt_append_nulstring (parser, q, " class ");
}
r1 = pt_print_bytes (parser, p->info.spec.entity_name);
q = pt_append_varchar (parser, q, r1);
}
return q;
}
#endif
/* EVALUATE */
/*
* pt_apply_evaluate () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_evaluate (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.evaluate.expression, arg);
PT_APPLY_WALK (parser, p->info.evaluate.into_var, arg);
return p;
}
/*
* pt_print_evaluate () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_evaluate (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
r1 = pt_print_bytes (parser, p->info.evaluate.expression);
b = pt_append_nulstring (parser, b, "evaluate ");
b = pt_append_varchar (parser, b, r1);
if (p->info.evaluate.into_var)
{
r1 = pt_print_bytes (parser, p->info.evaluate.into_var);
b = pt_append_nulstring (parser, b, " into ");
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/* EVENT_OBJECT */
/*
* pt_apply_event_object () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_event_object (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.event_object.event_object, arg);
PT_APPLY_WALK (parser, p->info.event_object.correlation_name, arg);
return p;
}
/*
* pt_print_event_object () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_event_object (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL;
return b;
}
/* EVENT_SPEC */
/*
* pt_apply_event_spec () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_event_spec (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.event_spec.event_target, arg);
return p;
}
/*
* pt_print_event_spec () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_event_spec (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
b = pt_append_nulstring (parser, b, pt_show_event_type (p->info.event_spec.event_type));
if (p->info.event_spec.event_target)
{
r1 = pt_print_bytes (parser, p->info.event_spec.event_target);
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/* EVENT_TARGET */
/*
* pt_apply_event_target () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_event_target (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.event_target.class_name, arg);
PT_APPLY_WALK (parser, p->info.event_target.attribute, arg);
return p;
}
/*
* pt_print_event_target () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_event_target (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
r1 = pt_print_bytes (parser, p->info.event_target.class_name);
b = pt_append_nulstring (parser, b, " on ");
b = pt_append_varchar (parser, b, r1);
if (p->info.event_target.attribute)
{
r1 = pt_print_bytes (parser, p->info.event_target.attribute);
b = pt_append_nulstring (parser, b, "(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ")");
}
return b;
}
/* EXECUTE_TRIGGER */
/*
* pt_apply_execute_trigger () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_execute_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.execute_trigger.trigger_spec_list, arg);
return p;
}
/*
* pt_print_execute_trigger () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_execute_trigger (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
r1 = pt_print_bytes_l (parser, p->info.execute_trigger.trigger_spec_list);
b = pt_append_nulstring (parser, b, "execute deferred trigger ");
b = pt_append_varchar (parser, b, r1);
return b;
}
/* EXPR */
/*
* pt_apply_expr () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_expr (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.expr.arg1, arg);
PT_APPLY_WALK (parser, p->info.expr.arg2, arg);
PT_APPLY_WALK (parser, p->info.expr.value, arg);
PT_APPLY_WALK (parser, p->info.expr.arg3, arg);
/* walk cast type in case it might contain a name */
PT_APPLY_WALK (parser, p->info.expr.cast_type, arg);
return p;
}
/*
* pt_init_expr () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_expr (PT_NODE * p)
{
p->info.expr.recursive_type = PT_TYPE_NONE;
return p;
}
static void
pt_print_range_op (PARSER_CONTEXT * parser, PT_STRING_BLOCK * sb, PT_NODE * t, PARSER_VARCHAR * lhs)
{
const char *op1 = NULL, *op2 = NULL;
PARSER_VARCHAR *rhs1 = NULL, *rhs2 = NULL;
switch (t->info.expr.op)
{
case PT_BETWEEN_GE_LE:
op1 = pt_show_binopcode (PT_GE);
op2 = pt_show_binopcode (PT_LE);
break;
case PT_BETWEEN_GE_LT:
op1 = pt_show_binopcode (PT_GE);
op2 = pt_show_binopcode (PT_LT);
break;
case PT_BETWEEN_GT_LE:
op1 = pt_show_binopcode (PT_GT);
op2 = pt_show_binopcode (PT_LE);
break;
case PT_BETWEEN_GT_LT:
op1 = pt_show_binopcode (PT_GT);
op2 = pt_show_binopcode (PT_LT);
break;
case PT_BETWEEN_EQ_NA:
op1 = pt_show_binopcode (PT_EQ);
break;
case PT_BETWEEN_INF_LE:
op1 = pt_show_binopcode (PT_LE);
break;
case PT_BETWEEN_INF_LT:
op1 = pt_show_binopcode (PT_LT);
break;
case PT_BETWEEN_GT_INF:
op1 = pt_show_binopcode (PT_GT);
break;
case PT_BETWEEN_GE_INF:
op1 = pt_show_binopcode (PT_GE);
break;
default:
assert (false);
return;
}
rhs1 = pt_print_bytes (parser, t->info.expr.arg1);
if (op2)
{
rhs2 = pt_print_bytes (parser, t->info.expr.arg2);
}
if (lhs && rhs1)
{
strcat_with_realloc (sb, (const char *) lhs->bytes);
strcat_with_realloc (sb, (char *) op1);
strcat_with_realloc (sb, (const char *) rhs1->bytes);
if (rhs2)
{
strcat_with_realloc (sb, " and ");
strcat_with_realloc (sb, (const char *) lhs->bytes);
strcat_with_realloc (sb, (char *) op2);
strcat_with_realloc (sb, (const char *) rhs2->bytes);
}
}
}
/*
* pt_print_expr () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_expr (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1, *r2, *r3, *r4;
PT_NODE *t, *or_next;
int print_from = 0;
PT_NODE *arg3;
PT_NODE *between, *between_ge_lt;
PT_NODE *dot_node_ptr = NULL;
assert_release (p != p->info.expr.arg1);
assert_release (p != p->info.expr.arg2);
assert_release (p != p->info.expr.arg3);
if (p->info.expr.paren_type == 1)
{
q = pt_append_nulstring (parser, q, "(");
}
switch (p->info.expr.op)
{
case PT_FUNCTION_HOLDER:
/* FUNCTION_HOLDER has a PT_FUNCTION on arg1 */
q = pt_print_function (parser, p->info.expr.arg1);
break;
case PT_UNARY_MINUS:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, "-");
q = pt_append_varchar (parser, q, r1);
break;
case PT_BIT_NOT:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, "~");
q = pt_append_varchar (parser, q, r1);
break;
case PT_BIT_COUNT:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " bit_count(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_PRIOR:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " prior ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_CONNECT_BY_ROOT:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " connect_by_root ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_QPRIOR:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " prior ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_NOT:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " not ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_EXISTS:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " exists ");
q = pt_append_varchar (parser, q, r1);
break;
case PT_MODULUS:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " mod(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_RAND:
q = pt_append_nulstring (parser, q, " rand(");
if (p->info.expr.arg1 != NULL)
{
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DRAND:
q = pt_append_nulstring (parser, q, " drand(");
if (p->info.expr.arg1 != NULL)
{
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_RANDOM:
q = pt_append_nulstring (parser, q, " random(");
if (p->info.expr.arg1 != NULL)
{
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DRANDOM:
q = pt_append_nulstring (parser, q, " drandom(");
if (p->info.expr.arg1 != NULL)
{
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_FLOOR:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " floor(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CEIL:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " ceil(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SIGN:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " sign(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ABS:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " abs(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_POWER:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " power(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ROUND:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " round(");
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_LOG:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " log(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_EXP:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " exp(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SQRT:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " sqrt(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TRUNC:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " trunc(");
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CHR:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " chr(");
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 != NULL && p->info.expr.arg2->node_type == PT_VALUE)
{
q = pt_append_nulstring (parser, q, " using ");
q = pt_append_nulstring (parser, q, lang_get_codeset_name (p->info.expr.arg2->info.value.data_value.i));
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_INSTR:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " instr(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
if (p->info.expr.arg3 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
r3 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r3);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_POSITION:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " position(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " in ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_FINDINSET:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " find_in_set(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SUBSTRING:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
if (p->info.expr.qualifier == PT_SUBSTR_ORG)
{
q = pt_append_nulstring (parser, q, " substring(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " from ");
q = pt_append_varchar (parser, q, r2);
if (p->info.expr.arg3)
{
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_nulstring (parser, q, " for ");
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
}
else if (p->info.expr.qualifier == PT_SUBSTR)
{
q = pt_append_nulstring (parser, q, " substr(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
if (p->info.expr.arg3)
{
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_SUBSTRING_INDEX:
q = pt_append_nulstring (parser, q, "substring_index(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ", ");
r3 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r3);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_OCTET_LENGTH:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " octet_length(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_BIT_LENGTH:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " bit_length(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CHAR_LENGTH:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " char_length(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_LOWER:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " lower(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_UPPER:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " upper(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_HEX:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " hex(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ASCII:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " ascii(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CONV:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
r3 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_nulstring (parser, q, " conv(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r3);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_BIN:
q = pt_append_nulstring (parser, q, " bin(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_MD5:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " md5(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_AES_ENCRYPT:
q = pt_append_nulstring (parser, q, " aes_encrypt(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_AES_DECRYPT:
q = pt_append_nulstring (parser, q, " aes_decrypt(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SHA_ONE:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " sha1(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SHA_TWO:
q = pt_append_nulstring (parser, q, " sha2(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TO_BASE64:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " to_base64(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_FROM_BASE64:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " from_base64(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_EXTRACT:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " extract(");
switch (p->info.expr.qualifier)
{
case PT_YEAR:
q = pt_append_nulstring (parser, q, "year ");
break;
case PT_MONTH:
q = pt_append_nulstring (parser, q, "month ");
break;
case PT_DAY:
q = pt_append_nulstring (parser, q, "day ");
break;
case PT_HOUR:
q = pt_append_nulstring (parser, q, "hour ");
break;
case PT_MINUTE:
q = pt_append_nulstring (parser, q, "minute ");
break;
case PT_SECOND:
q = pt_append_nulstring (parser, q, "second ");
break;
case PT_MILLISECOND:
q = pt_append_nulstring (parser, q, "millisecond ");
break;
default:
break;
}
q = pt_append_nulstring (parser, q, " from ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CURRENT_VALUE:
if (parser->custom_print & PT_PRINT_SUPPRESS_SERIAL_CONV)
{
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ".currval");
}
else
{
q = pt_append_nulstring (parser, q, "serial_current_value(");
/* Only the column name is printed. */
if (p->info.expr.arg1->node_type == PT_DOT_)
{
dot_node_ptr = p->info.expr.arg1->info.expr.arg2;
while (dot_node_ptr && dot_node_ptr->node_type == PT_DOT_)
{
dot_node_ptr = dot_node_ptr->info.expr.arg2;
}
r1 = pt_print_bytes (parser, p->info.expr.arg1->info.expr.arg2);
}
else
{
r1 = pt_print_bytes (parser, p->info.expr.arg1);
}
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_NEXT_VALUE:
if (parser->custom_print & PT_PRINT_SUPPRESS_SERIAL_CONV)
{
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ".nextval");
}
else
{
q = pt_append_nulstring (parser, q, "serial_next_value(");
/* Only the column name is printed. */
if (p->info.expr.arg1->node_type == PT_DOT_)
{
dot_node_ptr = p->info.expr.arg1->info.expr.arg2;
while (dot_node_ptr && dot_node_ptr->node_type == PT_DOT_)
{
dot_node_ptr = dot_node_ptr->info.expr.arg2;
}
r1 = pt_print_bytes (parser, p->info.expr.arg1->info.expr.arg2);
}
else
{
r1 = pt_print_bytes (parser, p->info.expr.arg1);
}
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_TO_NUMBER:
q = pt_append_nulstring (parser, q, " to_number(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TO_DATE:
case PT_TO_TIME:
case PT_TO_TIMESTAMP:
case PT_TO_DATETIME:
case PT_TO_CHAR:
case PT_TO_DATETIME_TZ:
case PT_TO_TIMESTAMP_TZ:
{
int flags;
bool has_user_format = false;
bool has_user_lang = false;
INTL_LANG lang_id;
if (p->info.expr.op == PT_TO_DATE)
{
q = pt_append_nulstring (parser, q, " to_date(");
}
else if (p->info.expr.op == PT_TO_TIME)
{
q = pt_append_nulstring (parser, q, " to_time(");
}
else if (p->info.expr.op == PT_TO_TIMESTAMP)
{
q = pt_append_nulstring (parser, q, " to_timestamp(");
}
else if (p->info.expr.op == PT_TO_DATETIME)
{
q = pt_append_nulstring (parser, q, " to_datetime(");
}
else if (p->info.expr.op == PT_TO_CHAR)
{
q = pt_append_nulstring (parser, q, " to_char(");
}
else if (p->info.expr.op == PT_TO_DATETIME_TZ)
{
q = pt_append_nulstring (parser, q, " to_datetime_tz(");
}
else if (p->info.expr.op == PT_TO_TIMESTAMP_TZ)
{
q = pt_append_nulstring (parser, q, " to_timestamp_tz(");
}
else
{
assert (false);
}
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
assert (p->info.expr.arg3);
if (p->info.expr.arg3->node_type == PT_HOST_VAR)
{
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r1);
}
else if (p->info.expr.arg3->node_type == PT_VALUE)
{
flags = p->info.expr.arg3->info.value.data_value.i;
lang_id = lang_get_lang_id_from_flag (flags, &has_user_format, &has_user_lang);
if (has_user_format)
{
const char *lang_name = lang_get_lang_name_from_id (lang_id);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
if (lang_name != NULL && has_user_lang)
{
q = pt_append_nulstring (parser, q, ", '");
q = pt_append_nulstring (parser, q, lang_name);
q = pt_append_nulstring (parser, q, "'");
}
}
}
else if (parser->flag.is_parsing_static_sql)
{
assert (p->info.expr.arg3->node_type == PT_EXPR && p->info.expr.arg3->info.expr.op == PT_CAST);
assert (p->info.expr.arg3->info.expr.cast_type->node_type == PT_DATA_TYPE);
assert (PT_IS_SIMPLE_CHAR_STRING_TYPE (p->info.expr.arg3->info.expr.cast_type->type_enum));
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r1);
}
else
{
/*
create table foo(a char(20), b varchar, c nchar(20), d nchar varying, e sequence(int));
insert into foo values('aaa', 'bbb', n'ccc', n'ddd', {1, 2, 3, 4, 5});
select to_char(e) from foo order by 1;
--In a case like "select to_char(e) from foo", it enters the second step.
*/
assert ((pt_has_error (parser) || er_errid () != NO_ERROR)
|| (p->info.expr.arg2 &&
p->info.expr.arg2->node_type == PT_VALUE && p->info.expr.arg2->type_enum == PT_TYPE_NULL));
}
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_SYS_DATE:
q = pt_append_nulstring (parser, q, " SYS_DATE ");
break;
case PT_CURRENT_DATE:
q = pt_append_nulstring (parser, q, " CURRENT_DATE ");
break;
case PT_SYS_TIME:
q = pt_append_nulstring (parser, q, " SYS_TIME ");
break;
case PT_CURRENT_TIME:
q = pt_append_nulstring (parser, q, " CURRENT_TIME ");
break;
case PT_SYS_TIMESTAMP:
q = pt_append_nulstring (parser, q, " SYS_TIMESTAMP ");
break;
case PT_CURRENT_TIMESTAMP:
q = pt_append_nulstring (parser, q, " CURRENT_TIMESTAMP ");
break;
case PT_SYS_DATETIME:
q = pt_append_nulstring (parser, q, " SYS_DATETIME ");
break;
case PT_CURRENT_DATETIME:
q = pt_append_nulstring (parser, q, " CURRENT_DATETIME ");
break;
case PT_UTC_TIME:
q = pt_append_nulstring (parser, q, " utc_time() ");
break;
case PT_UTC_DATE:
q = pt_append_nulstring (parser, q, " utc_date() ");
break;
case PT_CURRENT_USER:
q = pt_append_nulstring (parser, q, " CURRENT_USER ");
break;
case PT_USER:
q = pt_append_nulstring (parser, q, " user() ");
break;
case PT_ROW_COUNT:
q = pt_append_nulstring (parser, q, " row_count() ");
break;
case PT_LAST_INSERT_ID:
q = pt_append_nulstring (parser, q, " last_insert_id() ");
break;
case PT_MONTHS_BETWEEN:
q = pt_append_nulstring (parser, q, " months_between(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ADDDATE:
q = pt_append_nulstring (parser, q, " adddate(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SUBDATE:
q = pt_append_nulstring (parser, q, " subdate(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DATE_ADD:
case PT_DATE_SUB:
if (p->info.expr.op == PT_DATE_ADD)
{
q = pt_append_nulstring (parser, q, " date_add(");
}
else if (p->info.expr.op == PT_DATE_SUB)
{
q = pt_append_nulstring (parser, q, " date_sub(");
}
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", INTERVAL ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
switch (p->info.expr.arg3->info.expr.qualifier)
{
case PT_MILLISECOND:
q = pt_append_nulstring (parser, q, " MILLISECOND");
break;
case PT_SECOND:
q = pt_append_nulstring (parser, q, " SECOND");
break;
case PT_MINUTE:
q = pt_append_nulstring (parser, q, " MINUTE");
break;
case PT_HOUR:
q = pt_append_nulstring (parser, q, " HOUR");
break;
case PT_DAY:
q = pt_append_nulstring (parser, q, " DAY");
break;
case PT_WEEK:
q = pt_append_nulstring (parser, q, " WEEK");
break;
case PT_MONTH:
q = pt_append_nulstring (parser, q, " MONTH");
break;
case PT_QUARTER:
q = pt_append_nulstring (parser, q, " QUARTER");
break;
case PT_YEAR:
q = pt_append_nulstring (parser, q, " YEAR");
break;
case PT_SECOND_MILLISECOND:
q = pt_append_nulstring (parser, q, " SECOND_MILLISECOND");
break;
case PT_MINUTE_MILLISECOND:
q = pt_append_nulstring (parser, q, " MINUTE_MILLISECOND");
break;
case PT_MINUTE_SECOND:
q = pt_append_nulstring (parser, q, " MINUTE_SECOND");
break;
case PT_HOUR_MILLISECOND:
q = pt_append_nulstring (parser, q, " HOUR_MILLISECOND");
break;
case PT_HOUR_SECOND:
q = pt_append_nulstring (parser, q, " HOUR_SECOND");
break;
case PT_HOUR_MINUTE:
q = pt_append_nulstring (parser, q, " HOUR_MINUTE");
break;
case PT_DAY_MILLISECOND:
q = pt_append_nulstring (parser, q, " DAY_MILLISECOND");
break;
case PT_DAY_SECOND:
q = pt_append_nulstring (parser, q, " DAY_SECOND");
break;
case PT_DAY_MINUTE:
q = pt_append_nulstring (parser, q, " DAY_MINUTE");
break;
case PT_DAY_HOUR:
q = pt_append_nulstring (parser, q, " DAY_HOUR");
break;
case PT_YEAR_MONTH:
q = pt_append_nulstring (parser, q, " YEAR_MONTH");
break;
default:
break;
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ATAN:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " atan(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ATAN2:
q = pt_append_nulstring (parser, q, " atan2(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_FORMAT:
q = pt_append_nulstring (parser, q, " format(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DATE_FORMAT:
q = pt_append_nulstring (parser, q, " date_format(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_STR_TO_DATE:
q = pt_append_nulstring (parser, q, " str_to_date(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_LAST_DAY:
q = pt_append_nulstring (parser, q, " last_day(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TIME_FORMAT:
q = pt_append_nulstring (parser, q, " time_format(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_UNIX_TIMESTAMP:
q = pt_append_nulstring (parser, q, " unix_timestamp(");
if (p->info.expr.arg1)
{
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TIMESTAMP:
q = pt_append_nulstring (parser, q, " timestamp(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2)
{
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_YEARF:
q = pt_append_nulstring (parser, q, " year(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_MONTHF:
q = pt_append_nulstring (parser, q, " month(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DAYF:
q = pt_append_nulstring (parser, q, " day(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DAYOFMONTH:
q = pt_append_nulstring (parser, q, " dayofmonth(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_HOURF:
q = pt_append_nulstring (parser, q, " hour(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_MINUTEF:
q = pt_append_nulstring (parser, q, " minute(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SECONDF:
q = pt_append_nulstring (parser, q, " second(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_QUARTERF:
q = pt_append_nulstring (parser, q, " quarter(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_WEEKDAY:
q = pt_append_nulstring (parser, q, " weekday(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DAYOFWEEK:
q = pt_append_nulstring (parser, q, " dayofweek(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DAYOFYEAR:
q = pt_append_nulstring (parser, q, " dayofyear(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TODAYS:
q = pt_append_nulstring (parser, q, " to_days(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_FROMDAYS:
q = pt_append_nulstring (parser, q, " from_days(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TIMETOSEC:
q = pt_append_nulstring (parser, q, " time_to_sec(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SECTOTIME:
q = pt_append_nulstring (parser, q, " sec_to_time(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_MAKEDATE:
q = pt_append_nulstring (parser, q, " makedate(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_MAKETIME:
q = pt_append_nulstring (parser, q, " maketime(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ", ");
r3 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r3);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ADDTIME:
q = pt_append_nulstring (parser, q, " addtime(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_WEEKF:
q = pt_append_nulstring (parser, q, " week(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ADD_MONTHS:
q = pt_append_nulstring (parser, q, " add_months(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SYS_CONNECT_BY_PATH:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " sys_connect_by_path(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_REPLACE:
q = pt_append_nulstring (parser, q, " replace(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg3 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_REPEAT:
q = pt_append_nulstring (parser, q, " repeat(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SPACE:
q = pt_append_nulstring (parser, q, " space(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TRANSLATE:
q = pt_append_nulstring (parser, q, " translate(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_IF:
q = pt_append_nulstring (parser, q, " if(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_IFNULL:
q = pt_append_nulstring (parser, q, " ifnull(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ISNULL:
q = pt_append_nulstring (parser, q, " isnull(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_COS:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " cos(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SIN:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " sin(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TAN:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " tan(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DATEF:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " date(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TIMEF:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " time(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DEFAULTF:
if (parser->flag.is_parsing_static_sql && !p->flag.for_default_func)
{
q = pt_append_nulstring (parser, q, " default");
}
else
{
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " default(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_OID_OF_DUPLICATE_KEY:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " oid_of_duplicate_key(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DEGREES:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " degrees(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_RADIANS:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " radians(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SCHEMA:
q = pt_append_nulstring (parser, q, " schema()");
break;
case PT_DATABASE:
q = pt_append_nulstring (parser, q, " database()");
break;
case PT_VERSION:
q = pt_append_nulstring (parser, q, " version()");
break;
case PT_PI:
q = pt_append_nulstring (parser, q, " pi()");
break;
case PT_COT:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " cot(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ACOS:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " acos(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ASIN:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " asin(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_LN:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " ln(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_LOG2:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " log2(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_LOG10:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " log10(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CONCAT:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, " concat(");
}
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2)
{
r2 = pt_print_bytes (parser, p->info.expr.arg2);
if (r2)
{
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
}
}
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_CONCAT_WS:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, " concat_ws(");
r3 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r3);
q = pt_append_nulstring (parser, q, ", ");
}
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2)
{
r2 = pt_print_bytes (parser, p->info.expr.arg2);
if (r2)
{
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
}
}
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_FIELD:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, " field(");
r3 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r3);
q = pt_append_nulstring (parser, q, ", ");
}
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 && p->info.expr.arg2->flag.is_hidden_column == 0)
{
r2 = pt_print_bytes (parser, p->info.expr.arg2);
if (r2)
{
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
}
}
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_LEFT:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " left(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_RIGHT:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " right(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_LOCATE:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, " locate(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
if (p->info.expr.arg3)
{
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_MID:
q = pt_append_nulstring (parser, q, " mid(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ", ");
r3 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r3);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_STRCMP:
q = pt_append_nulstring (parser, q, " strcmp(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DATEDIFF:
q = pt_append_nulstring (parser, q, " datediff(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TIMEDIFF:
q = pt_append_nulstring (parser, q, " timediff(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_REVERSE:
q = pt_append_nulstring (parser, q, " reverse(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DISK_SIZE:
q = pt_append_nulstring (parser, q, " disk_size(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_LPAD:
q = pt_append_nulstring (parser, q, " lpad(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg3 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_RPAD:
q = pt_append_nulstring (parser, q, " rpad(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg3 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_LTRIM:
q = pt_append_nulstring (parser, q, " ltrim(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_RTRIM:
q = pt_append_nulstring (parser, q, " rtrim(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_LIKE_LOWER_BOUND:
q = pt_append_nulstring (parser, q, " like_match_lower_bound(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_LIKE_UPPER_BOUND:
q = pt_append_nulstring (parser, q, " like_match_upper_bound(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_FROM_UNIXTIME:
q = pt_append_nulstring (parser, q, " from_unixtime(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 != NULL)
{
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TRIM:
q = pt_append_nulstring (parser, q, " trim(");
switch (p->info.expr.qualifier)
{
case PT_LEADING:
q = pt_append_nulstring (parser, q, "leading ");
print_from = 1;
break;
case PT_TRAILING:
q = pt_append_nulstring (parser, q, "trailing ");
print_from = 1;
break;
case PT_BOTH:
q = pt_append_nulstring (parser, q, "both ");
print_from = 1;
break;
default:
break;
}
if (p->info.expr.arg2)
{
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
}
if (p->info.expr.arg2 || print_from)
{
q = pt_append_nulstring (parser, q, " from ");
}
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CAST:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
if (PT_EXPR_INFO_IS_FLAGED (p, PT_EXPR_INFO_CAST_COLL_MODIFIER))
{
/* CAST op with this flag does not transform into T_CAST */
char buf[PT_MEMB_BUF_SIZE];
bool use_parentheses = false;
sprintf (buf, " collate %s", lang_get_collation_name (PT_GET_COLLATION_MODIFIER (p)));
if (p->info.expr.arg1 == NULL)
{
/* Do nothing. It must be an error case. */
}
else if (p->info.expr.arg1->node_type == PT_VALUE)
{
PT_NODE *v = p->info.expr.arg1;
int v_coll_id;
v_coll_id = (v->data_type != NULL) ? (v->data_type->info.data_type.collation_id) : LANG_SYS_COLLATION;
/* if argument value was printed with 'collate', then use parentheses */
if (v->info.value.print_collation == false || v->info.value.is_collate_allowed == false
|| (v_coll_id == LANG_SYS_COLLATION && (parser->custom_print & PT_SUPPRESS_CHARSET_PRINT)))
{
v_coll_id = -1;
}
if (v_coll_id != -1)
{
use_parentheses = true;
}
}
else if (p->info.expr.arg1->node_type != PT_NAME && p->info.expr.arg1->node_type != PT_DOT_
&& p->info.expr.arg1->node_type != PT_HOST_VAR)
{
use_parentheses = true;
}
if (use_parentheses)
{
/* put arg1 in parantheses (if arg1 is an expression, COLLATE applies to last subexpression) */
q = pt_append_nulstring (parser, NULL, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
q = pt_append_nulstring (parser, q, buf);
}
else
{
q = pt_append_nulstring (parser, r1, buf);
}
}
else if (p->info.expr.cast_type != NULL
&& p->info.expr.cast_type->info.data_type.collation_flag != TP_DOMAIN_COLL_NORMAL)
{
assert (PT_HAS_COLLATION (p->info.expr.cast_type->type_enum));
assert (p->data_type == NULL || p->data_type->type_enum == p->info.expr.cast_type->type_enum);
q = pt_append_varchar (parser, q, r1);
}
else
{
if (parser->flag.is_parsing_trigger && p->info.expr.flag)
{
q = pt_append_varchar (parser, q, r1);
break;
}
r2 = pt_print_bytes (parser, p->info.expr.cast_type);
q = pt_append_nulstring (parser, q, " cast(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " as ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_CASE:
switch (p->info.expr.qualifier)
{
case PT_SIMPLE_CASE:
arg3 = p->info.expr.arg3;
assert (arg3->node_type == PT_EXPR || arg3->node_type == PT_VALUE);
if (arg3->node_type == PT_EXPR)
{
r1 = pt_print_bytes (parser, arg3->info.expr.arg1);
r2 = pt_print_bytes (parser, arg3->info.expr.arg2);
}
else
{
r2 = r1 = pt_print_bytes (parser, arg3);
}
r3 = pt_print_bytes (parser, p->info.expr.arg1);
r4 = (p->info.expr.arg2->type_enum == PT_TYPE_NULL) ? NULL : pt_print_bytes (parser, p->info.expr.arg2);
if (!p->info.expr.continued_case)
{
q = pt_append_nulstring (parser, q, "case ");
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, " when ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, " then ");
q = pt_append_varchar (parser, q, r3);
if (r4)
{
if (p->info.expr.arg2->node_type != PT_EXPR || p->info.expr.arg2->info.expr.op != PT_CASE
|| !p->info.expr.arg2->info.expr.continued_case)
q = pt_append_nulstring (parser, q, " else ");
q = pt_append_varchar (parser, q, r4);
}
if (!p->info.expr.continued_case)
{
q = pt_append_nulstring (parser, q, " end");
}
break;
case PT_SEARCHED_CASE:
r1 = pt_print_bytes (parser, p->info.expr.arg3);
r2 = pt_print_bytes (parser, p->info.expr.arg1);
r3 = (p->info.expr.arg2 == NULL
|| p->info.expr.arg2->type_enum == PT_TYPE_NULL) ? NULL : pt_print_bytes (parser, p->info.expr.arg2);
if (!p->info.expr.continued_case)
{
q = pt_append_nulstring (parser, q, "case");
}
q = pt_append_nulstring (parser, q, " when ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " then ");
q = pt_append_varchar (parser, q, r2);
if (r3)
{
if (p->info.expr.arg2->node_type != PT_EXPR || p->info.expr.arg2->info.expr.op != PT_CASE
|| !p->info.expr.arg2->info.expr.continued_case)
{
q = pt_append_nulstring (parser, q, " else ");
}
q = pt_append_varchar (parser, q, r3);
}
if (!p->info.expr.continued_case)
{
q = pt_append_nulstring (parser, q, " end");
}
break;
default:
break;
}
break;
case PT_NULLIF:
q = pt_append_nulstring (parser, q, "nullif(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_COALESCE:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, "coalesce(");
}
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 && p->info.expr.arg2->flag.is_hidden_column == 0)
{
r2 = pt_print_bytes (parser, p->info.expr.arg2);
if (r2)
{
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
}
}
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_NVL:
q = pt_append_nulstring (parser, q, "nvl(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_NVL2:
q = pt_append_nulstring (parser, q, "nvl2(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ", ");
r3 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r3);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DECODE:
arg3 = p->info.expr.arg3;
assert (arg3->node_type == PT_EXPR || arg3->node_type == PT_VALUE);
if (arg3->node_type == PT_EXPR)
{
r1 = pt_print_bytes (parser, arg3->info.expr.arg1);
r2 = pt_print_bytes (parser, arg3->info.expr.arg2);
}
else
{
r2 = r1 = pt_print_bytes (parser, arg3);
}
r3 = pt_print_bytes (parser, p->info.expr.arg1);
r4 = ((p->info.expr.arg2 == NULL || p->info.expr.arg2->type_enum == PT_TYPE_NULL)
? NULL : pt_print_bytes (parser, p->info.expr.arg2));
if (!p->info.expr.continued_case)
{
q = pt_append_nulstring (parser, q, "decode(");
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r3);
if (r4)
{
if (p->info.expr.arg2->node_type != PT_EXPR || p->info.expr.arg2->info.expr.op != PT_DECODE
|| !p->info.expr.arg2->info.expr.continued_case)
{
q = pt_append_nulstring (parser, q, ", ");
}
q = pt_append_varchar (parser, q, r4);
}
if (!p->info.expr.continued_case)
{
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_LEAST:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, "least(");
}
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 && p->info.expr.arg2->flag.is_hidden_column == 0)
{
r2 = pt_print_bytes (parser, p->info.expr.arg2);
if (r2)
{
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
}
}
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_GREATEST:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, "greatest(");
}
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 && p->info.expr.arg2->flag.is_hidden_column == 0)
{
r2 = pt_print_bytes (parser, p->info.expr.arg2);
if (r2)
{
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
}
}
if (p->info.expr.continued_case == 1)
{
q = pt_append_nulstring (parser, q, ")");
}
break;
case PT_BETWEEN_INF_LE:
case PT_BETWEEN_INF_LT:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, "min");
q = pt_append_nulstring (parser, q, pt_show_binopcode (p->info.expr.op));
q = pt_append_varchar (parser, q, r1);
break;
case PT_BETWEEN_GE_INF:
case PT_BETWEEN_GT_INF:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, pt_show_binopcode (p->info.expr.op));
q = pt_append_nulstring (parser, q, "max");
break;
case PT_INST_NUM:
q = pt_append_nulstring (parser, q, "inst_num()");
break;
case PT_ROWNUM:
q = pt_append_nulstring (parser, q, "rownum");
break;
case PT_ORDERBY_NUM:
q = pt_append_nulstring (parser, q, "orderby_num()");
break;
case PT_CONNECT_BY_ISCYCLE:
q = pt_append_nulstring (parser, q, "connect_by_iscycle");
break;
case PT_CONNECT_BY_ISLEAF:
q = pt_append_nulstring (parser, q, "connect_by_isleaf");
break;
case PT_LEVEL:
q = pt_append_nulstring (parser, q, "level");
break;
case PT_LIST_DBS:
q = pt_append_nulstring (parser, q, " list_dbs() ");
break;
case PT_SYS_GUID:
q = pt_append_nulstring (parser, q, " sys_guid() ");
break;
case PT_PATH_EXPR_SET:
r1 = pt_print_bytes_l (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
break;
case PT_INCR:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " incr(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DECR:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " decr(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_BIT_TO_BLOB:
q = pt_append_nulstring (parser, q, " bit_to_blob(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CHAR_TO_BLOB:
q = pt_append_nulstring (parser, q, " char_to_blob(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_BLOB_TO_BIT:
q = pt_append_nulstring (parser, q, " blob_to_bit(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2)
{
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_nulstring (parser, q, ", ");
q = pt_append_varchar (parser, q, r2);
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CHAR_TO_CLOB:
q = pt_append_nulstring (parser, q, " char_to_clob(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CLOB_TO_CHAR:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " clob_to_char(");
q = pt_append_varchar (parser, q, r1);
if (p->info.expr.arg2 != NULL && p->info.expr.arg2->node_type == PT_VALUE
&& p->info.expr.arg2->info.value.data_value.i != LANG_SYS_CODESET)
{
q = pt_append_nulstring (parser, q, " using ");
q = pt_append_nulstring (parser, q, lang_get_codeset_name (p->info.expr.arg2->info.value.data_value.i));
}
q = pt_append_nulstring (parser, q, ")");
break;
case PT_BLOB_FROM_FILE:
q = pt_append_nulstring (parser, q, " blob_from_file(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CLOB_FROM_FILE:
q = pt_append_nulstring (parser, q, " clob_from_file(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_BLOB_LENGTH:
q = pt_append_nulstring (parser, q, " blob_length(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CLOB_LENGTH:
q = pt_append_nulstring (parser, q, " clob_length(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TYPEOF:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " typeof(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_INDEX_CARDINALITY:
q = pt_append_nulstring (parser, q, " index_cardinality(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ESTIMATED_TABLE_ROWS:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " estimated_table_rows(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ESTIMATED_AVG_ROW_LENGTH:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " estimated_avg_row_length(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ESTIMATED_DATA_LENGTH:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " estimated_data_length(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_ESTIMATED_DATA_FREE:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " estimated_data_free(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TO_ENUMERATION_VALUE:
/* only print argument */
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
break;
case PT_RANGE:
if (parser->custom_print & PT_CONVERT_RANGE)
{
PT_STRING_BLOCK sb;
sb.length = 0;
sb.size = 1024;
sb.body = NULL;
sb.body = (char *) malloc (sb.size);
if (sb.body == NULL)
{
return NULL;
}
sb.body[0] = 0;
r4 = pt_print_bytes (parser, p->info.expr.arg1);
if (p->info.expr.arg2 && p->info.expr.arg2->or_next)
{
strcat_with_realloc (&sb, "(");
}
for (t = p->info.expr.arg2; t; t = t->or_next)
{
if (!p->info.expr.paren_type)
{
strcat_with_realloc (&sb, "(");
}
pt_print_range_op (parser, &sb, t, r4);
if (!p->info.expr.paren_type)
{
strcat_with_realloc (&sb, ")");
}
if (t->or_next)
{
strcat_with_realloc (&sb, " or ");
}
}
if (p->info.expr.arg2 && p->info.expr.arg2->or_next)
{
strcat_with_realloc (&sb, ")");
}
q = pt_append_nulstring (parser, q, sb.body);
free (sb.body);
/* break case PT_RANGE */
break;
}
[[fallthrough]];
default:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
if ((parser->custom_print & PT_PRINT_SUPPRESS_FOR_DBLINK) && p->info.expr.op == PT_MOD)
{
/* '%' instead of 'mod' for other DBMS */
q = pt_append_nulstring (parser, q, " % ");
}
else
{
q = pt_append_nulstring (parser, q, pt_show_binopcode (p->info.expr.op));
}
if (r2 && (r2->bytes[0] == '-') && q && (q->bytes[q->length - 1] == '-'))
{
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
}
if (p->info.expr.op == PT_RANGE)
{
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
}
else
{
q = pt_append_varchar (parser, q, r2);
}
break;
case PT_EVALUATE_VARIABLE:
q = pt_append_nulstring (parser, q, "@");
q = pt_append_nulstring (parser, q, p->info.expr.arg1->info.value.text);
break;
case PT_DEFINE_VARIABLE:
q = pt_append_nulstring (parser, q, "@");
q = pt_append_nulstring (parser, q, p->info.expr.arg1->info.value.text);
q = pt_append_nulstring (parser, q, " := ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
break;
case PT_EXEC_STATS:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " exec_stats(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_INET_ATON:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " inet_aton(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_INET_NTOA:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " inet_ntoa(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_CHARSET:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " charset(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_COERCIBILITY:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " coercibility(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_COLLATION:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " collation(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_WIDTH_BUCKET:
q = pt_append_nulstring (parser, q, "width_bucket(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
/* we use PT_BETWEEN and PT_BETWEEN_GE_LT to represent the boundaries */
between = p->info.expr.arg2;
if (between == NULL || between->node_type != PT_EXPR || between->info.expr.op != PT_BETWEEN)
{
return NULL;
}
between_ge_lt = between->info.expr.arg2;
if (between_ge_lt == NULL || between_ge_lt->node_type != PT_EXPR
|| between_ge_lt->info.expr.op != PT_BETWEEN_GE_LT)
{
return NULL;
}
r2 = pt_print_bytes (parser, between_ge_lt->info.expr.arg1);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ", ");
r3 = pt_print_bytes (parser, between_ge_lt->info.expr.arg2);
q = pt_append_varchar (parser, q, r3);
q = pt_append_nulstring (parser, q, ", ");
r4 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r4);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TRACE_STATS:
q = pt_append_nulstring (parser, q, " trace_stats()");
break;
case PT_LIKE_ESCAPE:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, pt_show_binopcode (p->info.expr.op));
q = pt_append_varchar (parser, q, r2);
break;
case PT_INDEX_PREFIX:
q = pt_append_nulstring (parser, q, " index_prefix(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SLEEP:
q = pt_append_nulstring (parser, q, " sleep(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_DBTIMEZONE:
q = pt_append_nulstring (parser, q, "dbtimezone");
break;
case PT_SESSIONTIMEZONE:
q = pt_append_nulstring (parser, q, "sessiontimezone");
break;
case PT_NEW_TIME:
q = pt_append_nulstring (parser, q, " newtime(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ", ");
r3 = pt_print_bytes (parser, p->info.expr.arg3);
q = pt_append_varchar (parser, q, r3);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_FROM_TZ:
q = pt_append_nulstring (parser, q, " from_tz(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r2 = pt_print_bytes (parser, p->info.expr.arg2);
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_TZ_OFFSET:
q = pt_append_nulstring (parser, q, " tz_offset(");
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_UTC_TIMESTAMP:
q = pt_append_nulstring (parser, q, " utc_timestamp() ");
break;
case PT_CRC32:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " crc32(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_SCHEMA_DEF:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " schema_def(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
case PT_COLLECTION_TO_STRING:
r1 = pt_print_bytes (parser, p->info.expr.arg1);
q = pt_append_nulstring (parser, q, " collection_to_string(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
break;
}
for (t = p->or_next; t; t = t->or_next)
{
or_next = t->or_next;
t->or_next = NULL;
r1 = pt_print_bytes (parser, t);
if (r1)
{
q = pt_append_nulstring (parser, q, " or ");
q = pt_append_varchar (parser, q, r1);
}
t->or_next = or_next;
}
if (p->info.expr.paren_type == 1)
{
q = pt_append_nulstring (parser, q, ")");
}
if ((parser->custom_print & PT_PRINT_ALIAS) && p->alias_print != NULL)
{
q = pt_append_nulstring (parser, q, " as [");
q = pt_append_nulstring (parser, q, p->alias_print);
q = pt_append_nulstring (parser, q, "]");
}
return q;
}
/* FILE_PATH */
/*
* pt_apply_file_path () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_file_path (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/*
* pt_print_file_path () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_file_path (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
if (p->info.file_path.string)
{
r1 = pt_print_bytes (parser, p->info.file_path.string);
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* FUNCTION */
/*
* pt_apply_function () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_function (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.function.arg_list, arg);
PT_APPLY_WALK (parser, p->info.function.order_by, arg);
PT_APPLY_WALK (parser, p->info.function.percentile, arg);
if (p->info.function.analytic.is_analytic)
{
PT_APPLY_WALK (parser, p->info.function.analytic.partition_by, arg);
PT_APPLY_WALK (parser, p->info.function.analytic.order_by, arg);
PT_APPLY_WALK (parser, p->info.function.analytic.offset, arg);
PT_APPLY_WALK (parser, p->info.function.analytic.default_value, arg);
PT_APPLY_WALK (parser, p->info.function.analytic.expanded_list, arg);
}
return p;
}
/*
* pt_init_function () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_function (PT_NODE * p)
{
p->info.function.function_type = (FUNC_CODE) 0;
p->info.function.all_or_distinct = (PT_MISC_TYPE) 0;
return p;
}
/*
* pt_print_function () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_function (PARSER_CONTEXT * parser, PT_NODE * p)
{
FUNC_CODE code;
PARSER_VARCHAR *q = 0, *r1;
PT_NODE *order_by = NULL;
code = p->info.function.function_type;
if (code == PT_GENERIC)
{
r1 = pt_print_bytes_l (parser, p->info.function.arg_list);
if (parser->custom_print & PT_PRINT_NO_SPECIFIED_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_with_qualifier_removed (p->info.function.generic_name));
}
else if (parser->custom_print & PT_PRINT_NO_CURRENT_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_without_current_user_name (p->info.function.generic_name));
}
else
{
q = pt_append_name (parser, q, p->info.function.generic_name);
}
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
else if (code < PT_TOP_AGG_FUNC)
{
q = pt_append_nulstring (parser, q, fcode_get_lowercase_name (code));
q = pt_append_nulstring (parser, q, "(");
if (code == PT_COUNT_STAR)
{
q = pt_append_nulstring (parser, q, "*");
}
else
{
if (code == PT_GROUP_CONCAT)
{
if (p->info.function.arg_list != NULL)
{
r1 = pt_print_bytes (parser, p->info.function.arg_list);
}
else
{
// it is unexpected but a badly formed function may miss its arg_list.
r1 = NULL;
}
if (p->info.function.order_by != NULL)
{
PARSER_VARCHAR *r2;
r2 = pt_print_bytes_l (parser, p->info.function.order_by);
r1 = pt_append_nulstring (parser, r1, " order by ");
r1 = pt_append_varchar (parser, r1, r2);
}
/* SEPARATOR */
if (p->info.function.arg_list != NULL && p->info.function.arg_list->next != NULL)
{
PARSER_VARCHAR *r2;
/* print separator */
r1 = pt_append_nulstring (parser, r1, " separator ");
r2 = pt_print_bytes (parser, p->info.function.arg_list->next);
r1 = pt_append_varchar (parser, r1, r2);
}
}
else
{
r1 = pt_print_bytes_l (parser, p->info.function.arg_list);
}
if (p->info.function.all_or_distinct == PT_DISTINCT)
{
q = pt_append_nulstring (parser, q, "distinct ");
}
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
}
else if (code == PT_LEAD || code == PT_LAG)
{
q = pt_append_nulstring (parser, q, fcode_get_lowercase_name (code));
q = pt_append_nulstring (parser, q, "(");
r1 = pt_print_bytes (parser, p->info.function.arg_list);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.function.analytic.offset);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.function.analytic.default_value);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
else if (code == PT_NTH_VALUE)
{
q = pt_append_nulstring (parser, q, fcode_get_lowercase_name (code));
q = pt_append_nulstring (parser, q, "(");
r1 = pt_print_bytes (parser, p->info.function.arg_list);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ", ");
r1 = pt_print_bytes (parser, p->info.function.analytic.offset);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
else if (code == PT_CUME_DIST || code == PT_PERCENT_RANK)
{
r1 = pt_print_bytes_l (parser, p->info.function.arg_list);
q = pt_append_nulstring (parser, q, fcode_get_lowercase_name (code));
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
if (!p->info.function.analytic.is_analytic)
{ /* aggregate */
if (p->info.function.order_by)
{
r1 = pt_print_bytes_l (parser, p->info.function.order_by);
q = pt_append_nulstring (parser, q, " within group(order by ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
}
}
else if (code == PT_PERCENTILE_CONT || code == PT_PERCENTILE_DISC)
{
q = pt_append_nulstring (parser, q, fcode_get_lowercase_name (code));
q = pt_append_nulstring (parser, q, "(");
r1 = pt_print_bytes (parser, p->info.function.percentile);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") within group (order by ");
r1 = pt_print_bytes (parser, p->info.function.arg_list);
q = pt_append_varchar (parser, q, r1);
if (p->info.function.analytic.is_analytic)
{
order_by = p->info.function.analytic.order_by;
}
else
{
order_by = p->info.function.order_by;
}
if (order_by != NULL)
{
if (order_by->info.sort_spec.asc_or_desc == PT_DESC)
{
q = pt_append_nulstring (parser, q, " desc");
}
if (order_by->info.sort_spec.nulls_first_or_last == PT_NULLS_FIRST)
{
q = pt_append_nulstring (parser, q, " nulls first");
}
else if (order_by->info.sort_spec.nulls_first_or_last == PT_NULLS_LAST)
{
q = pt_append_nulstring (parser, q, " nulls last");
}
}
q = pt_append_nulstring (parser, q, ")");
}
else if (code == F_SET || code == F_MULTISET || code == F_SEQUENCE)
{
if (p->spec_ident)
{
/* this is tagged as an "in" clause right hand side Print it as a parenthesized list */
r1 = pt_print_bytes_l (parser, p->info.function.arg_list);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
else
{
r1 = pt_print_bytes_l (parser, p->info.function.arg_list);
if (code != F_SEQUENCE)
{
q = pt_append_nulstring (parser, q, fcode_get_lowercase_name (code));
}
q = pt_append_nulstring (parser, q, "{");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, "}");
}
}
else if (code == F_CLASS_OF)
{
r1 = pt_print_bytes_l (parser, p->info.function.arg_list);
q = pt_append_nulstring (parser, q, fcode_get_lowercase_name (code));
q = pt_append_nulstring (parser, q, " ");
q = pt_append_varchar (parser, q, r1);
}
else
{
r1 = pt_print_bytes_l (parser, p->info.function.arg_list);
q = pt_append_nulstring (parser, q, fcode_get_lowercase_name (code));
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
if (p->info.function.analytic.is_analytic)
{
if (p->info.function.analytic.from_last)
{
q = pt_append_nulstring (parser, q, " from last ");
}
if (p->info.function.analytic.ignore_nulls)
{
q = pt_append_nulstring (parser, q, " ignore nulls ");
}
q = pt_append_nulstring (parser, q, " over (");
if (p->info.function.analytic.partition_by)
{
r1 = pt_print_bytes_l (parser, p->info.function.analytic.partition_by);
q = pt_append_nulstring (parser, q, "partition by ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.function.analytic.order_by && p->info.function.function_type != PT_PERCENTILE_CONT
&& p->info.function.function_type != PT_PERCENTILE_DISC)
{
r1 = pt_print_bytes_l (parser, p->info.function.analytic.order_by);
if (p->info.function.analytic.partition_by)
{
q = pt_append_nulstring (parser, q, " ");
}
q = pt_append_nulstring (parser, q, "order by ");
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
}
if ((parser->custom_print & PT_PRINT_ALIAS) && p->alias_print != NULL)
{
q = pt_append_nulstring (parser, q, " as [");
q = pt_append_nulstring (parser, q, p->alias_print);
q = pt_append_nulstring (parser, q, "]");
}
return q;
}
/* GET_OPTIMIZATION_LEVEL */
/*
* pt_apply_get_opt_lvl () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_get_opt_lvl (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.get_opt_lvl.args, arg);
PT_APPLY_WALK (parser, p->info.get_opt_lvl.into_var, arg);
return p;
}
/*
* pt_init_get_opt_lvl () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_get_opt_lvl (PT_NODE * p)
{
p->info.get_opt_lvl.option = PT_OPT_LVL;
return p;
}
/*
* pt_print_get_opt_lvl () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_get_opt_lvl (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
PT_MISC_TYPE option;
option = p->info.get_opt_lvl.option;
b = pt_append_nulstring (parser, b, "get optimization ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (option));
if (p->info.get_opt_lvl.args)
{
r1 = pt_print_bytes (parser, p->info.get_opt_lvl.args);
b = pt_append_nulstring (parser, b, " ");
b = pt_append_varchar (parser, b, r1);
}
if (p->info.get_opt_lvl.into_var)
{
r1 = pt_print_bytes (parser, p->info.get_opt_lvl.into_var);
b = pt_append_nulstring (parser, b, " into ");
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/* GET_TRIGGER */
/*
* pt_apply_get_trigger () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_get_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.get_trigger.into_var, arg);
return p;
}
/*
* pt_print_get_trigger () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_get_trigger (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
b = pt_append_nulstring (parser, b, "get trigger ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.get_trigger.option));
if (p->info.get_trigger.into_var)
{
r1 = pt_print_bytes (parser, p->info.get_trigger.into_var);
b = pt_append_nulstring (parser, b, " into ");
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/* GET_XACTION */
/*
* pt_apply_get_xaction () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_get_xaction (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.get_xaction.into_var, arg);
return p;
}
/*
* pt_print_get_xaction () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_get_xaction (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
b = pt_append_nulstring (parser, b, "get transaction ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.get_xaction.option));
if (p->info.get_xaction.into_var)
{
r1 = pt_print_bytes (parser, p->info.get_xaction.into_var);
b = pt_append_nulstring (parser, b, " into ");
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/* GRANT */
/*
* pt_apply_grant () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_grant (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.grant.auth_cmd_list, arg);
PT_APPLY_WALK (parser, p->info.grant.user_list, arg);
PT_APPLY_WALK (parser, p->info.grant.spec_list, arg);
return p;
}
/*
* pt_init_grant () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_grant (PT_NODE * p)
{
p->info.grant.grant_option = (PT_MISC_TYPE) 0;
return (p);
}
/*
* pt_print_grant () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_grant (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1, *r2, *r3;
unsigned int save_custom;
r1 = pt_print_bytes_l (parser, p->info.grant.auth_cmd_list);
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r2 = pt_print_bytes_l (parser, p->info.grant.spec_list);
parser->custom_print = save_custom;
r3 = pt_print_bytes_l (parser, p->info.grant.user_list);
q = pt_append_nulstring (parser, q, "grant ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " on ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, " to ");
q = pt_append_varchar (parser, q, r3);
if (p->info.grant.grant_option == PT_GRANT_OPTION)
{
q = pt_append_nulstring (parser, q, " with grant option ");
}
return q;
}
/* HOST_VAR */
/*
* pt_apply_host_var () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_host_var (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/*
* pt_print_host_var () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_host_var (PARSER_CONTEXT * parser, PT_NODE * p)
{
PT_NODE *t, *or_next;
PARSER_VARCHAR *q = NULL, *r;
char s[PT_MEMB_BUF_SIZE];
if (parser->print_db_value)
{
/* Skip cast to enum type. */
if (p->info.host_var.var_type == PT_HOST_IN
&& (p->expected_domain == NULL || TP_DOMAIN_TYPE (p->expected_domain) != DB_TYPE_ENUMERATION))
{
PT_NODE *save_error_msgs;
/* keep previous error, and print value if error occurs, reset and go ahead for example: curently, it is
* impossiable to occurs anyway, add this code for safety */
save_error_msgs = parser->error_msgs;
parser->error_msgs = NULL;
q = (*parser->print_db_value) (parser, p);
if (q)
{
if (pt_has_error (parser))
{
parser_free_tree (parser, parser->error_msgs);
}
parser->error_msgs = save_error_msgs; /* restore */
return q;
}
if (pt_has_error (parser))
{
parser_free_tree (parser, parser->error_msgs);
}
parser->error_msgs = save_error_msgs; /* restore */
}
}
q = pt_append_nulstring (parser, q, " ");
if (parser->flag.is_parsing_static_sql == 1 && pt_has_error (parser))
{
/*
* To avoid the following error message:
* Semantic: Illegal left hand side of an assignment clause. update [dba.tbl] [dba.tbl] set ?:0 ='ttt' where id =1
* we need to print the host variable name as it is.
* The following error message is expected:
* Semantic: Illegal left hand side of an assignment clause. update [dba.tbl] [dba.tbl] set s ='ttt' where id =1
*/
q = pt_append_nulstring (parser, q, p->info.host_var.label);
}
else
{
q = pt_append_nulstring (parser, q, p->info.host_var.str);
/* for internal print, print a host variable with its index */
if (parser->custom_print & PT_PRINT_NO_HOST_VAR_INDEX)
{
sprintf (s, " ");
}
else
{
sprintf (s, ":%d", p->info.host_var.index);
}
q = pt_append_nulstring (parser, q, s);
}
q = pt_append_nulstring (parser, q, " ");
for (t = p->or_next; t; t = t->or_next)
{
or_next = t->or_next;
t->or_next = NULL;
r = pt_print_bytes (parser, t);
if (r)
{
q = pt_append_nulstring (parser, q, " or ");
q = pt_append_varchar (parser, q, r);
}
t->or_next = or_next;
}
return q;
}
/* INSERT */
/*
* pt_apply_insert () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_insert (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.insert.spec, arg);
/* do not check attribute list for dblink */
if (p->info.insert.spec && p->info.insert.spec->info.spec.remote_server_name == NULL)
{
PT_APPLY_WALK (parser, p->info.insert.attr_list, arg);
}
PT_APPLY_WALK (parser, p->info.insert.value_clauses, arg);
PT_APPLY_WALK (parser, p->info.insert.into_var, arg);
PT_APPLY_WALK (parser, p->info.insert.where, arg);
PT_APPLY_WALK (parser, p->info.insert.internal_stmts, arg);
PT_APPLY_WALK (parser, p->info.insert.waitsecs_hint, arg);
PT_APPLY_WALK (parser, p->info.insert.odku_assignments, arg);
PT_APPLY_WALK (parser, p->info.insert.odku_non_null_attrs, arg);
PT_APPLY_WALK (parser, p->info.insert.non_null_attrs, arg);
return p;
}
/*
* pt_init_insert () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_insert (PT_NODE * p)
{
p->info.insert.is_subinsert = (PT_MISC_TYPE) 0;
p->info.insert.hint = PT_HINT_NONE;
p->info.insert.server_allowed = SERVER_INSERT_NOT_CHECKED;
return p;
}
/*
* pt_print_insert () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_insert (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1, *r2;
PT_NODE *crt_list = NULL;
bool is_first_list = true, multiple_values_insert = false;
// TODO: [PL/CSQL] need refactoring
unsigned int save_custom = parser->custom_print;
if (parser->flag.is_parsing_static_sql || parser->flag.is_parsing_trigger)
{
parser->custom_print |= PT_SUPPRESS_RESOLVED;
parser->custom_print & ~PT_PRINT_ALIAS;
}
r1 = pt_print_bytes (parser, p->info.insert.spec);
r2 = pt_print_bytes_l (parser, p->info.insert.attr_list);
parser->custom_print = save_custom;
if (p->info.insert.is_subinsert == PT_IS_SUBINSERT)
{
b = pt_append_nulstring (parser, b, "(");
}
if (p->info.insert.do_replace)
{
b = pt_append_nulstring (parser, b, "replace ");
}
else
{
b = pt_append_nulstring (parser, b, "insert ");
}
if (p->info.insert.hint != PT_HINT_NONE)
{
b = pt_append_nulstring (parser, b, "/*+");
if ((p->info.insert.hint & PT_HINT_LK_TIMEOUT) && p->info.insert.waitsecs_hint)
{
PARSER_VARCHAR *vc;
b = pt_append_nulstring (parser, b, " LOCK_TIMEOUT(");
vc = pt_print_bytes (parser, p->info.insert.waitsecs_hint);
b = pt_append_varchar (parser, b, vc);
b = pt_append_nulstring (parser, b, ")");
}
if (p->info.insert.hint & PT_HINT_NO_LOGGING)
{
b = pt_append_nulstring (parser, b, " NO_LOGGING");
}
if (p->info.insert.hint & PT_HINT_INSERT_MODE)
{
PARSER_VARCHAR *vc;
b = pt_append_nulstring (parser, b, " INSERT_EXECUTION_MODE(");
vc = pt_print_bytes (parser, p->info.insert.insert_mode);
b = pt_append_varchar (parser, b, vc);
b = pt_append_nulstring (parser, b, ")");
}
if (p->info.insert.hint & PT_HINT_USE_SBR)
{
b = pt_append_nulstring (parser, b, " USE_SBR");
}
b = pt_append_nulstring (parser, b, " */ ");
}
b = pt_append_nulstring (parser, b, "into ");
b = pt_append_varchar (parser, b, r1);
if (r2)
{
b = pt_append_nulstring (parser, b, " (");
if ((p->info.insert.hint & PT_HINT_USE_SBR) && (parser->custom_print & PT_PRINT_ORIGINAL_BEFORE_CONST_FOLDING))
{
PARSER_VARCHAR *column_list = NULL;
PT_NODE *attr = NULL;
attr = p->info.insert.attr_list;
while (attr)
{
column_list = pt_append_name (parser, column_list, attr->info.name.original);
attr = attr->next;
if (attr)
{
column_list = pt_append_nulstring (parser, column_list, ", ");
}
}
b = pt_append_varchar (parser, b, column_list);
}
else
{
b = pt_append_varchar (parser, b, r2);
}
b = pt_append_nulstring (parser, b, ") ");
}
else
{
b = pt_append_nulstring (parser, b, " ");
}
for (crt_list = p->info.insert.value_clauses, is_first_list = true,
multiple_values_insert = (crt_list != NULL && crt_list->next != NULL);
crt_list != NULL; crt_list = crt_list->next, is_first_list = false)
{
if (!is_first_list)
{
b = pt_append_nulstring (parser, b, ", ");
}
switch (crt_list->info.node_list.list_type)
{
case PT_IS_DEFAULT_VALUE:
if (is_first_list && multiple_values_insert)
{
b = pt_append_nulstring (parser, b, "values ");
}
b = pt_append_nulstring (parser, b, "default values");
break;
case PT_IS_VALUE:
r1 = pt_print_bytes_l (parser, crt_list->info.node_list.list);
if (is_first_list)
{
b = pt_append_nulstring (parser, b, "values ");
}
b = pt_append_nulstring (parser, b, "(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ")");
break;
case PT_IS_SUBQUERY:
{
PT_NODE *ptr_subquery = crt_list->info.node_list.list;
if (ptr_subquery != NULL && ptr_subquery->node_type == PT_SELECT)
{
/* TODO why do we change is_subquery? What about PT_UNION and the rest? */
ptr_subquery->info.query.is_subquery = (PT_MISC_TYPE) 0;
}
r1 = pt_print_bytes (parser, ptr_subquery);
b = pt_append_varchar (parser, b, r1);
}
break;
default:
assert (false);
break;
}
}
if (p->info.insert.into_var)
{
if (!(parser->custom_print & PT_SUPPRESS_INTO))
{
r1 = pt_print_bytes (parser, p->info.insert.into_var);
b = pt_append_nulstring (parser, b, " into ");
b = pt_append_varchar (parser, b, r1);
}
}
if (p->info.insert.odku_assignments)
{
r1 = pt_print_bytes_l (parser, p->info.insert.odku_assignments);
b = pt_append_nulstring (parser, b, " on duplicate key update ");
b = pt_append_varchar (parser, b, r1);
}
if (p->info.insert.is_subinsert == PT_IS_SUBINSERT)
{
b = pt_append_nulstring (parser, b, ") ");
}
if (!(parser->custom_print & PT_SUPPRESS_INTO) && p->info.insert.where)
{
r1 = pt_print_and_list (parser, p->info.insert.where);
b = pt_append_nulstring (parser, b, "\n-- check condition: ");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, "\n");
}
return b;
}
/* INTERSECTION */
/*
* pt_apply_intersection () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_intersection (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.query.with, arg);
PT_APPLY_WALK (parser, p->info.query.q.union_.arg1, arg);
PT_APPLY_WALK (parser, p->info.query.q.union_.arg2, arg);
PT_APPLY_WALK (parser, p->info.query.into_list, arg);
PT_APPLY_WALK (parser, p->info.query.order_by, arg);
PT_APPLY_WALK (parser, p->info.query.orderby_for, arg);
return p;
}
/*
* pt_init_intersection () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_intersection (PT_NODE * p)
{
p->info.query.all_distinct = PT_ALL;
p->info.query.hint = PT_HINT_NONE;
p->info.query.scan_op_type = S_SELECT;
return p;
}
/*
* pt_print_intersection () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_intersection (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1, *r2;
if (p->info.query.with != NULL)
{
r1 = pt_print_bytes_l (parser, p->info.query.with);
q = pt_append_varchar (parser, q, r1);
}
r1 = pt_print_bytes (parser, p->info.query.q.union_.arg1);
r2 = pt_print_bytes (parser, p->info.query.q.union_.arg2);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
if (p->info.query.all_distinct == PT_ALL)
{
q = pt_append_nulstring (parser, q, " intersect all ");
}
else
{
q = pt_append_nulstring (parser, q, " intersect ");
}
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
if (p->info.query.order_by)
{
r1 = pt_print_bytes_l (parser, p->info.query.order_by);
q = pt_append_nulstring (parser, q, " order by ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.orderby_for)
{
r1 = pt_print_bytes_l (parser, p->info.query.orderby_for);
q = pt_append_nulstring (parser, q, " for");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.limit && p->info.query.flag.rewrite_limit)
{
r1 = pt_print_bytes_l (parser, p->info.query.limit);
q = pt_append_nulstring (parser, q, " limit ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* AUTO INCREMENT */
/*
* pt_apply_auto_increment () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_auto_increment (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/*
* pt_print_auto_increment () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_auto_increment (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1, *r2;
r1 = pt_print_bytes (parser, p->info.auto_increment.start_val);
r2 = pt_print_bytes (parser, p->info.auto_increment.increment_val);
b = pt_append_nulstring (parser, b, " AUTO_INCREMENT");
if ((p->info.auto_increment.start_val) && (p->info.auto_increment.increment_val))
{
b = pt_append_nulstring (parser, b, "(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ", ");
b = pt_append_varchar (parser, b, r2);
b = pt_append_nulstring (parser, b, ") ");
}
return b;
}
/* ISOLATION_LVL */
/*
* pt_apply_isolation_lvl () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_isolation_lvl (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.isolation_lvl.level, arg);
return p;
}
/*
* pt_init_isolation_lvl () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_isolation_lvl (PT_NODE * p)
{
p->info.isolation_lvl.schema = p->info.isolation_lvl.instances = PT_NO_ISOLATION_LEVEL;
return (p);
}
/*
* pt_print_isolation_lvl () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_isolation_lvl (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
b = pt_append_nulstring (parser, b, "isolation level ");
if (p->info.isolation_lvl.schema == PT_SERIALIZABLE && p->info.isolation_lvl.instances == PT_SERIALIZABLE)
{
b = pt_append_nulstring (parser, b, " serializable ");
}
else
{
if (p->info.isolation_lvl.schema != PT_NO_ISOLATION_LEVEL)
{
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.isolation_lvl.schema));
b = pt_append_nulstring (parser, b, " schema");
}
if (p->info.isolation_lvl.instances != PT_NO_ISOLATION_LEVEL)
{
if (p->info.isolation_lvl.schema != PT_NO_ISOLATION_LEVEL)
{
b = pt_append_nulstring (parser, b, ",");
}
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.isolation_lvl.instances));
b = pt_append_nulstring (parser, b, " instances ");
}
}
if (p->info.isolation_lvl.level)
{
r1 = pt_print_bytes (parser, p->info.isolation_lvl.level);
b = pt_append_varchar (parser, b, r1);
}
if (p->info.isolation_lvl.async_ws)
{
b = pt_append_nulstring (parser, b, ", async workspace ");
}
return b;
}
/* METHOD_CALL */
/*
* pt_apply_method_call () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_method_call (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
if (PT_IS_METHOD (p))
{
PT_APPLY_WALK (parser, p->info.method_call.method_name, arg);
}
PT_APPLY_WALK (parser, p->info.method_call.arg_list, arg);
PT_APPLY_WALK (parser, p->info.method_call.on_call_target, arg);
PT_APPLY_WALK (parser, p->info.method_call.to_return_var, arg);
return p;
}
/*
* pt_print_method_call () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_method_call (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1, *r2;
r1 = pt_print_bytes (parser, p->info.method_call.method_name);
r2 = pt_print_bytes_l (parser, p->info.method_call.arg_list);
if (p->info.method_call.call_or_expr == PT_IS_CALL_STMT)
{
q = pt_append_nulstring (parser, q, "call ");
}
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
if (p->info.method_call.on_call_target)
{
r1 = pt_print_bytes (parser, p->info.method_call.on_call_target);
q = pt_append_nulstring (parser, q, " on ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* METHOD_DEF */
/*
* pt_apply_method_def () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_method_def (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.method_def.method_name, arg);
PT_APPLY_WALK (parser, p->info.method_def.method_args_list, arg);
PT_APPLY_WALK (parser, p->info.method_def.function_name, arg);
return p;
}
/*
* pt_init_method_def () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_method_def (PT_NODE * p)
{
p->info.method_def.mthd_type = PT_NORMAL;
return p;
}
/*
* pt_print_method_def () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_method_def (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
r1 = pt_print_bytes (parser, p->info.method_def.method_name);
if (p->info.method_def.mthd_type == PT_META_ATTR)
{
q = pt_append_nulstring (parser, q, " class ");
}
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, "( ");
if (p->info.method_def.method_args_list)
{
r1 = pt_print_bytes_l (parser, p->info.method_def.method_args_list);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ") ");
if (p->type_enum != PT_TYPE_NONE)
{
if (p->data_type)
{
r1 = pt_print_bytes (parser, p->data_type);
q = pt_append_varchar (parser, q, r1);
}
else
{
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
}
}
if (p->info.method_def.function_name)
{
r1 = pt_print_bytes (parser, p->info.method_def.function_name);
q = pt_append_nulstring (parser, q, " function ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* NAME */
/*
* pt_apply_name () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_name (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.name.path_correlation, arg);
PT_APPLY_WALK (parser, p->info.name.default_value, arg);
PT_APPLY_WALK (parser, p->info.name.constant_value, arg);
PT_APPLY_WALK (parser, p->info.name.indx_key_limit, arg);
return p;
}
/*
* pt_init_name () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_name (PT_NODE * p)
{
p->info.name.db_object_chn = NULL_CHN;
return p;
}
/*
* pt_print_name () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_name (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
unsigned int save_custom = parser->custom_print;
parser->custom_print = parser->custom_print | p->info.name.custom_print;
if (!(parser->custom_print & PT_SUPPRESS_META_ATTR_CLASS) && (p->info.name.meta_class == PT_META_CLASS))
{
q = pt_append_nulstring (parser, q, "class ");
}
if (p->info.name.meta_class == PT_CLASSOID_ATTR)
{
q = pt_append_nulstring (parser, q, "class(");
}
if (p->info.name.meta_class == PT_PARAMETER)
{
q = pt_append_nulstring (parser, q, ":");
}
if (p->info.name.meta_class == PT_OID_ATTR)
{
/* print the correlation name, which may be in one of two locations, before and after name resolution. */
if (p->info.name.original && p->info.name.original[0])
{
char lcase_name[DB_MAX_IDENTIFIER_LENGTH];
intl_identifier_lower (p->info.name.original, lcase_name);
q = pt_append_name (parser, q, lcase_name);
}
else if (p->info.name.resolved)
{
if (parser->custom_print & PT_PRINT_NO_SPECIFIED_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_with_qualifier_removed (p->info.name.resolved));
}
else if (parser->custom_print & PT_PRINT_NO_CURRENT_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_without_current_user_name (p->info.name.resolved));
}
else
{
q = pt_append_name (parser, q, p->info.name.resolved);
}
}
}
else
/* do not print 'resolved' for PT_PARAMETER(i.e, 'out parameter') */
if (!(parser->custom_print & PT_SUPPRESS_RESOLVED) && (p->info.name.resolved && p->info.name.resolved[0])
&& p->info.name.meta_class != PT_CLASS && p->info.name.meta_class != PT_PARAMETER
&& p->info.name.meta_class != PT_HINT_NAME)
{
/* Print both resolved name and original name If there is a non-zero length resolved name, print it, followed by
* ".". */
if ((parser->custom_print & PT_FORCE_ORIGINAL_TABLE_NAME) && (p->info.name.meta_class == PT_NORMAL))
{
/* make sure spec_id points to original table */
PT_NODE *original_spec;
assert (p->info.name.spec_id);
original_spec = (PT_NODE *) p->info.name.spec_id;
if (original_spec->info.spec.entity_name && original_spec->info.spec.entity_name->info.name.original)
{
const char *original_name = original_spec->info.spec.entity_name->info.name.original;
if (parser->custom_print & PT_PRINT_NO_SPECIFIED_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_with_qualifier_removed (original_name));
}
else if (parser->custom_print & PT_PRINT_NO_CURRENT_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_without_current_user_name (original_name));
}
else
{
q = pt_append_name (parser, q, original_name);
}
}
else
{
if (parser->custom_print & PT_PRINT_NO_SPECIFIED_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_with_qualifier_removed (p->info.name.resolved));
}
else if (parser->custom_print & PT_PRINT_NO_CURRENT_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_without_current_user_name (p->info.name.resolved));
}
else
{
q = pt_append_name (parser, q, p->info.name.resolved);
}
}
}
else
{
if (parser->custom_print & PT_PRINT_NO_SPECIFIED_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_with_qualifier_removed (p->info.name.resolved));
}
else if (parser->custom_print & PT_PRINT_NO_CURRENT_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_without_current_user_name (p->info.name.resolved));
}
else
{
q = pt_append_name (parser, q, p->info.name.resolved);
}
}
/* this is to catch OID_ATTR's which don't have their meta class set correctly. It should probably not by
* unconditional. */
if (p->info.name.meta_class != PT_META_CLASS && p->info.name.original && p->info.name.original[0])
{
q = pt_append_nulstring (parser, q, ".");
if (parser->custom_print & PT_PRINT_NO_SPECIFIED_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_with_qualifier_removed (p->info.name.original));
}
else if (parser->custom_print & PT_PRINT_NO_CURRENT_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_without_current_user_name (p->info.name.original));
}
else
{
q = pt_append_name (parser, q, p->info.name.original);
}
if (p->info.name.meta_class == PT_INDEX_NAME)
{
if (p->etc == (void *) PT_IDX_HINT_FORCE)
{
q = pt_append_nulstring (parser, q, "(+)");
}
if (p->etc == (void *) PT_IDX_HINT_IGNORE)
{
q = pt_append_nulstring (parser, q, "(-)");
}
}
if (p->info.name.indx_key_limit)
{
q = pt_append_nulstring (parser, q, " keylimit ");
if (p->info.name.indx_key_limit->next)
{
r1 = pt_print_bytes (parser, p->info.name.indx_key_limit->next);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ",");
}
r1 = pt_print_bytes (parser, p->info.name.indx_key_limit);
q = pt_append_varchar (parser, q, r1);
}
}
if (p->info.name.meta_class == PT_INDEX_NAME && p->info.name.original == NULL
&& p->etc == (void *) PT_IDX_HINT_CLASS_NONE)
{
q = pt_append_nulstring (parser, q, ".");
q = pt_append_nulstring (parser, q, "none");
}
}
else
{
/* here we print whatever the length */
if (p->info.name.original)
{
if (parser->custom_print & PT_PRINT_NO_SPECIFIED_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_with_qualifier_removed (p->info.name.original));
}
else if (parser->custom_print & PT_PRINT_NO_CURRENT_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_without_current_user_name (p->info.name.original));
}
else
{
q = pt_append_name (parser, q, p->info.name.original);
}
if (p->info.name.meta_class == PT_INDEX_NAME)
{
if (p->etc == (void *) PT_IDX_HINT_FORCE)
{
q = pt_append_nulstring (parser, q, "(+)");
}
/* TODO: temporary for IGNORE INDEX */
if (p->etc == (void *) PT_IDX_HINT_IGNORE)
{
q = pt_append_nulstring (parser, q, "(-)");
}
}
if (p->info.name.indx_key_limit)
{
q = pt_append_nulstring (parser, q, " keylimit ");
if (p->info.name.indx_key_limit->next)
{
r1 = pt_print_bytes (parser, p->info.name.indx_key_limit->next);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ",");
}
r1 = pt_print_bytes (parser, p->info.name.indx_key_limit);
q = pt_append_varchar (parser, q, r1);
}
}
else
{
if (p->info.name.meta_class == PT_INDEX_NAME && p->info.name.resolved && p->info.name.resolved[0]
&& p->etc == (void *) PT_IDX_HINT_CLASS_NONE)
{
/* always print resolved for "class_name.NONE" index names */
if (parser->custom_print & PT_PRINT_NO_SPECIFIED_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_with_qualifier_removed (p->info.name.resolved));
}
else if (parser->custom_print & PT_PRINT_NO_CURRENT_USER_NAME)
{
q = pt_append_name (parser, q, pt_get_name_without_current_user_name (p->info.name.resolved));
}
else
{
q = pt_append_name (parser, q, p->info.name.resolved);
}
q = pt_append_nulstring (parser, q, ".");
q = pt_append_nulstring (parser, q, "none");
}
}
}
if (p->info.name.meta_class == PT_CLASSOID_ATTR)
{
q = pt_append_nulstring (parser, q, ")");
}
if (!(parser->custom_print & PT_SUPPRESS_SELECTOR))
{
if (p->info.name.path_correlation)
{
r1 = pt_print_bytes (parser, p->info.name.path_correlation);
q = pt_append_nulstring (parser, q, " {");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, "}");
}
}
if (p->type_enum == PT_TYPE_STAR)
{
q = pt_append_nulstring (parser, q, ".*");
}
if (PT_NAME_INFO_IS_FLAGED (p, PT_NAME_INFO_DESC))
{
q = pt_append_nulstring (parser, q, " desc");
}
if ((parser->custom_print & PT_PRINT_ALIAS) && p->alias_print != NULL)
{
q = pt_append_nulstring (parser, q, " as [");
q = pt_append_nulstring (parser, q, p->alias_print);
q = pt_append_nulstring (parser, q, "]");
}
parser->custom_print = save_custom;
return q;
}
/* PREPARE TO COMMIT */
/*
* pt_apply_prepare_to_commit () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_prepare_to_commit (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/*
* pt_print_prepare_to_commit () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_prepare_to_commit (PARSER_CONTEXT * parser, PT_NODE * p)
{
char s[PT_MEMB_BUF_SIZE];
sprintf (s, "prepare to commit %d ", p->info.prepare_to_commit.trans_id);
return pt_append_nulstring (parser, NULL, s);
}
/* REMOVE_TRIGGER */
/*
* pt_apply_remove_trigger () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_remove_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.remove_trigger.trigger_spec_list, arg);
return p;
}
/*
* pt_print_remove_trigger () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_remove_trigger (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
r1 = pt_print_bytes_l (parser, p->info.remove_trigger.trigger_spec_list);
b = pt_append_nulstring (parser, b, "drop deferred trigger ");
b = pt_append_varchar (parser, b, r1);
return b;
}
/* RENAME */
/*
* pt_apply_rename () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_rename (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.rename.old_name, arg);
PT_APPLY_WALK (parser, p->info.rename.in_class, arg);
PT_APPLY_WALK (parser, p->info.rename.new_name, arg);
return p;
}
/*
* pt_print_rename () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_rename (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL;
PT_NODE *crt_pair = p;
b = pt_append_nulstring (parser, b, "rename ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.rename.entity_type));
b = pt_append_nulstring (parser, b, " ");
do
{
PARSER_VARCHAR *r1, *r2;
r1 = pt_print_bytes (parser, crt_pair->info.rename.old_name);
r2 = pt_print_bytes (parser, crt_pair->info.rename.new_name);
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, " as ");
b = pt_append_varchar (parser, b, r2);
if (crt_pair->next != NULL)
{
b = pt_append_nulstring (parser, b, ", ");
}
crt_pair = crt_pair->next;
}
while (crt_pair != NULL);
return b;
}
/* RENAME TRIGGER */
/*
* pt_apply_rename_trigger () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_rename_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.rename_trigger.old_name, arg);
PT_APPLY_WALK (parser, p->info.rename_trigger.new_name, arg);
return p;
}
/*
* pt_print_rename_trigger () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_rename_trigger (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1, *r2;
r1 = pt_print_bytes (parser, p->info.rename_trigger.old_name);
r2 = pt_print_bytes (parser, p->info.rename_trigger.new_name);
b = pt_append_nulstring (parser, b, "rename trigger ");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, " as ");
b = pt_append_varchar (parser, b, r2);
return b;
}
/* RESOLUTION */
/*
* pt_apply_resolution () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_resolution (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.resolution.attr_mthd_name, arg);
PT_APPLY_WALK (parser, p->info.resolution.of_sup_class_name, arg);
PT_APPLY_WALK (parser, p->info.resolution.as_attr_mthd_name, arg);
return p;
}
/*
* pt_init_resolution () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_resolution (PT_NODE * p)
{
p->info.resolution.attr_type = PT_NORMAL;
return p;
}
/*
* pt_print_resolution () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_resolution (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1, *r2;
r1 = pt_print_bytes (parser, p->info.resolution.attr_mthd_name);
r2 = pt_print_bytes (parser, p->info.resolution.of_sup_class_name);
if (p->info.resolution.attr_type == PT_META_ATTR)
{
q = pt_append_nulstring (parser, q, " class ");
}
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " of ");
q = pt_append_varchar (parser, q, r2);
if (p->info.resolution.as_attr_mthd_name)
{
r1 = pt_print_bytes (parser, p->info.resolution.as_attr_mthd_name);
q = pt_append_nulstring (parser, q, " as ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* REVOKE */
/*
* pt_apply_revoke () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_revoke (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.revoke.auth_cmd_list, arg);
PT_APPLY_WALK (parser, p->info.revoke.user_list, arg);
PT_APPLY_WALK (parser, p->info.revoke.spec_list, arg);
return p;
}
/*
* pt_print_revoke () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_revoke (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1, *r2, *r3;
unsigned int save_custom;
r1 = pt_print_bytes_l (parser, p->info.revoke.auth_cmd_list);
save_custom = parser->custom_print;
parser->custom_print |= PT_SUPPRESS_RESOLVED;
r2 = pt_print_bytes_l (parser, p->info.revoke.spec_list);
parser->custom_print = save_custom;
r3 = pt_print_bytes_l (parser, p->info.revoke.user_list);
q = pt_append_nulstring (parser, q, "revoke ");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " on ");
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, " from ");
q = pt_append_varchar (parser, q, r3);
return q;
}
/* ROLLBACK_WORK */
/*
* pt_apply_rollback_work () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_rollback_work (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.rollback_work.save_name, arg);
return p;
}
/*
* pt_print_rollback_work () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_rollback_work (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
q = pt_append_nulstring (parser, q, "rollback work");
if (p->info.rollback_work.save_name)
{
r1 = pt_print_bytes (parser, p->info.rollback_work.save_name);
q = pt_append_nulstring (parser, q, " to savepoint ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* SAVEPOINT */
/*
* pt_apply_savepoint () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_savepoint (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.savepoint.save_name, arg);
return p;
}
/*
* pt_print_savepoint () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_savepoint (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
r1 = pt_print_bytes (parser, p->info.savepoint.save_name);
b = pt_append_nulstring (parser, b, "savepoint ");
b = pt_append_varchar (parser, b, r1);
return b;
}
/* SCOPE */
/*
* pt_apply_scope () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_scope (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.scope.from, arg);
PT_APPLY_WALK (parser, p->info.scope.stmt, arg);
return p;
}
/*
* pt_print_scope () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_scope (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1, *r2;
r1 = pt_print_bytes (parser, p->info.scope.stmt);
r2 = pt_print_bytes (parser, p->info.scope.from);
b = pt_append_nulstring (parser, b, "scope ");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, " from ");
b = pt_append_varchar (parser, b, r2);
return b;
}
/* SELECT */
/*
* pt_apply_select () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_select (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.query.with, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.list, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.from, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.where, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.connect_by, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.start_with, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.after_cb_filter, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.group_by, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.having, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.using_index, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.with_increment, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.leading, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.use_nl, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.use_idx, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.index_ss, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.index_ls, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.use_merge, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.no_use_hash, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.use_hash, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.waitsecs_hint, arg);
PT_APPLY_WALK (parser, p->info.query.into_list, arg);
PT_APPLY_WALK (parser, p->info.query.order_by, arg);
PT_APPLY_WALK (parser, p->info.query.orderby_for, arg);
PT_APPLY_WALK (parser, p->info.query.qcache_hint, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.check_where, arg);
PT_APPLY_WALK (parser, p->info.query.limit, arg);
PT_APPLY_WALK (parser, p->info.query.q.select.for_update, arg);
return p;
}
/*
* pt_init_select () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_select (PT_NODE * p)
{
p->info.query.q.select.hint = PT_HINT_NONE;
p->info.query.q.select.check_cycles = CONNECT_BY_CYCLES_ERROR;
p->info.query.all_distinct = PT_ALL;
p->info.query.is_subquery = (PT_MISC_TYPE) 0;
p->info.query.hint = PT_HINT_NONE;
p->info.query.scan_op_type = S_SELECT;
return p;
}
/*
* pt_print_select () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_select (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1 = NULL;
PT_NODE *temp = NULL, *where_list = NULL;
bool set_paren = false; /* init */
bool toggle_print_alias = false;
bool is_first_list;
unsigned int save_custom = 0;
PT_NODE *from = NULL, *derived_table = NULL;
from = p->info.query.q.select.from;
if (from != NULL && from->info.spec.derived_table_type == PT_IS_SHOWSTMT
&& (derived_table = from->info.spec.derived_table) != NULL && derived_table->node_type == PT_SHOWSTMT)
{
r1 = pt_print_bytes (parser, derived_table);
q = pt_append_varchar (parser, q, r1);
where_list = p->info.query.q.select.where;
if (where_list != NULL)
{
r1 = pt_print_and_list (parser, where_list);
q = pt_append_nulstring (parser, q, " where ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
if (PT_SELECT_INFO_IS_FLAGED (p, PT_SELECT_INFO_IDX_SCHEMA))
{
q = pt_append_nulstring (parser, q, "show index from ");
r1 = pt_print_bytes_spec_list (parser, p->info.query.q.select.from);
q = pt_append_varchar (parser, q, r1);
return q;
}
if (PT_SELECT_INFO_IS_FLAGED (p, PT_SELECT_INFO_COLS_SCHEMA)
|| PT_SELECT_INFO_IS_FLAGED (p, PT_SELECT_FULL_INFO_COLS_SCHEMA))
{
PT_NODE *from = p->info.query.q.select.from;
if (from->info.spec.derived_table_type == PT_IS_SUBQUERY)
{
char s[64];
PT_NODE *subq = from->info.spec.derived_table;
sprintf (s, "show %s columns from ", PT_SELECT_INFO_IS_FLAGED (p, PT_SELECT_INFO_COLS_SCHEMA) ? "" : "full");
q = pt_append_nulstring (parser, q, s);
if (subq != NULL)
{
r1 = pt_print_bytes_spec_list (parser, subq->info.query.q.select.from);
q = pt_append_varchar (parser, q, r1);
}
else
{
// immature parse tree probably due to an error.
q = pt_append_nulstring (parser, q, "unknown");
}
where_list = p->info.query.q.select.where;
if (where_list)
{
r1 = pt_print_and_list (parser, where_list);
q = pt_append_nulstring (parser, q, " where ");
q = pt_append_varchar (parser, q, r1);
}
}
else
{
q = pt_append_nulstring (parser, q, "");
}
return q;
}
if (p->info.query.is_subquery == PT_IS_SUBQUERY
|| (p->info.query.is_subquery == PT_IS_UNION_SUBQUERY && p->info.query.order_by)
|| (p->info.query.is_subquery == PT_IS_UNION_QUERY && p->info.query.order_by))
{
if (!p->info.query.flag.subquery_cached)
{
set_paren = true;
}
}
if (set_paren)
{
q = pt_append_nulstring (parser, q, "(");
}
temp = p->info.query.q.select.list;
if (temp && temp->node_type == PT_NODE_LIST) /* values(...),... */
{
q = pt_append_nulstring (parser, q, "values ");
save_custom = parser->custom_print;
parser->custom_print |= PT_PRINT_ALIAS;
is_first_list = true;
for (temp = temp; temp; temp = temp->next)
{
if (!is_first_list)
{
q = pt_append_nulstring (parser, q, ",(");
}
else
{
q = pt_append_nulstring (parser, q, "(");
is_first_list = false;
}
r1 = pt_print_bytes_l (parser, temp->info.node_list.list);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
parser->custom_print = save_custom;
}
else
{
if (p->info.query.with != NULL)
{
r1 = pt_print_bytes_l (parser, p->info.query.with);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, "select ");
if (p->info.query.q.select.hint != PT_HINT_NONE
|| (p->info.query.hint != PT_HINT_NONE && p->info.query.hint != PT_HINT_REEXECUTE))
{
q = pt_append_nulstring (parser, q, "/*+ ");
if (p->info.query.hint & PT_HINT_QUERY_CACHE)
{
/* query cache */
q = pt_append_nulstring (parser, q, "QUERY_CACHE");
if (p->info.query.qcache_hint)
{
r1 = pt_print_bytes (parser, p->info.query.qcache_hint);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.query.q.select.hint & PT_HINT_ORDERED)
{
/* force join left-to-right */
q = pt_append_nulstring (parser, q, "ORDERED ");
}
else if (p->info.query.q.select.hint & PT_HINT_LEADING && p->info.query.q.select.leading != NULL)
{
/* force join left-to-right */
q = pt_append_nulstring (parser, q, "LEADING");
if (p->info.query.q.select.leading)
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.leading);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.query.q.select.hint & PT_HINT_NO_INDEX_SS)
{
q = pt_append_nulstring (parser, q, "NO_INDEX_SS ");
}
else if (p->info.query.q.select.hint & PT_HINT_INDEX_SS)
{
q = pt_append_nulstring (parser, q, "INDEX_SS");
if (p->info.query.q.select.index_ss)
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.index_ss);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
#if 0
if (p->info.query.q.select.hint & PT_HINT_Y)
{
/* -- not used */
q = pt_append_nulstring (parser, q, "Y ");
}
#endif /* 0 */
if (p->info.query.q.select.hint & PT_HINT_USE_NL)
{
/* force nl-join */
q = pt_append_nulstring (parser, q, "USE_NL");
if (p->info.query.q.select.use_nl)
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.use_nl);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.query.q.select.hint & PT_HINT_USE_IDX)
{
/* force idx-join */
q = pt_append_nulstring (parser, q, "USE_IDX");
if (p->info.query.q.select.use_idx)
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.use_idx);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.query.q.select.hint & PT_HINT_USE_MERGE)
{
/* force merge-join */
q = pt_append_nulstring (parser, q, "USE_MERGE");
if (p->info.query.q.select.use_merge)
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.use_merge);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.query.q.select.hint & PT_HINT_NO_USE_HASH)
{
/* disable hash-join */
q = pt_append_nulstring (parser, q, "NO_USE_HASH");
if (p->info.query.q.select.no_use_hash)
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.no_use_hash);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.query.q.select.hint & PT_HINT_USE_HASH)
{
/* force hash-join */
q = pt_append_nulstring (parser, q, "USE_HASH");
if (p->info.query.q.select.use_hash)
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.use_hash);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.query.q.select.hint & PT_HINT_LK_TIMEOUT && p->info.query.q.select.waitsecs_hint)
{
/* lock timeout */
q = pt_append_nulstring (parser, q, "LOCK_TIMEOUT(");
r1 = pt_print_bytes (parser, p->info.query.q.select.waitsecs_hint);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
if (p->info.query.q.select.hint & PT_HINT_USE_IDX_DESC)
{
q = pt_append_nulstring (parser, q, "USE_DESC_IDX ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_COVERING_IDX)
{
q = pt_append_nulstring (parser, q, "NO_COVERING_IDX ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_IDX_DESC)
{
q = pt_append_nulstring (parser, q, "NO_DESC_IDX ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_MULTI_RANGE_OPT)
{
q = pt_append_nulstring (parser, q, "NO_MULTI_RANGE_OPT ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_SORT_LIMIT)
{
q = pt_append_nulstring (parser, q, "NO_SORT_LIMIT ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_HASH_AGGREGATE)
{
q = pt_append_nulstring (parser, q, "NO_HASH_AGGREGATE ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_HASH_LIST_SCAN)
{
q = pt_append_nulstring (parser, q, "NO_HASH_LIST_SCAN ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_PUSH_PRED)
{
q = pt_append_nulstring (parser, q, "NO_PUSH_PRED ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_MERGE)
{
q = pt_append_nulstring (parser, q, "NO_MERGE ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_SUBQUERY_CACHE)
{
q = pt_append_nulstring (parser, q, "NO_SUBQUERY_CACHE ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_PARALLEL_SCAN)
{
q = pt_append_nulstring (parser, q, "NO_PARALLEL_SCAN ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_PARALLEL_SUBQUERY)
{
q = pt_append_nulstring (parser, q, "NO_PARALLEL_SUBQUERY ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_PARALLEL_HASH_JOIN)
{
q = pt_append_nulstring (parser, q, "NO_PARALLEL_HASH_JOIN ");
}
if (p->info.query.q.select.hint & PT_HINT_PARALLEL)
{
q = pt_append_nulstring (parser, q, "PARALLEL");
char buffer[10];
snprintf (buffer, sizeof (buffer), "%d", p->info.query.q.select.num_parallel_threads);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_nulstring (parser, q, buffer);
q = pt_append_nulstring (parser, q, ") ");
}
if (p->info.query.q.select.hint & PT_HINT_NLJ_KEEP_HEAP_PAGE_PINNED)
{
q = pt_append_nulstring (parser, q, "NLJ_KEEP_HEAP_PAGE_PINNED ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_ELIMINATE_JOIN)
{
q = pt_append_nulstring (parser, q, "NO_ELIMINATE_JOIN ");
}
if (p->info.query.q.select.hint & PT_HINT_NO_INDEX_LS)
{
q = pt_append_nulstring (parser, q, "NO_INDEX_LS ");
}
else if (p->info.query.q.select.hint & PT_HINT_INDEX_LS)
{
if ((p->info.query.q.select.hint & PT_HINT_NO_INDEX_SS)
|| !(p->info.query.q.select.hint & PT_HINT_INDEX_SS))
{ /* skip scan is disabled */
q = pt_append_nulstring (parser, q, "INDEX_LS");
if (p->info.query.q.select.index_ls)
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.index_ls);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
}
if (p->info.query.q.select.hint & PT_HINT_SELECT_RECORD_INFO)
{
q = pt_append_nulstring (parser, q, "SELECT_RECORD_INFO ");
}
if (p->info.query.q.select.hint & PT_HINT_SAMPLING_SCAN)
{
q = pt_append_nulstring (parser, q, "SAMPLING_SCAN ");
}
if (p->info.query.q.select.hint & PT_HINT_SELECT_PAGE_INFO)
{
q = pt_append_nulstring (parser, q, "SELECT_PAGE_INFO ");
}
if (p->info.query.q.select.hint & PT_HINT_SELECT_KEY_INFO)
{
q = pt_append_nulstring (parser, q, "SELECT_KEY_INFO");
if (p->info.query.q.select.using_index)
{
q = pt_append_nulstring (parser, q, "(");
q = pt_append_nulstring (parser, q, p->info.query.q.select.using_index->info.name.original);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
assert (0);
}
}
if (p->info.query.q.select.hint & PT_HINT_SELECT_BTREE_NODE_INFO)
{
q = pt_append_nulstring (parser, q, "SELECT_BTREE_NODE_INFO");
if (p->info.query.q.select.using_index)
{
q = pt_append_nulstring (parser, q, "(");
q = pt_append_nulstring (parser, q, p->info.query.q.select.using_index->info.name.original);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
assert (0);
}
}
if (p->info.query.q.select.hint & PT_HINT_INLINE_CTE)
{
q = pt_append_nulstring (parser, q, "INLINE ");
}
if (p->info.query.q.select.hint & PT_HINT_MATERIALIZE_CTE)
{
q = pt_append_nulstring (parser, q, "MATERIALIZE ");
}
q = pt_append_nulstring (parser, q, "*/ ");
}
if (p->info.query.all_distinct == PT_ALL)
{
/* left out "all", its the default. */
}
else if (p->info.query.all_distinct == PT_DISTINCT)
{
q = pt_append_nulstring (parser, q, "distinct ");
}
if (PT_SELECT_INFO_IS_FLAGED (p, PT_SELECT_INFO_IS_UPD_DEL_QUERY))
{
/* print select list with column alias for system generated select of update query */
for (temp = p->info.query.q.select.list; temp != NULL; temp = temp->next)
{
r1 = pt_print_bytes (parser, temp);
q = pt_append_varchar (parser, q, r1);
if (temp->alias_print != NULL)
{
q = pt_append_nulstring (parser, q, " as [");
q = pt_append_nulstring (parser, q, temp->alias_print);
q = pt_append_nulstring (parser, q, "]");
}
if (temp->next != NULL)
{
q = pt_append_nulstring (parser, q, ",");
}
}
}
else if ((parser->custom_print & PT_SUPPRESS_SELECT_LIST) != 0 && p->info.query.is_subquery != PT_IS_SUBQUERY)
{
/* suppress select list: print NA */
for (temp = p->info.query.q.select.list; temp != NULL; temp = temp->next)
{
q = pt_append_nulstring (parser, q, "NA");
if (temp->next != NULL)
{
q = pt_append_nulstring (parser, q, ",");
}
}
}
else
{
/* ordinary cases */
r1 = pt_print_bytes_l (parser, p->info.query.q.select.list);
q = pt_append_varchar (parser, q, r1);
}
if (parser->custom_print & PT_PRINT_ALIAS)
{
parser->custom_print ^= PT_PRINT_ALIAS;
toggle_print_alias = true;
}
if (!(parser->custom_print & PT_SUPPRESS_INTO))
{
if (p->info.query.into_list)
{
r1 = pt_print_bytes_l (parser, p->info.query.into_list);
q = pt_append_nulstring (parser, q, " into ");
q = pt_append_varchar (parser, q, r1);
}
}
from = p->info.query.q.select.from;
if (from != NULL)
{
/* for derived_table alias should be printed e.g. create table t2(id int primary key) as select id from
* (select count(*) id from t1) */
if (PT_SPEC_IS_DERIVED (from))
{
save_custom = parser->custom_print;
parser->custom_print |= PT_PRINT_ALIAS;
}
r1 = pt_print_bytes_spec_list (parser, from);
if (PT_SPEC_IS_DERIVED (from))
{
parser->custom_print = save_custom;
}
q = pt_append_nulstring (parser, q, " from ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.q.select.single_table_opt && p->info.query.q.select.from && !p->info.query.q.select.from->next)
{
int level;
qo_get_optimization_param (&level, QO_PARAM_LEVEL);
if (OPTIMIZATION_ENABLED (level))
{
assert (p->info.query.q.select.start_with == NULL);
p->info.query.q.select.start_with = p->info.query.q.select.where;
p->info.query.q.select.where = NULL;
}
}
if (p->info.query.q.select.after_cb_filter)
{
/* We need to print out the filter too. There's no special syntax for it, the filter is part of the where
* clause. */
where_list = parser_append_node (p->info.query.q.select.after_cb_filter, p->info.query.q.select.where);
}
else
{
where_list = p->info.query.q.select.where;
}
if (where_list)
{
r1 = pt_print_and_list (parser, where_list);
if (r1 != NULL)
{
q = pt_append_nulstring (parser, q, " where ");
q = pt_append_varchar (parser, q, r1);
}
}
if (p->info.query.q.select.after_cb_filter)
{
if (p->info.query.q.select.where)
{
/* We appended the filtering expression to the join expression and we need to cut that link. */
assert (where_list == p->info.query.q.select.where);
while (where_list->next != p->info.query.q.select.after_cb_filter)
{
where_list = where_list->next;
}
where_list->next = NULL;
}
else
{
assert (where_list == p->info.query.q.select.after_cb_filter);
}
}
if (p->info.query.q.select.start_with)
{
r1 = pt_print_and_list (parser, p->info.query.q.select.start_with);
q = pt_append_nulstring (parser, q, " start with ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.q.select.single_table_opt && p->info.query.q.select.from && !p->info.query.q.select.from->next)
{
int level;
qo_get_optimization_param (&level, QO_PARAM_LEVEL);
if (OPTIMIZATION_ENABLED (level))
{
assert (p->info.query.q.select.where == NULL);
p->info.query.q.select.where = p->info.query.q.select.start_with;
p->info.query.q.select.start_with = NULL;
}
}
if (p->info.query.q.select.connect_by)
{
r1 = pt_print_and_list (parser, p->info.query.q.select.connect_by);
if (p->info.query.q.select.check_cycles == CONNECT_BY_CYCLES_NONE
|| p->info.query.q.select.check_cycles == CONNECT_BY_CYCLES_NONE_IGNORE)
{
q = pt_append_nulstring (parser, q, " connect by nocycle ");
}
else
{
q = pt_append_nulstring (parser, q, " connect by ");
}
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.q.select.group_by)
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.group_by);
q = pt_append_nulstring (parser, q, " group by ");
q = pt_append_varchar (parser, q, r1);
if (p->info.query.q.select.group_by->flag.with_rollup)
{
q = pt_append_nulstring (parser, q, " with rollup");
}
}
if (p->info.query.q.select.having)
{
r1 = pt_print_and_list (parser, p->info.query.q.select.having);
q = pt_append_nulstring (parser, q, " having ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.q.select.using_index)
{
if (p->info.query.q.select.using_index->info.name.original == NULL)
{
if (p->info.query.q.select.using_index->info.name.resolved == NULL)
{
q = pt_append_nulstring (parser, q, " using index none");
}
else
{
if (p->info.query.q.select.using_index->etc == (void *) PT_IDX_HINT_CLASS_NONE)
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.using_index);
q = pt_append_nulstring (parser, q, " using index ");
q = pt_append_varchar (parser, q, r1);
}
else
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.using_index->next);
q = pt_append_nulstring (parser, q, " using index all except ");
q = pt_append_varchar (parser, q, r1);
}
}
}
else
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.using_index);
q = pt_append_nulstring (parser, q, " using index ");
q = pt_append_varchar (parser, q, r1);
}
}
if (p->info.query.q.select.with_increment)
{
temp = p->info.query.q.select.with_increment;
q = pt_append_nulstring (parser, q, ((temp->node_type == PT_EXPR && temp->info.expr.op == PT_DECR)
? "with decrement for " : "with increment for "));
q = pt_append_varchar (parser, q, pt_print_bytes_l (parser, p->info.query.q.select.with_increment));
}
if (PT_SELECT_INFO_IS_FLAGED (p, PT_SELECT_INFO_FOR_UPDATE))
{
q = pt_append_nulstring (parser, q, " for update");
if (p->info.query.q.select.for_update != NULL)
{
r1 = pt_print_bytes_l (parser, p->info.query.q.select.for_update);
q = pt_append_nulstring (parser, q, " of ");
q = pt_append_varchar (parser, q, r1);
}
else
{
r1 = NULL;
for (temp = p->info.query.q.select.from; temp != NULL; temp = temp->next)
{
if (temp->info.spec.flag & PT_SPEC_FLAG_FOR_UPDATE_CLAUSE)
{
if (r1 == NULL)
{
q = pt_append_nulstring (parser, q, " of ");
}
else
{
q = pt_append_nulstring (parser, q, ", ");
}
r1 = pt_print_bytes (parser, temp->info.spec.range_var);
q = pt_append_varchar (parser, q, r1);
}
}
}
}
if (p->info.query.order_by)
{
r1 = pt_print_bytes_l (parser, p->info.query.order_by);
if (p->info.query.flag.order_siblings)
{
q = pt_append_nulstring (parser, q, " order siblings by ");
}
else
{
q = pt_append_nulstring (parser, q, " order by ");
}
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.orderby_for)
{
r1 = pt_print_bytes_l (parser, p->info.query.orderby_for);
q = pt_append_nulstring (parser, q, " for ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.limit && p->info.query.flag.rewrite_limit)
{
r1 = pt_print_bytes_l (parser, p->info.query.limit);
q = pt_append_nulstring (parser, q, " limit ");
q = pt_append_varchar (parser, q, r1);
}
if (toggle_print_alias == true)
{
parser->custom_print ^= PT_PRINT_ALIAS;
}
}
if (set_paren)
{
q = pt_append_nulstring (parser, q, ")");
if ((parser->custom_print & PT_PRINT_ALIAS) && p->alias_print != NULL)
{
q = pt_append_nulstring (parser, q, " as [");
q = pt_append_nulstring (parser, q, p->alias_print);
q = pt_append_nulstring (parser, q, "]");
}
}
if (!(parser->custom_print & PT_SUPPRESS_INTO) && p->info.query.q.select.check_where)
{
r1 = pt_print_and_list (parser, p->info.query.q.select.check_where);
q = pt_append_nulstring (parser, q, "\n-- check condition: ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* SET_NAMES */
/*
* pt_apply_set_names () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_set_names (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.set_names.charset_node, arg);
PT_APPLY_WALK (parser, p->info.set_names.collation_node, arg);
return p;
}
/* SET_TIMEZONE */
/*
* pt_apply_set_timezone () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_set_timezone (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.set_timezone.timezone_node, arg);
return p;
}
/*
* pt_print_set_names () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_set_names (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
b = pt_append_nulstring (parser, b, "set names ");
assert (p->info.set_names.charset_node != NULL);
if (p->info.set_names.charset_node != NULL)
{
r1 = pt_print_bytes (parser, p->info.set_names.charset_node);
b = pt_append_varchar (parser, b, r1);
}
if (p->info.set_names.collation_node != NULL)
{
r1 = pt_print_bytes (parser, p->info.set_names.collation_node);
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/*
* pt_print_set_timezone () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_set_timezone (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
b = pt_append_nulstring (parser, b, "set timezone ");
assert (p->info.set_timezone.timezone_node != NULL);
r1 = pt_print_bytes (parser, p->info.set_timezone.timezone_node);
b = pt_append_varchar (parser, b, r1);
return b;
}
/* SET_OPTIMIZATION_LEVEL */
/*
* pt_apply_set_opt_lvl () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_set_opt_lvl (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.set_opt_lvl.val, arg);
return p;
}
/*
* pt_init_set_opt_lvl () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_set_opt_lvl (PT_NODE * p)
{
p->info.set_opt_lvl.option = PT_OPT_LVL;
return (p);
}
/*
* pt_print_set_opt_lvl () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_set_opt_lvl (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1, *r2 = NULL;
PT_MISC_TYPE option;
option = p->info.set_opt_lvl.option;
r1 = pt_print_bytes (parser, p->info.set_opt_lvl.val);
if (option == PT_OPT_COST)
{
r2 = pt_print_bytes (parser, p->info.set_opt_lvl.val->next);
}
b = pt_append_nulstring (parser, b, "set optimization ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (option));
b = pt_append_nulstring (parser, b, " ");
b = pt_append_varchar (parser, b, r1);
if (option == PT_OPT_COST)
{
b = pt_append_nulstring (parser, b, " ");
b = pt_append_varchar (parser, b, r2);
}
return b;
}
/* SET_SYSTEM_PARAMETERS */
/*
* pt_apply_set_sys_params () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_set_sys_params (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.set_sys_params.val, arg);
return p;
}
/*
* pt_print_set_sys_params () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_set_sys_params (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
b = pt_append_nulstring (parser, b, "set parameters ");
if (p->info.set_sys_params.val)
{
r1 = pt_print_bytes (parser, p->info.set_sys_params.val);
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/* SET_TRIGGER */
/*
* pt_apply_set_trigger () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_set_trigger (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.set_trigger.val, arg);
return p;
}
/*
* pt_print_set_trigger () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_set_trigger (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
b = pt_append_nulstring (parser, b, "set trigger ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.set_trigger.option));
if (p->info.set_trigger.option == PT_TRIGGER_TRACE && p->info.set_trigger.val
&& p->info.set_trigger.val->info.value.data_value.i <= 0)
{
if (p->info.set_trigger.val->info.value.data_value.i == 0)
{
b = pt_append_nulstring (parser, b, " off");
}
else
{
b = pt_append_nulstring (parser, b, " on");
}
}
else
{
r1 = pt_print_bytes (parser, p->info.set_trigger.val);
b = pt_append_nulstring (parser, b, " ");
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/*
* pt_apply_showstmt () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_showstmt (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.showstmt.show_args, arg);
return p;
}
/*
* pt_init_showstmt () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_showstmt (PT_NODE * p)
{
p->info.showstmt.show_type = SHOWSTMT_NULL;
return (p);
}
/*
* pt_print_showstmt () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_showstmt (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
SHOWSTMT_TYPE show_type;
show_type = p->info.showstmt.show_type;
b = pt_append_nulstring (parser, b, showstmt_get_metadata (show_type)->alias_print);
r1 = pt_print_bytes_l (parser, p->info.showstmt.show_args);
b = pt_append_varchar (parser, b, r1);
return b;
}
/* SET_XACTION */
/*
* pt_apply_set_xaction () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_set_xaction (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.set_xaction.xaction_modes, arg);
return p;
}
/*
* pt_print_set_xaction () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_set_xaction (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
r1 = pt_print_bytes_l (parser, p->info.set_xaction.xaction_modes);
b = pt_append_nulstring (parser, b, "set transaction ");
b = pt_append_varchar (parser, b, r1);
return b;
}
/* SORT_SPEC */
/*
* pt_apply_sort_spec () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_sort_spec (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.sort_spec.expr, arg);
return p;
}
/*
* pt_init_sort_spec () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_sort_spec (PT_NODE * p)
{
p->info.sort_spec.asc_or_desc = PT_ASC;
p->info.sort_spec.nulls_first_or_last = PT_NULLS_DEFAULT;
return p;
}
/*
* pt_print_sort_spec () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_sort_spec (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
r1 = pt_print_bytes (parser, p->info.sort_spec.expr);
q = pt_append_varchar (parser, q, r1);
if (p->info.sort_spec.asc_or_desc == PT_DESC)
{
q = pt_append_nulstring (parser, q, " desc ");
}
if (p->info.sort_spec.nulls_first_or_last == PT_NULLS_FIRST)
{
q = pt_append_nulstring (parser, q, " nulls first ");
}
else if (p->info.sort_spec.nulls_first_or_last == PT_NULLS_LAST)
{
q = pt_append_nulstring (parser, q, " nulls last ");
}
return q;
}
/* TIMEOUT */
/*
* pt_apply_timeout () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_timeout (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.timeout.val, arg);
return p;
}
/*
* pt_print_timeout () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_timeout (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
PT_NODE *val;
b = pt_append_nulstring (parser, b, "lock timeout ");
val = p->info.timeout.val;
if (val)
{
if (val->info.value.data_value.i == -1)
{
b = pt_append_nulstring (parser, b, "infinite");
}
else if (val->info.value.data_value.i == 0)
{
b = pt_append_nulstring (parser, b, "off");
}
else
{
r1 = pt_print_bytes (parser, p->info.timeout.val);
b = pt_append_varchar (parser, b, r1);
}
}
return b;
}
/* TRIGGER_ACTION */
/*
* pt_apply_trigger_action () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_trigger_action (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.trigger_action.expression, arg);
PT_APPLY_WALK (parser, p->info.trigger_action.string, arg);
return p;
}
/*
* pt_print_trigger_action () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_trigger_action (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
switch (p->info.trigger_action.action_type)
{
case PT_REJECT:
case PT_INVALIDATE_XACTION:
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.trigger_action.action_type));
break;
case PT_PRINT:
r1 = pt_print_bytes (parser, p->info.trigger_action.string);
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.trigger_action.action_type));
b = pt_append_nulstring (parser, b, " ");
b = pt_append_varchar (parser, b, r1);
break;
case PT_EXPRESSION:
r1 = pt_print_bytes (parser, p->info.trigger_action.expression);
b = pt_append_varchar (parser, b, r1);
break;
default:
break;
}
return b;
}
/* TRIGGER_SPEC_LIST */
/*
* pt_apply_trigger_spec_list () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_trigger_spec_list (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.trigger_spec_list.trigger_name_list, arg);
PT_APPLY_WALK (parser, p->info.trigger_spec_list.event_list, arg);
return p;
}
/*
* pt_print_trigger_spec_list () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_trigger_spec_list (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
r1 = pt_print_bytes_l (parser, p->info.trigger_spec_list.trigger_name_list);
b = pt_append_varchar (parser, b, r1);
return b;
}
/* UNION_STMT */
/*
* pt_apply_union_stmt () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_union_stmt (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.query.with, arg);
PT_APPLY_WALK (parser, p->info.query.q.union_.arg1, arg);
PT_APPLY_WALK (parser, p->info.query.q.union_.arg2, arg);
PT_APPLY_WALK (parser, p->info.query.into_list, arg);
PT_APPLY_WALK (parser, p->info.query.order_by, arg);
PT_APPLY_WALK (parser, p->info.query.orderby_for, arg);
PT_APPLY_WALK (parser, p->info.query.limit, arg);
// todo - there is a lot less stuff here than on pt_apply_select. I am not sure this is safe.
// e.g. this is used for parser_copy_tree too. which should deep copy entire tree! otherwise we may have some
// unpleasant effects.
return p;
}
/*
* pt_init_union_stmt () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_union_stmt (PT_NODE * p)
{
p->info.query.all_distinct = PT_ALL;
p->info.query.hint = PT_HINT_NONE;
p->info.query.scan_op_type = S_SELECT;
return p;
}
/*
* pt_print_union_stmt () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_union_stmt (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1, *r2;
if (p->info.query.with != NULL)
{
r1 = pt_print_bytes_l (parser, p->info.query.with);
q = pt_append_varchar (parser, q, r1);
}
r1 = pt_print_bytes (parser, p->info.query.q.union_.arg1);
r2 = pt_print_bytes (parser, p->info.query.q.union_.arg2);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " union ");
if (p->info.query.all_distinct == PT_ALL)
{
q = pt_append_nulstring (parser, q, "all ");
}
q = pt_append_varchar (parser, q, r2);
q = pt_append_nulstring (parser, q, ")");
if (p->info.query.order_by)
{
r1 = pt_print_bytes_l (parser, p->info.query.order_by);
q = pt_append_nulstring (parser, q, " order by ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.orderby_for)
{
r1 = pt_print_bytes_l (parser, p->info.query.orderby_for);
q = pt_append_nulstring (parser, q, " for ");
q = pt_append_varchar (parser, q, r1);
}
if (p->info.query.limit && p->info.query.flag.rewrite_limit)
{
r1 = pt_print_bytes_l (parser, p->info.query.limit);
q = pt_append_nulstring (parser, q, " limit ");
q = pt_append_varchar (parser, q, r1);
}
return q;
}
/* UPDATE */
/*
* pt_apply_update () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_update (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.update.with, arg);
PT_APPLY_WALK (parser, p->info.update.spec, arg);
PT_APPLY_WALK (parser, p->info.update.assignment, arg);
PT_APPLY_WALK (parser, p->info.update.search_cond, arg);
PT_APPLY_WALK (parser, p->info.update.order_by, arg);
PT_APPLY_WALK (parser, p->info.update.orderby_for, arg);
PT_APPLY_WALK (parser, p->info.update.using_index, arg);
PT_APPLY_WALK (parser, p->info.update.object_parameter, arg);
PT_APPLY_WALK (parser, p->info.update.cursor_name, arg);
PT_APPLY_WALK (parser, p->info.update.check_where, arg);
PT_APPLY_WALK (parser, p->info.update.internal_stmts, arg);
PT_APPLY_WALK (parser, p->info.update.waitsecs_hint, arg);
PT_APPLY_WALK (parser, p->info.update.leading_hint, arg);
PT_APPLY_WALK (parser, p->info.update.use_nl_hint, arg);
PT_APPLY_WALK (parser, p->info.update.use_idx_hint, arg);
PT_APPLY_WALK (parser, p->info.update.use_merge_hint, arg);
PT_APPLY_WALK (parser, p->info.update.no_use_hash_hint, arg);
PT_APPLY_WALK (parser, p->info.update.use_hash_hint, arg);
PT_APPLY_WALK (parser, p->info.update.limit, arg);
return p;
}
/*
* pt_init_update () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_update (PT_NODE * p)
{
p->info.update.hint = PT_HINT_NONE;
return p;
}
/*
* pt_print_update () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_update (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
if (p->info.update.with != NULL)
{
r1 = pt_print_bytes_l (parser, p->info.update.with);
b = pt_append_varchar (parser, b, r1);
}
b = pt_append_nulstring (parser, b, "update ");
if (p->info.update.hint != PT_HINT_NONE)
{
b = pt_append_nulstring (parser, b, "/*+");
if (p->info.update.hint & PT_HINT_LK_TIMEOUT && p->info.update.waitsecs_hint)
{
b = pt_append_nulstring (parser, b, " LOCK_TIMEOUT(");
r1 = pt_print_bytes (parser, p->info.update.waitsecs_hint);
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ")");
}
if (p->info.update.hint & PT_HINT_NO_LOGGING)
{
b = pt_append_nulstring (parser, b, " NO_LOGGING");
}
if (p->info.update.hint & PT_HINT_ORDERED)
{
/* force join left-to-right */
b = pt_append_nulstring (parser, b, " ORDERED ");
}
if (p->info.update.hint & PT_HINT_LEADING)
{
/* force join left-to-right */
b = pt_append_nulstring (parser, b, " LEADING");
if (p->info.update.leading_hint)
{
r1 = pt_print_bytes_l (parser, p->info.update.leading_hint);
b = pt_append_nulstring (parser, b, "(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
}
else
{
b = pt_append_nulstring (parser, b, " ");
}
}
if (p->info.update.hint & PT_HINT_USE_NL)
{
/* force nl-join */
b = pt_append_nulstring (parser, b, " USE_NL");
if (p->info.update.use_nl_hint)
{
r1 = pt_print_bytes_l (parser, p->info.update.use_nl_hint);
b = pt_append_nulstring (parser, b, "(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
}
else
{
b = pt_append_nulstring (parser, b, " ");
}
}
if (p->info.update.hint & PT_HINT_USE_IDX)
{
/* force idx-join */
b = pt_append_nulstring (parser, b, " USE_IDX");
if (p->info.update.use_idx_hint)
{
r1 = pt_print_bytes_l (parser, p->info.update.use_idx_hint);
b = pt_append_nulstring (parser, b, "(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
}
else
{
b = pt_append_nulstring (parser, b, " ");
}
}
if (p->info.update.hint & PT_HINT_USE_MERGE)
{
/* force merge-join */
b = pt_append_nulstring (parser, b, " USE_MERGE");
if (p->info.update.use_merge_hint)
{
r1 = pt_print_bytes_l (parser, p->info.update.use_merge_hint);
b = pt_append_nulstring (parser, b, "(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
}
else
{
b = pt_append_nulstring (parser, b, " ");
}
}
if (p->info.update.hint & PT_HINT_NO_USE_HASH)
{
/* disable hash-join */
b = pt_append_nulstring (parser, b, " NO_USE_HASH");
if (p->info.update.no_use_hash_hint)
{
r1 = pt_print_bytes_l (parser, p->info.update.no_use_hash_hint);
b = pt_append_nulstring (parser, b, "(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
}
else
{
b = pt_append_nulstring (parser, b, " ");
}
}
if (p->info.update.hint & PT_HINT_USE_HASH)
{
/* force hash-join */
b = pt_append_nulstring (parser, b, " USE_HASH");
if (p->info.update.use_hash_hint)
{
r1 = pt_print_bytes_l (parser, p->info.update.use_hash_hint);
b = pt_append_nulstring (parser, b, "(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
}
else
{
b = pt_append_nulstring (parser, b, " ");
}
}
if (p->info.update.hint & PT_HINT_USE_IDX_DESC)
{
b = pt_append_nulstring (parser, b, " USE_DESC_IDX ");
}
if (p->info.update.hint & PT_HINT_NO_COVERING_IDX)
{
b = pt_append_nulstring (parser, b, " NO_COVERING_IDX ");
}
if (p->info.update.hint & PT_HINT_NO_IDX_DESC)
{
b = pt_append_nulstring (parser, b, " NO_DESC_IDX ");
}
if (p->info.update.hint & PT_HINT_NO_MULTI_RANGE_OPT)
{
b = pt_append_nulstring (parser, b, " NO_MULTI_RANGE_OPT ");
}
if (p->info.update.hint & PT_HINT_NO_SORT_LIMIT)
{
b = pt_append_nulstring (parser, b, " NO_SORT_LIMIT ");
}
if (p->info.update.hint & PT_HINT_USE_SBR)
{
b = pt_append_nulstring (parser, b, " USE_SBR ");
}
if (p->info.update.hint & PT_HINT_NO_SUPPLEMENTAL_LOG)
{
b = pt_append_nulstring (parser, b, " NO_SUPPLEMENTAL_LOG ");
}
if (p->info.update.hint & PT_HINT_NO_PARALLEL_HASH_JOIN)
{
b = pt_append_nulstring (parser, b, "NO_PARALLEL_HASH_JOIN ");
}
b = pt_append_nulstring (parser, b, " */ ");
}
if (!IS_UPDATE_OBJ (p))
{
/* print the spec list */
r1 = pt_print_bytes_spec_list (parser, p->info.update.spec);
b = pt_append_varchar (parser, b, r1);
}
else
{
r1 = pt_print_bytes (parser, p->info.update.object_parameter);
b = pt_append_nulstring (parser, b, "object ");
b = pt_append_varchar (parser, b, r1);
}
r1 = pt_print_bytes_l (parser, p->info.update.assignment);
b = pt_append_nulstring (parser, b, " set ");
b = pt_append_varchar (parser, b, r1);
if (p->info.update.search_cond)
{
r1 = pt_print_and_list (parser, p->info.update.search_cond);
b = pt_append_nulstring (parser, b, " where ");
b = pt_append_varchar (parser, b, r1);
}
if (p->info.update.using_index)
{
if (p->info.update.using_index->info.name.original == NULL)
{
if (p->info.update.using_index->info.name.resolved == NULL)
{
b = pt_append_nulstring (parser, b, " using index none");
}
else
{
if (p->info.update.using_index->etc == (void *) PT_IDX_HINT_CLASS_NONE)
{
r1 = pt_print_bytes_l (parser, p->info.update.using_index);
b = pt_append_nulstring (parser, b, " using index ");
b = pt_append_varchar (parser, b, r1);
}
else
{
r1 = pt_print_bytes_l (parser, p->info.update.using_index->next);
b = pt_append_nulstring (parser, b, " using index all except ");
b = pt_append_varchar (parser, b, r1);
}
}
}
else
{
r1 = pt_print_bytes_l (parser, p->info.update.using_index);
b = pt_append_nulstring (parser, b, " using index ");
b = pt_append_varchar (parser, b, r1);
}
}
if (p->info.update.order_by)
{
r1 = pt_print_bytes_l (parser, p->info.update.order_by);
b = pt_append_nulstring (parser, b, " order by ");
b = pt_append_varchar (parser, b, r1);
}
if (p->info.update.orderby_for)
{
r1 = pt_print_bytes_l (parser, p->info.update.orderby_for);
b = pt_append_nulstring (parser, b, " for ");
b = pt_append_varchar (parser, b, r1);
}
if (p->info.update.limit && p->info.update.rewrite_limit)
{
r1 = pt_print_bytes_l (parser, p->info.update.limit);
b = pt_append_nulstring (parser, b, " limit ");
b = pt_append_varchar (parser, b, r1);
}
if (!(parser->custom_print & PT_SUPPRESS_INTO) && p->info.update.check_where)
{
r1 = pt_print_and_list (parser, p->info.update.check_where);
b = pt_append_nulstring (parser, b, "\n-- check condition: ");
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/* UPDATE_STATS */
/*
* pt_apply_update_stats () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_update_stats (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.update_stats.class_list, arg);
return p;
}
/*
* pt_print_update_stats () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_update_stats (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1;
b = pt_append_nulstring (parser, b, "update statistics on ");
if (p->info.update_stats.all_classes > 0)
{
b = pt_append_nulstring (parser, b, "all classes");
}
else if (p->info.update_stats.all_classes < 0)
{
b = pt_append_nulstring (parser, b, "catalog classes");
}
else
{
r1 = pt_print_bytes_l (parser, p->info.update_stats.class_list);
b = pt_append_varchar (parser, b, r1);
}
if (p->info.update_stats.with_fullscan > 0)
{
assert (p->info.update_stats.with_fullscan == STATS_WITH_FULLSCAN);
b = pt_append_nulstring (parser, b, " with fullscan");
}
return b;
}
/* GET_STATS */
/*
* pt_apply_get_stats () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_get_stats (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.get_stats.class_, arg);
PT_APPLY_WALK (parser, p->info.get_stats.args, arg);
PT_APPLY_WALK (parser, p->info.get_stats.into_var, arg);
return p;
}
/*
* pt_print_get_stats () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_get_stats (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1;
b = pt_append_nulstring (parser, b, "get statistics ");
if (p->info.get_stats.args)
{
r1 = pt_print_bytes (parser, p->info.get_stats.args);
b = pt_append_varchar (parser, b, r1);
}
if (p->info.get_stats.class_)
{
r1 = pt_print_bytes (parser, p->info.get_stats.class_);
b = pt_append_nulstring (parser, b, " on ");
b = pt_append_varchar (parser, b, r1);
}
if (p->info.get_stats.into_var)
{
r1 = pt_print_bytes (parser, p->info.get_stats.into_var);
b = pt_append_nulstring (parser, b, " into ");
b = pt_append_varchar (parser, b, r1);
}
return b;
}
#if defined (ENABLE_UNUSED_FUNCTION)
/* USE */
/*
* pt_apply_use () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_use (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.use.use_list, arg);
PT_APPLY_WALK (parser, p->info.use.exclude_list, arg);
return p;
}
/*
* pt_print_use () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_use (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1;
if (p->info.use.use_list)
{
r1 = pt_print_bytes_l (parser, p->info.use.use_list);
b = pt_append_nulstring (parser, b, "use ");
b = pt_append_varchar (parser, b, r1);
if (p->info.use.relative == PT_DEFAULT)
{
b = pt_append_nulstring (parser, b, " with default");
}
else if (p->info.use.relative == PT_CURRENT)
{
b = pt_append_nulstring (parser, b, " with current");
}
}
else if (p->info.use.exclude_list)
{
r1 = pt_print_bytes_l (parser, p->info.use.exclude_list);
b = pt_append_nulstring (parser, b, "exclude ");
b = pt_append_varchar (parser, b, r1);
if (p->info.use.relative == PT_DEFAULT)
{
b = pt_append_nulstring (parser, b, " from default");
}
else if (p->info.use.relative == PT_CURRENT)
{
b = pt_append_nulstring (parser, b, " from current");
}
}
else if (p->info.use.relative == PT_DEFAULT)
{
b = pt_append_nulstring (parser, b, "use default");
}
else
{
b = pt_append_nulstring (parser, b, "use all");
}
if (p->info.use.as_default)
{
b = pt_append_nulstring (parser, b, " as default");
}
return b;
}
#endif
/* VALUE */
/*
* pt_apply_value () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_value (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
switch (p->type_enum)
{
case PT_TYPE_SET:
case PT_TYPE_MULTISET:
case PT_TYPE_SEQUENCE:
PT_APPLY_WALK (parser, p->info.value.data_value.set, arg);
default:
break;
}
return p;
}
/*
* pt_init_value () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_value (PT_NODE * p)
{
p->info.value.host_var_index = -1;
return p;
}
/*
* pt_apply_set_session_variables () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_set_session_variables (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.set_variables.assignments, arg);
return p;
}
/*
* pt_print_set_session_variables () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_set_session_variables (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1 = NULL;
b = pt_append_nulstring (parser, b, "SET ");
r1 = pt_print_bytes_l (parser, p->info.set_variables.assignments);
b = pt_append_varchar (parser, b, r1);
return b;
}
/*
* pt_apply_drop_session_variables () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_drop_session_variables (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.drop_session_var.variables, arg);
return p;
}
/*
* pt_print_session_variables () - print a list of session variables
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_session_variables (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r = NULL;
if (!p)
{
return 0;
}
q = pt_append_nulstring (parser, q, "@");
r = pt_print_bytes (parser, p);
q = pt_append_varchar (parser, q, r);
while (p->next)
{ /* print in the original order ... */
p = p->next;
r = pt_print_bytes (parser, p);
if (r)
{
if (q)
{
q = pt_append_bytes (parser, q, ", ", 2);
}
q = pt_append_nulstring (parser, q, "@");
q = pt_append_varchar (parser, q, r);
}
}
return q;
}
/*
* pt_print_drop_session_variables () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_drop_session_variables (PARSER_CONTEXT * parser, PT_NODE * p)
{
PT_NODE *var = NULL;
PARSER_VARCHAR *b = NULL, *r1 = NULL;
b = pt_append_nulstring (parser, b, "DROP ");
var = p->info.drop_session_var.variables;
while (var)
{
r1 = pt_print_session_variables (parser, p->info.drop_session_var.variables);
}
b = pt_append_varchar (parser, b, r1);
return b;
}
/*
* pt_print_value () -
* return:
* parser(in):
* p(in):
*/
/*
* Note: The cached statements in the XASL cache are identified by their
* string representation (parser_print_tree ()). The strings can
* sometimes be identical even if constant literals or values types are
* different. For example "select 2;" can be same as "select 2;"
* regardless of the value's type (2 can be an integer, a float, a
* double, etc.). It is necessary to generate unique string
* representations of each pair <value, type_of_value>. The easiest fix
* is to wrap the literals in casts like this: "select cast (2 as int);"
* and "select cast (2 as float)". However, great care must be exercised
* when fixing this as the resulting string might be parsed again by our
* SQL parser (for example the strings in vclass definitions are parsed
* during view definition translation, see mq_translate ()).
* If a type ambiguity does occur, the XASL cache will return query
* results with unexpected types to the client.
*
* Printing charset introducer and COLLATE modifier of values.
* Four flags control the printing of charset and collate for strings:
* - PT_SUPPRESS_CHARSET_PRINT: when printing columns header in results
* - PT_SUPPRESS_COLLATE_PRINT: some string literals should not
* have COLLATE modifier: in ENUM definition, partition list or
* LIKE ESCAPE sequence
* - PT_CHARSET_COLLATE_FULL : printing of already compiled statement
* (view definition, index function or filter expression)
* - PT_CHARSET_COLLATE_USER_ONLY: printing of an uncompiled statement
* (in HA replication); it prints the statement exactly as the user
* input. This is mutually exclusive with PT_CHARSET_COLLATE_FULL.
*/
/* TODO Investigate the scenarios when this function prints ambiguous strings
* and fix the issue by either printing different strings or setting the
* print_type_ambiguity flag that disables the caching of the statement.
*/
static PARSER_VARCHAR *
pt_print_value (PARSER_CONTEXT * parser, PT_NODE * p)
{
DB_VALUE *val;
PARSER_VARCHAR *q = 0, *r1;
char s[PT_MEMB_PRINTABLE_BUF_SIZE];
const char *r;
int prt_coll_id = -1;
INTL_CODESET prt_cs = INTL_CODESET_NONE;
/* at first, check NULL value */
if (p->info.value.db_value_is_initialized)
{
val = pt_value_to_db (parser, p);
if (val)
{
if (DB_IS_NULL (val))
{
q = pt_append_nulstring (parser, q, pt_show_type_enum (PT_TYPE_NULL));
if ((parser->custom_print & PT_PRINT_ALIAS) && p->alias_print != NULL)
{
q = pt_append_nulstring (parser, q, " as [");
q = pt_append_nulstring (parser, q, p->alias_print);
q = pt_append_nulstring (parser, q, "]");
}
return q;
}
}
else
{
assert (false);
er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_GENERIC_ERROR, 0);
}
}
if (PT_HAS_COLLATION (p->type_enum))
{
prt_coll_id = (p->data_type != NULL) ? (p->data_type->info.data_type.collation_id) : LANG_SYS_COLLATION;
if ((p->info.value.print_collation == false
&& !(parser->custom_print & (PT_CHARSET_COLLATE_FULL | PT_CHARSET_COLLATE_USER_ONLY)))
|| (p->info.value.is_collate_allowed == false)
|| (prt_coll_id == LANG_SYS_COLLATION && (parser->custom_print & PT_SUPPRESS_CHARSET_PRINT))
|| (parser->custom_print & PT_CHARSET_COLLATE_USER_ONLY && !PT_HAS_COLLATION_MODIFIER (p)))
{
prt_coll_id = -1;
}
prt_cs = (p->data_type != NULL) ? (INTL_CODESET) (p->data_type->info.data_type.units) : LANG_SYS_CODESET;
/* do not print charset introducer for NCHAR and VARNCHAR */
if ((p->info.value.print_charset == false
&& !(parser->custom_print & (PT_CHARSET_COLLATE_FULL | PT_CHARSET_COLLATE_USER_ONLY)))
|| (p->type_enum != PT_TYPE_CHAR && p->type_enum != PT_TYPE_VARCHAR)
|| (prt_cs == LANG_SYS_CODESET && (parser->custom_print & PT_SUPPRESS_CHARSET_PRINT))
|| (parser->custom_print & PT_CHARSET_COLLATE_USER_ONLY && p->info.value.has_cs_introducer == false))
{
prt_cs = INTL_CODESET_NONE;
}
}
switch (p->type_enum)
{
case PT_TYPE_SET:
case PT_TYPE_MULTISET:
case PT_TYPE_SEQUENCE:
if (p->spec_ident || ((parser->custom_print & PT_PRINT_SUPPRESS_FOR_DBLINK) && p->flag.print_in_value_for_dblink))
{
/* this is tagged as an "in" clause right hand side Print it as a parenthesized list */
/* print_in_value_for_dblink is a flag as same meaning for dblink */
r1 = pt_print_bytes_l (parser, p->info.value.data_value.set);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
else
{
if (p->type_enum != PT_TYPE_SEQUENCE && !(parser->custom_print & PT_PRINT_SUPPRESS_FOR_DBLINK))
{
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
}
q = pt_append_nulstring (parser, q, "{");
if (p->info.value.data_value.set)
{
r1 = pt_print_bytes_l (parser, p->info.value.data_value.set);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, "}");
}
break;
case PT_TYPE_LOGICAL:
case PT_TYPE_FLOAT:
case PT_TYPE_DOUBLE:
case PT_TYPE_NUMERIC:
case PT_TYPE_INTEGER:
case PT_TYPE_BIGINT:
case PT_TYPE_SMALLINT:
if (p->info.value.text != NULL && !(parser->custom_print & PT_SUPPRESS_BIGINT_CAST))
{
r = p->info.value.text;
}
else
{
switch (p->type_enum)
{
case PT_TYPE_FLOAT:
sprintf (s, db_value_printer::DECIMAL_FORMAT, DB_FLOAT_DECIMAL_PRECISION, p->info.value.data_value.f);
break;
case PT_TYPE_DOUBLE:
sprintf (s, db_value_printer::DECIMAL_FORMAT, DB_DOUBLE_DECIMAL_PRECISION, p->info.value.data_value.d);
break;
case PT_TYPE_NUMERIC:
strcpy (s, (const char *) p->info.value.data_value.str->bytes);
break;
case PT_TYPE_INTEGER:
sprintf (s, "%ld", p->info.value.data_value.i);
break;
case PT_TYPE_BIGINT:
if (parser->custom_print & PT_SUPPRESS_BIGINT_CAST)
{
sprintf (s, "%lld", (long long) p->info.value.data_value.bigint);
}
else
{
sprintf (s, "cast(%lld as BIGINT)", (long long) p->info.value.data_value.bigint);
}
break;
case PT_TYPE_LOGICAL:
sprintf (s, "%ld <> 0", p->info.value.data_value.i);
break;
case PT_TYPE_SMALLINT:
sprintf (s, "%ld", p->info.value.data_value.i);
break;
default:
s[0] = '\0';
break;
}
r = s;
}
q = pt_append_nulstring (parser, q, r);
break;
case PT_TYPE_DATE:
case PT_TYPE_TIME:
case PT_TYPE_TIMESTAMP:
case PT_TYPE_TIMESTAMPTZ:
case PT_TYPE_TIMESTAMPLTZ:
case PT_TYPE_DATETIME:
case PT_TYPE_DATETIMETZ:
case PT_TYPE_DATETIMELTZ:
if (!(parser->custom_print & PT_PRINT_SUPPRESS_FOR_DBLINK))
{
if (p->info.value.text)
{
q = pt_append_nulstring (parser, q, p->info.value.text);
break;
}
}
r = (char *) p->info.value.data_value.str->bytes;
switch (p->type_enum)
{
case PT_TYPE_DATE:
q = pt_append_nulstring (parser, q, "date ");
break;
case PT_TYPE_TIME:
q = pt_append_nulstring (parser, q, "time ");
break;
case PT_TYPE_TIMESTAMP:
q = pt_append_nulstring (parser, q, "timestamp ");
break;
case PT_TYPE_TIMESTAMPTZ:
q = pt_append_nulstring (parser, q, "timestamptz ");
break;
case PT_TYPE_TIMESTAMPLTZ:
q = pt_append_nulstring (parser, q, "timestampltz ");
break;
case PT_TYPE_DATETIME:
q = pt_append_nulstring (parser, q, "datetime ");
break;
case PT_TYPE_DATETIMETZ:
q = pt_append_nulstring (parser, q, "datetimetz ");
break;
case PT_TYPE_DATETIMELTZ:
q = pt_append_nulstring (parser, q, "datetimeltz ");
break;
default:
break;
}
q = pt_append_string_prefix (parser, q, p);
q = pt_append_quoted_string (parser, q, r, ((r) ? strlen (r) : 0));
break;
case PT_TYPE_CHAR:
case PT_TYPE_BIT:
if (!(parser->custom_print & PT_PRINT_SUPPRESS_FOR_DBLINK))
{
if (p->info.value.text && prt_cs == INTL_CODESET_NONE && prt_coll_id == -1)
{
if (parser->flag.dont_prt_long_string && (strlen (p->info.value.text) >= DONT_PRT_LONG_STRING_LENGTH))
{
parser->flag.long_string_skipped = 1;
break;
}
q = pt_append_nulstring (parser, q, p->info.value.text);
break;
}
}
r1 = p->info.value.data_value.str;
if (parser->flag.dont_prt_long_string)
{
if (r1 && r1->length >= DONT_PRT_LONG_STRING_LENGTH)
{
parser->flag.long_string_skipped = 1;
break;
}
}
{
PT_NODE *dt;
PARSER_VARCHAR *tmp = NULL;
char s[PT_MEMB_BUF_SIZE];
tmp = pt_append_string_prefix (parser, tmp, p);
if (prt_cs != INTL_CODESET_NONE)
{
tmp = pt_append_nulstring (parser, tmp, lang_charset_introducer (prt_cs));
}
if (r1)
{
tmp = pt_append_quoted_string (parser, tmp, (char *) r1->bytes, r1->length);
}
else
{
tmp = pt_append_nulstring (parser, tmp, "''");
}
dt = p->data_type;
if (dt && dt->info.data_type.precision != TP_FLOATING_PRECISION_VALUE)
{
q = pt_append_nulstring (parser, q, "cast(");
q = pt_append_varchar (parser, q, tmp);
if (prt_coll_id != -1)
{
sprintf (s, " as %s(%d) collate %s)", pt_show_type_enum (p->type_enum), dt->info.data_type.precision,
lang_get_collation_name (prt_coll_id));
}
else
{
sprintf (s, " as %s(%d))", pt_show_type_enum (p->type_enum), dt->info.data_type.precision);
}
q = pt_append_nulstring (parser, q, s);
}
else
{
q = pt_append_varchar (parser, q, tmp);
if (prt_coll_id != -1)
{
q = pt_append_nulstring (parser, q, " collate ");
q = pt_append_nulstring (parser, q, lang_get_collation_name (prt_coll_id));
}
}
}
break;
case PT_TYPE_VARCHAR: /* have to check for embedded quotes */
case PT_TYPE_VARBIT:
if (!(parser->custom_print & PT_PRINT_SUPPRESS_FOR_DBLINK))
{
if (p->info.value.text && prt_cs == INTL_CODESET_NONE && prt_coll_id == -1)
{
if (parser->flag.dont_prt_long_string && (strlen (p->info.value.text) >= DONT_PRT_LONG_STRING_LENGTH))
{
parser->flag.long_string_skipped = 1;
break;
}
q = pt_append_nulstring (parser, q, p->info.value.text);
break;
}
}
r1 = p->info.value.data_value.str;
if (parser->flag.dont_prt_long_string)
{
if (r1 && r1->length >= DONT_PRT_LONG_STRING_LENGTH)
{
parser->flag.long_string_skipped = 1;
break;
}
}
q = pt_append_string_prefix (parser, q, p);
if (prt_cs != INTL_CODESET_NONE)
{
q = pt_append_nulstring (parser, q, lang_charset_introducer (prt_cs));
}
if (r1)
{
q = pt_append_quoted_string (parser, q, (const char *) r1->bytes, r1->length);
}
else
{
q = pt_append_nulstring (parser, q, "''");
}
if (prt_coll_id != -1)
{
q = pt_append_nulstring (parser, q, " collate ");
q = pt_append_nulstring (parser, q, lang_get_collation_name (prt_coll_id));
}
break;
case PT_TYPE_MONETARY:
if (parser->flag.dont_prt_long_string)
{
if (log10 (p->info.value.data_value.money.amount) >= DONT_PRT_LONG_STRING_LENGTH)
{
parser->flag.long_string_skipped = 1;
break;
}
}
{
PT_MONETARY *val;
val = &(p->info.value.data_value.money);
/* this string may be used for replication, so it must be parsable */
sprintf (s, "%s%.2f", intl_get_money_esc_ISO_symbol (pt_currency_to_db (val->type)), val->amount);
#if defined(HPUX)
/* workaround for HP's broken printf */
if (strstr (s, "++") || strstr (s, "--"))
#else /* HPUX */
if (strstr (s, "Inf"))
#endif /* HPUX */
{
sprintf (s, "%s%.2f", intl_get_money_esc_ISO_symbol (pt_currency_to_db (val->type)),
(val->amount > 0 ? DBL_MAX : -DBL_MAX));
}
q = pt_append_nulstring (parser, q, s);
if (pt_currency_to_db (val->type) == DB_CURRENCY_NULL)
{
parser->flag.print_type_ambiguity = 1;
}
}
break;
case PT_TYPE_BLOB:
case PT_TYPE_CLOB:
case PT_TYPE_NULL:
case PT_TYPE_NA:
case PT_TYPE_STAR: /* as in count (*) */
case PT_TYPE_OBJECT:
q = pt_append_nulstring (parser, q, pt_show_type_enum (p->type_enum));
break;
case PT_TYPE_ENUMERATION:
q = pt_append_string_prefix (parser, q, p);
if (p->info.value.data_value.enumeration.str_val)
{
/* prefer to print enumeration string value */
q =
pt_append_quoted_string (parser, q, (char *) p->info.value.data_value.enumeration.str_val->bytes,
p->info.value.data_value.enumeration.str_val->length);
if (prt_coll_id != -1)
{
q = pt_append_nulstring (parser, q, " collate ");
q = pt_append_nulstring (parser, q, lang_get_collation_name (prt_coll_id));
}
}
else
{
/* print index if it is a valid value */
sprintf (s, "%ld", p->info.value.data_value.i);
q = pt_append_nulstring (parser, q, s);
}
break;
case PT_TYPE_JSON:
assert (p->info.value.data_value.str != NULL);
q = pt_append_nulstring (parser, q, "json \'");
q = pt_append_nulstring (parser, q, (char *) p->info.value.data_value.str->bytes);
q = pt_append_nulstring (parser, q, "\'");
break;
default:
q = pt_append_nulstring (parser, q, "-- Unknown value type --");
parser->flag.print_type_ambiguity = 1;
break;
}
if ((parser->custom_print & PT_PRINT_ALIAS) && p->alias_print != NULL)
{
q = pt_append_nulstring (parser, q, " as [");
q = pt_append_nulstring (parser, q, p->alias_print);
q = pt_append_nulstring (parser, q, "]");
}
return q;
}
/* ZZ_ERROR_MSG */
/*
* pt_apply_error_msg () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_error_msg (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/*
* pt_print_error_msg () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_error_msg (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0;
char s[PT_MEMB_ERR_BUF_SIZE];
if (p->info.error_msg.statement_number > 0)
{
b = pt_append_nulstring (parser, b, "stmt=");
sprintf (s, "%d, ", p->info.error_msg.statement_number);
b = pt_append_nulstring (parser, b, s);
}
sprintf (s, "near line=%d", p->line_number);
b = pt_append_nulstring (parser, b, s);
if (p->column_number > 0)
{
sprintf (s, ", col=%d", p->column_number);
b = pt_append_nulstring (parser, b, s);
}
b = pt_append_nulstring (parser, b, ": ");
b = pt_append_nulstring (parser, b, p->info.error_msg.error_message);
return b;
}
/* CONSTRAINT */
/*
* pt_apply_constraint () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_constraint (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
switch (p->info.constraint.type)
{
case PT_CONSTRAIN_NULL:
case PT_CONSTRAIN_UNKNOWN:
break;
case PT_CONSTRAIN_PRIMARY_KEY:
PT_APPLY_WALK (parser, p->info.constraint.un.primary_key.attrs, arg);
break;
case PT_CONSTRAIN_FOREIGN_KEY:
PT_APPLY_WALK (parser, p->info.constraint.un.foreign_key.attrs, arg);
PT_APPLY_WALK (parser, p->info.constraint.un.foreign_key.referenced_class, arg);
PT_APPLY_WALK (parser, p->info.constraint.un.foreign_key.referenced_attrs, arg);
break;
case PT_CONSTRAIN_NOT_NULL:
PT_APPLY_WALK (parser, p->info.constraint.un.not_null.attr, arg);
break;
case PT_CONSTRAIN_UNIQUE:
PT_APPLY_WALK (parser, p->info.constraint.un.unique.attrs, arg);
break;
case PT_CONSTRAIN_CHECK:
PT_APPLY_WALK (parser, p->info.constraint.un.check.expr, arg);
break;
}
return p;
}
/*
* pt_init_constraint () -
* return:
* node(in):
*/
static PT_NODE *
pt_init_constraint (PT_NODE * node)
{
if (node)
{
node->info.constraint.type = PT_CONSTRAIN_UNKNOWN;
}
return node;
}
/*
* pt_print_col_def_constraint () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_col_def_constraint (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1, *r2;
assert (p->node_type == PT_CONSTRAINT);
assert (p->info.constraint.name == NULL);
switch (p->info.constraint.type)
{
case PT_CONSTRAIN_UNKNOWN:
assert (false);
break;
case PT_CONSTRAIN_PRIMARY_KEY:
b = pt_append_nulstring (parser, b, "primary key ");
break;
case PT_CONSTRAIN_FOREIGN_KEY:
r2 = pt_print_bytes (parser, p->info.constraint.un.foreign_key.referenced_class);
b = pt_append_nulstring (parser, b, "foreign key ");
b = pt_append_nulstring (parser, b, " references ");
b = pt_append_varchar (parser, b, r2);
b = pt_append_nulstring (parser, b, " ");
if (p->info.constraint.un.foreign_key.referenced_attrs)
{
r1 = pt_print_bytes_l (parser, p->info.constraint.un.foreign_key.referenced_attrs);
b = pt_append_nulstring (parser, b, "(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
}
if (p->info.constraint.un.foreign_key.match_type != PT_MATCH_REGULAR)
{
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.constraint.un.foreign_key.match_type));
b = pt_append_nulstring (parser, b, " ");
}
if (p->info.constraint.un.foreign_key.delete_action != PT_RULE_RESTRICT)
{
b = pt_append_nulstring (parser, b, "on delete ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.constraint.un.foreign_key.delete_action));
b = pt_append_nulstring (parser, b, " ");
}
if (p->info.constraint.un.foreign_key.update_action != PT_RULE_RESTRICT)
{
b = pt_append_nulstring (parser, b, "on update ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.constraint.un.foreign_key.update_action));
b = pt_append_nulstring (parser, b, " ");
}
break;
case PT_CONSTRAIN_NULL:
break;
case PT_CONSTRAIN_NOT_NULL:
/*
* Print nothing here. It is a duplicate of the "NOT NULL" printed for the column constraint. */
break;
case PT_CONSTRAIN_UNIQUE:
b = pt_append_nulstring (parser, b, "unique ");
break;
case PT_CONSTRAIN_CHECK:
r1 = pt_print_bytes (parser, p->info.constraint.un.check.expr);
b = pt_append_nulstring (parser, b, "check(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
break;
}
/*
* "NOT DEFERRABLE INITIALLY IMMEDIATE" is the default, so print
* nothing in that case. It's arguably safer to print the explicit
* info, but it's also likely to run afoul of SQL parsers that don't
* understand the full SQL2 jazz yet.
*/
if (p->info.constraint.deferrable)
{
b = pt_append_nulstring (parser, b, "deferrable ");
}
if (p->info.constraint.initially_deferred)
{
b = pt_append_nulstring (parser, b, "initially deferred ");
}
return b;
}
/*
* pt_print_constraint () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_constraint (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = 0, *r1, *r2;
if (p->info.constraint.name)
{
r1 = pt_print_bytes (parser, p->info.constraint.name);
b = pt_append_nulstring (parser, b, "constraint ");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, " ");
}
switch (p->info.constraint.type)
{
case PT_CONSTRAIN_UNKNOWN:
b = pt_append_nulstring (parser, b, "unknown ");
break;
case PT_CONSTRAIN_PRIMARY_KEY:
r1 = pt_print_bytes_l (parser, p->info.constraint.un.primary_key.attrs);
b = pt_append_nulstring (parser, b, "primary key (");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
break;
case PT_CONSTRAIN_FOREIGN_KEY:
r1 = pt_print_bytes_l (parser, p->info.constraint.un.foreign_key.attrs);
r2 = pt_print_bytes (parser, p->info.constraint.un.foreign_key.referenced_class);
b = pt_append_nulstring (parser, b, "foreign key (");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") references ");
b = pt_append_varchar (parser, b, r2);
b = pt_append_nulstring (parser, b, " ");
if (p->info.constraint.un.foreign_key.referenced_attrs)
{
r1 = pt_print_bytes_l (parser, p->info.constraint.un.foreign_key.referenced_attrs);
b = pt_append_nulstring (parser, b, "(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
}
if (p->info.constraint.un.foreign_key.match_type != PT_MATCH_REGULAR)
{
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.constraint.un.foreign_key.match_type));
b = pt_append_nulstring (parser, b, " ");
}
if (p->info.constraint.un.foreign_key.delete_action != PT_RULE_RESTRICT)
{
b = pt_append_nulstring (parser, b, "on delete ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.constraint.un.foreign_key.delete_action));
b = pt_append_nulstring (parser, b, " ");
}
if (p->info.constraint.un.foreign_key.update_action != PT_RULE_RESTRICT)
{
b = pt_append_nulstring (parser, b, "on update ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (p->info.constraint.un.foreign_key.update_action));
b = pt_append_nulstring (parser, b, " ");
}
break;
case PT_CONSTRAIN_NULL:
break;
case PT_CONSTRAIN_NOT_NULL:
/*
* Print nothing here. It is a duplicate of the "NOT NULL" printed for the column constraint. */
break;
case PT_CONSTRAIN_UNIQUE:
r1 = pt_print_bytes_l (parser, p->info.constraint.un.unique.attrs);
b = pt_append_nulstring (parser, b, "unique(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
break;
case PT_CONSTRAIN_CHECK:
r1 = pt_print_bytes (parser, p->info.constraint.un.check.expr);
b = pt_append_nulstring (parser, b, "check(");
b = pt_append_varchar (parser, b, r1);
b = pt_append_nulstring (parser, b, ") ");
break;
}
/*
* "NOT DEFERRABLE INITIALLY IMMEDIATE" is the default, so print
* nothing in that case. It's arguably safer to print the explicit
* info, but it's also likely to run afoul of SQL parsers that don't
* understand the full SQL2 jazz yet.
*/
if (p->info.constraint.deferrable)
{
b = pt_append_nulstring (parser, b, "deferrable ");
}
if (p->info.constraint.initially_deferred)
{
b = pt_append_nulstring (parser, b, "initially deferred ");
}
if (p->info.constraint.comment)
{
r1 = pt_print_bytes (parser, p->info.constraint.comment);
b = pt_append_nulstring (parser, b, " comment ");
b = pt_append_varchar (parser, b, r1);
}
return b;
}
/* POINTER */
/*
* pt_apply_pointer () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_pointer (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
if (p->info.pointer.do_walk)
{
PT_APPLY_WALK (parser, p->info.pointer.node, arg);
}
return p;
}
/*
* pt_init_pointer () -
* return:
* node(in):
*/
static PT_NODE *
pt_init_pointer (PT_NODE * node)
{
if (node)
{
node->info.pointer.type = PT_POINTER_NORMAL;
node->info.pointer.do_walk = true;
}
return node;
}
/*
* pt_print_pointer () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_pointer (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL;
if (p)
{
b = pt_print_bytes_alias (parser, p->info.pointer.node);
}
return b;
}
/*
* pt_apply_node_list () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_node_list (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.node_list.list, arg);
return p;
}
/*
* pt_init_node_list () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_node_list (PT_NODE * p)
{
p->info.node_list.list_type = (PT_MISC_TYPE) 0;
return p;
}
/*
* pt_print_node_list () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_node_list (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = pt_print_bytes_l (parser, p->info.node_list.list);
return b;
}
/* MERGE STATEMENT */
/*
* pt_apply_merge () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_merge (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.merge.into, arg);
PT_APPLY_WALK (parser, p->info.merge.using_clause, arg);
PT_APPLY_WALK (parser, p->info.merge.search_cond, arg);
PT_APPLY_WALK (parser, p->info.merge.insert.attr_list, arg);
PT_APPLY_WALK (parser, p->info.merge.insert.value_clauses, arg);
PT_APPLY_WALK (parser, p->info.merge.insert.search_cond, arg);
PT_APPLY_WALK (parser, p->info.merge.insert.class_where, arg);
PT_APPLY_WALK (parser, p->info.merge.update.assignment, arg);
PT_APPLY_WALK (parser, p->info.merge.update.search_cond, arg);
PT_APPLY_WALK (parser, p->info.merge.update.del_search_cond, arg);
PT_APPLY_WALK (parser, p->info.merge.check_where, arg);
PT_APPLY_WALK (parser, p->info.merge.waitsecs_hint, arg);
return p;
}
/*
* pt_init_merge () -
* return:
* p(in):
*/
static PT_NODE *
pt_init_merge (PT_NODE * p)
{
p->info.merge.hint = PT_HINT_NONE;
return p;
}
/*
* pt_print_merge () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_merge (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r1;
PT_NODE_LIST_INFO *list_info = NULL;
q = pt_append_nulstring (parser, q, "merge ");
if (p->info.merge.hint != PT_HINT_NONE)
{
q = pt_append_nulstring (parser, q, "/*+");
if (p->info.merge.hint & PT_HINT_LK_TIMEOUT && p->info.merge.waitsecs_hint)
{
q = pt_append_nulstring (parser, q, " LOCK_TIMEOUT(");
r1 = pt_print_bytes (parser, p->info.merge.waitsecs_hint);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
if (p->info.merge.hint & PT_HINT_NO_LOGGING)
{
q = pt_append_nulstring (parser, q, " NO_LOGGING");
}
if (p->info.merge.hint & PT_HINT_USE_UPDATE_IDX)
{
q = pt_append_nulstring (parser, q, " USE_UPDATE_IDX(");
r1 = pt_print_bytes (parser, p->info.merge.update.index_hint);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
if (p->info.merge.hint & PT_HINT_USE_INSERT_IDX)
{
q = pt_append_nulstring (parser, q, " USE_INSERT_IDX(");
r1 = pt_print_bytes (parser, p->info.merge.insert.index_hint);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
}
if (p->info.merge.hint & PT_HINT_NO_USE_HASH)
{
/* disable hash-join */
q = pt_append_nulstring (parser, q, " NO_USE_HASH");
if (p->info.merge.no_use_hash)
{
r1 = pt_print_bytes_l (parser, p->info.merge.no_use_hash);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
if (p->info.merge.hint & PT_HINT_USE_HASH)
{
/* force hash-join */
q = pt_append_nulstring (parser, q, " USE_HASH");
if (p->info.merge.use_hash)
{
r1 = pt_print_bytes_l (parser, p->info.merge.use_hash);
q = pt_append_nulstring (parser, q, "(");
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
else
{
q = pt_append_nulstring (parser, q, " ");
}
}
q = pt_append_nulstring (parser, q, " */");
}
q = pt_append_nulstring (parser, q, " into ");
r1 = pt_print_bytes_spec_list (parser, p->info.merge.into);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " using ");
r1 = pt_print_bytes_spec_list (parser, p->info.merge.using_clause);
q = pt_append_varchar (parser, q, r1);
if (p->info.merge.search_cond)
{
q = pt_append_nulstring (parser, q, " on ");
r1 = pt_print_and_list (parser, p->info.merge.search_cond);
q = pt_append_varchar (parser, q, r1);
}
if (p->info.merge.update.assignment)
{
q = pt_append_nulstring (parser, q, " when matched then update set ");
r1 = pt_print_bytes_l (parser, p->info.merge.update.assignment);
q = pt_append_varchar (parser, q, r1);
if (p->info.merge.update.search_cond)
{
q = pt_append_nulstring (parser, q, " where ");
r1 = pt_print_and_list (parser, p->info.merge.update.search_cond);
q = pt_append_varchar (parser, q, r1);
}
if (p->info.merge.update.has_delete)
{
q = pt_append_nulstring (parser, q, " delete where ");
if (p->info.merge.update.del_search_cond)
{
r1 = pt_print_and_list (parser, p->info.merge.update.del_search_cond);
q = pt_append_varchar (parser, q, r1);
}
else
{
q = pt_append_nulstring (parser, q, "(true)");
}
}
}
if (p->info.merge.insert.value_clauses)
{
q = pt_append_nulstring (parser, q, " when not matched then insert ");
if (p->info.merge.insert.attr_list)
{
q = pt_append_nulstring (parser, q, "(");
r1 = pt_print_bytes_l (parser, p->info.merge.insert.attr_list);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
list_info = &p->info.merge.insert.value_clauses->info.node_list;
if (list_info->list_type == PT_IS_DEFAULT_VALUE)
{
q = pt_append_nulstring (parser, q, "default values ");
}
else
{
q = pt_append_nulstring (parser, q, "values (");
r1 = pt_print_bytes_l (parser, list_info->list);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ") ");
}
if (p->info.merge.insert.search_cond)
{
q = pt_append_nulstring (parser, q, "where ");
r1 = pt_print_and_list (parser, p->info.merge.insert.search_cond);
q = pt_append_varchar (parser, q, r1);
}
}
return q;
}
/*
* pt_apply_tuple_value ()
* return :
* parser (in) :
* p (in) :
* g (in) :
* arg (in) :
*/
static PT_NODE *
pt_apply_tuple_value (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.tuple_value.name, arg);
return p;
}
/*
* pt_init_tuple_value ()
* return :
* p (in) :
*/
static PT_NODE *
pt_init_tuple_value (PT_NODE * p)
{
p->info.tuple_value.index = -1;
return p;
}
/*
* pt_print_tuple_value ()
* return :
* parser (in) :
* p (in) :
*/
static PARSER_VARCHAR *
pt_print_tuple_value (PARSER_CONTEXT * parser, PT_NODE * p)
{
if (p->info.tuple_value.name == NULL)
{
assert (false);
return pt_append_bytes (parser, NULL, "unknown", 0);
}
return pt_print_name (parser, p->info.tuple_value.name);
}
/*
* pt_apply_insert_value ()
* return :
* parser (in) :
* p (in) :
* g (in) :
* arg (in) :
*/
static PT_NODE *
pt_apply_insert_value (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.insert_value.original_node, arg);
return p;
}
static PT_NODE *
pt_apply_kill (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/*
* pt_init_insert_value ()
* return :
* p (in) :
*/
static PT_NODE *
pt_init_insert_value (PT_NODE * p)
{
db_make_null (&p->info.insert_value.value);
return p;
}
static PT_NODE *
pt_init_kill (PT_NODE * p)
{
p->info.killstmt.kill_type = KILLSTMT_TRAN;
return p;
}
/* WITH CLAUSE */
/*
* pt_apply_with_clause () -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_with_clause (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.with_clause.cte_definition_list, arg);
return p;
}
/* CTE */
/*
* pt_apply_cte() -
* return:
* parser(in):
* p(in):
* g(in):
* arg(in):
*/
static PT_NODE *
pt_apply_cte (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.cte.non_recursive_part, arg);
PT_APPLY_WALK (parser, p->info.cte.recursive_part, arg);
return p;
}
/*
* pt_print_insert_value ()
* return :
* parser (in) :
* p (in) :
*/
static PARSER_VARCHAR *
pt_print_insert_value (PARSER_CONTEXT * parser, PT_NODE * p)
{
/* The original_node is HOST_VAR type. Use custom print to avoid printing HOST_VAR. */
if (parser->custom_print & PT_PRINT_DB_VALUE)
{
return pt_print_db_value (parser, &p->info.insert_value.value);
}
if (p->info.insert_value.original_node != NULL)
{
return pt_print_bytes_l (parser, p->info.insert_value.original_node);
}
else
{
assert (false);
return NULL;
}
}
/*
* pt_print_with_clause ()
* return :
* parser (in) :
* p (in) :
*/
static PARSER_VARCHAR *
pt_print_with_clause (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL;
PT_NODE *cte;
bool first_cte = true;
q = pt_append_nulstring (parser, q, "with ");
if (p->info.with_clause.recursive)
{
q = pt_append_nulstring (parser, q, "recursive ");
}
for (cte = p->info.with_clause.cte_definition_list; cte != NULL; cte = cte->next)
{
PARSER_VARCHAR *r = pt_print_cte (parser, cte);
if (!first_cte)
{
q = pt_append_nulstring (parser, q, ", ");
}
q = pt_append_varchar (parser, q, r);
first_cte = false;
}
return q;
}
/*
* pt_print_with_cte ()
* return :
* parser (in) :
* p (in) :
*/
static PARSER_VARCHAR *
pt_print_cte (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
/* name of cte */
r1 = pt_print_bytes_l (parser, p->info.cte.name);
q = pt_append_varchar (parser, q, r1);
/* attribute list */
q = pt_append_nulstring (parser, q, "(");
r1 = pt_print_bytes_l (parser, p->info.cte.as_attr_list);
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ")");
/* AS keyword */
q = pt_append_nulstring (parser, q, " as ");
/* cte definition */
q = pt_append_nulstring (parser, q, "(");
r1 = pt_print_bytes_l (parser, p->info.cte.non_recursive_part);
q = pt_append_varchar (parser, q, r1);
if (p->info.cte.recursive_part)
{
q = pt_append_nulstring (parser, q, " union ");
if (p->info.cte.only_all == PT_ALL)
{
q = pt_append_nulstring (parser, q, "all ");
}
r1 = pt_print_bytes_l (parser, p->info.cte.recursive_part);
q = pt_append_varchar (parser, q, r1);
}
q = pt_append_nulstring (parser, q, ")");
return q;
}
/*
* pt_apply_named_arg ()
* return :
* parser (in) :
* p (in) :
* g (in) :
* arg (in) :
*/
static PT_NODE *
pt_apply_named_arg (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.named_arg.name, arg);
PT_APPLY_WALK (parser, p->info.named_arg.value, arg);
return p;
}
/*
* pt_print_named_arg ()
* return :
* parser (in) :
* p (in) :
*/
static PARSER_VARCHAR *
pt_print_named_arg (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *res = pt_print_bytes (parser, p->info.named_arg.name);
PARSER_VARCHAR *v = pt_print_bytes (parser, p->info.named_arg.value);
res = pt_append_nulstring (parser, res, " = ");
res = pt_append_varchar (parser, res, v);
return res;
}
/*
* pt_print_index_columns () -
* return:
* parser(in):
* p(in):
*/
static PARSER_VARCHAR *
pt_print_index_columns (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL, *r1;
int list_size = 0, i;
PT_NODE *q = NULL;
if (p->info.index.function_expr == NULL)
{
/* normal index */
b = pt_print_bytes_l (parser, p->info.index.column_names);
}
else
{
/* function index */
q = p->info.index.column_names;
while (q != NULL)
{
list_size++;
q = q->next;
}
q = p->info.index.column_names;
for (i = 0; i < p->info.index.func_pos && q != NULL; i++)
{
r1 = pt_print_bytes (parser, q);
r1 = pt_append_bytes (parser, r1, ", ", 2);
b = pt_append_varchar (parser, b, r1);
q = q->next;
}
/* print function expression */
r1 = pt_print_bytes (parser, p->info.index.function_expr);
if (q && i < list_size - p->info.index.func_no_args)
{
r1 = pt_append_bytes (parser, r1, ", ", 2);
}
b = pt_append_varchar (parser, b, r1);
/* do not print the function arguments again */
for (i = p->info.index.func_pos; i < list_size - p->info.index.func_no_args && q != NULL; i++)
{
r1 = pt_print_bytes (parser, q);
if (q->next && i < list_size - p->info.index.func_no_args - 1)
{
r1 = pt_append_bytes (parser, r1, ", ", 2);
}
b = pt_append_varchar (parser, b, r1);
q = q->next;
}
}
return b;
}
/*
* parser_init_func_vectors () -
* return:
* parser_init_func_vectors(in):
*/
void
parser_init_func_vectors (void)
{
if (!pt_apply_f)
{
pt_init_apply_f ();
}
if (!pt_init_f)
{
pt_init_init_f ();
}
if (!pt_print_f)
{
pt_init_print_f ();
}
}
/*
* pt_is_const_expr_node () :
* return:
* node (in):
*/
bool
pt_is_const_expr_node (PT_NODE * node)
{
if (node == NULL)
{
return false;
}
switch (node->node_type)
{
case PT_VALUE:
case PT_HOST_VAR:
return true;
case PT_NAME:
if (node->info.name.meta_class == PT_PARAMETER)
{
return true;
}
else
{
return false;
}
case PT_EXPR:
switch (node->info.expr.op)
{
case PT_FUNCTION_HOLDER:
{
bool const_function_holder = false;
PT_NODE *function = node->info.expr.arg1;
PT_NODE *f_arg = function->info.function.arg_list;
/* FUNCTION is const if all arguments of FUNCTION are constant */
const_function_holder = true;
while (f_arg != NULL)
{
if (pt_is_const_expr_node (f_arg) == false)
{
const_function_holder = false;
break;
}
f_arg = f_arg->next;
}
return const_function_holder;
}
break;
case PT_PLUS:
case PT_STRCAT:
case PT_MINUS:
case PT_TIMES:
case PT_DIVIDE:
case PT_BIT_AND:
case PT_BIT_OR:
case PT_BIT_XOR:
case PT_BITSHIFT_LEFT:
case PT_BITSHIFT_RIGHT:
case PT_DIV:
case PT_MOD:
case PT_LEFT:
case PT_RIGHT:
case PT_STRCMP:
case PT_EQ:
case PT_NE:
case PT_GE:
case PT_GT:
case PT_LT:
case PT_LE:
case PT_NULLSAFE_EQ:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& pt_is_const_expr_node (node->info.expr.arg2)) ? true : false;
case PT_UNARY_MINUS:
case PT_BIT_NOT:
case PT_BIT_COUNT:
return pt_is_const_expr_node (node->info.expr.arg1);
case PT_MODULUS:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& pt_is_const_expr_node (node->info.expr.arg2)) ? true : false;
case PT_PI:
case PT_ROW_COUNT:
case PT_DEFAULTF:
case PT_OID_OF_DUPLICATE_KEY:
case PT_SCHEMA_DEF:
return true;
case PT_FLOOR:
case PT_CEIL:
case PT_SIGN:
case PT_ABS:
case PT_CHR:
case PT_EXP:
case PT_SQRT:
case PT_ACOS:
case PT_ASIN:
case PT_ATAN:
case PT_COS:
case PT_SIN:
case PT_TAN:
case PT_COT:
case PT_DEGREES:
case PT_RADIANS:
case PT_LN:
case PT_LOG2:
case PT_LOG10:
case PT_DATEF:
case PT_TIMEF:
return pt_is_const_expr_node (node->info.expr.arg1);
case PT_POWER:
case PT_ROUND:
case PT_TRUNC:
case PT_LOG:
case PT_DATEDIFF:
case PT_TIMEDIFF:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& pt_is_const_expr_node (node->info.expr.arg2)) ? true : false;
case PT_INSTR:
case PT_CONV:
return (pt_is_const_expr_node (node->info.expr.arg1) && pt_is_const_expr_node (node->info.expr.arg2)
&& pt_is_const_expr_node (node->info.expr.arg3)) ? true : false;
case PT_POSITION:
case PT_FINDINSET:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& pt_is_const_expr_node (node->info.expr.arg2)) ? true : false;
case PT_SUBSTRING_INDEX:
case PT_SUBSTRING:
case PT_LOCATE:
return (pt_is_const_expr_node (node->info.expr.arg1) && pt_is_const_expr_node (node->info.expr.arg2)
&& (node->info.expr.arg3 ? pt_is_const_expr_node (node->info.expr.arg3) : true)) ? true : false;
case PT_CHAR_LENGTH:
case PT_OCTET_LENGTH:
case PT_BIT_LENGTH:
case PT_LOWER:
case PT_UPPER:
case PT_HEX:
case PT_ASCII:
case PT_BIN:
case PT_MD5:
case PT_SHA_ONE:
case PT_REVERSE:
case PT_DISK_SIZE:
case PT_TO_BASE64:
case PT_FROM_BASE64:
case PT_TZ_OFFSET:
case PT_CRC32:
case PT_CONV_TZ:
return pt_is_const_expr_node (node->info.expr.arg1);
case PT_TRIM:
case PT_LTRIM:
case PT_RTRIM:
case PT_LIKE_LOWER_BOUND:
case PT_LIKE_UPPER_BOUND:
case PT_FROM_UNIXTIME:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& (node->info.expr.arg2 ? pt_is_const_expr_node (node->info.expr.arg2) : true)) ? true : false;
case PT_LPAD:
case PT_RPAD:
case PT_REPLACE:
case PT_TRANSLATE:
case PT_INDEX_PREFIX:
return (pt_is_const_expr_node (node->info.expr.arg1) && pt_is_const_expr_node (node->info.expr.arg2)
&& (node->info.expr.arg3 ? pt_is_const_expr_node (node->info.expr.arg3) : true)) ? true : false;
case PT_ADD_MONTHS:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& pt_is_const_expr_node (node->info.expr.arg2)) ? true : false;
case PT_LAST_DAY:
return pt_is_const_expr_node (node->info.expr.arg1);
case PT_UNIX_TIMESTAMP:
if (node->info.expr.arg1)
{
return pt_is_const_expr_node (node->info.expr.arg1);
}
else
{
return true;
}
case PT_MONTHS_BETWEEN:
case PT_TIME_FORMAT:
case PT_TIMESTAMP:
if (node->info.expr.arg2)
{
return (pt_is_const_expr_node (node->info.expr.arg1)
&& pt_is_const_expr_node (node->info.expr.arg2)) ? true : false;
}
else
{
return (pt_is_const_expr_node (node->info.expr.arg1)) ? true : false;
}
case PT_YEARF:
case PT_MONTHF:
case PT_DAYF:
case PT_DAYOFMONTH:
case PT_HOURF:
case PT_MINUTEF:
case PT_SECONDF:
case PT_QUARTERF:
case PT_WEEKDAY:
case PT_DAYOFWEEK:
case PT_DAYOFYEAR:
case PT_TODAYS:
case PT_FROMDAYS:
case PT_TIMETOSEC:
case PT_SECTOTIME:
case PT_TO_ENUMERATION_VALUE:
return (pt_is_const_expr_node (node->info.expr.arg1)) ? true : false;
case PT_SCHEMA:
case PT_DATABASE:
case PT_VERSION:
return true;
case PT_ATAN2:
case PT_FORMAT:
case PT_ADDDATE:
case PT_DATE_ADD:
case PT_SUBDATE:
case PT_DATE_SUB:
case PT_DATE_FORMAT:
case PT_STR_TO_DATE:
case PT_REPEAT:
case PT_MAKEDATE:
case PT_ADDTIME:
case PT_WEEKF:
case PT_AES_ENCRYPT:
case PT_AES_DECRYPT:
case PT_SHA_TWO:
case PT_FROM_TZ:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& pt_is_const_expr_node (node->info.expr.arg2)) ? true : false;
case PT_SYS_DATE:
case PT_CURRENT_DATE:
case PT_SYS_TIME:
case PT_CURRENT_TIME:
case PT_SYS_TIMESTAMP:
case PT_CURRENT_TIMESTAMP:
case PT_SYS_DATETIME:
case PT_CURRENT_DATETIME:
case PT_UTC_TIME:
case PT_UTC_DATE:
case PT_LOCAL_TRANSACTION_ID:
case PT_CURRENT_USER:
case PT_USER:
case PT_LIST_DBS:
case PT_DBTIMEZONE:
case PT_SESSIONTIMEZONE:
case PT_UTC_TIMESTAMP:
return true;
case PT_TO_CHAR:
case PT_TO_DATE:
case PT_TO_TIME:
case PT_TO_TIMESTAMP:
case PT_TO_DATETIME:
case PT_TO_NUMBER:
case PT_TO_DATETIME_TZ:
case PT_TO_TIMESTAMP_TZ:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& (node->info.expr.arg2 ? pt_is_const_expr_node (node->info.expr.arg2) : true)) ? true : false;
case PT_CURRENT_VALUE:
case PT_NEXT_VALUE:
return true;
case PT_CAST:
return pt_is_const_expr_node (node->info.expr.arg1);
case PT_CASE:
case PT_DECODE:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& pt_is_const_expr_node (node->info.expr.arg2)) ? true : false;
case PT_IF:
return (pt_is_const_expr_node (node->info.expr.arg2)
&& pt_is_const_expr_node (node->info.expr.arg3)) ? true : false;
case PT_IFNULL:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& pt_is_const_expr_node (node->info.expr.arg2)) ? true : false;
case PT_ISNULL:
return pt_is_const_expr_node (node->info.expr.arg1);
case PT_CONCAT:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& (node->info.expr.arg2 ? pt_is_const_expr_node (node->info.expr.arg2) : true)) ? true : false;
case PT_CONCAT_WS:
case PT_FIELD:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& (node->info.expr.arg2 ? pt_is_const_expr_node (node->info.expr.arg2) : true)
&& pt_is_const_expr_node (node->info.expr.arg3)) ? true : false;
case PT_NULLIF:
case PT_COALESCE:
case PT_NVL:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& pt_is_const_expr_node (node->info.expr.arg2)) ? true : false;
case PT_NVL2:
case PT_MID:
case PT_MAKETIME:
case PT_NEW_TIME:
return (pt_is_const_expr_node (node->info.expr.arg1) && pt_is_const_expr_node (node->info.expr.arg2)
&& pt_is_const_expr_node (node->info.expr.arg3)) ? true : false;
case PT_EXTRACT:
return pt_is_const_expr_node (node->info.expr.arg1);
case PT_LEAST:
case PT_GREATEST:
return (pt_is_const_expr_node (node->info.expr.arg1)
&& pt_is_const_expr_node (node->info.expr.arg2)) ? true : false;
case PT_INET_ATON:
case PT_INET_NTOA:
case PT_CHARSET:
case PT_COLLATION:
return pt_is_const_expr_node (node->info.expr.arg1);
case PT_COERCIBILITY:
/* coercibility is always folded to constant */
assert (false);
case PT_WIDTH_BUCKET:
return (pt_is_const_expr_node (node->info.expr.arg1) && pt_is_const_expr_node (node->info.expr.arg2)
&& pt_is_const_expr_node (node->info.expr.arg3));
default:
return false;
}
default:
return false;
}
return false;
}
/*
* pt_is_ascii_string_value_node () -
* return: whether the node is a non-national string value (CHAR or VARCHAR)
* node(in):
*/
bool
pt_is_ascii_string_value_node (const PT_NODE * const node)
{
return (PT_IS_VALUE_NODE (node) && PT_IS_CHAR_STRING_TYPE (node->type_enum));
}
/*
* pt_restore_assignment_links - restore assignments links after a call to
* get_assignments_lists.
* return:
* assigns(in): first node of original assignment list
* links(in): The links array returned by get_assignment lists
* count(in): count of links in links array. This is used in
* get_assignments_lists if an error occurs. If this is -1 then just iterate
* through assignments list while restoring it, until the next statement is
* NULL.
*
* Note:
* The links array is freed
*/
void
pt_restore_assignment_links (PT_NODE * assigns, PT_NODE ** links, int count)
{
PT_NODE *lhs = NULL, *rhs = NULL, *att = NULL;
int links_idx = 0;
while (assigns && (links_idx < count || count == -1))
{
lhs = assigns->info.expr.arg1;
rhs = assigns->info.expr.arg2;
if (lhs->node_type == PT_NAME)
{
lhs->next = links[links_idx++];
if (links_idx < count || count == -1)
{
rhs->next = links[links_idx++];
}
}
else
{ /* PT_IS_N_COLUMN_UPDATE_EXPR(lhs) == true */
lhs = lhs->info.expr.arg1;
for (att = lhs; att && (links_idx < count || count == -1); att = att->next)
{
att->next = links[links_idx++];
}
rhs->next = links[links_idx++];
}
assigns = assigns->next;
}
/* free links array */
if (links)
{
db_private_free (NULL, links);
}
}
/*
* pt_get_assignment_lists - Returns corresponding lists of names and
* expressions
* return: Error code
* parser(in): Parser context
* select_names(out):
* select_values(out):
* const_names(out):
* const_values(out):
* assign(in): Parse tree of assignment lists
*
* Note:
*/
int
pt_get_assignment_lists (PARSER_CONTEXT * parser, PT_NODE ** select_names, PT_NODE ** select_values,
PT_NODE ** const_names, PT_NODE ** const_values, int *no_vals, int *no_consts,
PT_NODE * assign, PT_NODE *** old_links)
{
#define ASSIGN_LINKS_EXTENT 10
int error = NO_ERROR;
int links_chunk = ASSIGN_LINKS_EXTENT, links_alloc = ASSIGN_LINKS_EXTENT;
int links_idx = 0;
PT_NODE *lhs, *rhs, *att;
PT_NODE **links, **new_links;
links = (PT_NODE **) db_private_alloc (NULL, links_alloc * sizeof (PT_NODE *));
if (!links)
{
error = ER_OUT_OF_VIRTUAL_MEMORY;
goto exit_on_error;
}
if (!select_names || !select_values || !const_names || !const_values || !no_vals || !no_consts)
{
/* bullet proofing, should not get here */
#if defined(CUBRID_DEBUG)
fprintf (stdout, "system error detected in %s, line %d.\n", __FILE__, __LINE__);
#endif
error = ER_GENERIC_ERROR;
goto exit_on_error;
}
*select_names = *select_values = *const_names = *const_values = NULL;
*no_vals = *no_consts = 0;
while (assign)
{
if (assign->node_type != PT_EXPR || assign->info.expr.op != PT_ASSIGN || !(lhs = assign->info.expr.arg1)
|| !(rhs = assign->info.expr.arg2) || !(lhs->node_type == PT_NAME || PT_IS_N_COLUMN_UPDATE_EXPR (lhs)))
{
/* bullet proofing, should not get here */
#if defined(CUBRID_DEBUG)
fprintf (stdout, "system error detected in %s, line %d.\n", __FILE__, __LINE__);
#endif
error = ER_GENERIC_ERROR;
goto exit_on_error;
}
if (lhs->node_type == PT_NAME)
{
/* allocate more space if needed */
if (links_idx >= links_alloc)
{
links_alloc += links_chunk;
new_links = (PT_NODE **) db_private_realloc (NULL, links, links_alloc * sizeof (PT_NODE *));
if (new_links == NULL)
{
error = ER_OUT_OF_VIRTUAL_MEMORY;
goto exit_on_error;
}
links = new_links;
}
links[links_idx++] = lhs->next;
links[links_idx++] = rhs->next;
++(*no_vals);
}
else
{ /* PT_IS_N_COLUMN_UPDATE_EXPR(lhs) == true */
lhs = lhs->info.expr.arg1;
for (att = lhs; att; att = att->next)
{
if (att->node_type != PT_NAME)
{
#if defined(CUBRID_DEBUG)
fprintf (stdout, "system error detected in %s, line %d.\n", __FILE__, __LINE__);
#endif
error = ER_GENERIC_ERROR;
goto exit_on_error;
}
/* allocate more space if needed */
if (links_idx >= links_alloc)
{
links_alloc += links_chunk;
new_links = (PT_NODE **) db_private_realloc (NULL, links, links_alloc * sizeof (PT_NODE *));
if (new_links == NULL)
{
error = ER_OUT_OF_VIRTUAL_MEMORY;
goto exit_on_error;
}
links = new_links;
}
links[links_idx++] = att->next;
++(*no_vals);
}
/* allocate more space if needed */
if (links_idx >= links_alloc)
{
links_alloc += links_chunk;
new_links = (PT_NODE **) db_private_realloc (NULL, links, links_alloc * sizeof (PT_NODE *));
if (new_links == NULL)
{
error = ER_OUT_OF_VIRTUAL_MEMORY;
goto exit_on_error;
}
links = new_links;
}
links[links_idx++] = rhs->next;
}
if (!PT_IS_CONST_NOT_HOSTVAR (rhs))
{
/* assume evaluation needed. */
if (*select_names == NULL)
{
*select_names = lhs;
*select_values = rhs;
}
else
{
parser_append_node (lhs, *select_names);
parser_append_node (rhs, *select_values);
}
}
else
{
++(*no_consts);
/* we already have a constant value */
if (*const_names == NULL)
{
*const_names = lhs;
*const_values = rhs;
}
else
{
parser_append_node (lhs, *const_names);
parser_append_node (rhs, *const_values);
}
}
assign = assign->next;
}
*old_links = links;
return error;
exit_on_error:
if (links != NULL)
{
pt_restore_assignment_links (assign, links, links_idx);
}
*old_links = NULL;
return error;
}
/*
* pt_function_index_skip_expr () - Some expressions should not be counted in
* the pt_is_nested_expr test as functions (e.g. cast expression).
* as a consequence, these expressions should be also skipped
* when the column names are searched (e.g. in lookup_node()).
*
* return : The node that needs to be verified after skipping expressions
* node(in) : Function index expression
*/
PT_NODE *
pt_function_index_skip_expr (PT_NODE * node)
{
if (node == NULL || !PT_IS_EXPR_NODE (node))
{
/* do nothing */
return node;
}
switch (node->info.expr.op)
{
case PT_CAST:
case PT_UNARY_MINUS:
return pt_function_index_skip_expr (node->info.expr.arg1);
default:
return node;
}
}
/*
* pt_is_nested_expr () : checks if the given PT_NODE is a complex
* expression, that contains at least one
* argument that is not a PT_VALUE or
* PT_NAME node
* return:
* node(in): PT_EXPR
*/
static bool
pt_is_nested_expr (const PT_NODE * node)
{
PT_NODE *func, *arg;
assert (node->node_type == PT_EXPR);
if (node->info.expr.op != PT_FUNCTION_HOLDER)
{
arg = pt_function_index_skip_expr (node->info.expr.arg1);
if ((arg != NULL) && (PT_IS_NAME_NODE (arg) == false) && (PT_IS_VALUE_NODE (arg) == false))
{
return true;
}
arg = pt_function_index_skip_expr (node->info.expr.arg2);
if ((arg != NULL) && (PT_IS_NAME_NODE (arg) == false) && (PT_IS_VALUE_NODE (arg) == false))
{
return true;
}
arg = pt_function_index_skip_expr (node->info.expr.arg3);
if ((arg != NULL) && (PT_IS_NAME_NODE (arg) == false) && (PT_IS_VALUE_NODE (arg) == false))
{
return true;
}
return false;
}
/* the given operator is not PT_FUNCTION_HOLDER */
func = node->info.expr.arg1;
for (arg = func->info.function.arg_list; arg != NULL; arg = arg->next)
{
PT_NODE *save_arg = arg;
arg = pt_function_index_skip_expr (arg);
if ((arg != NULL) && (PT_IS_NAME_NODE (arg) == false) && (PT_IS_VALUE_NODE (arg) == false))
{
return true;
}
arg = save_arg;
}
return false;
}
/*
* pt_function_is_allowed_as_function_index () : checks if the given function
* is allowed in the structure of a function index
* return:
* func(in): parse tree node function
*/
static bool
pt_function_is_allowed_as_function_index (const PT_NODE * func)
{
assert (func != NULL && func->node_type == PT_FUNCTION);
// TODO: expose get_signatures () of func_type.cpp & filter out funcs returning PT_TYPE_JSON
switch (func->info.function.function_type)
{
case F_BENCHMARK:
case F_JSON_OBJECT:
case F_JSON_ARRAY:
case F_JSON_MERGE:
case F_JSON_MERGE_PATCH:
case F_JSON_INSERT:
case F_JSON_REMOVE:
case F_JSON_ARRAY_APPEND:
case F_JSON_GET_ALL_PATHS:
case F_JSON_REPLACE:
case F_JSON_SET:
case F_JSON_KEYS:
case F_JSON_ARRAY_INSERT:
case F_JSON_SEARCH:
case F_JSON_EXTRACT:
return false;
case F_INSERT_SUBSTRING:
case F_ELT:
case F_JSON_CONTAINS:
case F_JSON_CONTAINS_PATH:
case F_JSON_DEPTH:
case F_JSON_LENGTH:
case F_JSON_TYPE:
case F_JSON_VALID:
case F_JSON_PRETTY:
case F_JSON_QUOTE:
case F_JSON_UNQUOTE:
return true;
default:
return true;
}
}
/*
* pt_expr_is_allowed_as_function_index () : checks if the given operator
* is allowed in the structure of a function index
* return:
* expr(in): expression parse tree node
*/
static bool
pt_expr_is_allowed_as_function_index (const PT_NODE * expr)
{
assert (expr != NULL && expr->node_type == PT_EXPR);
/* if add it here, add it to validate_regu_key_function_index () as well */
switch (expr->info.expr.op)
{
case PT_CAST:
if (!PT_EXPR_INFO_IS_FLAGED (expr, PT_EXPR_INFO_CAST_COLL_MODIFIER))
{
break;
}
[[fallthrough]];
case PT_MOD:
case PT_LEFT:
case PT_RIGHT:
case PT_REPEAT:
case PT_MID:
case PT_STRCMP:
case PT_REVERSE:
case PT_BIT_COUNT:
case PT_MODULUS:
case PT_FLOOR:
case PT_CEIL:
case PT_ABS:
case PT_POWER:
case PT_ROUND:
case PT_LOG:
case PT_EXP:
case PT_SQRT:
case PT_SIN:
case PT_COS:
case PT_TAN:
case PT_COT:
case PT_ACOS:
case PT_ASIN:
case PT_ATAN:
case PT_ATAN2:
case PT_DEGREES:
case PT_DATEF:
case PT_TIMEF:
case PT_RADIANS:
case PT_LN:
case PT_LOG2:
case PT_LOG10:
case PT_TRUNC:
case PT_CHR:
case PT_INSTR:
case PT_LEAST:
case PT_GREATEST:
case PT_POSITION:
case PT_LOWER:
case PT_UPPER:
case PT_CHAR_LENGTH:
case PT_LTRIM:
case PT_RTRIM:
case PT_FROM_UNIXTIME:
case PT_SUBSTRING_INDEX:
case PT_MD5:
case PT_AES_ENCRYPT:
case PT_AES_DECRYPT:
case PT_SHA_ONE:
case PT_SHA_TWO:
case PT_TO_BASE64:
case PT_FROM_BASE64:
case PT_LPAD:
case PT_RPAD:
case PT_REPLACE:
case PT_TRANSLATE:
case PT_ADD_MONTHS:
case PT_LAST_DAY:
case PT_UNIX_TIMESTAMP:
case PT_STR_TO_DATE:
case PT_TIME_FORMAT:
case PT_TIMESTAMP:
case PT_YEARF:
case PT_MONTHF:
case PT_DAYF:
case PT_DAYOFMONTH:
case PT_HOURF:
case PT_MINUTEF:
case PT_SECONDF:
case PT_QUARTERF:
case PT_WEEKDAY:
case PT_DAYOFWEEK:
case PT_DAYOFYEAR:
case PT_TODAYS:
case PT_FROMDAYS:
case PT_TIMETOSEC:
case PT_SECTOTIME:
case PT_MAKEDATE:
case PT_MAKETIME:
case PT_WEEKF:
case PT_MONTHS_BETWEEN:
case PT_FORMAT:
case PT_DATE_FORMAT:
case PT_ADDDATE:
case PT_DATE_ADD:
case PT_DATEDIFF:
case PT_TIMEDIFF:
case PT_SUBDATE:
case PT_DATE_SUB:
case PT_FUNCTION_HOLDER:
case PT_BIT_LENGTH:
case PT_OCTET_LENGTH:
case PT_IFNULL:
case PT_LOCATE:
case PT_SUBSTRING:
case PT_NVL:
case PT_NVL2:
case PT_NULLIF:
case PT_TO_CHAR:
case PT_TO_DATE:
case PT_TO_DATETIME:
case PT_TO_TIMESTAMP:
case PT_TO_TIME:
case PT_TO_NUMBER:
case PT_TRIM:
case PT_INET_ATON:
case PT_INET_NTOA:
case PT_TO_DATETIME_TZ:
case PT_TO_TIMESTAMP_TZ:
case PT_CRC32:
return true;
case PT_TZ_OFFSET:
default:
return false;
}
return false;
}
/*
* pt_expr_keep_uniqueness () : checks if the given operator
* is keeping uniqueness
* return:
* expr(in): expression parse tree node
*/
bool
pt_expr_keep_uniqueness (const PT_NODE * expr)
{
switch (expr->info.expr.op)
{
case PT_REVERSE:
case PT_CONCAT:
case PT_STRCAT:
case PT_PLUS:
case PT_MINUS:
case PT_EQ: /* for predicate */
return true;
case PT_CAST:
if (PT_EXPR_INFO_IS_FLAGED (expr, PT_EXPR_INFO_CAST_WRAP)) /* auto generated cast */
{
return true;
}
return false;
default:
return false;
}
return false;
}
/*
* pt_is_function_index_expr () : checks if the given PT_EXPR
* is allowed in the structure of a
* function index. This is true if the
* operator is allowed and the expression
* is a simple one, with at least one
* attribute name as an argument
* return:
* expr(in): PT_EXPR
*/
bool
pt_is_function_index_expr (PARSER_CONTEXT * parser, PT_NODE * expr, bool report_error)
{
if (!expr)
{
return false;
}
if (expr->node_type == PT_VALUE)
{
if (report_error)
{
PT_ERRORm (parser, expr, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_CONSTANT_IN_FUNCTION_INDEX_NOT_ALLOWED);
}
return false;
}
if (expr->node_type != PT_EXPR)
{
if (report_error)
{
/* the initial expression might have been rewritten to something else (ex: TO_CHAR(col) rewrites to a PT_NAME
* if col has a character data type. */
PT_ERRORm (parser, expr, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_INVALID_FUNCTION_INDEX_EXPR);
}
return false;
}
if (!pt_expr_is_allowed_as_function_index (expr))
{
if (report_error)
{
PT_ERRORmf (parser, expr, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_FUNCTION_CANNOT_BE_USED_FOR_INDEX,
pt_show_binopcode (expr->info.expr.op));
}
return false;
}
if (pt_is_const_expr_node (expr))
{
if (report_error)
{
PT_ERRORm (parser, expr, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_CONSTANT_IN_FUNCTION_INDEX_NOT_ALLOWED);
}
return false;
}
if (pt_is_nested_expr (expr))
{
if (report_error)
{
PT_ERRORm (parser, expr, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_INVALID_FUNCTION_INDEX);
}
return false;
}
if (expr->info.expr.op == PT_FUNCTION_HOLDER)
{
PT_NODE *func = expr->info.expr.arg1;
if (!pt_function_is_allowed_as_function_index (func))
{
if (report_error)
{
PT_ERRORmf (parser, expr, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_FUNCTION_CANNOT_BE_USED_FOR_INDEX,
fcode_get_uppercase_name (func->info.function.function_type));
}
return false;
}
}
return true;
}
/*
* pt_expr_to_sort_spec () : creates a list of PT_SORT_SPEC nodes from
* the arguments of a given expression.
* return: PT_NODE representing a list of PT_SORT_SPEC nodes
* expr(in): PT_EXPR
* parser(in):
*/
PT_NODE *
pt_expr_to_sort_spec (PARSER_CONTEXT * parser, PT_NODE * expr)
{
PT_NODE *node = NULL;
if (!PT_IS_EXPR_NODE (expr))
{
return NULL;
}
if (expr->info.expr.op == PT_FUNCTION_HOLDER)
{
PT_NODE *func, *arg;
func = expr->info.expr.arg1;
for (arg = func->info.function.arg_list; arg != NULL; arg = arg->next)
{
PT_NODE *save_arg = arg;
arg = pt_function_index_skip_expr (arg);
if (PT_IS_NAME_NODE (arg))
{
PT_NODE *srt_spec = parser_new_node (parser, PT_SORT_SPEC);
if (srt_spec == NULL)
{
PT_INTERNAL_ERROR (parser, "allocate new node");
return NULL;
}
srt_spec->info.sort_spec.expr = parser_copy_tree (parser, arg);
srt_spec->info.sort_spec.expr->next = NULL;
srt_spec->info.sort_spec.asc_or_desc = PT_ASC;
node = parser_append_node (srt_spec, node);
}
arg = save_arg;
}
}
else
{
PT_NODE *arg;
arg = pt_function_index_skip_expr (expr->info.expr.arg1);
if (PT_IS_NAME_NODE (arg))
{
PT_NODE *srt_spec = parser_new_node (parser, PT_SORT_SPEC);
if (srt_spec == NULL)
{
PT_INTERNAL_ERROR (parser, "allocate new node");
return NULL;
}
srt_spec->info.sort_spec.expr = parser_copy_tree (parser, arg);
srt_spec->info.sort_spec.asc_or_desc = PT_ASC;
node = parser_append_node (srt_spec, node);
}
arg = pt_function_index_skip_expr (expr->info.expr.arg2);
if (PT_IS_NAME_NODE (arg))
{
PT_NODE *srt_spec = parser_new_node (parser, PT_SORT_SPEC);
if (srt_spec == NULL)
{
PT_INTERNAL_ERROR (parser, "allocate new node");
return NULL;
}
srt_spec->info.sort_spec.expr = parser_copy_tree (parser, arg);
srt_spec->info.sort_spec.asc_or_desc = PT_ASC;
node = parser_append_node (srt_spec, node);
}
arg = pt_function_index_skip_expr (expr->info.expr.arg3);
if (PT_IS_NAME_NODE (arg))
{
PT_NODE *srt_spec = parser_new_node (parser, PT_SORT_SPEC);
if (srt_spec == NULL)
{
PT_INTERNAL_ERROR (parser, "allocate new node");
return NULL;
}
srt_spec->info.sort_spec.expr = parser_copy_tree (parser, arg);
srt_spec->info.sort_spec.asc_or_desc = PT_ASC;
node = parser_append_node (srt_spec, node);
}
}
return node;
}
/*
* pt_is_join_expr () : checks if the given expression has non-constant
* arguments from only one class
* return: true if more than one classes are involved in the expression,
* false otherwise
* expr(in): PT_EXPR
* spec_id(out): the spec id of the PT_SPEC used (if false is returned)
*/
bool
pt_is_join_expr (PT_NODE * expr, UINTPTR * spec_id)
{
PT_NODE *func = NULL;
PT_NODE *arg = NULL;
assert (expr != NULL && spec_id != NULL);
*spec_id = 0;
if (expr->info.expr.op != PT_FUNCTION_HOLDER)
{
arg = pt_function_index_skip_expr (expr->info.expr.arg1);
if (PT_IS_NAME_NODE (arg))
{
if (*spec_id == 0)
{
*spec_id = arg->info.name.spec_id;
}
else
{
if (*spec_id != arg->info.name.spec_id)
{
return true;
}
}
}
arg = pt_function_index_skip_expr (expr->info.expr.arg2);
if (PT_IS_NAME_NODE (arg))
{
if (*spec_id == 0)
{
*spec_id = arg->info.name.spec_id;
}
else
{
if (*spec_id != arg->info.name.spec_id)
{
return true;
}
}
}
arg = pt_function_index_skip_expr (expr->info.expr.arg3);
if (PT_IS_NAME_NODE (arg))
{
if (*spec_id == 0)
{
*spec_id = arg->info.name.spec_id;
}
else
{
if (*spec_id != arg->info.name.spec_id)
{
return true;
}
}
}
}
else
{
func = expr->info.expr.arg1;
for (arg = func->info.function.arg_list; arg != NULL; arg = arg->next)
{
PT_NODE *tmp = pt_function_index_skip_expr (arg);
if (PT_IS_NAME_NODE (tmp))
{
if (*spec_id == 0)
{
*spec_id = tmp->info.name.spec_id;
}
else
{
if (*spec_id != tmp->info.name.spec_id)
{
return true;
}
}
}
}
}
return false;
}
/*
* pt_sort_spec_list_to_name_node_list () : creates a list of name nodes
* from sort spec nodes list
* return: name list if sort spec nodes contain only name nodes,
* NULL otherwise
* expr(in): sort spec list
* parser(in):
*/
PT_NODE *
pt_sort_spec_list_to_name_node_list (PARSER_CONTEXT * parser, PT_NODE * sort_spec_list)
{
PT_NODE *name_list = NULL;
PT_NODE *node = NULL, *name_node = NULL;
for (node = sort_spec_list; node; node = node->next)
{
if (!PT_IS_SORT_SPEC_NODE (node) || node->info.sort_spec.expr->node_type != PT_NAME)
{
return NULL;
}
}
for (node = sort_spec_list; node; node = node->next)
{
name_node = parser_copy_tree (parser, node->info.sort_spec.expr);
if (node->info.sort_spec.asc_or_desc == PT_DESC)
{
PT_NAME_INFO_SET_FLAG (name_node, PT_NAME_INFO_DESC);
}
name_list = parser_append_node (name_node, name_list);
}
return name_list;
}
/*
* PT_VACUUM section
*/
/*
* pt_apply_vacuum () - Apply function "q" on all the children of a VACUUM
* parse tree node.
*
* return : Updated VACUUM parse tree node.
* parser (in) : Parse context.
* p (in) : VACUUM parse tree node.
* g (in) : Function to apply on all node's children.
* arg (in) : Argument for function g.
*/
static PT_NODE *
pt_apply_vacuum (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
assert (PT_IS_VACUUM_NODE (p));
return p;
}
/*
* pt_init_vacuum () - Initialize a VACUUM parse tree node.
*
* return : Initialized parse tree node.
* p (in) : VACUUM parse tree node.
*/
static PT_NODE *
pt_init_vacuum (PT_NODE * p)
{
assert (PT_IS_VACUUM_NODE (p));
return p;
}
/*
* pt_print_vacuum () - Print a VACUUM parse tree node.
*
* return : Return printed version of parse tree node.
* parser (in) : Parser context.
* p (in) :
*/
static PARSER_VARCHAR *
pt_print_vacuum (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL;
assert (PT_IS_VACUUM_NODE (p));
q = pt_append_nulstring (parser, q, "VACUUM");
return q;
}
/*
* pt_apply_query_trace ()
* return :
* parser (in) :
* p (in) :
* g (in) :
* arg (in) :
*/
static PT_NODE *
pt_apply_query_trace (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
return p;
}
/*
* pt_init_query_trace ()
* return :
* p (in) :
*/
static PT_NODE *
pt_init_query_trace (PT_NODE * p)
{
p->info.trace.on_off = PT_TRACE_OFF;
p->info.trace.format = PT_TRACE_FORMAT_TEXT;
return p;
}
/*
* pt_print_query_trace ()
* return :
* parser (in) :
* p (in) :
*/
static PARSER_VARCHAR *
pt_print_query_trace (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *b = NULL;
PT_MISC_TYPE onoff, format;
onoff = p->info.trace.on_off;
format = p->info.trace.format;
b = pt_append_nulstring (parser, b, "set trace ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (onoff));
if (onoff == PT_TRACE_ON)
{
b = pt_append_nulstring (parser, b, " output ");
b = pt_append_nulstring (parser, b, pt_show_misc_type (format));
}
return b;
}
/*
* pt_clean_tree_copy_info () - deallocate memory used by a PT_TREE_COPY_INFO
*/
static void
pt_clean_tree_copy_info (PT_TREE_COPY_INFO * tree_copy_info)
{
PT_CTE_COPY_INFO *cte_info_it, *save_next;
/* deallocate CTE list */
for (cte_info_it = tree_copy_info->cte_structures_list; cte_info_it != NULL; cte_info_it = save_next)
{
save_next = cte_info_it->next;
free (cte_info_it);
}
}
static PT_NODE *
pt_apply_json_table (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.json_table_info.expr, arg);
PT_APPLY_WALK (parser, p->info.json_table_info.tree, arg);
return p;
}
static PARSER_VARCHAR *
pt_print_json_table (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *pstr = NULL;
PARSER_VARCHAR *substr = NULL;
// print format:
// json_table (.expr, .tree)
// 'json_table ('
pstr = pt_append_nulstring (parser, pstr, "json_table (");
// print expr
substr = pt_print_bytes (parser, p->info.json_table_info.expr);
pstr = pt_append_varchar (parser, pstr, substr);
// ', ' print tree
pstr = pt_append_nulstring (parser, pstr, ", ");
substr = pt_print_bytes (parser, p->info.json_table_info.tree);
pstr = pt_append_varchar (parser, pstr, substr);
// ')'
pstr = pt_append_nulstring (parser, pstr, ")");
return pstr;
}
static PT_NODE *
pt_apply_json_table_node (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.json_table_node_info.columns, arg);
PT_APPLY_WALK (parser, p->info.json_table_node_info.nested_paths, arg);
return p;
}
static PARSER_VARCHAR *
pt_print_json_table_node (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *pstr = NULL;
PARSER_VARCHAR *substr = NULL;
// print format:
// .path columns (.columns, .nested paths)
// todo - print columns and nested path in same order as defined by user...
// print path
pstr = pt_append_nulstring (parser, pstr, "'");
pstr = pt_append_nulstring (parser, pstr, p->info.json_table_node_info.path);
pstr = pt_append_nulstring (parser, pstr, "'");
// 'columns ('
pstr = pt_append_nulstring (parser, pstr, " columns (");
// print columns
substr = pt_print_bytes (parser, p->info.json_table_node_info.columns);
pstr = pt_append_varchar (parser, pstr, substr);
if (p->info.json_table_node_info.columns != NULL && p->info.json_table_node_info.nested_paths != NULL)
{
pstr = pt_append_nulstring (parser, pstr, ", ");
}
for (PT_NODE * nested = p->info.json_table_node_info.nested_paths; nested != NULL; nested = nested->next)
{
// 'nested path ' print nested ', '
pstr = pt_append_nulstring (parser, pstr, "nested path ");
substr = pt_print_bytes (parser, p->info.json_table_node_info.nested_paths);
pstr = pt_append_varchar (parser, pstr, substr);
if (nested->next != NULL)
{
pstr = pt_append_nulstring (parser, pstr, ", ");
}
}
// ' )'
pstr = pt_append_nulstring (parser, pstr, " )");
return pstr;
}
static PT_NODE *
pt_init_json_table_column (PT_NODE * p)
{
p->info.json_table_column_info.func = JSON_TABLE_EXTRACT;
p->info.json_table_column_info.on_error.m_behavior = JSON_TABLE_RETURN_NULL;
p->info.json_table_column_info.on_empty.m_behavior = JSON_TABLE_RETURN_NULL;
return p;
}
static PT_NODE *
pt_apply_json_table_column (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.json_table_column_info.name, arg);
return p;
}
//
// pt_json_table_column_behavior_to_string ()
//
// return : stringify behavior
// behavior_type (in) : behavior enum value
//
static const char *
pt_json_table_column_behavior_to_string (const json_table_column_behavior_type & behavior_type)
{
switch (behavior_type)
{
case json_table_column_behavior_type::JSON_TABLE_RETURN_NULL:
return "NULL";
case json_table_column_behavior_type::JSON_TABLE_DEFAULT_VALUE:
return "DEFAULT";
case json_table_column_behavior_type::JSON_TABLE_THROW_ERROR:
return "ERROR";
default:
assert (false);
return "UNKNOWN BEHAVIOR";
}
}
//
// pt_print_json_table_column_error_or_empty_behavior () - print json table column behavior
//
// return : parser varchar
// parser (in) : parser context
// pstr (in/out) : parser varchar where printed column behavior is appended
// column_behavior (in) : column behavior
//
static PARSER_VARCHAR *
pt_print_json_table_column_error_or_empty_behavior (PARSER_CONTEXT * parser,
PARSER_VARCHAR * pstr,
const struct json_table_column_behavior &column_behavior)
{
PARSER_VARCHAR *substr = NULL;
// print behavior type
pstr = pt_append_nulstring (parser, pstr, pt_json_table_column_behavior_to_string (column_behavior.m_behavior));
if (column_behavior.m_behavior == json_table_column_behavior_type::JSON_TABLE_DEFAULT_VALUE)
{
pstr = pt_append_nulstring (parser, pstr, " ");
substr = pt_print_db_value (parser, column_behavior.m_default_value);
pstr = pt_append_varchar (parser, pstr, substr);
}
return pstr;
}
//
// pt_print_json_table_column_info () - print json table column info
//
// return : parser varchar
// parser (in) : parser context
// p (in) : print column
// pstr (in/out) : parser varchar where printed column info is appended
//
static PARSER_VARCHAR *
pt_print_json_table_column_info (PARSER_CONTEXT * parser, PT_NODE * p, PARSER_VARCHAR * pstr)
{
PARSER_VARCHAR *substr = NULL;
const char *type = NULL;
assert (p->node_type == PT_JSON_TABLE_COLUMN);
// print format:
// name FOR ORDINALITY
// | name type PATH string path[on_error][on_empty]
// | name type EXISTS PATH string path
// print name
pstr = pt_append_nulstring (parser, pstr, p->info.json_table_column_info.name->info.name.original);
// get the type
type = pt_type_enum_to_db_domain_name (p->type_enum);
switch (p->info.json_table_column_info.func)
{
case json_table_column_function::JSON_TABLE_ORDINALITY:
// print FOR ORDINALITY
pstr = pt_append_nulstring (parser, pstr, " FOR ORDINALITY");
break;
case json_table_column_function::JSON_TABLE_EXTRACT:
// print type
pstr = pt_append_nulstring (parser, pstr, " ");
if (p->data_type != NULL)
{
substr = pt_print_bytes (parser, p->data_type);
pstr = pt_append_varchar (parser, pstr, substr);
}
else
{
pstr = pt_append_nulstring (parser, pstr, type);
}
// print PATH
pstr = pt_append_nulstring (parser, pstr, " PATH ");
// print path
pstr = pt_append_nulstring (parser, pstr, "'");
pstr = pt_append_nulstring (parser, pstr, p->info.json_table_column_info.path);
pstr = pt_append_nulstring (parser, pstr, "'");
// print on_empty
pstr = pt_append_nulstring (parser, pstr, " ");
pstr = pt_print_json_table_column_error_or_empty_behavior (parser, pstr, p->info.json_table_column_info.on_empty);
pstr = pt_append_nulstring (parser, pstr, " ON EMPTY");
// print on_error
pstr = pt_append_nulstring (parser, pstr, " ");
pstr = pt_print_json_table_column_error_or_empty_behavior (parser, pstr, p->info.json_table_column_info.on_error);
pstr = pt_append_nulstring (parser, pstr, " ON ERROR");
break;
case json_table_column_function::JSON_TABLE_EXISTS:
// print type
pstr = pt_append_nulstring (parser, pstr, " ");
if (p->data_type != NULL)
{
substr = pt_print_bytes (parser, p->data_type);
pstr = pt_append_varchar (parser, pstr, substr);
}
else
{
pstr = pt_append_nulstring (parser, pstr, type);
}
// print EXISTS PATH
pstr = pt_append_nulstring (parser, pstr, " EXISTS PATH ");
// print path
pstr = pt_append_nulstring (parser, pstr, "'");
pstr = pt_append_nulstring (parser, pstr, p->info.json_table_column_info.path);
pstr = pt_append_nulstring (parser, pstr, "'");
break;
default:
/* should not be here */
assert (false);
break;
}
return pstr;
}
static PARSER_VARCHAR *
pt_print_json_table_columns (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *pstr = NULL;
PT_NODE *p_it = NULL;
// append each column
for (p_it = p; p_it->next != NULL; p_it = p_it->next)
{
pstr = pt_print_json_table_column_info (parser, p_it, pstr);
if (p_it->next != NULL)
{
// print ','
pstr = pt_append_nulstring (parser, pstr, ", ");
}
}
// the last column
pstr = pt_print_json_table_column_info (parser, p_it, pstr);
return pstr;
}
// pt_move_node - move PT_NODE pointer from source to destination. useful to automatically assign and unlink
void
pt_move_node (REFPTR (PT_NODE, destp), REFPTR (PT_NODE, srcp))
{
destp = srcp;
srcp = NULL;
}
static PT_NODE *
pt_apply_dblink_table (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
if (p->info.dblink_table.is_name)
{
PT_APPLY_WALK (parser, p->info.dblink_table.conn, arg);
PT_APPLY_WALK (parser, p->info.dblink_table.owner_name, arg);
}
PT_APPLY_WALK (parser, p->info.dblink_table.url, arg);
PT_APPLY_WALK (parser, p->info.dblink_table.user, arg);
PT_APPLY_WALK (parser, p->info.dblink_table.pwd, arg);
PT_APPLY_WALK (parser, p->info.dblink_table.qstr, arg);
PT_APPLY_WALK (parser, p->info.dblink_table.pushed_pred, arg);
PT_APPLY_WALK (parser, p->info.dblink_table.cols, arg);
PT_APPLY_WALK (parser, p->info.dblink_table.sel_list, arg);
PT_APPLY_WALK (parser, p->info.dblink_table.owner_list, arg);
return p;
}
static PARSER_VARCHAR *
pt_print_remote_info (PARSER_CONTEXT * parser, PT_DBLINK_INFO * pt, bool is_dml)
{
PARSER_VARCHAR *var = 0;
char *t, *s;
var = pt_append_bytes (parser, var, "'", 1);
// "cci:CUBRID:{HOST}:{PORT}:{DBNAME}:<user-name>:<password>:{PROPERITIES}"
s = (char *) pt->url->info.value.data_value.str->bytes;
// skip cci:
s = strchr (s, ':');
// skip CUBRID:
s = strchr (s + 1, ':');
t = ++s;
// host
s = strchr (s, ':');
// port
s = strchr (s + 1, ':');
// dbname
s = strchr (s + 1, ':');
var = pt_append_bytes (parser, var, t, (int) (s - t));
t = s + 2;
var = pt_append_nulstring (parser, var, ":");
var =
pt_append_bytes (parser, var, (char *) pt->user->info.value.data_value.str->bytes,
pt->user->info.value.data_value.str->length);
var = pt_append_nulstring (parser, var, ":");
var = pt_append_bytes (parser, var, (char *) pt->pwd->info.value.data_value.str->bytes,
pt->pwd->info.value.data_value.str->length);
// properties
if (!is_dml)
{
var = pt_append_nulstring (parser, var, t);
}
var = pt_append_bytes (parser, var, "'", 1);
return var;
}
static PARSER_VARCHAR *
pt_print_dblink_table (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *var = 0, *r;
PT_DBLINK_INFO *pt = &(p->info.dblink_table);
bool print_detail = true;
q = pt_append_nulstring (parser, q, "DBLINK(");
if (p->info.dblink_table.is_name)
{
if (p->info.dblink_table.owner_name)
{
r = pt_print_bytes (parser, p->info.dblink_table.owner_name);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, ".");
}
r = pt_print_bytes (parser, p->info.dblink_table.conn);
q = pt_append_varchar (parser, q, r);
if (((parser->custom_print & PT_PRINT_DBLINK_INFO) == 0) || !pt->url || !pt->user || !pt->pwd)
{
print_detail = false;
}
else
{
/* For Query-cache:
* Separate comments have been added
* for cases where there is no change in the query but information on the server has changed. */
}
}
if (print_detail)
{
var = pt_print_remote_info (parser, pt, false);
}
if ((parser->custom_print & PT_PRINT_DBLINK_INFO) == 0)
{
q = pt_append_varchar (parser, q, var);
}
else
{
if (parser->dblink_server_text == NULL)
{
parser->dblink_server_text = var;
}
else
{
if (var)
{
parser->dblink_server_text = pt_append_nulstring (parser, parser->dblink_server_text, ",");
}
parser->dblink_server_text = pt_append_varchar (parser, parser->dblink_server_text, var);
}
}
q = pt_append_bytes (parser, q, ", ", 2);
if (p->info.dblink_table.rewritten)
{
q =
pt_append_quoted_string (parser, q, (char *) p->info.dblink_table.rewritten->bytes,
p->info.dblink_table.rewritten->length);
}
else if (p->info.dblink_table.qstr)
{
unsigned int alias_print_flag = (parser->custom_print & PT_CHARSET_COLLATE_FULL);
parser->custom_print &= ~PT_CHARSET_COLLATE_FULL;
r = pt_print_bytes (parser, p->info.dblink_table.qstr);
parser->custom_print |= alias_print_flag;
q = pt_append_varchar (parser, q, r);
}
q = pt_append_bytes (parser, q, ")", 1);
return q;
}
static PARSER_VARCHAR *
pt_print_dblink_table_dml (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r;
PT_DBLINK_INFO *pt = &(p->info.dblink_table);
assert (p->info.dblink_table.is_name == true);
if (p->info.dblink_table.owner_name)
{
r = pt_print_bytes (parser, p->info.dblink_table.owner_name);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, ".");
}
r = pt_print_bytes (parser, p->info.dblink_table.conn);
q = pt_append_varchar (parser, q, r);
/* For Query-cache:
* Separate comments have been added
* for cases where there is no change in the query but information on the server has changed. */
if ((parser->custom_print & PT_PRINT_DBLINK_INFO) && (pt->url && pt->user && pt->pwd))
{
PARSER_VARCHAR *var = pt_print_remote_info (parser, pt, true);
if (parser->dblink_server_text == NULL)
{
parser->dblink_server_text = var;
}
else
{
if (var)
{
parser->dblink_server_text = pt_append_nulstring (parser, parser->dblink_server_text, ",");
}
parser->dblink_server_text = pt_append_varchar (parser, parser->dblink_server_text, var);
}
}
return q;
}
static PT_NODE *
pt_apply_create_server (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.create_server.server_name, arg);
PT_APPLY_WALK (parser, p->info.create_server.owner_name, arg);
PT_APPLY_WALK (parser, p->info.create_server.host, arg);
PT_APPLY_WALK (parser, p->info.create_server.port, arg);
PT_APPLY_WALK (parser, p->info.create_server.dbname, arg);
PT_APPLY_WALK (parser, p->info.create_server.user, arg);
PT_APPLY_WALK (parser, p->info.create_server.pwd, arg);
PT_APPLY_WALK (parser, p->info.create_server.prop, arg);
PT_APPLY_WALK (parser, p->info.create_server.comment, arg);
return p;
}
static PARSER_VARCHAR *
pt_print_create_server (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r;
PT_CREATE_SERVER_INFO *si = &(p->info.create_server);
q = pt_append_nulstring (parser, q, "CREATE SERVER ");
if (si->owner_name)
{
r = pt_print_bytes (parser, si->owner_name);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, ".");
}
r = pt_print_bytes (parser, si->server_name);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, " ( HOST=");
r = pt_print_bytes (parser, si->host);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, ", PORT=");
r = pt_print_bytes (parser, si->port);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, ", DBNAME=");
r = pt_print_bytes (parser, si->dbname);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, ", USER=");
r = pt_print_bytes (parser, si->user);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, ", PASSWORD=");
r = pt_print_bytes (parser, si->pwd);
q = pt_append_varchar (parser, q, r);
if (si->prop != NULL)
{
q = pt_append_nulstring (parser, q, ", PROPERTIES=");
r = pt_print_bytes (parser, si->prop);
q = pt_append_varchar (parser, q, r);
}
if (si->comment != NULL)
{
q = pt_append_nulstring (parser, q, ", COMMENT=");
r = pt_print_bytes (parser, si->comment);
q = pt_append_varchar (parser, q, r);
}
q = pt_append_nulstring (parser, q, " )");
return q;
}
static PT_NODE *
pt_apply_drop_server (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.drop_server.owner_name, arg);
PT_APPLY_WALK (parser, p->info.drop_server.server_name, arg);
return p;
}
static PARSER_VARCHAR *
pt_print_drop_server (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r;
if (p->info.drop_server.if_exists)
{
q = pt_append_nulstring (parser, q, "DROP SERVER IF EXISTS ");
}
else
{
q = pt_append_nulstring (parser, q, "DROP SERVER ");
}
if (p->info.drop_server.owner_name)
{
r = pt_print_bytes (parser, p->info.drop_server.owner_name);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, ".");
}
r = pt_print_bytes (parser, p->info.drop_server.server_name);
q = pt_append_varchar (parser, q, r);
return q;
}
static PT_NODE *
pt_apply_rename_server (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.rename_server.old_name, arg);
PT_APPLY_WALK (parser, p->info.rename_server.new_name, arg);
PT_APPLY_WALK (parser, p->info.rename_server.owner_name, arg);
return p;
}
static PARSER_VARCHAR *
pt_print_rename_server (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r;
q = pt_append_nulstring (parser, q, "RENAME SERVER ");
if (p->info.rename_server.owner_name)
{
r = pt_print_bytes (parser, p->info.rename_server.owner_name);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, ".");
}
r = pt_print_bytes (parser, p->info.rename_server.old_name);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, " AS ");
r = pt_print_bytes (parser, p->info.rename_server.new_name);
q = pt_append_varchar (parser, q, r);
return q;
}
static PT_NODE *
pt_apply_alter_server (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, p->info.alter_server.server_name, arg);
PT_APPLY_WALK (parser, p->info.alter_server.current_owner_name, arg);
PT_APPLY_WALK (parser, p->info.alter_server.host, arg);
PT_APPLY_WALK (parser, p->info.alter_server.port, arg);
PT_APPLY_WALK (parser, p->info.alter_server.dbname, arg);
PT_APPLY_WALK (parser, p->info.alter_server.user, arg);
PT_APPLY_WALK (parser, p->info.alter_server.pwd, arg);
PT_APPLY_WALK (parser, p->info.alter_server.prop, arg);
PT_APPLY_WALK (parser, p->info.alter_server.comment, arg);
PT_APPLY_WALK (parser, p->info.alter_server.owner_name, arg);
return p;
}
static PARSER_VARCHAR *
pt_print_alter_server (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = 0, *r;
char *pt;
bool is_delimiter = false;
PT_ALTER_SERVER_INFO *alter = &(p->info.alter_server);
q = pt_append_nulstring (parser, q, "ALTER SERVER ");
if (alter->current_owner_name)
{
r = pt_print_bytes (parser, alter->current_owner_name);
q = pt_append_varchar (parser, q, r);
q = pt_append_nulstring (parser, q, ".");
}
r = pt_print_bytes (parser, alter->server_name);
q = pt_append_varchar (parser, q, r);
if (alter->xbits.bit_owner)
{
assert (alter->owner_name && alter->owner_name->node_type == PT_NAME);
q = pt_append_nulstring (parser, q, " OWNER TO ");
r = pt_print_bytes (parser, alter->owner_name);
q = pt_append_varchar (parser, q, r);
is_delimiter = true;
}
if (alter->xbits.bit_host)
{
assert (alter->host && (alter->host->node_type == PT_VALUE));
pt = (char *) PT_VALUE_GET_BYTES (alter->host);
assert (pt && *pt);
if (is_delimiter)
{
q = pt_append_bytes (parser, q, (char *) ",", 1);
}
q = pt_append_nulstring (parser, q, " CHANGE HOST=");
r = pt_print_bytes (parser, alter->host);
q = pt_append_varchar (parser, q, r);
is_delimiter = true;
}
if (alter->xbits.bit_port)
{
if (is_delimiter)
{
q = pt_append_bytes (parser, q, (char *) ",", 1);
}
q = pt_append_nulstring (parser, q, " CHANGE PORT=");
r = pt_print_bytes (parser, alter->port);
q = pt_append_varchar (parser, q, r);
is_delimiter = true;
}
if (alter->xbits.bit_dbname)
{
assert (alter->dbname && alter->dbname->node_type == PT_NAME);
assert (alter->dbname->info.name.original && *alter->dbname->info.name.original);
if (is_delimiter)
{
q = pt_append_bytes (parser, q, (char *) ",", 1);
}
q = pt_append_nulstring (parser, q, " CHANGE DBNAME=");
r = pt_print_bytes (parser, alter->dbname);
q = pt_append_varchar (parser, q, r);
is_delimiter = true;
}
if (alter->xbits.bit_user)
{
assert (alter->user && alter->user->node_type == PT_NAME);
assert (alter->user->info.name.original && *alter->user->info.name.original);
if (is_delimiter)
{
q = pt_append_bytes (parser, q, (char *) ",", 1);
}
q = pt_append_nulstring (parser, q, " CHANGE USER=");
r = pt_print_bytes (parser, alter->user);
q = pt_append_varchar (parser, q, r);
is_delimiter = true;
}
if (alter->xbits.bit_pwd)
{
assert (alter->pwd && alter->pwd->node_type == PT_VALUE);
pt = (char *) PT_VALUE_GET_BYTES (alter->pwd);
assert (pt && *pt);
if (is_delimiter)
{
q = pt_append_bytes (parser, q, (char *) ",", 1);
}
q = pt_append_nulstring (parser, q, " CHANGE PASSWORD=");
r = pt_print_bytes (parser, alter->pwd);
q = pt_append_varchar (parser, q, r);
is_delimiter = true;
}
if (alter->xbits.bit_prop)
{
if (is_delimiter)
{
q = pt_append_bytes (parser, q, (char *) ",", 1);
}
q = pt_append_nulstring (parser, q, " CHANGE PROPERTIES=");
if (alter->prop)
{
assert (alter->prop->node_type == PT_VALUE);
r = pt_print_bytes (parser, alter->prop);
q = pt_append_varchar (parser, q, r);
}
is_delimiter = true;
}
if (alter->xbits.bit_comment)
{
if (is_delimiter)
{
q = pt_append_bytes (parser, q, (char *) ",", 1);
}
q = pt_append_nulstring (parser, q, " CHANGE COMMENT=");
if (alter->comment)
{
assert (alter->comment->node_type == PT_VALUE);
r = pt_print_bytes (parser, alter->comment);
q = pt_append_varchar (parser, q, r);
}
}
return q;
}
static PT_NODE *
pt_apply_alter_synonym (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, PT_SYNONYM_NAME (p), arg);
PT_APPLY_WALK (parser, PT_SYNONYM_TARGET_NAME (p), arg);
return p;
}
static PT_NODE *
pt_apply_create_synonym (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, PT_SYNONYM_NAME (p), arg);
PT_APPLY_WALK (parser, PT_SYNONYM_TARGET_NAME (p), arg);
return p;
}
static PT_NODE *
pt_apply_drop_synonym (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, PT_SYNONYM_NAME (p), arg);
return p;
}
static PT_NODE *
pt_apply_rename_synonym (PARSER_CONTEXT * parser, PT_NODE * p, void *arg)
{
PT_APPLY_WALK (parser, PT_SYNONYM_OLD_NAME (p), arg);
PT_APPLY_WALK (parser, PT_SYNONYM_NEW_NAME (p), arg);
return p;
}
static PARSER_VARCHAR *
pt_print_alter_synonym (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
unsigned int save_custom;
save_custom = parser->custom_print;
parser->custom_print |= PT_PRINT_NO_SPECIFIED_USER_NAME;
q = pt_append_nulstring (parser, q, "alters ");
/* private is not printed because PT_PRIVATE is the default. */
if (PT_SYNONYM_ACCESS_MODIFIER (p) == PT_PUBLIC)
{
q = pt_append_nulstring (parser, q, "public ");
}
q = pt_append_nulstring (parser, q, "synonym ");
r1 = pt_print_bytes (parser, PT_SYNONYM_OWNER_NAME (p));
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ".");
r1 = pt_print_bytes (parser, PT_SYNONYM_NAME (p));
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " for ");
assert (PT_SYNONYM_TARGET_NAME (p) != NULL || PT_SYNONYM_COMMENT (p) != NULL);
if (PT_SYNONYM_TARGET_NAME (p))
{
r1 = pt_print_bytes (parser, PT_SYNONYM_TARGET_OWNER_NAME (p));
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ".");
r1 = pt_print_bytes (parser, PT_SYNONYM_TARGET_NAME (p));
q = pt_append_varchar (parser, q, r1);
}
if (PT_SYNONYM_COMMENT (p))
{
r1 = pt_print_bytes (parser, PT_SYNONYM_COMMENT (p));
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
parser->custom_print = save_custom;
return q;
}
static PARSER_VARCHAR *
pt_print_create_synonym (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
unsigned int save_custom;
save_custom = parser->custom_print;
parser->custom_print |= PT_PRINT_NO_SPECIFIED_USER_NAME;
q = pt_append_nulstring (parser, q, "create ");
if (PT_SYNONYM_OR_REPLACE (p))
{
q = pt_append_nulstring (parser, q, "or replace ");
}
/* PT_PRIVATE is not printed because PT_PRIVATE is the default. */
if (PT_SYNONYM_ACCESS_MODIFIER (p) == PT_PUBLIC)
{
q = pt_append_nulstring (parser, q, "public ");
}
q = pt_append_nulstring (parser, q, "synonym ");
r1 = pt_print_bytes (parser, PT_SYNONYM_OWNER_NAME (p));
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ".");
r1 = pt_print_bytes (parser, PT_SYNONYM_NAME (p));
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " for ");
r1 = pt_print_bytes (parser, PT_SYNONYM_TARGET_OWNER_NAME (p));
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ".");
r1 = pt_print_bytes (parser, PT_SYNONYM_TARGET_NAME (p));
q = pt_append_varchar (parser, q, r1);
if (PT_SYNONYM_COMMENT (p))
{
r1 = pt_print_bytes (parser, PT_SYNONYM_COMMENT (p));
q = pt_append_nulstring (parser, q, " comment ");
q = pt_append_varchar (parser, q, r1);
}
parser->custom_print = save_custom;
return q;
}
static PARSER_VARCHAR *
pt_print_drop_synonym (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
unsigned int save_custom;
save_custom = parser->custom_print;
parser->custom_print |= PT_PRINT_NO_SPECIFIED_USER_NAME;
q = pt_append_nulstring (parser, q, "drop ");
/* private is not printed because PT_PRIVATE is the default. */
if (PT_SYNONYM_ACCESS_MODIFIER (p) == PT_PUBLIC)
{
q = pt_append_nulstring (parser, q, "public ");
}
q = pt_append_nulstring (parser, q, "synonym ");
if (PT_SYNONYM_IF_EXISTS (p))
{
q = pt_append_nulstring (parser, q, "if exists ");
}
r1 = pt_print_bytes (parser, PT_SYNONYM_OWNER_NAME (p));
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ".");
r1 = pt_print_bytes (parser, PT_SYNONYM_NAME (p));
q = pt_append_varchar (parser, q, r1);
parser->custom_print = save_custom;
return q;
}
static PARSER_VARCHAR *
pt_print_rename_synonym (PARSER_CONTEXT * parser, PT_NODE * p)
{
PARSER_VARCHAR *q = NULL, *r1;
unsigned int save_custom;
save_custom = parser->custom_print;
parser->custom_print |= PT_PRINT_NO_SPECIFIED_USER_NAME;
q = pt_append_nulstring (parser, q, "rename ");
/* private is not printed because PT_PRIVATE is the default. */
if (PT_SYNONYM_ACCESS_MODIFIER (p) == PT_PUBLIC)
{
q = pt_append_nulstring (parser, q, "public ");
}
q = pt_append_nulstring (parser, q, "synonym ");
r1 = pt_print_bytes (parser, PT_SYNONYM_OWNER_NAME (p));
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ".");
r1 = pt_print_bytes (parser, PT_SYNONYM_OLD_NAME (p));
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, " to ");
r1 = pt_print_bytes (parser, PT_SYNONYM_OWNER_NAME (p));
q = pt_append_varchar (parser, q, r1);
q = pt_append_nulstring (parser, q, ".");
r1 = pt_print_bytes (parser, PT_SYNONYM_NEW_NAME (p));
q = pt_append_varchar (parser, q, r1);
parser->custom_print = save_custom;
return q;
}