Added/augmented functions: decode/regexp_count/regexp_instr/regexp_replace/regexp_subst

This commit is contained in:
dengxuyue
2022-07-09 15:02:16 +08:00
committed by dengxuyue
parent f65486ba95
commit a038ba49eb
22 changed files with 8047 additions and 91 deletions

View File

@ -9708,15 +9708,33 @@
"regexnesel", 1,
AddBuiltinFunc(_0(1821), _1("regexnesel"), _2(4), _3(true), _4(false), _5(regexnesel), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(4, 2281, 26, 2281, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexnesel"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("restriction selectivity of regex non-match"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
),
AddFuncGroup(
"regexp_count", 3,
AddBuiltinFunc(_0(385), _1("regexp_count"), _2(2), _3(true), _4(false), _5(regexp_count_noopt), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_count_noopt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("find match(es) count for regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(386), _1("regexp_count"), _2(3), _3(false), _4(false), _5(regexp_count_position), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 25, 25, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_count_position"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("find match(es) count for regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(387), _1("regexp_count"), _2(4), _3(false), _4(false), _5(regexp_count_matchopt), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(4, 25, 25, 23, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_count_matchopt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("find match(es) count for regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
),
AddFuncGroup(
"regexp_instr", 5,
AddBuiltinFunc(_0(630), _1("regexp_instr"), _2(2), _3(true), _4(false), _5(regexp_instr_noopt), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_instr_noopt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("find match(es) position for regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(631), _1("regexp_instr"), _2(3), _3(false), _4(false), _5(regexp_instr_position), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 25, 25, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_instr_position"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("find match(es) position for regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(632), _1("regexp_instr"), _2(4), _3(false), _4(false), _5(regexp_instr_occurren), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(4, 25, 25, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_instr_occurren"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("find match(es) position for regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(633), _1("regexp_instr"), _2(5), _3(false), _4(false), _5(regexp_instr_returnopt), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(5, 25, 25, 23, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_instr_returnopt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("find match(es) position for regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(634), _1("regexp_instr"), _2(6), _3(false), _4(false), _5(regexp_instr_matchopt), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(6, 25, 25, 23, 23, 23, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_instr_matchopt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("find match(es) position for regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
),
AddFuncGroup(
"regexp_matches", 2,
AddBuiltinFunc(_0(2763), _1("regexp_matches"), _2(2), _3(true), _4(true), _5(regexp_matches_no_flags), _6(1009), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(1), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_matches_no_flags"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("find match(es) for regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(2764), _1("regexp_matches"), _2(3), _3(true), _4(true), _5(regexp_matches), _6(1009), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(10), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 25, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_matches"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("find match(es) for regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
),
AddFuncGroup(
"regexp_replace", 2,
"regexp_replace", 6,
AddBuiltinFunc(_0(1116), _1("regexp_replace"), _2(2), _3(false), _4(false), _5(regexp_replace_noopt), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_replace_noopt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("replace text using regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(2284), _1("regexp_replace"), _2(3), _3(false), _4(false), _5(textregexreplace_noopt), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 25, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("textregexreplace_noopt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("replace text using regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(2285), _1("regexp_replace"), _2(4), _3(false), _4(false), _5(textregexreplace), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(4, 25, 25, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("textregexreplace"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("replace text using regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
AddBuiltinFunc(_0(2285), _1("regexp_replace"), _2(4), _3(false), _4(false), _5(textregexreplace), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(4, 25, 25, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("textregexreplace"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("replace text using regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(1117), _1("regexp_replace"), _2(4), _3(false), _4(false), _5(regexp_replace_position), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(4, 25, 25, 25, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_replace_position"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("replace text using regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(1118), _1("regexp_replace"), _2(5), _3(false), _4(false), _5(regexp_replace_occur), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(5, 25, 25, 25, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_replace_occur"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("replace text using regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(1119), _1("regexp_replace"), _2(6), _3(false), _4(false), _5(regexp_replace_matchopt), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(6, 25, 25, 25, 23, 23, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_replace_matchopt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("replace text using regexp"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
),
AddFuncGroup(
"regexp_split_to_array", 2,
@ -9728,6 +9746,12 @@
AddBuiltinFunc(_0(2765), _1("regexp_split_to_table"), _2(2), _3(true), _4(true), _5(regexp_split_to_table_no_flags), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(1000), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_split_to_table_no_flags"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("split string by pattern"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(2766), _1("regexp_split_to_table"), _2(3), _3(true), _4(true), _5(regexp_split_to_table), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(1000), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 25, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_split_to_table"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("split string by pattern"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
),
AddFuncGroup(
"regexp_substr", 3,
AddBuiltinFunc(_0(1566), _1("regexp_substr"), _2(3), _3(false), _4(false), _5(regexp_substr_with_position), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 25, 25, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_substr_with_position"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("extract text matching regular expression"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(1567), _1("regexp_substr"), _2(4), _3(false), _4(false), _5(regexp_substr_with_occur), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(4, 25, 25, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_substr_with_occur"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("extract text matching regular expression"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)),
AddBuiltinFunc(_0(1568), _1("regexp_substr"), _2(5), _3(false), _4(false), _5(regexp_substr_with_opt), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(5, 25, 25, 23, 23, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regexp_substr_with_opt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("extract text matching regular expression"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
),
AddFuncGroup(
"regoperatorin", 1,
AddBuiltinFunc(_0(2216), _1("regoperatorin"), _2(1), _3(true), _4(false), _5(regoperatorin), _6(2204), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2275), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("regoperatorin"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))

View File

@ -44,9 +44,18 @@ static Node* coerce_record_to_complex(
ParseState* pstate, Node* node, Oid targetTypeId, CoercionContext ccontext, CoercionForm cformat, int location);
static bool is_complex_array(Oid typid);
static bool typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId);
static Oid choose_decode_result1_type(ParseState* pstate, List* exprs, const char* context);
static void handle_diff_category(ParseState* pstate, Node* nextExpr, const char* context,
TYPCATEGORY preferCategory, TYPCATEGORY nextCategory, Oid preferType, Oid nextType);
static bool category_can_be_matched(TYPCATEGORY preferCategory, TYPCATEGORY nextCategory);
static bool type_can_be_matched(Oid preferType, Oid nextType);
static Oid choose_specific_expr_type(ParseState* pstate, List* exprs, const char* context);
static Oid choose_nvl_type(ParseState* pstate, List* exprs, const char* context);
static Oid choose_expr_type(ParseState* pstate, List* exprs, const char* context, Node** which_expr);
static bool check_category_in_whitelist(TYPCATEGORY category, Oid type);
static bool check_numeric_type_in_blacklist(Oid type);
static bool meet_decode_compatibility(List* exprs, const char* context);
static bool meet_c_format_compatibility(List* exprs, const char* context);
/*
* @Description: same as get_element_type() except this reports error
@ -1063,6 +1072,138 @@ int parser_coercion_errposition(ParseState* pstate, int coerce_location, Node* i
}
}
/* choose_decode_result1_type
* Choose case when and decode return value type in A_FORMAT.
*/
static Oid choose_decode_result1_type(ParseState* pstate, List* exprs, const char* context)
{
Node* preferExpr = NULL;
Oid preferType = UNKNOWNOID;
TYPCATEGORY preferCategory = TYPCATEGORY_UNKNOWN;
ListCell* lc = NULL;
/* result1 is the first expr, treat result1 type (or category) as return value type */
foreach (lc, exprs) {
preferExpr = (Node*)lfirst(lc);
/* if first expr is "null", treat it as unknown type */
if (IsA(preferExpr, Const) && ((Const*)preferExpr)->constisnull) {
break;
}
preferType = getBaseType(exprType(preferExpr));
preferCategory = get_typecategory(preferType);
break;
}
if (lc == NULL) {
return preferType;
}
lc = lnext(lc);
for_each_cell(lc, lc)
{
Node* nextExpr = (Node*)lfirst(lc);
Oid nextType = getBaseType(exprType(nextExpr));
/* skip "null" */
if (IsA(nextExpr, Const) && ((Const*)nextExpr)->constisnull) {
continue;
}
/* no need to check if nextType the same as preferType */
if (nextType != preferType) {
TYPCATEGORY nextCategory = get_typecategory(nextType);
/*
* Both types in different categories, we check if nextCategory/nextType can be implicitly
* converted to preferCategory/preferType. Here we will treat unknow type as text type.
*/
if (nextCategory != preferCategory) {
handle_diff_category(pstate, nextExpr, context, preferCategory, nextCategory, preferType, nextType);
}
/* both types is same categories, we choose a priority higher. */
else if (GetPriority(preferType) < GetPriority(nextType)) {
preferType = nextType;
}
}
}
/*
* If preferCategory is TYPCATEGORY_NUMERIC, choose NUMERICOID as preferType.
* To compatible with a string representing a large number needs to be converted to a number type.
* e.g., "select decode(1, 2, 2, '63274723794832454677432493248593478549543535453'::text);"
*/
if (preferCategory == TYPCATEGORY_NUMERIC) {
preferType = NUMERICOID;
}
return preferType;
}
/*
* Handle the case where nextCategory and preferCategory are different.
* Check whether nextCategory can be converted to preferCategory,
* or nextType can be converted to preferType.
*/
static void handle_diff_category(ParseState* pstate, Node* nextExpr, const char* context,
TYPCATEGORY preferCategory, TYPCATEGORY nextCategory, Oid preferType, Oid nextType)
{
if (!category_can_be_matched(preferCategory, nextCategory) &&
!type_can_be_matched(preferType, nextType)) {
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("%s types %s and %s cannot be matched",
context,
format_type_be(preferType == UNKNOWNOID ? TEXTOID : preferType),
format_type_be(nextType == UNKNOWNOID ? TEXTOID : nextType)),
parser_errposition(pstate, exprLocation(nextExpr))));
}
}
/*
* Check whether nextCategory can be converted to preferCategory.
*/
static bool category_can_be_matched(TYPCATEGORY preferCategory, TYPCATEGORY nextCategory)
{
bool can_be_matched = false;
static TYPCATEGORY categoryMatchedList[][2] = {
{TYPCATEGORY_STRING, TYPCATEGORY_UNKNOWN}, {TYPCATEGORY_STRING, TYPCATEGORY_NUMERIC},
{TYPCATEGORY_UNKNOWN, TYPCATEGORY_STRING}, {TYPCATEGORY_UNKNOWN, TYPCATEGORY_NUMERIC},
{TYPCATEGORY_NUMERIC, TYPCATEGORY_STRING}, {TYPCATEGORY_NUMERIC, TYPCATEGORY_UNKNOWN},
{TYPCATEGORY_STRING, TYPCATEGORY_DATETIME}, {TYPCATEGORY_STRING, TYPCATEGORY_TIMESPAN},
{TYPCATEGORY_UNKNOWN, TYPCATEGORY_DATETIME}, {TYPCATEGORY_UNKNOWN, TYPCATEGORY_TIMESPAN}};
for (unsigned int i = 0; i < sizeof(categoryMatchedList) / sizeof(categoryMatchedList[0]); i++) {
if (preferCategory == categoryMatchedList[i][0] && nextCategory == categoryMatchedList[i][1]) {
can_be_matched = true;
break;
}
}
return can_be_matched;
}
/*
* Check whether nextType can be converted to preferType.
*/
static bool type_can_be_matched(Oid preferType, Oid nextType)
{
bool can_be_matched = false;
static Oid typeMatchedList[][2] = {
{RAWOID, VARCHAROID}, {RAWOID, TEXTOID}, {VARCHAROID, RAWOID}, {TEXTOID, RAWOID}};
for (unsigned int i = 0; i < sizeof(typeMatchedList) / sizeof(typeMatchedList[0]); i++) {
if (preferType == typeMatchedList[i][0] && nextType == typeMatchedList[i][1]) {
can_be_matched = true;
break;
}
}
return can_be_matched;
}
/* choose_specific_expr_type
* Choose case when and coalesce return value type in C_FORMAT.
*/
@ -1292,6 +1433,86 @@ static Oid choose_expr_type(ParseState* pstate, List* exprs, const char* context
return ptype;
}
/*
* To maintain forward compatibility, decode type conversion rules compatible with O is
* only valid for a few specific type categories. Save these type categories in the form
* of a whitelist. If any one is not in the whitelist, allInWhitelist is set to false.
*/
bool check_all_in_whitelist(List* resultexprs)
{
bool allInWhitelist = true;
Node* exprTmp = NULL;
ListCell* lc = NULL;
Oid exprTypeTmp = UNKNOWNOID;
TYPCATEGORY exprCategoryTmp = TYPCATEGORY_UNKNOWN;
foreach (lc, resultexprs) {
exprTmp = (Node*)lfirst(lc);
/* if exprTmp is "null", treat it as unknown type, can skip it. */
if (IsA(exprTmp, Const) && ((Const*)exprTmp)->constisnull) {
continue;
}
exprTypeTmp = getBaseType(exprType(exprTmp));
exprCategoryTmp = get_typecategory(exprTypeTmp);
if (!check_category_in_whitelist(exprCategoryTmp, exprTypeTmp)) {
allInWhitelist = false;
break;
}
}
return allInWhitelist;
}
/*
* Check whether the given category and type is in the whitelist.
*/
static bool check_category_in_whitelist(TYPCATEGORY category, Oid type)
{
bool categoryInWhitelist = false;
static TYPCATEGORY categoryWhitelist[] = {TYPCATEGORY_BOOLEAN, TYPCATEGORY_NUMERIC, TYPCATEGORY_STRING,
TYPCATEGORY_UNKNOWN, TYPCATEGORY_DATETIME, TYPCATEGORY_TIMESPAN, TYPCATEGORY_USER};
for (unsigned int i = 0; i < sizeof(categoryWhitelist) / sizeof(categoryWhitelist[0]); i++) {
if (category == categoryWhitelist[i]) {
/*
* For TYPCATEGORY_USER, just RAW in the whitelist.
* For TYPCATEGORY_NUMERIC, some numeric type not in the whitelist.
*/
if ((category == TYPCATEGORY_USER && type != RAWOID) ||
(category == TYPCATEGORY_NUMERIC && check_numeric_type_in_blacklist(type))) {
break;
}
categoryInWhitelist = true;
break;
}
}
return categoryInWhitelist;
}
/*
* Check whether the given numeric type is in the blacklist.
*/
static bool check_numeric_type_in_blacklist(Oid type)
{
bool typeInBlacklist = false;
static Oid numericTypeBlacklist[] = {CASHOID, INT16OID, REGPROCOID, OIDOID, REGPROCEDUREOID,
REGOPEROID, REGOPERATOROID, REGCLASSOID, REGTYPEOID, REGCONFIGOID, REGDICTIONARYOID};
for (unsigned int i = 0; i < sizeof(numericTypeBlacklist) / sizeof(numericTypeBlacklist[0]); i++) {
if (type == numericTypeBlacklist[i]) {
typeInBlacklist = true;
break;
}
}
return typeInBlacklist;
}
/*
* select_common_type()
* Determine the common supertype of a list of input expressions.
@ -1341,10 +1562,14 @@ Oid select_common_type(ParseState* pstate, List* exprs, const char* context, Nod
}
}
if ((u_sess->attr.attr_sql.sql_compatibility == C_FORMAT && context != NULL &&
(0 == strncmp(context, "CASE", sizeof("CASE")) || 0 == strncmp(context, "COALESCE", sizeof("COALESCE")))) ||
(ENABLE_SQL_BETA_FEATURE(A_STYLE_COERCE) && context != NULL &&
(0 == strncmp(context, "CASE", sizeof("CASE"))))) {
if (meet_decode_compatibility(exprs, context)) {
/*
* For A format, result1 is considered the most significant type in determining preferred type.
* In this function, try to choose a higher priority type of the same category as result1.
* And check whether other parameters can be implicitly converted to the data type of result1.
*/
ptype = choose_decode_result1_type(pstate, exprs, context);
} else if (meet_c_format_compatibility(exprs, context)) {
/*
* To C format, we need handle numeric and string mix situation.
* For A format, type should be coerced by the first case, therefore, it can accept cases like
@ -1353,9 +1578,8 @@ Oid select_common_type(ParseState* pstate, List* exprs, const char* context, Nod
* using C format coercion.
*/
ptype = choose_specific_expr_type(pstate, exprs, context);
}
/* Follow A db nvl*/
else if (context != NULL && 0 == strncmp(context, "NVL", sizeof("NVL"))) {
} else if (context != NULL && 0 == strncmp(context, "NVL", sizeof("NVL"))) {
/* Follow A db nvl*/
ptype = choose_nvl_type(pstate, exprs, context);
} else {
ptype = choose_expr_type(pstate, exprs, context, which_expr);
@ -1381,6 +1605,29 @@ Oid select_common_type(ParseState* pstate, List* exprs, const char* context, Nod
return ptype;
}
/*
* Check meet the decode type conversion rules compatibility or not.
*/
static bool meet_decode_compatibility(List* exprs, const char* context)
{
bool res = u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && ENABLE_SQL_BETA_FEATURE(A_STYLE_COERCE) &&
context != NULL && 0 == strncmp(context, "CASE", sizeof("CASE")) && check_all_in_whitelist(exprs);
return res;
}
/*
* Check meet the c format compatibility or not.
* For A format, some temporary are also in it.
*/
static bool meet_c_format_compatibility(List* exprs, const char* context)
{
bool res = (u_sess->attr.attr_sql.sql_compatibility == C_FORMAT && context != NULL &&
(0 == strncmp(context, "CASE", sizeof("CASE")) || 0 == strncmp(context, "COALESCE", sizeof("COALESCE")))) ||
(ENABLE_SQL_BETA_FEATURE(A_STYLE_COERCE) && context != NULL &&
(0 == strncmp(context, "CASE", sizeof("CASE"))));
return res;
}
/*
* coerce_to_common_type()
* Coerce an expression to the given type.

View File

@ -1634,12 +1634,28 @@ static Node* transformCaseExpr(ParseState* pstate, CaseExpr* c)
}
newc->defresult = (Expr*)transformExpr(pstate, defresult);
/* check results in resultexprs and defresult whether all are in the whitelist. */
List* defresultexprs = NIL;
defresultexprs = lappend(defresultexprs, newc->defresult);
bool allInWhitelist = check_all_in_whitelist(resultexprs) && check_all_in_whitelist(defresultexprs);
list_free_ext(defresultexprs);
/*
* Note: default result is considered the most significant type in
* determining preferred type. This is how the code worked before, but it
* seems a little bogus to me --- tgl
*
* For A format, result1 is considered the most significant type in
* determining preferred type. So append default result to the end of
* the list. Make sure result1 is the first element of the list.
*/
resultexprs = lcons(newc->defresult, resultexprs);
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT &&
ENABLE_SQL_BETA_FEATURE(A_STYLE_COERCE) && allInWhitelist) {
resultexprs = lappend(resultexprs, newc->defresult);
} else {
resultexprs = lcons(newc->defresult, resultexprs);
}
ptype = select_common_type(pstate, resultexprs, "CASE", NULL);
AssertEreport(OidIsValid(ptype), MOD_OPT, "");

View File

@ -59,7 +59,7 @@ bool open_join_children = true;
bool will_shutdown = false;
/* hard-wired binary version number */
const uint32 GRAND_VERSION_NUM = 92609;
const uint32 GRAND_VERSION_NUM = 92610;
const uint32 PREDPUSH_SAME_LEVEL_VERSION_NUM = 92522;
const uint32 UPSERT_WHERE_VERSION_NUM = 92514;

View File

@ -2072,6 +2072,36 @@ DATA(insert OID = 2284 ( regexp_replace PGNSP PGUID 12 1 0 0 0 f f f f f f i
DESCR("replace text using regexp");
DATA(insert OID = 2285 ( regexp_replace PGNSP PGUID 12 1 0 0 0 f f f f f f i 4 0 25 "25 25 25 25" _null_ _null_ _null_ _null_ textregexreplace _null_ _null_ _null_ "" f));
DESCR("replace text using regexp");
DATA(insert OID = 1116 ( regexp_replace PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 25 "25 25" _null_ _null_ _null_ _null_ regexp_replace_noopt _null_ _null_ _null_ "" f));
DESCR("replace text using regexp");
DATA(insert OID = 1117 ( regexp_replace PGNSP PGUID 12 1 0 0 0 f f f f f f i 4 0 25 "25 25 25 23" _null_ _null_ _null_ _null_ regexp_replace_position _null_ _null_ _null_ "" f));
DESCR("replace text using regexp");
DATA(insert OID = 1118 ( regexp_replace PGNSP PGUID 12 1 0 0 0 f f f f f f i 5 0 25 "25 25 25 23 23" _null_ _null_ _null_ _null_ regexp_replace_occur _null_ _null_ _null_ "" f));
DESCR("replace text using regexp");
DATA(insert OID = 1119 ( regexp_replace PGNSP PGUID 12 1 0 0 0 f f f f f f i 6 0 25 "25 25 25 23 23 25" _null_ _null_ _null_ _null_ regexp_replace_matchopt _null_ _null_ _null_ "" f));
DESCR("replace text using regexp");
DATA(insert OID = 385 ( regexp_count PGNSP PGUID 12 1 1 0 0 f f f f t f i 2 0 23 "25 25" _null_ _null_ _null_ _null_ regexp_count_noopt _null_ _null_ _null_ "" f));
DESCR("find all match count for regexp");
DATA(insert OID = 386 ( regexp_count PGNSP PGUID 12 1 1 0 0 f f f f f f i 3 0 23 "25 25 23" _null_ _null_ _null_ _null_ regexp_count_position _null_ _null_ _null_ "" f));
DESCR("find all match count for regexp");
DATA(insert OID = 387 ( regexp_count PGNSP PGUID 12 1 1 0 0 f f f f f f i 4 0 23 "25 25 23 25" _null_ _null_ _null_ _null_ regexp_count_matchopt _null_ _null_ _null_ "" f));
DESCR("find all match count for regexp");
DATA(insert OID = 630 ( regexp_instr PGNSP PGUID 12 1 1 0 0 f f f f t f i 2 0 23 "25 25" _null_ _null_ _null_ _null_ regexp_instr_noopt _null_ _null_ _null_ "" f));
DESCR("find match position for regexp");
DATA(insert OID = 631 ( regexp_instr PGNSP PGUID 12 1 1 0 0 f f f f f f i 3 0 23 "25 25 23" _null_ _null_ _null_ _null_ regexp_instr_position _null_ _null_ _null_ "" f));
DESCR("find match position for regexp");
DATA(insert OID = 632 ( regexp_instr PGNSP PGUID 12 1 1 0 0 f f f f f f i 4 0 23 "25 25 23 23" _null_ _null_ _null_ _null_ regexp_instr_occurren _null_ _null_ _null_ "" f));
DESCR("find match position for regexp");
DATA(insert OID = 633 ( regexp_instr PGNSP PGUID 12 1 1 0 0 f f f f f f i 5 0 23 "25 25 23 23 23" _null_ _null_ _null_ _null_ regexp_instr_returnopt _null_ _null_ _null_ "" f));
DESCR("find match position for regexp");
DATA(insert OID = 634 ( regexp_instr PGNSP PGUID 12 1 1 0 0 f f f f f f i 6 0 23 "25 25 23 23 23 25" _null_ _null_ _null_ _null_ regexp_instr_matchopt _null_ _null_ _null_ "" f));
DESCR("find match position for regexp");
DATA(insert OID = 1566 ( regexp_substr PGNSP PGUID 12 1 1 0 0 f f f f f f i 3 0 23 "25 25 23" _null_ _null_ _null_ _null_ regexp_substr_with_position _null_ _null_ _null_ "" f));
DESCR("extract text matching regular expression");
DATA(insert OID = 1567 ( regexp_substr PGNSP PGUID 12 1 1 0 0 f f f f f f i 4 0 23 "25 25 23 23" _null_ _null_ _null_ _null_ regexp_substr_with_occur _null_ _null_ _null_ "" f));
DESCR("extract text matching regular expression");
DATA(insert OID = 1568 ( regexp_substr PGNSP PGUID 12 1 1 0 0 f f f f f f i 5 0 23 "25 25 23 23 25" _null_ _null_ _null_ _null_ regexp_substr_with_opt _null_ _null_ _null_ "" f));
DESCR("extract text matching regular expression");
DATA(insert OID = 2763 ( regexp_matches PGNSP PGUID 12 1 1 0 0 f f f f t t i 2 0 1009 "25 25" _null_ _null_ _null_ _null_ regexp_matches_no_flags _null_ _null_ _null_ "" f));
DESCR("find all match groups for regexp");
DATA(insert OID = 2764 ( regexp_matches PGNSP PGUID 12 1 10 0 0 f f f f t t i 3 0 1009 "25 25 25" _null_ _null_ _null_ _null_ regexp_matches _null_ _null_ _null_ "" f));

View File

@ -0,0 +1,18 @@
DROP FUNCTION IF EXISTS pg_catalog.regexp_count(text, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_count(text, text, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_count(text, text, int, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_instr(text, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_instr(text, text, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_instr(text, text, int, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_instr(text, text, int, int, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_instr(text, text, int, int, int, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_replace(text, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_replace(text, text, text, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_replace(text, text, text, int, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_replace(text, text, text, int, int, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_substr(text, text, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_substr(text, text, int, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_substr(text, text, int, int, text) CASCADE;

View File

@ -0,0 +1,18 @@
DROP FUNCTION IF EXISTS pg_catalog.regexp_count(text, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_count(text, text, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_count(text, text, int, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_instr(text, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_instr(text, text, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_instr(text, text, int, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_instr(text, text, int, int, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_instr(text, text, int, int, int, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_replace(text, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_replace(text, text, text, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_replace(text, text, text, int, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_replace(text, text, text, int, int, text) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_substr(text, text, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_substr(text, text, int, int) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.regexp_substr(text, text, int, int, text) CASCADE;

View File

@ -0,0 +1,110 @@
-- regexp_count
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 385;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_count(text, text)
RETURNS integer
LANGUAGE internal
IMMUTABLE STRICT NOT FENCED NOT SHIPPABLE
AS $function$regexp_count_noopt$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 386;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_count(text, text, int)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_count_position$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 387;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_count(text, text, int, text)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_count_matchopt$function$;
-- regexp_instr
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 630;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_instr(text, text)
RETURNS integer
LANGUAGE internal
IMMUTABLE STRICT NOT FENCED NOT SHIPPABLE
AS $function$regexp_instr_noopt$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 631;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_instr(text, text, int)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_instr_position$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 632;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_instr(text, text, int, int)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_instr_occurren$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 633;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_instr(text, text, int, int, int)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_instr_returnopt$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 634;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_instr(text, text, int, int, int, text)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_instr_matchopt$function$;
-- regexp_replace
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1116;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_replace(text, text)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_replace_noopt$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1117;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_replace(text, text, text, int)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_replace_position$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1118;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_replace(text, text, text, int, int)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_replace_occur$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1119;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_replace(text, text, text, int, int, text)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_replace_matchopt$function$;
-- regexp_substr
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1566;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_substr(text, text, int)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_substr_with_position$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1567;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_substr(text, text, int, int)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_substr_with_occur$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1568;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_substr(text, text, int, int, text)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_substr_with_opt$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 0;

View File

@ -0,0 +1,110 @@
-- regexp_count
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 385;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_count(text, text)
RETURNS integer
LANGUAGE internal
IMMUTABLE STRICT NOT FENCED NOT SHIPPABLE
AS $function$regexp_count_noopt$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 386;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_count(text, text, int)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_count_position$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 387;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_count(text, text, int, text)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_count_matchopt$function$;
-- regexp_instr
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 630;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_instr(text, text)
RETURNS integer
LANGUAGE internal
IMMUTABLE STRICT NOT FENCED NOT SHIPPABLE
AS $function$regexp_instr_noopt$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 631;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_instr(text, text, int)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_instr_position$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 632;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_instr(text, text, int, int)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_instr_occurren$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 633;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_instr(text, text, int, int, int)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_instr_returnopt$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 634;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_instr(text, text, int, int, int, text)
RETURNS integer
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_instr_matchopt$function$;
-- regexp_replace
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1116;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_replace(text, text)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_replace_noopt$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1117;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_replace(text, text, text, int)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_replace_position$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1118;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_replace(text, text, text, int, int)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_replace_occur$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1119;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_replace(text, text, text, int, int, text)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_replace_matchopt$function$;
-- regexp_substr
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1566;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_substr(text, text, int)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_substr_with_position$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1567;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_substr(text, text, int, int)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_substr_with_occur$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 1568;
CREATE OR REPLACE FUNCTION pg_catalog.regexp_substr(text, text, int, int, text)
RETURNS text
LANGUAGE internal
IMMUTABLE NOT FENCED NOT SHIPPABLE
AS $function$regexp_substr_with_opt$function$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 0;

View File

@ -57,6 +57,7 @@ extern Node* coerce_to_specific_type(ParseState* pstate, Node* node, Oid targetT
extern int parser_coercion_errposition(ParseState* pstate, int coerce_location, Node* input_expr);
extern Oid select_common_type(ParseState* pstate, List* exprs, const char* context, Node** which_expr);
extern bool check_all_in_whitelist(List* resultexprs);
extern Node* coerce_to_common_type(ParseState* pstate, Node* node, Oid targetTypeId, const char* context);
extern bool check_generic_type_consistency(Oid* actual_arg_types, Oid* declared_arg_types, int nargs);

View File

@ -170,11 +170,11 @@ select count(distinct(a)) col1, d, avg(b) col2, sum(distinct(a)) col3, avg(disti
(7 rows)
explain (costs off) select distinct case when min(distinct c)>60 then min(distinct c) else null end as min, count(distinct(b)) from t_distinct group by b;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
Row Adapter
-> Vector Hash Aggregate
Group By Key: CASE WHEN (min(DISTINCT c) > 60) THEN min(DISTINCT c) ELSE NULL::integer END, count(DISTINCT b)
Group By Key: CASE WHEN (min(DISTINCT c) > 60) THEN (min(DISTINCT c))::numeric ELSE NULL::numeric END, count(DISTINCT b)
-> Vector Sort Aggregate
Group By Key: b
-> Vector Sort

View File

@ -721,10 +721,10 @@ select count(distinct(a)) col1, d, avg(b) col2, sum(distinct(a)) col3, avg(disti
(7 rows)
explain (costs off) select distinct case when min(distinct c)>60 then min(distinct c) else null end as min, count(distinct(b)) from t_distinct group by b;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------
HashAggregate
Group By Key: CASE WHEN (min(DISTINCT c) > 60) THEN min(DISTINCT c) ELSE NULL::integer END, count(DISTINCT b)
Group By Key: CASE WHEN (min(DISTINCT c) > 60) THEN (min(DISTINCT c))::numeric ELSE NULL::numeric END, count(DISTINCT b)
-> GroupAggregate
Group By Key: b
-> Sort

View File

@ -350,12 +350,12 @@ select '20180831' rpt_Dt, org_id org_id,
end) bxs
from m_inte_counter_detail a left join m_pub_org_stat_stt b on a.org_id = b.net_bank
group by a.org_id;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Row Adapter
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = ANY ('{TTS,GXH}'::text[])) THEN a.term_code ELSE NULL::character varying END)), (count(DISTINCT CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.is_type)::text = ANY ('{TTS,GXH}'::text[]))) THEN a.term_code ELSE NULL::character varying END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), a.org_id
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = ANY ('{TTS,GXH}'::text[])) THEN a.term_code ELSE NULL::character varying END)), (count(DISTINCT CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.is_type)::text = ANY ('{TTS,GXH}'::text[]))) THEN a.term_code ELSE NULL::character varying END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), a.org_id
-> Vector Sort Aggregate
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END), count(DISTINCT CASE WHEN ((a.is_type)::text = ANY ('{TTS,GXH}'::text[])) THEN a.term_code ELSE NULL::character varying END), count(DISTINCT CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.is_type)::text = ANY ('{TTS,GXH}'::text[]))) THEN a.term_code ELSE NULL::character varying END), count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END), a.org_id
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END), count(DISTINCT CASE WHEN ((a.is_type)::text = ANY ('{TTS,GXH}'::text[])) THEN a.term_code ELSE NULL::character varying END), count(DISTINCT CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.is_type)::text = ANY ('{TTS,GXH}'::text[]))) THEN a.term_code ELSE NULL::character varying END), count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END), a.org_id
Group By Key: a.org_id
-> Vector Sort
Output: a.org_id, a.rpt_dt, a.ywbh, a.is_type, a.term_code
@ -391,12 +391,12 @@ select '20180831' rpt_Dt, a.org_id,
end) bxs
from m_inte_counter_detail a left join m_pub_org_stat_stt b on a.org_id = b.net_bank
group by org_id;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Row Adapter
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = ANY ('{TTS,GXH}'::text[])) THEN a.term_code ELSE NULL::character varying END)), (sum(DISTINCT (CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.is_type)::text = ANY ('{TTS,GXH}'::text[]))) THEN a.term_code ELSE NULL::character varying END)::numeric)), (sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric)), a.org_id
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = ANY ('{TTS,GXH}'::text[])) THEN a.term_code ELSE NULL::character varying END)), (sum(DISTINCT (CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.is_type)::text = ANY ('{TTS,GXH}'::text[]))) THEN a.term_code ELSE NULL::character varying END)::numeric)), (sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric)), a.org_id
-> Vector Sort Aggregate
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END), count(DISTINCT CASE WHEN ((a.is_type)::text = ANY ('{TTS,GXH}'::text[])) THEN a.term_code ELSE NULL::character varying END), sum(DISTINCT (CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.is_type)::text = ANY ('{TTS,GXH}'::text[]))) THEN a.term_code ELSE NULL::character varying END)::numeric), sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric), a.org_id
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END), count(DISTINCT CASE WHEN ((a.is_type)::text = ANY ('{TTS,GXH}'::text[])) THEN a.term_code ELSE NULL::character varying END), sum(DISTINCT (CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.is_type)::text = ANY ('{TTS,GXH}'::text[]))) THEN a.term_code ELSE NULL::character varying END)::numeric), sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric), a.org_id
Group By Key: a.org_id
-> Vector Sort
Output: a.org_id, a.rpt_dt, a.ywbh, a.is_type, a.term_code
@ -425,12 +425,12 @@ select '20180831' rpt_Dt, a.org_id,
from m_inte_counter_detail a left join m_pub_org_stat_stt b on a.org_id = b.net_bank
group by org_id
having count(distinct a.is_type) > 100;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Row Adapter
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END)), (sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric)), a.org_id
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END)), (sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric)), a.org_id
-> Vector Sort Aggregate
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END), sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric), a.org_id
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END), sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric), a.org_id
Group By Key: a.org_id
Filter: (count(DISTINCT a.is_type) > 100)
-> Vector Sort
@ -460,12 +460,12 @@ select '20180831' rpt_Dt, org_id,
from m_inte_counter_detail a left join m_pub_org_stat_stt b on a.org_id = b.net_bank
group by a.org_id
having sum(distinct a.is_type) + avg(distinct org_id)> 100;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Row Adapter
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END)), (sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric)), a.org_id
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END)), (sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric)), a.org_id
-> Vector Sort Aggregate
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END), sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric), a.org_id
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END), sum(DISTINCT (CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)::numeric), a.org_id
Group By Key: a.org_id
Filter: ((sum(DISTINCT (a.is_type)::numeric) + avg(DISTINCT (a.org_id)::numeric)) > 100::numeric)
-> Vector Sort
@ -496,12 +496,12 @@ select '20180831' rpt_Dt, org_id,
group by a.org_id
having sum(distinct a.is_type) + avg(distinct org_id)> 100
order by 2;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Row Adapter
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), a.org_id
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), a.org_id
-> Vector Sort Aggregate
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END), count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END), a.org_id
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END), count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END), a.org_id
Group By Key: a.org_id
Filter: ((sum(DISTINCT (a.is_type)::numeric) + avg(DISTINCT (a.org_id)::numeric)) > 100::numeric)
-> Vector Sort
@ -532,12 +532,12 @@ select '20180831' rpt_Dt, org_id,
group by a.org_id
having sum(distinct a.is_type) + avg(distinct (a.org_id + org_id))> 100
order by 2;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Row Adapter
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), a.org_id
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), a.org_id
-> Vector Sort Aggregate
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END), count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END), a.org_id
Output: '20180831'::text, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END), count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END), a.org_id
Group By Key: a.org_id
Filter: ((sum(DISTINCT (a.is_type)::numeric) + avg(DISTINCT ((a.org_id)::numeric + (a.org_id)::numeric))) > 100::numeric)
-> Vector Sort
@ -570,17 +570,17 @@ select '20180831' rpt_Dt, org_id,
group by cube(a.org_id)
having sum(distinct a.is_type) + avg(distinct (a.org_id + org_id))> 100
order by 2;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Row Adapter
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), (GROUPING(a.org_id)), (rank() OVER (PARTITION BY a.org_id)), a.org_id
Output: ('20180831'::text), a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), (GROUPING(a.org_id)), (rank() OVER (PARTITION BY a.org_id)), a.org_id
-> Vector WindowAgg
Output: '20180831'::text, a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), (GROUPING(a.org_id)), rank() OVER (PARTITION BY a.org_id), a.org_id
Output: '20180831'::text, a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), (GROUPING(a.org_id)), rank() OVER (PARTITION BY a.org_id), a.org_id
-> Vector Sort
Output: a.org_id, a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), (GROUPING(a.org_id))
Output: a.org_id, a.org_id, (count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END)), (count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END)), (GROUPING(a.org_id))
Sort Key: a.org_id
-> Vector Sort Aggregate
Output: a.org_id, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1 ELSE NULL::integer END), count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END), GROUPING(a.org_id)
Output: a.org_id, a.org_id, count(CASE WHEN (((a.rpt_dt)::text = '20180831'::text) AND ((a.ywbh)::text = ANY ('{223,478,819,886}'::text[]))) THEN 1::numeric ELSE NULL::numeric END), count(DISTINCT CASE WHEN ((a.is_type)::text = 'BXS'::text) THEN a.term_code ELSE NULL::character varying END), GROUPING(a.org_id)
Group By Key: a.org_id
Group By Key: ()
Filter: ((sum(DISTINCT (a.is_type)::numeric) + avg(DISTINCT ((a.org_id)::numeric + (a.org_id)::numeric))) > 100::numeric)

