Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CBRD-24909] dblink related synonym processing #4513

Merged
merged 7 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions src/parser/csql_grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -3187,6 +3187,12 @@ create_stmt
{
PT_ERROR (this_parser, node, "PUBLIC SYNONYM is not supported.");
}

assert (PT_SYNONYM_TARGET_NAME (node) != NULL);
if (PT_NAME_INFO_IS_FLAGED (PT_SYNONYM_TARGET_NAME (node), PT_NAME_INFO_SERVER_SPECIFIED))
{
PT_SYNONYM_IS_DBLINKED (node) = 1;
}
}

$$ = node;
Expand All @@ -3203,12 +3209,21 @@ class_name_for_synonym
PT_NODE *cname = CONTAINER_AT_0 ($1);
PT_NODE *sname = CONTAINER_AT_1 ($1);

cname->info.name.original = pt_append_string (this_parser, cname->info.name.original, "@");
cname->info.name.original = pt_append_string (this_parser, cname->info.name.original, sname->info.name.original);
parser_free_tree(this_parser, sname);

// Set automatically assign a user name.
PT_NAME_INFO_SET_FLAG (cname, PT_NAME_INFO_USER_SPECIFIED);
if (cname && sname)
{
if (cname->info.name.resolved)
{
cname->info.name.original = pt_append_string (this_parser, ".", cname->info.name.original);
cname->info.name.original = pt_append_string (this_parser, cname->info.name.resolved, cname->info.name.original);
cname->info.name.resolved = NULL;
}
cname->info.name.original = pt_append_string (this_parser, cname->info.name.original, "@");
cname->info.name.original = pt_append_string (this_parser, cname->info.name.original, sname->info.name.original);

PT_NAME_INFO_SET_FLAG (cname, PT_NAME_INFO_SERVER_SPECIFIED);

parser_free_tree(this_parser, sname);
}

$$ = cname;
}
Expand Down Expand Up @@ -4058,6 +4073,14 @@ alter_stmt
{
PT_ERROR (this_parser, node, "PUBLIC SYNONYM is not supported.");
}

if (PT_SYNONYM_TARGET_NAME (node) != NULL)
{
if (PT_NAME_INFO_IS_FLAGED (PT_SYNONYM_TARGET_NAME (node), PT_NAME_INFO_SERVER_SPECIFIED))
{
PT_SYNONYM_IS_DBLINKED (node) = 1;
}
}
}

$$ = node;
Expand Down
3 changes: 3 additions & 0 deletions src/parser/parse_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,7 @@ struct json_t;
#define PT_SYNONYM_ACCESS_MODIFIER(n) ((n)->info.synonym.access_modifier)
#define PT_SYNONYM_OR_REPLACE(n) ((n)->info.synonym.or_replace)
#define PT_SYNONYM_IF_EXISTS(n) ((n)->info.synonym.if_exists)
#define PT_SYNONYM_IS_DBLINKED(n) ((n)->info.synonym.is_dblinked) /* for user.table@server */

/* Check node_type of PT_NODE */
#define PT_NODE_IS_EXPR(n) (PT_ASSERT_NOT_NULL ((n)), (n)->node_type == PT_EXPR)
Expand Down Expand Up @@ -2746,6 +2747,7 @@ struct pt_name_info
#define PT_NAME_FOR_UPDATE 2048 /* Table name in FOR UPDATE clause */
#define PT_NAME_DEFAULTF_ACCEPTS 4096 /* name of table/column that default function accepts: real table's, cte's */
#define PT_NAME_INFO_USER_SPECIFIED 8192 /* resolved_name is added to original_name to make user_specified_name. */
#define PT_NAME_INFO_SERVER_SPECIFIED 16384 /* server name is specified for dblink */

short flag;
#define PT_NAME_INFO_IS_FLAGED(e, f) ((e)->info.name.flag & (short) (f))
Expand Down Expand Up @@ -3533,6 +3535,7 @@ struct pt_synonym_info
PT_NODE *comment; /* PT_VALUE */
unsigned or_replace:1; /* OR REPLACE clause for CREATE SYNONYM */
unsigned if_exists:1; /* IF EXISTS clause for DROP SYNONYM */
unsigned is_dblinked:1; /* server name specified */
};

