From 7782e1d46a196e04ed3972d0bf34c91fc508f386 Mon Sep 17 00:00:00 2001 From: beyondykk Date: Thu, 28 Dec 2023 10:51:08 +0900 Subject: [PATCH 1/5] [CBRD-25139] When using oracle style empty string, the result of replace is null. --- src/parser/type_checking.c | 18 ++++++++++++++++-- src/query/fetch.c | 3 ++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/parser/type_checking.c b/src/parser/type_checking.c index 10a55372da9..f63981cff12 100644 --- a/src/parser/type_checking.c +++ b/src/parser/type_checking.c @@ -18237,17 +18237,31 @@ pt_fold_const_expr (PARSER_CONTEXT * parser, PT_NODE * expr, void *arg) } if (prm_get_bool_value (PRM_ID_ORACLE_STYLE_EMPTY_STRING) - && (op == PT_STRCAT || op == PT_PLUS || op == PT_CONCAT || op == PT_CONCAT_WS)) + && (op == PT_STRCAT || op == PT_PLUS || op == PT_CONCAT || op == PT_CONCAT_WS || op == PT_REPLACE)) { TP_DOMAIN *domain; + if (op == PT_REPLACE) + { + opd3 = expr->info.expr.arg3; + type3 = (opd3) ? opd3->type_enum : PT_TYPE_NULL; + } + /* use the caching variant of this function ! */ domain = pt_xasl_node_to_domain (parser, expr); if (domain && (QSTR_IS_ANY_CHAR_OR_BIT (TP_DOMAIN_TYPE (domain)) || type1 == PT_TYPE_NULL || type2 == PT_TYPE_NULL)) { - if (opd1 && opd1->node_type == PT_VALUE && type1 == PT_TYPE_NULL) + if (opd3 && opd3->node_type == PT_VALUE && type3 == PT_TYPE_NULL) /* REPLACE */ + { + result = parser_copy_tree (parser, opd1); + if (result == NULL) + { + has_error = true; + } + } + else if (opd1 && opd1->node_type == PT_VALUE && type1 == PT_TYPE_NULL) { /* fold 'null || char_opnd' expr to 'char_opnd' */ result = parser_copy_tree (parser, opd2); diff --git a/src/query/fetch.c b/src/query/fetch.c index 49aa7e80373..1810c92df2b 100644 --- a/src/query/fetch.c +++ b/src/query/fetch.c @@ -1551,7 +1551,8 @@ fetch_peek_arith (THREAD_ENTRY * thread_p, REGU_VARIABLE * regu_var, val_descr * goto error; } } - if (DB_IS_NULL (peek_left) || (peek_third && DB_IS_NULL (peek_third))) + if (!prm_get_bool_value (PRM_ID_ORACLE_STYLE_EMPTY_STRING) + && (DB_IS_NULL (peek_left) || (peek_third && DB_IS_NULL (peek_third)))) { PRIM_SET_NULL (arithptr->value); } From b86ae299153c9ad6b9bbf6a2bf6ca299c0153083 Mon Sep 17 00:00:00 2001 From: beyondykk Date: Fri, 29 Dec 2023 09:58:02 +0900 Subject: [PATCH 2/5] refine code --- src/parser/type_checking.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/parser/type_checking.c b/src/parser/type_checking.c index f63981cff12..ac6ba01a396 100644 --- a/src/parser/type_checking.c +++ b/src/parser/type_checking.c @@ -18268,7 +18268,6 @@ pt_fold_const_expr (PARSER_CONTEXT * parser, PT_NODE * expr, void *arg) if (result == NULL) { has_error = true; - goto end; } } else if (opd2 && opd2->node_type == PT_VALUE && type2 == PT_TYPE_NULL) @@ -18278,7 +18277,6 @@ pt_fold_const_expr (PARSER_CONTEXT * parser, PT_NODE * expr, void *arg) if (result == NULL) { has_error = true; - goto end; } } From 03677d7c0ee1ec30ea49f4d6b3d92ffadd3602b2 Mon Sep 17 00:00:00 2001 From: beyondykk Date: Tue, 2 Jan 2024 10:00:17 +0900 Subject: [PATCH 3/5] fix, empty string as NULL --- src/parser/type_checking.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/parser/type_checking.c b/src/parser/type_checking.c index ac6ba01a396..8a3165e5be3 100644 --- a/src/parser/type_checking.c +++ b/src/parser/type_checking.c @@ -18255,11 +18255,18 @@ pt_fold_const_expr (PARSER_CONTEXT * parser, PT_NODE * expr, void *arg) { if (opd3 && opd3->node_type == PT_VALUE && type3 == PT_TYPE_NULL) /* REPLACE */ { - result = parser_copy_tree (parser, opd1); - if (result == NULL) + /* need to replace the NULL with empty string */ + int err = + db_string_make_empty_typed_string (&opd3->info.value.db_value, DB_TYPE_STRING, DB_DEFAULT_PRECISION, + TP_DOMAIN_CODESET (domain), TP_DOMAIN_COLLATION (domain)); + if (err != NO_ERROR) { has_error = true; } + else + { + result = expr; + } } else if (opd1 && opd1->node_type == PT_VALUE && type1 == PT_TYPE_NULL) { From 752ddbd8d3e97b30660c2461b3c661309f6f0aa8 Mon Sep 17 00:00:00 2001 From: beyondykk Date: Tue, 2 Jan 2024 13:32:36 +0900 Subject: [PATCH 4/5] Empty-Commit for appveyor fail From ad5832c1dbc20a8d84c05d5a6b20100eb5c2339a Mon Sep 17 00:00:00 2001 From: beyondykk Date: Tue, 2 Jan 2024 16:35:46 +0900 Subject: [PATCH 5/5] replace(null,arg1,arg2) handling --- src/parser/type_checking.c | 25 ++++++++++++++----------- src/query/fetch.c | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/parser/type_checking.c b/src/parser/type_checking.c index 8a3165e5be3..e8bdfe8164a 100644 --- a/src/parser/type_checking.c +++ b/src/parser/type_checking.c @@ -18253,19 +18253,22 @@ pt_fold_const_expr (PARSER_CONTEXT * parser, PT_NODE * expr, void *arg) if (domain && (QSTR_IS_ANY_CHAR_OR_BIT (TP_DOMAIN_TYPE (domain)) || type1 == PT_TYPE_NULL || type2 == PT_TYPE_NULL)) { - if (opd3 && opd3->node_type == PT_VALUE && type3 == PT_TYPE_NULL) /* REPLACE */ + if (opd3) /* REPLACE */ { - /* need to replace the NULL with empty string */ - int err = - db_string_make_empty_typed_string (&opd3->info.value.db_value, DB_TYPE_STRING, DB_DEFAULT_PRECISION, - TP_DOMAIN_CODESET (domain), TP_DOMAIN_COLLATION (domain)); - if (err != NO_ERROR) - { - has_error = true; - } - else + if (opd3->node_type == PT_VALUE && type3 == PT_TYPE_NULL) { - result = expr; + /* need to replace the NULL with empty string */ + int err = + db_string_make_empty_typed_string (&opd3->info.value.db_value, DB_TYPE_STRING, DB_DEFAULT_PRECISION, + TP_DOMAIN_CODESET (domain), TP_DOMAIN_COLLATION (domain)); + if (err != NO_ERROR) + { + has_error = true; + } + else + { + result = expr; + } } } else if (opd1 && opd1->node_type == PT_VALUE && type1 == PT_TYPE_NULL) diff --git a/src/query/fetch.c b/src/query/fetch.c index 1810c92df2b..a2106656d2c 100644 --- a/src/query/fetch.c +++ b/src/query/fetch.c @@ -1552,7 +1552,7 @@ fetch_peek_arith (THREAD_ENTRY * thread_p, REGU_VARIABLE * regu_var, val_descr * } } if (!prm_get_bool_value (PRM_ID_ORACLE_STYLE_EMPTY_STRING) - && (DB_IS_NULL (peek_left) || (peek_third && DB_IS_NULL (peek_third)))) + && (DB_IS_NULL (peek_left) || DB_IS_NULL (peek_right) || (peek_third && DB_IS_NULL (peek_third)))) { PRIM_SET_NULL (arithptr->value); }