File diff suppressed because it is too large Load Diff

View File

@ -1199,26 +1199,28 @@ from test_decode_coercion;
select
decode(1, 2, 'never', col_bool)
from test_decode_coercion;
ERROR: CASE types boolean and text cannot be matched
ERROR: CASE types text and boolean cannot be matched
LINE 2: decode(1, 2, 'never', col_bool)
^
^
CONTEXT: referenced column: col_bool
-- still invalid
-- now supported
select
decode(1, 2, 'never', col_date)
from test_decode_coercion;
ERROR: CASE types timestamp without time zone and text cannot be matched
LINE 2: decode(1, 2, 'never', col_date)
^
CONTEXT: referenced column: col_date
-- still invalid
col_date
--------------------------
Sat Jan 01 01:01:01 2000
(1 row)
-- now supported
select
decode(1, 2, 'never', col_time)
from test_decode_coercion;
ERROR: CASE types timestamp without time zone and text cannot be matched
LINE 2: decode(1, 2, 'never', col_time)
^
CONTEXT: referenced column: col_time
col_time
--------------------------
Sat Jan 01 01:01:01 2000
(1 row)
drop schema forall_save_exceptions cascade;
NOTICE: drop cascades to 17 other objects
DETAIL: drop cascades to table test_forall

View File

