依据社区评审意见,修改代码
This commit is contained in:
@ -2800,6 +2800,7 @@ modify_column_cmd:
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ColId Typename ON_UPDATE_TIME UPDATE b_expr
|
||||
#ifndef ENBALE_MULTI_NODE
|
||||
{
|
||||
if (u_sess->attr.attr_sql.sql_compatibility == B_FORMAT)
|
||||
{
|
||||
@ -2828,6 +2829,7 @@ modify_column_cmd:
|
||||
$$ = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
| ColId NOT NULL_P opt_enable
|
||||
{
|
||||
AlterTableCmd *n = makeNode(AlterTableCmd);
|
||||
@ -6328,6 +6330,7 @@ ColConstraintElem:
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ON_UPDATE_TIME UPDATE b_expr
|
||||
#ifndef ENBALE_MULTI_NODE
|
||||
{
|
||||
if (u_sess->attr.attr_sql.sql_compatibility == B_FORMAT)
|
||||
{
|
||||
@ -6348,6 +6351,7 @@ ColConstraintElem:
|
||||
$$ = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
| GENERATED ALWAYS AS '(' a_expr ')' STORED
|
||||
{
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
|
||||
@ -10015,6 +10015,35 @@ static void ATExecSetNotNull(AlteredTableInfo* tab, Relation rel, const char* co
|
||||
heap_close(attr_rel, RowExclusiveLock);
|
||||
}
|
||||
|
||||
bool FetchOnUpdateExpress(Relation rel, char* colName)
|
||||
{
|
||||
HeapTuple htup = NULL;
|
||||
bool isnull = false;
|
||||
bool temp_on_update = FALSE;
|
||||
htup = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
|
||||
if (!HeapTupleIsValid(htup))
|
||||
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||
errmsg("column \"%s\" of relation \"%s\" does not exist", colName, RelationGetRelationName(rel))));
|
||||
Form_pg_attribute attTup = (Form_pg_attribute)GETSTRUCT(htup);
|
||||
AttrNumber temp_attnum = attTup->attnum;
|
||||
|
||||
ScanKeyData skey[2];
|
||||
Relation adrel = heap_open(AttrDefaultRelationId, RowExclusiveLock);
|
||||
ScanKeyInit(&skey[0], Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||
ScanKeyInit(&skey[1], Anum_pg_attrdef_adnum, BTEqualStrategyNumber, F_INT2EQ, Int16GetDatum(temp_attnum));
|
||||
SysScanDesc adscan = systable_beginscan(adrel, AttrDefaultIndexId, true, NULL, 2, skey);
|
||||
|
||||
if (HeapTupleIsValid(htup = systable_getnext(adscan))) {
|
||||
Datum val = heap_getattr(htup, Anum_pg_attrdef_adsrc_on_update, adrel->rd_att, &isnull);
|
||||
if (val && pg_strcasecmp(TextDatumGetCString(val), "") != 0) {
|
||||
temp_on_update = TRUE;
|
||||
}
|
||||
}
|
||||
systable_endscan(adscan);
|
||||
heap_close(adrel, RowExclusiveLock);
|
||||
return temp_on_update;
|
||||
}
|
||||
|
||||
/*
|
||||
* ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
|
||||
*/
|
||||
@ -10050,32 +10079,7 @@ static void ATExecColumnDefault(Relation rel, const char* colName, Node* newDefa
|
||||
errmsg("column \"%s\" of relation \"%s\" is a generated column", colName, RelationGetRelationName(rel))));
|
||||
}
|
||||
|
||||
HeapTuple htup = NULL;
|
||||
bool isnull = false;
|
||||
char* tempUpdateExpr = NULL;
|
||||
bool on_update = FALSE;
|
||||
htup = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
|
||||
if (!HeapTupleIsValid(htup))
|
||||
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||
errmsg("column \"%s\" of relation \"%s\" does not exist", colName, RelationGetRelationName(rel))));
|
||||
Form_pg_attribute attTup = (Form_pg_attribute)GETSTRUCT(htup);
|
||||
AttrNumber temp_attnum = attTup->attnum;
|
||||
|
||||
ScanKeyData skey[2];
|
||||
Relation adrel = heap_open(AttrDefaultRelationId, RowExclusiveLock);
|
||||
ScanKeyInit(&skey[0], Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||
ScanKeyInit(&skey[1], Anum_pg_attrdef_adnum, BTEqualStrategyNumber, F_INT2EQ, Int16GetDatum(temp_attnum));
|
||||
SysScanDesc adscan = systable_beginscan(adrel, AttrDefaultIndexId, true, NULL, 2, skey);
|
||||
|
||||
if (HeapTupleIsValid(htup = systable_getnext(adscan))) {
|
||||
Datum val = heap_getattr(htup, Anum_pg_attrdef_adsrc_on_update, adrel->rd_att, &isnull);
|
||||
if (val && pg_strcasecmp(TextDatumGetCString(val), "") != 0) {
|
||||
tempUpdateExpr = TextDatumGetCString(val);
|
||||
on_update = TRUE;
|
||||
}
|
||||
}
|
||||
systable_endscan(adscan);
|
||||
heap_close(adrel, RowExclusiveLock);
|
||||
bool on_update = FetchOnUpdateExpress(rel, colName);
|
||||
|
||||
/*
|
||||
* Remove any old default for the column. We use RESTRICT here for
|
||||
|
||||
@ -422,8 +422,7 @@ static bool GetUpdateExprCol(TupleDesc tupdesc, int atti)
|
||||
|
||||
static void RecoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, CmdType cmdtype)
|
||||
{
|
||||
Relation rel = resultRelInfo->ri_RelationDesc;
|
||||
TupleDesc tupdesc = RelationGetDescr(rel);
|
||||
TupleDesc tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
|
||||
int natts = tupdesc->natts;
|
||||
MemoryContext oldContext;
|
||||
|
||||
@ -446,8 +445,8 @@ static void RecoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, CmdT
|
||||
|
||||
expr = (Expr *)build_column_default(rel, i + 1, false, true);
|
||||
if (expr == NULL)
|
||||
elog(ERROR, "no update expression found for column number %d of table \"%s\"", i + 1,
|
||||
RelationGetRelationName(rel));
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("no update expression found for column number %d of table \"%s\"", i + 1,
|
||||
RelationGetRelationName(rel))));
|
||||
|
||||
resultRelInfo->ri_UpdatedExprs[i] = ExecPrepareExpr(expr, estate);
|
||||
resultRelInfo->ri_NumUpdatedNeeded++;
|
||||
@ -481,10 +480,6 @@ bool ExecComputeStoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, T
|
||||
int attnum;
|
||||
uint32 updated_colnum_resno;
|
||||
Bitmapset* updatedCols = GetUpdatedColumns(node->resultRelInfo, node->ps.state);
|
||||
HeapTuple oldtup = GetTupleForTrigger(estate, NULL, resultRelInfo, oldPartitionOid, bucketid, otid, LockTupleShared, NULL);
|
||||
|
||||
RecoredUpdateExpr(resultRelInfo, estate, cmdtype);
|
||||
|
||||
/*
|
||||
* If no generated columns have been affected by this change, then skip
|
||||
* the rest.
|
||||
@ -492,6 +487,10 @@ bool ExecComputeStoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, T
|
||||
if (resultRelInfo->ri_NumUpdatedNeeded == 0)
|
||||
return true;
|
||||
|
||||
HeapTuple oldtup = GetTupleForTrigger(estate, NULL, resultRelInfo, oldPartitionOid, bucketid, otid, LockTupleShared, NULL);
|
||||
|
||||
RecoredUpdateExpr(resultRelInfo, estate, cmdtype);
|
||||
|
||||
/* compare update operator whether the newtuple is equal to the oldtuple,
|
||||
* if equal, so update don't fix the default column value */
|
||||
Datum* oldvalues = (Datum*)palloc(natts * sizeof(Datum));
|
||||
@ -503,10 +502,6 @@ bool ExecComputeStoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, T
|
||||
temp_id = attnum;
|
||||
for (int32 i = 0; i < (int32)natts; i++) {
|
||||
if (updated_colnum_resno == (i + 1)) {
|
||||
Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
|
||||
opfuncoid = OpernameGetOprid(list_make1(makeString("=")), attr->atttypid, attr->atttypid);
|
||||
RegProcedure oprcode = get_opcode(opfuncoid);
|
||||
fmgr_info(oprcode, &eqproc);
|
||||
if (slot->tts_isnull[i] && oldnulls[i]) {
|
||||
match = true;
|
||||
} else if (slot->tts_isnull[i] && !oldnulls[i]) {
|
||||
@ -514,6 +509,10 @@ bool ExecComputeStoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, T
|
||||
} else if (!slot->tts_isnull[i] && oldnulls[i]) {
|
||||
match = false;
|
||||
} else {
|
||||
Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
|
||||
opfuncoid = OpernameGetOprid(list_make1(makeString("=")), attr->atttypid, attr->atttypid);
|
||||
RegProcedure oprcode = get_opcode(opfuncoid);
|
||||
fmgr_info(oprcode, &eqproc);
|
||||
match = DatumGetBool(FunctionCall2Coll(&eqproc, DEFAULT_COLLATION_OID, slot->tts_values[i], oldvalues[i]));
|
||||
}
|
||||
update_fix_result = update_fix_result && match;
|
||||
@ -534,8 +533,6 @@ bool ExecComputeStoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, T
|
||||
values = (Datum *)palloc(sizeof(*values) * natts);
|
||||
nulls = (bool *)palloc(sizeof(*nulls) * natts);
|
||||
replaces = (bool *)palloc0(sizeof(*replaces) * natts);
|
||||
rc = memset_s(replaces, sizeof(bool) * natts, 0, sizeof(bool) * natts);
|
||||
securec_check(rc, "\0", "\0");
|
||||
temp_id = -1;
|
||||
attnum = bms_next_member(updatedCols, temp_id);
|
||||
updated_colnum_resno = attnum + FirstLowInvalidHeapAttributeNumber;
|
||||
@ -553,7 +550,7 @@ bool ExecComputeStoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, T
|
||||
if (GetUpdateExprCol(tupdesc, i) && resultRelInfo->ri_UpdatedExprs[i]) {
|
||||
ExprContext *econtext;
|
||||
Datum val;
|
||||
bool isnull;
|
||||
bool isnull = false;
|
||||
|
||||
econtext = GetPerTupleExprContext(estate);
|
||||
econtext->ecxt_scantuple = slot;
|
||||
@ -2069,7 +2066,7 @@ TupleTableSlot* ExecUpdate(ItemPointer tupleid,
|
||||
LockTupleMode lockmode;
|
||||
|
||||
/* acquire Form_pg_attrdef ad_on_update */
|
||||
if (result_relation_desc->rd_att->constr && result_relation_desc->rd_att->constr->has_on_update && DB_IS_CMPT(B_FORMAT)) {
|
||||
if (result_relation_desc->rd_att->constr && result_relation_desc->rd_att->constr->has_on_update) {
|
||||
bool update_fix_result = ExecComputeStoredUpdateExpr(result_rel_info, estate, slot, tuple, CMD_UPDATE, node, tupleid, oldPartitionOid, bucketid);
|
||||
if (!update_fix_result) {
|
||||
tuple = slot->tts_tuple;
|
||||
|
||||
@ -29,7 +29,7 @@ typedef struct RawColumnDefault {
|
||||
AttrNumber attnum; /* attribute to attach default to */
|
||||
Node *raw_default; /* default value (untransformed parse tree) */
|
||||
char generatedCol; /* generated column setting */
|
||||
Node *update_expr = NULL;
|
||||
Node *update_expr;
|
||||
} RawColumnDefault;
|
||||
|
||||
typedef struct CookedConstraint {
|
||||
@ -42,7 +42,7 @@ typedef struct CookedConstraint {
|
||||
int inhcount; /* number of times constraint is inherited */
|
||||
bool is_no_inherit; /* constraint has local def and cannot be
|
||||
* inherited */
|
||||
Node *update_expr = NULL;
|
||||
Node *update_expr;
|
||||
} CookedConstraint;
|
||||
|
||||
typedef struct CeHeapInfo {
|
||||
|
||||
@ -1014,7 +1014,7 @@ typedef struct ColumnDef {
|
||||
Position *position;
|
||||
Form_pg_attribute dropped_attr; /* strcuture for dropped attribute during create table like OE */
|
||||
char generatedCol; /* generated column setting */
|
||||
Node *update_default = NULL;
|
||||
Node *update_default;
|
||||
} ColumnDef;
|
||||
|
||||
/*
|
||||
@ -1326,7 +1326,7 @@ typedef struct Constraint {
|
||||
InformationalConstraint *inforConstraint;
|
||||
char generated_when; /* ALWAYS or BY DEFAULT */
|
||||
char generated_kind; /* currently always STORED */
|
||||
Node *update_expr = NULL;
|
||||
Node *update_expr;
|
||||
} Constraint;
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user