From dbc856db93db457f11411bbfe4ce203829e481db Mon Sep 17 00:00:00 2001 From: luo_zihao5524 Date: Tue, 11 Jul 2023 20:47:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=96=B0=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E6=8E=A7=E5=88=B6A=E5=85=BC=E5=AE=B9=E6=80=A7=E4=B8=8B?= =?UTF-8?q?=E7=A9=BA=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=84=8F=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/parser/gram.y | 2 +- src/common/backend/parser/hint_gram.y | 2 +- src/common/backend/utils/adt/a_compat.cpp | 29 +- src/common/backend/utils/adt/format_type.cpp | 3 +- src/common/backend/utils/adt/nlssort.cpp | 3 +- src/common/backend/utils/adt/regexp.cpp | 12 +- src/common/backend/utils/adt/varchar.cpp | 2 +- src/common/backend/utils/adt/varlena.cpp | 81 +- src/common/backend/utils/misc/guc/guc_sql.cpp | 3 +- src/gausskernel/optimizer/commands/copy.cpp | 4 +- src/gausskernel/process/tcop/postgres.cpp | 13 +- .../codegen/codegenutil/varlenacodegen.cpp | 18 +- .../codegen/vecexecutor/vecexprcodegen.cpp | 6 +- src/gausskernel/runtime/opfusion/opfusion.cpp | 4 +- .../vecexecutor/vecprimitive/varchar.inl | 2 +- src/include/miscadmin.h | 4 +- .../regress/expected/accept_empty_str.out | 1815 ++++++++++++++++ .../regress/expected/not_accept_empty_str.out | 1822 +++++++++++++++++ src/test/regress/expected/pg_empty_str.out | 1817 ++++++++++++++++ .../regress/input/accept_empty_copy.source | 33 + .../input/not_accept_empty_copy.source | 33 + .../regress/output/accept_empty_copy.source | 107 + .../output/not_accept_empty_copy.source | 107 + src/test/regress/parallel_schedule0A | 3 + src/test/regress/sql/accept_empty_str.sql | 405 ++++ src/test/regress/sql/not_accept_empty_str.sql | 405 ++++ src/test/regress/sql/pg_empty_str.sql | 407 ++++ 27 files changed, 7069 insertions(+), 73 deletions(-) create mode 100644 src/test/regress/expected/accept_empty_str.out create mode 100644 src/test/regress/expected/not_accept_empty_str.out create mode 100644 src/test/regress/expected/pg_empty_str.out create mode 100644 src/test/regress/input/accept_empty_copy.source create mode 100644 src/test/regress/input/not_accept_empty_copy.source create mode 100644 src/test/regress/output/accept_empty_copy.source create mode 100644 src/test/regress/output/not_accept_empty_copy.source create mode 100644 src/test/regress/sql/accept_empty_str.sql create mode 100644 src/test/regress/sql/not_accept_empty_str.sql create mode 100644 src/test/regress/sql/pg_empty_str.sql diff --git a/src/common/backend/parser/gram.y b/src/common/backend/parser/gram.y index 5310d636ba..46f0d7869c 100644 --- a/src/common/backend/parser/gram.y +++ b/src/common/backend/parser/gram.y @@ -24603,7 +24603,7 @@ makeStringConst(char *str, int location) if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { - if (NULL == str || 0 == strlen(str)) + if (NULL == str || (0 == strlen(str) && !ACCEPT_EMPTY_STR)) { n->val.type = T_Null; n->val.val.str = str; diff --git a/src/common/backend/parser/hint_gram.y b/src/common/backend/parser/hint_gram.y index dcc4b37fff..72901f17a2 100755 --- a/src/common/backend/parser/hint_gram.y +++ b/src/common/backend/parser/hint_gram.y @@ -672,7 +672,7 @@ makeStringValue(char *str) if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { - if (NULL == str || 0 == strlen(str)) + if (NULL == str || (0 == strlen(str) && !ACCEPT_EMPTY_STR)) { val->type = T_Null; val->val.str = str; diff --git a/src/common/backend/utils/adt/a_compat.cpp b/src/common/backend/utils/adt/a_compat.cpp index 00ef60dcf7..eb99d69f3a 100644 --- a/src/common/backend/utils/adt/a_compat.cpp +++ b/src/common/backend/utils/adt/a_compat.cpp @@ -204,7 +204,8 @@ Datum lpad(PG_FUNCTION_ARGS) SET_VARSIZE(ret, ptr_ret - (char*)ret); - if (0 == VARSIZE_ANY_EXHDR(ret) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !RETURN_NS) + if (0 == VARSIZE_ANY_EXHDR(ret) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && + !ACCEPT_EMPTY_STR && !RETURN_NS) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(ret); @@ -300,7 +301,8 @@ Datum rpad(PG_FUNCTION_ARGS) SET_VARSIZE(ret, ptr_ret - (char*)ret); - if (0 == VARSIZE_ANY_EXHDR(ret) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !RETURN_NS) + if (0 == VARSIZE_ANY_EXHDR(ret) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && + !ACCEPT_EMPTY_STR && !RETURN_NS) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(ret); @@ -331,7 +333,8 @@ Datum btrim(PG_FUNCTION_ARGS) ret = dotrim(VARDATA_ANY(string), VARSIZE_ANY_EXHDR(string), VARDATA_ANY(set), VARSIZE_ANY_EXHDR(set), true, true); - if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && + !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(ret); @@ -352,7 +355,8 @@ Datum btrim1(PG_FUNCTION_ARGS) ret = dotrim(VARDATA_ANY(string), VARSIZE_ANY_EXHDR(string), " ", 1, true, true); - if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && + !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(ret); @@ -589,7 +593,8 @@ Datum ltrim(PG_FUNCTION_ARGS) ret = dotrim(VARDATA_ANY(string), VARSIZE_ANY_EXHDR(string), VARDATA_ANY(set), VARSIZE_ANY_EXHDR(set), true, false); - if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && + !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(ret); @@ -609,7 +614,8 @@ Datum ltrim1(PG_FUNCTION_ARGS) ret = dotrim(VARDATA_ANY(string), VARSIZE_ANY_EXHDR(string), " ", 1, true, false); - if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && + !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(ret); @@ -639,7 +645,8 @@ Datum rtrim(PG_FUNCTION_ARGS) ret = dotrim(VARDATA_ANY(string), VARSIZE_ANY_EXHDR(string), VARDATA_ANY(set), VARSIZE_ANY_EXHDR(set), false, true); - if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && + !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(ret); @@ -668,7 +675,8 @@ Datum rtrim1(PG_FUNCTION_ARGS) ret = dotrim(VARDATA_ANY(string), VARSIZE_ANY_EXHDR(string), " ", 1, false, true); } - if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && + !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(ret); @@ -775,7 +783,7 @@ Datum translate(PG_FUNCTION_ARGS) m -= source_len; } - if (0 == retlen && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (0 == retlen && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { PG_RETURN_NULL(); } else { SET_VARSIZE(result, retlen + VARHDRSZ); @@ -999,7 +1007,8 @@ Datum repeat(PG_FUNCTION_ARGS) tlen -= slen; } - if (0 == VARSIZE_ANY_EXHDR(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !RETURN_NS) { + if (0 == VARSIZE_ANY_EXHDR(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && + !ACCEPT_EMPTY_STR && !RETURN_NS) { PG_RETURN_NULL(); } else PG_RETURN_TEXT_P(result); diff --git a/src/common/backend/utils/adt/format_type.cpp b/src/common/backend/utils/adt/format_type.cpp index 74f5cf7eed..e910bd5be8 100644 --- a/src/common/backend/utils/adt/format_type.cpp +++ b/src/common/backend/utils/adt/format_type.cpp @@ -455,7 +455,8 @@ Datum oidvectortypes(PG_FUNCTION_ARGS) left -= slen; } - if ((!strcmp(result, "")) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !RETURN_NS) { + if ((!strcmp(result, "")) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && + !ACCEPT_EMPTY_STR && !RETURN_NS) { pfree_ext(result); PG_RETURN_NULL(); } diff --git a/src/common/backend/utils/adt/nlssort.cpp b/src/common/backend/utils/adt/nlssort.cpp index a0ddfb22f7..aae2a9b76c 100644 --- a/src/common/backend/utils/adt/nlssort.cpp +++ b/src/common/backend/utils/adt/nlssort.cpp @@ -23,6 +23,7 @@ * --------------------------------------------------------------------------------------- */ #include "postgres.h" +#include "miscadmin.h" #include "mb/pg_wchar.h" #include "utils/builtins.h" #include "knl/knl_session.h" @@ -71,7 +72,7 @@ Datum nlssort(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } if (VARSIZE_ANY_EXHDR(PG_GETARG_TEXT_P(0)) == 0) { - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { PG_RETURN_NULL(); } else { PG_RETURN_TEXT_P(cstring_to_text("\0")); diff --git a/src/common/backend/utils/adt/regexp.cpp b/src/common/backend/utils/adt/regexp.cpp index 78dc1dec4d..23d8b390ba 100644 --- a/src/common/backend/utils/adt/regexp.cpp +++ b/src/common/backend/utils/adt/regexp.cpp @@ -613,7 +613,7 @@ Datum regexp_replace(PG_FUNCTION_ARGS) re = RE_compile_and_cache(pattern, re_flags.cflags, PG_GET_COLLATION()); result = replace_text_regexp(src, (void*)re, r, position, occurrence); - if (VARHDRSZ == VARSIZE(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (VARHDRSZ == VARSIZE(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(result); @@ -684,7 +684,7 @@ Datum textregexreplace_noopt(PG_FUNCTION_ARGS) result = replace_text_regexp(s, (void*)re, r, 1, occurrence); - if (VARHDRSZ == VARSIZE(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (VARHDRSZ == VARSIZE(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(result); @@ -739,7 +739,7 @@ Datum textregexreplace(PG_FUNCTION_ARGS) result = replace_text_regexp(s, (void*)re, r, 1, occurrence); - if (VARHDRSZ == VARSIZE(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (VARHDRSZ == VARSIZE(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(result); @@ -1276,13 +1276,13 @@ static ArrayType* build_regexp_matches_result(regexp_matches_ctx* matchctx) /* return value datatype must be text */ #define RESET_NULL_FLAG(_result) \ do { \ - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !RETURN_NS) { \ + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !RETURN_NS && !ACCEPT_EMPTY_STR) { \ if ((_result) == ((Datum)0)) { \ fcinfo->isnull = true; \ } else { \ text *t = DatumGetTextP((_result)); \ fcinfo->isnull = false; \ - if (VARSIZE_ANY_EXHDR(t) == 0) { \ + if (VARSIZE_ANY_EXHDR(t) == 0 && !ACCEPT_EMPTY_STR) { \ fcinfo->isnull = true; \ (_result) = (Datum)0; \ } \ @@ -1689,7 +1689,7 @@ Datum regexp_substr_core(PG_FUNCTION_ARGS) PG_GET_COLLATION()); if (ret == NULL || (VARHDRSZ == VARSIZE(ret) && - u_sess->attr.attr_sql.sql_compatibility == A_FORMAT)) { + u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR)) { PG_RETURN_NULL(); } else { PG_RETURN_TEXT_P(ret); diff --git a/src/common/backend/utils/adt/varchar.cpp b/src/common/backend/utils/adt/varchar.cpp index 9d3756fd11..1503ef7ebd 100644 --- a/src/common/backend/utils/adt/varchar.cpp +++ b/src/common/backend/utils/adt/varchar.cpp @@ -1520,7 +1520,7 @@ static void vlpad_internal(ScalarVector* parg1, ScalarVector* parg2, ScalarVecto SET_VARSIZE(ret, ptr_ret - (char*)ret); - if (0 == VARSIZE_ANY_EXHDR(ret) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !RETURN_NS) { + if (0 == VARSIZE_ANY_EXHDR(ret) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR && !RETURN_NS) { SET_NULL(pflagsRes[idx]); } else { VecRet->m_vals[idx] = PointerGetDatum(ret); diff --git a/src/common/backend/utils/adt/varlena.cpp b/src/common/backend/utils/adt/varlena.cpp index e6d4e897c2..50a5adafd4 100644 --- a/src/common/backend/utils/adt/varlena.cpp +++ b/src/common/backend/utils/adt/varlena.cpp @@ -135,6 +135,8 @@ static void text_format_append_string(StringInfo buf, const char* str, int flags // adapt A db's substrb static text* get_substring_really(Datum str, int32 start, int32 length, bool length_not_specified); +static text* get_result_of_concat(text* result, FunctionCallInfo fcinfo); + /***************************************************************************** * CONVERSION ROUTINES EXPORTED FOR USE BY C CODE * *****************************************************************************/ @@ -3106,7 +3108,7 @@ Datum bytea_substr_orclcompat(PG_FUNCTION_ARGS) total = toast_raw_datum_size(str) - VARHDRSZ; if ((length < 0) || (start > total) || (start + total < 0)) { - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT || + if ((u_sess->attr.attr_sql.sql_compatibility == A_FORMAT&& !ACCEPT_EMPTY_STR) || u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) PG_RETURN_NULL(); else { @@ -3120,10 +3122,12 @@ Datum bytea_substr_orclcompat(PG_FUNCTION_ARGS) */ result = bytea_substring_orclcompat(str, start, length, false); - if ((NULL == result || 0 == VARSIZE_ANY_EXHDR(result)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (NULL == result || (0 == VARSIZE_ANY_EXHDR(result) && + u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR)) { PG_RETURN_NULL(); - else - PG_RETURN_BYTEA_P(result); + } + + PG_RETURN_BYTEA_P(result); } // adapt A db's substr(bytea x,integer y) @@ -3138,7 +3142,7 @@ Datum bytea_substr_no_len_orclcompat(PG_FUNCTION_ARGS) total = toast_raw_datum_size(str) - VARHDRSZ; if ((start > total) || (start + total < 0)) { - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else { result = PG_STR_GET_BYTEA(""); @@ -3151,10 +3155,12 @@ Datum bytea_substr_no_len_orclcompat(PG_FUNCTION_ARGS) */ result = bytea_substring_orclcompat(str, start, -1, true); - if ((NULL == result || 0 == VARSIZE_ANY_EXHDR(result)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (NULL == result || (0 == VARSIZE_ANY_EXHDR(result) && + u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR)) { PG_RETURN_NULL(); - else - PG_RETURN_BYTEA_P(result); + } + + PG_RETURN_BYTEA_P(result); } // Does the real work for bytea_substr_orclcompat() and bytea_substr_no_len_orclcompat(). @@ -4219,10 +4225,12 @@ Datum replace_text(PG_FUNCTION_ARGS) ret_text = cstring_to_text_with_len(str.data, str.len); pfree_ext(str.data); - if (VARHDRSZ == VARSIZE(ret_text) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (VARHDRSZ == VARSIZE(ret_text) && + u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { PG_RETURN_NULL(); - else - PG_RETURN_TEXT_P(ret_text); + } + + PG_RETURN_TEXT_P(ret_text); } /* @@ -4510,7 +4518,7 @@ Datum split_text(PG_FUNCTION_ARGS) if (inputstring_len < 1) { text_position_cleanup(&state); - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !RETURN_NS) { + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR && !RETURN_NS) { PG_RETURN_NULL(); } @@ -4525,7 +4533,7 @@ Datum split_text(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(inputstring); } - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !RETURN_NS) { + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR && !RETURN_NS) { PG_RETURN_NULL(); } @@ -4544,7 +4552,7 @@ Datum split_text(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(inputstring); } - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { PG_RETURN_NULL(); } @@ -4571,7 +4579,7 @@ Datum split_text(PG_FUNCTION_ARGS) result_text = text_substring(PointerGetDatum(inputstring), start_posn, end_posn - start_posn, false); } - if (TEXTISORANULL(result_text) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (TEXTISORANULL(result_text) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { PG_RETURN_NULL(); } @@ -4763,7 +4771,7 @@ Datum array_to_text(PG_FUNCTION_ARGS) result = array_to_text_internal(fcinfo, v, fldsep, NULL); /* To A db, empty string need return NULL.*/ - if (0 == VARSIZE_ANY_EXHDR(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (0 == VARSIZE_ANY_EXHDR(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { PG_RETURN_NULL(); } else { PG_RETURN_TEXT_P(result); @@ -4800,7 +4808,7 @@ Datum array_to_text_null(PG_FUNCTION_ARGS) result = array_to_text_internal(fcinfo, v, fldsep, null_string); /* To A db, empty string need return NULL.*/ - if (0 == VARSIZE_ANY_EXHDR(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (0 == VARSIZE_ANY_EXHDR(result) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { PG_RETURN_NULL(); } else { PG_RETURN_TEXT_P(result); @@ -5906,11 +5914,25 @@ static text* concat_internal(const char* sepstr, int seplen, int argidx, Functio result = cstring_to_text_with_len(str.data, str.len); pfree_ext(str.data); - if ((result == NULL || (0 == VARSIZE_ANY_EXHDR(result) && !DB_IS_CMPT(B_FORMAT | PG_FORMAT))) && - (CONCAT_VARIADIC || DB_IS_CMPT(A_FORMAT))) + return get_result_of_concat(result, fcinfo); +} + +static text* get_result_of_concat(text* result, FunctionCallInfo fcinfo) +{ + if (result == NULL) { PG_RETURN_NULL(); - else + } + + if (VARSIZE_ANY_EXHDR(result) > 0 || + DB_IS_CMPT(B_FORMAT | PG_FORMAT) || + (DB_IS_CMPT(A_FORMAT) && ACCEPT_EMPTY_STR)) { return result; + } + + if (DB_IS_CMPT(A_FORMAT) || CONCAT_VARIADIC) { + PG_RETURN_NULL(); + } + return result; } /* @@ -5971,7 +5993,7 @@ Datum text_left(PG_FUNCTION_ARGS) } rlen = pg_mbcharcliplen(p, len, part_off); - if (0 == rlen && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (0 == rlen && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { PG_RETURN_NULL(); } @@ -6008,7 +6030,7 @@ Datum text_right(PG_FUNCTION_ARGS) } } off = pg_mbcharcliplen(p, len, part_off); - if (0 == (len - off) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (0 == (len - off) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { PG_RETURN_NULL(); } @@ -6307,7 +6329,8 @@ Datum text_format(PG_FUNCTION_ARGS) result = cstring_to_text_with_len(str.data, str.len); pfree_ext(str.data); - if ((result == NULL || VARSIZE_ANY_EXHDR(result) == 0) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (result == NULL || + (VARSIZE_ANY_EXHDR(result) == 0 && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR)) PG_RETURN_NULL(); else PG_RETURN_TEXT_P(result); @@ -6673,7 +6696,7 @@ Datum substrb_with_lenth(PG_FUNCTION_ARGS) int32 total = 0; total = toast_raw_datum_size(str) - VARHDRSZ; if ((length < 0) || (total == 0) || (start > total) || (start + total < 0)) { - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else { result = cstring_to_text(""); @@ -6682,8 +6705,10 @@ Datum substrb_with_lenth(PG_FUNCTION_ARGS) } result = get_substring_really(str, start, length, false); - if ((NULL == result || 0 == VARSIZE_ANY_EXHDR(result)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if ((NULL == result || 0 == VARSIZE_ANY_EXHDR(result)) && + u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { PG_RETURN_NULL(); + } PG_RETURN_TEXT_P(result); } @@ -6698,7 +6723,7 @@ Datum substrb_without_lenth(PG_FUNCTION_ARGS) int32 total = 0; total = toast_raw_datum_size(str) - VARHDRSZ; if ((total == 0) || (start > total) || (start + total < 0)) { - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) PG_RETURN_NULL(); else { result = cstring_to_text(""); @@ -6707,8 +6732,10 @@ Datum substrb_without_lenth(PG_FUNCTION_ARGS) } result = get_substring_really(str, start, -1, true); - if ((NULL == result || 0 == VARSIZE_ANY_EXHDR(result)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if ((NULL == result || 0 == VARSIZE_ANY_EXHDR(result)) && + u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { PG_RETURN_NULL(); + } PG_RETURN_TEXT_P(result); } diff --git a/src/common/backend/utils/misc/guc/guc_sql.cpp b/src/common/backend/utils/misc/guc/guc_sql.cpp index 20f7254004..9996c3f7d9 100755 --- a/src/common/backend/utils/misc/guc/guc_sql.cpp +++ b/src/common/backend/utils/misc/guc/guc_sql.cpp @@ -356,7 +356,8 @@ static const struct behavior_compat_entry behavior_compat_options[OPT_MAX] = { {"compat_cursor", OPT_COMPAT_CURSOR}, {"char_coerce_compat", OPT_CHAR_COERCE_COMPAT}, {"truncate_numeric_tail_zero", OPT_TRUNC_NUMERIC_TAIL_ZERO}, - {"array_count_compat", OPT_ARRAY_COUNT_COMPAT} + {"array_count_compat", OPT_ARRAY_COUNT_COMPAT}, + {"accept_empty_str", OPT_ACCEPT_EMPTY_STR} }; static const struct behavior_compat_entry plsql_compile_check_options[PLPSQL_OPT_MAX] = { diff --git a/src/gausskernel/optimizer/commands/copy.cpp b/src/gausskernel/optimizer/commands/copy.cpp index 35637fb6a9..b130f7d3f3 100644 --- a/src/gausskernel/optimizer/commands/copy.cpp +++ b/src/gausskernel/optimizer/commands/copy.cpp @@ -6182,8 +6182,8 @@ bool NextCopyFrom(CopyState cstate, ExprContext* econtext, Datum* values, bool* * 1. A db SQL compatibility requires; or * 2. This column donesn't accept any empty string. */ - if ((u_sess->attr.attr_sql.sql_compatibility == A_FORMAT || !accept_empty_str[m]) && - (string != NULL && string[0] == '\0')) { + if (((u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) || + !accept_empty_str[m]) && (string != NULL && string[0] == '\0')) { /* for any type, '' = null */ string = NULL; } diff --git a/src/gausskernel/process/tcop/postgres.cpp b/src/gausskernel/process/tcop/postgres.cpp index 7c535af485..4cf69495b4 100755 --- a/src/gausskernel/process/tcop/postgres.cpp +++ b/src/gausskernel/process/tcop/postgres.cpp @@ -3847,8 +3847,8 @@ static int getSingleNodeIdx(StringInfo input_message, CachedPlanSource* psrc, co plength = pq_getmsgint(input_message, 4); isNull = (plength == -1); /* add null value process for date type */ - if ((VARCHAROID == ptype || TIMESTAMPOID == ptype || TIMESTAMPTZOID == ptype || TIMEOID == ptype || - TIMETZOID == ptype || INTERVALOID == ptype || SMALLDATETIMEOID == ptype) && + if (((VARCHAROID == ptype && !ACCEPT_EMPTY_STR) || TIMESTAMPOID == ptype || TIMESTAMPTZOID == ptype || + TIMEOID == ptype || TIMETZOID == ptype || INTERVALOID == ptype || SMALLDATETIMEOID == ptype) && 0 == plength && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) isNull = true; @@ -4650,8 +4650,8 @@ static void exec_bind_message(StringInfo input_message) plength = pq_getmsgint(input_message, 4); isNull = (plength == -1); /* add null value process for date type */ - if ((VARCHAROID == ptype || TIMESTAMPOID == ptype || TIMESTAMPTZOID == ptype || TIMEOID == ptype || - TIMETZOID == ptype || INTERVALOID == ptype || SMALLDATETIMEOID == ptype) && + if (((VARCHAROID == ptype && !ACCEPT_EMPTY_STR) || TIMESTAMPOID == ptype || TIMESTAMPTZOID == ptype || + TIMEOID == ptype || TIMETZOID == ptype || INTERVALOID == ptype || SMALLDATETIMEOID == ptype) && 0 == plength && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) isNull = true; @@ -11281,8 +11281,9 @@ static void exec_batch_bind_execute(StringInfo input_message) plength = pq_getmsgint(input_message, 4); isNull = (plength == -1); /* add null value process for date type */ - if ((VARCHAROID == ptype || TIMESTAMPOID == ptype || TIMESTAMPTZOID == ptype || TIMEOID == ptype || - TIMETZOID == ptype || INTERVALOID == ptype || SMALLDATETIMEOID == ptype) && + if (((VARCHAROID == ptype && !ACCEPT_EMPTY_STR) || TIMESTAMPOID == ptype || + TIMESTAMPTZOID == ptype || TIMEOID == ptype || TIMETZOID == ptype || + INTERVALOID == ptype || SMALLDATETIMEOID == ptype) && 0 == plength && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) isNull = true; diff --git a/src/gausskernel/runtime/codegen/codegenutil/varlenacodegen.cpp b/src/gausskernel/runtime/codegen/codegenutil/varlenacodegen.cpp index 9b379250cd..1c6eced614 100644 --- a/src/gausskernel/runtime/codegen/codegenutil/varlenacodegen.cpp +++ b/src/gausskernel/runtime/codegen/codegenutil/varlenacodegen.cpp @@ -450,7 +450,7 @@ llvm::Function* substr_codegen() * in case of A db compatible format we have to prepare a flag to indicate whether * result string is NULL, so we add one more parameter. */ - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) fn_prototype.addArgument(GsCodeGen::NamedVariable("isNull", int8PtrType)); llvm::Function* jitted_substr = fn_prototype.generatePrototype(&builder, &llvmargs[0]); @@ -459,7 +459,7 @@ llvm::Function* substr_codegen() start = llvmargs[1]; len = llvmargs[2]; - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) isNull = llvmargs[3]; /* @@ -497,7 +497,7 @@ llvm::Function* substr_codegen() *in case of ORC, we should set isNull to True if res_len == 0; *otherwise, just return the result. */ - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { DEFINE_BLOCK(be_null, jitted_substr); DEFINE_BLOCK(bnot_null, jitted_substr); DEFINE_BLOCK(ret_bb, jitted_substr); @@ -568,13 +568,13 @@ llvm::Function* rtrim1_codegen() * in case of A db compatible format we have to prepare a flag to indicate whether * result string is NULL, so we add one more parameter. */ - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) fn_prototype.addArgument(GsCodeGen::NamedVariable("isNull", int8PtrType)); llvm::Function* jitted_rtrim1 = fn_prototype.generatePrototype(&builder, &llvmargs[0]); argval = llvmargs[0]; - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) isNull = llvmargs[1]; /* load rtrim1 ir function from module */ @@ -599,7 +599,7 @@ llvm::Function* rtrim1_codegen() *in case of ORC, we should set isNull to True if res_len == 0; *otherwise, just return the result. */ - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { DEFINE_BLOCK(be_null, jitted_rtrim1); DEFINE_BLOCK(bnot_null, jitted_rtrim1); DEFINE_BLOCK(ret_bb, jitted_rtrim1); @@ -671,12 +671,12 @@ llvm::Function* btrim1_codegen() * in case of A db compatible format we have to prepare a flag to indicate whether * result string is NULL, so we add one more parameter. */ - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) fn_prototype.addArgument(GsCodeGen::NamedVariable("isNull", int8PtrType)); llvm::Function* jitted_btrim1 = fn_prototype.generatePrototype(&builder, &llvmargs[0]); argval = llvmargs[0]; - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) isNull = llvmargs[1]; /* load rtrim1 ir function from IR file*/ @@ -701,7 +701,7 @@ llvm::Function* btrim1_codegen() *in case of ORC, we should set isNull to True if res_len == 0; *otherwise, just return the result. */ - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { DEFINE_BLOCK(be_null, jitted_btrim1); DEFINE_BLOCK(bnot_null, jitted_btrim1); DEFINE_BLOCK(ret_bb, jitted_btrim1); diff --git a/src/gausskernel/runtime/codegen/vecexecutor/vecexprcodegen.cpp b/src/gausskernel/runtime/codegen/vecexecutor/vecexprcodegen.cpp index 06cb669d41..dbd985a7f5 100644 --- a/src/gausskernel/runtime/codegen/vecexecutor/vecexprcodegen.cpp +++ b/src/gausskernel/runtime/codegen/vecexecutor/vecexprcodegen.cpp @@ -2874,7 +2874,7 @@ llvm::Value* VecExprCodeGen::FuncCodeGen(ExprCodeGenArgs* args) * then we have to set 'isNull' flag to True, * and then jump to the be_null block. */ - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { res1 = inner_builder.CreateCall(func_substr, {inargs[0], inargs[1], inargs[2], isNull}); llvm::Value* res_flag = inner_builder.CreateLoad(int8Type, isNull, "resflag"); llvm::Value* cmp = inner_builder.CreateICmpEQ(res_flag, null_true, "check"); @@ -2897,7 +2897,7 @@ llvm::Value* VecExprCodeGen::FuncCodeGen(ExprCodeGenArgs* args) * then we have to set 'isNull' flag to True, * and then jump to the be_null block. */ - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { res1 = inner_builder.CreateCall(func_rtrim1, {inargs[0], isNull}); llvm::Value* res_flag = inner_builder.CreateLoad(int8Type, isNull, "resflag"); llvm::Value* cmp = inner_builder.CreateICmpEQ(res_flag, null_true, "check"); @@ -2919,7 +2919,7 @@ llvm::Value* VecExprCodeGen::FuncCodeGen(ExprCodeGenArgs* args) * then we have to set 'isNull' flag to True, * and then jump to the be_null block. */ - if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { + if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { res1 = inner_builder.CreateCall(func_btrim1, {inargs[0], isNull}); llvm::Value* res_flag = inner_builder.CreateLoad(int8Type, isNull, "resflag"); llvm::Value* cmp = inner_builder.CreateICmpEQ(res_flag, null_true, "check"); diff --git a/src/gausskernel/runtime/opfusion/opfusion.cpp b/src/gausskernel/runtime/opfusion/opfusion.cpp index c439cb06dc..ec351275fb 100644 --- a/src/gausskernel/runtime/opfusion/opfusion.cpp +++ b/src/gausskernel/runtime/opfusion/opfusion.cpp @@ -762,8 +762,8 @@ void OpFusion::updatePreAllocParamter(StringInfo input_message) plength = pq_getmsgint(input_message, 4); isNull = (plength == -1); /* add null value process for date type */ - if ((VARCHAROID == ptype || TIMESTAMPOID == ptype || TIMESTAMPTZOID == ptype || TIMEOID == ptype || - TIMETZOID == ptype || INTERVALOID == ptype || SMALLDATETIMEOID == ptype) && + if (((VARCHAROID == ptype && !ACCEPT_EMPTY_STR) || TIMESTAMPOID == ptype || TIMESTAMPTZOID == ptype || + TIMEOID == ptype || TIMETZOID == ptype || INTERVALOID == ptype || SMALLDATETIMEOID == ptype) && plength == 0 && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) { isNull = true; } diff --git a/src/gausskernel/runtime/vecexecutor/vecprimitive/varchar.inl b/src/gausskernel/runtime/vecexecutor/vecprimitive/varchar.inl index 1f27eb1f56..d996abd26f 100755 --- a/src/gausskernel/runtime/vecexecutor/vecprimitive/varchar.inl +++ b/src/gausskernel/runtime/vecexecutor/vecprimitive/varchar.inl @@ -309,7 +309,7 @@ inline static Datum null_return(bool *is_null) { text *result = NULL; - if(u_sess->attr.attr_sql.sql_compatibility == A_FORMAT) + if(u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && !ACCEPT_EMPTY_STR) { *is_null = true; return (Datum)0; diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 7969e86282..a27389d57b 100755 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -134,7 +134,8 @@ extern bool contain_backend_version(uint32 version_number); #define OPT_CHAR_COERCE_COMPAT 4194304 #define OPT_TRUNC_NUMERIC_TAIL_ZERO 8388608 #define OPT_ARRAY_COUNT_COMPAT 16777216 -#define OPT_MAX 25 +#define OPT_ACCEPT_EMPTY_STR 33554432 +#define OPT_MAX 26 #define PLPSQL_OPT_FOR_LOOP 1 #define PLPSQL_OPT_OUTPARAM 2 @@ -155,6 +156,7 @@ extern bool contain_backend_version(uint32 version_number); #define RETURN_NS (u_sess->utils_cxt.behavior_compat_flags & OPT_RETURN_NS_OR_NULL) #define CORRECT_TO_NUMBER (u_sess->utils_cxt.behavior_compat_flags & OPT_CORRECT_TO_NUMBER) #define SUPPORT_BIND_SEARCHPATH (u_sess->utils_cxt.behavior_compat_flags & OPT_BIND_SEARCHPATH) +#define ACCEPT_EMPTY_STR (u_sess->utils_cxt.behavior_compat_flags & OPT_ACCEPT_EMPTY_STR) /*CONCAT_VARIADIC controls 1.the variadic type process, and 2. td mode null return process in concat. By default, the * option is blank and the behavior is new and compatible with current A and C mode, if the option is set, the * behavior is old and the same as previous GAUSSDB kernel. */ diff --git a/src/test/regress/expected/accept_empty_str.out b/src/test/regress/expected/accept_empty_str.out new file mode 100644 index 0000000000..e3eff0d936 --- /dev/null +++ b/src/test/regress/expected/accept_empty_str.out @@ -0,0 +1,1815 @@ +-- test about issue +create schema accept_schema; +set current_schema to 'accept_schema'; +create table tchar(c char(10)); +set behavior_compat_options to 'accept_empty_str'; +insert into tchar values(' '); +select * from tchar where c = ''; + c +------------ + +(1 row) + +select * from tchar where c = ' '; + c +------------ + +(1 row) + +select * from tchar where c is null; + c +--- +(0 rows) + +drop table tchar; +-- test about const str +select '' is null; + ?column? +---------- + f +(1 row) + +select ' ' is null; + ?column? +---------- + f +(1 row) + +select ' abc ' is null; + ?column? +---------- + f +(1 row) + +select length(''); + length +-------- + 0 +(1 row) + +select length(null); + length +-------- + +(1 row) + +select length(' '); + length +-------- + 1 +(1 row) + +select length(' abc '); + length +-------- + 5 +(1 row) + +select '123'::char(3) is null; + ?column? +---------- + f +(1 row) + +select ''::char(3) is null; + ?column? +---------- + f +(1 row) + +select '123'::varchar(3) is null; + ?column? +---------- + f +(1 row) + +select ''::varchar(3) is null; + ?column? +---------- + f +(1 row) + +select '123'::text is null; + ?column? +---------- + f +(1 row) + +select ''::text is null; + ?column? +---------- + f +(1 row) + +select '123'::clob is null; + ?column? +---------- + f +(1 row) + +select ''::clob is null; + ?column? +---------- + f +(1 row) + +select '123'::blob is null; + ?column? +---------- + f +(1 row) + +select ''::blob is null; + ?column? +---------- + f +(1 row) + +select '123'::bytea is null; + ?column? +---------- + f +(1 row) + +select ''::bytea is null; + ?column? +---------- + f +(1 row) + +select '123'::int1 is null; + ?column? +---------- + f +(1 row) + +select ''::int1 is null; +ERROR: invalid input syntax for integer: "" +LINE 1: select ''::int1 is null; + ^ +select '123'::int2 is null; + ?column? +---------- + f +(1 row) + +select ''::int2 is null; +ERROR: invalid input syntax for integer: "" +LINE 1: select ''::int2 is null; + ^ +select '123'::int is null; + ?column? +---------- + f +(1 row) + +select ''::int is null; +ERROR: invalid input syntax for integer: "" +LINE 1: select ''::int is null; + ^ +select '123'::int8 is null; + ?column? +---------- + f +(1 row) + +select ''::int8 is null; +ERROR: invalid input syntax for type bigint: "" +LINE 1: select ''::int8 is null; + ^ +select '123'::float4 is null; + ?column? +---------- + f +(1 row) + +select ''::float4 is null; +ERROR: invalid input syntax for type real: "" +LINE 1: select ''::float4 is null; + ^ +select '123'::float8 is null; + ?column? +---------- + f +(1 row) + +select ''::float8 is null; +ERROR: invalid input syntax for type double precision: "" +LINE 1: select ''::float8 is null; + ^ +select '123'::numeric is null; + ?column? +---------- + f +(1 row) + +select ''::numeric is null; +ERROR: invalid input syntax for type numeric: "" +LINE 1: select ''::numeric is null; + ^ +select ''::date is null; +ERROR: invalid input syntax for type timestamp: "" +LINE 1: select ''::date is null; + ^ +select ''::time is null; +ERROR: invalid input syntax for type time: "" +LINE 1: select ''::time is null; + ^ +select ''::timestamp is null; +ERROR: invalid input syntax for type timestamp: "" +LINE 1: select ''::timestamp is null; + ^ +-- test about var str +create table result_tab ("statement" text, result text); +declare +str_empty text := ''; +str_space text := ' '; +str_num text := '123'; +str text := ' abc '; +begin + insert into result_tab select 'select str_empty is null', str_empty is null; + insert into result_tab select 'select str_space is null', str_space is null; + insert into result_tab select 'select str is null', str is null; + insert into result_tab select 'select length(str_empty)', length(str_empty); + insert into result_tab select 'select length(null)', length(null); + insert into result_tab select 'select length(str_space)', length(str_space); + insert into result_tab select 'select length(str)', length(str); + insert into result_tab select 'select str_num::text is null', str_num::text is null; + insert into result_tab select 'select str_empty::text is null', str_empty::text is null; + insert into result_tab select 'select str_num::bytea is null;', str_num::bytea is null; + insert into result_tab select 'select str_empty::bytea is null', str_empty::bytea is null; + insert into result_tab select 'select str_num::int is null', str_num::int is null; + insert into result_tab select 'select str_num::float8 is null', str_num::float8 is null; + insert into result_tab select 'select str_num::numeric is null', str_num::numeric is null; +end; +/ +select * from result_tab; + statement | result +---------------------------------+-------- + select str_empty is null | false + select str_space is null | false + select str is null | false + select length(str_empty) | 0 + select length(null) | + select length(str_space) | 1 + select length(str) | 5 + select str_num::text is null | false + select str_empty::text is null | false + select str_num::bytea is null; | false + select str_empty::bytea is null | false + select str_num::int is null | false + select str_num::float8 is null | false + select str_num::numeric is null | false +(14 rows) + +-- test about function which return str +SELECT overlay('hello' placing 'world' from 2 for 3 ) is null; + ?column? +---------- + f +(1 row) + +SELECT overlay('hello' placing '' from 1 for 5 ) is null; + ?column? +---------- + f +(1 row) + +SELECT quote_ident('') is null; + ?column? +---------- + f +(1 row) + +SELECT quote_literal('') is null; + ?column? +---------- + f +(1 row) + +SELECT quote_nullable('') is null; + ?column? +---------- + f +(1 row) + +SELECT reverse('') is null; + ?column? +---------- + f +(1 row) + +SELECT ''||'' is null; + ?column? +---------- + false +(1 row) + +SELECT ''||41; + ?column? +---------- + 41 +(1 row) + +SELECT lower('') is null; + ?column? +---------- + f +(1 row) + +SELECT initcap('') is null; + ?column? +---------- + f +(1 row) + +SELECT ascii(''); + ascii +------- + 0 +(1 row) + +SELECT lpad('yes', 5) is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 5, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 1, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 0, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 5) is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 5, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 1, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 0, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT btrim('yzy', 'y') is null; + ?column? +---------- + f +(1 row) + +SELECT btrim('zzz', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT ltrim('yzy', 'y') is null; + ?column? +---------- + f +(1 row) + +SELECT ltrim('zzz', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT rtrim('yzy', 'y') is null; + ?column? +---------- + f +(1 row) + +SELECT rtrim('zzz', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT btrim(' z ') is null; + ?column? +---------- + f +(1 row) + +SELECT btrim(' ') is null; + ?column? +---------- + f +(1 row) + +SELECT ltrim(' z ') is null; + ?column? +---------- + f +(1 row) + +SELECT ltrim(' ') is null; + ?column? +---------- + f +(1 row) + +SELECT rtrim(' z ') is null; + ?column? +---------- + f +(1 row) + +SELECT rtrim(' ') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xyx', 'x', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xzx', 'x', '') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xxx', 'x', '') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xxx', 'x', ' ') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xxx', '', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('', 'x', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT repeat('a', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat('a', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat(' ', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat(' ', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat('', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat('', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT pg_catalog.oidvectortypes('123 456') is null; + ?column? +---------- + f +(1 row) + +SELECT pg_catalog.oidvectortypes('') is null; + ?column? +---------- + f +(1 row) + +SELECT pg_catalog.oidvectortypes(' ') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('Thomas', '.[mN]a.', 'M') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('omas', '.[mN]a.', ''); + regexp_replace +---------------- + +(1 row) + +SELECT regexp_replace('Thomas', '', 'M') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('', '.[mN]a.', 'M') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('omas', '.[mN]a.', '') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('bar','b(..)', '', 1, 1, 'n') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 'g') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('abc','abc', '', 'g') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_substr('str','st') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_substr('str','[ac]') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_substr('str','') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_substr('','st') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_split_to_table('hello world', E'\\s+') is null; + ?column? +---------- + f + f +(2 rows) + +SELECT regexp_split_to_table('', E'\\s+') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_split_to_table('hello world', '') is null; + ?column? +---------- + f + f + f + f + f + f + f + f + f + f + f +(11 rows) + +SELECT regexp_split_to_table('hello world', null) is null; + ?column? +---------- +(0 rows) + +SELECT substr('123', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123', 4) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123', 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123', 1, 0) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123', 1, -1) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 4) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 1, 0) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 1, -1) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 4) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 1, 0) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 1, -1) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 4) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 1, 0) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 1, -1) is null; +ERROR: negative substring length not allowed +SELECT substring('123'::bytea, 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 4) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 1, 0) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 1, -1) is null; +ERROR: negative substring length not allowed +SELECT replace('abc', 'ab', 'd') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'abc', '') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'abc', null) is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'ab', '') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'ab', null) is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', '', 'd') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', null, 'd') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('', 'ab', 'd') is null; + ?column? +---------- + f +(1 row) + +SELECT replace(null, 'ab', 'd') is null; + ?column? +---------- + t +(1 row) + +SELECT replace('abc', 'ab') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'abc') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', '') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', null) is null; + ?column? +---------- + f +(1 row) + +SELECT replace('', 'ab') is null; + ?column? +---------- + f +(1 row) + +SELECT replace(null, 'ab') is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('1~2~3', '~', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3~', '~', 4) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3', '~', -1) is null; +ERROR: field position must be greater than zero +SELECT split_part('1~2~3', '', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3', '', 2) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3', null, 1) is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('', '~', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part(null, '~', 1) is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('1~2~3', '|', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3', '|', 2) is null; + ?column? +---------- + f +(1 row) + +SELECT concat('Hello', ' World!') is null; + ?column? +---------- + f +(1 row) + +SELECT concat('', ' World!') is null; + ?column? +---------- + f +(1 row) + +SELECT concat('Hello', '') is null; + ?column? +---------- + f +(1 row) + +SELECT concat('', '') is null; + ?column? +---------- + f +(1 row) + +SELECT concat('Hello', null) is null; + ?column? +---------- + f +(1 row) + +SELECT concat(null, ' World!') is null; + ?column? +---------- + f +(1 row) + +SELECT concat_ws(',', 'ABCDE', 2, NULL, 22); + concat_ws +------------ + ABCDE,2,22 +(1 row) + +SELECT concat_ws('', 'ABCDE', 2, NULL, 22); + concat_ws +----------- + ABCDE222 +(1 row) + +SELECT concat_ws(',', '') is null; + ?column? +---------- + f +(1 row) + +SELECT concat_ws('', '') is null; + ?column? +---------- + f +(1 row) + +SELECT left('abcde', 2) is null; + ?column? +---------- + f +(1 row) + +SELECT left('abcde', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT left('abcde', -1) is null; + ?column? +---------- + f +(1 row) + +SELECT left('', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT left('', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT left('', -1) is null; + ?column? +---------- + f +(1 row) + +SELECT right('abcde', 2) is null; + ?column? +---------- + f +(1 row) + +SELECT right('abcde', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT right('abcde', -1) is null; + ?column? +---------- + f +(1 row) + +SELECT right('', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT right('', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT right('', -1) is null; + ?column? +---------- + f +(1 row) + +SELECT format('Hello %s', 'World'); + format +------------- + Hello World +(1 row) + +SELECT format('Hello %s', ''); + format +-------- + Hello +(1 row) + +SELECT format('%s', 'World'); + format +-------- + World +(1 row) + +SELECT format('', 'World'); + format +-------- + +(1 row) + +SELECT format('', ''); + format +-------- + +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',') AS RESULT; + result +--------- + 1,2,3,5 +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '') AS RESULT; + result +-------- + 1235 +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null) AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], '') AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], null) AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*') AS RESULT; + result +----------- + 1,2,3,*,5 +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '', '') AS RESULT; + result +-------- + 1235 +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null, null) AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], '', '') AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], null, null) AS RESULT; + result +-------- + +(1 row) + +SELECT nlssort('A', 'nls_sort=schinese_pinyin_m') is null; + ?column? +---------- + f +(1 row) + +SELECT nlssort('', 'nls_sort=schinese_pinyin_m') is null; + ?column? +---------- + f +(1 row) + +SELECT nlssort('A', '') is null; +ERROR: Sort method is not supported! +DETAIL: Not support the given sort method. +SELECT convert('text_in_utf8'::bytea, 'UTF8', 'GBK') is null; + ?column? +---------- + f +(1 row) + +SELECT convert(''::bytea, 'UTF8', 'GBK') is null; + ?column? +---------- + f +(1 row) + +SELECT convert('text_in_utf8'::bytea, '', 'GBK') is null; +ERROR: invalid source encoding name "" +SELECT convert('text_in_utf8'::bytea, 'UTF8', '') is null; +ERROR: invalid destination encoding name "" +SELECT convert_from('text_in_utf8'::bytea, 'UTF8') is null; + ?column? +---------- + f +(1 row) + +SELECT convert_from(''::bytea, 'UTF8') is null; + ?column? +---------- + f +(1 row) + +SELECT convert_from('text_in_utf8'::bytea, '') is null; +ERROR: invalid source encoding name "" +SELECT convert_to('text_in_utf8'::bytea, 'UTF8') is null; +ERROR: function convert_to(bytea, unknown) does not exist +LINE 1: SELECT convert_to('text_in_utf8'::bytea, 'UTF8') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT convert_to(''::bytea, 'UTF8') is null; +ERROR: function convert_to(bytea, unknown) does not exist +LINE 1: SELECT convert_to(''::bytea, 'UTF8') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT convert_to('text_in_utf8'::bytea, '') is null; +ERROR: function convert_to(bytea, unknown) does not exist +LINE 1: SELECT convert_to('text_in_utf8'::bytea, '') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT md5('ABC') is null; + ?column? +---------- + f +(1 row) + +SELECT md5('') is null; + ?column? +---------- + f +(1 row) + +SELECT sha('ABC') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha('') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha1('ABC') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha1('') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha2('ABC') is null; +ERROR: function sha2(unknown) does not exist +LINE 1: SELECT sha2('ABC') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT sha2('') is null; +ERROR: function sha2(unknown) does not exist +LINE 1: SELECT sha2('') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT decode('MTIzAAE=', 'base64') is null; + ?column? +---------- + f +(1 row) + +SELECT decode('', 'base64') is null; + ?column? +---------- + f +(1 row) + +SELECT decode('MTIzAAE=', '') is null; +ERROR: unrecognized encoding: "" +select similar_escape('\s+ab','2') is null; + ?column? +---------- + f +(1 row) + +select similar_escape('\s+ab','') is null; + ?column? +---------- + f +(1 row) + +select similar_escape('','2') is null; + ?column? +---------- + f +(1 row) + +select svals('"aa"=>"bb"') is null; + ?column? +---------- + f +(1 row) + +select svals('') is null; + ?column? +---------- +(0 rows) + +select tconvert('aa', 'bb') is null; + ?column? +---------- + f +(1 row) + +select tconvert('', 'bb') is null; + ?column? +---------- + f +(1 row) + +select tconvert('aa', '') is null; + ?column? +---------- + f +(1 row) + +select tconvert('', '') is null; + ?column? +---------- + f +(1 row) + +SELECT encode(E'123\\000\\001', 'base64') is null; + ?column? +---------- + f +(1 row) + +SELECT encode('', 'base64') is null; + ?column? +---------- + f +(1 row) + +SELECT encode(E'123\\000\\001', '') is null; +ERROR: unrecognized encoding: "" +-- test about vec +CREATE TABLE vec_t1 +( + c varchar +) WITH (ORIENTATION = COLUMN); +CREATE TABLE vec_t2 +( + c varchar not null +) WITH (ORIENTATION = COLUMN); +insert into vec_t1 values(''); +insert into vec_t1 values(' '); +insert into vec_t1 values('abc'); +insert into vec_t2 values(''); +insert into vec_t2 values(' '); +insert into vec_t2 values('abc'); +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | a | f +(3 rows) + +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | | f +(3 rows) + +select c as input, substr(c, 1, -1) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | | f +(3 rows) + +delete from vec_t1; +insert into vec_t1 values(''); +insert into vec_t1 values('yzy'); +insert into vec_t1 values('zzz'); +insert into vec_t1 values(' z '); +insert into vec_t1 values(' '); +SELECT c as input, btrim(c, 'y') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | z | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +SELECT c as input, btrim(c, 'z') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | | f + z | z | f + | | f +(5 rows) + +SELECT c as input, btrim(c) as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | yz | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +-- test row to vec +set try_vector_engine_strategy=force; +create table vec_t3(c text); +insert into vec_t3 values(''); +insert into vec_t3 values(' '); +insert into vec_t3 values('abc'); +explain analyze select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; +--?QUERY PLAN.* +--?.* +--?Row Adapter.* +--?Vector Adapter(type: BATCH MODE).* +--?Seq Scan on vec_t3.* +--?.* +(4 rows) + +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | a | f +(3 rows) + +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | | f +(3 rows) + +delete from vec_t3; +insert into vec_t3 values(''); +insert into vec_t3 values('yzy'); +insert into vec_t3 values('zzz'); +insert into vec_t3 values(' z '); +insert into vec_t3 values(' '); +explain analyze SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; +--?QUERY PLAN.* +--?.* +--?Row Adapter.* +--?Vector Adapter(type: BATCH MODE).* +--?Seq Scan on vec_t3.* +--?.* +(4 rows) + +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; + input | result | isnull +-------+--------+-------- + | | f + yzy | yz | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t3; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t3; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +create table pad2_tab(a text, b int); +insert into pad2_tab values('yes', 5), ('yes', 1), ('yes', 0); +create table pad3_tab(a text, b int, c text); +insert into pad3_tab values('yes', 5, 'z'), ('yes', 1, 'z'), ('yes', 0, 'z'); +SELECT a as p1, b as p2, lpad(a, b) is null from pad2_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | f +(3 rows) + +SELECT a as p1, b as p2, lpad(a, b, c) is null from pad3_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | f +(3 rows) + +SELECT a as p1, b as p2, rpad(a, b) is null from pad2_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | f +(3 rows) + +SELECT a as p1, b as p2, rpad(a, b, c) is null from pad3_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | f +(3 rows) + +create table trim2(a text, b text); +insert into trim2 values('yzy', 'y'), ('zzz', 'z'); +create table trim1(a text); +insert into trim1 values(' z '), (' '); +SELECT a as p1, b as p2, btrim(a, b) is null from trim2; + p1 | p2 | ?column? +-----+----+---------- + yzy | y | f + zzz | z | f +(2 rows) + +SELECT a as p1, b as p2, ltrim(a, b) is null from trim2; + p1 | p2 | ?column? +-----+----+---------- + yzy | y | f + zzz | z | f +(2 rows) + +SELECT a as p1, b as p2, rtrim(a, b) is null from trim2; + p1 | p2 | ?column? +-----+----+---------- + yzy | y | f + zzz | z | f +(2 rows) + +SELECT a as p1, btrim(a) is null from trim1; + p1 | ?column? +-----+---------- + z | f + | f +(2 rows) + +SELECT a as p1, ltrim(a) is null from trim1; + p1 | ?column? +-----+---------- + z | f + | f +(2 rows) + +SELECT a as p1, rtrim(a) is null from trim1; + p1 | ?column? +-----+---------- + z | f + | f +(2 rows) + +create table translate3(a text, b text, c text); +insert into translate3 values('xyx', 'x', 'z'), ('xzx', 'x', ''), ('xxx', 'x', ''), ('xxx', 'x', ' '), ('xxx', '', 'z'), ('', 'x', 'z'); +SELECT a as p1, b as p2, c as p3, translate(a, b, c) is null from translate3; + p1 | p2 | p3 | ?column? +-----+----+----+---------- + xyx | x | z | f + xzx | x | | f + xxx | x | | f + xxx | x | | f + xxx | | z | f + | x | z | f +(6 rows) + +create table repeat2 (a text, b int); +insert into repeat2 values('a', 3), ('a', 0), (' ', 3), ('', 3), ('', 0); +SELECT a as p1, b as p2, repeat(a, b) is null from repeat2; + p1 | p2 | ?column? +----+----+---------- + a | 3 | f + a | 0 | f + | 3 | f + | 3 | f + | 0 | f +(5 rows) + +create table oidvectortypes1 (a oidvector); +insert into oidvectortypes1 values ('123 456'), (''), (' '); +SELECT a as p1, oidvectortypes(a) is null from oidvectortypes1; + p1 | ?column? +---------+---------- + 123 456 | f + | f + | f +(3 rows) + +create table regexp_replace3 (a text, b text, c text); +insert into regexp_replace3 values('Thomas', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''), ('Thomas', '', 'M'), ('', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''); +SELECT a as p1, b as p2, c as p3, regexp_replace(a, b, c) is null from regexp_replace3; + p1 | p2 | p3 | ?column? +--------+---------+----+---------- + Thomas | .[mN]a. | M | f + omas | .[mN]a. | | f + Thomas | | M | f + | .[mN]a. | M | f + omas | .[mN]a. | | f +(5 rows) + +create table regexp_replace6 (a text, b text, c text, d int, e int, f text); +insert into regexp_replace6 values ('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n'), ('bar','b(..)', '', 1, 1, 'n'); +SELECT a as p1, b as p2, c as p3, d as p4, e as p5, f as p6, regexp_replace(a, b, c, d, e, f) is null from regexp_replace6; + p1 | p2 | p3 | p4 | p5 | p6 | ?column? +-----------+-------+------+----+----+----+---------- + foobarbaz | b(..) | X\1Y | 2 | 2 | n | f + bar | b(..) | | 1 | 1 | n | f +(2 rows) + +create table regexp_split_to_table2 (a text, b text); +insert into regexp_split_to_table2 values('hello world', E'\\s+'), ('', E'\\s+'), ('hello world', ''), ('hello world', null); +SELECT a as p1, b as p2, regexp_split_to_table(a, b) is null from regexp_split_to_table2; + p1 | p2 | ?column? +-------------+-----+---------- + hello world | \s+ | f + hello world | \s+ | f + | \s+ | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f +(14 rows) + +create table substr2(a bytea, b int); +insert into substr2 values ('123'::bytea, 3), ('123'::bytea, 4); +select a as p1, b as p2, substr(a, b) is null from substr2; + p1 | p2 | ?column? +----------+----+---------- + \x313233 | 3 | f + \x313233 | 4 | f +(2 rows) + +create table substr3(a bytea, b int, c int); +insert into substr3 values('123'::bytea, 1, 2), ('123'::bytea, 1, 0); +select a as p1, b as p2, c as p3, substr(a, b, c) is null from substr3; + p1 | p2 | p3 | ?column? +----------+----+----+---------- + \x313233 | 1 | 2 | f + \x313233 | 1 | 0 | f +(2 rows) + +create table replace3 (a text, b text, c text); +insert into replace3 values ('abc', 'ab', 'd'), ('abc', 'abc', ''), ('abc', 'abc', ''), ('abc', 'ab', ''), ('abc', 'ab', null), ('abc', '', 'd'), ('abc', null, 'd'), ('', 'ab', 'd'), (null, 'ab', 'd'); +SELECT a as p1, b as p2, c as p3, replace(a, b, c) is null from replace3; + p1 | p2 | p3 | ?column? +-----+-----+----+---------- + abc | ab | d | f + abc | abc | | f + abc | abc | | f + abc | ab | | f + abc | ab | | f + abc | | d | f + abc | | d | f + | ab | d | f + | ab | d | t +(9 rows) + +create table replace2 (a text, b text); +insert into replace2 values('abc', 'ab'), ('abc', 'abc'), ('abc', ''), ('abc', null), ('', 'ab'), (null, 'ab'); +SELECT a as p1, b as p2, replace(a, b) is null from replace2; + p1 | p2 | ?column? +-----+-----+---------- + abc | ab | f + abc | abc | f + abc | | f + abc | | f + | ab | f + | ab | t +(6 rows) + +create table split_part3 (a text, b text, c int); +insert into split_part3 values('1~2~3', '~', 3), ('1~2~3~', '~', 4), ('1~2~3', '', 1), ('1~2~3', null, 1), ('', '~', 1), (null, '~', 1); +SELECT a as p1, b as p2, c as p3, split_part(a, b, c) is null from split_part3; + p1 | p2 | p3 | ?column? +--------+----+----+---------- + 1~2~3 | ~ | 3 | f + 1~2~3~ | ~ | 4 | f + 1~2~3 | | 1 | f + 1~2~3 | | 1 | t + | ~ | 1 | f + | ~ | 1 | t +(6 rows) + +create table array_to_string2(a integer[], b text); +insert into array_to_string2 values(ARRAY[1, 2, 3, NULL, 5], ','), (ARRAY[1, 2, 3, NULL, 5], ''), (ARRAY[1, 2, 3, NULL, 5], null), (ARRAY[NULL], ''), (ARRAY[NULL], null); +SELECT a as p1, b as p2, array_to_string(a, b) AS RESULT from array_to_string2; + p1 | p2 | result +----------------+----+--------- + {1,2,3,NULL,5} | , | 1,2,3,5 + {1,2,3,NULL,5} | | 1235 + {1,2,3,NULL,5} | | + {NULL} | | + {NULL} | | +(5 rows) + +create table array_to_string3(a integer[], b text, c text); +insert into array_to_string3 values(ARRAY[1, 2, 3, NULL, 5], ',', '*'), (ARRAY[1, 2, 3, NULL, 5], '', ''), (ARRAY[1, 2, 3, NULL, 5], null, null), (ARRAY[NULL], '', ''), (ARRAY[NULL], null, null); +SELECT a as p1, b as p2, c as p3, array_to_string(a, b, c) AS RESULT from array_to_string3; + p1 | p2 | p3 | result +----------------+----+----+----------- + {1,2,3,NULL,5} | , | * | 1,2,3,*,5 + {1,2,3,NULL,5} | | | 1235 + {1,2,3,NULL,5} | | | + {NULL} | | | + {NULL} | | | +(5 rows) + +set try_vector_engine_strategy=off; diff --git a/src/test/regress/expected/not_accept_empty_str.out b/src/test/regress/expected/not_accept_empty_str.out new file mode 100644 index 0000000000..a2149a9028 --- /dev/null +++ b/src/test/regress/expected/not_accept_empty_str.out @@ -0,0 +1,1822 @@ +-- test about issue +create schema not_accept_schema; +set current_schema to 'not_accept_schema'; +create table tchar(c char(10)); +set behavior_compat_options to ''; +insert into tchar values(' '); +select * from tchar where c = ''; + c +--- +(0 rows) + +select * from tchar where c = ' '; + c +------------ + +(1 row) + +select * from tchar where c is null; + c +--- +(0 rows) + +drop table tchar; +-- test about const str +select '' is null; + ?column? +---------- + t +(1 row) + +select ' ' is null; + ?column? +---------- + f +(1 row) + +select ' abc ' is null; + ?column? +---------- + f +(1 row) + +select length(''); + length +-------- + +(1 row) + +select length(null); + length +-------- + +(1 row) + +select length(' '); + length +-------- + 1 +(1 row) + +select length(' abc '); + length +-------- + 5 +(1 row) + +select '123'::char(3) is null; + ?column? +---------- + f +(1 row) + +select ''::char(3) is null; + ?column? +---------- + t +(1 row) + +select '123'::varchar(3) is null; + ?column? +---------- + f +(1 row) + +select ''::varchar(3) is null; + ?column? +---------- + t +(1 row) + +select '123'::text is null; + ?column? +---------- + f +(1 row) + +select ''::text is null; + ?column? +---------- + t +(1 row) + +select '123'::clob is null; + ?column? +---------- + f +(1 row) + +select ''::clob is null; + ?column? +---------- + t +(1 row) + +select '123'::blob is null; + ?column? +---------- + f +(1 row) + +select ''::blob is null; + ?column? +---------- + t +(1 row) + +select '123'::bytea is null; + ?column? +---------- + f +(1 row) + +select ''::bytea is null; + ?column? +---------- + t +(1 row) + +select '123'::int1 is null; + ?column? +---------- + f +(1 row) + +select ''::int1 is null; + ?column? +---------- + t +(1 row) + +select '123'::int2 is null; + ?column? +---------- + f +(1 row) + +select ''::int2 is null; + ?column? +---------- + t +(1 row) + +select '123'::int is null; + ?column? +---------- + f +(1 row) + +select ''::int is null; + ?column? +---------- + t +(1 row) + +select '123'::int8 is null; + ?column? +---------- + f +(1 row) + +select ''::int8 is null; + ?column? +---------- + t +(1 row) + +select '123'::float4 is null; + ?column? +---------- + f +(1 row) + +select ''::float4 is null; + ?column? +---------- + t +(1 row) + +select '123'::float8 is null; + ?column? +---------- + f +(1 row) + +select ''::float8 is null; + ?column? +---------- + t +(1 row) + +select '123'::numeric is null; + ?column? +---------- + f +(1 row) + +select ''::numeric is null; + ?column? +---------- + t +(1 row) + +select ''::date is null; + ?column? +---------- + t +(1 row) + +select ''::time is null; + ?column? +---------- + t +(1 row) + +select ''::timestamp is null; + ?column? +---------- + t +(1 row) + +-- test about var str +create table result_tab ("statement" text, result text); +declare +str_empty text := ''; +str_space text := ' '; +str_num text := '123'; +str text := ' abc '; +begin + insert into result_tab select 'select str_empty is null', str_empty is null; + insert into result_tab select 'select str_space is null', str_space is null; + insert into result_tab select 'select str is null', str is null; + insert into result_tab select 'select length(str_empty)', length(str_empty); + insert into result_tab select 'select length(null)', length(null); + insert into result_tab select 'select length(str_space)', length(str_space); + insert into result_tab select 'select length(str)', length(str); + insert into result_tab select 'select str_num::text is null', str_num::text is null; + insert into result_tab select 'select str_empty::text is null', str_empty::text is null; + insert into result_tab select 'select str_num::bytea is null;', str_num::bytea is null; + insert into result_tab select 'select str_empty::bytea is null', str_empty::bytea is null; + insert into result_tab select 'select str_num::int is null', str_num::int is null; + insert into result_tab select 'select str_num::float8 is null', str_num::float8 is null; + insert into result_tab select 'select str_num::numeric is null', str_num::numeric is null; +end; +/ +select * from result_tab; + statement | result +---------------------------------+-------- + select str_empty is null | true + select str_space is null | false + select str is null | false + select length(str_empty) | + select length(null) | + select length(str_space) | 1 + select length(str) | 5 + select str_num::text is null | false + select str_empty::text is null | true + select str_num::bytea is null; | false + select str_empty::bytea is null | true + select str_num::int is null | false + select str_num::float8 is null | false + select str_num::numeric is null | false +(14 rows) + +-- test about function which return str +SELECT overlay('hello' placing 'world' from 2 for 3 ) is null; + ?column? +---------- + f +(1 row) + +SELECT overlay('hello' placing '' from 1 for 5 ) is null; + ?column? +---------- + t +(1 row) + +SELECT quote_ident('') is null; + ?column? +---------- + t +(1 row) + +SELECT quote_literal('') is null; + ?column? +---------- + t +(1 row) + +SELECT quote_nullable('') is null; + ?column? +---------- + f +(1 row) + +SELECT reverse('') is null; + ?column? +---------- + t +(1 row) + +SELECT ''||'' is null; + ?column? +---------- + true +(1 row) + +SELECT ''||41; + ?column? +---------- + 41 +(1 row) + +SELECT lower('') is null; + ?column? +---------- + t +(1 row) + +SELECT initcap('') is null; + ?column? +---------- + t +(1 row) + +SELECT ascii(''); + ascii +------- + +(1 row) + +SELECT lpad('yes', 5) is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 0) is null; + ?column? +---------- + t +(1 row) + +SELECT lpad('yes', 5, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 1, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 0, 'z') is null; + ?column? +---------- + t +(1 row) + +SELECT rpad('yes', 5) is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 0) is null; + ?column? +---------- + t +(1 row) + +SELECT rpad('yes', 5, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 1, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 0, 'z') is null; + ?column? +---------- + t +(1 row) + +SELECT btrim('yzy', 'y') is null; + ?column? +---------- + f +(1 row) + +SELECT btrim('zzz', 'z') is null; + ?column? +---------- + t +(1 row) + +SELECT ltrim('yzy', 'y') is null; + ?column? +---------- + f +(1 row) + +SELECT ltrim('zzz', 'z') is null; + ?column? +---------- + t +(1 row) + +SELECT rtrim('yzy', 'y') is null; + ?column? +---------- + f +(1 row) + +SELECT rtrim('zzz', 'z') is null; + ?column? +---------- + t +(1 row) + +SELECT btrim(' z ') is null; + ?column? +---------- + f +(1 row) + +SELECT btrim(' ') is null; + ?column? +---------- + t +(1 row) + +SELECT ltrim(' z ') is null; + ?column? +---------- + f +(1 row) + +SELECT ltrim(' ') is null; + ?column? +---------- + t +(1 row) + +SELECT rtrim(' z ') is null; + ?column? +---------- + f +(1 row) + +SELECT rtrim(' ') is null; + ?column? +---------- + t +(1 row) + +SELECT translate('xyx', 'x', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xzx', 'x', '') is null; + ?column? +---------- + t +(1 row) + +SELECT translate('xxx', 'x', '') is null; + ?column? +---------- + t +(1 row) + +SELECT translate('xxx', 'x', ' ') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xxx', '', 'z') is null; + ?column? +---------- + t +(1 row) + +SELECT translate('', 'x', 'z') is null; + ?column? +---------- + t +(1 row) + +SELECT repeat('a', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat('a', 0) is null; + ?column? +---------- + t +(1 row) + +SELECT repeat(' ', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat(' ', 0) is null; + ?column? +---------- + t +(1 row) + +SELECT repeat('', 3) is null; + ?column? +---------- + t +(1 row) + +SELECT repeat('', 0) is null; + ?column? +---------- + t +(1 row) + +SELECT pg_catalog.oidvectortypes('123 456') is null; + ?column? +---------- + f +(1 row) + +SELECT pg_catalog.oidvectortypes('') is null; + ?column? +---------- + t +(1 row) + +SELECT pg_catalog.oidvectortypes(' ') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_replace('Thomas', '.[mN]a.', 'M') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('omas', '.[mN]a.', ''); + regexp_replace +---------------- + +(1 row) + +SELECT regexp_replace('Thomas', '', 'M') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('', '.[mN]a.', 'M') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_replace('omas', '.[mN]a.', '') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('bar','b(..)', '', 1, 1, 'n') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 'g') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('abc','abc', '', 'g') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_substr('str','st') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_substr('str','[ac]') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_substr('str','') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_substr('','st') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_split_to_table('hello world', E'\\s+') is null; + ?column? +---------- + f + f +(2 rows) + +SELECT regexp_split_to_table('', E'\\s+') is null; + ?column? +---------- +(0 rows) + +SELECT regexp_split_to_table('hello world', '') is null; + ?column? +---------- +(0 rows) + +SELECT regexp_split_to_table('hello world', null) is null; + ?column? +---------- +(0 rows) + +SELECT substr('123', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123', 4) is null; + ?column? +---------- + t +(1 row) + +SELECT substr('123', 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123', 1, 0) is null; + ?column? +---------- + t +(1 row) + +SELECT substr('123', 1, -1) is null; + ?column? +---------- + t +(1 row) + +SELECT substr('123'::bytea, 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 4) is null; + ?column? +---------- + t +(1 row) + +SELECT substr('123'::bytea, 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 1, 0) is null; + ?column? +---------- + t +(1 row) + +SELECT substr('123'::bytea, 1, -1) is null; + ?column? +---------- + t +(1 row) + +SELECT substrb('123', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 4) is null; + ?column? +---------- + t +(1 row) + +SELECT substrb('123', 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 1, 0) is null; + ?column? +---------- + t +(1 row) + +SELECT substrb('123', 1, -1) is null; + ?column? +---------- + t +(1 row) + +SELECT substring('123', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 4) is null; + ?column? +---------- + t +(1 row) + +SELECT substring('123', 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 1, 0) is null; + ?column? +---------- + t +(1 row) + +SELECT substring('123', 1, -1) is null; +ERROR: negative substring length not allowed +SELECT substring('123'::bytea, 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 4) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 1, 0) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 1, -1) is null; +ERROR: negative substring length not allowed +SELECT replace('abc', 'ab', 'd') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'abc', '') is null; + ?column? +---------- + t +(1 row) + +SELECT replace('abc', 'abc', null) is null; + ?column? +---------- + t +(1 row) + +SELECT replace('abc', 'ab', '') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'ab', null) is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', '', 'd') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', null, 'd') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('', 'ab', 'd') is null; + ?column? +---------- + t +(1 row) + +SELECT replace(null, 'ab', 'd') is null; + ?column? +---------- + t +(1 row) + +SELECT replace('abc', 'ab') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'abc') is null; +ERROR: function returned NULL +SELECT replace('abc', '') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', null) is null; + ?column? +---------- + f +(1 row) + +SELECT replace('', 'ab') is null; + ?column? +---------- + t +(1 row) + +SELECT replace(null, 'ab') is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('1~2~3', '~', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3~', '~', 4) is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('1~2~3', '~', -1) is null; +ERROR: field position must be greater than zero +SELECT split_part('1~2~3', '', 1) is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('1~2~3', '', 2) is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('1~2~3', null, 1) is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('', '~', 1) is null; + ?column? +---------- + t +(1 row) + +SELECT split_part(null, '~', 1) is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('1~2~3', '|', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3', '|', 2) is null; + ?column? +---------- + t +(1 row) + +SELECT concat('Hello', ' World!') is null; + ?column? +---------- + f +(1 row) + +SELECT concat('', ' World!') is null; + ?column? +---------- + f +(1 row) + +SELECT concat('Hello', '') is null; + ?column? +---------- + f +(1 row) + +SELECT concat('', '') is null; + ?column? +---------- + t +(1 row) + +SELECT concat('Hello', null) is null; + ?column? +---------- + f +(1 row) + +SELECT concat(null, ' World!') is null; + ?column? +---------- + f +(1 row) + +SELECT concat_ws(',', 'ABCDE', 2, NULL, 22); + concat_ws +------------ + ABCDE,2,22 +(1 row) + +SELECT concat_ws('', 'ABCDE', 2, NULL, 22); + concat_ws +----------- + +(1 row) + +SELECT concat_ws(',', '') is null; + ?column? +---------- + t +(1 row) + +SELECT concat_ws('', '') is null; + ?column? +---------- + t +(1 row) + +SELECT left('abcde', 2) is null; + ?column? +---------- + f +(1 row) + +SELECT left('abcde', 0) is null; + ?column? +---------- + t +(1 row) + +SELECT left('abcde', -1) is null; + ?column? +---------- + f +(1 row) + +SELECT left('', 1) is null; + ?column? +---------- + t +(1 row) + +SELECT left('', 0) is null; + ?column? +---------- + t +(1 row) + +SELECT left('', -1) is null; + ?column? +---------- + t +(1 row) + +SELECT right('abcde', 2) is null; + ?column? +---------- + f +(1 row) + +SELECT right('abcde', 0) is null; + ?column? +---------- + t +(1 row) + +SELECT right('abcde', -1) is null; + ?column? +---------- + f +(1 row) + +SELECT right('', 1) is null; + ?column? +---------- + t +(1 row) + +SELECT right('', 0) is null; + ?column? +---------- + t +(1 row) + +SELECT right('', -1) is null; + ?column? +---------- + t +(1 row) + +SELECT format('Hello %s', 'World'); + format +------------- + Hello World +(1 row) + +SELECT format('Hello %s', ''); + format +-------- + Hello +(1 row) + +SELECT format('%s', 'World'); + format +-------- + World +(1 row) + +SELECT format('', 'World'); + format +-------- + +(1 row) + +SELECT format('', ''); + format +-------- + +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',') AS RESULT; + result +--------- + 1,2,3,5 +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '') AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null) AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], '') AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], null) AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*') AS RESULT; + result +----------- + 1,2,3,*,5 +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '', '') AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null, null) AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], '', '') AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], null, null) AS RESULT; + result +-------- + +(1 row) + +SELECT nlssort('A', 'nls_sort=schinese_pinyin_m') is null; + ?column? +---------- + f +(1 row) + +SELECT nlssort('', 'nls_sort=schinese_pinyin_m') is null; + ?column? +---------- + t +(1 row) + +SELECT nlssort('A', '') is null; + ?column? +---------- + t +(1 row) + +SELECT convert('text_in_utf8'::bytea, 'UTF8', 'GBK') is null; + ?column? +---------- + f +(1 row) + +SELECT convert(''::bytea, 'UTF8', 'GBK') is null; + ?column? +---------- + t +(1 row) + +SELECT convert('text_in_utf8'::bytea, '', 'GBK') is null; + ?column? +---------- + t +(1 row) + +SELECT convert('text_in_utf8'::bytea, 'UTF8', '') is null; + ?column? +---------- + t +(1 row) + +SELECT convert_from('text_in_utf8'::bytea, 'UTF8') is null; + ?column? +---------- + f +(1 row) + +SELECT convert_from(''::bytea, 'UTF8') is null; + ?column? +---------- + t +(1 row) + +SELECT convert_from('text_in_utf8'::bytea, '') is null; + ?column? +---------- + t +(1 row) + +SELECT convert_to('text_in_utf8'::bytea, 'UTF8') is null; +ERROR: function convert_to(bytea, unknown) does not exist +LINE 1: SELECT convert_to('text_in_utf8'::bytea, 'UTF8') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT convert_to(''::bytea, 'UTF8') is null; +ERROR: function convert_to(bytea, unknown) does not exist +LINE 1: SELECT convert_to(''::bytea, 'UTF8') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT convert_to('text_in_utf8'::bytea, '') is null; +ERROR: function convert_to(bytea, unknown) does not exist +LINE 1: SELECT convert_to('text_in_utf8'::bytea, '') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT md5('ABC') is null; + ?column? +---------- + f +(1 row) + +SELECT md5('') is null; + ?column? +---------- + t +(1 row) + +SELECT sha('ABC') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha('') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha1('ABC') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha1('') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha2('ABC') is null; +ERROR: function sha2(unknown) does not exist +LINE 1: SELECT sha2('ABC') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT sha2('') is null; +ERROR: function sha2(unknown) does not exist +LINE 1: SELECT sha2('') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT decode('MTIzAAE=', 'base64') is null; + ?column? +---------- + f +(1 row) + +SELECT decode('', 'base64') is null; + ?column? +---------- + t +(1 row) + +SELECT decode('MTIzAAE=', '') is null; + ?column? +---------- + t +(1 row) + +select similar_escape('\s+ab','2') is null; + ?column? +---------- + f +(1 row) + +select similar_escape('\s+ab','') is null; + ?column? +---------- + f +(1 row) + +select similar_escape('','2') is null; + ?column? +---------- + t +(1 row) + +select svals('"aa"=>"bb"') is null; + ?column? +---------- + f +(1 row) + +select svals('') is null; + ?column? +---------- +(0 rows) + +select tconvert('aa', 'bb') is null; + ?column? +---------- + f +(1 row) + +select tconvert('', 'bb') is null; + ?column? +---------- + t +(1 row) + +select tconvert('aa', '') is null; + ?column? +---------- + f +(1 row) + +select tconvert('', '') is null; + ?column? +---------- + t +(1 row) + +SELECT encode(E'123\\000\\001', 'base64') is null; + ?column? +---------- + f +(1 row) + +SELECT encode('', 'base64') is null; + ?column? +---------- + t +(1 row) + +SELECT encode(E'123\\000\\001', '') is null; + ?column? +---------- + t +(1 row) + +-- test about vec +CREATE TABLE vec_t1 +( + c varchar +) WITH (ORIENTATION = COLUMN); +CREATE TABLE vec_t2 +( + c varchar not null +) WITH (ORIENTATION = COLUMN); +insert into vec_t1 values(''); +insert into vec_t1 values(' '); +insert into vec_t1 values('abc'); +insert into vec_t2 values(''); +ERROR: null value in column "c" violates not-null constraint +DETAIL: Failing row contains (null). +insert into vec_t2 values(' '); +insert into vec_t2 values('abc'); +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | t + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | t + | | f + abc | a | f +(3 rows) + +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | t + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | t + | | t + abc | | t +(3 rows) + +select c as input, substr(c, 1, -1) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | t + | | t + abc | | t +(3 rows) + +delete from vec_t1; +insert into vec_t1 values(''); +insert into vec_t1 values('yzy'); +insert into vec_t1 values('zzz'); +insert into vec_t1 values(' z '); +insert into vec_t1 values(' '); +SELECT c as input, btrim(c, 'y') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | t + yzy | z | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +SELECT c as input, btrim(c, 'z') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | t + yzy | yzy | f + zzz | | t + z | z | f + | | f +(5 rows) + +SELECT c as input, btrim(c) as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | t + yzy | yzy | f + zzz | zzz | f + z | z | f + | | t +(5 rows) + +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | t + yzy | yz | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | t + yzy | yzy | f + zzz | | t + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | t + yzy | yzy | f + zzz | zzz | f + z | z | f + | | t +(5 rows) + +-- test row to vec +set try_vector_engine_strategy=force; +create table vec_t3(c text); +insert into vec_t3 values(''); +insert into vec_t3 values(' '); +insert into vec_t3 values('abc'); +explain analyze select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; +--?QUERY PLAN.* +--?.* +--?Row Adapter.* +--?Vector Adapter(type: BATCH MODE).* +--?Seq Scan on vec_t3.* +--?.* +(4 rows) + +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | t + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | t + | | f + abc | a | f +(3 rows) + +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | t + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | t + | | t + abc | | t +(3 rows) + +delete from vec_t3; +insert into vec_t3 values(''); +insert into vec_t3 values('yzy'); +insert into vec_t3 values('zzz'); +insert into vec_t3 values(' z '); +insert into vec_t3 values(' '); +explain analyze SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; +--?QUERY PLAN.* +--?.* +--?Row Adapter.* +--?Vector Adapter(type: BATCH MODE).* +--?Seq Scan on vec_t3.* +--?.* +(4 rows) + +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; + input | result | isnull +-------+--------+-------- + | | t + yzy | yz | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t3; + input | result | isnull +-------+--------+-------- + | | t + yzy | yzy | f + zzz | | t + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t3; + input | result | isnull +-------+--------+-------- + | | t + yzy | yzy | f + zzz | zzz | f + z | z | f + | | t +(5 rows) + +create table pad2_tab(a text, b int); +insert into pad2_tab values('yes', 5), ('yes', 1), ('yes', 0); +create table pad3_tab(a text, b int, c text); +insert into pad3_tab values('yes', 5, 'z'), ('yes', 1, 'z'), ('yes', 0, 'z'); +SELECT a as p1, b as p2, lpad(a, b) is null from pad2_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | t +(3 rows) + +SELECT a as p1, b as p2, lpad(a, b, c) is null from pad3_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | t +(3 rows) + +SELECT a as p1, b as p2, rpad(a, b) is null from pad2_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | t +(3 rows) + +SELECT a as p1, b as p2, rpad(a, b, c) is null from pad3_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | t +(3 rows) + +create table trim2(a text, b text); +insert into trim2 values('yzy', 'y'), ('zzz', 'z'); +create table trim1(a text); +insert into trim1 values(' z '), (' '); +SELECT a as p1, b as p2, btrim(a, b) is null from trim2; + p1 | p2 | ?column? +-----+----+---------- + yzy | y | f + zzz | z | t +(2 rows) + +SELECT a as p1, b as p2, ltrim(a, b) is null from trim2; + p1 | p2 | ?column? +-----+----+---------- + yzy | y | f + zzz | z | t +(2 rows) + +SELECT a as p1, b as p2, rtrim(a, b) is null from trim2; + p1 | p2 | ?column? +-----+----+---------- + yzy | y | f + zzz | z | t +(2 rows) + +SELECT a as p1, btrim(a) is null from trim1; + p1 | ?column? +-----+---------- + z | f + | t +(2 rows) + +SELECT a as p1, ltrim(a) is null from trim1; + p1 | ?column? +-----+---------- + z | f + | t +(2 rows) + +SELECT a as p1, rtrim(a) is null from trim1; + p1 | ?column? +-----+---------- + z | f + | t +(2 rows) + +create table translate3(a text, b text, c text); +insert into translate3 values('xyx', 'x', 'z'), ('xzx', 'x', ''), ('xxx', 'x', ''), ('xxx', 'x', ' '), ('xxx', '', 'z'), ('', 'x', 'z'); +SELECT a as p1, b as p2, c as p3, translate(a, b, c) is null from translate3; + p1 | p2 | p3 | ?column? +-----+----+----+---------- + xyx | x | z | f + xzx | x | | t + xxx | x | | t + xxx | x | | f + xxx | | z | t + | x | z | t +(6 rows) + +create table repeat2 (a text, b int); +insert into repeat2 values('a', 3), ('a', 0), (' ', 3), ('', 3), ('', 0); +SELECT a as p1, b as p2, repeat(a, b) is null from repeat2; + p1 | p2 | ?column? +----+----+---------- + a | 3 | f + a | 0 | t + | 3 | f + | 3 | t + | 0 | t +(5 rows) + +create table oidvectortypes1 (a oidvector); +insert into oidvectortypes1 values ('123 456'), (''), (' '); +SELECT a as p1, oidvectortypes(a) is null from oidvectortypes1; + p1 | ?column? +---------+---------- + 123 456 | f + | t + | t +(3 rows) + +create table regexp_replace3 (a text, b text, c text); +insert into regexp_replace3 values('Thomas', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''), ('Thomas', '', 'M'), ('', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''); +SELECT a as p1, b as p2, c as p3, regexp_replace(a, b, c) is null from regexp_replace3; + p1 | p2 | p3 | ?column? +--------+---------+----+---------- + Thomas | .[mN]a. | M | f + omas | .[mN]a. | | t + Thomas | | M | f + | .[mN]a. | M | t + omas | .[mN]a. | | t +(5 rows) + +create table regexp_replace6 (a text, b text, c text, d int, e int, f text); +insert into regexp_replace6 values ('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n'), ('bar','b(..)', '', 1, 1, 'n'); +SELECT a as p1, b as p2, c as p3, d as p4, e as p5, f as p6, regexp_replace(a, b, c, d, e, f) is null from regexp_replace6; + p1 | p2 | p3 | p4 | p5 | p6 | ?column? +-----------+-------+------+----+----+----+---------- + foobarbaz | b(..) | X\1Y | 2 | 2 | n | f + bar | b(..) | | 1 | 1 | n | t +(2 rows) + +create table regexp_split_to_table2 (a text, b text); +insert into regexp_split_to_table2 values('hello world', E'\\s+'), ('', E'\\s+'), ('hello world', ''), ('hello world', null); +SELECT a as p1, b as p2, regexp_split_to_table(a, b) is null from regexp_split_to_table2; + p1 | p2 | ?column? +-------------+-----+---------- + hello world | \s+ | f + hello world | \s+ | f +(2 rows) + +create table substr2(a bytea, b int); +insert into substr2 values ('123'::bytea, 3), ('123'::bytea, 4); +select a as p1, b as p2, substr(a, b) is null from substr2; + p1 | p2 | ?column? +----------+----+---------- + \x313233 | 3 | f + \x313233 | 4 | t +(2 rows) + +create table substr3(a bytea, b int, c int); +insert into substr3 values('123'::bytea, 1, 2), ('123'::bytea, 1, 0); +select a as p1, b as p2, c as p3, substr(a, b, c) is null from substr3; + p1 | p2 | p3 | ?column? +----------+----+----+---------- + \x313233 | 1 | 2 | f + \x313233 | 1 | 0 | t +(2 rows) + +create table replace3 (a text, b text, c text); +insert into replace3 values ('abc', 'ab', 'd'), ('abc', 'abc', ''), ('abc', 'abc', ''), ('abc', 'ab', ''), ('abc', 'ab', null), ('abc', '', 'd'), ('abc', null, 'd'), ('', 'ab', 'd'), (null, 'ab', 'd'); +SELECT a as p1, b as p2, c as p3, replace(a, b, c) is null from replace3; + p1 | p2 | p3 | ?column? +-----+-----+----+---------- + abc | ab | d | f + abc | abc | | t + abc | abc | | t + abc | ab | | f + abc | ab | | f + abc | | d | f + abc | | d | f + | ab | d | t + | ab | d | t +(9 rows) + +create table replace2 (a text, b text); +insert into replace2 values('abc', 'ab'), ('abc', 'abc'), ('abc', ''), ('abc', null), ('', 'ab'), (null, 'ab'); +SELECT a as p1, b as p2, replace(a, b) is null from replace2; +ERROR: function returned NULL +create table split_part3 (a text, b text, c int); +insert into split_part3 values('1~2~3', '~', 3), ('1~2~3~', '~', 4), ('1~2~3', '', 1), ('1~2~3', null, 1), ('', '~', 1), (null, '~', 1); +SELECT a as p1, b as p2, c as p3, split_part(a, b, c) is null from split_part3; + p1 | p2 | p3 | ?column? +--------+----+----+---------- + 1~2~3 | ~ | 3 | f + 1~2~3~ | ~ | 4 | t + 1~2~3 | | 1 | t + 1~2~3 | | 1 | t + | ~ | 1 | t + | ~ | 1 | t +(6 rows) + +create table array_to_string2(a integer[], b text); +insert into array_to_string2 values(ARRAY[1, 2, 3, NULL, 5], ','), (ARRAY[1, 2, 3, NULL, 5], ''), (ARRAY[1, 2, 3, NULL, 5], null), (ARRAY[NULL], ''), (ARRAY[NULL], null); +SELECT a as p1, b as p2, array_to_string(a, b) AS RESULT from array_to_string2; + p1 | p2 | result +----------------+----+--------- + {1,2,3,NULL,5} | , | 1,2,3,5 + {1,2,3,NULL,5} | | + {1,2,3,NULL,5} | | + {NULL} | | + {NULL} | | +(5 rows) + +create table array_to_string3(a integer[], b text, c text); +insert into array_to_string3 values(ARRAY[1, 2, 3, NULL, 5], ',', '*'), (ARRAY[1, 2, 3, NULL, 5], '', ''), (ARRAY[1, 2, 3, NULL, 5], null, null), (ARRAY[NULL], '', ''), (ARRAY[NULL], null, null); +SELECT a as p1, b as p2, c as p3, array_to_string(a, b, c) AS RESULT from array_to_string3; + p1 | p2 | p3 | result +----------------+----+----+----------- + {1,2,3,NULL,5} | , | * | 1,2,3,*,5 + {1,2,3,NULL,5} | | | + {1,2,3,NULL,5} | | | + {NULL} | | | + {NULL} | | | +(5 rows) + +set try_vector_engine_strategy=off; diff --git a/src/test/regress/expected/pg_empty_str.out b/src/test/regress/expected/pg_empty_str.out new file mode 100644 index 0000000000..4070cb7186 --- /dev/null +++ b/src/test/regress/expected/pg_empty_str.out @@ -0,0 +1,1817 @@ +-- test about issue +create database test_pg dbcompatibility 'PG'; +\c test_pg +create schema accept_schema; +set current_schema to 'accept_schema'; +create table tchar(c char(10)); +set behavior_compat_options to 'accept_empty_str'; +insert into tchar values(' '); +select * from tchar where c = ''; + c +------------ + +(1 row) + +select * from tchar where c = ' '; + c +------------ + +(1 row) + +select * from tchar where c is null; + c +--- +(0 rows) + +drop table tchar; +-- test about const str +select '' is null; + ?column? +---------- + f +(1 row) + +select ' ' is null; + ?column? +---------- + f +(1 row) + +select ' abc ' is null; + ?column? +---------- + f +(1 row) + +select length(''); + length +-------- + 0 +(1 row) + +select length(null); + length +-------- + +(1 row) + +select length(' '); + length +-------- + 1 +(1 row) + +select length(' abc '); + length +-------- + 5 +(1 row) + +select '123'::char(3) is null; + ?column? +---------- + f +(1 row) + +select ''::char(3) is null; + ?column? +---------- + f +(1 row) + +select '123'::varchar(3) is null; + ?column? +---------- + f +(1 row) + +select ''::varchar(3) is null; + ?column? +---------- + f +(1 row) + +select '123'::text is null; + ?column? +---------- + f +(1 row) + +select ''::text is null; + ?column? +---------- + f +(1 row) + +select '123'::clob is null; + ?column? +---------- + f +(1 row) + +select ''::clob is null; + ?column? +---------- + f +(1 row) + +select '123'::blob is null; + ?column? +---------- + f +(1 row) + +select ''::blob is null; + ?column? +---------- + f +(1 row) + +select '123'::bytea is null; + ?column? +---------- + f +(1 row) + +select ''::bytea is null; + ?column? +---------- + f +(1 row) + +select '123'::int1 is null; + ?column? +---------- + f +(1 row) + +select ''::int1 is null; +ERROR: invalid input syntax for integer: "" +LINE 1: select ''::int1 is null; + ^ +select '123'::int2 is null; + ?column? +---------- + f +(1 row) + +select ''::int2 is null; +ERROR: invalid input syntax for integer: "" +LINE 1: select ''::int2 is null; + ^ +select '123'::int is null; + ?column? +---------- + f +(1 row) + +select ''::int is null; +ERROR: invalid input syntax for integer: "" +LINE 1: select ''::int is null; + ^ +select '123'::int8 is null; + ?column? +---------- + f +(1 row) + +select ''::int8 is null; +ERROR: invalid input syntax for type bigint: "" +LINE 1: select ''::int8 is null; + ^ +select '123'::float4 is null; + ?column? +---------- + f +(1 row) + +select ''::float4 is null; +ERROR: invalid input syntax for type real: "" +LINE 1: select ''::float4 is null; + ^ +select '123'::float8 is null; + ?column? +---------- + f +(1 row) + +select ''::float8 is null; +ERROR: invalid input syntax for type double precision: "" +LINE 1: select ''::float8 is null; + ^ +select '123'::numeric is null; + ?column? +---------- + f +(1 row) + +select ''::numeric is null; +ERROR: invalid input syntax for type numeric: "" +LINE 1: select ''::numeric is null; + ^ +select ''::date is null; +ERROR: invalid input syntax for type date: "" +LINE 1: select ''::date is null; + ^ +select ''::time is null; +ERROR: invalid input syntax for type time: "" +LINE 1: select ''::time is null; + ^ +select ''::timestamp is null; +ERROR: invalid input syntax for type timestamp: "" +LINE 1: select ''::timestamp is null; + ^ +-- test about var str +create table result_tab ("statement" text, result text); +declare +str_empty text := ''; +str_space text := ' '; +str_num text := '123'; +str text := ' abc '; +begin + insert into result_tab select 'select str_empty is null', str_empty is null; + insert into result_tab select 'select str_space is null', str_space is null; + insert into result_tab select 'select str is null', str is null; + insert into result_tab select 'select length(str_empty)', length(str_empty); + insert into result_tab select 'select length(null)', length(null); + insert into result_tab select 'select length(str_space)', length(str_space); + insert into result_tab select 'select length(str)', length(str); + insert into result_tab select 'select str_num::text is null', str_num::text is null; + insert into result_tab select 'select str_empty::text is null', str_empty::text is null; + insert into result_tab select 'select str_num::bytea is null;', str_num::bytea is null; + insert into result_tab select 'select str_empty::bytea is null', str_empty::bytea is null; + insert into result_tab select 'select str_num::int is null', str_num::int is null; + insert into result_tab select 'select str_num::float8 is null', str_num::float8 is null; + insert into result_tab select 'select str_num::numeric is null', str_num::numeric is null; +end; +/ +select * from result_tab; + statement | result +---------------------------------+-------- + select str_empty is null | false + select str_space is null | false + select str is null | false + select length(str_empty) | 0 + select length(null) | + select length(str_space) | 1 + select length(str) | 5 + select str_num::text is null | false + select str_empty::text is null | false + select str_num::bytea is null; | false + select str_empty::bytea is null | false + select str_num::int is null | false + select str_num::float8 is null | false + select str_num::numeric is null | false +(14 rows) + +-- test about function which return str +SELECT overlay('hello' placing 'world' from 2 for 3 ) is null; + ?column? +---------- + f +(1 row) + +SELECT overlay('hello' placing '' from 1 for 5 ) is null; + ?column? +---------- + f +(1 row) + +SELECT quote_ident('') is null; + ?column? +---------- + f +(1 row) + +SELECT quote_literal('') is null; + ?column? +---------- + f +(1 row) + +SELECT quote_nullable('') is null; + ?column? +---------- + f +(1 row) + +SELECT reverse('') is null; + ?column? +---------- + f +(1 row) + +SELECT ''||'' is null; + ?column? +---------- + false +(1 row) + +SELECT ''||41; + ?column? +---------- + 41 +(1 row) + +SELECT lower('') is null; + ?column? +---------- + f +(1 row) + +SELECT initcap('') is null; + ?column? +---------- + f +(1 row) + +SELECT ascii(''); + ascii +------- + 0 +(1 row) + +SELECT lpad('yes', 5) is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 5, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 1, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT lpad('yes', 0, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 5) is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 5, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 1, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT rpad('yes', 0, 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT btrim('yzy', 'y') is null; + ?column? +---------- + f +(1 row) + +SELECT btrim('zzz', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT ltrim('yzy', 'y') is null; + ?column? +---------- + f +(1 row) + +SELECT ltrim('zzz', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT rtrim('yzy', 'y') is null; + ?column? +---------- + f +(1 row) + +SELECT rtrim('zzz', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT btrim(' z ') is null; + ?column? +---------- + f +(1 row) + +SELECT btrim(' ') is null; + ?column? +---------- + f +(1 row) + +SELECT ltrim(' z ') is null; + ?column? +---------- + f +(1 row) + +SELECT ltrim(' ') is null; + ?column? +---------- + f +(1 row) + +SELECT rtrim(' z ') is null; + ?column? +---------- + f +(1 row) + +SELECT rtrim(' ') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xyx', 'x', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xzx', 'x', '') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xxx', 'x', '') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xxx', 'x', ' ') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('xxx', '', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT translate('', 'x', 'z') is null; + ?column? +---------- + f +(1 row) + +SELECT repeat('a', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat('a', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat(' ', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat(' ', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat('', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT repeat('', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT pg_catalog.oidvectortypes('123 456') is null; + ?column? +---------- + f +(1 row) + +SELECT pg_catalog.oidvectortypes('') is null; + ?column? +---------- + f +(1 row) + +SELECT pg_catalog.oidvectortypes(' ') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('Thomas', '.[mN]a.', 'M') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('omas', '.[mN]a.', ''); + regexp_replace +---------------- + +(1 row) + +SELECT regexp_replace('Thomas', '', 'M') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('', '.[mN]a.', 'M') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('omas', '.[mN]a.', '') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('bar','b(..)', '', 1, 1, 'n') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 'g') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_replace('abc','abc', '', 'g') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_substr('str','st') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_substr('str','[ac]') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_substr('str','') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_substr('','st') is null; + ?column? +---------- + t +(1 row) + +SELECT regexp_split_to_table('hello world', E'\\s+') is null; + ?column? +---------- + f + f +(2 rows) + +SELECT regexp_split_to_table('', E'\\s+') is null; + ?column? +---------- + f +(1 row) + +SELECT regexp_split_to_table('hello world', '') is null; + ?column? +---------- + f + f + f + f + f + f + f + f + f + f + f +(11 rows) + +SELECT regexp_split_to_table('hello world', null) is null; + ?column? +---------- +(0 rows) + +SELECT substr('123', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123', 4) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123', 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123', 1, 0) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123', 1, -1) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 4) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 1, 0) is null; + ?column? +---------- + f +(1 row) + +SELECT substr('123'::bytea, 1, -1) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 4) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 1, 0) is null; + ?column? +---------- + f +(1 row) + +SELECT substrb('123', 1, -1) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 4) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 1, 0) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123', 1, -1) is null; +ERROR: negative substring length not allowed +SELECT substring('123'::bytea, 3) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 4) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 1, 2) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 1, 0) is null; + ?column? +---------- + f +(1 row) + +SELECT substring('123'::bytea, 1, -1) is null; +ERROR: negative substring length not allowed +SELECT replace('abc', 'ab', 'd') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'abc', '') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'abc', null) is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'ab', '') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'ab', null) is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', '', 'd') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', null, 'd') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('', 'ab', 'd') is null; + ?column? +---------- + f +(1 row) + +SELECT replace(null, 'ab', 'd') is null; + ?column? +---------- + t +(1 row) + +SELECT replace('abc', 'ab') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', 'abc') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', '') is null; + ?column? +---------- + f +(1 row) + +SELECT replace('abc', null) is null; + ?column? +---------- + f +(1 row) + +SELECT replace('', 'ab') is null; + ?column? +---------- + f +(1 row) + +SELECT replace(null, 'ab') is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('1~2~3', '~', 3) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3~', '~', 4) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3', '~', -1) is null; +ERROR: field position must be greater than zero +SELECT split_part('1~2~3', '', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3', '', 2) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3', null, 1) is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('', '~', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part(null, '~', 1) is null; + ?column? +---------- + t +(1 row) + +SELECT split_part('1~2~3', '|', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT split_part('1~2~3', '|', 2) is null; + ?column? +---------- + f +(1 row) + +SELECT concat('Hello', ' World!') is null; + ?column? +---------- + f +(1 row) + +SELECT concat('', ' World!') is null; + ?column? +---------- + f +(1 row) + +SELECT concat('Hello', '') is null; + ?column? +---------- + f +(1 row) + +SELECT concat('', '') is null; + ?column? +---------- + f +(1 row) + +SELECT concat('Hello', null) is null; + ?column? +---------- + f +(1 row) + +SELECT concat(null, ' World!') is null; + ?column? +---------- + f +(1 row) + +SELECT concat_ws(',', 'ABCDE', 2, NULL, 22); + concat_ws +------------ + ABCDE,2,22 +(1 row) + +SELECT concat_ws('', 'ABCDE', 2, NULL, 22); + concat_ws +----------- + ABCDE222 +(1 row) + +SELECT concat_ws(',', '') is null; + ?column? +---------- + f +(1 row) + +SELECT concat_ws('', '') is null; + ?column? +---------- + f +(1 row) + +SELECT left('abcde', 2) is null; + ?column? +---------- + f +(1 row) + +SELECT left('abcde', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT left('abcde', -1) is null; + ?column? +---------- + f +(1 row) + +SELECT left('', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT left('', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT left('', -1) is null; + ?column? +---------- + f +(1 row) + +SELECT right('abcde', 2) is null; + ?column? +---------- + f +(1 row) + +SELECT right('abcde', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT right('abcde', -1) is null; + ?column? +---------- + f +(1 row) + +SELECT right('', 1) is null; + ?column? +---------- + f +(1 row) + +SELECT right('', 0) is null; + ?column? +---------- + f +(1 row) + +SELECT right('', -1) is null; + ?column? +---------- + f +(1 row) + +SELECT format('Hello %s', 'World'); + format +------------- + Hello World +(1 row) + +SELECT format('Hello %s', ''); + format +-------- + Hello +(1 row) + +SELECT format('%s', 'World'); + format +-------- + World +(1 row) + +SELECT format('', 'World'); + format +-------- + +(1 row) + +SELECT format('', ''); + format +-------- + +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',') AS RESULT; + result +--------- + 1,2,3,5 +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '') AS RESULT; + result +-------- + 1235 +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null) AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], '') AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], null) AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*') AS RESULT; + result +----------- + 1,2,3,*,5 +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '', '') AS RESULT; + result +-------- + 1235 +(1 row) + +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null, null) AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], '', '') AS RESULT; + result +-------- + +(1 row) + +SELECT array_to_string(ARRAY[NULL], null, null) AS RESULT; + result +-------- + +(1 row) + +SELECT nlssort('A', 'nls_sort=schinese_pinyin_m') is null; + ?column? +---------- + f +(1 row) + +SELECT nlssort('', 'nls_sort=schinese_pinyin_m') is null; + ?column? +---------- + f +(1 row) + +SELECT nlssort('A', '') is null; +ERROR: Sort method is not supported! +DETAIL: Not support the given sort method. +SELECT convert('text_in_utf8'::bytea, 'UTF8', 'GBK') is null; + ?column? +---------- + f +(1 row) + +SELECT convert(''::bytea, 'UTF8', 'GBK') is null; + ?column? +---------- + f +(1 row) + +SELECT convert('text_in_utf8'::bytea, '', 'GBK') is null; +ERROR: invalid source encoding name "" +SELECT convert('text_in_utf8'::bytea, 'UTF8', '') is null; +ERROR: invalid destination encoding name "" +SELECT convert_from('text_in_utf8'::bytea, 'UTF8') is null; + ?column? +---------- + f +(1 row) + +SELECT convert_from(''::bytea, 'UTF8') is null; + ?column? +---------- + f +(1 row) + +SELECT convert_from('text_in_utf8'::bytea, '') is null; +ERROR: invalid source encoding name "" +SELECT convert_to('text_in_utf8'::bytea, 'UTF8') is null; +ERROR: function convert_to(bytea, unknown) does not exist +LINE 1: SELECT convert_to('text_in_utf8'::bytea, 'UTF8') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT convert_to(''::bytea, 'UTF8') is null; +ERROR: function convert_to(bytea, unknown) does not exist +LINE 1: SELECT convert_to(''::bytea, 'UTF8') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT convert_to('text_in_utf8'::bytea, '') is null; +ERROR: function convert_to(bytea, unknown) does not exist +LINE 1: SELECT convert_to('text_in_utf8'::bytea, '') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT md5('ABC') is null; + ?column? +---------- + f +(1 row) + +SELECT md5('') is null; + ?column? +---------- + f +(1 row) + +SELECT sha('ABC') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha('') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha1('ABC') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha1('') is null; +ERROR: sha/sha1 is supported only in B-format database +SELECT sha2('ABC') is null; +ERROR: function sha2(unknown) does not exist +LINE 1: SELECT sha2('ABC') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT sha2('') is null; +ERROR: function sha2(unknown) does not exist +LINE 1: SELECT sha2('') is null; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT decode('MTIzAAE=', 'base64') is null; + ?column? +---------- + f +(1 row) + +SELECT decode('', 'base64') is null; + ?column? +---------- + f +(1 row) + +SELECT decode('MTIzAAE=', '') is null; +ERROR: unrecognized encoding: "" +select similar_escape('\s+ab','2') is null; + ?column? +---------- + f +(1 row) + +select similar_escape('\s+ab','') is null; + ?column? +---------- + f +(1 row) + +select similar_escape('','2') is null; + ?column? +---------- + f +(1 row) + +select svals('"aa"=>"bb"') is null; + ?column? +---------- + f +(1 row) + +select svals('') is null; + ?column? +---------- +(0 rows) + +select tconvert('aa', 'bb') is null; + ?column? +---------- + f +(1 row) + +select tconvert('', 'bb') is null; + ?column? +---------- + f +(1 row) + +select tconvert('aa', '') is null; + ?column? +---------- + f +(1 row) + +select tconvert('', '') is null; + ?column? +---------- + f +(1 row) + +SELECT encode(E'123\\000\\001', 'base64') is null; + ?column? +---------- + f +(1 row) + +SELECT encode('', 'base64') is null; + ?column? +---------- + f +(1 row) + +SELECT encode(E'123\\000\\001', '') is null; +ERROR: unrecognized encoding: "" +-- test about vec +CREATE TABLE vec_t1 +( + c varchar +) WITH (ORIENTATION = COLUMN); +CREATE TABLE vec_t2 +( + c varchar not null +) WITH (ORIENTATION = COLUMN); +insert into vec_t1 values(''); +insert into vec_t1 values(' '); +insert into vec_t1 values('abc'); +insert into vec_t2 values(''); +insert into vec_t2 values(' '); +insert into vec_t2 values('abc'); +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | a | f +(3 rows) + +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | | f +(3 rows) + +select c as input, substr(c, 1, -1) as result, result is null as is_null from vec_t1; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | | f +(3 rows) + +delete from vec_t1; +insert into vec_t1 values(''); +insert into vec_t1 values('yzy'); +insert into vec_t1 values('zzz'); +insert into vec_t1 values(' z '); +insert into vec_t1 values(' '); +SELECT c as input, btrim(c, 'y') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | z | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +SELECT c as input, btrim(c, 'z') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | | f + z | z | f + | | f +(5 rows) + +SELECT c as input, btrim(c) as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | yz | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t1; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +-- test row to vec +set try_vector_engine_strategy=force; +create table vec_t3(c text); +insert into vec_t3 values(''); +insert into vec_t3 values(' '); +insert into vec_t3 values('abc'); +explain analyze select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; +--?QUERY PLAN.* +--?.* +--?Row Adapter.* +--?Vector Adapter(type: BATCH MODE).* +--?Seq Scan on vec_t3.* +--?.* +(4 rows) + +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | a | f +(3 rows) + +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | ab | f +(3 rows) + +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t3; + input | result | is_null +-------+--------+--------- + | | f + | | f + abc | | f +(3 rows) + +delete from vec_t3; +insert into vec_t3 values(''); +insert into vec_t3 values('yzy'); +insert into vec_t3 values('zzz'); +insert into vec_t3 values(' z '); +insert into vec_t3 values(' '); +explain analyze SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; +--?QUERY PLAN.* +--?.* +--?Row Adapter.* +--?Vector Adapter(type: BATCH MODE).* +--?Seq Scan on vec_t3.* +--?.* +(4 rows) + +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; + input | result | isnull +-------+--------+-------- + | | f + yzy | yz | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t3; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | | f + z | z | f + | | f +(5 rows) + +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t3; + input | result | isnull +-------+--------+-------- + | | f + yzy | yzy | f + zzz | zzz | f + z | z | f + | | f +(5 rows) + +create table pad2_tab(a text, b int); +insert into pad2_tab values('yes', 5), ('yes', 1), ('yes', 0); +create table pad3_tab(a text, b int, c text); +insert into pad3_tab values('yes', 5, 'z'), ('yes', 1, 'z'), ('yes', 0, 'z'); +SELECT a as p1, b as p2, lpad(a, b) is null from pad2_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | f +(3 rows) + +SELECT a as p1, b as p2, lpad(a, b, c) is null from pad3_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | f +(3 rows) + +SELECT a as p1, b as p2, rpad(a, b) is null from pad2_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | f +(3 rows) + +SELECT a as p1, b as p2, rpad(a, b, c) is null from pad3_tab; + p1 | p2 | ?column? +-----+----+---------- + yes | 5 | f + yes | 1 | f + yes | 0 | f +(3 rows) + +create table trim2(a text, b text); +insert into trim2 values('yzy', 'y'), ('zzz', 'z'); +create table trim1(a text); +insert into trim1 values(' z '), (' '); +SELECT a as p1, b as p2, btrim(a, b) is null from trim2; + p1 | p2 | ?column? +-----+----+---------- + yzy | y | f + zzz | z | f +(2 rows) + +SELECT a as p1, b as p2, ltrim(a, b) is null from trim2; + p1 | p2 | ?column? +-----+----+---------- + yzy | y | f + zzz | z | f +(2 rows) + +SELECT a as p1, b as p2, rtrim(a, b) is null from trim2; + p1 | p2 | ?column? +-----+----+---------- + yzy | y | f + zzz | z | f +(2 rows) + +SELECT a as p1, btrim(a) is null from trim1; + p1 | ?column? +-----+---------- + z | f + | f +(2 rows) + +SELECT a as p1, ltrim(a) is null from trim1; + p1 | ?column? +-----+---------- + z | f + | f +(2 rows) + +SELECT a as p1, rtrim(a) is null from trim1; + p1 | ?column? +-----+---------- + z | f + | f +(2 rows) + +create table translate3(a text, b text, c text); +insert into translate3 values('xyx', 'x', 'z'), ('xzx', 'x', ''), ('xxx', 'x', ''), ('xxx', 'x', ' '), ('xxx', '', 'z'), ('', 'x', 'z'); +SELECT a as p1, b as p2, c as p3, translate(a, b, c) is null from translate3; + p1 | p2 | p3 | ?column? +-----+----+----+---------- + xyx | x | z | f + xzx | x | | f + xxx | x | | f + xxx | x | | f + xxx | | z | f + | x | z | f +(6 rows) + +create table repeat2 (a text, b int); +insert into repeat2 values('a', 3), ('a', 0), (' ', 3), ('', 3), ('', 0); +SELECT a as p1, b as p2, repeat(a, b) is null from repeat2; + p1 | p2 | ?column? +----+----+---------- + a | 3 | f + a | 0 | f + | 3 | f + | 3 | f + | 0 | f +(5 rows) + +create table oidvectortypes1 (a oidvector); +insert into oidvectortypes1 values ('123 456'), (''), (' '); +SELECT a as p1, oidvectortypes(a) is null from oidvectortypes1; + p1 | ?column? +---------+---------- + 123 456 | f + | f + | f +(3 rows) + +create table regexp_replace3 (a text, b text, c text); +insert into regexp_replace3 values('Thomas', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''), ('Thomas', '', 'M'), ('', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''); +SELECT a as p1, b as p2, c as p3, regexp_replace(a, b, c) is null from regexp_replace3; + p1 | p2 | p3 | ?column? +--------+---------+----+---------- + Thomas | .[mN]a. | M | f + omas | .[mN]a. | | f + Thomas | | M | f + | .[mN]a. | M | f + omas | .[mN]a. | | f +(5 rows) + +create table regexp_replace6 (a text, b text, c text, d int, e int, f text); +insert into regexp_replace6 values ('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n'), ('bar','b(..)', '', 1, 1, 'n'); +SELECT a as p1, b as p2, c as p3, d as p4, e as p5, f as p6, regexp_replace(a, b, c, d, e, f) is null from regexp_replace6; + p1 | p2 | p3 | p4 | p5 | p6 | ?column? +-----------+-------+------+----+----+----+---------- + foobarbaz | b(..) | X\1Y | 2 | 2 | n | f + bar | b(..) | | 1 | 1 | n | f +(2 rows) + +create table regexp_split_to_table2 (a text, b text); +insert into regexp_split_to_table2 values('hello world', E'\\s+'), ('', E'\\s+'), ('hello world', ''), ('hello world', null); +SELECT a as p1, b as p2, regexp_split_to_table(a, b) is null from regexp_split_to_table2; + p1 | p2 | ?column? +-------------+-----+---------- + hello world | \s+ | f + hello world | \s+ | f + | \s+ | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f + hello world | | f +(14 rows) + +create table substr2(a bytea, b int); +insert into substr2 values ('123'::bytea, 3), ('123'::bytea, 4); +select a as p1, b as p2, substr(a, b) is null from substr2; + p1 | p2 | ?column? +----------+----+---------- + \x313233 | 3 | f + \x313233 | 4 | f +(2 rows) + +create table substr3(a bytea, b int, c int); +insert into substr3 values('123'::bytea, 1, 2), ('123'::bytea, 1, 0); +select a as p1, b as p2, c as p3, substr(a, b, c) is null from substr3; + p1 | p2 | p3 | ?column? +----------+----+----+---------- + \x313233 | 1 | 2 | f + \x313233 | 1 | 0 | f +(2 rows) + +create table replace3 (a text, b text, c text); +insert into replace3 values ('abc', 'ab', 'd'), ('abc', 'abc', ''), ('abc', 'abc', ''), ('abc', 'ab', ''), ('abc', 'ab', null), ('abc', '', 'd'), ('abc', null, 'd'), ('', 'ab', 'd'), (null, 'ab', 'd'); +SELECT a as p1, b as p2, c as p3, replace(a, b, c) is null from replace3; + p1 | p2 | p3 | ?column? +-----+-----+----+---------- + abc | ab | d | f + abc | abc | | f + abc | abc | | f + abc | ab | | f + abc | ab | | f + abc | | d | f + abc | | d | f + | ab | d | f + | ab | d | t +(9 rows) + +create table replace2 (a text, b text); +insert into replace2 values('abc', 'ab'), ('abc', 'abc'), ('abc', ''), ('abc', null), ('', 'ab'), (null, 'ab'); +SELECT a as p1, b as p2, replace(a, b) is null from replace2; + p1 | p2 | ?column? +-----+-----+---------- + abc | ab | f + abc | abc | f + abc | | f + abc | | f + | ab | f + | ab | t +(6 rows) + +create table split_part3 (a text, b text, c int); +insert into split_part3 values('1~2~3', '~', 3), ('1~2~3~', '~', 4), ('1~2~3', '', 1), ('1~2~3', null, 1), ('', '~', 1), (null, '~', 1); +SELECT a as p1, b as p2, c as p3, split_part(a, b, c) is null from split_part3; + p1 | p2 | p3 | ?column? +--------+----+----+---------- + 1~2~3 | ~ | 3 | f + 1~2~3~ | ~ | 4 | f + 1~2~3 | | 1 | f + 1~2~3 | | 1 | t + | ~ | 1 | f + | ~ | 1 | t +(6 rows) + +create table array_to_string2(a integer[], b text); +insert into array_to_string2 values(ARRAY[1, 2, 3, NULL, 5], ','), (ARRAY[1, 2, 3, NULL, 5], ''), (ARRAY[1, 2, 3, NULL, 5], null), (ARRAY[NULL], ''), (ARRAY[NULL], null); +SELECT a as p1, b as p2, array_to_string(a, b) AS RESULT from array_to_string2; + p1 | p2 | result +----------------+----+--------- + {1,2,3,NULL,5} | , | 1,2,3,5 + {1,2,3,NULL,5} | | 1235 + {1,2,3,NULL,5} | | + {NULL} | | + {NULL} | | +(5 rows) + +create table array_to_string3(a integer[], b text, c text); +insert into array_to_string3 values(ARRAY[1, 2, 3, NULL, 5], ',', '*'), (ARRAY[1, 2, 3, NULL, 5], '', ''), (ARRAY[1, 2, 3, NULL, 5], null, null), (ARRAY[NULL], '', ''), (ARRAY[NULL], null, null); +SELECT a as p1, b as p2, c as p3, array_to_string(a, b, c) AS RESULT from array_to_string3; + p1 | p2 | p3 | result +----------------+----+----+----------- + {1,2,3,NULL,5} | , | * | 1,2,3,*,5 + {1,2,3,NULL,5} | | | 1235 + {1,2,3,NULL,5} | | | + {NULL} | | | + {NULL} | | | +(5 rows) + +set try_vector_engine_strategy=off; diff --git a/src/test/regress/input/accept_empty_copy.source b/src/test/regress/input/accept_empty_copy.source new file mode 100644 index 0000000000..9761852afd --- /dev/null +++ b/src/test/regress/input/accept_empty_copy.source @@ -0,0 +1,33 @@ +create schema accept_schema_copy; +set current_schema to 'accept_schema_copy'; +set behavior_compat_options to 'accept_empty_str'; +create table t ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +insert into t values('abc', 'abc', 'abc', 'abc'), (' ', ' ', ' ', ' '), ('', '', '', ''); + +create table t_stdin ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_csv ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_text_tab ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_binary ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); + +COPY t TO '@abs_srcdir@/data/datanode1/accept_t_csv.data' WITH(FORMAT 'csv'); +COPY t TO '@abs_srcdir@/data/datanode1/accept_t_text.data' WITH(FORMAT 'text'); +COPY t TO '@abs_srcdir@/data/datanode1/accept_t_binary.data' WITH(FORMAT 'binary'); + +COPY t_csv FROM '@abs_srcdir@/data/datanode1/accept_t_csv.data' WITH(FORMAT 'csv'); +COPY t_text_tab FROM '@abs_srcdir@/data/datanode1/accept_t_text.data' WITH(FORMAT 'text'); +COPY t_binary FROM '@abs_srcdir@/data/datanode1/accept_t_binary.data' WITH(FORMAT 'binary'); + +SELECT * FROM t; +SELECT * FROM t_csv; +SELECT * FROM t_text_tab; +SELECT * FROM t_binary; + +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t; +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_csv; +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_text_tab; +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_binary; + +\d t; +\d t_csv; +\d t_text; +\d t_binary; \ No newline at end of file diff --git a/src/test/regress/input/not_accept_empty_copy.source b/src/test/regress/input/not_accept_empty_copy.source new file mode 100644 index 0000000000..9fed5d86e8 --- /dev/null +++ b/src/test/regress/input/not_accept_empty_copy.source @@ -0,0 +1,33 @@ +create schema not_accept_schema_copy; +set current_schema to 'not_accept_schema_copy'; +set behavior_compat_options to ''; +create table t ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +insert into t values('abc', 'abc', 'abc', 'abc'), (' ', ' ', ' ', ' '), ('', '', '', ''); + +create table t_stdin ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_csv ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_text_tab ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_binary ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); + +COPY t TO '@abs_srcdir@/data/datanode1/not_accept_t_csv.data' WITH(FORMAT 'csv'); +COPY t TO '@abs_srcdir@/data/datanode1/not_accept_t_text.data' WITH(FORMAT 'text'); +COPY t TO '@abs_srcdir@/data/datanode1/not_accept_t_binary.data' WITH(FORMAT 'binary'); + +COPY t_csv FROM '@abs_srcdir@/data/datanode1/not_accept_t_csv.data' WITH(FORMAT 'csv'); +COPY t_text_tab FROM '@abs_srcdir@/data/datanode1/not_accept_t_text.data' WITH(FORMAT 'text'); +COPY t_binary FROM '@abs_srcdir@/data/datanode1/not_accept_t_binary.data' WITH(FORMAT 'binary'); + +SELECT * FROM t; +SELECT * FROM t_csv; +SELECT * FROM t_text_tab; +SELECT * FROM t_binary; + +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t; +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_csv; +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_text_tab; +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_binary; + +\d t; +\d t_csv; +\d t_text; +\d t_binary; \ No newline at end of file diff --git a/src/test/regress/output/accept_empty_copy.source b/src/test/regress/output/accept_empty_copy.source new file mode 100644 index 0000000000..4209534e3e --- /dev/null +++ b/src/test/regress/output/accept_empty_copy.source @@ -0,0 +1,107 @@ +create schema accept_schema_copy; +set current_schema to 'accept_schema_copy'; +set behavior_compat_options to 'accept_empty_str'; +create table t ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +insert into t values('abc', 'abc', 'abc', 'abc'), (' ', ' ', ' ', ' '), ('', '', '', ''); +create table t_stdin ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_csv ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_text_tab ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_binary ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +COPY t TO '@abs_srcdir@/data/datanode1/accept_t_csv.data' WITH(FORMAT 'csv'); +COPY t TO '@abs_srcdir@/data/datanode1/accept_t_text.data' WITH(FORMAT 'text'); +COPY t TO '@abs_srcdir@/data/datanode1/accept_t_binary.data' WITH(FORMAT 'binary'); +COPY t_csv FROM '@abs_srcdir@/data/datanode1/accept_t_csv.data' WITH(FORMAT 'csv'); +COPY t_text_tab FROM '@abs_srcdir@/data/datanode1/accept_t_text.data' WITH(FORMAT 'text'); +COPY t_binary FROM '@abs_srcdir@/data/datanode1/accept_t_binary.data' WITH(FORMAT 'binary'); +SELECT * FROM t; + t_varchar | t_text | t_char | t_bytea +-----------+--------+------------+---------- + abc | abc | abc | \x616263 + | | | \x202020 + | | | \x +(3 rows) + +SELECT * FROM t_csv; + t_varchar | t_text | t_char | t_bytea +-----------+--------+------------+---------- + abc | abc | abc | \x616263 + | | | \x202020 + | | | \x +(3 rows) + +SELECT * FROM t_text_tab; + t_varchar | t_text | t_char | t_bytea +-----------+--------+------------+---------- + abc | abc | abc | \x616263 + | | | \x202020 + | | | \x +(3 rows) + +SELECT * FROM t_binary; + t_varchar | t_text | t_char | t_bytea +-----------+--------+------------+---------- + abc | abc | abc | \x616263 + | | | \x202020 + | | | \x +(3 rows) + +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t; + varchar is null | text is null | char is null | bytea is null +-----------------+--------------+--------------+--------------- + f | f | f | f + f | f | f | f + f | f | f | f +(3 rows) + +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_csv; + varchar is null | text is null | char is null | bytea is null +-----------------+--------------+--------------+--------------- + f | f | f | f + f | f | f | f + f | f | f | f +(3 rows) + +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_text_tab; + varchar is null | text is null | char is null | bytea is null +-----------------+--------------+--------------+--------------- + f | f | f | f + f | f | f | f + f | f | f | f +(3 rows) + +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_binary; + varchar is null | text is null | char is null | bytea is null +-----------------+--------------+--------------+--------------- + f | f | f | f + f | f | f | f + f | f | f | f +(3 rows) + +\d t; + Table "accept_schema_copy.t" + Column | Type | Modifiers +-----------+-------------------+----------- + t_varchar | character varying | + t_text | text | + t_char | character(10) | + t_bytea | bytea | + +\d t_csv; + Table "accept_schema_copy.t_csv" + Column | Type | Modifiers +-----------+-------------------+----------- + t_varchar | character varying | + t_text | text | + t_char | character(10) | + t_bytea | bytea | + +\d t_text; +\d t_binary; + Table "accept_schema_copy.t_binary" + Column | Type | Modifiers +-----------+-------------------+----------- + t_varchar | character varying | + t_text | text | + t_char | character(10) | + t_bytea | bytea | + diff --git a/src/test/regress/output/not_accept_empty_copy.source b/src/test/regress/output/not_accept_empty_copy.source new file mode 100644 index 0000000000..02288e1187 --- /dev/null +++ b/src/test/regress/output/not_accept_empty_copy.source @@ -0,0 +1,107 @@ +create schema not_accept_schema_copy; +set current_schema to 'not_accept_schema_copy'; +set behavior_compat_options to ''; +create table t ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +insert into t values('abc', 'abc', 'abc', 'abc'), (' ', ' ', ' ', ' '), ('', '', '', ''); +create table t_stdin ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_csv ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_text_tab ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +create table t_binary ("t_varchar" varchar, "t_text" text, "t_char" char(10), "t_bytea" bytea); +COPY t TO '@abs_srcdir@/data/datanode1/not_accept_t_csv.data' WITH(FORMAT 'csv'); +COPY t TO '@abs_srcdir@/data/datanode1/not_accept_t_text.data' WITH(FORMAT 'text'); +COPY t TO '@abs_srcdir@/data/datanode1/not_accept_t_binary.data' WITH(FORMAT 'binary'); +COPY t_csv FROM '@abs_srcdir@/data/datanode1/not_accept_t_csv.data' WITH(FORMAT 'csv'); +COPY t_text_tab FROM '@abs_srcdir@/data/datanode1/not_accept_t_text.data' WITH(FORMAT 'text'); +COPY t_binary FROM '@abs_srcdir@/data/datanode1/not_accept_t_binary.data' WITH(FORMAT 'binary'); +SELECT * FROM t; + t_varchar | t_text | t_char | t_bytea +-----------+--------+------------+---------- + abc | abc | abc | \x616263 + | | | \x202020 + | | | +(3 rows) + +SELECT * FROM t_csv; + t_varchar | t_text | t_char | t_bytea +-----------+--------+------------+---------- + abc | abc | abc | \x616263 + | | | \x202020 + | | | +(3 rows) + +SELECT * FROM t_text_tab; + t_varchar | t_text | t_char | t_bytea +-----------+--------+------------+---------- + abc | abc | abc | \x616263 + | | | \x202020 + | | | +(3 rows) + +SELECT * FROM t_binary; + t_varchar | t_text | t_char | t_bytea +-----------+--------+------------+---------- + abc | abc | abc | \x616263 + | | | \x202020 + | | | +(3 rows) + +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t; + varchar is null | text is null | char is null | bytea is null +-----------------+--------------+--------------+--------------- + f | f | f | f + f | f | f | f + t | t | t | t +(3 rows) + +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_csv; + varchar is null | text is null | char is null | bytea is null +-----------------+--------------+--------------+--------------- + f | f | f | f + f | f | f | f + t | t | t | t +(3 rows) + +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_text_tab; + varchar is null | text is null | char is null | bytea is null +-----------------+--------------+--------------+--------------- + f | f | f | f + f | f | f | f + t | t | t | t +(3 rows) + +SELECT "t_varchar" is null as "varchar is null", "t_text" is null as "text is null", "t_char" is null as "char is null", "t_bytea" is null as "bytea is null" FROM t_binary; + varchar is null | text is null | char is null | bytea is null +-----------------+--------------+--------------+--------------- + f | f | f | f + f | f | f | f + t | t | t | t +(3 rows) + +\d t; + Table "not_accept_schema_copy.t" + Column | Type | Modifiers +-----------+-------------------+----------- + t_varchar | character varying | + t_text | text | + t_char | character(10) | + t_bytea | bytea | + +\d t_csv; + Table "not_accept_schema_copy.t_csv" + Column | Type | Modifiers +-----------+-------------------+----------- + t_varchar | character varying | + t_text | text | + t_char | character(10) | + t_bytea | bytea | + +\d t_text; +\d t_binary; + Table "not_accept_schema_copy.t_binary" + Column | Type | Modifiers +-----------+-------------------+----------- + t_varchar | character varying | + t_text | text | + t_char | character(10) | + t_bytea | bytea | + diff --git a/src/test/regress/parallel_schedule0A b/src/test/regress/parallel_schedule0A index 894813e784..967c1a19ba 100644 --- a/src/test/regress/parallel_schedule0A +++ b/src/test/regress/parallel_schedule0A @@ -562,3 +562,6 @@ test: udf_crem create_c_function test: publication test: subscription test: fdw_audit + +# test for empty string in A format database +test: accept_empty_str not_accept_empty_str pg_empty_str accept_empty_copy not_accept_empty_copy diff --git a/src/test/regress/sql/accept_empty_str.sql b/src/test/regress/sql/accept_empty_str.sql new file mode 100644 index 0000000000..dd9fb93e4a --- /dev/null +++ b/src/test/regress/sql/accept_empty_str.sql @@ -0,0 +1,405 @@ +-- test about issue +create schema accept_schema; +set current_schema to 'accept_schema'; +create table tchar(c char(10)); +set behavior_compat_options to 'accept_empty_str'; +insert into tchar values(' '); +select * from tchar where c = ''; +select * from tchar where c = ' '; +select * from tchar where c is null; +drop table tchar; + +-- test about const str +select '' is null; +select ' ' is null; +select ' abc ' is null; +select length(''); +select length(null); +select length(' '); +select length(' abc '); +select '123'::char(3) is null; +select ''::char(3) is null; +select '123'::varchar(3) is null; +select ''::varchar(3) is null; +select '123'::text is null; +select ''::text is null; +select '123'::clob is null; +select ''::clob is null; +select '123'::blob is null; +select ''::blob is null; +select '123'::bytea is null; +select ''::bytea is null; +select '123'::int1 is null; +select ''::int1 is null; +select '123'::int2 is null; +select ''::int2 is null; +select '123'::int is null; +select ''::int is null; +select '123'::int8 is null; +select ''::int8 is null; +select '123'::float4 is null; +select ''::float4 is null; +select '123'::float8 is null; +select ''::float8 is null; +select '123'::numeric is null; +select ''::numeric is null; +select ''::date is null; +select ''::time is null; +select ''::timestamp is null; + +-- test about var str +create table result_tab ("statement" text, result text); +declare +str_empty text := ''; +str_space text := ' '; +str_num text := '123'; +str text := ' abc '; +begin + insert into result_tab select 'select str_empty is null', str_empty is null; + insert into result_tab select 'select str_space is null', str_space is null; + insert into result_tab select 'select str is null', str is null; + insert into result_tab select 'select length(str_empty)', length(str_empty); + insert into result_tab select 'select length(null)', length(null); + insert into result_tab select 'select length(str_space)', length(str_space); + insert into result_tab select 'select length(str)', length(str); + insert into result_tab select 'select str_num::text is null', str_num::text is null; + insert into result_tab select 'select str_empty::text is null', str_empty::text is null; + insert into result_tab select 'select str_num::bytea is null;', str_num::bytea is null; + insert into result_tab select 'select str_empty::bytea is null', str_empty::bytea is null; + insert into result_tab select 'select str_num::int is null', str_num::int is null; + insert into result_tab select 'select str_num::float8 is null', str_num::float8 is null; + insert into result_tab select 'select str_num::numeric is null', str_num::numeric is null; +end; +/ + +select * from result_tab; + +-- test about function which return str +SELECT overlay('hello' placing 'world' from 2 for 3 ) is null; +SELECT overlay('hello' placing '' from 1 for 5 ) is null; +SELECT quote_ident('') is null; +SELECT quote_literal('') is null; +SELECT quote_nullable('') is null; +SELECT reverse('') is null; +SELECT ''||'' is null; +SELECT ''||41; +SELECT lower('') is null; +SELECT initcap('') is null; +SELECT ascii(''); +SELECT lpad('yes', 5) is null; +SELECT lpad('yes', 1) is null; +SELECT lpad('yes', 0) is null; +SELECT lpad('yes', 5, 'z') is null; +SELECT lpad('yes', 1, 'z') is null; +SELECT lpad('yes', 0, 'z') is null; +SELECT rpad('yes', 5) is null; +SELECT rpad('yes', 1) is null; +SELECT rpad('yes', 0) is null; +SELECT rpad('yes', 5, 'z') is null; +SELECT rpad('yes', 1, 'z') is null; +SELECT rpad('yes', 0, 'z') is null; +SELECT btrim('yzy', 'y') is null; +SELECT btrim('zzz', 'z') is null; +SELECT ltrim('yzy', 'y') is null; +SELECT ltrim('zzz', 'z') is null; +SELECT rtrim('yzy', 'y') is null; +SELECT rtrim('zzz', 'z') is null; +SELECT btrim(' z ') is null; +SELECT btrim(' ') is null; +SELECT ltrim(' z ') is null; +SELECT ltrim(' ') is null; +SELECT rtrim(' z ') is null; +SELECT rtrim(' ') is null; +SELECT translate('xyx', 'x', 'z') is null; +SELECT translate('xzx', 'x', '') is null; +SELECT translate('xxx', 'x', '') is null; +SELECT translate('xxx', 'x', ' ') is null; +SELECT translate('xxx', '', 'z') is null; +SELECT translate('', 'x', 'z') is null; +SELECT repeat('a', 3) is null; +SELECT repeat('a', 0) is null; +SELECT repeat(' ', 3) is null; +SELECT repeat(' ', 0) is null; +SELECT repeat('', 3) is null; +SELECT repeat('', 0) is null; +SELECT pg_catalog.oidvectortypes('123 456') is null; +SELECT pg_catalog.oidvectortypes('') is null; +SELECT pg_catalog.oidvectortypes(' ') is null; +SELECT regexp_replace('Thomas', '.[mN]a.', 'M') is null; +SELECT regexp_replace('omas', '.[mN]a.', ''); +SELECT regexp_replace('Thomas', '', 'M') is null; +SELECT regexp_replace('', '.[mN]a.', 'M') is null; +SELECT regexp_replace('omas', '.[mN]a.', '') is null; +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n') is null; +SELECT regexp_replace('bar','b(..)', '', 1, 1, 'n') is null; +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 'g') is null; +SELECT regexp_replace('abc','abc', '', 'g') is null; +SELECT regexp_substr('str','st') is null; +SELECT regexp_substr('str','[ac]') is null; +SELECT regexp_substr('str','') is null; +SELECT regexp_substr('','st') is null; +SELECT regexp_split_to_table('hello world', E'\\s+') is null; +SELECT regexp_split_to_table('', E'\\s+') is null; +SELECT regexp_split_to_table('hello world', '') is null; +SELECT regexp_split_to_table('hello world', null) is null; +SELECT substr('123', 3) is null; +SELECT substr('123', 4) is null; +SELECT substr('123', 1, 2) is null; +SELECT substr('123', 1, 0) is null; +SELECT substr('123', 1, -1) is null; +SELECT substr('123'::bytea, 3) is null; +SELECT substr('123'::bytea, 4) is null; +SELECT substr('123'::bytea, 1, 2) is null; +SELECT substr('123'::bytea, 1, 0) is null; +SELECT substr('123'::bytea, 1, -1) is null; +SELECT substrb('123', 3) is null; +SELECT substrb('123', 4) is null; +SELECT substrb('123', 1, 2) is null; +SELECT substrb('123', 1, 0) is null; +SELECT substrb('123', 1, -1) is null; +SELECT substring('123', 3) is null; +SELECT substring('123', 4) is null; +SELECT substring('123', 1, 2) is null; +SELECT substring('123', 1, 0) is null; +SELECT substring('123', 1, -1) is null; +SELECT substring('123'::bytea, 3) is null; +SELECT substring('123'::bytea, 4) is null; +SELECT substring('123'::bytea, 1, 2) is null; +SELECT substring('123'::bytea, 1, 0) is null; +SELECT substring('123'::bytea, 1, -1) is null; +SELECT replace('abc', 'ab', 'd') is null; +SELECT replace('abc', 'abc', '') is null; +SELECT replace('abc', 'abc', null) is null; +SELECT replace('abc', 'ab', '') is null; +SELECT replace('abc', 'ab', null) is null; +SELECT replace('abc', '', 'd') is null; +SELECT replace('abc', null, 'd') is null; +SELECT replace('', 'ab', 'd') is null; +SELECT replace(null, 'ab', 'd') is null; +SELECT replace('abc', 'ab') is null; +SELECT replace('abc', 'abc') is null; +SELECT replace('abc', '') is null; +SELECT replace('abc', null) is null; +SELECT replace('', 'ab') is null; +SELECT replace(null, 'ab') is null; +SELECT split_part('1~2~3', '~', 3) is null; +SELECT split_part('1~2~3~', '~', 4) is null; +SELECT split_part('1~2~3', '~', -1) is null; +SELECT split_part('1~2~3', '', 1) is null; +SELECT split_part('1~2~3', '', 2) is null; +SELECT split_part('1~2~3', null, 1) is null; +SELECT split_part('', '~', 1) is null; +SELECT split_part(null, '~', 1) is null; +SELECT split_part('1~2~3', '|', 1) is null; +SELECT split_part('1~2~3', '|', 2) is null; +SELECT concat('Hello', ' World!') is null; +SELECT concat('', ' World!') is null; +SELECT concat('Hello', '') is null; +SELECT concat('', '') is null; +SELECT concat('Hello', null) is null; +SELECT concat(null, ' World!') is null; +SELECT concat_ws(',', 'ABCDE', 2, NULL, 22); +SELECT concat_ws('', 'ABCDE', 2, NULL, 22); +SELECT concat_ws(',', '') is null; +SELECT concat_ws('', '') is null; +SELECT left('abcde', 2) is null; +SELECT left('abcde', 0) is null; +SELECT left('abcde', -1) is null; +SELECT left('', 1) is null; +SELECT left('', 0) is null; +SELECT left('', -1) is null; +SELECT right('abcde', 2) is null; +SELECT right('abcde', 0) is null; +SELECT right('abcde', -1) is null; +SELECT right('', 1) is null; +SELECT right('', 0) is null; +SELECT right('', -1) is null; +SELECT format('Hello %s', 'World'); +SELECT format('Hello %s', ''); +SELECT format('%s', 'World'); +SELECT format('', 'World'); +SELECT format('', ''); +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null) AS RESULT; +SELECT array_to_string(ARRAY[NULL], '') AS RESULT; +SELECT array_to_string(ARRAY[NULL], null) AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '', '') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null, null) AS RESULT; +SELECT array_to_string(ARRAY[NULL], '', '') AS RESULT; +SELECT array_to_string(ARRAY[NULL], null, null) AS RESULT; +SELECT nlssort('A', 'nls_sort=schinese_pinyin_m') is null; +SELECT nlssort('', 'nls_sort=schinese_pinyin_m') is null; +SELECT nlssort('A', '') is null; +SELECT convert('text_in_utf8'::bytea, 'UTF8', 'GBK') is null; +SELECT convert(''::bytea, 'UTF8', 'GBK') is null; +SELECT convert('text_in_utf8'::bytea, '', 'GBK') is null; +SELECT convert('text_in_utf8'::bytea, 'UTF8', '') is null; +SELECT convert_from('text_in_utf8'::bytea, 'UTF8') is null; +SELECT convert_from(''::bytea, 'UTF8') is null; +SELECT convert_from('text_in_utf8'::bytea, '') is null; +SELECT convert_to('text_in_utf8'::bytea, 'UTF8') is null; +SELECT convert_to(''::bytea, 'UTF8') is null; +SELECT convert_to('text_in_utf8'::bytea, '') is null; +SELECT md5('ABC') is null; +SELECT md5('') is null; +SELECT sha('ABC') is null; +SELECT sha('') is null; +SELECT sha1('ABC') is null; +SELECT sha1('') is null; +SELECT sha2('ABC') is null; +SELECT sha2('') is null; +SELECT decode('MTIzAAE=', 'base64') is null; +SELECT decode('', 'base64') is null; +SELECT decode('MTIzAAE=', '') is null; +select similar_escape('\s+ab','2') is null; +select similar_escape('\s+ab','') is null; +select similar_escape('','2') is null; +select svals('"aa"=>"bb"') is null; +select svals('') is null; +select tconvert('aa', 'bb') is null; +select tconvert('', 'bb') is null; +select tconvert('aa', '') is null; +select tconvert('', '') is null; +SELECT encode(E'123\\000\\001', 'base64') is null; +SELECT encode('', 'base64') is null; +SELECT encode(E'123\\000\\001', '') is null; + +-- test about vec +CREATE TABLE vec_t1 +( + c varchar +) WITH (ORIENTATION = COLUMN); + +CREATE TABLE vec_t2 +( + c varchar not null +) WITH (ORIENTATION = COLUMN); + +insert into vec_t1 values(''); +insert into vec_t1 values(' '); +insert into vec_t1 values('abc'); + +insert into vec_t2 values(''); +insert into vec_t2 values(' '); +insert into vec_t2 values('abc'); + +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 1, -1) as result, result is null as is_null from vec_t1; + +delete from vec_t1; +insert into vec_t1 values(''); +insert into vec_t1 values('yzy'); +insert into vec_t1 values('zzz'); +insert into vec_t1 values(' z '); +insert into vec_t1 values(' '); + +SELECT c as input, btrim(c, 'y') as result, result is null as isnull from vec_t1; +SELECT c as input, btrim(c, 'z') as result, result is null as isnull from vec_t1; +SELECT c as input, btrim(c) as result, result is null as isnull from vec_t1; +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t1; +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t1; +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t1; + +-- test row to vec +set try_vector_engine_strategy=force; +create table vec_t3(c text); +insert into vec_t3 values(''); +insert into vec_t3 values(' '); +insert into vec_t3 values('abc'); + +explain analyze select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t3; + +delete from vec_t3; +insert into vec_t3 values(''); +insert into vec_t3 values('yzy'); +insert into vec_t3 values('zzz'); +insert into vec_t3 values(' z '); +insert into vec_t3 values(' '); + +explain analyze SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t3; +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t3; + +create table pad2_tab(a text, b int); +insert into pad2_tab values('yes', 5), ('yes', 1), ('yes', 0); +create table pad3_tab(a text, b int, c text); +insert into pad3_tab values('yes', 5, 'z'), ('yes', 1, 'z'), ('yes', 0, 'z'); +SELECT a as p1, b as p2, lpad(a, b) is null from pad2_tab; +SELECT a as p1, b as p2, lpad(a, b, c) is null from pad3_tab; +SELECT a as p1, b as p2, rpad(a, b) is null from pad2_tab; +SELECT a as p1, b as p2, rpad(a, b, c) is null from pad3_tab; + +create table trim2(a text, b text); +insert into trim2 values('yzy', 'y'), ('zzz', 'z'); +create table trim1(a text); +insert into trim1 values(' z '), (' '); +SELECT a as p1, b as p2, btrim(a, b) is null from trim2; +SELECT a as p1, b as p2, ltrim(a, b) is null from trim2; +SELECT a as p1, b as p2, rtrim(a, b) is null from trim2; +SELECT a as p1, btrim(a) is null from trim1; +SELECT a as p1, ltrim(a) is null from trim1; +SELECT a as p1, rtrim(a) is null from trim1; + +create table translate3(a text, b text, c text); +insert into translate3 values('xyx', 'x', 'z'), ('xzx', 'x', ''), ('xxx', 'x', ''), ('xxx', 'x', ' '), ('xxx', '', 'z'), ('', 'x', 'z'); +SELECT a as p1, b as p2, c as p3, translate(a, b, c) is null from translate3; + +create table repeat2 (a text, b int); +insert into repeat2 values('a', 3), ('a', 0), (' ', 3), ('', 3), ('', 0); +SELECT a as p1, b as p2, repeat(a, b) is null from repeat2; + +create table oidvectortypes1 (a oidvector); +insert into oidvectortypes1 values ('123 456'), (''), (' '); +SELECT a as p1, oidvectortypes(a) is null from oidvectortypes1; + +create table regexp_replace3 (a text, b text, c text); +insert into regexp_replace3 values('Thomas', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''), ('Thomas', '', 'M'), ('', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''); +SELECT a as p1, b as p2, c as p3, regexp_replace(a, b, c) is null from regexp_replace3; + +create table regexp_replace6 (a text, b text, c text, d int, e int, f text); +insert into regexp_replace6 values ('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n'), ('bar','b(..)', '', 1, 1, 'n'); +SELECT a as p1, b as p2, c as p3, d as p4, e as p5, f as p6, regexp_replace(a, b, c, d, e, f) is null from regexp_replace6; + +create table regexp_split_to_table2 (a text, b text); +insert into regexp_split_to_table2 values('hello world', E'\\s+'), ('', E'\\s+'), ('hello world', ''), ('hello world', null); +SELECT a as p1, b as p2, regexp_split_to_table(a, b) is null from regexp_split_to_table2; + +create table substr2(a bytea, b int); +insert into substr2 values ('123'::bytea, 3), ('123'::bytea, 4); +select a as p1, b as p2, substr(a, b) is null from substr2; + +create table substr3(a bytea, b int, c int); +insert into substr3 values('123'::bytea, 1, 2), ('123'::bytea, 1, 0); +select a as p1, b as p2, c as p3, substr(a, b, c) is null from substr3; + +create table replace3 (a text, b text, c text); +insert into replace3 values ('abc', 'ab', 'd'), ('abc', 'abc', ''), ('abc', 'abc', ''), ('abc', 'ab', ''), ('abc', 'ab', null), ('abc', '', 'd'), ('abc', null, 'd'), ('', 'ab', 'd'), (null, 'ab', 'd'); +SELECT a as p1, b as p2, c as p3, replace(a, b, c) is null from replace3; + +create table replace2 (a text, b text); +insert into replace2 values('abc', 'ab'), ('abc', 'abc'), ('abc', ''), ('abc', null), ('', 'ab'), (null, 'ab'); +SELECT a as p1, b as p2, replace(a, b) is null from replace2; + +create table split_part3 (a text, b text, c int); +insert into split_part3 values('1~2~3', '~', 3), ('1~2~3~', '~', 4), ('1~2~3', '', 1), ('1~2~3', null, 1), ('', '~', 1), (null, '~', 1); +SELECT a as p1, b as p2, c as p3, split_part(a, b, c) is null from split_part3; + +create table array_to_string2(a integer[], b text); +insert into array_to_string2 values(ARRAY[1, 2, 3, NULL, 5], ','), (ARRAY[1, 2, 3, NULL, 5], ''), (ARRAY[1, 2, 3, NULL, 5], null), (ARRAY[NULL], ''), (ARRAY[NULL], null); +SELECT a as p1, b as p2, array_to_string(a, b) AS RESULT from array_to_string2; + +create table array_to_string3(a integer[], b text, c text); +insert into array_to_string3 values(ARRAY[1, 2, 3, NULL, 5], ',', '*'), (ARRAY[1, 2, 3, NULL, 5], '', ''), (ARRAY[1, 2, 3, NULL, 5], null, null), (ARRAY[NULL], '', ''), (ARRAY[NULL], null, null); +SELECT a as p1, b as p2, c as p3, array_to_string(a, b, c) AS RESULT from array_to_string3; + +set try_vector_engine_strategy=off; \ No newline at end of file diff --git a/src/test/regress/sql/not_accept_empty_str.sql b/src/test/regress/sql/not_accept_empty_str.sql new file mode 100644 index 0000000000..becb9b5fd5 --- /dev/null +++ b/src/test/regress/sql/not_accept_empty_str.sql @@ -0,0 +1,405 @@ +-- test about issue +create schema not_accept_schema; +set current_schema to 'not_accept_schema'; +create table tchar(c char(10)); +set behavior_compat_options to ''; +insert into tchar values(' '); +select * from tchar where c = ''; +select * from tchar where c = ' '; +select * from tchar where c is null; +drop table tchar; + +-- test about const str +select '' is null; +select ' ' is null; +select ' abc ' is null; +select length(''); +select length(null); +select length(' '); +select length(' abc '); +select '123'::char(3) is null; +select ''::char(3) is null; +select '123'::varchar(3) is null; +select ''::varchar(3) is null; +select '123'::text is null; +select ''::text is null; +select '123'::clob is null; +select ''::clob is null; +select '123'::blob is null; +select ''::blob is null; +select '123'::bytea is null; +select ''::bytea is null; +select '123'::int1 is null; +select ''::int1 is null; +select '123'::int2 is null; +select ''::int2 is null; +select '123'::int is null; +select ''::int is null; +select '123'::int8 is null; +select ''::int8 is null; +select '123'::float4 is null; +select ''::float4 is null; +select '123'::float8 is null; +select ''::float8 is null; +select '123'::numeric is null; +select ''::numeric is null; +select ''::date is null; +select ''::time is null; +select ''::timestamp is null; + +-- test about var str +create table result_tab ("statement" text, result text); +declare +str_empty text := ''; +str_space text := ' '; +str_num text := '123'; +str text := ' abc '; +begin + insert into result_tab select 'select str_empty is null', str_empty is null; + insert into result_tab select 'select str_space is null', str_space is null; + insert into result_tab select 'select str is null', str is null; + insert into result_tab select 'select length(str_empty)', length(str_empty); + insert into result_tab select 'select length(null)', length(null); + insert into result_tab select 'select length(str_space)', length(str_space); + insert into result_tab select 'select length(str)', length(str); + insert into result_tab select 'select str_num::text is null', str_num::text is null; + insert into result_tab select 'select str_empty::text is null', str_empty::text is null; + insert into result_tab select 'select str_num::bytea is null;', str_num::bytea is null; + insert into result_tab select 'select str_empty::bytea is null', str_empty::bytea is null; + insert into result_tab select 'select str_num::int is null', str_num::int is null; + insert into result_tab select 'select str_num::float8 is null', str_num::float8 is null; + insert into result_tab select 'select str_num::numeric is null', str_num::numeric is null; +end; +/ + +select * from result_tab; + +-- test about function which return str +SELECT overlay('hello' placing 'world' from 2 for 3 ) is null; +SELECT overlay('hello' placing '' from 1 for 5 ) is null; +SELECT quote_ident('') is null; +SELECT quote_literal('') is null; +SELECT quote_nullable('') is null; +SELECT reverse('') is null; +SELECT ''||'' is null; +SELECT ''||41; +SELECT lower('') is null; +SELECT initcap('') is null; +SELECT ascii(''); +SELECT lpad('yes', 5) is null; +SELECT lpad('yes', 1) is null; +SELECT lpad('yes', 0) is null; +SELECT lpad('yes', 5, 'z') is null; +SELECT lpad('yes', 1, 'z') is null; +SELECT lpad('yes', 0, 'z') is null; +SELECT rpad('yes', 5) is null; +SELECT rpad('yes', 1) is null; +SELECT rpad('yes', 0) is null; +SELECT rpad('yes', 5, 'z') is null; +SELECT rpad('yes', 1, 'z') is null; +SELECT rpad('yes', 0, 'z') is null; +SELECT btrim('yzy', 'y') is null; +SELECT btrim('zzz', 'z') is null; +SELECT ltrim('yzy', 'y') is null; +SELECT ltrim('zzz', 'z') is null; +SELECT rtrim('yzy', 'y') is null; +SELECT rtrim('zzz', 'z') is null; +SELECT btrim(' z ') is null; +SELECT btrim(' ') is null; +SELECT ltrim(' z ') is null; +SELECT ltrim(' ') is null; +SELECT rtrim(' z ') is null; +SELECT rtrim(' ') is null; +SELECT translate('xyx', 'x', 'z') is null; +SELECT translate('xzx', 'x', '') is null; +SELECT translate('xxx', 'x', '') is null; +SELECT translate('xxx', 'x', ' ') is null; +SELECT translate('xxx', '', 'z') is null; +SELECT translate('', 'x', 'z') is null; +SELECT repeat('a', 3) is null; +SELECT repeat('a', 0) is null; +SELECT repeat(' ', 3) is null; +SELECT repeat(' ', 0) is null; +SELECT repeat('', 3) is null; +SELECT repeat('', 0) is null; +SELECT pg_catalog.oidvectortypes('123 456') is null; +SELECT pg_catalog.oidvectortypes('') is null; +SELECT pg_catalog.oidvectortypes(' ') is null; +SELECT regexp_replace('Thomas', '.[mN]a.', 'M') is null; +SELECT regexp_replace('omas', '.[mN]a.', ''); +SELECT regexp_replace('Thomas', '', 'M') is null; +SELECT regexp_replace('', '.[mN]a.', 'M') is null; +SELECT regexp_replace('omas', '.[mN]a.', '') is null; +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n') is null; +SELECT regexp_replace('bar','b(..)', '', 1, 1, 'n') is null; +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 'g') is null; +SELECT regexp_replace('abc','abc', '', 'g') is null; +SELECT regexp_substr('str','st') is null; +SELECT regexp_substr('str','[ac]') is null; +SELECT regexp_substr('str','') is null; +SELECT regexp_substr('','st') is null; +SELECT regexp_split_to_table('hello world', E'\\s+') is null; +SELECT regexp_split_to_table('', E'\\s+') is null; +SELECT regexp_split_to_table('hello world', '') is null; +SELECT regexp_split_to_table('hello world', null) is null; +SELECT substr('123', 3) is null; +SELECT substr('123', 4) is null; +SELECT substr('123', 1, 2) is null; +SELECT substr('123', 1, 0) is null; +SELECT substr('123', 1, -1) is null; +SELECT substr('123'::bytea, 3) is null; +SELECT substr('123'::bytea, 4) is null; +SELECT substr('123'::bytea, 1, 2) is null; +SELECT substr('123'::bytea, 1, 0) is null; +SELECT substr('123'::bytea, 1, -1) is null; +SELECT substrb('123', 3) is null; +SELECT substrb('123', 4) is null; +SELECT substrb('123', 1, 2) is null; +SELECT substrb('123', 1, 0) is null; +SELECT substrb('123', 1, -1) is null; +SELECT substring('123', 3) is null; +SELECT substring('123', 4) is null; +SELECT substring('123', 1, 2) is null; +SELECT substring('123', 1, 0) is null; +SELECT substring('123', 1, -1) is null; +SELECT substring('123'::bytea, 3) is null; +SELECT substring('123'::bytea, 4) is null; +SELECT substring('123'::bytea, 1, 2) is null; +SELECT substring('123'::bytea, 1, 0) is null; +SELECT substring('123'::bytea, 1, -1) is null; +SELECT replace('abc', 'ab', 'd') is null; +SELECT replace('abc', 'abc', '') is null; +SELECT replace('abc', 'abc', null) is null; +SELECT replace('abc', 'ab', '') is null; +SELECT replace('abc', 'ab', null) is null; +SELECT replace('abc', '', 'd') is null; +SELECT replace('abc', null, 'd') is null; +SELECT replace('', 'ab', 'd') is null; +SELECT replace(null, 'ab', 'd') is null; +SELECT replace('abc', 'ab') is null; +SELECT replace('abc', 'abc') is null; +SELECT replace('abc', '') is null; +SELECT replace('abc', null) is null; +SELECT replace('', 'ab') is null; +SELECT replace(null, 'ab') is null; +SELECT split_part('1~2~3', '~', 3) is null; +SELECT split_part('1~2~3~', '~', 4) is null; +SELECT split_part('1~2~3', '~', -1) is null; +SELECT split_part('1~2~3', '', 1) is null; +SELECT split_part('1~2~3', '', 2) is null; +SELECT split_part('1~2~3', null, 1) is null; +SELECT split_part('', '~', 1) is null; +SELECT split_part(null, '~', 1) is null; +SELECT split_part('1~2~3', '|', 1) is null; +SELECT split_part('1~2~3', '|', 2) is null; +SELECT concat('Hello', ' World!') is null; +SELECT concat('', ' World!') is null; +SELECT concat('Hello', '') is null; +SELECT concat('', '') is null; +SELECT concat('Hello', null) is null; +SELECT concat(null, ' World!') is null; +SELECT concat_ws(',', 'ABCDE', 2, NULL, 22); +SELECT concat_ws('', 'ABCDE', 2, NULL, 22); +SELECT concat_ws(',', '') is null; +SELECT concat_ws('', '') is null; +SELECT left('abcde', 2) is null; +SELECT left('abcde', 0) is null; +SELECT left('abcde', -1) is null; +SELECT left('', 1) is null; +SELECT left('', 0) is null; +SELECT left('', -1) is null; +SELECT right('abcde', 2) is null; +SELECT right('abcde', 0) is null; +SELECT right('abcde', -1) is null; +SELECT right('', 1) is null; +SELECT right('', 0) is null; +SELECT right('', -1) is null; +SELECT format('Hello %s', 'World'); +SELECT format('Hello %s', ''); +SELECT format('%s', 'World'); +SELECT format('', 'World'); +SELECT format('', ''); +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null) AS RESULT; +SELECT array_to_string(ARRAY[NULL], '') AS RESULT; +SELECT array_to_string(ARRAY[NULL], null) AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '', '') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null, null) AS RESULT; +SELECT array_to_string(ARRAY[NULL], '', '') AS RESULT; +SELECT array_to_string(ARRAY[NULL], null, null) AS RESULT; +SELECT nlssort('A', 'nls_sort=schinese_pinyin_m') is null; +SELECT nlssort('', 'nls_sort=schinese_pinyin_m') is null; +SELECT nlssort('A', '') is null; +SELECT convert('text_in_utf8'::bytea, 'UTF8', 'GBK') is null; +SELECT convert(''::bytea, 'UTF8', 'GBK') is null; +SELECT convert('text_in_utf8'::bytea, '', 'GBK') is null; +SELECT convert('text_in_utf8'::bytea, 'UTF8', '') is null; +SELECT convert_from('text_in_utf8'::bytea, 'UTF8') is null; +SELECT convert_from(''::bytea, 'UTF8') is null; +SELECT convert_from('text_in_utf8'::bytea, '') is null; +SELECT convert_to('text_in_utf8'::bytea, 'UTF8') is null; +SELECT convert_to(''::bytea, 'UTF8') is null; +SELECT convert_to('text_in_utf8'::bytea, '') is null; +SELECT md5('ABC') is null; +SELECT md5('') is null; +SELECT sha('ABC') is null; +SELECT sha('') is null; +SELECT sha1('ABC') is null; +SELECT sha1('') is null; +SELECT sha2('ABC') is null; +SELECT sha2('') is null; +SELECT decode('MTIzAAE=', 'base64') is null; +SELECT decode('', 'base64') is null; +SELECT decode('MTIzAAE=', '') is null; +select similar_escape('\s+ab','2') is null; +select similar_escape('\s+ab','') is null; +select similar_escape('','2') is null; +select svals('"aa"=>"bb"') is null; +select svals('') is null; +select tconvert('aa', 'bb') is null; +select tconvert('', 'bb') is null; +select tconvert('aa', '') is null; +select tconvert('', '') is null; +SELECT encode(E'123\\000\\001', 'base64') is null; +SELECT encode('', 'base64') is null; +SELECT encode(E'123\\000\\001', '') is null; + +-- test about vec +CREATE TABLE vec_t1 +( + c varchar +) WITH (ORIENTATION = COLUMN); + +CREATE TABLE vec_t2 +( + c varchar not null +) WITH (ORIENTATION = COLUMN); + +insert into vec_t1 values(''); +insert into vec_t1 values(' '); +insert into vec_t1 values('abc'); + +insert into vec_t2 values(''); +insert into vec_t2 values(' '); +insert into vec_t2 values('abc'); + +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 1, -1) as result, result is null as is_null from vec_t1; + +delete from vec_t1; +insert into vec_t1 values(''); +insert into vec_t1 values('yzy'); +insert into vec_t1 values('zzz'); +insert into vec_t1 values(' z '); +insert into vec_t1 values(' '); + +SELECT c as input, btrim(c, 'y') as result, result is null as isnull from vec_t1; +SELECT c as input, btrim(c, 'z') as result, result is null as isnull from vec_t1; +SELECT c as input, btrim(c) as result, result is null as isnull from vec_t1; +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t1; +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t1; +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t1; + +-- test row to vec +set try_vector_engine_strategy=force; +create table vec_t3(c text); +insert into vec_t3 values(''); +insert into vec_t3 values(' '); +insert into vec_t3 values('abc'); + +explain analyze select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t3; + +delete from vec_t3; +insert into vec_t3 values(''); +insert into vec_t3 values('yzy'); +insert into vec_t3 values('zzz'); +insert into vec_t3 values(' z '); +insert into vec_t3 values(' '); + +explain analyze SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t3; +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t3; + +create table pad2_tab(a text, b int); +insert into pad2_tab values('yes', 5), ('yes', 1), ('yes', 0); +create table pad3_tab(a text, b int, c text); +insert into pad3_tab values('yes', 5, 'z'), ('yes', 1, 'z'), ('yes', 0, 'z'); +SELECT a as p1, b as p2, lpad(a, b) is null from pad2_tab; +SELECT a as p1, b as p2, lpad(a, b, c) is null from pad3_tab; +SELECT a as p1, b as p2, rpad(a, b) is null from pad2_tab; +SELECT a as p1, b as p2, rpad(a, b, c) is null from pad3_tab; + +create table trim2(a text, b text); +insert into trim2 values('yzy', 'y'), ('zzz', 'z'); +create table trim1(a text); +insert into trim1 values(' z '), (' '); +SELECT a as p1, b as p2, btrim(a, b) is null from trim2; +SELECT a as p1, b as p2, ltrim(a, b) is null from trim2; +SELECT a as p1, b as p2, rtrim(a, b) is null from trim2; +SELECT a as p1, btrim(a) is null from trim1; +SELECT a as p1, ltrim(a) is null from trim1; +SELECT a as p1, rtrim(a) is null from trim1; + +create table translate3(a text, b text, c text); +insert into translate3 values('xyx', 'x', 'z'), ('xzx', 'x', ''), ('xxx', 'x', ''), ('xxx', 'x', ' '), ('xxx', '', 'z'), ('', 'x', 'z'); +SELECT a as p1, b as p2, c as p3, translate(a, b, c) is null from translate3; + +create table repeat2 (a text, b int); +insert into repeat2 values('a', 3), ('a', 0), (' ', 3), ('', 3), ('', 0); +SELECT a as p1, b as p2, repeat(a, b) is null from repeat2; + +create table oidvectortypes1 (a oidvector); +insert into oidvectortypes1 values ('123 456'), (''), (' '); +SELECT a as p1, oidvectortypes(a) is null from oidvectortypes1; + +create table regexp_replace3 (a text, b text, c text); +insert into regexp_replace3 values('Thomas', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''), ('Thomas', '', 'M'), ('', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''); +SELECT a as p1, b as p2, c as p3, regexp_replace(a, b, c) is null from regexp_replace3; + +create table regexp_replace6 (a text, b text, c text, d int, e int, f text); +insert into regexp_replace6 values ('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n'), ('bar','b(..)', '', 1, 1, 'n'); +SELECT a as p1, b as p2, c as p3, d as p4, e as p5, f as p6, regexp_replace(a, b, c, d, e, f) is null from regexp_replace6; + +create table regexp_split_to_table2 (a text, b text); +insert into regexp_split_to_table2 values('hello world', E'\\s+'), ('', E'\\s+'), ('hello world', ''), ('hello world', null); +SELECT a as p1, b as p2, regexp_split_to_table(a, b) is null from regexp_split_to_table2; + +create table substr2(a bytea, b int); +insert into substr2 values ('123'::bytea, 3), ('123'::bytea, 4); +select a as p1, b as p2, substr(a, b) is null from substr2; + +create table substr3(a bytea, b int, c int); +insert into substr3 values('123'::bytea, 1, 2), ('123'::bytea, 1, 0); +select a as p1, b as p2, c as p3, substr(a, b, c) is null from substr3; + +create table replace3 (a text, b text, c text); +insert into replace3 values ('abc', 'ab', 'd'), ('abc', 'abc', ''), ('abc', 'abc', ''), ('abc', 'ab', ''), ('abc', 'ab', null), ('abc', '', 'd'), ('abc', null, 'd'), ('', 'ab', 'd'), (null, 'ab', 'd'); +SELECT a as p1, b as p2, c as p3, replace(a, b, c) is null from replace3; + +create table replace2 (a text, b text); +insert into replace2 values('abc', 'ab'), ('abc', 'abc'), ('abc', ''), ('abc', null), ('', 'ab'), (null, 'ab'); +SELECT a as p1, b as p2, replace(a, b) is null from replace2; + +create table split_part3 (a text, b text, c int); +insert into split_part3 values('1~2~3', '~', 3), ('1~2~3~', '~', 4), ('1~2~3', '', 1), ('1~2~3', null, 1), ('', '~', 1), (null, '~', 1); +SELECT a as p1, b as p2, c as p3, split_part(a, b, c) is null from split_part3; + +create table array_to_string2(a integer[], b text); +insert into array_to_string2 values(ARRAY[1, 2, 3, NULL, 5], ','), (ARRAY[1, 2, 3, NULL, 5], ''), (ARRAY[1, 2, 3, NULL, 5], null), (ARRAY[NULL], ''), (ARRAY[NULL], null); +SELECT a as p1, b as p2, array_to_string(a, b) AS RESULT from array_to_string2; + +create table array_to_string3(a integer[], b text, c text); +insert into array_to_string3 values(ARRAY[1, 2, 3, NULL, 5], ',', '*'), (ARRAY[1, 2, 3, NULL, 5], '', ''), (ARRAY[1, 2, 3, NULL, 5], null, null), (ARRAY[NULL], '', ''), (ARRAY[NULL], null, null); +SELECT a as p1, b as p2, c as p3, array_to_string(a, b, c) AS RESULT from array_to_string3; + +set try_vector_engine_strategy=off; \ No newline at end of file diff --git a/src/test/regress/sql/pg_empty_str.sql b/src/test/regress/sql/pg_empty_str.sql new file mode 100644 index 0000000000..24f4bdea5c --- /dev/null +++ b/src/test/regress/sql/pg_empty_str.sql @@ -0,0 +1,407 @@ +-- test about issue +create database test_pg dbcompatibility 'PG'; +\c test_pg +create schema accept_schema; +set current_schema to 'accept_schema'; +create table tchar(c char(10)); +set behavior_compat_options to 'accept_empty_str'; +insert into tchar values(' '); +select * from tchar where c = ''; +select * from tchar where c = ' '; +select * from tchar where c is null; +drop table tchar; + +-- test about const str +select '' is null; +select ' ' is null; +select ' abc ' is null; +select length(''); +select length(null); +select length(' '); +select length(' abc '); +select '123'::char(3) is null; +select ''::char(3) is null; +select '123'::varchar(3) is null; +select ''::varchar(3) is null; +select '123'::text is null; +select ''::text is null; +select '123'::clob is null; +select ''::clob is null; +select '123'::blob is null; +select ''::blob is null; +select '123'::bytea is null; +select ''::bytea is null; +select '123'::int1 is null; +select ''::int1 is null; +select '123'::int2 is null; +select ''::int2 is null; +select '123'::int is null; +select ''::int is null; +select '123'::int8 is null; +select ''::int8 is null; +select '123'::float4 is null; +select ''::float4 is null; +select '123'::float8 is null; +select ''::float8 is null; +select '123'::numeric is null; +select ''::numeric is null; +select ''::date is null; +select ''::time is null; +select ''::timestamp is null; + +-- test about var str +create table result_tab ("statement" text, result text); +declare +str_empty text := ''; +str_space text := ' '; +str_num text := '123'; +str text := ' abc '; +begin + insert into result_tab select 'select str_empty is null', str_empty is null; + insert into result_tab select 'select str_space is null', str_space is null; + insert into result_tab select 'select str is null', str is null; + insert into result_tab select 'select length(str_empty)', length(str_empty); + insert into result_tab select 'select length(null)', length(null); + insert into result_tab select 'select length(str_space)', length(str_space); + insert into result_tab select 'select length(str)', length(str); + insert into result_tab select 'select str_num::text is null', str_num::text is null; + insert into result_tab select 'select str_empty::text is null', str_empty::text is null; + insert into result_tab select 'select str_num::bytea is null;', str_num::bytea is null; + insert into result_tab select 'select str_empty::bytea is null', str_empty::bytea is null; + insert into result_tab select 'select str_num::int is null', str_num::int is null; + insert into result_tab select 'select str_num::float8 is null', str_num::float8 is null; + insert into result_tab select 'select str_num::numeric is null', str_num::numeric is null; +end; +/ + +select * from result_tab; + +-- test about function which return str +SELECT overlay('hello' placing 'world' from 2 for 3 ) is null; +SELECT overlay('hello' placing '' from 1 for 5 ) is null; +SELECT quote_ident('') is null; +SELECT quote_literal('') is null; +SELECT quote_nullable('') is null; +SELECT reverse('') is null; +SELECT ''||'' is null; +SELECT ''||41; +SELECT lower('') is null; +SELECT initcap('') is null; +SELECT ascii(''); +SELECT lpad('yes', 5) is null; +SELECT lpad('yes', 1) is null; +SELECT lpad('yes', 0) is null; +SELECT lpad('yes', 5, 'z') is null; +SELECT lpad('yes', 1, 'z') is null; +SELECT lpad('yes', 0, 'z') is null; +SELECT rpad('yes', 5) is null; +SELECT rpad('yes', 1) is null; +SELECT rpad('yes', 0) is null; +SELECT rpad('yes', 5, 'z') is null; +SELECT rpad('yes', 1, 'z') is null; +SELECT rpad('yes', 0, 'z') is null; +SELECT btrim('yzy', 'y') is null; +SELECT btrim('zzz', 'z') is null; +SELECT ltrim('yzy', 'y') is null; +SELECT ltrim('zzz', 'z') is null; +SELECT rtrim('yzy', 'y') is null; +SELECT rtrim('zzz', 'z') is null; +SELECT btrim(' z ') is null; +SELECT btrim(' ') is null; +SELECT ltrim(' z ') is null; +SELECT ltrim(' ') is null; +SELECT rtrim(' z ') is null; +SELECT rtrim(' ') is null; +SELECT translate('xyx', 'x', 'z') is null; +SELECT translate('xzx', 'x', '') is null; +SELECT translate('xxx', 'x', '') is null; +SELECT translate('xxx', 'x', ' ') is null; +SELECT translate('xxx', '', 'z') is null; +SELECT translate('', 'x', 'z') is null; +SELECT repeat('a', 3) is null; +SELECT repeat('a', 0) is null; +SELECT repeat(' ', 3) is null; +SELECT repeat(' ', 0) is null; +SELECT repeat('', 3) is null; +SELECT repeat('', 0) is null; +SELECT pg_catalog.oidvectortypes('123 456') is null; +SELECT pg_catalog.oidvectortypes('') is null; +SELECT pg_catalog.oidvectortypes(' ') is null; +SELECT regexp_replace('Thomas', '.[mN]a.', 'M') is null; +SELECT regexp_replace('omas', '.[mN]a.', ''); +SELECT regexp_replace('Thomas', '', 'M') is null; +SELECT regexp_replace('', '.[mN]a.', 'M') is null; +SELECT regexp_replace('omas', '.[mN]a.', '') is null; +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n') is null; +SELECT regexp_replace('bar','b(..)', '', 1, 1, 'n') is null; +SELECT regexp_replace('foobarbaz','b(..)', E'X\\1Y', 'g') is null; +SELECT regexp_replace('abc','abc', '', 'g') is null; +SELECT regexp_substr('str','st') is null; +SELECT regexp_substr('str','[ac]') is null; +SELECT regexp_substr('str','') is null; +SELECT regexp_substr('','st') is null; +SELECT regexp_split_to_table('hello world', E'\\s+') is null; +SELECT regexp_split_to_table('', E'\\s+') is null; +SELECT regexp_split_to_table('hello world', '') is null; +SELECT regexp_split_to_table('hello world', null) is null; +SELECT substr('123', 3) is null; +SELECT substr('123', 4) is null; +SELECT substr('123', 1, 2) is null; +SELECT substr('123', 1, 0) is null; +SELECT substr('123', 1, -1) is null; +SELECT substr('123'::bytea, 3) is null; +SELECT substr('123'::bytea, 4) is null; +SELECT substr('123'::bytea, 1, 2) is null; +SELECT substr('123'::bytea, 1, 0) is null; +SELECT substr('123'::bytea, 1, -1) is null; +SELECT substrb('123', 3) is null; +SELECT substrb('123', 4) is null; +SELECT substrb('123', 1, 2) is null; +SELECT substrb('123', 1, 0) is null; +SELECT substrb('123', 1, -1) is null; +SELECT substring('123', 3) is null; +SELECT substring('123', 4) is null; +SELECT substring('123', 1, 2) is null; +SELECT substring('123', 1, 0) is null; +SELECT substring('123', 1, -1) is null; +SELECT substring('123'::bytea, 3) is null; +SELECT substring('123'::bytea, 4) is null; +SELECT substring('123'::bytea, 1, 2) is null; +SELECT substring('123'::bytea, 1, 0) is null; +SELECT substring('123'::bytea, 1, -1) is null; +SELECT replace('abc', 'ab', 'd') is null; +SELECT replace('abc', 'abc', '') is null; +SELECT replace('abc', 'abc', null) is null; +SELECT replace('abc', 'ab', '') is null; +SELECT replace('abc', 'ab', null) is null; +SELECT replace('abc', '', 'd') is null; +SELECT replace('abc', null, 'd') is null; +SELECT replace('', 'ab', 'd') is null; +SELECT replace(null, 'ab', 'd') is null; +SELECT replace('abc', 'ab') is null; +SELECT replace('abc', 'abc') is null; +SELECT replace('abc', '') is null; +SELECT replace('abc', null) is null; +SELECT replace('', 'ab') is null; +SELECT replace(null, 'ab') is null; +SELECT split_part('1~2~3', '~', 3) is null; +SELECT split_part('1~2~3~', '~', 4) is null; +SELECT split_part('1~2~3', '~', -1) is null; +SELECT split_part('1~2~3', '', 1) is null; +SELECT split_part('1~2~3', '', 2) is null; +SELECT split_part('1~2~3', null, 1) is null; +SELECT split_part('', '~', 1) is null; +SELECT split_part(null, '~', 1) is null; +SELECT split_part('1~2~3', '|', 1) is null; +SELECT split_part('1~2~3', '|', 2) is null; +SELECT concat('Hello', ' World!') is null; +SELECT concat('', ' World!') is null; +SELECT concat('Hello', '') is null; +SELECT concat('', '') is null; +SELECT concat('Hello', null) is null; +SELECT concat(null, ' World!') is null; +SELECT concat_ws(',', 'ABCDE', 2, NULL, 22); +SELECT concat_ws('', 'ABCDE', 2, NULL, 22); +SELECT concat_ws(',', '') is null; +SELECT concat_ws('', '') is null; +SELECT left('abcde', 2) is null; +SELECT left('abcde', 0) is null; +SELECT left('abcde', -1) is null; +SELECT left('', 1) is null; +SELECT left('', 0) is null; +SELECT left('', -1) is null; +SELECT right('abcde', 2) is null; +SELECT right('abcde', 0) is null; +SELECT right('abcde', -1) is null; +SELECT right('', 1) is null; +SELECT right('', 0) is null; +SELECT right('', -1) is null; +SELECT format('Hello %s', 'World'); +SELECT format('Hello %s', ''); +SELECT format('%s', 'World'); +SELECT format('', 'World'); +SELECT format('', ''); +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null) AS RESULT; +SELECT array_to_string(ARRAY[NULL], '') AS RESULT; +SELECT array_to_string(ARRAY[NULL], null) AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], '', '') AS RESULT; +SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], null, null) AS RESULT; +SELECT array_to_string(ARRAY[NULL], '', '') AS RESULT; +SELECT array_to_string(ARRAY[NULL], null, null) AS RESULT; +SELECT nlssort('A', 'nls_sort=schinese_pinyin_m') is null; +SELECT nlssort('', 'nls_sort=schinese_pinyin_m') is null; +SELECT nlssort('A', '') is null; +SELECT convert('text_in_utf8'::bytea, 'UTF8', 'GBK') is null; +SELECT convert(''::bytea, 'UTF8', 'GBK') is null; +SELECT convert('text_in_utf8'::bytea, '', 'GBK') is null; +SELECT convert('text_in_utf8'::bytea, 'UTF8', '') is null; +SELECT convert_from('text_in_utf8'::bytea, 'UTF8') is null; +SELECT convert_from(''::bytea, 'UTF8') is null; +SELECT convert_from('text_in_utf8'::bytea, '') is null; +SELECT convert_to('text_in_utf8'::bytea, 'UTF8') is null; +SELECT convert_to(''::bytea, 'UTF8') is null; +SELECT convert_to('text_in_utf8'::bytea, '') is null; +SELECT md5('ABC') is null; +SELECT md5('') is null; +SELECT sha('ABC') is null; +SELECT sha('') is null; +SELECT sha1('ABC') is null; +SELECT sha1('') is null; +SELECT sha2('ABC') is null; +SELECT sha2('') is null; +SELECT decode('MTIzAAE=', 'base64') is null; +SELECT decode('', 'base64') is null; +SELECT decode('MTIzAAE=', '') is null; +select similar_escape('\s+ab','2') is null; +select similar_escape('\s+ab','') is null; +select similar_escape('','2') is null; +select svals('"aa"=>"bb"') is null; +select svals('') is null; +select tconvert('aa', 'bb') is null; +select tconvert('', 'bb') is null; +select tconvert('aa', '') is null; +select tconvert('', '') is null; +SELECT encode(E'123\\000\\001', 'base64') is null; +SELECT encode('', 'base64') is null; +SELECT encode(E'123\\000\\001', '') is null; + +-- test about vec +CREATE TABLE vec_t1 +( + c varchar +) WITH (ORIENTATION = COLUMN); + +CREATE TABLE vec_t2 +( + c varchar not null +) WITH (ORIENTATION = COLUMN); + +insert into vec_t1 values(''); +insert into vec_t1 values(' '); +insert into vec_t1 values('abc'); + +insert into vec_t2 values(''); +insert into vec_t2 values(' '); +insert into vec_t2 values('abc'); + +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t1; +select c as input, substr(c, 1, -1) as result, result is null as is_null from vec_t1; + +delete from vec_t1; +insert into vec_t1 values(''); +insert into vec_t1 values('yzy'); +insert into vec_t1 values('zzz'); +insert into vec_t1 values(' z '); +insert into vec_t1 values(' '); + +SELECT c as input, btrim(c, 'y') as result, result is null as isnull from vec_t1; +SELECT c as input, btrim(c, 'z') as result, result is null as isnull from vec_t1; +SELECT c as input, btrim(c) as result, result is null as isnull from vec_t1; +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t1; +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t1; +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t1; + +-- test row to vec +set try_vector_engine_strategy=force; +create table vec_t3(c text); +insert into vec_t3 values(''); +insert into vec_t3 values(' '); +insert into vec_t3 values('abc'); + +explain analyze select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 1, 2) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 1, 1) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 0, 2) as result, result is null as is_null from vec_t3; +select c as input, substr(c, 1, 0) as result, result is null as is_null from vec_t3; + +delete from vec_t3; +insert into vec_t3 values(''); +insert into vec_t3 values('yzy'); +insert into vec_t3 values('zzz'); +insert into vec_t3 values(' z '); +insert into vec_t3 values(' '); + +explain analyze SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; +SELECT c as input, rtrim(c, 'y') as result, result is null as isnull from vec_t3; +SELECT c as input, rtrim(c, 'z') as result, result is null as isnull from vec_t3; +SELECT c as input, rtrim(c) as result, result is null as isnull from vec_t3; + +create table pad2_tab(a text, b int); +insert into pad2_tab values('yes', 5), ('yes', 1), ('yes', 0); +create table pad3_tab(a text, b int, c text); +insert into pad3_tab values('yes', 5, 'z'), ('yes', 1, 'z'), ('yes', 0, 'z'); +SELECT a as p1, b as p2, lpad(a, b) is null from pad2_tab; +SELECT a as p1, b as p2, lpad(a, b, c) is null from pad3_tab; +SELECT a as p1, b as p2, rpad(a, b) is null from pad2_tab; +SELECT a as p1, b as p2, rpad(a, b, c) is null from pad3_tab; + +create table trim2(a text, b text); +insert into trim2 values('yzy', 'y'), ('zzz', 'z'); +create table trim1(a text); +insert into trim1 values(' z '), (' '); +SELECT a as p1, b as p2, btrim(a, b) is null from trim2; +SELECT a as p1, b as p2, ltrim(a, b) is null from trim2; +SELECT a as p1, b as p2, rtrim(a, b) is null from trim2; +SELECT a as p1, btrim(a) is null from trim1; +SELECT a as p1, ltrim(a) is null from trim1; +SELECT a as p1, rtrim(a) is null from trim1; + +create table translate3(a text, b text, c text); +insert into translate3 values('xyx', 'x', 'z'), ('xzx', 'x', ''), ('xxx', 'x', ''), ('xxx', 'x', ' '), ('xxx', '', 'z'), ('', 'x', 'z'); +SELECT a as p1, b as p2, c as p3, translate(a, b, c) is null from translate3; + +create table repeat2 (a text, b int); +insert into repeat2 values('a', 3), ('a', 0), (' ', 3), ('', 3), ('', 0); +SELECT a as p1, b as p2, repeat(a, b) is null from repeat2; + +create table oidvectortypes1 (a oidvector); +insert into oidvectortypes1 values ('123 456'), (''), (' '); +SELECT a as p1, oidvectortypes(a) is null from oidvectortypes1; + +create table regexp_replace3 (a text, b text, c text); +insert into regexp_replace3 values('Thomas', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''), ('Thomas', '', 'M'), ('', '.[mN]a.', 'M'), ('omas', '.[mN]a.', ''); +SELECT a as p1, b as p2, c as p3, regexp_replace(a, b, c) is null from regexp_replace3; + +create table regexp_replace6 (a text, b text, c text, d int, e int, f text); +insert into regexp_replace6 values ('foobarbaz','b(..)', E'X\\1Y', 2, 2, 'n'), ('bar','b(..)', '', 1, 1, 'n'); +SELECT a as p1, b as p2, c as p3, d as p4, e as p5, f as p6, regexp_replace(a, b, c, d, e, f) is null from regexp_replace6; + +create table regexp_split_to_table2 (a text, b text); +insert into regexp_split_to_table2 values('hello world', E'\\s+'), ('', E'\\s+'), ('hello world', ''), ('hello world', null); +SELECT a as p1, b as p2, regexp_split_to_table(a, b) is null from regexp_split_to_table2; + +create table substr2(a bytea, b int); +insert into substr2 values ('123'::bytea, 3), ('123'::bytea, 4); +select a as p1, b as p2, substr(a, b) is null from substr2; + +create table substr3(a bytea, b int, c int); +insert into substr3 values('123'::bytea, 1, 2), ('123'::bytea, 1, 0); +select a as p1, b as p2, c as p3, substr(a, b, c) is null from substr3; + +create table replace3 (a text, b text, c text); +insert into replace3 values ('abc', 'ab', 'd'), ('abc', 'abc', ''), ('abc', 'abc', ''), ('abc', 'ab', ''), ('abc', 'ab', null), ('abc', '', 'd'), ('abc', null, 'd'), ('', 'ab', 'd'), (null, 'ab', 'd'); +SELECT a as p1, b as p2, c as p3, replace(a, b, c) is null from replace3; + +create table replace2 (a text, b text); +insert into replace2 values('abc', 'ab'), ('abc', 'abc'), ('abc', ''), ('abc', null), ('', 'ab'), (null, 'ab'); +SELECT a as p1, b as p2, replace(a, b) is null from replace2; + +create table split_part3 (a text, b text, c int); +insert into split_part3 values('1~2~3', '~', 3), ('1~2~3~', '~', 4), ('1~2~3', '', 1), ('1~2~3', null, 1), ('', '~', 1), (null, '~', 1); +SELECT a as p1, b as p2, c as p3, split_part(a, b, c) is null from split_part3; + +create table array_to_string2(a integer[], b text); +insert into array_to_string2 values(ARRAY[1, 2, 3, NULL, 5], ','), (ARRAY[1, 2, 3, NULL, 5], ''), (ARRAY[1, 2, 3, NULL, 5], null), (ARRAY[NULL], ''), (ARRAY[NULL], null); +SELECT a as p1, b as p2, array_to_string(a, b) AS RESULT from array_to_string2; + +create table array_to_string3(a integer[], b text, c text); +insert into array_to_string3 values(ARRAY[1, 2, 3, NULL, 5], ',', '*'), (ARRAY[1, 2, 3, NULL, 5], '', ''), (ARRAY[1, 2, 3, NULL, 5], null, null), (ARRAY[NULL], '', ''), (ARRAY[NULL], null, null); +SELECT a as p1, b as p2, c as p3, array_to_string(a, b, c) AS RESULT from array_to_string3; + +set try_vector_engine_strategy=off; \ No newline at end of file -- Gitee