@ -224,10 +224,10 @@ explain (verbose on, costs off) select b, c from test_union_1 minus select b, c
(11 rows)
explain (verbose on, costs off) select b, substr(c, 1, 3), c from test_union_1 minus (select 1, t2.b::varchar(10), t1.c from (select a,b,case c when 1 then 1 else null end as c from test_union_2 where b<0) t1 right join test_union_2 t2 on t1.b=t2.c group by 1, 2, 3);
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
HashSetOp Except
Output: "*SELECT* 1".b, "*SELECT* 1".substr, "*SELECT* 1".c, (0)
Output: "*SELECT* 1".b, "*SELECT* 1".substr, (("*SELECT* 1".c)::numeric), (0)
-> Append
-> Subquery Scan on "*SELECT* 1"
Output: "*SELECT* 1".b, "*SELECT* 1".substr, "*SELECT* 1".c, 0
@ -236,17 +236,17 @@ explain (verbose on, costs off) select b, substr(c, 1, 3), c from test_union_1
-> Subquery Scan on "*SELECT* 2"
Output: 1, ("*SELECT* 2".b)::text, "*SELECT* 2".c, 1
-> HashAggregate
Output: (1), ((t2.b)::character varying(10)), (CASE test_union_2.c WHEN 1 THEN 1 ELSE NULL::integer END)
Group By Key: 1, (t2.b)::character varying(10), (CASE test_union_2.c WHEN 1 THEN 1 ELSE NULL::integer END)
Output: (1), ((t2.b)::character varying(10)), (CASE test_union_2.c WHEN 1 THEN 1::numeric ELSE NULL::numeric END)
Group By Key: 1, (t2.b)::character varying(10), (CASE test_union_2.c WHEN 1 THEN 1::numeric ELSE NULL::numeric END)
-> Hash Left Join
Output: 1, (t2.b)::character varying(10), (CASE test_union_2.c WHEN 1 THEN 1 ELSE NULL::integer END)
Output: 1, (t2.b)::character varying(10), (CASE test_union_2.c WHEN 1 THEN 1::numeric ELSE NULL::numeric END)
Hash Cond: (t2.c = test_union_2.b)
-> Seq Scan on distribute_setop_1.test_union_2 t2
Output: t2.a, t2.b, t2.c
-> Hash
Output: test_union_2.b, (CASE test_union_2.c WHEN 1 THEN 1 ELSE NULL::integer END)
Output: test_union_2.b, (CASE test_union_2.c WHEN 1 THEN 1::numeric ELSE NULL::numeric END)
-> Seq Scan on distribute_setop_1.test_union_2
Output: test_union_2.b, CASE test_union_2.c WHEN 1 THEN 1 ELSE NULL::integer END
Output: test_union_2.b, CASE test_union_2.c WHEN 1 THEN 1::numeric ELSE NULL::numeric END
Filter: (test_union_2.b < 0)
(22 rows)

