forked from huawei/openGauss-server
!1448 修复upsert子查询、first last函数等特性功能不可用问题
Merge pull request !1448 from gentle_hu/guass
This commit is contained in:
commit
6057d21b37
|
|
@ -258,6 +258,7 @@ hot_standby_feedback|bool|0,0|NULL|NULL|
|
|||
ident_file|string|0,0|NULL|NULL|
|
||||
ignore_checksum_failure|bool|0,0|NULL|Continues processing after a checksum failure.|
|
||||
ignore_system_indexes|bool|0,0|NULL|When ignore_system_indexes set to on, it is very useful for recovering data from the table which system index is corrupted.|
|
||||
parctl_min_cost|int|-1,2147483647|NULL|NULL|
|
||||
io_control_unit|int|1000,1000000|NULL|NULL|
|
||||
gin_pending_list_limit|int|64,2147483647|kB|NULL|
|
||||
intervalstyle|enum|postgres,postgres_verbose,sql_standard,iso_8601,a|NULL|NULL|
|
||||
|
|
|
|||
|
|
@ -352,6 +352,14 @@
|
|||
"array_recv", 1,
|
||||
AddBuiltinFunc(_0(2400), _1("array_recv"), _2(3), _3(true), _4(false), _5(array_recv), _6(2277), _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(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_recv"), _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))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"array_remove", 1,
|
||||
AddBuiltinFunc(_0(6555), _1("array_remove"), _2(2), _3(false), _4(false), _5(array_remove), _6(2277), _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, 2277, 2283), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_remove"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"array_replace", 1,
|
||||
AddBuiltinFunc(_0(6556), _1("array_replace"), _2(3), _3(false), _4(false), _5(array_replace), _6(2277), _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, 2277, 2283,2283), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_replace"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"array_send", 1,
|
||||
AddBuiltinFunc(_0(2401), _1("array_send"), _2(1), _3(true), _4(false), _5(array_send), _6(17), _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, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_send"), _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))
|
||||
|
|
@ -2550,6 +2558,14 @@
|
|||
"fenced_udf_process", 1,
|
||||
AddBuiltinFunc(_0(4207), _1("fenced_udf_process"), _2(1), _3(true), _4(false), _5(fenced_udf_process), _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('s'), _19(0), _20(1, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("fenced_udf_process"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"first", 1,
|
||||
AddBuiltinFunc(_0(6560), _1("first"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(2283), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2283), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"first_transition", 1,
|
||||
AddBuiltinFunc(_0(6558), _1("first_transition"), _2(2), _3(true), _4(false), _5(first_transition), _6(2283), _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, 2283, 2283), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("first_transition"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"finish", 1,
|
||||
AddBuiltinFunc(_0(1518), _1("finish"), _2(0), _3(true), _4(true), _5(debug_client_finish), _6(2249), _7(PG_PLDEBUG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(1), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(0), _21(4, 26, 25, 23, 25), _22(4, 'o', 'o', 'o', 'o'), _23(4, "funcoid", "funcname", "lineno", "query"), _24(NULL), _25("debug_client_finish"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
|
||||
|
|
@ -6025,10 +6041,18 @@
|
|||
"language_handler_out", 1,
|
||||
AddBuiltinFunc(_0(2303), _1("language_handler_out"), _2(1), _3(true), _4(false), _5(language_handler_out), _6(2275), _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(1, 2280), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("language_handler_out"), _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))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"last", 1,
|
||||
AddBuiltinFunc(_0(6561), _1("last"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(2283), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2283), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"last_day", 1,
|
||||
AddBuiltinFunc(_0(4075), _1("last_day"), _2(1), _3(true), _4(false), _5(last_day), _6(1114), _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(1, 1114), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("last_day"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"last_transition", 1,
|
||||
AddBuiltinFunc(_0(6559), _1("last_transition"), _2(2), _3(true), _4(false), _5(last_transition), _6(2283), _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, 2283, 2283), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("last_transition"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"last_value", 1,
|
||||
AddBuiltinFunc(_0(3113), _1("last_value"), _2(1), _3(true), _4(false), _5(window_last_value), _6(2283), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(true), _16(false), _17(false), _18('i'), _19(0), _20(1, 2283), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("window_last_value"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("fetch the last row value"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
|
||||
|
|
|
|||
|
|
@ -17959,6 +17959,7 @@ upsert_clause:
|
|||
n->targetList = $5;
|
||||
$$ = (Node *) n;
|
||||
} else {
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
/* check subquery in set clause*/
|
||||
ListCell* cell = NULL;
|
||||
ResTarget* res = NULL;
|
||||
|
|
@ -17966,14 +17967,14 @@ upsert_clause:
|
|||
res = (ResTarget*)lfirst(cell);
|
||||
if (IsA(res->val,SubLink)) {
|
||||
const char* message = "Update with subquery is not yet supported whithin INSERT ON DUPLICATE KEY UPDATE statement.";
|
||||
InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
|
||||
InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
|
||||
ereport(errstate,
|
||||
(errmodule(MOD_PARSER),
|
||||
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("Update with subquery is not yet supported whithin INSERT ON DUPLICATE KEY UPDATE statement.")));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
UpsertClause *uc = makeNode(UpsertClause);
|
||||
uc->targetList = $5;
|
||||
uc->location = @1;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ OBJS = acl.o arrayfuncs.o array_selfuncs.o array_typanalyze.o \
|
|||
tsquery_op.o tsquery_rewrite.o tsquery_util.o tsrank.o \
|
||||
tsvector.o tsvector_op.o tsvector_parser.o \
|
||||
txid.o uuid.o windowfuncs.o xml.o extended_statistics.o clientlogic_bytea.o clientlogicsettings.o \
|
||||
median_aggs.o expr_distinct.o nlssort.o
|
||||
median_aggs.o expr_distinct.o nlssort.o first_last_agg.o
|
||||
|
||||
like.o: like.cpp like_match.cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -5531,6 +5531,279 @@ Datum array_unnest(PG_FUNCTION_ARGS)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check if search is same as replace
|
||||
*/
|
||||
static bool array_same_replace(FunctionCallInfo locfcinfo, Datum search, bool search_isnull,
|
||||
Datum replace, bool replace_isnull)
|
||||
{
|
||||
if (search_isnull != replace_isnull) {
|
||||
return false;
|
||||
} else if (search_isnull == true) {
|
||||
Assert(replace_isnull);
|
||||
return true;
|
||||
} else {
|
||||
locfcinfo->arg[0] = search;
|
||||
locfcinfo->arg[1] = replace;
|
||||
locfcinfo->argnull[0] = search_isnull;
|
||||
locfcinfo->argnull[1] = replace_isnull;
|
||||
locfcinfo->isnull = false;
|
||||
return DatumGetBool(FunctionCallInvoke(locfcinfo));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* array_replace/array_remove support
|
||||
*
|
||||
* Find all array entries matching (not distinct from) search/search_isnull,
|
||||
* and delete them if remove is true, else replace them with
|
||||
* replace/replace_isnull. Comparisons are done using the specified
|
||||
* collation. fcinfo is passed only for caching purposes.
|
||||
*/
|
||||
static ArrayType *array_replace_internal(ArrayType *array, Datum search, bool search_isnull, Datum replace,
|
||||
bool replace_isnull, bool remove, Oid collation, FunctionCallInfo fcinfo)
|
||||
{
|
||||
|
||||
ArrayType *result = NULL;
|
||||
Oid element_type;
|
||||
Datum *values = NULL;
|
||||
bool *nulls = NULL;
|
||||
int *dim = NULL;
|
||||
int ndim;
|
||||
int nitems;
|
||||
int nresult;
|
||||
int i;
|
||||
int32 nbytes = 0;
|
||||
int32 dataoffset;
|
||||
bool hasnulls = false;
|
||||
int typlen;
|
||||
bool typbyval = false;
|
||||
char typalign;
|
||||
char *arraydataptr = NULL;
|
||||
bits8 *bitmap = NULL;
|
||||
int bitmask;
|
||||
bool changed = false;
|
||||
TypeCacheEntry *typentry = NULL;
|
||||
FunctionCallInfoData locfcinfo;
|
||||
errno_t rc = EOK;
|
||||
|
||||
element_type = ARR_ELEMTYPE(array);
|
||||
ndim = ARR_NDIM(array);
|
||||
dim = ARR_DIMS(array);
|
||||
nitems = ArrayGetNItems(ndim, dim);
|
||||
/* Return input array unmodified if it is empty */
|
||||
if (nitems <= 0)
|
||||
return array;
|
||||
/*
|
||||
* We can't remove elements from multi-dimensional arrays, since the
|
||||
* result might not be rectangular.
|
||||
*/
|
||||
if (remove && ndim > 1)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("removing elements from multidimensional arrays is not supported")));
|
||||
/*
|
||||
* We arrange to look up the equality function only once per series of
|
||||
* calls, assuming the element type doesn't change underneath us.
|
||||
*/
|
||||
typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
|
||||
if (typentry == NULL || typentry->type_id != element_type) {
|
||||
typentry = lookup_type_cache(element_type, TYPECACHE_EQ_OPR_FINFO);
|
||||
if (!OidIsValid(typentry->eq_opr_finfo.fn_oid))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("could not identify an equality operator for type %s",
|
||||
format_type_be(element_type))));
|
||||
fcinfo->flinfo->fn_extra = (void *) typentry;
|
||||
}
|
||||
typlen = typentry->typlen;
|
||||
typbyval = typentry->typbyval;
|
||||
typalign = typentry->typalign;
|
||||
/*
|
||||
* Detoast values if they are toasted. The replacement value must be
|
||||
* detoasted for insertion into the result array, while detoasting the
|
||||
* search value only once saves cycles.
|
||||
*/
|
||||
if (typlen == -1) {
|
||||
if (!search_isnull)
|
||||
search = PointerGetDatum(PG_DETOAST_DATUM(search));
|
||||
if (!replace_isnull)
|
||||
replace = PointerGetDatum(PG_DETOAST_DATUM(replace));
|
||||
}
|
||||
/* Prepare to apply the comparison operator */
|
||||
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2, collation, NULL, NULL);
|
||||
/* directly return if search is same as replace */
|
||||
if (!remove && array_same_replace(&locfcinfo, search, search_isnull, replace, replace_isnull)) {
|
||||
return array;
|
||||
}
|
||||
/* Allocate temporary arrays for new values */
|
||||
values = (Datum *) palloc(nitems * sizeof(Datum));
|
||||
nulls = (bool *) palloc(nitems * sizeof(bool));
|
||||
/* Loop over source data */
|
||||
arraydataptr = ARR_DATA_PTR(array);
|
||||
bitmap = ARR_NULLBITMAP(array);
|
||||
bitmask = 1;
|
||||
hasnulls = false;
|
||||
nresult = 0;
|
||||
for (i = 0; i < nitems; i++) {
|
||||
Datum elt;
|
||||
bool isNull = false;
|
||||
bool oprresult = false;
|
||||
bool skip = false;
|
||||
/* Get source element, checking for NULL */
|
||||
if (bitmap && (*bitmap & bitmask) == 0) {
|
||||
isNull = true;
|
||||
/* If searching for NULL, we have a match */
|
||||
if (search_isnull) {
|
||||
if (remove) {
|
||||
skip = true;
|
||||
changed = true;
|
||||
} else if (!replace_isnull) {
|
||||
values[nresult] = replace;
|
||||
isNull = false;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
isNull = false;
|
||||
elt = fetch_att(arraydataptr, typbyval, typlen);
|
||||
arraydataptr = att_addlength_datum(arraydataptr, typlen, elt);
|
||||
arraydataptr = (char *) att_align_nominal(arraydataptr, typalign);
|
||||
if (search_isnull) {
|
||||
/* no match possible, keep element */
|
||||
values[nresult] = elt;
|
||||
} else {
|
||||
/* Compare the pair of elements */
|
||||
locfcinfo.arg[0] = elt;
|
||||
locfcinfo.arg[1] = search;
|
||||
locfcinfo.argnull[0] = false;
|
||||
locfcinfo.argnull[1] = false;
|
||||
locfcinfo.isnull = false;
|
||||
oprresult = DatumGetBool(FunctionCallInvoke(&locfcinfo));
|
||||
if (locfcinfo.isnull || !oprresult) {
|
||||
/* no match, keep element */
|
||||
values[nresult] = elt;
|
||||
} else {
|
||||
/* match, so replace or delete */
|
||||
changed = true;
|
||||
if (remove) {
|
||||
skip = true;
|
||||
} else {
|
||||
values[nresult] = replace;
|
||||
isNull = replace_isnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!skip) {
|
||||
nulls[nresult] = isNull;
|
||||
if (isNull) {
|
||||
hasnulls = true;
|
||||
} else {
|
||||
/* Update total result size */
|
||||
nbytes = att_addlength_datum(nbytes, typlen, values[nresult]);
|
||||
nbytes = att_align_nominal(nbytes, typalign);
|
||||
/* check for overflow of total request */
|
||||
if (!AllocSizeIsValid(nbytes))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||
errmsg("array size exceeds the maximum allowed (%d)",
|
||||
(int) MaxAllocSize)));
|
||||
}
|
||||
nresult++;
|
||||
}
|
||||
/* advance bitmap pointer if any */
|
||||
if (bitmap) {
|
||||
bitmask <<= 1;
|
||||
if (bitmask == 0x100) {
|
||||
bitmap++;
|
||||
bitmask = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If not changed just return the original array
|
||||
*/
|
||||
if (!changed) {
|
||||
pfree(values);
|
||||
pfree(nulls);
|
||||
return array;
|
||||
}
|
||||
/* If all elements were removed return an empty array */
|
||||
if (nresult == 0) {
|
||||
pfree(values);
|
||||
pfree(nulls);
|
||||
return construct_empty_array(element_type);
|
||||
}
|
||||
/* Allocate and initialize the result array */
|
||||
if (hasnulls) {
|
||||
dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nresult);
|
||||
nbytes += dataoffset;
|
||||
} else {
|
||||
dataoffset = 0; /* marker for no null bitmap */
|
||||
nbytes += ARR_OVERHEAD_NONULLS(ndim);
|
||||
}
|
||||
result = (ArrayType *) palloc0(nbytes);
|
||||
SET_VARSIZE(result, nbytes);
|
||||
result->ndim = ndim;
|
||||
result->dataoffset = dataoffset;
|
||||
result->elemtype = element_type;
|
||||
rc = memcpy_s(ARR_DIMS(result), nbytes - sizeof(ArrayType), ARR_DIMS(array), ndim * sizeof(int));
|
||||
securec_check(rc, "\0", "\0");
|
||||
rc = memcpy_s(ARR_LBOUND(result), nbytes - (sizeof(ArrayType) + sizeof(int) * ndim),
|
||||
ARR_LBOUND(array), ndim * sizeof(int));
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
if (remove) {
|
||||
/* Adjust the result length */
|
||||
ARR_DIMS(result)[0] = nresult;
|
||||
}
|
||||
/* Insert data into result array */
|
||||
CopyArrayEls(result, values, nulls, nresult, typlen, typbyval, typalign, false);
|
||||
pfree(values);
|
||||
pfree(nulls);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove any occurrences of an element from an array
|
||||
*
|
||||
* If used on a multi-dimensional array this will raise an error.
|
||||
*/
|
||||
Datum array_remove(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *array = NULL;
|
||||
Datum search = PG_GETARG_DATUM(1);
|
||||
bool search_isnull = PG_ARGISNULL(1);
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
array = PG_GETARG_ARRAYTYPE_P(0);
|
||||
array = array_replace_internal(array, search, search_isnull, (Datum) 0, true, true, PG_GET_COLLATION(), fcinfo);
|
||||
PG_RETURN_ARRAYTYPE_P(array);
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace any occurrences of an element in an array
|
||||
*/
|
||||
Datum array_replace(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *array = NULL;
|
||||
Datum search = PG_GETARG_DATUM(1);
|
||||
bool search_isnull = PG_ARGISNULL(1);
|
||||
Datum replace = PG_GETARG_DATUM(2);
|
||||
bool replace_isnull = PG_ARGISNULL(2);
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
array = PG_GETARG_ARRAYTYPE_P(0);
|
||||
array = array_replace_internal(array, search, search_isnull, replace, replace_isnull, false, PG_GET_COLLATION(),
|
||||
fcinfo);
|
||||
PG_RETURN_ARRAYTYPE_P(array);
|
||||
}
|
||||
|
||||
/*
|
||||
* The type, dimension needs to be checked during collection operations.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -32,4 +32,4 @@ Datum first_transition(PG_FUNCTION_ARGS)
|
|||
Datum last_transition(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_DATUM(PG_GETARG_DATUM(1));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4601,10 +4601,12 @@ static void set_deparse_planstate(deparse_namespace* dpns, PlanState* ps)
|
|||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
if (IsA(ps, ModifyTableState))
|
||||
dpns->inner_tlist = ((ModifyTableState*)ps)->mt_upsert->us_excludedtlist;
|
||||
else
|
||||
#else
|
||||
if (IsA(ps, ModifyTableState) && ((ModifyTableState*)ps)->mt_upsert != NULL &&
|
||||
((ModifyTableState*)ps)->mt_upsert->us_action != UPSERT_NONE)
|
||||
#endif
|
||||
if (dpns->inner_planstate != NULL)
|
||||
dpns->inner_tlist = ((ModifyTableState*)ps)->mt_upsert->us_excludedtlist;
|
||||
else if (dpns->inner_planstate != NULL)
|
||||
dpns->inner_tlist = dpns->inner_planstate->plan->targetlist;
|
||||
else
|
||||
dpns->inner_tlist = NIL;
|
||||
|
|
|
|||
|
|
@ -1006,7 +1006,7 @@ static bool check_cgroup_name(char** newval, void** extra, GucSource source)
|
|||
|
||||
p = *newval;
|
||||
|
||||
if (StringIsValid(p) && IS_PGXC_COORDINATOR && t_thrd.shemem_ptr_cxt.MyBEEntry &&
|
||||
if (StringIsValid(p) && IS_SERVICE_NODE && t_thrd.shemem_ptr_cxt.MyBEEntry &&
|
||||
(currentGucContext == PGC_SUSET || currentGucContext == PGC_USERSET)) {
|
||||
if (g_instance.wlm_cxt->gscgroup_init_done == 0)
|
||||
ereport(ERROR,
|
||||
|
|
@ -1035,7 +1035,7 @@ static bool check_cgroup_name(char** newval, void** extra, GucSource source)
|
|||
static void assign_cgroup_name(const char* newval, void* extra)
|
||||
{
|
||||
/* set "control_group" global variable */
|
||||
if (IS_PGXC_COORDINATOR && t_thrd.shemem_ptr_cxt.MyBEEntry && newval && *newval) {
|
||||
if (IS_SERVICE_NODE && t_thrd.shemem_ptr_cxt.MyBEEntry && newval && *newval) {
|
||||
if (g_instance.wlm_cxt->gscgroup_init_done == 0)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1796,7 +1796,7 @@ bool WLMIsSimpleQuery(const QueryDesc* queryDesc, bool force_control, bool isQue
|
|||
|
||||
g_wlm_params->use_planA = false;
|
||||
|
||||
if (IS_PGXC_DATANODE || (IS_PGXC_COORDINATOR && IsConnFromCoord()) ||
|
||||
if (COORDINATOR_NOT_SINGLE || (IS_SERVICE_NODE && IsConnFromCoord()) ||
|
||||
u_sess->attr.attr_resource.parctl_min_cost < 0) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1875,7 +1875,7 @@ bool WLMIsSimpleQuery(const QueryDesc* queryDesc, bool force_control, bool isQue
|
|||
*/
|
||||
bool WLMNeedTrackResource(const QueryDesc* queryDesc)
|
||||
{
|
||||
if ((!(IS_SINGLE_NODE || IS_PGXC_COORDINATOR)) || (IS_PGXC_COORDINATOR && IsConnFromCoord()) ||
|
||||
if (!IS_SERVICE_NODE || (IS_PGXC_COORDINATOR && IsConnFromCoord()) ||
|
||||
t_thrd.wlm_cxt.collect_info->sdetail.statement == NULL || !u_sess->attr.attr_resource.enable_resource_track ||
|
||||
u_sess->attr.attr_resource.resource_track_cost < 0 || u_sess->attr.attr_sql.enable_cluster_resize ||
|
||||
t_thrd.wlm_cxt.parctl_state.special) {
|
||||
|
|
@ -2929,7 +2929,7 @@ void WLMSwitchCGroup(void)
|
|||
}
|
||||
|
||||
/* simple query will skip the cgroup loading */
|
||||
if (IS_PGXC_COORDINATOR && (IsConnFromCoord() || t_thrd.wlm_cxt.parctl_state.simple)) {
|
||||
if (IS_SERVICE_NODE && (IsConnFromCoord() || t_thrd.wlm_cxt.parctl_state.simple)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,6 +160,12 @@ List* check_op_list_template(Plan* result_plan, List* (*check_eval)(Node*))
|
|||
|
||||
res_list = list_concat_unique(res_list, check_eval((Node*)splan->resconstantqual));
|
||||
} break;
|
||||
case T_ModifyTable: {
|
||||
ModifyTable* splan = (ModifyTable*)result_plan;
|
||||
if (splan->upsertAction == UPSERT_UPDATE && splan->updateTlist != NULL) {
|
||||
res_list = list_concat_unique(res_list, check_eval((Node*)splan->updateTlist));
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6389,9 +6389,6 @@ void standard_ProcessUtility(Node* parse_tree, const char* query_string, ParamLi
|
|||
break;
|
||||
|
||||
case T_CreateResourcePoolStmt:
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
DISTRIBUTED_FEATURE_NOT_SUPPORTED();
|
||||
#endif
|
||||
if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) {
|
||||
char* first_exec_node = find_first_exec_cn();
|
||||
bool is_first_node = (strcmp(first_exec_node, g_instance.attr.attr_common.PGXCNodeName) == 0);
|
||||
|
|
@ -6448,9 +6445,6 @@ void standard_ProcessUtility(Node* parse_tree, const char* query_string, ParamLi
|
|||
break;
|
||||
|
||||
case T_AlterResourcePoolStmt:
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
DISTRIBUTED_FEATURE_NOT_SUPPORTED();
|
||||
#endif
|
||||
if (IS_PGXC_COORDINATOR) {
|
||||
char* first_exec_node = find_first_exec_cn();
|
||||
bool is_first_node = (strcmp(first_exec_node, g_instance.attr.attr_common.PGXCNodeName) == 0);
|
||||
|
|
@ -6471,9 +6465,6 @@ void standard_ProcessUtility(Node* parse_tree, const char* query_string, ParamLi
|
|||
break;
|
||||
|
||||
case T_DropResourcePoolStmt:
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
DISTRIBUTED_FEATURE_NOT_SUPPORTED();
|
||||
#endif
|
||||
if (IS_PGXC_COORDINATOR) {
|
||||
char* first_exec_node = find_first_exec_cn();
|
||||
bool is_first_node = (strcmp(first_exec_node, g_instance.attr.attr_common.PGXCNodeName) == 0);
|
||||
|
|
|
|||
|
|
@ -1565,6 +1565,10 @@ bool ExecCheckIndexConstraints(TupleTableSlot *slot, EState *estate, Relation ta
|
|||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("INSERT ON DUPLICATE KEY UPDATE does not support deferrable"
|
||||
" unique constraints/exclusion constraints.")));
|
||||
/*
|
||||
* We consider a partitioned table with a global index as a normal table,
|
||||
* because conflicts can be between multiple partitions.
|
||||
*/
|
||||
if (isPartitioned && !isgpi) {
|
||||
partitionedindexid = RelationGetRelid(indexRelation);
|
||||
|
||||
|
|
|
|||
|
|
@ -338,6 +338,10 @@ DATA(insert ( 3545 bytea_string_agg_transfn - bytea_string_agg_finalfn 0 2281 _
|
|||
DATA(insert ( 3124 json_agg_transfn - json_agg_finalfn 0 2281 _null_ _null_ n 0));
|
||||
DATA(insert ( 3403 json_object_agg_transfn - json_object_agg_finalfn 0 2281 _null_ _null_ n 0));
|
||||
|
||||
/* first last */
|
||||
DATA(insert ( 6560 first_transition - - 0 2283 _null_ _null_ n 0));
|
||||
DATA(insert ( 6561 last_transition - - 0 2283 _null_ _null_ n 0));
|
||||
|
||||
/* hll distribute agg */
|
||||
DATA(insert ( 4366 hll_add_trans0 hll_union_collect hll_pack 0 4370 _null_ _null_ n 0));
|
||||
#define HLL_ADD_TRANS0_OID 4366
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ typedef enum {
|
|||
#define IS_SINGLE_NODE (g_instance.role == VSINGLENODE)
|
||||
#define REMOTE_CONN_TYPE u_sess->attr.attr_common.remoteConnType
|
||||
#define COORDINATOR_NOT_SINGLE (g_instance.role == VDATANODE && g_instance.role != VSINGLENODE)
|
||||
#define IS_SERVICE_NODE (g_instance.role == VCOORDINATOR || g_instance.role == VSINGLENODE)
|
||||
|
||||
#define IsConnFromApp() (u_sess->attr.attr_common.remoteConnType == REMOTE_CONN_APP)
|
||||
#define IsConnFromCoord() (u_sess->attr.attr_common.remoteConnType == REMOTE_CONN_COORD)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
select oid, * from pg_proc where proname in ('first', 'first_transition', 'last', 'last_transition') order by oid;
|
||||
oid | proname | pronamespace | proowner | prolang | procost | prorows | provariadic | protransform | proisagg | proiswindow | prosecdef | proleakproof | proisstrict | proretset | provolatile | pronargs | pronargdefaults | prorettype | proargtypes | proallargtypes | proargmodes | proargnames | proargdefaults | prosrc | probin | proconfig | proacl | prodefaultargpos | fencedmode | proshippable | propackage | prokind | proargsrc | propackageid | proisprivate | proargtypesext | prodefaultargposext
|
||||
------+------------------+--------------+----------+---------+---------+---------+-------------+--------------+----------+-------------+-----------+--------------+-------------+-----------+-------------+----------+-----------------+------------+-------------+----------------+-------------+-------------+----------------+------------------+--------+-----------+--------+------------------+------------+--------------+------------+---------+-----------+--------------+--------------+----------------+---------------------
|
||||
6558 | first_transition | 11 | 10 | 12 | 1 | 0 | 0 | - | f | f | f | f | t | f | i | 2 | 0 | 2283 | 2283 2283 | | | | | first_transition | | | | | f | | f | f | | 0 | f | |
|
||||
6559 | last_transition | 11 | 10 | 12 | 1 | 0 | 0 | - | f | f | f | f | t | f | i | 2 | 0 | 2283 | 2283 2283 | | | | | last_transition | | | | | f | | f | f | | 0 | f | |
|
||||
6560 | first | 11 | 10 | 12 | 1 | 0 | 0 | - | t | f | f | f | f | f | i | 1 | 0 | 2283 | 2283 | | | | | aggregate_dummy | | | | | f | | f | f | | 0 | f | |
|
||||
6561 | last | 11 | 10 | 12 | 1 | 0 | 0 | - | t | f | f | f | f | f | i | 1 | 0 | 2283 | 2283 | | | | | aggregate_dummy | | | | | f | | f | f | | 0 | f | |
|
||||
oid | proname | pronamespace | proowner | prolang | procost | prorows | provariadic | protransform | proisagg | proiswindow | prosecdef | proleakproof | proisstrict | proretset | provolatile | pronargs | pronargdefaults | prorettype | proargtypes | proallargtypes | proargmodes | proargnames | proargdefaults | prosrc | probin | proconfig | proacl | prodefaultargpos | fencedmode | proshippable | propackage | prokind | proargsrc | propackageid | proisprivate | proargtypesext | prodefaultargposext | allargtypes | allargtypesext
|
||||
------+------------------+--------------+----------+---------+---------+---------+-------------+--------------+----------+-------------+-----------+--------------+-------------+-----------+-------------+----------+-----------------+------------+-------------+----------------+-------------+-------------+----------------+------------------+--------+-----------+--------+------------------+------------+--------------+------------+---------+-----------+--------------+--------------+----------------+---------------------+-------------+----------------
|
||||
6558 | first_transition | 11 | 10 | 12 | 1 | 0 | 0 | - | f | f | f | f | t | f | i | 2 | 0 | 2283 | 2283 2283 | | | | | first_transition | | | | | f | | f | f | | 0 | f | | | 2283 2283 |
|
||||
6559 | last_transition | 11 | 10 | 12 | 1 | 0 | 0 | - | f | f | f | f | t | f | i | 2 | 0 | 2283 | 2283 2283 | | | | | last_transition | | | | | f | | f | f | | 0 | f | | | 2283 2283 |
|
||||
6560 | first | 11 | 10 | 12 | 1 | 0 | 0 | - | t | f | f | f | f | f | i | 1 | 0 | 2283 | 2283 | | | | | aggregate_dummy | | | | | f | | f | f | | 0 | f | | | 2283 |
|
||||
6561 | last | 11 | 10 | 12 | 1 | 0 | 0 | - | t | f | f | f | f | f | i | 1 | 0 | 2283 | 2283 | | | | | aggregate_dummy | | | | | f | | f | f | | 0 | f | | | 2283 |
|
||||
(4 rows)
|
||||
|
||||
create table first_last_test(a int, b int, c int, d int);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,27 @@ INSERT INTO newproducts_row SELECT * FROM newproducts_base;
|
|||
ANALYZE products_row;
|
||||
ANALYZE newproducts_row;
|
||||
-- explain verbose
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
MERGE INTO products_row p
|
||||
USING newproducts_row np
|
||||
ON p.product_id = np.product_id
|
||||
WHEN MATCHED THEN
|
||||
UPDATE SET product_name = np.product_name, category = np.category, total = np.total where np.product_id = 5;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Merge on mergeinto_1.products_row p
|
||||
Update Cond: (p.product_id = 5)
|
||||
-> Hash Join
|
||||
Output: np.product_id, np.product_name, np.category, np.total, p.product_id, p.product_name, p.category, p.total, p.ctid, np.ctid
|
||||
Hash Cond: (p.product_id = np.product_id)
|
||||
-> Seq Scan on mergeinto_1.products_row p
|
||||
Output: p.product_id, p.product_name, p.category, p.total, p.ctid
|
||||
-> Hash
|
||||
Output: np.product_id, np.product_name, np.category, np.total, np.ctid
|
||||
-> Seq Scan on mergeinto_1.newproducts_row np
|
||||
Output: np.product_id, np.product_name, np.category, np.total, np.ctid
|
||||
(11 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
MERGE INTO products_row p
|
||||
USING newproducts_row np
|
||||
|
|
@ -59,26 +80,19 @@ WHEN MATCHED THEN
|
|||
UPDATE SET product_name = np.product_name, category = np.category, total = np.total
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT VALUES (np.product_id, np.product_name, np.category, np.total);
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Streaming (type: GATHER)
|
||||
Node/s: All datanodes
|
||||
-> Merge on mergeinto_1.products_row p
|
||||
-> Streaming(type: REDISTRIBUTE)
|
||||
Output: np.product_id, np.product_name, np.category, np.total, p.product_id, p.product_name, p.category, p.total, p.ctid, p.xc_node_id, np.ctid, (CASE WHEN (p.ctid IS NULL) THEN np.product_id ELSE p.product_id END)
|
||||
Distribute Key: (CASE WHEN (p.ctid IS NULL) THEN np.product_id ELSE p.product_id END)
|
||||
Spawn on: All datanodes
|
||||
Consumer Nodes: All datanodes
|
||||
-> Nested Loop Left Join
|
||||
Output: np.product_id, np.product_name, np.category, np.total, p.product_id, p.product_name, p.category, p.total, p.ctid, p.xc_node_id, np.ctid, CASE WHEN (p.ctid IS NULL) THEN np.product_id ELSE p.product_id END
|
||||
Join Filter: (p.product_id = np.product_id)
|
||||
-> Seq Scan on mergeinto_1.newproducts_row np
|
||||
Output: np.product_id, np.product_name, np.category, np.total, np.ctid
|
||||
Distribute Key: np.product_id
|
||||
-> Seq Scan on mergeinto_1.products_row p
|
||||
Output: p.product_id, p.product_name, p.category, p.total, p.ctid, p.xc_node_id
|
||||
Distribute Key: p.product_id
|
||||
(17 rows)
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Merge on mergeinto_1.products_row p
|
||||
-> Hash Right Join
|
||||
Output: np.product_id, np.product_name, np.category, np.total, p.product_id, p.product_name, p.category, p.total, p.ctid, np.ctid
|
||||
Hash Cond: (p.product_id = np.product_id)
|
||||
-> Seq Scan on mergeinto_1.products_row p
|
||||
Output: p.product_id, p.product_name, p.category, p.total, p.ctid
|
||||
-> Hash
|
||||
Output: np.product_id, np.product_name, np.category, np.total, np.ctid
|
||||
-> Seq Scan on mergeinto_1.newproducts_row np
|
||||
Output: np.product_id, np.product_name, np.category, np.total, np.ctid
|
||||
(10 rows)
|
||||
|
||||
-- only MATCHED clause
|
||||
MERGE INTO products_row p
|
||||
|
|
|
|||
|
|
@ -1456,6 +1456,12 @@ WHERE d.classoid IS NULL AND p1.oid <= 9999 order by 1;
|
|||
6422 | numeric
|
||||
6433 | numeric
|
||||
6434 | numeric_bool
|
||||
6555 | array_remove
|
||||
6556 | array_replace
|
||||
6558 | first_transition
|
||||
6559 | last_transition
|
||||
6560 | first
|
||||
6561 | last
|
||||
6666 | network_larger
|
||||
6667 | network_smaller
|
||||
6668 | max
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ create table pkt (a int primary key, b int, c int);
|
|||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pkt_pkey" for table "pkt"
|
||||
create table fkt (a int primary key, b int references pkt, c int);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "fkt_pkey" for table "fkt"
|
||||
create table up_neg_11(c1 int, c2 int) partition by range(c1)(partition p1 values less than(10), partition p2 values less than(maxvalue));
|
||||
create unique index index_up_neg_11 on up_neg_11(c2);
|
||||
-- procedure test
|
||||
CREATE SCHEMA upsert_test_procedure;
|
||||
-- explain test
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ insert into up_neg_07 select a,a,a from generate_series(1,20) as a;
|
|||
insert into up_neg_08 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_09 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_10 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_11 values(1,1),(2,2),(11,11),(12,12);
|
||||
-- table cases
|
||||
---- col table
|
||||
insert into up_neg_01 values(1,2,3) on duplicate key update c3 = 1;
|
||||
|
|
@ -103,12 +104,6 @@ insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c4 = 1 from up_n
|
|||
ERROR: syntax error at or near "from"
|
||||
LINE 1: ... values(1,1,1,1,1) on duplicate key update c4 = 1 from up_ne...
|
||||
^
|
||||
---- sub query
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update (c2) = (select c2 from up_neg_05);
|
||||
ERROR: Update with subquery is not yet supported whithin INSERT ON DUPLICATE KEY UPDATE statement.
|
||||
---- update distribute key
|
||||
insert into up_neg_06 values(101, 1, 1) on duplicate key update c3=101;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
---- update partition key
|
||||
insert into up_neg_07 values(101, 1, 300) on duplicate key update c3=101;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
|
|
@ -120,6 +115,22 @@ insert into up_neg_09 values(101, 1, 1) on duplicate key update c2=101;
|
|||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c2 =1,c3=101;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
---- cross-partition upsert
|
||||
insert into up_neg_11 values(1, 1) on duplicate key update c1 = 15;
|
||||
select * from up_neg_11 partition(p1);
|
||||
c1 | c2
|
||||
----+----
|
||||
2 | 2
|
||||
(1 row)
|
||||
|
||||
select * from up_neg_11 partition(p2);
|
||||
c1 | c2
|
||||
----+----
|
||||
11 | 11
|
||||
12 | 12
|
||||
15 | 1
|
||||
(3 rows)
|
||||
|
||||
--update unique key mul type plans
|
||||
EXPLAIN (VERBOSE on, COSTS off) insert into up_neg_10 values(101, 1, 300) on duplicate key update c1=101;
|
||||
QUERY PLAN
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ test: analyze_commands
|
|||
test: single_node_ddl
|
||||
test: single_node_sqlbypass
|
||||
#test: mediavarchar.cppn
|
||||
#test: array_funcs first_last_agg
|
||||
test: array_funcs first_last_agg
|
||||
test: get_instr_unique_sql
|
||||
|
||||
# run tablespace by itself, and first, because it forces a checkpoint;
|
||||
|
|
@ -165,8 +165,7 @@ test: single_node_sequence
|
|||
|
||||
# run and check forbidden functions are still forbidden to use in single node
|
||||
test: single_node_forbidden
|
||||
test: single_node_mergeinto
|
||||
#test: merge_1
|
||||
test: single_node_mergeinto merge_1
|
||||
|
||||
# Trigger tests
|
||||
test: single_node_triggers
|
||||
|
|
@ -332,7 +331,7 @@ test: upsert_001 upsert_002 upsert_003 upsert_008 upsert_009 upsert_010
|
|||
test: upsert_grammer_test_01 upsert_unlog_test upsert_tmp_test
|
||||
test: upsert_grammer_test_02 upsert_restriction upsert_composite
|
||||
test: upsert_trigger_test upsert_explain
|
||||
#test: upsert_subquery
|
||||
test: upsert_subquery
|
||||
test: upsert_clean
|
||||
|
||||
# all pass
|
||||
|
|
|
|||
|
|
@ -5158,7 +5158,7 @@ static void check_global_variables()
|
|||
}
|
||||
}
|
||||
|
||||
#define BASE_PGXC_LIKE_MACRO_NUM 1416
|
||||
#define BASE_PGXC_LIKE_MACRO_NUM 1415
|
||||
static void check_pgxc_like_macros()
|
||||
{
|
||||
#ifdef BUILD_BY_CMAKE
|
||||
|
|
|
|||
|
|
@ -64,6 +64,13 @@ ANALYZE products_row;
|
|||
ANALYZE newproducts_row;
|
||||
|
||||
-- explain verbose
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
MERGE INTO products_row p
|
||||
USING newproducts_row np
|
||||
ON p.product_id = np.product_id
|
||||
WHEN MATCHED THEN
|
||||
UPDATE SET product_name = np.product_name, category = np.category, total = np.total where np.product_id = 5;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
MERGE INTO products_row p
|
||||
USING newproducts_row np
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ create view up_view as select *from up_neg_01;
|
|||
create materialized view mat_view as select *from up_neg_01;
|
||||
create table pkt (a int primary key, b int, c int);
|
||||
create table fkt (a int primary key, b int references pkt, c int);
|
||||
|
||||
create table up_neg_11(c1 int, c2 int) partition by range(c1)(partition p1 values less than(10), partition p2 values less than(maxvalue));
|
||||
create unique index index_up_neg_11 on up_neg_11(c2);
|
||||
|
||||
-- procedure test
|
||||
CREATE SCHEMA upsert_test_procedure;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ insert into up_neg_07 select a,a,a from generate_series(1,20) as a;
|
|||
insert into up_neg_08 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_09 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_10 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_11 values(1,1),(2,2),(11,11),(12,12);
|
||||
|
||||
-- table cases
|
||||
---- col table
|
||||
|
|
@ -86,11 +87,6 @@ insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c1 =1, c2 = 1, c
|
|||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c4 = 1 where c1=1;
|
||||
---- from clause
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c4 = 1 from up_neg_04 where c1=1;
|
||||
---- sub query
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update (c2) = (select c2 from up_neg_05);
|
||||
|
||||
---- update distribute key
|
||||
insert into up_neg_06 values(101, 1, 1) on duplicate key update c3=101;
|
||||
---- update partition key
|
||||
insert into up_neg_07 values(101, 1, 300) on duplicate key update c3=101;
|
||||
insert into up_neg_08 values(101, 1, 300) on duplicate key update c3=101;
|
||||
|
|
@ -98,6 +94,11 @@ insert into up_neg_09 values(101, 1, 1) on duplicate key update c3=101;
|
|||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c2=101;
|
||||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c2 =1,c3=101;
|
||||
|
||||
---- cross-partition upsert
|
||||
insert into up_neg_11 values(1, 1) on duplicate key update c1 = 15;
|
||||
select * from up_neg_11 partition(p1);
|
||||
select * from up_neg_11 partition(p2);
|
||||
|
||||
--update unique key mul type plans
|
||||
EXPLAIN (VERBOSE on, COSTS off) insert into up_neg_10 values(101, 1, 300) on duplicate key update c1=101;
|
||||
insert into up_neg_10 values(101, 1, 300) on duplicate key update c3=101;
|
||||
|
|
|
|||
Loading…
Reference in New Issue