/* Info field of the basic NODE
Expand Down
20 changes: 18 additions & 2 deletions src/parser/parser_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -10451,9 +10451,17 @@ pt_set_user_specified_name (PARSER_CONTEXT * parser, PT_NODE * node, void *arg,
{
const char *target_owner_name = NULL;

if (PT_SYNONYM_IS_DBLINKED (node))
{
target_owner_name = synonym_owner_name;
}
else
{
target_owner_name = pt_get_qualifier_name (parser, PT_SYNONYM_TARGET_NAME (node));
}

/* When processing PT_NAME, resolved_name is prefixed to original_name.
* If original_name is the name of a system class/vclass, resolved_name is not prefixed to original_name. */
target_owner_name = pt_get_qualifier_name (parser, PT_SYNONYM_TARGET_NAME (node));
if (target_owner_name == NULL
&& sm_check_system_class_by_name (PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_NAME (node))) == true)
{
Expand Down Expand Up @@ -10481,9 +10489,17 @@ pt_set_user_specified_name (PARSER_CONTEXT * parser, PT_NODE * node, void *arg,
assert (synonym_owner_name != NULL);
PT_SYNONYM_OWNER_NAME (node) = pt_name (parser, synonym_owner_name);

if (PT_SYNONYM_IS_DBLINKED (node))
{
target_owner_name = synonym_owner_name;
}
else
{
target_owner_name = pt_get_qualifier_name (parser, PT_SYNONYM_TARGET_NAME (node));
}

/* When processing PT_NAME, resolved_name is prefixed to original_name.
* If original_name is the name of a system class/vclass, resolved_name is not prefixed to original_name. */
target_owner_name = pt_get_qualifier_name (parser, PT_SYNONYM_TARGET_NAME (node));
if (target_owner_name == NULL
&& sm_check_system_class_by_name (PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_NAME (node))) == true)
{
Expand Down
30 changes: 18 additions & 12 deletions src/parser/semantic_check.c
Original file line number Diff line number Diff line change
Expand Up @@ -8939,13 +8939,16 @@ pt_check_alter_synonym (PARSER_CONTEXT * parser, PT_NODE * node)
/* PT_SYNONYM_TARGET_NAME (node) != NULL */

/* target_owner_name */
owner_name = PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_OWNER_NAME (node));
assert (owner_name != NULL && *owner_name != '\0');
owner_obj = db_find_user (owner_name);
if (owner_obj == NULL)
if (!PT_SYNONYM_IS_DBLINKED (node))
{
PT_ERRORmf (parser, node, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_USER_IS_NOT_IN_DB, owner_name);
return;
owner_name = PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_OWNER_NAME (node));
assert (owner_name != NULL && *owner_name != '\0');
owner_obj = db_find_user (owner_name);
if (owner_obj == NULL)
{
PT_ERRORmf (parser, node, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_USER_IS_NOT_IN_DB, owner_name);
return;
}
}
}
}
Expand Down Expand Up @@ -9043,13 +9046,16 @@ pt_check_create_synonym (PARSER_CONTEXT * parser, PT_NODE * node)
* || (synonym_obj == NULL && db_find_class () == NULL && er_errid () == ER_LC_UNKNOWN_CLASSNAME) */

/* target_owner_name */
owner_name = PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_OWNER_NAME (node));
assert (owner_name != NULL && *owner_name != '\0');
owner_obj = db_find_user (owner_name);
if (owner_obj == NULL)
if (!PT_SYNONYM_IS_DBLINKED (node))
{
PT_ERRORmf (parser, node, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_USER_IS_NOT_IN_DB, owner_name);
return;
owner_name = PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_OWNER_NAME (node));
assert (owner_name != NULL && *owner_name != '\0');
owner_obj = db_find_user (owner_name);
if (owner_obj == NULL)
{
PT_ERRORmf (parser, node, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_USER_IS_NOT_IN_DB, owner_name);
return;
}
}
}

Expand Down
60 changes: 46 additions & 14 deletions src/query/execute_statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,10 @@ static int do_insert_checks (PARSER_CONTEXT * parser, PT_NODE * statement, PT_NO
PT_NODE ** update, PT_NODE * values);

static int do_alter_synonym_internal (const char *synonym_name, const char *target_name, DB_OBJECT * target_owner,
const char *comment, const int is_public_synonym);
const char *comment, const int is_public_synonym, bool is_dblinked);
static int do_create_synonym_internal (const char *synonym_name, DB_OBJECT * synonym_owner, const char *target_name,
DB_OBJECT * target_owner, const char *comment, const int is_public_synonym,
const int or_replace);
const int or_replace, bool is_dblinked);
static int do_drop_synonym_internal (const char *synonym_name, const int is_public_synonym, const int if_exists,
DB_OBJECT * synonym_class_obj, DB_OBJECT * synonym_obj);
static int do_rename_synonym_internal (const char *old_synonym_name, const char *new_synonym_name);
Expand Down Expand Up @@ -17775,10 +17775,16 @@ do_alter_synonym (PARSER_CONTEXT * parser, PT_NODE * statement)
else
{
/* PT_SYNONYM_TARGET_NAME (statement) != NULL */

sm_user_specified_name (PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_NAME (statement)), target_name_buf,
DB_MAX_IDENTIFIER_LENGTH);
target_name = target_name_buf;
if (PT_SYNONYM_IS_DBLINKED (statement))
{
target_name = PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_NAME (statement));
}
else
{
sm_user_specified_name (PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_NAME (statement)), target_name_buf,
DB_MAX_IDENTIFIER_LENGTH);
target_name = target_name_buf;
}