View File

@ -140,15 +140,15 @@ WHERE enumtypid = 'insenum'::regtype
ORDER BY enumsortorder;
enumlabel | so
-----------+----
L1 | 1
i1 | 2
i2 | 3
i3 | 4
i4 | 5
i5 | 6
i6 | 7
i7 | 8
i8 | 9
L1 | 1
i1 | 2
i2 | 3
i3 | 4
i4 | 5
i5 | 6
i6 | 7
i7 | 8
i8 | 9
i9 | 10
i10 | 11
i11 | 12
@ -160,18 +160,18 @@ ORDER BY enumsortorder;
i17 | 18
i18 | 19
i19 | 20
i20 |
i21 |
i22 |
i23 |
i24 |
i25 |
i26 |
i27 |
i28 |
i29 |
i30 |
L2 |
i20 |
i21 |
i22 |
i23 |
i24 |
i25 |
i26 |
i27 |
i28 |
i29 |
i30 |
L2 |
(32 rows)
--

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
# ----------
test: alter_hw_package
test: hw_grant_package gsc_func gsc_db
test: uppercase_attribute_name
test: uppercase_attribute_name decode_compatible_with_o
test: replace_func_with_two_args trunc_func_for_date nlssort_pinyin updatable_views
# parse xlog and page

File diff suppressed because it is too large Load Diff

View File

@ -966,12 +966,12 @@ select
decode(1, 2, 'never', col_bool)
from test_decode_coercion;
-- still invalid
-- now supported
select
decode(1, 2, 'never', col_date)
from test_decode_coercion;
-- still invalid
-- now supported
select
decode(1, 2, 'never', col_time)
from test_decode_coercion;

View File

@ -1,3 +1,202 @@
-- test regexp_count(source_char, pattern [, position [, match_param] ])
set behavior_compat_options = aformat_regexp_match;
select regexp_count('abc', '^a');
select regexp_count('abc', '');
select regexp_count(null, '');
select regexp_count(null, null);
select regexp_count('abc', null);
select regexp_count('abc'||chr(10)||'def', '^(a|d)');
select regexp_count('abc'||chr(10)||'def', '^(a|d)', 1, 'm');
select regexp_count('abc'||chr(13)||chr(10)||'def', '^(a|d)', 1, 'm');
select regexp_count('abc'||chr(13)||chr(10)||'def', '^(a|d)', 1, 'n');
select regexp_count('abc'||chr(13)||chr(10)||'def', '^(a|d)', 1, 'p');
select regexp_count('abc'||chr(13)||chr(10)||'def', '^(a|d)', 1, 'w');
select regexp_count('abc'||chr(10)||'def', 'abc.d');
select regexp_count('abc'||chr(10)||'def', 'abc.d', 1, 'w');
select regexp_count('abc'||chr(10)||'def', 'abc.d', 1, 'g');
select regexp_count('abc'||chr(10)||'def', 'abc.d', 1, 'p');
select regexp_count('abc'||chr(10)||'def', 'abc.d', 2, 'w');
select regexp_count('abc'||chr(10)||'def', 'abc.d', null, 'w');
select regexp_count('abc'||chr(10)||'def', 'abc.d', 1000, 'w');
select regexp_count('abc'||chr(10)||'def', 'abc.d', 1000, null);
select regexp_count('abc', 'b', 0, '');
select regexp_count('abc', 'b', -1, '');
select regexp_count(null, 'b', -1, '');
select regexp_count(null, 'b', 1, 'g');
select regexp_count('abc', null, 1, 'g');
select regexp_count('abc def', '[a-z]{0,}');
select regexp_count('abc def', '[a-z]*');
select regexp_count('abc def', '[a-z]+');
select regexp_count('smishtm1_23','^\w+$',3);
select regexp_count('smishtm1_23','\w+$',3);
select regexp_count('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 5);
select regexp_count('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 20);
select regexp_count('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 35);
select regexp_count('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 36);
create table regexptable(id int,char_value CHAR(255), nchar_value NCHAR(255), varchar2_value VARCHAR2(255), nvarchar2_value NVARCHAR2(255), clob_value CLOB, text_value TEXT);
insert into regexptable values(1,'123jui','56700986.58 ','ring1023','smishtm1_23','qwe@qq.com','homeoooo9876000');
insert into regexptable values(2,'rooob000','-89098.980 ','9999.99900','j_ack_990','123@sina.com','-765489097.07658');
insert into regexptable values(3,'ring1023','9999.99900 ','marry_10','marry_10','qwe@11.cm','kingqueen0980_');
insert into regexptable values(4,'happyeveryday999','-900876','KINGGGkingooo765','_123abc','rty@qq.com','oplplPPPPPP11098');
insert into regexptable values(5,'clobbiger9098','654799009.9076','KINGkoo5','__acbcbf__','qwe@sina.com','oplplPPPPPP11098');
insert into regexptable values(6,'homeoooo9876000','-765489097.07658','KINGKkingooo098','kingqueen0980_','123@163.com','oplplPPPPPP11098');
insert into regexptable values(7,regexp_count('1233444',''),regexp_count('1233444',''),regexp_count('1233444','1'),regexp_count('1233444','2'),regexp_count('1233444','3'),regexp_count('1233444','4'));
select id, regexp_count(char_value,'^[A-Za-z0-9]+$',1) as result , char_value from regexptable order by 1, 2, 3;
--error
select id, regexp_count(char_value,'^[A-Za-z0-9]+$',2) as result , char_value from regexptable order by 1, 2, 3;
select id, regexp_count(nchar_value,'^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$') as result , nchar_value from regexptable order by 1, 2, 3;
--error
select id, regexp_count(nchar_value,'^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$',2) as result , nchar_value from regexptable order by 1, 2, 3;
select id, regexp_count(varchar2_value,'^.{3,8}$',1,'i') as result , varchar2_value from regexptable order by 1, 2, 3;
-- test regexp_instr(source_char, pattern [, position [, occurrence [, return_opt [, match_param]]]])
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '');
select regexp_instr(null, '');
select regexp_instr('abc', '');
select regexp_instr('abc', null);
select regexp_instr(null, 'b', 0);
select regexp_instr(null, 'b', 1);
select regexp_instr('abc', 'b', null);
select regexp_instr('abc', 'b', 1, null);
select regexp_instr('abc', 'b', -1, '');
select regexp_instr(null, 'b', -1, '');
select regexp_instr(null, 'b', 1, -1);
select regexp_instr(null, 'b', 1, 0);
select regexp_instr('abc', null, 1, -1);
select regexp_instr('abc', null, 1, 1, -1);
select regexp_instr('abc', null, 1, 1, 0);
select regexp_instr('abc def', '[a-z]{0,}', 1, 1);
select regexp_instr('abc def', '[a-z]{0,}', 1, 2);
select regexp_instr('abc def', '[a-z]{0,}', 1, 3);
select regexp_instr('abc def', '[a-z]{0,}', 1, 4);
select regexp_instr('abc def', '[a-z]{0,}', 1000);
select regexp_instr('abc def', '[a-z]{0,}', 7);
select regexp_instr('abc def', '[a-z]{0,}', 8);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', null);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+');
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 0, 6);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', -1, 6);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 1, 0);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', null, 1);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 1, null);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 1, 6, 0);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 1, 6, -1);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 1, 6, 1);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 5, 5);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 5, 5, 2);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 100, 5);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 100, 0);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 100, -1);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 1, 100);
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[s|r|p][[:alpha:]]{6}', 3, 2, 0, 'i');
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[s|r|p][[:alpha:]]{6}', 3, 2, 1, 'i');
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[s|r|p][[:alpha:]]{6}', 3, 2, 1, 'c');
select regexp_instr('500 OMG Parkway, Redwood Shores, CA', '[s|r|p][[:alpha:]]{6}', 3, 2, 1, 'g');
select regexp_instr('abc'||chr(10)||'def', '^(a|d)?.', 1, 2, 0, 'm');
select regexp_instr('abc'||chr(10)||'def', '^(a|d)?.', 1, 2, 1, 'm');
select regexp_instr('smishtm1_23','^\w+$',3);
select regexp_instr('smishtm1_23','\w+$',3);
-- test regexp_substr(source_char, pattern [, position [, occurrence [, match_param]]])
select regexp_substr('', '[^ ]+');
select regexp_substr(null, '[^ ]+');
select regexp_substr(null, '');
select regexp_substr('abc', '');
select regexp_substr('abc', null);
select regexp_substr(null, 'b', 0);
select regexp_substr(null, 'b', 1);
select regexp_substr('abc', 'b', null);
select regexp_substr('abc', 'b', 1, null);
select regexp_substr('abc', 'b', -1, '');
select regexp_substr(null, 'b', -1, '');
select regexp_substr(null, 'b', 1, -1);
select regexp_substr(null, 'b', 1, 0);
select regexp_substr(null, 'b', 1, 1);
select regexp_substr('smishtm1_23','^\w+$',3,1);
select regexp_substr('abc def', '[a-z]{0,}', 7);
select regexp_substr('abc def', '[a-z]{0,}', 8);
select regexp_substr('abc def', '[a-z]{0,}', 9);
select regexp_substr('sping'||chr(10)||'sppkg', 'sp.+g');
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '');
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', null);
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+');
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', null);
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 0);
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 1);
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 1000);
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 9);
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 9, null);
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 9, 0);
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 9, 1);
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 9, 3);
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 9, 5);
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 9, 4, '');
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 9, 4, 'g');
select regexp_substr('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', 9, 4, null);
select regexp_substr('', '^(a|d)?.', 1, 2, 'm');
select regexp_substr(null, '^(a|d)?.', 1, 2, 'm');
select regexp_substr('abc'||chr(10)||'def', null, 1, 2, 'm');
select regexp_substr('abc'||chr(10)||'def', '', 1, 2, 'm');
select regexp_substr('abc'||chr(10)||'def', '^(a|d)?.', 1, 2, 'm');
select regexp_substr('abc'||chr(10)||'def', '^(a|d)?.', 1, null, 'm');
-- test regexp_replace(source_char, pattern [, replace_str [, position [, occurrence [, match_param]]]])
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+');
select regexp_replace('', '[^ ]+');
select regexp_replace('abc', '');
select regexp_replace('abc', null);
select regexp_replace(null, '[^ ]+');
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '');
select regexp_replace('', '[^ ]+', '-', 1);
select regexp_replace(null, '[^ ]+', '-', 1);
select regexp_replace(null, 'b', 'a', 0);
select regexp_replace(null, 'b', 'a', 1);
select regexp_replace('abc', 'b', 'a', null);
select regexp_replace('abc', 'b', 'a', 1, null);
select regexp_replace('abc', 'b', 'a', -1, '');
select regexp_replace(null, 'b', 'a', -1, '');
select regexp_replace(null, 'b', 'a', 1, -1);
select regexp_replace(null, 'b', 'a', 1, 0);
select regexp_replace(null, 'b', 'a', 1, 1);
select regexp_replace('abc', 'b', null, 1, 1);
select regexp_replace('abc', 'b', null, 1, null);
select regexp_replace('abc', 'b', null, 1, -1);
select regexp_replace('abc', 'b', '-', null, -1, 'n');
select regexp_replace('sping'||chr(10)||'sppkg', 'sp.+g', '-');
select regexp_replace('smishtm1_23','^\w+$','*',3,1);
select regexp_replace('123abc', '[0-9]*','9',100);
select regexp_replace('', '[a-z]{0,}', '$');
select regexp_replace('a', '[a-z]{0,}', '$');
select regexp_replace('abc def', '[a-z]{0,}', '$');
select regexp_replace('abc def', '[a-z]{0,}', '$', 3);
select regexp_replace('abc def', '[a-z]{0,}', '$', 4);
select regexp_replace('abc def', '[a-z]{0,}', '$', 5);
select regexp_replace('abc def', '[a-z]{0,}', '$', 7);
select regexp_replace('abc def', '[a-z]{0,}', '$', 8);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '', '-', null);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '', '-', 1);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', null, '-', 1);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '', 1);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', null, 1);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 0);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 1000);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 5);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 34);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 35);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 1, -1);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 1, 0);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 1, 1);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 1, 6);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 1, 7);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 1, null);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 1, 2, null);
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 1, 2, '');
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 1, 2, 'm');
select regexp_replace('500 OMG Parkway, Redwood Shores, CA', '[^ ]+', '-', 1, 2, 'g');
select regexp_replace('abc'||chr(10)||'def', '^(a|d)?.', '-', 1, 2, 'm');
select regexp_replace('abc'||chr(13)||chr(10)||'def', '^(a|d)?.', '-', 1, 2, 'm');
set behavior_compat_options = '';
-- Test regexp_matches
select regexp_matches('abb', '(?<=a)b*');
select regexp_matches('a', 'a(?<=a)b*');