/* target_owner */
target_owner_obj = db_find_user (PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_OWNER_NAME (statement)));
Expand All @@ -17796,7 +17802,9 @@ do_alter_synonym (PARSER_CONTEXT * parser, PT_NODE * statement)
comment = (char *) PT_SYNONYM_COMMENT_BYTES (statement);
}

error = do_alter_synonym_internal (synonym_name, target_name, target_owner_obj, comment, FALSE);
error =
do_alter_synonym_internal (synonym_name, target_name, target_owner_obj, comment, FALSE,
PT_SYNONYM_IS_DBLINKED (statement));
if (error != NO_ERROR)
{
ASSERT_ERROR ();
Expand All @@ -17816,7 +17824,7 @@ do_alter_synonym (PARSER_CONTEXT * parser, PT_NODE * statement)
*/
static int
do_alter_synonym_internal (const char *synonym_name, const char *target_name, DB_OBJECT * target_owner,
const char *comment, const int is_public_synonym)
const char *comment, const int is_public_synonym, bool is_dblinked)
{
DB_OBJECT *class_obj = NULL;
DB_OBJECT *instance_obj = NULL;
Expand Down Expand Up @@ -17891,7 +17899,14 @@ do_alter_synonym_internal (const char *synonym_name, const char *target_name, DB
}

/* target_name */
db_make_string (&value, sm_remove_qualifier_name (target_name));
if (is_dblinked)
{
db_make_string (&value, target_name);
}
else
{
db_make_string (&value, sm_remove_qualifier_name (target_name));
}
error = dbt_put_internal (obj_tmpl, "target_name", &value);
db_value_clear (&value);
if (error != NO_ERROR)
Expand Down Expand Up @@ -17977,7 +17992,8 @@ do_create_synonym (PARSER_CONTEXT * parser, PT_NODE * statement)
DB_OBJECT *synonym_owner_obj = NULL;
DB_OBJECT *target_owner_obj = NULL;
char synonym_name[DB_MAX_IDENTIFIER_LENGTH] = { '\0' };
char target_name[DB_MAX_IDENTIFIER_LENGTH] = { '\0' };
const char *target_name = NULL;
char target_name_buf[DB_MAX_IDENTIFIER_LENGTH] = { '\0' };
const char *comment = NULL;
int or_replace = FALSE;
int error = NO_ERROR;
Expand Down Expand Up @@ -18005,7 +18021,16 @@ do_create_synonym (PARSER_CONTEXT * parser, PT_NODE * statement)
or_replace = PT_SYNONYM_OR_REPLACE (statement);

/* target_name */
sm_user_specified_name (PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_NAME (statement)), target_name, DB_MAX_IDENTIFIER_LENGTH);
if (PT_SYNONYM_IS_DBLINKED (statement))
{
target_name = PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_NAME (statement));
}
else
{
sm_user_specified_name (PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_NAME (statement)), target_name_buf,
DB_MAX_IDENTIFIER_LENGTH);
target_name = target_name_buf;
}

/* target_owner */
target_owner_obj = au_find_user (PT_NAME_ORIGINAL (PT_SYNONYM_TARGET_OWNER_NAME (statement)));
Expand All @@ -18024,7 +18049,7 @@ do_create_synonym (PARSER_CONTEXT * parser, PT_NODE * statement)

error =
do_create_synonym_internal (synonym_name, synonym_owner_obj, target_name, target_owner_obj, comment, FALSE,
or_replace);
or_replace, PT_SYNONYM_IS_DBLINKED (statement));
if (error != NO_ERROR)
{
ASSERT_ERROR ();
Expand All @@ -18047,7 +18072,7 @@ do_create_synonym (PARSER_CONTEXT * parser, PT_NODE * statement)
static int
do_create_synonym_internal (const char *synonym_name, DB_OBJECT * synonym_owner, const char *target_name,
DB_OBJECT * target_owner, const char *comment, const int is_public_synonym,
const int or_replace)
const int or_replace, bool is_dblinked)
{
DB_OBJECT *class_obj = NULL;
DB_OBJECT *instance_obj = NULL;
Expand Down Expand Up @@ -18182,7 +18207,14 @@ do_create_synonym_internal (const char *synonym_name, DB_OBJECT * synonym_owner,
}

/* target_name */
db_make_string (&value, sm_remove_qualifier_name (target_name));
if (is_dblinked)
{
db_make_string (&value, target_name);
}
else
{
db_make_string (&value, sm_remove_qualifier_name (target_name));
}
error = dbt_put_internal (obj_tmpl, "target_name", &value);
db_value_clear (&value);
if (error != NO_ERROR)
Expand Down
Loading