已关闭
[Feat] code of pg identity as identity #9227
XXXCA创建于 5月6日关闭于 7月23日
[Feat] code of pg identity as identity #9227
已关闭
XXXCA创建于 5月6日关闭于 7月23日
共 113 个文件变更+3691-1518
@@ -2379,10 +2379,6 @@ static void ParsePgAttributeTupleData(binary tupdata, int len, binary nullBitmap
2379 "attcollation: %d",2379 "attcollation: %d",
2380 indents[indentLevel],2380 indents[indentLevel],
2381 (pgAttributeTupData->attcollation));2381 (pgAttributeTupData->attcollation));
2382- fprintf(stdout,
2383- "\n%s" "attkvtype: %d",
2384- indents[indentLevel],
2385- (pgAttributeTupData->attkvtype));
2386 2382 
2387#ifdef DEBUG2383#ifdef DEBUG
2388 int remain = len - ATTRIBUTE_FIXED_PART_SIZE;2384 int remain = len - ATTRIBUTE_FIXED_PART_SIZE;
@@ -1645,6 +1645,12 @@ static void JumbleExpr(pgssJumbleState* jstate, Node* node)
1645 APP_JUMB_STRING(ce->cursor_name);1645 APP_JUMB_STRING(ce->cursor_name);
1646 APP_JUMB(ce->cursor_param);1646 APP_JUMB(ce->cursor_param);
1647 } break;1647 } break;
1648+ case T_NextValueExpr: {
1649+ NextValueExpr* nve = (NextValueExpr*)node;
1650+ 
1651+ APP_JUMB(nve->seqid);
1652+ APP_JUMB(nve->typeId);
1653+ } break;
1648 case T_TargetEntry: {1654 case T_TargetEntry: {
1649 TargetEntry* tle = (TargetEntry*)node;1655 TargetEntry* tle = (TargetEntry*)node;
1650 1656 
@@ -545,7 +545,7 @@ Oid get_seq_id_from_tle(Query* query, TargetEntry* tle)
545 Relation rel = try_relation_open(rte->relid, AccessShareLock);545 Relation rel = try_relation_open(rte->relid, AccessShareLock);
546 if (rel->rd_rel->relkind == RELKIND_RELATION) {546 if (rel->rd_rel->relkind == RELKIND_RELATION) {
547 relation_close(rel, AccessShareLock);547 relation_close(rel, AccessShareLock);
548- return pg_get_serial_sequence_internal(rte->relid, var->varattno, true, NULL);548+ return getIdentitySequence(rte->relid, var->varattno, true, true);
549 } else if (rel->rd_rel->relkind == RELKIND_VIEW) {549 } else if (rel->rd_rel->relkind == RELKIND_VIEW) {
550 sub_query = get_view_query(rel);550 sub_query = get_view_query(rel);
551 } else if (rel->rd_rel->relkind == RELKIND_MATVIEW) {551 } else if (rel->rd_rel->relkind == RELKIND_MATVIEW) {
@@ -567,7 +567,7 @@ static Oid get_identity_seq_id(Oid tableOid)
567 Relation rel = try_relation_open(tableOid, AccessShareLock);567 Relation rel = try_relation_open(tableOid, AccessShareLock);
568 if (rel->rd_rel->relkind != RELKIND_VIEW && rel->rd_rel->relkind != RELKIND_MATVIEW) {568 if (rel->rd_rel->relkind != RELKIND_VIEW && rel->rd_rel->relkind != RELKIND_MATVIEW) {
569 relation_close(rel, AccessShareLock);569 relation_close(rel, AccessShareLock);
570- return get_table_identity(tableOid);570+ return getIdentitySequenceForD(tableOid, NULL, NULL);
571 }571 }
572 572 
573 Query* viewquery = rel->rd_rel->relkind == RELKIND_VIEW ? get_view_query(rel) : get_matview_query(rel);573 Query* viewquery = rel->rd_rel->relkind == RELKIND_VIEW ? get_view_query(rel) : get_matview_query(rel);
@@ -1224,26 +1224,12 @@ int get_is_compute(Oid rel_oid, char* colname)
1224 return is_compute;1224 return is_compute;
1225}1225}
1226 1226 
1227-int get_is_identity(Oid rel_oid, char* colname)1227+int get_is_identity(Oid relid, char* colname)
1228{1228{
1229- bool is_identity = false;1229+ Oid seqOid = InvalidOid;
1230- char* relname = get_rel_name(rel_oid);
1231 1230 
1232- bool isRetNull = false;1231+ seqOid = getIdentitySequenceForD(relid, colname, NULL);
1233- Datum result = DirectCall2(&isRetNull, pg_get_serial_sequence, InvalidOid,1232+ return OidIsValid(seqOid);
1234- CStringGetTextDatum(relname), CStringGetTextDatum(colname));
1235- if (isRetNull) {
1236- pfree_ext(relname);
1237- return 0;
1238- }
1239-
1240- char* seqname = text_to_cstring(DatumGetTextPP(result));
1241- if (StrEndWith(seqname, "_seq_identity")) {
1242- is_identity = true;
1243- }
1244- pfree_ext(relname);
1245- pfree_ext(seqname);
1246- return is_identity;
1247}1233}
1248 1234 
1249int get_is_hidden(Oid rel_oid, char* colname)1235int get_is_hidden(Oid rel_oid, char* colname)
@@ -28,7 +28,7 @@
28 */28 */
29%type <list> tsql_stmtmulti29%type <list> tsql_stmtmulti
30 30 
31-%type <list> identity_seed_increment31+%type <list> identity_seed_increment identity_seq_options
32%type <node> DBCCCheckIdentStmt DBCCStmt tsql_stmt tsql_CreateProcedureStmt tsql_IndexStmt tsql_TransactionStmt tsql_InsertStmt32%type <node> DBCCCheckIdentStmt DBCCStmt tsql_stmt tsql_CreateProcedureStmt tsql_IndexStmt tsql_TransactionStmt tsql_InsertStmt
33%type <node> tsql_UseStmt33%type <node> tsql_UseStmt
34%token <keyword> CATCH CHECKIDENT DBCC NO_INFOMSGS NORESEED RESEED SAVE TRAN TRY TSQL_CLUSTERED TSQL_NONCLUSTERED TSQL_COLUMNSTORE TSQL_PERSISTED TSQL_TOP TSQL_PERCENT34%token <keyword> CATCH CHECKIDENT DBCC NO_INFOMSGS NORESEED RESEED SAVE TRAN TRY TSQL_CLUSTERED TSQL_NONCLUSTERED TSQL_COLUMNSTORE TSQL_PERSISTED TSQL_TOP TSQL_PERCENT
@@ -646,8 +646,8 @@ tsql_subprogram_body: {
646ColConstraintElem: IDENTITY_P identity_seed_increment646ColConstraintElem: IDENTITY_P identity_seed_increment
647 {647 {
648 Constraint *n = makeNode(Constraint);648 Constraint *n = makeNode(Constraint);
649- n->contype = CONSTR_IDENTITY;649+ n->contype = CONSTR_D_IDENTITY;
650- n->generated_when = ATTRIBUTE_IDENTITY_ALWAYS;650+ n->generated_when = ATTRIBUTE_IDENTITY_D;
651 n->options = $2;651 n->options = $2;
652 n->location = @1;652 n->location = @1;
653 $$ = (Node *)n;653 $$ = (Node *)n;
@@ -778,6 +778,16 @@ identity_seed_increment:
778 $$ = list_make2(makeDefElem("start", (Node *)makeInteger(1)), makeDefElem("increment", (Node *)makeInteger(1)));778 $$ = list_make2(makeDefElem("start", (Node *)makeInteger(1)), makeDefElem("increment", (Node *)makeInteger(1)));
779 }779 }
780 ;780 ;
781+ 
782+identity_seq_options:
783+ identity_seed_increment { $$ = $1; }
784+ | '(' NumericOnly ',' NumericOnly ',' any_name ')'
785+ {
786+ $$ = list_make3(makeDefElem("start", (Node *)$2),
787+ makeDefElem("increment", (Node *)$4),
788+ makeDefElem("sequence_name", (Node *)$6));
789+ }
790+ 
781rotate_clause:791rotate_clause:
782 ROTATE '(' func_application_list rotate_for_clause rotate_in_clause ')' alias_clause %prec ROTATE792 ROTATE '(' func_application_list rotate_for_clause rotate_in_clause ')' alias_clause %prec ROTATE
783 {793 {
@@ -2137,6 +2147,7 @@ direct_label_keyword: ABORT_P
2137 | OUTER_P2147 | OUTER_P
2138 | OUTFILE2148 | OUTFILE
2139 | OVERLAY2149 | OVERLAY
2150+ | OVERRIDING
2140 | OWNED2151 | OWNED
2141 | OWNER2152 | OWNER
2142 | PACKAGE2153 | PACKAGE
@@ -2402,7 +2413,7 @@ direct_label_keyword: ABORT_P
2402 | UNTIL2413 | UNTIL
2403 | UNUSABLE2414 | UNUSABLE
2404 | UPDATE2415 | UPDATE
2405- | TSQL_UPDLOCK2416+ | TSQL_UPDLOCK
2406 | USE_P2417 | USE_P
2407 | USEEOF2418 | USEEOF
2408 | USER2419 | USER
@@ -3402,19 +3413,36 @@ tsql_UnsignedNumericOnly: Iconst { $$ = makeInteger($1); }
3402 | FCONST { $$ = makeFloat($1); }3413 | FCONST { $$ = makeFloat($1); }
3403 3414 
3404 3415 
3405- 
3406alter_table_cmd:3416alter_table_cmd:
3407- TSQL_CONVERT TO convert_charset opt_collate3417+ TSQL_CONVERT TO convert_charset opt_collate
3408- {3418+ {
3409- AlterTableCmd *n = makeNode(AlterTableCmd);3419+ AlterTableCmd *n = makeNode(AlterTableCmd);
3410- n->subtype = AT_ConvertCharset;3420+ n->subtype = AT_ConvertCharset;
3411- CharsetCollateOptions *cc = makeNode(CharsetCollateOptions);3421+ CharsetCollateOptions *cc = makeNode(CharsetCollateOptions);
3412- cc->cctype = OPT_CHARSETCOLLATE;3422+ cc->cctype = OPT_CHARSETCOLLATE;
3413- cc->charset = $3;3423+ cc->charset = $3;
3414- cc->collate = $4;3424+ cc->collate = $4;
3415- n->def = (Node *)cc;3425+ n->def = (Node *)cc;
3416- $$ = (Node*)n;3426+ $$ = (Node*)n;
3417- }3427+ }
3428+ /* ALTER TABLE <name> ALTER [COLUMN] <colname> ADD IDENTITY ... */
3429+ /* not document, only for gs_dump */
3430+ | ALTER opt_column ColId ADD_P IDENTITY_P identity_seq_options
3431+ {
3432+ AlterTableCmd *n = makeNode(AlterTableCmd);
3433+ Constraint *c = makeNode(Constraint);
3434+ 
3435+ c->contype = CONSTR_D_IDENTITY;
3436+ c->generated_when = ATTRIBUTE_IDENTITY_D;
3437+ c->options = $6;
3438+ c->location = @5;
3439+ 
3440+ n->subtype = AT_AddIdentity;
3441+ n->name = $3;
3442+ n->def = (Node *) c;
3443+ 
3444+ $$ = (Node *) n;
3445+ }
3418 ;3446 ;
3419 3447 
3420/* DATEDIFF() arguments3448/* DATEDIFF() arguments
@@ -519,6 +519,7 @@ PG_KEYWORD("output", TSQL_OUTPUT, UNRESERVED_KEYWORD, DIRECT_LABEL)
519PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD, AS_LABEL)519PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD, AS_LABEL)
520PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD, AS_LABEL)520PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD, AS_LABEL)
521PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD, DIRECT_LABEL)521PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD, DIRECT_LABEL)
522+PG_KEYWORD("overriding", OVERRIDING, UNRESERVED_KEYWORD, DIRECT_LABEL)
522PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD, DIRECT_LABEL)523PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD, DIRECT_LABEL)
523PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD, DIRECT_LABEL)524PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD, DIRECT_LABEL)
524PG_KEYWORD("package", PACKAGE, UNRESERVED_KEYWORD, DIRECT_LABEL)525PG_KEYWORD("package", PACKAGE, UNRESERVED_KEYWORD, DIRECT_LABEL)
@@ -5662,7 +5662,6 @@ stmt_execsql : K_ALTER
5662 {5662 {
5663 int tok = -1;5663 int tok = -1;
5664 bool FuncNoarg = false;5664 bool FuncNoarg = false;
5665- char* serverName = NULL;
5666 PLwdatum *objtypwdatum = NULL;5665 PLwdatum *objtypwdatum = NULL;
5667 PLwdatum objtypwdatumtemp;5666 PLwdatum objtypwdatumtemp;
5668 objtypwdatumtemp.datum = yylval.wdatum.datum;5667 objtypwdatumtemp.datum = yylval.wdatum.datum;
@@ -8954,7 +8953,8 @@ static void checkTypeName(List* nest_typnames, List* target_nest_typnames)
8954 bool found = false;8953 bool found = false;
8955 List* funcname = NIL;8954 List* funcname = NIL;
8956 FuncCandidateList clist = NULL;8955 FuncCandidateList clist = NULL;
8957- char *cp[3] = {0};8956+ const int SIZE = 3;
8957+ char *cp[SIZE] = {0};
8958 8958
8959 for (i = 0; i < target_nest_typnames->length; i++) {8959 for (i = 0; i < target_nest_typnames->length; i++) {
8960 if (target_ntype->layer == ntype->layer &&8960 if (target_ntype->layer == ntype->layer &&
@@ -8989,8 +8989,8 @@ static void checkTypeName(List* nest_typnames, List* target_nest_typnames)
8989 continue;8989 continue;
8990 }8990 }
8991 8991 
8992- plpgsql_parser_funcname(ntype->typname, cp, 3);8992+ plpgsql_parser_funcname(ntype->typname, cp, SIZE);
8993- for (int i = 0; i < (sizeof(cp) / sizeof(cp[0]) - 1) ; i++) {8993+ for (int i = 0; i < SIZE; i++) {
8994 if (cp[i] && cp[i][0] != '\0') {8994 if (cp[i] && cp[i][0] != '\0') {
8995 if (i != 0) {8995 if (i != 0) {
8996 funcname = list_make2(funcname, makeString(cp[i]));8996 funcname = list_make2(funcname, makeString(cp[i]));
@@ -9014,7 +9014,8 @@ static void checkTypeName(List* nest_typnames, List* target_nest_typnames)
9014 errno_t rc = snprintf_s(mes, length, length -1, "%s\"%s\"", report_mes, ntype->typname);9014 errno_t rc = snprintf_s(mes, length, length -1, "%s\"%s\"", report_mes, ntype->typname);
9015 securec_check_ss(rc, "", "");9015 securec_check_ss(rc, "", "");
9016 InsertErrorMessage(mes, plpgsql_yylloc);9016 InsertErrorMessage(mes, plpgsql_yylloc);
9017- ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg(mes)));9017+ ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT),
9018+ errmsg("Wrong type of expression, should not use type \"%s\"", ntype->typname)));
9018 }9019 }
9019}9020}
9020 9021 
@@ -9238,7 +9239,7 @@ static bool construct_object_type(StringInfo ds, ArrayParseContext *context, Typ
9238 return construct_array_start(ds, context, type, tok, parenlevel, loc);9239 return construct_array_start(ds, context, type, tok, parenlevel, loc);
9239 }9240 }
9240 if (type->typtyp == TYPTYPE_ABSTRACT_OBJECT)9241 if (type->typtyp == TYPTYPE_ABSTRACT_OBJECT)
9241- appendStringInfo(ds, name_str);9242+ appendStringInfoString(ds, name_str);
9242 else9243 else
9243 appendStringInfo(ds, "ROW");9244 appendStringInfo(ds, "ROW");
9244 pfree_ext(name_str);9245 pfree_ext(name_str);
@@ -9418,7 +9419,6 @@ read_sql_construct6(int until,
9418 ArrayParseContext context;9419 ArrayParseContext context;
9419 List *idents = 0;9420 List *idents = 0;
9420 List* nest_typnames = NIL;9421 List* nest_typnames = NIL;
9421- int comma_cnt = 0;
9422 int typname_indexs[MAX_LAYER] = {0};9422 int typname_indexs[MAX_LAYER] = {0};
9423 const char left_bracket[2] = "[";9423 const char left_bracket[2] = "[";
9424 const char right_bracket[2] = "]";9424 const char right_bracket[2] = "]";
@@ -9431,7 +9431,7 @@ read_sql_construct6(int until,
9431 int left_brace_count = 0;9431 int left_brace_count = 0;
9432 int right_brace_count = 0;9432 int right_brace_count = 0;
9433 bool stop_count = false;9433 bool stop_count = false;
9434- int stop_tok;9434+ int stop_tok = -1;
9435 bool record_typename = false;9435 bool record_typename = false;
9436 int bracket_diff=0;9436 int bracket_diff=0;
9437 /* mark if there are 2 table of index by var call functions in an expr */9437 /* mark if there are 2 table of index by var call functions in an expr */
@@ -14270,7 +14270,6 @@ static Oid plpgsql_build_anonymous_subtype(char* typname, PLpgSQL_type* newp, co
14270 Form_pg_type baseType;14270 Form_pg_type baseType;
14271 ObjectAddress referenced;14271 ObjectAddress referenced;
14272 PLpgSQL_type* res = NULL;14272 PLpgSQL_type* res = NULL;
14273- SubTypeRange* typerange = NULL;
14274 14273 
14275 /* check is typname too long */14274 /* check is typname too long */
14276 if (strlen(typname) >= NAMEDATALEN) {14275 if (strlen(typname) >= NAMEDATALEN) {
@@ -14385,7 +14384,7 @@ plpgsql_build_function_package_subtype(char* typname, PLpgSQL_type* newp, const
14385 char* pkgtypname = NULL;14384 char* pkgtypname = NULL;
14386 char* schamaname = NULL;14385 char* schamaname = NULL;
14387 Oid pkgoid = InvalidOid;14386 Oid pkgoid = InvalidOid;
14388- SubTypeRange* typerange = NULL;14387+
14389 char* casttypename = NULL;14388 char* casttypename = NULL;
14390 bool sameType = false;14389 bool sameType = false;
14391 14390 
@@ -14577,7 +14576,8 @@ check_labels(const char *start_label, const char *end_label, int end_location)
14577 ereport(errstate,14576 ereport(errstate,
14578 (errcode(ERRCODE_SYNTAX_ERROR),14577 (errcode(ERRCODE_SYNTAX_ERROR),
14579 errmsg("end label \"%s\" differs from block's label \"%s\"",14578 errmsg("end label \"%s\" differs from block's label \"%s\"",
14580- end_label, start_label),14579+ end_label == NULL ? "NULL" : end_label,
14580+ start_label == NULL ? "NULL" : start_label),
14581 parser_errposition(end_location)));14581 parser_errposition(end_location)));
14582 }14582 }
14583 }14583 }
@@ -4961,7 +4961,7 @@ int main(int argc, char* argv[])
4961 ss_mkdirdir(pg_data, vgdata, vglog, need_create_data);4961 ss_mkdirdir(pg_data, vgdata, vglog, need_create_data);
4962 } else {4962 } else {
4963 /* Create required subdirectories */4963 /* Create required subdirectories */
4964- printf(_("creating subdirectories ... in ordinary occasion"));4964+ printf(_("creating subdirectories ... in ordinary occasion "));
4965 (void)fflush(stdout);4965 (void)fflush(stdout);
4966 4966 
4967 for (i = 0; (unsigned int)(i) < lengthof(subdirs); i++) {4967 for (i = 0; (unsigned int)(i) < lengthof(subdirs); i++) {
@@ -893,6 +893,7 @@ bool raw_expression_tree_walker(Node* node, bool (*walker)(), void* context)
893 case T_ParamRef:893 case T_ParamRef:
894 case T_A_Const:894 case T_A_Const:
895 case T_A_Star:895 case T_A_Star:
896+ case T_NextValueExpr:
896 case T_Rownum:897 case T_Rownum:
897 /* primitive node types with no subnodes */898 /* primitive node types with no subnodes */
898 break;899 break;
@@ -178,6 +178,32 @@ const char* fmtId(const char* rawid)
178 return id_return->data;178 return id_return->data;
179}179}
180 180 
181+/*
182+ * fmtQualifiedId - construct a schema-qualified name, with quoting as needed.
183+ *
184+ * Like fmtId, use the result before calling again.
185+ *
186+ * Since we call fmtId and it also uses getLocalPQExpBuffer() we cannot
187+ * use that buffer until we're finished with calling fmtId().
188+ */
189+const char* fmtQualifiedId(const char *schema, const char *id)
190+{
191+ static PQExpBuffer id_return = NULL;
192+ 
193+ if (id_return != NULL) /* first time through? */
194+ resetPQExpBuffer(id_return);
195+ else
196+ id_return = createPQExpBuffer();
197+ 
198+ /* Suppress schema name if fetching from pre-7.3 DB */
199+ if (schema && *schema) {
200+ appendPQExpBuffer(id_return, "%s.", fmtId(schema));
201+ }
202+ appendPQExpBuffer(id_return, "%s", fmtId(id));
203+ 
204+ return id_return->data;
205+}
206+ 
181/*207/*
182 * Convert a string value to an SQL string literal and append it to208 * Convert a string value to an SQL string literal and append it to
183 * the given buffer. We assume the specified client_encoding and209 * the given buffer. We assume the specified client_encoding and
@@ -1797,6 +1823,29 @@ bool is_column_exists(PGconn* conn, Oid relid, const char* column_name)
1797 return isExists;1823 return isExists;
1798}1824}
1799 1825 
1826+bool StrEndWith(const char *str, const char *suffix)
1827+{
1828+ int strLen = strlen(str);
1829+ int suffixLen = strlen(suffix);
1830+ if (strLen < suffixLen) {
1831+ return false;
1832+ }
1833+ /* skip the rear digits */
1834+ int len = strLen - 1;
1835+ while (len >= 0 && isdigit(str[len])) {
1836+ --len;
1837+ }
1838+ if (len < 0 || len + 1 < suffixLen) {
1839+ return false;
1840+ }
1841+ for (int i = 0; i < suffixLen; i++) {
1842+ if (str[len - i] != suffix[suffixLen - 1 - i]) {
1843+ return false;
1844+ }
1845+ }
1846+ return true;
1847+}
1848+ 
1800#ifndef ENABLE_MULTIPLE_NODES1849#ifndef ENABLE_MULTIPLE_NODES
1801bool SetUppercaseAttributeNameToOff(PGconn* conn)1850bool SetUppercaseAttributeNameToOff(PGconn* conn)
1802{1851{
@@ -98,6 +98,7 @@ extern char* binary_upgrade_newowner;
98 98 
99extern void init_parallel_dump_utils(void);99extern void init_parallel_dump_utils(void);
100extern const char* fmtId(const char* identifier);100extern const char* fmtId(const char* identifier);
101+extern const char* fmtQualifiedId(const char* schema, const char* id);
101extern void appendStringLiteral(PQExpBuffer buf, const char* str, int encoding, bool std_strings);102extern void appendStringLiteral(PQExpBuffer buf, const char* str, int encoding, bool std_strings);
102extern void appendStringLiteralConn(PQExpBuffer buf, const char* str, PGconn* conn);103extern void appendStringLiteralConn(PQExpBuffer buf, const char* str, PGconn* conn);
103extern void appendStringLiteralDQ(PQExpBuffer buf, const char* str, const char* dqprefix);104extern void appendStringLiteralDQ(PQExpBuffer buf, const char* str, const char* dqprefix);
@@ -136,6 +137,7 @@ extern bool IsDir(const char* dirpath);
136extern char* make_absolute_path(const char* path);137extern char* make_absolute_path(const char* path);
137extern bool isExistsSQLResult(PGconn* conn, const char* sqlCmd);138extern bool isExistsSQLResult(PGconn* conn, const char* sqlCmd);
138extern bool is_column_exists(PGconn* conn, Oid relid, const char* column_name);139extern bool is_column_exists(PGconn* conn, Oid relid, const char* column_name);
140+extern bool StrEndWith(const char *str, const char *suffix);
139#ifndef ENABLE_MULTIPLE_NODES141#ifndef ENABLE_MULTIPLE_NODES
140extern bool SetUppercaseAttributeNameToOff(PGconn* conn);142extern bool SetUppercaseAttributeNameToOff(PGconn* conn);
141#endif143#endif
@@ -147,34 +147,8 @@ static void ShutdownWorkersHard(ParallelStateN* pstate);
147static void WaitForTerminatingWorkers(ParallelStateN* pstate);147static void WaitForTerminatingWorkers(ParallelStateN* pstate);
148static void sigTermHandler(SIGNAL_ARGS);148static void sigTermHandler(SIGNAL_ARGS);
149static void setup_cancel_handler(void);149static void setup_cancel_handler(void);
150-static const char* fmtQualifiedId(const char* schema, const char* id);
151static void archive_close_connection(int code, void* arg);150static void archive_close_connection(int code, void* arg);
152 151 
153-/*
154- * fmtQualifiedId - construct a schema-qualified name, with quoting as needed.
155- *
156- * Like fmtId, use the result before calling again.
157- *
158- * Since we call fmtId and it also uses getLocalPQExpBuffer() we cannot
159- * use that buffer until we're finished with calling fmtId().
160- */
161-static const char* fmtQualifiedId(const char* schema, const char* id)
162-{
163- static PQExpBuffer id_return = NULL;
164- 
165- if (id_return != NULL) /* first time through? */
166- resetPQExpBuffer(id_return);
167- else
168- id_return = createPQExpBuffer();
169- 
170- /* Suppress schema name if fetching from pre-7.3 DB */
171- if (schema != NULL && *schema) {
172- appendPQExpBuffer(id_return, "%s.", fmtId(schema));
173- }
174- appendPQExpBuffer(id_return, "%s", fmtId(id));
175- 
176- return id_return->data;
177-}
178/*152/*
179 * Find the ParallelSlotN for the current worker process or thread.153 * Find the ParallelSlotN for the current worker process or thread.
180 *154 *
@@ -252,16 +252,18 @@ typedef struct _tableInfo {
252 uint64 toast_frozenxid64; /* for restore toast frozen xid */252 uint64 toast_frozenxid64; /* for restore toast frozen xid */
253 int ncheck; /* # of CHECK expressions */253 int ncheck; /* # of CHECK expressions */
254 char* reloftype; /* underlying type for typed table */254 char* reloftype; /* underlying type for typed table */
255+ 
255 /* these two are set only if table is a sequence owned by a column: */256 /* these two are set only if table is a sequence owned by a column: */
256- Oid owning_tab; /* OID of table owning sequence */257+ Oid owning_tab; /* OID of table owning sequence */
257- int owning_col; /* attr # of column owning sequence */258+ int owningCol; /* attr # of column owning sequence */
259+ bool isIdentitySequence; /* used to dump internal sequence of identity column */
258 char parttype;260 char parttype;
259 bool relrowmovement;261 bool relrowmovement;
260- bool isIncremental; /* for matview, true if is an incremental type */262+ bool isIncremental; /* for matview, true if is an incremental type */
261 263 
262- int relpages; /* table's size in pages (from pg_class) */264+ int relpages; /* table's size in pages (from pg_class) */
263 265 
264- bool interesting; /* true if need to collect more data */266+ bool interesting; /* true if need to collect more data */
265 int autoinc_attnum;267 int autoinc_attnum;
266 DumpId autoincconstraint;268 DumpId autoincconstraint;
267 DumpId autoincindex;269 DumpId autoincindex;
@@ -289,6 +291,7 @@ typedef struct _tableInfo {
289 char* attstorage; /* attribute storage scheme */291 char* attstorage; /* attribute storage scheme */
290 char* typstorage; /* type storage scheme */292 char* typstorage; /* type storage scheme */
291 bool* attisdropped; /* true if attr is dropped; don't dump it */293 bool* attisdropped; /* true if attr is dropped; don't dump it */
294+ char* attidentity; /* identity attribute */
292 bool* attisblockchainhash; /* true if attr is "hash" column in blockchain table */295 bool* attisblockchainhash; /* true if attr is "hash" column in blockchain table */
293 int* attlen; /* attribute length, used by binary_upgrade */296 int* attlen; /* attribute length, used by binary_upgrade */
294 char* attalign; /* attribute align, used by binary_upgrade */297 char* attalign; /* attribute align, used by binary_upgrade */
@@ -299,6 +302,7 @@ typedef struct _tableInfo {
299 bool* notnull; /* NOT NULL constraints on attributes */302 bool* notnull; /* NOT NULL constraints on attributes */
300 bool* inhNotNull; /* true if NOT NULL is inherited */303 bool* inhNotNull; /* true if NOT NULL is inherited */
301 int* attkvtype; /* will not be 0 in timeseries table other wise 0 */304 int* attkvtype; /* will not be 0 in timeseries table other wise 0 */
305+ bool needsOverride; /* has GENERATED ALWAYS AS IDENTITY */
302 struct _attrDefInfo** attrdefs; /* DEFAULT expressions */306 struct _attrDefInfo** attrdefs; /* DEFAULT expressions */
303 struct _constraintInfo* checkexprs; /* CHECK constraints */307 struct _constraintInfo* checkexprs; /* CHECK constraints */
304 308 
@@ -2785,6 +2785,8 @@ bool SaveSqlModePipesAsConcat()
2785 initPQExpBuffer(&buf);2785 initPQExpBuffer(&buf);
2786 printfPQExpBuffer(&buf, "select setting from pg_settings where name = 'dolphin.sql_mode';");2786 printfPQExpBuffer(&buf, "select setting from pg_settings where name = 'dolphin.sql_mode';");
2787 res = PSQLexec(buf.data, false);2787 res = PSQLexec(buf.data, false);
2788+ termPQExpBuffer(&buf);
2789+ 
2788 if (res != NULL && PQntuples(res) == 1) {2790 if (res != NULL && PQntuples(res) == 1) {
2789 char* dolphinSqlMode = PQgetvalue(res, 0, 0);2791 char* dolphinSqlMode = PQgetvalue(res, 0, 0);
2790 /* already enable */2792 /* already enable */
@@ -2801,6 +2803,8 @@ bool SaveSqlModePipesAsConcat()
2801 res = NULL;2803 res = NULL;
2802 return true;2804 return true;
2803 }2805 }
2806+ 
2807+ PQclear(res);
2804 return false;2808 return false;
2805}2809}
2806 2810 
@@ -18,6 +18,7 @@
18#include "catalog/pg_class.h"18#include "catalog/pg_class.h"
19#include "catalog/pg_namespace.h"19#include "catalog/pg_namespace.h"
20#include "catalog/pg_default_acl.h"20#include "catalog/pg_default_acl.h"
21+#include "catalog/pg_attribute.h"
21#include "catalog/pg_attrdef.h"22#include "catalog/pg_attrdef.h"
22#include "catalog/pg_collation.h"23#include "catalog/pg_collation.h"
23#include "securec.h"24#include "securec.h"
@@ -537,7 +538,7 @@ bool describeTypes(const char* pattern, bool verbose, bool showSystem)
537 " CASE WHEN t.typtype = 's'\n"538 " CASE WHEN t.typtype = 's'\n"
538 " THEN pg_catalog.array_to_string(\n"539 " THEN pg_catalog.array_to_string(\n"
539 " ARRAY(\n"540 " ARRAY(\n"
540- " SELECT s.setlabel\n"541+ " SELECT s.setlabel\n"
541 " FROM pg_catalog.pg_set s\n"542 " FROM pg_catalog.pg_set s\n"
542 " WHERE s.settypid = t.oid\n"543 " WHERE s.settypid = t.oid\n"
543 " ORDER BY s.setsortorder\n"544 " ORDER BY s.setsortorder\n"
@@ -547,7 +548,7 @@ bool describeTypes(const char* pattern, bool verbose, bool showSystem)
547 appendPQExpBuffer(&buf,548 appendPQExpBuffer(&buf,
548 " pg_catalog.array_to_string(\n"549 " pg_catalog.array_to_string(\n"
549 " ARRAY(\n"550 " ARRAY(\n"
550- " SELECT e.enumlabel\n"551+ " SELECT e.enumlabel\n"
551 " FROM pg_catalog.pg_enum e\n"552 " FROM pg_catalog.pg_enum e\n"
552 " WHERE e.enumtypid = t.oid\n");553 " WHERE e.enumtypid = t.oid\n");
553 554 
@@ -1443,8 +1444,27 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
1443 PQExpBufferData tmpbuf;1444 PQExpBufferData tmpbuf;
1444 /* this is used for partition table */1445 /* this is used for partition table */
1445 PQExpBufferData tmp_part_buf;1446 PQExpBufferData tmp_part_buf;
1446- int cols;1447+ int cols = 0;
1448+ int colcnt = 0;
1447 int numrows = 0;1449 int numrows = 0;
1450+ int attnameCol = -1; /* column indexes in "res" */
1451+ int atttypeCol = -1;
1452+ int attrdefCol = -1;
1453+ int attnotnullCol = -1;
1454+ int attrNumCol = -1;
1455+ int attrdefUpdateCol = -1;
1456+ int attcollCol = -1;
1457+ int indexdefCol = -1;
1458+ int fdwoptsCol = -1;
1459+ int clientLogicOrgTypeCol = -1;
1460+ int clientLogicOrgTypeOidCol = -1;
1461+ int attidentityCol = -1;
1462+ int attgeneratedCol = -1;
1463+ int attstorageCol = -1;
1464+ int attstattargetCol = -1;
1465+ int attdescrCol = -1;
1466+ int attkvtypeCol = -1;
1467+ 
1448 int exprForNum = 128;1468 int exprForNum = 128;
1449 struct {1469 struct {
1450 int16 checks;1470 int16 checks;
@@ -1460,6 +1480,7 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
1460 char relpersistence;1480 char relpersistence;
1461 char relreplident;1481 char relreplident;
1462 } tableinfo;1482 } tableinfo;
1483+ 
1463 bool show_modifiers = false;1484 bool show_modifiers = false;
1464 bool retval = false;1485 bool retval = false;
1465 bool hasreplident = is_column_exists(pset.db, RelationRelationId, "relreplident");1486 bool hasreplident = is_column_exists(pset.db, RelationRelationId, "relreplident");
@@ -1511,7 +1532,6 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
1511 if (NULL == res) {1532 if (NULL == res) {
1512 goto error_return;1533 goto error_return;
1513 }1534 }
1514- 
1515 PQclear(res);1535 PQclear(res);
1516 res = NULL;1536 res = NULL;
1517 }1537 }
@@ -1683,38 +1703,49 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
1683 }1703 }
1684#endif1704#endif
1685 1705 
1686- printfPQExpBuffer(&buf, "SELECT a.attname,");1706+ printfPQExpBuffer(&buf, "SELECT a.attname");
1687- if (!hasOnUpdateFeature) {1707+ attnameCol = colcnt++;
1708+ appendPQExpBuffer(&buf, ",\n pg_catalog.format_type(a.atttypid, a.atttypmod) as atttype");
1709+ atttypeCol = colcnt++;
1710+ appendPQExpBuffer(&buf, ",\n (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for %d)"
1711+ " FROM pg_catalog.pg_attrdef d"
1712+ " WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef) as attdef",
1713+ exprForNum);
1714+ attrdefCol = colcnt++;
1715+ appendPQExpBuffer(&buf, ",\n a.attnotnull");
1716+ attnotnullCol = colcnt++;
1717+ appendPQExpBuffer(&buf, ",\n a.attnum");
1718+ attrNumCol = colcnt++;
1719+ 
1720+ if (hasOnUpdateFeature) {
1688 appendPQExpBuffer(&buf,1721 appendPQExpBuffer(&buf,
1689- "\n pg_catalog.format_type(a.atttypid, a.atttypmod),"1722+ ",\n (SELECT substring(pg_catalog.pg_get_expr(d.adbin_on_update, d.adrelid) for %d)"
1690- "\n (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for %d)"1723+ " FROM pg_catalog.pg_attrdef d"
1691- "\n FROM pg_catalog.pg_attrdef d"1724+ " WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef) as attdefupdate",
1692- "\n WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),"1725+ exprForNum);
1693- "\n a.attnotnull, a.attnum,", exprForNum);
1694 } else {1726 } else {
1695 appendPQExpBuffer(&buf,1727 appendPQExpBuffer(&buf,
1696- "\n pg_catalog.format_type(a.atttypid, a.atttypmod),"1728+ ",\n ''::text as attdefupdate");
1697- "\n (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for %d)"
1698- "\n FROM pg_catalog.pg_attrdef d"
1699- "\n WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),"
1700- "\n (SELECT substring(pg_catalog.pg_get_expr(d.adbin_on_update, d.adrelid) for %d)"
1701- "\n FROM pg_catalog.pg_attrdef d"
1702- "\n WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),"
1703- "\n a.attnotnull, a.attnum,", exprForNum, exprForNum);
1704 }1729 }
1730+ attrdefUpdateCol = colcnt++;
1731+ 
1705 if (pset.sversion >= 90100) {1732 if (pset.sversion >= 90100) {
1706 appendPQExpBuffer(&buf,1733 appendPQExpBuffer(&buf,
1707- "\n (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t\n"1734+ ",\n (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t\n"
1708 " WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS "1735 " WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS "
1709 "attcollation");1736 "attcollation");
1710 } else {1737 } else {
1711- appendPQExpBuffer(&buf, "\n NULL AS attcollation");1738+ appendPQExpBuffer(&buf, ",\n NULL AS attcollation");
1712 }1739 }
1740+ attcollCol = colcnt++;
1741+ 
1713 if (tableinfo.relkind == 'i' || tableinfo.relkind == 'I') {1742 if (tableinfo.relkind == 'i' || tableinfo.relkind == 'I') {
1714 appendPQExpBuffer(&buf, ",\n pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE) AS indexdef");1743 appendPQExpBuffer(&buf, ",\n pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE) AS indexdef");
1715 } else {1744 } else {
1716 appendPQExpBuffer(&buf, ",\n NULL AS indexdef");1745 appendPQExpBuffer(&buf, ",\n NULL AS indexdef");
1717 }1746 }
1747+ indexdefCol = colcnt++;
1748+ 
1718 if (tableinfo.relkind == 'f' && pset.sversion >= 90200) {1749 if (tableinfo.relkind == 'f' && pset.sversion >= 90200) {
1719 appendPQExpBuffer(&buf,1750 appendPQExpBuffer(&buf,
1720 ",\n CASE WHEN attfdwoptions IS NULL THEN '' ELSE "1751 ",\n CASE WHEN attfdwoptions IS NULL THEN '' ELSE "
@@ -1724,6 +1755,8 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
1724 } else {1755 } else {
1725 appendPQExpBuffer(&buf, ",\n NULL AS attfdwoptions");1756 appendPQExpBuffer(&buf, ",\n NULL AS attfdwoptions");
1726 }1757 }
1758+ fdwoptsCol = colcnt++;
1759+ 
1727#ifdef HAVE_CE1760#ifdef HAVE_CE
1728 if (hasFullEncryptFeature && pset.sversion >= 90100) {1761 if (hasFullEncryptFeature && pset.sversion >= 90100) {
1729 appendPQExpBuffer(&buf,1762 appendPQExpBuffer(&buf,
@@ -1740,11 +1773,17 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
1740 appendPQExpBuffer(&buf, "\n NULL AS clientlogic_original_type");1773 appendPQExpBuffer(&buf, "\n NULL AS clientlogic_original_type");
1741 appendPQExpBuffer(&buf, ",\n NULL AS clientlogic_original_type_oid");1774 appendPQExpBuffer(&buf, ",\n NULL AS clientlogic_original_type_oid");
1742 }1775 }
1776+ clientLogicOrgTypeCol = colcnt++;
1777+ clientLogicOrgTypeOidCol = colcnt++;
1743#endif1778#endif
1779+ 
1744 if (verbose) {1780 if (verbose) {
1745 appendPQExpBuffer(&buf, ",\n a.attstorage");1781 appendPQExpBuffer(&buf, ",\n a.attstorage");
1782+ attstorageCol = colcnt++;
1783+ 
1746 appendPQExpBuffer(1784 appendPQExpBuffer(
1747 &buf, ",\n CASE WHEN a.attstattarget=-1 THEN NULL ELSE a.attstattarget END AS attstattarget");1785 &buf, ",\n CASE WHEN a.attstattarget=-1 THEN NULL ELSE a.attstattarget END AS attstattarget");
1786+ attstattargetCol = colcnt++;
1748 1787 
1749 /*1788 /*
1750 * In 9.0+, we have column comments for: relations, views, composite1789 * In 9.0+, we have column comments for: relations, views, composite
@@ -1753,18 +1792,31 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
1753 if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' || tableinfo.relkind == 'f' ||1792 if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' || tableinfo.relkind == 'f' ||
1754 tableinfo.relkind == 'c' || tableinfo.relkind == 'm' || tableinfo.relkind == 'e' || 1793 tableinfo.relkind == 'c' || tableinfo.relkind == 'm' || tableinfo.relkind == 'e' ||
1755 tableinfo.relkind == 'o') {1794 tableinfo.relkind == 'o') {
1756- appendPQExpBuffer(&buf, ", pg_catalog.col_description(a.attrelid, a.attnum)");1795+ appendPQExpBuffer(&buf, ", pg_catalog.col_description(a.attrelid, a.attnum) as coldesc");
1796+ attdescrCol = colcnt++;
1757 }1797 }
1798+ 
1758 appendPQExpBuffer(&buf, ",\n a.attkvtype");1799 appendPQExpBuffer(&buf, ",\n a.attkvtype");
1800+ attkvtypeCol = colcnt++;
1759 }1801 }
1802+ 
1760 if (hasGenColFeature) {1803 if (hasGenColFeature) {
1761 appendPQExpBuffer(&buf, ",\n (SELECT h.adgencol"1804 appendPQExpBuffer(&buf, ",\n (SELECT h.adgencol"
1762 "\n FROM pg_catalog.pg_attrdef h"1805 "\n FROM pg_catalog.pg_attrdef h"
1763 "\n WHERE h.adrelid = a.attrelid AND h.adnum = a.attnum AND a.atthasdef)"1806 "\n WHERE h.adrelid = a.attrelid AND h.adnum = a.attnum AND a.atthasdef)"
1764 " AS generated_column");1807 " AS generated_column");
1765 } else {1808 } else {
1766- appendPQExpBuffer(&buf, ", '' AS generated_column ");1809+ appendPQExpBuffer(&buf, ",\n ''::\"char\" AS generated_column ");
1767 }1810 }
1811+ attgeneratedCol = colcnt++;
1812+ 
1813+ /* describe new attribute `attidentity` */
1814+ if (pset.sversion >= 90200) {
1815+ appendPQExpBufferStr(&buf, ",\n a.attidentity");
1816+ } else {
1817+ appendPQExpBufferStr(&buf, ",\n ''::\"char\" AS attidentity");
1818+ }
1819+ attidentityCol = colcnt++;
1768 1820 
1769 if (tableinfo.relkind == 'r' && atooid(oid) < FirstBootstrapObjectId) {1821 if (tableinfo.relkind == 'r' && atooid(oid) < FirstBootstrapObjectId) {
1770 appendPQExpBuffer(&buf, "\nFROM (select * from pg_catalog.gs_catalog_attribute_records('%s')) as a", oid);1822 appendPQExpBuffer(&buf, "\nFROM (select * from pg_catalog.gs_catalog_attribute_records('%s')) as a", oid);
@@ -1880,30 +1932,30 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
1880 /* Generate table cells to be printed */1932 /* Generate table cells to be printed */
1881 for (i = 0; i < numrows; i++) {1933 for (i = 0; i < numrows; i++) {
1882 /* Column */1934 /* Column */
1883- printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false);1935+ printTableAddCell(&cont, PQgetvalue(res, i, attnameCol), false, false);
1884 1936 
1885 /* Type */1937 /* Type */
1886#ifdef HAVE_CE1938#ifdef HAVE_CE
1887- if (hasFullEncryptFeature && (strncmp(1939+ if (hasFullEncryptFeature &&
1888- PQgetvalue(res, i, 1), "byteawithoutorderwithequalcol", sizeof("byteawithoutorderwithequalcol") - 1) == 0 ||1940+ (strncmp(PQgetvalue(res, i, atttypeCol),
1889- strncmp(PQgetvalue(res, i, 1), "byteawithoutordercol", sizeof("byteawithoutordercol") - 1) == 0)) {1941+ "byteawithoutorderwithequalcol",
1890- printTableAddCell(&cont, PQgetvalue(res, i, PQfnumber(res, "clientlogic_original_type")), false, false);1942+ sizeof("byteawithoutorderwithequalcol") - 1) == 0 ||
1943+ strncmp(PQgetvalue(res, i, atttypeCol),
1944+ "byteawithoutordercol",
1945+ sizeof("byteawithoutordercol") - 1) == 0)) {
1946+ printTableAddCell(&cont, PQgetvalue(res, i, clientLogicOrgTypeCol), false, false);
1891 } else {1947 } else {
1892- printTableAddCell(&cont, PQgetvalue(res, i, 1), false, false);1948+ printTableAddCell(&cont, PQgetvalue(res, i, atttypeCol), false, false);
1893 }1949 }
1894#else1950#else
1895- printTableAddCell(&cont, PQgetvalue(res, i, 1), false, false);1951+ printTableAddCell(&cont, PQgetvalue(res, i, atttypeCol), false, false);
1896#endif /* HAVE_CE */1952#endif /* HAVE_CE */
1897 1953 
1898 /* Modifiers: collate, not null, default */1954 /* Modifiers: collate, not null, default */
1899 if (show_modifiers) {1955 if (show_modifiers) {
1900 resetPQExpBuffer(&tmpbuf);1956 resetPQExpBuffer(&tmpbuf);
1901- 1957+ /* collate */
1902- 1958+ if (!PQgetisnull(res, i, attcollCol)) {
1903- if (hasOnUpdateFeature) {
1904- if (!PQgetisnull(res, i, 6)) {
1905- if (tmpbuf.len > 0)
1906- appendPQExpBufferStr(&tmpbuf, " ");
1907 char* collate = PQgetvalue(res, i, 6);1959 char* collate = PQgetvalue(res, i, 6);
1908 PQExpBufferData charsetbuf;1960 PQExpBufferData charsetbuf;
1909 initPQExpBuffer(&charsetbuf);1961 initPQExpBuffer(&charsetbuf);
@@ -1920,92 +1972,84 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
1920 termPQExpBuffer(&charsetbuf);1972 termPQExpBuffer(&charsetbuf);
1921 PQclear(charset_res);1973 PQclear(charset_res);
1922 }1974 }
1923- } else {
1924- if (!PQgetisnull(res, i, 5)) {
1925- if (tmpbuf.len > 0)
1926- appendPQExpBufferStr(&tmpbuf, " ");
1927- char* collate = PQgetvalue(res, i, 5);
1928- PQExpBufferData charsetbuf;
1929- initPQExpBuffer(&charsetbuf);
1930- appendPQExpBuffer(&charsetbuf, _("select oid,collencoding from pg_collation where collname = '%s';"), collate);
1931- PGresult* charset_res = PSQLexec(charsetbuf.data, false);
1932- int collid = atoi(PQgetvalue(charset_res, 0, 0));
1933- if (COLLATION_IN_B_FORMAT(collid)) {
1934- int charset = atoi(PQgetvalue(charset_res, 0, 1));
1935- const char* encoding = pg_encoding_to_char(charset);
1936- appendPQExpBuffer(&tmpbuf, _("character set %s collate %s"), encoding, collate);
1937- } else {
1938- appendPQExpBuffer(&tmpbuf, _("collate %s"), collate);
1939- }
1940- termPQExpBuffer(&charsetbuf);
1941- PQclear(charset_res);
1942- }
1943- }
1944 1975 
1945- 1976+ /* not null */
1946- if (hasOnUpdateFeature) {1977+ if (strcmp(PQgetvalue(res, i, attnotnullCol), "t") == 0) {
1947- if (strcmp(PQgetvalue(res, i, 4), "t") == 0) {
1948 if (tmpbuf.len > 0)1978 if (tmpbuf.len > 0)
1949 appendPQExpBufferStr(&tmpbuf, " ");1979 appendPQExpBufferStr(&tmpbuf, " ");
1950 appendPQExpBufferStr(&tmpbuf, _("not null"));1980 appendPQExpBufferStr(&tmpbuf, _("not null"));
1951 }1981 }
1952- } else {
1953- if (strcmp(PQgetvalue(res, i, 3), "t") == 0) {
1954- if (tmpbuf.len > 0)
1955- appendPQExpBufferStr(&tmpbuf, " ");
1956- appendPQExpBufferStr(&tmpbuf, _("not null"));
1957- }
1958- }
1959 1982 
1960 /* handle "default" here */1983 /* handle "default" here */
1961 /* (note: above we cut off the 'default' string at 128) */1984 /* (note: above we cut off the 'default' string at 128) */
1962- char *default_value = PQgetvalue(res, i, 2);1985+ char *defaultValue = PQgetvalue(res, i, attrdefCol);
1963#ifdef HAVE_CE1986#ifdef HAVE_CE
1964 unsigned char *plaintext = NULL;1987 unsigned char *plaintext = NULL;
1965#endif1988#endif
1966- if (strlen(default_value) != 0) {1989+ if (strlen(defaultValue) != 0) {
1967#ifdef HAVE_CE1990#ifdef HAVE_CE
1968 if (hasFullEncryptFeature &&1991 if (hasFullEncryptFeature &&
1969- strlen(PQgetvalue(res, i, PQfnumber(res, "clientlogic_original_type"))) > 0) {1992+ strlen(PQgetvalue(res, i, clientLogicOrgTypeCol)) > 0) {
1970 size_t plainTextSize = 0;1993 size_t plainTextSize = 0;
1971- int original_type_id = atoi(PQgetvalue(res, i, PQfnumber(res, "clientlogic_original_type_oid")));1994+ int original_type_id = atoi(PQgetvalue(res, i, clientLogicOrgTypeOidCol));
1972 ProcessStatus process_status = ADD_TYPE;1995 ProcessStatus process_status = ADD_TYPE;
1973- ValuesProcessor::deprocess_value(pset.db, (unsigned char *)default_value, strlen(default_value),1996+ ValuesProcessor::deprocess_value(pset.db, (unsigned char *)defaultValue, strlen(defaultValue),
1974 original_type_id, 0, &plaintext, plainTextSize, process_status);1997 original_type_id, 0, &plaintext, plainTextSize, process_status);
1975 if (plaintext != NULL) {1998 if (plaintext != NULL) {
1976- default_value = (char *)plaintext;1999+ defaultValue = (char *)plaintext;
1977 }2000 }
1978 }2001 }
1979#endif2002#endif
1980 if (tmpbuf.len > 0) {2003 if (tmpbuf.len > 0) {
1981 appendPQExpBufferStr(&tmpbuf, " ");2004 appendPQExpBufferStr(&tmpbuf, " ");
1982 }2005 }
2006+ 
1983 /* translator: default values of column definitions */2007 /* translator: default values of column definitions */
1984- char* gencolType = PQgetvalue(res, i, PQfnumber(res, "generated_column"));2008+ const char* gencolType = PQgetvalue(res, i, attgeneratedCol);
1985- if (gencolType && strlen(gencolType) > 0) {2009+ 
1986- appendPQExpBuffer(&tmpbuf, (strcmp(gencolType, "p") == 0 ? _("as (%s) persisted") :2010+ if (gencolType[0] == ATTRIBUTE_GENERATED_STORED) {
1987- _("generated always as (%s) stored")), default_value);2011+ appendPQExpBuffer(&tmpbuf, _("generated always as (%s) stored"), defaultValue);
1988- } else if (strcmp(default_value, "AUTO_INCREMENT") == 0) {2012+ } else if (gencolType[0] == ATTRIBUTE_GENERATED_PERSISTED) {
1989- appendPQExpBuffer(&tmpbuf, _("%s"), default_value);2013+ appendPQExpBuffer(&tmpbuf, _("as (%s) persisted"), defaultValue);
2014+ } else if (strcmp(defaultValue, "AUTO_INCREMENT") == 0) {
2015+ appendPQExpBuffer(&tmpbuf, _("%s"), defaultValue);
1990 } else {2016 } else {
1991- appendPQExpBuffer(&tmpbuf, _("default %s"), default_value);2017+ appendPQExpBuffer(&tmpbuf, _("default %s"), defaultValue);
1992 }2018 }
1993 }2019 }
1994 2020 
1995- 2021+ /* identity column */
1996- if (hasOnUpdateFeature) {2022+ const char* identity = PQgetvalue(res, i, attidentityCol);
1997- char *on_update_value = PQgetvalue(res, i, 3);2023+ if (identity[0] == ATTRIBUTE_IDENTITY_ALWAYS) {
1998- if (strlen(on_update_value) > 0) {2024+ if (tmpbuf.len > 0) {
1999- if (tmpbuf.len > 0) {2025+ appendPQExpBufferStr(&tmpbuf, " ");
2000- appendPQExpBufferStr(&tmpbuf, " ");
2001- }
2002- /* translator: on_update values of column definitions */
2003- appendPQExpBuffer(&tmpbuf, _("on update %s"), on_update_value);
2004 }2026 }
2027+ appendPQExpBuffer(&tmpbuf, _("generated always as identity"));
2028+ } else if (identity[0] == ATTRIBUTE_IDENTITY_BY_DEFAULT) {
2029+ if (tmpbuf.len > 0) {
2030+ appendPQExpBufferStr(&tmpbuf, " ");
2031+ }
2032+ appendPQExpBuffer(&tmpbuf, _("generated by default as identity"));
2033+ } else if (identity[0] == ATTRIBUTE_IDENTITY_D) {
2034+ if (tmpbuf.len > 0) {
2035+ appendPQExpBufferStr(&tmpbuf, " ");
2036+ }
2037+ appendPQExpBuffer(&tmpbuf, _("identity"));
2005 }2038 }
2039+ 
2040+ /* on update default */
2041+ const char *onUpdateValue = PQgetvalue(res, i, attrdefUpdateCol);
2042+ if (strlen(onUpdateValue) > 0) {
2043+ if (tmpbuf.len > 0) {
2044+ appendPQExpBufferStr(&tmpbuf, " ");
2045+ }
2046+ /* translator: on_update values of column definitions */
2047+ appendPQExpBuffer(&tmpbuf, _("on update %s"), onUpdateValue);
2048+ }
2049+ 
2006#ifdef HAVE_CE2050#ifdef HAVE_CE
2007 if (hasFullEncryptFeature &&2051 if (hasFullEncryptFeature &&
2008- strlen(PQgetvalue(res, i, PQfnumber(res, "clientlogic_original_type"))) > 0) {2052+ strlen(PQgetvalue(res, i, clientLogicOrgTypeCol)) > 0) {
2009 appendPQExpBufferStr(&tmpbuf, _(" encrypted"));2053 appendPQExpBufferStr(&tmpbuf, _(" encrypted"));
2010 if (plaintext != NULL) {2054 if (plaintext != NULL) {
2011 free(plaintext);2055 free(plaintext);
@@ -2024,33 +2068,17 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
2024 2068 
2025 /* Expression for index column */2069 /* Expression for index column */
2026 if (tableinfo.relkind == 'i' || tableinfo.relkind == 'I') {2070 if (tableinfo.relkind == 'i' || tableinfo.relkind == 'I') {
2027- if (hasOnUpdateFeature) {2071+ printTableAddCell(&cont, PQgetvalue(res, i, indexdefCol), false, false);
2028- printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false);
2029- } else {
2030- printTableAddCell(&cont, PQgetvalue(res, i, 6), false, false);
2031- }
2032 }2072 }
2033 2073 
2034 /* FDW options for foreign table column, only for 9.2 or later */2074 /* FDW options for foreign table column, only for 9.2 or later */
2035 if ((tableinfo.relkind == 'f' || tableinfo.relkind == 'e') && pset.sversion >= 90200) {2075 if ((tableinfo.relkind == 'f' || tableinfo.relkind == 'e') && pset.sversion >= 90200) {
2036- if (hasOnUpdateFeature) {2076+ printTableAddCell(&cont, PQgetvalue(res, i, fdwoptsCol), false, false);
2037- printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
2038- } else {
2039- printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false);
2040- }
2041 }2077 }
2042 2078 
2043 /* Storage and Description */2079 /* Storage and Description */
2044 if (verbose) {2080 if (verbose) {
2045-#ifdef HAVE_CE2081+ char* storage = PQgetvalue(res, i, attstorageCol);
2046- int firstvcol = (hasFullEncryptFeature ? 10 : 8);
2047-#else
2048- int firstvcol = 8;
2049-#endif
2050- if (hasOnUpdateFeature) {
2051- firstvcol++;
2052- }
2053- char* storage = PQgetvalue(res, i, firstvcol);
2054 2082 
2055 /* these strings are literal in our syntax, so not translated. */2083 /* these strings are literal in our syntax, so not translated. */
2056 printTableAddCell(&cont,2084 printTableAddCell(&cont,
@@ -2065,21 +2093,21 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
2065 /* Statistics target, if the relkind supports this feature */2093 /* Statistics target, if the relkind supports this feature */
2066 if (tableinfo.relkind == 'r' || tableinfo.relkind == 'f' || tableinfo.relkind == 'm' || 2094 if (tableinfo.relkind == 'r' || tableinfo.relkind == 'f' || tableinfo.relkind == 'm' ||
2067 tableinfo.relkind == 'e') {2095 tableinfo.relkind == 'e') {
2068- printTableAddCell(&cont, PQgetvalue(res, i, firstvcol + 1), false, false);2096+ printTableAddCell(&cont, PQgetvalue(res, i, attstattargetCol), false, false);
2069 }2097 }
2070 2098 
2071 /* Column comments, if the relkind supports this feature. */2099 /* Column comments, if the relkind supports this feature. */
2072 if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' || tableinfo.relkind == 'c' ||2100 if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' || tableinfo.relkind == 'c' ||
2073 tableinfo.relkind == 'f' || tableinfo.relkind == 'm' || tableinfo.relkind == 'e' ||2101 tableinfo.relkind == 'f' || tableinfo.relkind == 'm' || tableinfo.relkind == 'e' ||
2074 tableinfo.relkind == 'o')2102 tableinfo.relkind == 'o')
2075- printTableAddCell(&cont, PQgetvalue(res, i, firstvcol + 2), false, false);2103+ printTableAddCell(&cont, PQgetvalue(res, i, attdescrCol), false, false);
2076 2104 
2077 /* For timeseries table, 1,2,3 stands for column type: ATT_KV_TAG, ATT_KV_FIELD, ATT_KV_TIMETAG,2105 /* For timeseries table, 1,2,3 stands for column type: ATT_KV_TAG, ATT_KV_FIELD, ATT_KV_TIMETAG,
2078 * see parsenodes.h2106 * see parsenodes.h
2079 */2107 */
2080 if ((tableinfo.relkind == 'r' || tableinfo.relkind == 'm') && (tableinfo.reloptions != NULL) &&2108 if ((tableinfo.relkind == 'r' || tableinfo.relkind == 'm') && (tableinfo.reloptions != NULL) &&
2081 strstr(tableinfo.reloptions, ORIENTATION_TIMESERIES)) {2109 strstr(tableinfo.reloptions, ORIENTATION_TIMESERIES)) {
2082- char* kvtype = PQgetvalue(res, i, firstvcol + 3);2110+ char* kvtype = PQgetvalue(res, i, attkvtypeCol);
2083 printTableAddCell(&cont, (char*)((kvtype[0] == '1' ? "kvtag" : (kvtype[0] == '2'2111 printTableAddCell(&cont, (char*)((kvtype[0] == '1' ? "kvtag" : (kvtype[0] == '2'
2084 ? "kvfield" : (kvtype[0] == '3' ? "kvtime" : (kvtype[0] == '4' ? "kvhide" : "none"))))),2112 ? "kvfield" : (kvtype[0] == '3' ? "kvtime" : (kvtype[0] == '4' ? "kvhide" : "none"))))),
2085 false,2113 false,
@@ -2218,7 +2246,8 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
2218 printfPQExpBuffer(&buf,2246 printfPQExpBuffer(&buf,
2219 "SELECT pg_catalog.quote_ident(nspname) || '.' ||"2247 "SELECT pg_catalog.quote_ident(nspname) || '.' ||"
2220 "\n pg_catalog.quote_ident(relname) || '.' ||"2248 "\n pg_catalog.quote_ident(relname) || '.' ||"
2221- "\n pg_catalog.quote_ident(attname)"2249+ "\n pg_catalog.quote_ident(attname),"
2250+ "\n d.deptype"
2222 "\nFROM pg_catalog.pg_class c"2251 "\nFROM pg_catalog.pg_class c"
2223 "\nINNER JOIN pg_catalog.pg_depend d ON c.oid=d.refobjid"2252 "\nINNER JOIN pg_catalog.pg_depend d ON c.oid=d.refobjid"
2224 "\nINNER JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace"2253 "\nINNER JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace"
@@ -2228,14 +2257,24 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation
2228 "\nWHERE d.classid='pg_catalog.pg_class'::pg_catalog.regclass"2257 "\nWHERE d.classid='pg_catalog.pg_class'::pg_catalog.regclass"
2229 "\n AND d.refclassid='pg_catalog.pg_class'::pg_catalog.regclass"2258 "\n AND d.refclassid='pg_catalog.pg_class'::pg_catalog.regclass"
2230 "\n AND d.objid=%s"2259 "\n AND d.objid=%s"
2231- "\n AND d.deptype='a'",2260+ "\n AND d.deptype IN ('a', 'i')",
2232 oid);2261 oid);
2233 2262 
2234 result = PSQLexec(buf.data, false);2263 result = PSQLexec(buf.data, false);
2235 if (result == NULL)2264 if (result == NULL)
2236 goto error_return;2265 goto error_return;
2237 else if (PQntuples(result) == 1) {2266 else if (PQntuples(result) == 1) {
2238- printfPQExpBuffer(&buf, _("Owned by: %s"), PQgetvalue(result, 0, 0));2267+ switch (PQgetvalue(result, 0, 1)[0]) {
2268+ case 'a':
2269+ printfPQExpBuffer(&buf, _("Owned by: %s"), PQgetvalue(result, 0, 0));
2270+ break;
2271+ case 'i':
2272+ printfPQExpBuffer(&buf, _("Sequence for identity column: %s"),
2273+ PQgetvalue(result, 0, 0));
2274+ break;
2275+ defalut:
2276+ break;
2277+ }
2239 printTableAddFooter(&cont, buf.data);2278 printTableAddFooter(&cont, buf.data);
2240 }2279 }
2241 2280 
@@ -4601,8 +4640,8 @@ bool listTSDictionaries(const char* pattern, bool verbose)
4601 appendPQExpBuffer(&buf,4640 appendPQExpBuffer(&buf,
4602 " ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM \n"4641 " ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM \n"
4603 " pg_catalog.pg_ts_template t \n"4642 " pg_catalog.pg_ts_template t \n"
4604- " LEFT JOIN pg_catalog.pg_namespace nt ON nt.oid = t.tmplnamespace \n"4643+ " LEFT JOIN pg_catalog.pg_namespace nt ON nt.oid = t.tmplnamespace \n"
4605- " WHERE d.dicttemplate = t.oid ) AS \"%s\", \n"4644+ " WHERE d.dicttemplate = t.oid ) AS \"%s\", \n"
4606 " d.dictinitoption as \"%s\", \n",4645 " d.dictinitoption as \"%s\", \n",
4607 gettext_noop("Template"),4646 gettext_noop("Template"),
4608 gettext_noop("Init options"));4647 gettext_noop("Init options"));
@@ -5447,7 +5486,7 @@ void ut_test_listOneExtensionContents()
5447 * printACLColumn5486 * printACLColumn
5448 *5487 *
5449 * Helper function for consistently formatting ACL (privilege) columns.5488 * Helper function for consistently formatting ACL (privilege) columns.
5450- * The proper targetlist entry is appended to buf. Note lack of any5489+ * The proper targetlist entry is appended to buf. Note lack of any
5451 * whitespace or comma decoration.5490 * whitespace or comma decoration.
5452 */5491 */
5453static void printACLColumn(PQExpBuffer buf, const char* colname)5492static void printACLColumn(PQExpBuffer buf, const char* colname)
@@ -1165,7 +1165,7 @@ static char** PsqlCompletion(const char *text, int start, int end)
1165 /* ALTER SEQUENCE <name> */1165 /* ALTER SEQUENCE <name> */
1166 else if (pg_strcasecmp(PREV3_WD, "ALTER") == 0 && pg_strcasecmp(PREV2_WD, "SEQUENCE") == 0) {1166 else if (pg_strcasecmp(PREV3_WD, "ALTER") == 0 && pg_strcasecmp(PREV2_WD, "SEQUENCE") == 0) {
1167 static const char* const listAlterSequence[] = {1167 static const char* const listAlterSequence[] = {
1168- "MAXVALUE", "NO MAXVALUE", "NOMAXVALUE", "OWNED BY", "OWNER TO", NULL1168+ "MAXVALUE", "NO MAXVALUE", "NOMAXVALUE", "OWNED BY", "OWNER TO", "RENAME TO", NULL
1169 };1169 };
1170 1170 
1171 COMPLETE_WITH_LIST(listAlterSequence);1171 COMPLETE_WITH_LIST(listAlterSequence);
@@ -1324,8 +1324,7 @@ static char** PsqlCompletion(const char *text, int start, int end)
1324 /* ALTER TABLE ALTER [COLUMN] <foo> */1324 /* ALTER TABLE ALTER [COLUMN] <foo> */
1325 else if ((pg_strcasecmp(PREV3_WD, "ALTER") == 0 && pg_strcasecmp(PREV2_WD, "COLUMN") == 0) ||1325 else if ((pg_strcasecmp(PREV3_WD, "ALTER") == 0 && pg_strcasecmp(PREV2_WD, "COLUMN") == 0) ||
1326 (pg_strcasecmp(PREV4_WD, "TABLE") == 0 && pg_strcasecmp(PREV2_WD, "ALTER") == 0)) {1326 (pg_strcasecmp(PREV4_WD, "TABLE") == 0 && pg_strcasecmp(PREV2_WD, "ALTER") == 0)) {
1327- static const char* const listColumnAlter[] = {"TYPE", "SET", "RESET", "DROP", NULL};1327+ static const char* const listColumnAlter[] = {"TYPE", "SET", "RESET", "RESTART", "ADD", "DROP", NULL};
1328- 
1329 COMPLETE_WITH_LIST(listColumnAlter);1328 COMPLETE_WITH_LIST(listColumnAlter);
1330 }1329 }
1331 /* ALTER TABLE ALTER [COLUMN] <foo> SET */1330 /* ALTER TABLE ALTER [COLUMN] <foo> SET */
@@ -1356,7 +1355,7 @@ static char** PsqlCompletion(const char *text, int start, int end)
1356 else if (((pg_strcasecmp(PREV4_WD, "ALTER") == 0 && pg_strcasecmp(PREV3_WD, "COLUMN") == 0) ||1355 else if (((pg_strcasecmp(PREV4_WD, "ALTER") == 0 && pg_strcasecmp(PREV3_WD, "COLUMN") == 0) ||
1357 (pg_strcasecmp(PREV5_WD, "TABLE") == 0 && pg_strcasecmp(PREV3_WD, "ALTER") == 0)) &&1356 (pg_strcasecmp(PREV5_WD, "TABLE") == 0 && pg_strcasecmp(PREV3_WD, "ALTER") == 0)) &&
1358 pg_strcasecmp(PREV_WD, "DROP") == 0) {1357 pg_strcasecmp(PREV_WD, "DROP") == 0) {
1359- static const char* const listColumnDrop[] = {"DEFAULT", "NOT NULL", NULL};1358+ static const char* const listColumnDrop[] = {"DEFAULT", "IDENTITY", "NOT NULL", NULL};
1360 1359 
1361 COMPLETE_WITH_LIST(listColumnDrop);1360 COMPLETE_WITH_LIST(listColumnDrop);
1362 } else if (pg_strcasecmp(PREV3_WD, "TABLE") == 0 && pg_strcasecmp(PREV_WD, "CLUSTER") == 0)1361 } else if (pg_strcasecmp(PREV3_WD, "TABLE") == 0 && pg_strcasecmp(PREV_WD, "CLUSTER") == 0)
@@ -3763,7 +3763,7 @@
3763 ),3763 ),
3764 AddFuncGroup(3764 AddFuncGroup(
3765 "gs_catalog_attribute_records", 1,3765 "gs_catalog_attribute_records", 1,
3766- AddBuiltinFunc(_0(8010), _1("gs_catalog_attribute_records"), _2(1), _3(true), _4(true), _5(gs_catalog_attribute_records), _6(2249), _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('s'), _19(0), _20(1, 26), _21(26, 26, 26, 19, 26, 23, 21, 21, 23, 23, 23, 16, 18, 18, 16, 16, 16, 16, 5545, 23, 26, 1034, 1009, 1009, 17, 5545, 19), _22(26, 'i', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'), _23(26, "relid", "attrelid", "attname", "atttypid", "attstattarget", "attlen", "attnum", "attndims", "attcacheoff", "atttypmod", "attbyval", "attstorage", "attalign", "attnotnull", "atthasdef", "attisdropped", "attislocal", "attcmprmode", "attinhcount", "attcollation", "attacl", "attoptions", "attfdwoptions", "attinitdefval", "attkvtype", "attdroppedname"), _24(NULL), _25("gs_catalog_attribute_records"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33("attribute description for catalog relation"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))3766+ AddBuiltinFunc(_0(8010), _1("gs_catalog_attribute_records"), _2(1), _3(true), _4(true), _5(gs_catalog_attribute_records), _6(2249), _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('s'), _19(0), _20(1, 26), _21(27, 26, 26, 19, 26, 23, 21, 21, 23, 23, 23, 16, 18, 18, 16, 16, 16, 16, 5545, 23, 26, 1034, 1009, 1009, 17, 5545, 19, 18), _22(27, 'i', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'), _23(27, "relid", "attrelid", "attname", "atttypid", "attstattarget", "attlen", "attnum", "attndims", "attcacheoff", "atttypmod", "attbyval", "attstorage", "attalign", "attnotnull", "atthasdef", "attisdropped", "attislocal", "attcmprmode", "attinhcount", "attcollation", "attacl", "attoptions", "attfdwoptions", "attinitdefval", "attkvtype", "attdroppedname", "attidentity"), _24(NULL), _25("gs_catalog_attribute_records"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33("attribute description for catalog relation"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
3767 ),3767 ),
3768 AddFuncGroup(3768 AddFuncGroup(
3769 "gs_cgroup_map_ng_conf", 1, 3769 "gs_cgroup_map_ng_conf", 1,
@@ -1461,15 +1461,18 @@ Datum gs_catalog_attribute_records(PG_FUNCTION_ARGS)
1461 values[Anum_pg_attribute_attcmprmode - 1] = Int8GetDatum(attr.attcmprmode);1461 values[Anum_pg_attribute_attcmprmode - 1] = Int8GetDatum(attr.attcmprmode);
1462 values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(attr.attinhcount);1462 values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(attr.attinhcount);
1463 values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attr.attcollation);1463 values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attr.attcollation);
1464+ 
1464 /* kvtype of catalog relations is always 0 */1465 /* kvtype of catalog relations is always 0 */
1465 values[Anum_pg_attribute_attkvtype - 1] = Int8GetDatum(0);1466 values[Anum_pg_attribute_attkvtype - 1] = Int8GetDatum(0);
1466- values[Anum_pg_attribute_attdroppedname - 1] = NameGetDatum(&attr.attdroppedname);1467+ /* attidentity of catalog relations is always '\0' */
1468+ values[Anum_pg_attribute_attidentity - 1] = CharGetDatum('\0');
1467 1469 
1468 /* Variable length attribute fields have little significance for catalog relations */1470 /* Variable length attribute fields have little significance for catalog relations */
1469 nulls[Anum_pg_attribute_attacl - 1] = true;1471 nulls[Anum_pg_attribute_attacl - 1] = true;
1470 nulls[Anum_pg_attribute_attoptions - 1] = true;1472 nulls[Anum_pg_attribute_attoptions - 1] = true;
1471 nulls[Anum_pg_attribute_attfdwoptions - 1] = true;1473 nulls[Anum_pg_attribute_attfdwoptions - 1] = true;
1472 nulls[Anum_pg_attribute_attinitdefval - 1] = true;1474 nulls[Anum_pg_attribute_attinitdefval - 1] = true;
1475+ nulls[Anum_pg_attribute_attdroppedname - 1] = true;
1473 1476 
1474 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);1477 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
1475 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));1478 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
@@ -227,6 +227,7 @@ bool CreateDeltaTable(Relation rel, Datum reloptions, bool isPartition, CreateSt
227 TupleDesc mainTableTupDesc = rel->rd_att;227 TupleDesc mainTableTupDesc = rel->rd_att;
228 228 
229 TupleDesc tupdesc = CreateTupleDescCopyConstr(mainTableTupDesc);229 TupleDesc tupdesc = CreateTupleDescCopyConstr(mainTableTupDesc);
230+ Form_pg_attribute_extra attrExtra = CreatePGAttributeExtra(mainTableTupDesc);
230 231 
231 // if psort index change relkind to relation232 // if psort index change relkind to relation
232 char relkind = rel->rd_rel->relkind == RELKIND_INDEX ? RELKIND_RELATION : rel->rd_rel->relkind;233 char relkind = rel->rd_rel->relkind == RELKIND_INDEX ? RELKIND_RELATION : rel->rd_rel->relkind;
@@ -266,7 +267,15 @@ bool CreateDeltaTable(Relation rel, Datum reloptions, bool isPartition, CreateSt
266 NULL,267 NULL,
267 REL_CMPRS_NOT_SUPPORT,268 REL_CMPRS_NOT_SUPPORT,
268 NULL,269 NULL,
269- false);270+ false,
271+ NULL,
272+ HEAP_DISK,
273+ AccessExclusiveLock,
274+ NULL,
275+ NIL,
276+ InvalidOid,
277+ InvalidOid,
278+ attrExtra);
270 Assert(delta_relid != InvalidOid);279 Assert(delta_relid != InvalidOid);
271 280 
272 /* make the delta relation visible, else heap_open will fail */281 /* make the delta relation visible, else heap_open will fail */
@@ -2119,6 +2119,10 @@ static bool find_expr_references_walker(Node* node, find_expr_references_context
2119 CoerceToDomain* cd = (CoerceToDomain*)node;2119 CoerceToDomain* cd = (CoerceToDomain*)node;
2120 2120 
2121 add_object_address(OCLASS_TYPE, cd->resulttype, 0, context->addrs);2121 add_object_address(OCLASS_TYPE, cd->resulttype, 0, context->addrs);
2122+ } else if (IsA(node, NextValueExpr)) {
2123+ NextValueExpr* nve = (NextValueExpr*)node;
2124+ 
2125+ add_object_address(OCLASS_CLASS, nve->seqid, 0, context->addrs);
2122 } else if (IsA(node, SortGroupClause)) {2126 } else if (IsA(node, SortGroupClause)) {
2123 SortGroupClause* sgc = (SortGroupClause*)node;2127 SortGroupClause* sgc = (SortGroupClause*)node;
2124 2128 
@@ -393,8 +393,9 @@ sub emit_pgattr_row
393 # new fileld attinitdefval of pg_attribute393 # new fileld attinitdefval of pg_attribute
394 attinitdefval => '_null_',394 attinitdefval => '_null_',
395 attkvtype => '0',395 attkvtype => '0',
396- attdroppedname => '_null_'396+ attdroppedname => '_null_',
397- );397+ attidentity => '',
398+ );
398 return { %PGATTR_DEFAULTS, %row };399 return { %PGATTR_DEFAULTS, %row };
399}400}
400 401 
@@ -404,7 +405,7 @@ sub bki_insert
404 my $row = shift;405 my $row = shift;
405 my @attnames = @_;406 my @attnames = @_;
406 my $oid = $row->{oid} ? "OID = $row->{oid} " : '';407 my $oid = $row->{oid} ? "OID = $row->{oid} " : '';
407- my $bki_values = join ' ', map $row->{$_}, @attnames;408+ my $bki_values = join ' ', map { $_ eq '' ? '""' : $_ } map $row->{$_}, @attnames;
408 printf BKI "insert %s( %s)\n", $oid, $bki_values;409 printf BKI "insert %s( %s)\n", $oid, $bki_values;
409}410}
410 411 
@@ -427,7 +428,9 @@ sub emit_schemapg_row
427 delete $row->{attfdwoptions};428 delete $row->{attfdwoptions};
428 # new fileld attinitdefval of pg_attribute429 # new fileld attinitdefval of pg_attribute
429 delete $row->{attinitdefval};430 delete $row->{attinitdefval};
431+ delete $row->{attkvtype};
430 delete $row->{attdroppedname};432 delete $row->{attdroppedname};
433+ delete $row->{attidentity};
431 434 
432 # Expand booleans from 'f'/'t' to 'false'/'true'.435 # Expand booleans from 'f'/'t' to 'false'/'true'.
433 # Some values might be other macros (eg FLOAT4PASSBYVAL), don't change.436 # Some values might be other macros (eg FLOAT4PASSBYVAL), don't change.
@@ -956,7 +956,7 @@ void InsertTablebucketidAttribute(Oid newRelOid)
956 securec_check(rc, "\0", "\0");956 securec_check(rc, "\0", "\0");
957 attStruct.attrelid = newRelOid;957 attStruct.attrelid = newRelOid;
958 958 
959- InsertPgAttributeTuple(rel, &attStruct, indstate);959+ InsertPgAttributeTuple(rel, &attStruct, NULL, indstate);
960 CatalogCloseIndexes(indstate);960 CatalogCloseIndexes(indstate);
961 heap_close(rel, RowExclusiveLock);961 heap_close(rel, RowExclusiveLock);
962}962}
@@ -973,7 +973,8 @@ void InsertTablebucketidAttribute(Oid newRelOid)
973 * NULL, in which case we'll fetch the necessary info. (Don't do this when973 * NULL, in which case we'll fetch the necessary info. (Don't do this when
974 * inserting multiple attributes, because it's a tad more expensive.)974 * inserting multiple attributes, because it's a tad more expensive.)
975 */975 */
976-void InsertPgAttributeTuple(Relation pg_attribute_rel, Form_pg_attribute new_attribute, CatalogIndexState indstate)976+void InsertPgAttributeTuple(Relation pg_attribute_rel, Form_pg_attribute new_attribute,
977+ Form_pg_attribute_extra attrExtra, CatalogIndexState indstate)
977{978{
978 Datum values[Natts_pg_attribute];979 Datum values[Natts_pg_attribute];
979 bool nulls[Natts_pg_attribute];980 bool nulls[Natts_pg_attribute];
@@ -1004,7 +1005,16 @@ void InsertPgAttributeTuple(Relation pg_attribute_rel, Form_pg_attribute new_att
1004 values[Anum_pg_attribute_attcmprmode - 1] = Int8GetDatum(new_attribute->attcmprmode);1005 values[Anum_pg_attribute_attcmprmode - 1] = Int8GetDatum(new_attribute->attcmprmode);
1005 values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(new_attribute->attinhcount);1006 values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(new_attribute->attinhcount);
1006 values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(new_attribute->attcollation);1007 values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(new_attribute->attcollation);
1007- values[Anum_pg_attribute_attkvtype - 1] = Int8GetDatum(new_attribute->attkvtype);1008+ 
1009+ if (attrExtra) {
1010+ values[Anum_pg_attribute_attkvtype - 1] = Int8GetDatum(attrExtra->attkvtype);
1011+ values[Anum_pg_attribute_attdroppedname - 1] = NameGetDatum(&attrExtra->attdroppedname);
1012+ values[Anum_pg_attribute_attidentity - 1] = CharGetDatum(attrExtra->attidentity);
1013+ } else {
1014+ values[Anum_pg_attribute_attkvtype - 1] = Int8GetDatum(0);
1015+ values[Anum_pg_attribute_attidentity - 1] = CharGetDatum('\0');
1016+ nulls[Anum_pg_attribute_attdroppedname - 1] = true;
1017+ }
1008 1018 
1009 /* start out with empty permissions and empty options */1019 /* start out with empty permissions and empty options */
1010 nulls[Anum_pg_attribute_attacl - 1] = true;1020 nulls[Anum_pg_attribute_attacl - 1] = true;
@@ -1013,7 +1023,6 @@ void InsertPgAttributeTuple(Relation pg_attribute_rel, Form_pg_attribute new_att
1013 1023 
1014 /* at default, new fileld attinitdefval of pg_attribute is null. */1024 /* at default, new fileld attinitdefval of pg_attribute is null. */
1015 nulls[Anum_pg_attribute_attinitdefval - 1] = true;1025 nulls[Anum_pg_attribute_attinitdefval - 1] = true;
1016- nulls[Anum_pg_attribute_attdroppedname - 1] = true;
1017 1026 
1018 tup = heap_form_tuple(RelationGetDescr(pg_attribute_rel), values, nulls);1027 tup = heap_form_tuple(RelationGetDescr(pg_attribute_rel), values, nulls);
1019 1028 
@@ -1057,14 +1066,16 @@ static bool make_gs_depend_param_body(GsDependParamBody* gs_depend_param_body, c
1057}1066}
1058 1067 
1059/* --------------------------------1068/* --------------------------------
1060- * AddNewAttributeTuples1069+ * AddNewAttributeTuples
1061 *1070 *
1062- * this registers the new relation's schema by adding1071+ * this registers the new relation's schema by adding
1063- * tuples to pg_attribute.1072+ * tuples to pg_attribute.
1064 * --------------------------------1073 * --------------------------------
1065 */1074 */
1066static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relkind,1075static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relkind,
1067- bool oidislocal, int oidinhcount, bool hasbucket, bool hasuids, List* depend_extend, const char* typ_name, Oid namespace_oid)1076+ bool oidislocal, int oidinhcount, bool hasbucket, bool hasuids,
1077+ List* depend_extend, const char* typ_name, Oid namespace_oid,
1078+ Form_pg_attribute_extra attrExtra)
1068{1079{
1069 Form_pg_attribute attr;1080 Form_pg_attribute attr;
1070 int i;1081 int i;
@@ -1098,7 +1109,9 @@ static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relki
1098 attr->attstattarget = -1;1109 attr->attstattarget = -1;
1099 attr->attcacheoff = -1;1110 attr->attcacheoff = -1;
1100 1111 
1101- InsertPgAttributeTuple(rel, attr, indstate);1112+ InsertPgAttributeTuple(rel, attr,
1113+ attrExtra ? &attrExtra[i] : NULL,
1114+ indstate);
1102 1115 
1103 /*1116 /*
1104 * During inplace/grey upgrade, we don't record dependencies1117 * During inplace/grey upgrade, we don't record dependencies
@@ -1173,7 +1186,7 @@ static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relki
1173 attStruct.attinhcount = oidinhcount;1186 attStruct.attinhcount = oidinhcount;
1174 }1187 }
1175 1188 
1176- InsertPgAttributeTuple(rel, &attStruct, indstate);1189+ InsertPgAttributeTuple(rel, &attStruct, NULL, indstate);
1177 }1190 }
1178 }1191 }
1179 1192 
@@ -2699,7 +2712,7 @@ Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltable
2699 bool allow_system_table_mods, PartitionState *partTableState, int8 row_compress,2712 bool allow_system_table_mods, PartitionState *partTableState, int8 row_compress,
2700 HashBucketInfo *bucketinfo, bool record_dependce, List *ceLst, StorageType storage_type,2713 HashBucketInfo *bucketinfo, bool record_dependce, List *ceLst, StorageType storage_type,
2701 LOCKMODE partLockMode, ObjectAddress *typaddress, List* depend_extend, Oid relrewrite,2714 LOCKMODE partLockMode, ObjectAddress *typaddress, List* depend_extend, Oid relrewrite,
2702- Oid typbasetype)2715+ Oid typbasetype, Form_pg_attribute_extra attrExtra)
2703{2716{
2704 Relation pg_class_desc;2717 Relation pg_class_desc;
2705 Relation new_rel_desc;2718 Relation new_rel_desc;
@@ -3116,8 +3129,10 @@ Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltable
3116 /*3129 /*
3117 * now add tuples to pg_attribute for the attributes in our new relation.3130 * now add tuples to pg_attribute for the attributes in our new relation.
3118 */3131 */
3119- AddNewAttributeTuples(3132+ AddNewAttributeTuples(relid, new_rel_desc->rd_att, relkind, oidislocal,
3120- relid, new_rel_desc->rd_att, relkind, oidislocal, oidinhcount, relhasbucket, relhasuids, depend_extend, relname, relnamespace);3133+ oidinhcount, relhasbucket, relhasuids, depend_extend,
3134+ relname, relnamespace, attrExtra);
3135+ 
3121 if (ceLst != NULL) {3136 if (ceLst != NULL) {
3122 AddNewGsSecEncryptedColumnsTuples(relid, ceLst);3137 AddNewGsSecEncryptedColumnsTuples(relid, ceLst);
3123 }3138 }
@@ -3482,6 +3497,7 @@ void RemoveAttributeById(Oid relid, AttrNumber attnum)
3482 values[Anum_pg_attribute_attstattarget - 1] = Int32GetDatum(0);3497 values[Anum_pg_attribute_attstattarget - 1] = Int32GetDatum(0);
3483 3498 
3484 values[Anum_pg_attribute_attdroppedname - 1] = NameGetDatum(&(attStruct->attname));3499 values[Anum_pg_attribute_attdroppedname - 1] = NameGetDatum(&(attStruct->attname));
3500+ values[Anum_pg_attribute_attidentity - 1] = CharGetDatum('\0');
3485 3501 
3486 /*3502 /*
3487 * Change the column name to something that isn't likely to conflict3503 * Change the column name to something that isn't likely to conflict
@@ -3497,6 +3513,7 @@ void RemoveAttributeById(Oid relid, AttrNumber attnum)
3497 replaces[Anum_pg_attribute_attstattarget - 1] = true;3513 replaces[Anum_pg_attribute_attstattarget - 1] = true;
3498 replaces[Anum_pg_attribute_attdroppedname - 1] = true;3514 replaces[Anum_pg_attribute_attdroppedname - 1] = true;
3499 replaces[Anum_pg_attribute_attname - 1] = true;3515 replaces[Anum_pg_attribute_attname - 1] = true;
3516+ replaces[Anum_pg_attribute_attidentity - 1] = true;
3500 3517 
3501 newatttuple = heap_modify_tuple(atttuple, RelationGetDescr(attr_rel), values, nulls, replaces);3518 newatttuple = heap_modify_tuple(atttuple, RelationGetDescr(attr_rel), values, nulls, replaces);
3502 simple_heap_update(attr_rel, &newatttuple->t_self, newatttuple);3519 simple_heap_update(attr_rel, &newatttuple->t_self, newatttuple);
@@ -3660,6 +3677,35 @@ void RemoveAttrDefaultById(Oid attrdefId)
3660 relation_close(myrel, NoLock);3677 relation_close(myrel, NoLock);
3661}3678}
3662 3679 
3680+char HeapTupleGetIdentity(HeapTuple tuple, Relation attr)
3681+{
3682+ bool isNull;
3683+ Datum d;
3684+ char identity = '\0';
3685+ 
3686+ d = tableam_tops_tuple_getattr(tuple, Anum_pg_attribute_attidentity, RelationGetDescr(attr), &isNull);
3687+ if (!isNull) {
3688+ identity = DatumGetChar(d);
3689+ }
3690+ 
3691+ return identity;
3692+}
3693+ 
3694+HeapTuple HeapTupleModifyIdentity(HeapTuple tuple, Relation attr, char identity)
3695+{
3696+ HeapTuple newTuple;
3697+ Datum values[Natts_pg_attribute] = { 0 };
3698+ bool nulls[Natts_pg_attribute] = { false };
3699+ bool replaces[Natts_pg_attribute] = { false };
3700+ 
3701+ replaces[Anum_pg_attribute_attidentity - 1] = true;
3702+ values[Anum_pg_attribute_attidentity - 1] = CharGetDatum(identity);
3703+ 
3704+ newTuple = heap_modify_tuple(tuple, RelationGetDescr(attr), values, nulls, replaces);
3705+ heap_freetuple(tuple);
3706+ return newTuple;
3707+}
3708+ 
3663/*3709/*
3664 * Remove error info table file for bulkload3710 * Remove error info table file for bulkload
3665 * there are problems in a rollback transaction3711 * there are problems in a rollback transaction
@@ -8463,7 +8509,7 @@ void AddOrDropUidsAttr(Oid relOid, bool oldRelHasUids, bool newRelHasUids)
8463 securec_check(rc, "\0", "\0");8509 securec_check(rc, "\0", "\0");
8464 /* Fill in the correct relation OID in the copied tuple */8510 /* Fill in the correct relation OID in the copied tuple */
8465 attStruct.attrelid = relOid;8511 attStruct.attrelid = relOid;
8466- InsertPgAttributeTuple(rel, &attStruct, indstate);8512+ InsertPgAttributeTuple(rel, &attStruct, NULL, indstate);
8467 CatalogCloseIndexes(indstate);8513 CatalogCloseIndexes(indstate);
8468 heap_close(rel, RowExclusiveLock);8514 heap_close(rel, RowExclusiveLock);
8469 8515 
@@ -8566,7 +8612,7 @@ HeapTuple heaptuple_from_pg_attribute(Relation pg_attribute_rel,
8566 values[Anum_pg_attribute_attcmprmode - 1] = Int8GetDatum(new_attribute->attcmprmode);8612 values[Anum_pg_attribute_attcmprmode - 1] = Int8GetDatum(new_attribute->attcmprmode);
8567 values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(new_attribute->attinhcount);8613 values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(new_attribute->attinhcount);
8568 values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(new_attribute->attcollation);8614 values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(new_attribute->attcollation);
8569- values[Anum_pg_attribute_attkvtype - 1] = Int8GetDatum(new_attribute->attkvtype);8615+ values[Anum_pg_attribute_attidentity - 1] = CharGetDatum('\0');
8570 8616 
8571 /* start out with empty permissions and empty options */8617 /* start out with empty permissions and empty options */
8572 nulls[Anum_pg_attribute_attacl - 1] = true;8618 nulls[Anum_pg_attribute_attacl - 1] = true;
@@ -562,7 +562,7 @@ static void AppendAttributeTuples(Relation indexRelation, int numatts)
562 Assert(indexTupDesc->attrs[i].attnum == i + 1);562 Assert(indexTupDesc->attrs[i].attnum == i + 1);
563 Assert(indexTupDesc->attrs[i].attcacheoff == -1);563 Assert(indexTupDesc->attrs[i].attcacheoff == -1);
564 564 
565- InsertPgAttributeTuple(pg_attribute, &indexTupDesc->attrs[i], indstate);565+ InsertPgAttributeTuple(pg_attribute, &indexTupDesc->attrs[i], NULL, indstate);
566 }566 }
567 567 
568 CatalogCloseIndexes(indstate);568 CatalogCloseIndexes(indstate);
@@ -749,13 +749,22 @@ CREATE VIEW columns AS
749 CAST(a.attnum AS sql_identifier) AS dtd_identifier,749 CAST(a.attnum AS sql_identifier) AS dtd_identifier,
750 CAST('NO' AS yes_or_no) AS is_self_referencing,750 CAST('NO' AS yes_or_no) AS is_self_referencing,
751 751 
752- CAST('NO' AS yes_or_no) AS is_identity,752+ 
753- CAST(null AS character_data) AS identity_generation,753+ CAST(CASE WHEN a.attidentity IN ('a', 'd') THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_identity,
754- CAST(null AS character_data) AS identity_start,754+ CAST(CASE a.attidentity WHEN 'a' THEN 'ALWAYS' WHEN 'd' THEN 'BY DEFAULT' END AS character_data) AS identity_generation,
755- CAST(null AS character_data) AS identity_increment,755+ CAST(CASE WHEN seq.oid IS NOT NULL THEN (pg_catalog.pg_sequence_parameters(seq.oid)).start_value ELSE NULL END
756- CAST(null AS character_data) AS identity_maximum,756+ AS character_data) AS identity_start,
757- CAST(null AS character_data) AS identity_minimum,757+ CAST(CASE WHEN seq.oid IS NOT NULL THEN (pg_catalog.pg_sequence_parameters(seq.oid)).increment ELSE NULL END
758- CAST(null AS yes_or_no) AS identity_cycle,758+ AS character_data) AS identity_increment,
759+ CAST(CASE WHEN seq.oid IS NOT NULL THEN (pg_catalog.pg_sequence_parameters(seq.oid)).maximum_value ELSE NULL END
760+ AS character_data) AS identity_maximum,
761+ CAST(CASE WHEN seq.oid IS NOT NULL THEN (pg_catalog.pg_sequence_parameters(seq.oid)).minimum_value ELSE NULL END
762+ AS character_data) AS identity_minimum,
763+ CAST(CASE WHEN seq.oid IS NOT NULL THEN
764+ CASE WHEN (pg_catalog.pg_sequence_parameters(seq.oid)).cycle_option
765+ THEN 'YES' ELSE 'NO' END
766+ ELSE NULL END
767+ AS yes_or_no) AS identity_cycle,
759 768 
760 CAST(CASE WHEN ad.adgencol = 's' THEN 'ALWAYS' ELSE 'NEVER' END AS character_data) AS is_generated,769 CAST(CASE WHEN ad.adgencol = 's' THEN 'ALWAYS' ELSE 'NEVER' END AS character_data) AS is_generated,
761 CAST(CASE WHEN ad.adgencol = 's' THEN pg_catalog.pg_get_expr(ad.adbin, ad.adrelid) END AS character_data) AS generation_expression,770 CAST(CASE WHEN ad.adgencol = 's' THEN pg_catalog.pg_get_expr(ad.adbin, ad.adrelid) END AS character_data) AS generation_expression,
@@ -783,8 +792,7 @@ CREATE VIEW columns AS
783 ELSE null792 ELSE null
784 END793 END
785 END 794 END
786- AS character_data)795+ AS character_data) AS EXTRA,
787- AS EXTRA,
788 CAST(array_to_string(ARRAY[796 CAST(array_to_string(ARRAY[
789 CASE WHEN has_column_privilege(c.oid, a.attnum, 'SELECT') THEN 'select' END,797 CASE WHEN has_column_privilege(c.oid, a.attnum, 'SELECT') THEN 'select' END,
790 CASE WHEN has_column_privilege(c.oid, a.attnum, 'INSERT') THEN 'insert' END,798 CASE WHEN has_column_privilege(c.oid, a.attnum, 'INSERT') THEN 'insert' END,
@@ -801,7 +809,9 @@ CREATE VIEW columns AS
801 ON (t.typtype = 'd' AND t.typbasetype = bt.oid)809 ON (t.typtype = 'd' AND t.typbasetype = bt.oid)
802 LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid))810 LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid))
803 ON a.attcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default')811 ON a.attcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default')
804- LEFT JOIN pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum812+ LEFT JOIN (pg_depend dep JOIN pg_class seq ON (dep.classid = 'pg_class'::regclass AND dep.objid = seq.oid AND dep.deptype = 'i' AND seq.relkind in ('s', 'S')))
813+ ON (dep.refclassid = 'pg_class'::regclass AND dep.refobjid = c.oid AND dep.refobjsubid = a.attnum)
814+ LEFT JOIN pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum
805 815 
806 WHERE (NOT pg_catalog.pg_is_other_temp_schema(nc.oid))816 WHERE (NOT pg_catalog.pg_is_other_temp_schema(nc.oid))
807 817 
@@ -1639,6 +1649,7 @@ CREATE VIEW sequences AS
1639 FROM pg_namespace nc, pg_class c1649 FROM pg_namespace nc, pg_class c
1640 WHERE c.relnamespace = nc.oid1650 WHERE c.relnamespace = nc.oid
1641 AND (c.relkind = 'L' or c.relkind = 'S')1651 AND (c.relkind = 'L' or c.relkind = 'S')
1652+ AND NOT EXISTS (SELECT 1 FROM pg_depend WHERE classid = 'pg_class'::regclass AND objid = c.oid AND deptype = 'i') /* not internal sequence */
1642 AND (NOT pg_catalog.pg_is_other_temp_schema(nc.oid))1653 AND (NOT pg_catalog.pg_is_other_temp_schema(nc.oid))
1643 AND (pg_catalog.pg_has_role(c.relowner, 'USAGE')1654 AND (pg_catalog.pg_has_role(c.relowner, 'USAGE')
1644 OR pg_catalog.has_sequence_privilege(c.oid, 'SELECT, UPDATE, USAGE') );1655 OR pg_catalog.has_sequence_privilege(c.oid, 'SELECT, UPDATE, USAGE') );
@@ -28,6 +28,7 @@
28#include "catalog/pg_proc.h"28#include "catalog/pg_proc.h"
29#include "catalog/pg_synonym.h"29#include "catalog/pg_synonym.h"
30#include "commands/extension.h"30#include "commands/extension.h"
31+#include "commands/sequence.h"
31#include "miscadmin.h"32#include "miscadmin.h"
32#include "storage/tcap.h"33#include "storage/tcap.h"
33#include "utils/fmgroids.h"34#include "utils/fmgroids.h"
@@ -707,7 +708,7 @@ Oid getExtensionOfObject(Oid classId, Oid objectId)
707/*708/*
708 * Detect whether a sequence is marked as "owned" by a column709 * Detect whether a sequence is marked as "owned" by a column
709 *710 *
710- * An ownership marker is an AUTO dependency from the sequence to the711+ * An ownership marker is an AUTO or INTERNAL dependency from the sequence to the
711 * column. If we find one, store the identity of the owning column712 * column. If we find one, store the identity of the owning column
712 * into *tableId and *colId and return TRUE; else return FALSE.713 * into *tableId and *colId and return TRUE; else return FALSE.
713 *714 *
@@ -715,7 +716,7 @@ Oid getExtensionOfObject(Oid classId, Oid objectId)
715 * a random one of them returned into the out parameters. This should716 * a random one of them returned into the out parameters. This should
716 * not happen, though.717 * not happen, though.
717 */718 */
718-bool sequenceIsOwned(Oid seqId, Oid* tableId, int32* colId)719+bool sequenceIsOwned(Oid seqId, char deptype, Oid* tableId, int32* colId)
719{720{
720 bool ret = false;721 bool ret = false;
721 Relation depRel = NULL;722 Relation depRel = NULL;
@@ -732,8 +733,8 @@ bool sequenceIsOwned(Oid seqId, Oid* tableId, int32* colId)
732 733 
733 while (HeapTupleIsValid((tup = systable_getnext(scan)))) {734 while (HeapTupleIsValid((tup = systable_getnext(scan)))) {
734 Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup);735 Form_pg_depend depform = (Form_pg_depend)GETSTRUCT(tup);
735- 736+ if (depform->refclassid == RelationRelationId &&
736- if (depform->refclassid == RelationRelationId && depform->deptype == DEPENDENCY_AUTO) {737+ depform->deptype == deptype) {
737 *tableId = depform->refobjid;738 *tableId = depform->refobjid;
738 *colId = depform->refobjsubid;739 *colId = depform->refobjsubid;
739 ret = true;740 ret = true;
@@ -748,21 +749,198 @@ bool sequenceIsOwned(Oid seqId, Oid* tableId, int32* colId)
748 return ret;749 return ret;
749}750}
750 751 
752+ 
751/*753/*
752- * Remove any existing "owned" markers for the specified sequence.754+ * Collect a list of OIDs of all sequences owned by the specified relation,
753- *755+ * and column if specified. If deptype is not zero, then only find sequences
754- * Note: we don't provide a special function to install an "owned"756+ * with the specified dependency type.
755- * marker; just use recordDependencyOn().
756 */757 */
757-void markSequenceUnowned(Oid seqId)758+static List* getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
758{759{
759- (void)deleteDependencyRecordsForClass(RelationRelationId, seqId, RelationRelationId, DEPENDENCY_AUTO);760+ List *result = NIL;
761+ Relation depRel;
762+ ScanKeyData key[3];
763+ SysScanDesc scan;
764+ HeapTuple tup;
765+ 
766+ depRel = heap_open(DependRelationId, AccessShareLock);
767+ 
768+ ScanKeyInit(&key[0],
769+ Anum_pg_depend_refclassid,
770+ BTEqualStrategyNumber, F_OIDEQ,
771+ ObjectIdGetDatum(RelationRelationId));
772+ ScanKeyInit(&key[1],
773+ Anum_pg_depend_refobjid,
774+ BTEqualStrategyNumber, F_OIDEQ,
775+ ObjectIdGetDatum(relid));
776+ if (attnum)
777+ ScanKeyInit(&key[2],
778+ Anum_pg_depend_refobjsubid,
779+ BTEqualStrategyNumber, F_INT4EQ,
780+ Int32GetDatum(attnum));
781+ 
782+ scan = systable_beginscan(depRel, DependReferenceIndexId, true,
783+ NULL, attnum ? 3 : 2, key);
784+ 
785+ while (HeapTupleIsValid(tup = systable_getnext(scan))) {
786+ Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
787+ /*
788+ * We assume any auto or internal dependency of a sequence on a column
789+ * must be what we are looking for. (We need the relkind test because
790+ * indexes can also have auto dependencies on columns.)
791+ */
792+ if (deprec->classid == RelationRelationId &&
793+ deprec->objsubid == 0 &&
794+ deprec->refobjsubid != 0 &&
795+ (deprec->deptype == DEPENDENCY_AUTO || deprec->deptype == DEPENDENCY_INTERNAL) &&
796+ RELKIND_IS_SEQUENCE(get_rel_relkind(deprec->objid))) {
797+ if (!deptype || deprec->deptype == deptype)
798+ result = lappend_oid(result, deprec->objid);
799+ }
800+ }
801+ 
802+ systable_endscan(scan);
803+ 
804+ heap_close(depRel, AccessShareLock);
805+ 
806+ return result;
760}807}
761 808 
762/*809/*
763- * Collect a list of OIDs of all sequences owned by the specified relation.810+ * Get oid of sequence owned (identity or serial) by the
811+ * column of specified relation.
764 */812 */
765-List* getOwnedSequences(Oid relid, List* attrList)813+Oid getOwnedSequence(Oid relid, AttrNumber attnum, char** seqname)
814+{
815+ Oid seqid;
816+ List *seqlist = getOwnedSequences_internal(relid, attnum, 0);
817+ 
818+ if (list_length(seqlist) > 1) {
819+ elog(ERROR, "more than one owned sequence found");
820+ } else if (seqlist == NIL) {
821+ return InvalidOid;
822+ }
823+ 
824+ if (seqname) {
825+ *seqname = NULL;
826+ }
827+ 
828+ seqid = linitial_oid(seqlist);
829+ if (OidIsValid(seqid) && seqname) {
830+ HeapTuple classtup;
831+ Form_pg_class classtuple;
832+ char* nspname = NULL;
833+ 
834+ /* Get the sequence's pg_class entry */
835+ classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(seqid));
836+ if (!HeapTupleIsValid(classtup)) {
837+ ereport(ERROR,
838+ (errcode(ERRCODE_CACHE_LOOKUP_FAILED),
839+ errmsg("cache lookup failed for relation %u", seqid)));
840+ }
841+ 
842+ classtuple = (Form_pg_class)GETSTRUCT(classtup);
843+ 
844+ /* Get the namespace */
845+ nspname = get_namespace_name(classtuple->relnamespace);
846+ if (nspname == NULL) {
847+ ReleaseSysCache(classtup);
848+ ereport(ERROR,
849+ (errcode(ERRCODE_CACHE_LOOKUP_FAILED),
850+ errmsg("cache lookup failed for namespace %u", classtuple->relnamespace)));
851+ }
852+ 
853+ /* And construct the result string */
854+ *seqname = quote_qualified_identifier(nspname, NameStr(classtuple->relname));
855+ 
856+ ReleaseSysCache(classtup);
857+ }
858+ return seqid;
859+}
860+ 
861+/*
862+ * Collect a list of OIDs of all sequences owned (identity or serial) by the
863+ * specified relation.
864+ */
865+List* getOwnedSequences(Oid relid)
866+{
867+ return getOwnedSequences_internal(relid, 0, 0);
868+}
869+ 
870+/*
871+ * Get owned identity sequence, error if not exactly one.
872+ * if forIdentityOfD, check sequence name suffix
873+ */
874+Oid getIdentitySequence(Oid relid, AttrNumber attnum, bool missing_ok, bool forIdentityOfD)
875+{
876+ List *seqlist = getOwnedSequences_internal(relid, attnum,
877+ forIdentityOfD ? DEPENDENCY_AUTO : DEPENDENCY_INTERNAL);
878+ 
879+ if (list_length(seqlist) > 1) {
880+ elog(ERROR, "more than one owned sequence found");
881+ } else if (seqlist == NIL) {
882+ if (missing_ok)
883+ return InvalidOid;
884+ else
885+ elog(ERROR, "no owned sequence found");
886+ }
887+ 
888+ Oid seqid = linitial_oid(seqlist);
889+ if (forIdentityOfD && OidIsValid(seqid)) {
890+ return StrEndWith(get_rel_name(seqid), "_seq_identity") ? seqid : InvalidOid;
891+ }
892+ 
893+ return seqid;
894+}
895+ 
896+/*
897+ * Get owned identity sequence by the specified relation in D format,
898+ * not generated as identity, if outAttrName != NULL, return attrname
899+ * which owned identity sequence.
900+ * if attrname != NULL, return the identity sequence owned by this attrname,
901+ * return InvalidOid if not.
902+ */
903+Oid getIdentitySequenceForD(Oid relid, const char* attrname, char** outAttrName)
904+{
905+ Relation rel = nullptr;
906+ TupleDesc tupdesc = nullptr;
907+ AttrNumber attnum = InvalidAttrNumber;
908+ Oid seqid = InvalidOid;
909+ 
910+ rel = RelationIdGetRelation(relid);
911+ tupdesc = RelationGetDescr(rel);
912+ 
913+ for (attnum = 1; attnum <= tupdesc->natts; attnum++) {
914+ Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
915+ if (attr->attisdropped) {
916+ continue;
917+ }
918+ 
919+ const char* attname = NameStr(attr->attname);
920+ if (attrname && (strcmp(attname, attrname) != 0)) {
921+ continue;
922+ }
923+ 
924+ seqid = getIdentitySequence(relid, attnum, true, true);
925+ if (OidIsValid(seqid)) {
926+ if (outAttrName) {
927+ *outAttrName = pstrdup(attname);
928+ }
929+ break;
930+ } else if (attrname) {
931+ RelationClose(rel);
932+ return InvalidOid;
933+ }
934+ }
935+ 
936+ RelationClose(rel);
937+ return seqid;
938+}
939+ 
940+/*
941+ * Collect a list of OIDs of all sequences owned by attriList of the specified relation.
942+ */
943+List* getOwnedSequencesOfAttrList(Oid relid, List* attrList)
766{944{
767 List* result = NIL;945 List* result = NIL;
768 Relation depRel = NULL;946 Relation depRel = NULL;
@@ -780,14 +958,15 @@ List* getOwnedSequences(Oid relid, List* attrList)
780 958 
781 while (HeapTupleIsValid(tup = systable_getnext(scan))) {959 while (HeapTupleIsValid(tup = systable_getnext(scan))) {
782 Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup);960 Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup);
783- 
784 /*961 /*
785 * We assume any auto dependency of a sequence on a column must be962 * We assume any auto dependency of a sequence on a column must be
786 * what we are looking for. (We need the relkind test because indexes963 * what we are looking for. (We need the relkind test because indexes
787 * can also have auto dependencies on columns.)964 * can also have auto dependencies on columns.)
788 */965 */
789- if (deprec->classid == RelationRelationId && deprec->objsubid == 0 && deprec->refobjsubid != 0 &&966+ if (deprec->classid == RelationRelationId &&
790- deprec->deptype == DEPENDENCY_AUTO && RELKIND_IS_SEQUENCE(get_rel_relkind(deprec->objid))) {967+ deprec->objsubid == 0 && deprec->refobjsubid != 0 &&
968+ (deprec->deptype == DEPENDENCY_AUTO || deprec->deptype == DEPENDENCY_INTERNAL) &&
969+ RELKIND_IS_SEQUENCE(get_rel_relkind(deprec->objid))) {
791 if (attrList != NULL) {970 if (attrList != NULL) {
792 if (list_member_int(attrList, deprec->refobjsubid))971 if (list_member_int(attrList, deprec->refobjsubid))
793 result = lappend_oid(result, deprec->objid);972 result = lappend_oid(result, deprec->objid);
@@ -806,8 +985,8 @@ List* getOwnedSequences(Oid relid, List* attrList)
806 985 
807/*986/*
808 * get_constraint_index987 * get_constraint_index
809- * Given the OID of a unique or primary-key constraint, return the988+ * Given the OID of a unique or primary-key constraint, return the
810- * OID of the underlying unique index.989+ * OID of the underlying unique index.
811 *990 *
812 * Return InvalidOid if the index couldn't be found; this suggests the991 * Return InvalidOid if the index couldn't be found; this suggests the
813 * given OID is bogus, but we leave it to caller to decide what to do.992 * given OID is bogus, but we leave it to caller to decide what to do.
@@ -1162,7 +1341,6 @@ void fillDepsrcIfNeeded(const ObjectAddress* origObject)
1162 1341 
1163 while (HeapTupleIsValid(tup = systable_getnext(scan))) {1342 while (HeapTupleIsValid(tup = systable_getnext(scan))) {
1164 depTuple = (Form_pg_depend)GETSTRUCT(tup);1343 depTuple = (Form_pg_depend)GETSTRUCT(tup);
1165- Datum depsrc = heap_getattr(tup, Anum_pg_depend_depsrc, RelationGetDescr(depRel), &isnull);
1166 /* skip those whose depsrc were already valid */1344 /* skip those whose depsrc were already valid */
1167 if (!isnull) {1345 if (!isnull) {
1168 continue;1346 continue;
@@ -200,7 +200,7 @@ F181 Multiple module support NO
200F191 Referential delete actions YES 200F191 Referential delete actions YES
201F200 TRUNCATE TABLE statement YES 201F200 TRUNCATE TABLE statement YES
202F201 CAST function YES 202F201 CAST function YES
203-F202 TRUNCATE TABLE: identity column restart option NO 203+F202 TRUNCATE TABLE: identity column restart option YES
204F221 Explicit defaults YES 204F221 Explicit defaults YES
205F222 INSERT statement: DEFAULT VALUES clause YES 205F222 INSERT statement: DEFAULT VALUES clause YES
206F231 Privilege tables YES 206F231 Privilege tables YES
@@ -241,9 +241,9 @@ F381 Extended schema manipulation 02 ALTER TABLE statement: ADD CONSTRAINT claus
241F381 Extended schema manipulation 03 ALTER TABLE statement: DROP CONSTRAINT clause YES 241F381 Extended schema manipulation 03 ALTER TABLE statement: DROP CONSTRAINT clause YES
242F382 Alter column data type YES 242F382 Alter column data type YES
243F383 Set column not null clause YES 243F383 Set column not null clause YES
244-F384 Drop identity property clause NO 244+F384 Drop identity property clause YES
245F385 Drop column generation expression clause NO 245F385 Drop column generation expression clause NO
246-F386 Set identity column generation clause NO 246+F386 Set identity column generation clause YES
247F391 Long identifiers YES 247F391 Long identifiers YES
248F392 Unicode escapes in identifiers YES 248F392 Unicode escapes in identifiers YES
249F393 Unicode escapes in literals YES 249F393 Unicode escapes in literals YES
@@ -420,11 +420,11 @@ T152 DISTINCT predicate with negation YES
420T171 LIKE clause in table definition YES 420T171 LIKE clause in table definition YES
421T172 AS subquery clause in table definition YES 421T172 AS subquery clause in table definition YES
422T173 Extended LIKE clause in table definition YES 422T173 Extended LIKE clause in table definition YES
423-T174 Identity columns NO 423+T174 Identity columns YES
424T175 Generated columns NO 424T175 Generated columns NO
425T176 Sequence generator support YES alter sequence is partially supported425T176 Sequence generator support YES alter sequence is partially supported
426-T177 Sequence generator support: simple restart option NO 426+T177 Sequence generator support: simple restart option YES
427-T178 Identity columns: simple restart option NO 427+T178 Identity columns: simple restart option YES
428T180 System-versioned tables NO 428T180 System-versioned tables NO
429T181 Application-time period tables NO 429T181 Application-time period tables NO
430T191 Referential action RESTRICT YES 430T191 Referential action RESTRICT YES
@@ -3577,6 +3577,19 @@ static CurrentOfExpr* _copyCurrentOfExpr(const CurrentOfExpr* from)
3577 return newnode;3577 return newnode;
3578}3578}
3579 3579 
3580+/*
3581+ * _copyNextValueExpr
3582+ */
3583+static NextValueExpr* _copyNextValueExpr(const NextValueExpr* from)
3584+{
3585+ NextValueExpr* newnode = makeNode(NextValueExpr);
3586+ 
3587+ COPY_SCALAR_FIELD(seqid);
3588+ COPY_SCALAR_FIELD(typeId);
3589+ 
3590+ return newnode;
3591+}
3592+ 
3580/*3593/*
3581 * _copyTargetEntry3594 * _copyTargetEntry
3582 */3595 */
@@ -4710,6 +4723,10 @@ static ColumnDef* _copyColumnDef(const ColumnDef* from)
4710 COPY_NODE_FIELD(raw_default);4723 COPY_NODE_FIELD(raw_default);
4711 COPY_SCALAR_FIELD(generatedCol);4724 COPY_SCALAR_FIELD(generatedCol);
4712 COPY_NODE_FIELD(cooked_default);4725 COPY_NODE_FIELD(cooked_default);
4726+ if (t_thrd.proc->workingVersionNum >= PG_IDENTITY_VERSION_NUM) {
4727+ COPY_SCALAR_FIELD(identity);
4728+ COPY_NODE_FIELD(identitySequence);
4729+ }
4713 COPY_NODE_FIELD(collClause);4730 COPY_NODE_FIELD(collClause);
4714 COPY_SCALAR_FIELD(collOid);4731 COPY_SCALAR_FIELD(collOid);
4715 COPY_NODE_FIELD(constraints);4732 COPY_NODE_FIELD(constraints);
@@ -5225,6 +5242,7 @@ static Query* _copyQuery(const Query* from)
5225 COPY_SCALAR_FIELD(isFetch);5242 COPY_SCALAR_FIELD(isFetch);
5226 }5243 }
5227 COPY_NODE_FIELD(rowMarks);5244 COPY_NODE_FIELD(rowMarks);
5245+ COPY_SCALAR_FIELD(override);
5228 COPY_NODE_FIELD(setOperations);5246 COPY_NODE_FIELD(setOperations);
5229 COPY_NODE_FIELD(constraintDeps);5247 COPY_NODE_FIELD(constraintDeps);
5230 COPY_NODE_FIELD(hintState);5248 COPY_NODE_FIELD(hintState);
@@ -5316,6 +5334,7 @@ static InsertStmt* _copyInsertStmt(const InsertStmt* from)
5316 COPY_NODE_FIELD(returningList);5334 COPY_NODE_FIELD(returningList);
5317 COPY_NODE_FIELD(withClause);5335 COPY_NODE_FIELD(withClause);
5318 COPY_NODE_FIELD(upsertClause);5336 COPY_NODE_FIELD(upsertClause);
5337+ COPY_SCALAR_FIELD(override);
5319 COPY_NODE_FIELD(hintState);5338 COPY_NODE_FIELD(hintState);
5320 if (t_thrd.proc->workingVersionNum >= REPLACE_INTO_VERSION_NUM) {5339 if (t_thrd.proc->workingVersionNum >= REPLACE_INTO_VERSION_NUM) {
5321 COPY_NODE_FIELD(targetList);5340 COPY_NODE_FIELD(targetList);
@@ -6425,6 +6444,7 @@ static CreateSeqStmt* _copyCreateSeqStmt(const CreateSeqStmt* from)
6425 COPY_SCALAR_FIELD(is_large);6444 COPY_SCALAR_FIELD(is_large);
6426 COPY_SCALAR_FIELD(missing_ok);6445 COPY_SCALAR_FIELD(missing_ok);
6427 COPY_SCALAR_FIELD(is_autoinc);6446 COPY_SCALAR_FIELD(is_autoinc);
6447+ COPY_SCALAR_FIELD(forIdentity);
6428 6448 
6429 return newnode;6449 return newnode;
6430}6450}
@@ -6438,6 +6458,7 @@ static AlterSeqStmt* _copyAlterSeqStmt(const AlterSeqStmt* from)
6438 COPY_SCALAR_FIELD(missing_ok);6458 COPY_SCALAR_FIELD(missing_ok);
6439 COPY_SCALAR_FIELD(is_large);6459 COPY_SCALAR_FIELD(is_large);
6440 COPY_SCALAR_FIELD(is_autoinc);6460 COPY_SCALAR_FIELD(is_autoinc);
6461+ COPY_SCALAR_FIELD(forIdentity);
6441 6462 
6442 return newnode;6463 return newnode;
6443}6464}
@@ -8720,6 +8741,9 @@ void* copyObject(const void* from)
8720 case T_CurrentOfExpr:8741 case T_CurrentOfExpr:
8721 retval = _copyCurrentOfExpr((CurrentOfExpr*)from);8742 retval = _copyCurrentOfExpr((CurrentOfExpr*)from);
8722 break;8743 break;
8744+ case T_NextValueExpr:
8745+ retval = _copyNextValueExpr((NextValueExpr*)from);
8746+ break;
8723 case T_TargetEntry:8747 case T_TargetEntry:
8724 retval = _copyTargetEntry((TargetEntry*)from);8748 retval = _copyTargetEntry((TargetEntry*)from);
8725 break;8749 break;
@@ -763,6 +763,14 @@ static bool _equalCurrentOfExpr(const CurrentOfExpr* a, const CurrentOfExpr* b)
763 return true;763 return true;
764}764}
765 765 
766+static bool _equalNextValueExpr(const NextValueExpr* a, const NextValueExpr* b)
767+{
768+ COMPARE_SCALAR_FIELD(seqid);
769+ COMPARE_SCALAR_FIELD(typeId);
770+ 
771+ return true;
772+}
773+ 
766static bool _equalTargetEntry(const TargetEntry* a, const TargetEntry* b)774static bool _equalTargetEntry(const TargetEntry* a, const TargetEntry* b)
767{775{
768 COMPARE_NODE_FIELD(expr);776 COMPARE_NODE_FIELD(expr);
@@ -1043,6 +1051,7 @@ static bool _equalQuery(const Query* a, const Query* b)
1043 COMPARE_SCALAR_FIELD(isFetch);1051 COMPARE_SCALAR_FIELD(isFetch);
1044 }1052 }
1045 COMPARE_NODE_FIELD(rowMarks);1053 COMPARE_NODE_FIELD(rowMarks);
1054+ COMPARE_SCALAR_FIELD(override);
1046 COMPARE_NODE_FIELD(setOperations);1055 COMPARE_NODE_FIELD(setOperations);
1047 COMPARE_NODE_FIELD(constraintDeps);1056 COMPARE_NODE_FIELD(constraintDeps);
1048 1057 
@@ -1097,7 +1106,8 @@ static bool _equalInsertStmt(const InsertStmt* a, const InsertStmt* b)
1097 COMPARE_NODE_FIELD(targetList);1106 COMPARE_NODE_FIELD(targetList);
1098 COMPARE_SCALAR_FIELD(isReplace);1107 COMPARE_SCALAR_FIELD(isReplace);
1099 }1108 }
1100- COMPARE_NODE_FIELD(upsertClause); 1109+ COMPARE_NODE_FIELD(upsertClause);
1110+ COMPARE_SCALAR_FIELD(override);
1101 COMPARE_SCALAR_FIELD(hasIgnore);1111 COMPARE_SCALAR_FIELD(hasIgnore);
1102 COMPARE_SCALAR_FIELD(is_dist_insertselect);1112 COMPARE_SCALAR_FIELD(is_dist_insertselect);
1103 1113 
@@ -2078,6 +2088,7 @@ static bool _equalCreateSeqStmt(const CreateSeqStmt* a, const CreateSeqStmt* b)
2078 COMPARE_NODE_FIELD(sequence);2088 COMPARE_NODE_FIELD(sequence);
2079 COMPARE_NODE_FIELD(options);2089 COMPARE_NODE_FIELD(options);
2080 COMPARE_SCALAR_FIELD(ownerId);2090 COMPARE_SCALAR_FIELD(ownerId);
2091+
2081#ifdef PGXC2092#ifdef PGXC
2082 COMPARE_SCALAR_FIELD(is_serial);2093 COMPARE_SCALAR_FIELD(is_serial);
2083#endif2094#endif
@@ -2086,6 +2097,7 @@ static bool _equalCreateSeqStmt(const CreateSeqStmt* a, const CreateSeqStmt* b)
2086 COMPARE_SCALAR_FIELD(is_large);2097 COMPARE_SCALAR_FIELD(is_large);
2087 COMPARE_SCALAR_FIELD(missing_ok);2098 COMPARE_SCALAR_FIELD(missing_ok);
2088 COMPARE_SCALAR_FIELD(is_autoinc);2099 COMPARE_SCALAR_FIELD(is_autoinc);
2100+ COMPARE_SCALAR_FIELD(forIdentity);
2089 2101 
2090 return true;2102 return true;
2091}2103}
@@ -2097,6 +2109,7 @@ static bool _equalAlterSeqStmt(const AlterSeqStmt* a, const AlterSeqStmt* b)
2097 COMPARE_SCALAR_FIELD(missing_ok);2109 COMPARE_SCALAR_FIELD(missing_ok);
2098 COMPARE_SCALAR_FIELD(is_large);2110 COMPARE_SCALAR_FIELD(is_large);
2099 COMPARE_SCALAR_FIELD(is_autoinc);2111 COMPARE_SCALAR_FIELD(is_autoinc);
2112+ COMPARE_SCALAR_FIELD(forIdentity);
2100 2113 
2101 return true;2114 return true;
2102}2115}
@@ -3060,6 +3073,10 @@ static bool _equalColumnDef(const ColumnDef* a, const ColumnDef* b)
3060 COMPARE_SCALAR_FIELD(cmprs_mode);3073 COMPARE_SCALAR_FIELD(cmprs_mode);
3061 COMPARE_NODE_FIELD(raw_default);3074 COMPARE_NODE_FIELD(raw_default);
3062 COMPARE_NODE_FIELD(cooked_default);3075 COMPARE_NODE_FIELD(cooked_default);
3076+ if (t_thrd.proc->workingVersionNum >= PG_IDENTITY_VERSION_NUM) {
3077+ COMPARE_SCALAR_FIELD(identity);
3078+ COMPARE_NODE_FIELD(identitySequence);
3079+ }
3063 COMPARE_SCALAR_FIELD(generatedCol);3080 COMPARE_SCALAR_FIELD(generatedCol);
3064 COMPARE_NODE_FIELD(collClause);3081 COMPARE_NODE_FIELD(collClause);
3065 COMPARE_NODE_FIELD(clientLogicColumnRef);3082 COMPARE_NODE_FIELD(clientLogicColumnRef);
@@ -4058,6 +4075,9 @@ bool equal(const void* a, const void* b)
4058 case T_CurrentOfExpr:4075 case T_CurrentOfExpr:
4059 retval = _equalCurrentOfExpr((CurrentOfExpr*)a, (CurrentOfExpr*)b);4076 retval = _equalCurrentOfExpr((CurrentOfExpr*)a, (CurrentOfExpr*)b);
4060 break;4077 break;
4078+ case T_NextValueExpr:
4079+ retval = _equalNextValueExpr((NextValueExpr*)a, (NextValueExpr*)b);
4080+ break;
4061 case T_TargetEntry:4081 case T_TargetEntry:
4062 retval = _equalTargetEntry((TargetEntry*)a, (TargetEntry*)b);4082 retval = _equalTargetEntry((TargetEntry*)a, (TargetEntry*)b);
4063 break;4083 break;
@@ -187,6 +187,9 @@ Oid exprType(const Node* expr)
187 case T_CoerceViaIO:187 case T_CoerceViaIO:
188 type = ((const CoerceViaIO*)expr)->resulttype;188 type = ((const CoerceViaIO*)expr)->resulttype;
189 break;189 break;
190+ case T_NextValueExpr:
191+ type = ((const NextValueExpr *) expr)->typeId;
192+ break;
190 case T_ArrayCoerceExpr:193 case T_ArrayCoerceExpr:
191 type = ((const ArrayCoerceExpr*)expr)->resulttype;194 type = ((const ArrayCoerceExpr*)expr)->resulttype;
192 break;195 break;
@@ -876,6 +879,10 @@ Oid exprCollation(const Node* expr)
876 case T_NullIfExpr:879 case T_NullIfExpr:
877 coll = ((const NullIfExpr*)expr)->opcollid;880 coll = ((const NullIfExpr*)expr)->opcollid;
878 break;881 break;
882+ case T_NextValueExpr:
883+ /* NextValueExpr's result is an integer type ... */
884+ coll = InvalidOid; /* ... so it has no collation */
885+ break;
879 case T_ScalarArrayOpExpr:886 case T_ScalarArrayOpExpr:
880 coll = InvalidOid; /* result is always boolean */887 coll = InvalidOid; /* result is always boolean */
881 break;888 break;
@@ -1785,6 +1792,7 @@ bool expression_tree_walker(Node* node, bool (*walker)(), void* context)
1785 case T_BitString:1792 case T_BitString:
1786 case T_TSQL_HexString:1793 case T_TSQL_HexString:
1787 case T_Null:1794 case T_Null:
1795+ case T_NextValueExpr:
1788 case T_PgFdwRemoteInfo:1796 case T_PgFdwRemoteInfo:
1789 case T_Rownum:1797 case T_Rownum:
1790 case T_UserVar:1798 case T_UserVar:
@@ -2460,6 +2468,7 @@ Node* expression_tree_mutator(Node* node, Node* (*mutator)(Node*, void*), void*
2460 case T_RangeTblRef:2468 case T_RangeTblRef:
2461 case T_SortGroupClause:2469 case T_SortGroupClause:
2462 case T_GroupingId:2470 case T_GroupingId:
2471+ case T_NextValueExpr:
2463 if (isCopy) {2472 if (isCopy) {
2464 return (Node*)copyObject(node);2473 return (Node*)copyObject(node);
2465 } else {2474 } else {
@@ -211,6 +211,7 @@ static const TagStr g_tagStrArr[] = {{T_Invalid, "Invalid"},
211 {T_CoerceToDomainValue, "CoerceToDomainValue"},211 {T_CoerceToDomainValue, "CoerceToDomainValue"},
212 {T_SetToDefault, "SetToDefault"},212 {T_SetToDefault, "SetToDefault"},
213 {T_CurrentOfExpr, "CurrentOfExpr"},213 {T_CurrentOfExpr, "CurrentOfExpr"},
214+ {T_NextValueExpr, "NextValueExpr"},
214 {T_TargetEntry, "TargetEntry"},215 {T_TargetEntry, "TargetEntry"},
215 {T_RangeTblRef, "RangeTblRef"},216 {T_RangeTblRef, "RangeTblRef"},
216 {T_JoinExpr, "JoinExpr"},217 {T_JoinExpr, "JoinExpr"},
@@ -2333,18 +2333,18 @@ static void _outLimit(StringInfo str, Limit* node)
2333 2333 
2334 if (node->numCols > 0) {2334 if (node->numCols > 0) {
2335 appendStringInfo(str, " :sortColIdx");2335 appendStringInfo(str, " :sortColIdx");
2336- for (size_t i = 0; i < node->numCols; i++) {2336+ for (int i = 0; i < node->numCols; i++) {
2337 appendStringInfo(str, " %d", node->sortColIdx[i]);2337 appendStringInfo(str, " %d", node->sortColIdx[i]);
2338 }2338 }
2339 2339 
2340 WRITE_GRPOP_FIELD(equalOperators, numCols);2340 WRITE_GRPOP_FIELD(equalOperators, numCols);
2341 2341 
2342 appendStringInfo(str, " :collations");2342 appendStringInfo(str, " :collations");
2343- for (size_t i = 0; i < node->numCols; i++) {2343+ for (int i = 0; i < node->numCols; i++) {
2344 appendStringInfo(str, " %u", node->collations[i]);2344 appendStringInfo(str, " %u", node->collations[i]);
2345 }2345 }
2346 2346 
2347- for (size_t i = 0; i < node->numCols; i++) {2347+ for (int i = 0; i < node->numCols; i++) {
2348 if (node->collations[i] >= FirstBootstrapObjectId &&2348 if (node->collations[i] >= FirstBootstrapObjectId &&
2349 IsStatisfyUpdateCompatibility(node->collations[i])) {2349 IsStatisfyUpdateCompatibility(node->collations[i])) {
2350 appendStringInfo(str, " :collname ");2350 appendStringInfo(str, " :collname ");
@@ -3332,6 +3332,15 @@ static void _outCurrentOfExpr(StringInfo str, CurrentOfExpr* node)
3332 WRITE_INT_FIELD(cursor_param);3332 WRITE_INT_FIELD(cursor_param);
3333}3333}
3334 3334 
3335+static void _outNextValueExpr(StringInfo str, NextValueExpr* node)
3336+{
3337+ WRITE_NODE_TYPE("NEXTVALUEEXPR");
3338+ 
3339+ WRITE_UINT_FIELD(seqid);
3340+ WRITE_UINT_FIELD(typeId);
3341+}
3342+ 
3343+ 
3335static void _outTargetEntry(StringInfo str, TargetEntry* node)3344static void _outTargetEntry(StringInfo str, TargetEntry* node)
3336{3345{
3337 WRITE_NODE_TYPE("TARGETENTRY");3346 WRITE_NODE_TYPE("TARGETENTRY");
@@ -4569,6 +4578,10 @@ static void _outColumnDef(StringInfo str, ColumnDef* node)
4569 WRITE_ENUM_FIELD(cmprs_mode, void);4578 WRITE_ENUM_FIELD(cmprs_mode, void);
4570 WRITE_NODE_FIELD(raw_default);4579 WRITE_NODE_FIELD(raw_default);
4571 WRITE_NODE_FIELD(cooked_default);4580 WRITE_NODE_FIELD(cooked_default);
4581+ if (t_thrd.proc->workingVersionNum >=PG_IDENTITY_VERSION_NUM) {
4582+ WRITE_CHAR_FIELD(identity);
4583+ WRITE_NODE_FIELD(identitySequence);
4584+ }
4572 WRITE_NODE_FIELD(collClause);4585 WRITE_NODE_FIELD(collClause);
4573 WRITE_OID_FIELD(collOid);4586 WRITE_OID_FIELD(collOid);
4574 WRITE_NODE_FIELD(constraints);4587 WRITE_NODE_FIELD(constraints);
@@ -5196,6 +5209,9 @@ static void _outQuery(StringInfo str, Query* node)
5196 WRITE_BOOL_FIELD(isFetch);5209 WRITE_BOOL_FIELD(isFetch);
5197 }5210 }
5198 WRITE_NODE_FIELD(rowMarks);5211 WRITE_NODE_FIELD(rowMarks);
5212+ if (t_thrd.proc->workingVersionNum >= PG_IDENTITY_VERSION_NUM) {
5213+ WRITE_ENUM_FIELD(override, OverridingKind);
5214+ }
5199 WRITE_NODE_FIELD(setOperations);5215 WRITE_NODE_FIELD(setOperations);
5200 WRITE_NODE_FIELD(constraintDeps);5216 WRITE_NODE_FIELD(constraintDeps);
5201 WRITE_NODE_FIELD(hintState);5217 WRITE_NODE_FIELD(hintState);
@@ -6104,7 +6120,13 @@ static void _outConstraint(StringInfo str, Constraint* node)
6104 }6120 }
6105 break;6121 break;
6106 6122 
6107- case CONSTR_IDENTITY:6123+ case CONSTR_GENERATED_IDENTITY:
6124+ if (t_thrd.proc->workingVersionNum >= PG_IDENTITY_VERSION_NUM) {
6125+ appendStringInfoString(str, "GENERATED_AS_IDENTITY");
6126+ WRITE_CHAR_FIELD(generated_when);
6127+ }
6128+ break;
6129+ case CONSTR_D_IDENTITY:
6108 if (IDENTITY_VERSION_NUM_MACRO) {6130 if (IDENTITY_VERSION_NUM_MACRO) {
6109 appendStringInfo(str, "IDENTITY");6131 appendStringInfo(str, "IDENTITY");
6110 WRITE_CHAR_FIELD(generated_when);6132 WRITE_CHAR_FIELD(generated_when);
@@ -6346,18 +6368,18 @@ static void _outVecLimit(StringInfo str, VecLimit* node)
6346 6368 
6347 if (node->numCols > 0) {6369 if (node->numCols > 0) {
6348 appendStringInfo(str, " :sortColIdx");6370 appendStringInfo(str, " :sortColIdx");
6349- for (size_t i = 0; i < node->numCols; i++) {6371+ for (int i = 0; i < node->numCols; i++) {
6350 appendStringInfo(str, " %d", node->sortColIdx[i]);6372 appendStringInfo(str, " %d", node->sortColIdx[i]);
6351 }6373 }
6352 6374 
6353 WRITE_GRPOP_FIELD(equalOperators, numCols);6375 WRITE_GRPOP_FIELD(equalOperators, numCols);
6354 6376 
6355 appendStringInfo(str, " :collations");6377 appendStringInfo(str, " :collations");
6356- for (size_t i = 0; i < node->numCols; i++) {6378+ for (int i = 0; i < node->numCols; i++) {
6357 appendStringInfo(str, " %u", node->collations[i]);6379 appendStringInfo(str, " %u", node->collations[i]);
6358 }6380 }
6359 6381 
6360- for (size_t i = 0; i < node->numCols; i++) {6382+ for (int i = 0; i < node->numCols; i++) {
6361 if (node->collations[i] >= FirstBootstrapObjectId6383 if (node->collations[i] >= FirstBootstrapObjectId
6362 && IsStatisfyUpdateCompatibility(node->collations[i])) {6384 && IsStatisfyUpdateCompatibility(node->collations[i])) {
6363 appendStringInfo(str, " :collname ");6385 appendStringInfo(str, " :collname ");
@@ -7167,6 +7189,9 @@ static void _outNode(StringInfo str, const void* obj)
7167 case T_CurrentOfExpr:7189 case T_CurrentOfExpr:
7168 _outCurrentOfExpr(str, (CurrentOfExpr*)obj);7190 _outCurrentOfExpr(str, (CurrentOfExpr*)obj);
7169 break;7191 break;
7192+ case T_NextValueExpr:
7193+ _outNextValueExpr(str, (NextValueExpr*)obj);
7194+ break;
7170 case T_TargetEntry:7195 case T_TargetEntry:
7171 _outTargetEntry(str, (TargetEntry*)obj);7196 _outTargetEntry(str, (TargetEntry*)obj);
7172 break;7197 break;
@@ -1622,6 +1622,9 @@ static Query* _readQuery(void)
1622 READ_BOOL_FIELD(isFetch);1622 READ_BOOL_FIELD(isFetch);
1623 }1623 }
1624 READ_NODE_FIELD(rowMarks);1624 READ_NODE_FIELD(rowMarks);
1625+ IF_EXIST(override) {
1626+ READ_ENUM_FIELD(override, OverridingKind);
1627+ }
1625 READ_NODE_FIELD(setOperations);1628 READ_NODE_FIELD(setOperations);
1626 READ_NODE_FIELD(constraintDeps);1629 READ_NODE_FIELD(constraintDeps);
1627 1630 
@@ -3240,6 +3243,19 @@ static CurrentOfExpr* _readCurrentOfExpr(void)
3240 READ_DONE();3243 READ_DONE();
3241}3244}
3242 3245 
3246+/*
3247+ * _readNextValueExpr
3248+ */
3249+static NextValueExpr* _readNextValueExpr(void)
3250+{
3251+ READ_LOCALS(NextValueExpr);
3252+ 
3253+ READ_UINT_FIELD(seqid);
3254+ READ_UINT_FIELD(typeId);
3255+ 
3256+ READ_DONE();
3257+}
3258+ 
3243/*3259/*
3244 * _readTargetEntry3260 * _readTargetEntry
3245 */3261 */
@@ -6275,6 +6291,12 @@ static ColumnDef* _readColumnDef()
6275 READ_ENUM_FIELD(cmprs_mode, int8);6291 READ_ENUM_FIELD(cmprs_mode, int8);
6276 READ_NODE_FIELD(raw_default);6292 READ_NODE_FIELD(raw_default);
6277 READ_NODE_FIELD(cooked_default);6293 READ_NODE_FIELD(cooked_default);
6294+ IF_EXIST(identity) {
6295+ READ_CHAR_FIELD(identity);
6296+ }
6297+ IF_EXIST(identitySequence) {
6298+ READ_NODE_FIELD(identitySequence);
6299+ }
6278 READ_NODE_FIELD(collClause);6300 READ_NODE_FIELD(collClause);
6279 READ_OID_FIELD(collOid);6301 READ_OID_FIELD(collOid);
6280 READ_NODE_FIELD(constraints);6302 READ_NODE_FIELD(constraints);
@@ -6547,8 +6569,13 @@ static Constraint* _readConstraint()
6547 IF_EXIST(generated_kind) {6569 IF_EXIST(generated_kind) {
6548 READ_CHAR_FIELD(generated_kind);6570 READ_CHAR_FIELD(generated_kind);
6549 }6571 }
6572+ } else if (MATCH_TYPE("GENERATED_AS_IDENTITY")) {
6573+ local_node->contype = CONSTR_GENERATED_IDENTITY;
6574+ IF_EXIST(generated_when) {
6575+ READ_CHAR_FIELD(generated_when);
6576+ }
6550 } else if (MATCH_TYPE("IDENTITY")) {6577 } else if (MATCH_TYPE("IDENTITY")) {
6551- local_node->contype = CONSTR_IDENTITY;6578+ local_node->contype = CONSTR_D_IDENTITY;
6552 IF_EXIST(generated_when) {6579 IF_EXIST(generated_when) {
6553 READ_CHAR_FIELD(generated_when);6580 READ_CHAR_FIELD(generated_when);
6554 }6581 }
@@ -7127,6 +7154,8 @@ Node* parseNodeString(void)
7127 return_value = _readSetToDefault();7154 return_value = _readSetToDefault();
7128 } else if (MATCH("CURRENTOFEXPR", 13)) {7155 } else if (MATCH("CURRENTOFEXPR", 13)) {
7129 return_value = _readCurrentOfExpr();7156 return_value = _readCurrentOfExpr();
7157+ } else if (MATCH("NEXTVALUEEXPR", 13)) {
7158+ return_value = _readNextValueExpr();
7130 } else if (MATCH("TARGETENTRY", 11)) {7159 } else if (MATCH("TARGETENTRY", 11)) {
7131 return_value = _readTargetEntry();7160 return_value = _readTargetEntry();
7132 } else if (MATCH("PSEUDOTARGETENTRY", 17)) {7161 } else if (MATCH("PSEUDOTARGETENTRY", 17)) {
@@ -1891,7 +1891,7 @@ static Query* transformInsertStmt(ParseState* pstate, InsertStmt* stmt)
1891 AssertEreport(pstate->p_ctenamespace == NIL, MOD_OPT, "para should be NIL");1891 AssertEreport(pstate->p_ctenamespace == NIL, MOD_OPT, "para should be NIL");
1892 1892 
1893 RightRefState* rightRefState = MakeRightRefStateIfSupported((SelectStmt*)stmt->selectStmt);1893 RightRefState* rightRefState = MakeRightRefStateIfSupported((SelectStmt*)stmt->selectStmt);
1894- 1894+ 
1895 qry->commandType = CMD_INSERT;1895 qry->commandType = CMD_INSERT;
1896 pstate->p_is_insert = true;1896 pstate->p_is_insert = true;
1897 pstate->p_has_ignore = stmt->hasIgnore;1897 pstate->p_has_ignore = stmt->hasIgnore;
@@ -1909,7 +1909,7 @@ static Query* transformInsertStmt(ParseState* pstate, InsertStmt* stmt)
1909 selectStmt = (SelectStmt *)stmt->selectStmt;1909 selectStmt = (SelectStmt *)stmt->selectStmt;
1910 ListCell* o_target = NULL;1910 ListCell* o_target = NULL;
1911 List *ctext_expr_list = NULL;1911 List *ctext_expr_list = NULL;
1912- 1912+ 
1913 foreach (o_target, stmt->targetList) {1913 foreach (o_target, stmt->targetList) {
1914 ResTarget* res = (ResTarget*)lfirst(o_target);1914 ResTarget* res = (ResTarget*)lfirst(o_target);
1915 1915 
@@ -2005,7 +2005,7 @@ static Query* transformInsertStmt(ParseState* pstate, InsertStmt* stmt)
2005 2005 
2006 /* Validate stmt->cols list, or build default list if no list given */2006 /* Validate stmt->cols list, or build default list if no list given */
2007 icolumns = checkInsertTargets(pstate, stmt->cols, &attrnos);2007 icolumns = checkInsertTargets(pstate, stmt->cols, &attrnos);
2008- 2008+ 
2009 AssertEreport(list_length(icolumns) == list_length(attrnos), MOD_OPT, "list length inconsistent");2009 AssertEreport(list_length(icolumns) == list_length(attrnos), MOD_OPT, "list length inconsistent");
2010 2010 
2011 /*2011 /*
@@ -2398,6 +2398,9 @@ static Query* transformInsertStmt(ParseState* pstate, InsertStmt* stmt)
2398 }2398 }
2399 }2399 }
2400 2400 
2401+ /* overriding clause */
2402+ qry->override = stmt->override;
2403+ 
2401 /* done building the range table and jointree */2404 /* done building the range table and jointree */
2402 qry->rtable = pstate->p_rtable;2405 qry->rtable = pstate->p_rtable;
2403 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);2406 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
@@ -5027,10 +5030,8 @@ static List* transformUpdateTargetList(ParseState* pstate, List* qryTlist, List*
5027 UndefinedColumnError(pstate, origTarget, targetRelationNum);5030 UndefinedColumnError(pstate, origTarget, targetRelationNum);
5028 }5031 }
5029 5032 
5030- checkIdentityColumn(pstate, targetrel, origTarget, attrno, "update");
5031- 
5032 updateTargetListEntry(pstate, tle, origTarget->name, attrno, origTarget->indirection, origTarget->location,5033 updateTargetListEntry(pstate, tle, origTarget->name, attrno, origTarget->indirection, origTarget->location,
5033- targetrel, target_rte);5034+ targetrel, target_rte);
5034 checkSRFInMultiUpdate(tle->expr, targetRelationNum);5035 checkSRFInMultiUpdate(tle->expr, targetRelationNum);
5035 tle->rtindex = rtindex;5036 tle->rtindex = rtindex;
5036 new_tle[rtindex - 1] = lappend(new_tle[rtindex - 1], tle);5037 new_tle[rtindex - 1] = lappend(new_tle[rtindex - 1], tle);
@@ -471,7 +471,7 @@ static bool is_temp_table(const char relpst);
471%type <node> alter_table_cmd alter_partition_cmd alter_type_cmd opt_collate_clause exchange_partition_cmd move_partition_cmd471%type <node> alter_table_cmd alter_partition_cmd alter_type_cmd opt_collate_clause exchange_partition_cmd move_partition_cmd
472 modify_column_cmd reset_partition_cmd modify_partition_cmd472 modify_column_cmd reset_partition_cmd modify_partition_cmd
473 replica_identity add_column_first_after event_from_clause add_column_cmd473 replica_identity add_column_first_after event_from_clause add_column_cmd
474-%type <list> alter_table_cmds alter_partition_cmds alter_table_or_partition alter_type_cmds add_column_cmds modify_column_cmds474+%type <list> alter_table_cmds alter_partition_cmds alter_table_or_partition alter_type_cmds add_column_cmds alter_identity_column_option_list modify_column_cmds
475 475 
476%type <dbehavior> opt_drop_behavior476%type <dbehavior> opt_drop_behavior
477 477 
@@ -482,7 +482,7 @@ static bool is_temp_table(const char relpst);
482 opt_pgxcnodes fields_options_list fields_options_fin lines_options_list482 opt_pgxcnodes fields_options_list fields_options_fin lines_options_list
483%type <defelt> createdb_opt_item alterdb_opt_item copy_opt_item characterset_option483%type <defelt> createdb_opt_item alterdb_opt_item copy_opt_item characterset_option
484 transaction_mode_item lines_option_item fields_options_item484 transaction_mode_item lines_option_item fields_options_item
485- create_extension_opt_item alter_extension_opt_item485+ create_extension_opt_item alter_extension_opt_item alter_identity_column_option
486 start_opt preserve_opt rename_opt status_opt comments_opt action_opt486 start_opt preserve_opt rename_opt status_opt comments_opt action_opt
487 end_opt definer_name_opt487 end_opt definer_name_opt
488 488 
@@ -658,7 +658,7 @@ static bool is_temp_table(const char relpst);
658%type <ival> row_or_rows first_or_next658%type <ival> row_or_rows first_or_next
659%type <boolean> opt_percent only_or_ties659%type <boolean> opt_percent only_or_ties
660 660 
661-%type <list> OptSeqOptList SeqOptList661+%type <list> OptSeqOptList SeqOptList OptParenthesizedSeqOptList
662%type <boolean> ignNulls fromLast662%type <boolean> ignNulls fromLast
663%type <defelt> SeqOptElem663%type <defelt> SeqOptElem
664 664 
@@ -799,7 +799,8 @@ static bool is_temp_table(const char relpst);
799%type <boolean> opt_if_not_exists799%type <boolean> opt_if_not_exists
800%type <chr> OptCompress generated_column_option800%type <chr> OptCompress generated_column_option
801%type <ival> KVType801%type <ival> KVType
802-%type <ival> ColCmprsMode802+%type <ival> ColCmprsMode
803+%type <ival> generated_when override_kind
803%type <fun_src> subprogram_body804%type <fun_src> subprogram_body
804%type <keyword> as_is as_empty805%type <keyword> as_is as_empty
805%type <node> column_item opt_table_partitioning_clause806%type <node> column_item opt_table_partitioning_clause
@@ -809,7 +810,7 @@ static bool is_temp_table(const char relpst);
809 range_start_end_item range_less_than_item list_partition_item hash_partition_item810 range_start_end_item range_less_than_item list_partition_item hash_partition_item
810 subpartitioning_clause range_subpartitioning_clause hash_subpartitioning_clause811 subpartitioning_clause range_subpartitioning_clause hash_subpartitioning_clause
811 list_subpartitioning_clause subpartition_item opt_subpartition_index_def812 list_subpartitioning_clause subpartition_item opt_subpartition_index_def
812- range_subpartition_index_list range_subpartition_index_item813+ range_subpartition_index_list range_subpartition_index_item
813%type <list> range_partition_definition_list list_partition_definition_list hash_partition_definition_list maxValueList listValueList814%type <list> range_partition_definition_list list_partition_definition_list hash_partition_definition_list maxValueList listValueList
814 column_item_list tablespaceList opt_interval_tablespaceList opt_hash_partition_definition_list815 column_item_list tablespaceList opt_interval_tablespaceList opt_hash_partition_definition_list
815 split_dest_partition_define_list split_dest_listsubpartition_define_list split_dest_rangesubpartition_define_list816 split_dest_partition_define_list split_dest_listsubpartition_define_list split_dest_rangesubpartition_define_list
@@ -1000,7 +1001,7 @@ static bool is_temp_table(const char relpst);
1000 NOT NOTHING NOTIFY NOTNULL NOVALIDATE NOWAIT NTH_VALUE_P NULL_P NULLCOLS NULLIF NULLS_P NUMBER_P NUMERIC NUMSTR NVARCHAR NVARCHAR2 NVL1001 NOT NOTHING NOTIFY NOTNULL NOVALIDATE NOWAIT NTH_VALUE_P NULL_P NULLCOLS NULLIF NULLS_P NUMBER_P NUMERIC NUMSTR NVARCHAR NVARCHAR2 NVL
1001 1002 
1002 OBJECT_P OF OFF OFFSET OIDS ON ONLY OPERATOR OPTIMIZATION OPTION OPTIONALLY OPTIONS OR1003 OBJECT_P OF OFF OFFSET OIDS ON ONLY OPERATOR OPTIMIZATION OPTION OPTIONALLY OPTIONS OR
1003- ORDER ORDINALITY OUT_P OUTER_P OVER OVERLAPS OVERLAY OWNED OWNER OUTFILE1004+ ORDER ORDINALITY OUT_P OUTER_P OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER OUTFILE
1004 1005 
1005 PACKAGE PACKAGES PARALLEL_ENABLE PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PCTFREE PER_P PERCENT PERFORMANCE PERM PLACING PLAN PLANS POLICY POSITION1006 PACKAGE PACKAGES PARALLEL_ENABLE PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PCTFREE PER_P PERCENT PERFORMANCE PERM PLACING PLAN PLANS POLICY POSITION
1006 PIPELINED1007 PIPELINED
@@ -4068,7 +4069,7 @@ AlterTableStmt:
4068 n->missing_ok = true;4069 n->missing_ok = true;
4069 $$ = (Node *)n;4070 $$ = (Node *)n;
4070 }4071 }
4071- | ALTER STREAM qualified_name alter_table_cmds4072+ | ALTER STREAM qualified_name alter_table_cmds
4072 {4073 {
4073 AlterTableStmt *n = makeNode(AlterTableStmt);4074 AlterTableStmt *n = makeNode(AlterTableStmt);
4074 n->relation = $3;4075 n->relation = $3;
@@ -5082,6 +5083,53 @@ alter_table_cmd:
5082 n->def = (Node *) makeString($6);5083 n->def = (Node *) makeString($6);
5083 $$ = (Node *)n;5084 $$ = (Node *)n;
5084 }5085 }
5086+ /* ALTER TABLE <name> ALTER [COLUMN] <colname> ADD GENERATED ... AS IDENTITY ... */
5087+ | ALTER opt_column ColId ADD_P GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList
5088+ {
5089+ AlterTableCmd *n = makeNode(AlterTableCmd);
5090+ Constraint *c = makeNode(Constraint);
5091+ 
5092+ c->contype = CONSTR_GENERATED_IDENTITY;
5093+ c->generated_when = $6;
5094+ c->options = $9;
5095+ c->location = @5;
5096+ 
5097+ n->subtype = AT_AddIdentity;
5098+ n->name = $3;
5099+ n->def = (Node *) c;
5100+ 
5101+ $$ = (Node *) n;
5102+ }
5103+ /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET <sequence options>/RESTART [ WHITE ] */
5104+ | ALTER opt_column ColId alter_identity_column_option_list
5105+ {
5106+ AlterTableCmd *n = makeNode(AlterTableCmd);
5107+ 
5108+ n->subtype = AT_SetIdentity;
5109+ n->name = $3;
5110+ n->def = (Node *) $4;
5111+ $$ = (Node *) n;
5112+ }
5113+ /* ALTER TABLE <name> ALTER [COLUMN] <colname> DROP IDENTITY */
5114+ | ALTER opt_column ColId DROP IDENTITY_P
5115+ {
5116+ AlterTableCmd *n = makeNode(AlterTableCmd);
5117+ 
5118+ n->subtype = AT_DropIdentity;
5119+ n->name = $3;
5120+ n->missing_ok = false;
5121+ $$ = (Node *) n;
5122+ }
5123+ /* ALTER TABLE <name> ALTER [COLUMN] <colname> DROP IDENTITY IF EXISTS */
5124+ | ALTER opt_column ColId DROP IDENTITY_P IF_P EXISTS
5125+ {
5126+ AlterTableCmd *n = makeNode(AlterTableCmd);
5127+ 
5128+ n->subtype = AT_DropIdentity;
5129+ n->name = $3;
5130+ n->missing_ok = true;
5131+ $$ = (Node *) n;
5132+ }
5085 /* ALTER TABLE <name> DROP [COLUMN] IF EXISTS <colname> [RESTRICT|CASCADE] */5133 /* ALTER TABLE <name> DROP [COLUMN] IF EXISTS <colname> [RESTRICT|CASCADE] */
5086 | DROP opt_column IF_P EXISTS ColId opt_drop_behavior5134 | DROP opt_column IF_P EXISTS ColId opt_drop_behavior
5087 {5135 {
@@ -5637,6 +5685,37 @@ alter_column_default:
5637 | DROP DEFAULT { $$ = NULL; }5685 | DROP DEFAULT { $$ = NULL; }
5638 ;5686 ;
5639 5687 
5688+alter_identity_column_option_list:
5689+ alter_identity_column_option { $$ = list_make1($1); }
5690+ | alter_identity_column_option_list alter_identity_column_option{ $$ = lappend($1, $2); }
5691+ ;
5692+ 
5693+alter_identity_column_option:
5694+ RESTART
5695+ {
5696+ $$ = makeDefElem("restart", NULL);
5697+ }
5698+ | RESTART opt_with NumericOnly
5699+ {
5700+ $$ = makeDefElem("restart", (Node *)$3);
5701+ }
5702+ | SET SeqOptElem
5703+ {
5704+ if (strcmp($2->defname, "restart") == 0 ||
5705+ strcmp($2->defname, "owned_by") == 0)
5706+ ereport(ERROR,
5707+ (errcode(ERRCODE_SYNTAX_ERROR),
5708+ errmsg("sequence option \"%s\" not supported here", $2->defname),
5709+ parser_errposition(@2)));
5710+ $$ = $2;
5711+ }
5712+ | SET GENERATED generated_when
5713+ {
5714+ $$ = makeDefElem("generated", (Node *) makeInteger($3));
5715+ }
5716+ ;
5717+ 
5718+ 
5640opt_drop_behavior:5719opt_drop_behavior:
5641 CASCADE { $$ = DROP_CASCADE; }5720 CASCADE { $$ = DROP_CASCADE; }
5642 | RESTRICT { $$ = DROP_RESTRICT; }5721 | RESTRICT { $$ = DROP_RESTRICT; }
@@ -7890,8 +7969,8 @@ ColConstraint:
7890 CONSTRAINT name ColConstraintElem7969 CONSTRAINT name ColConstraintElem
7891 {7970 {
7892 Constraint *n = (Constraint *) $3;7971 Constraint *n = (Constraint *) $3;
7893- const char* message = "check node type inconsistant";7972+ const char* message = "check node type inconsistant";
7894- InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);7973+ InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
7895 AssertEreport(IsA(n, Constraint),7974 AssertEreport(IsA(n, Constraint),
7896 MOD_OPT,7975 MOD_OPT,
7897 "check node type inconsistant");7976 "check node type inconsistant");
@@ -8365,21 +8444,29 @@ ColConstraintElem:
8365 InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);8444 InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
8366 ereport(errstate,8445 ereport(errstate,
8367 (errmodule(MOD_PARSER),8446 (errmodule(MOD_PARSER),
8368- errcode(ERRCODE_SYNTAX_ERROR),8447+ errcode(ERRCODE_SYNTAX_ERROR),
8369- errmsg("on update syntax is supported in dbcompatibility B."),8448+ errmsg("on update syntax is supported in dbcompatibility B."),
8370- parser_errposition(@1)));8449+ parser_errposition(@1)));
8371 $$ = NULL;8450 $$ = NULL;
8372 }8451 }
8373#endif8452#endif
8374 }8453 }
8375- | GENERATED ALWAYS AS '(' a_expr ')' generated_column_option8454+ | GENERATED generated_when AS '(' a_expr ')' generated_column_option
8376 {8455 {
8377#ifdef ENABLE_MULTIPLE_NODES8456#ifdef ENABLE_MULTIPLE_NODES
8378- const char* message = "Generated column is not yet supported";8457+ const char* message = "Generated column is not yet supported";
8379- InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);8458+ InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
8380- ereport(errstate, (errmodule(MOD_GEN_COL), errcode(ERRCODE_FEATURE_NOT_SUPPORTED),8459+ ereport(errstate,
8381- errmsg("Generated column is not yet supported.")));8460+ (errmodule(MOD_GEN_COL), errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8461+ errmsg(message)));
8382#endif8462#endif
8463+ if ($2 == ATTRIBUTE_IDENTITY_BY_DEFAULT) {
8464+ const char* message = "GENERATED DEFAULT column is not yet supported.";
8465+ InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
8466+ ereport(errstate,
8467+ (errmodule(MOD_PARSER), errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8468+ errmsg(message)));
8469+ }
8383 Constraint *n = makeNode(Constraint);8470 Constraint *n = makeNode(Constraint);
8384 n->contype = CONSTR_GENERATED;8471 n->contype = CONSTR_GENERATED;
8385 n->generated_when = ATTRIBUTE_IDENTITY_ALWAYS;8472 n->generated_when = ATTRIBUTE_IDENTITY_ALWAYS;
@@ -8388,14 +8475,30 @@ ColConstraintElem:
8388 n->location = @1;8475 n->location = @1;
8389 $$ = (Node *)n;8476 $$ = (Node *)n;
8390 }8477 }
8478+ | GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList
8479+ {
8480+#ifdef ENABLE_MULTIPLE_NODES
8481+ const char* message = "Generated AS Identity is not yet supported.";
8482+ InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
8483+ ereport(errstate,
8484+ (errmodule(MOD_PARSER), errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8485+ errmsg(message)));
8486+#endif
8487+ Constraint *n = makeNode(Constraint);
8488+ n->contype = CONSTR_GENERATED_IDENTITY;
8489+ n->generated_when = $2;
8490+ n->options = $5;
8491+ n->location = @1;
8492+ $$ = (Node *)n;
8493+ }
8391 | REFERENCES qualified_name opt_column_list key_match key_actions8494 | REFERENCES qualified_name opt_column_list key_match key_actions
8392 {8495 {
8393#ifdef ENABLE_MULTIPLE_NODES8496#ifdef ENABLE_MULTIPLE_NODES
8394- const char* message = "REFERENCES constraint is not yet supported.";8497+ const char* message = "REFERENCES constraint is not yet supported.";
8395- InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);8498+ InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
8396 ereport(errstate,8499 ereport(errstate,
8397 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),8500 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8398- errmsg("REFERENCES constraint is not yet supported.")));8501+ errmsg(message)));
8399#endif 8502#endif
8400 Constraint *n = makeNode(Constraint);8503 Constraint *n = makeNode(Constraint);
8401 n->contype = CONSTR_FOREIGN;8504 n->contype = CONSTR_FOREIGN;
@@ -8412,11 +8515,11 @@ ColConstraintElem:
8412 }8515 }
8413 | REFERENCES qualified_name opt_column_list key_match key_actions ENABLE_P8516 | REFERENCES qualified_name opt_column_list key_match key_actions ENABLE_P
8414 {8517 {
8415- const char* message = "REFERENCES constraint is not yet supported.";8518+ const char* message = "REFERENCES constraint is not yet supported.";
8416- InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);8519+ InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
8417 ereport(errstate,8520 ereport(errstate,
8418- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),8521+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8419- errmsg("REFERENCES constraint is not yet supported.")));8522+ errmsg("REFERENCES constraint is not yet supported.")));
8420 Constraint *n = makeNode(Constraint);8523 Constraint *n = makeNode(Constraint);
8421 n->contype = CONSTR_FOREIGN;8524 n->contype = CONSTR_FOREIGN;
8422 n->location = @1;8525 n->location = @1;
@@ -8432,6 +8535,11 @@ ColConstraintElem:
8432 }8535 }
8433 ;8536 ;
8434 8537
8538+generated_when:
8539+ ALWAYS { $$ = ATTRIBUTE_IDENTITY_ALWAYS; }
8540+ | BY DEFAULT { $$ = ATTRIBUTE_IDENTITY_BY_DEFAULT; }
8541+ ;
8542+ 
8435opt_unique_key:8543opt_unique_key:
8436 UNIQUE { $$ = NULL; }8544 UNIQUE { $$ = NULL; }
8437 | UNIQUE KEY8545 | UNIQUE KEY
@@ -8547,6 +8655,7 @@ TableLikeOptionList:
8547TableLikeIncludingOption:8655TableLikeIncludingOption:
8548 DEFAULTS { $$ = CREATE_TABLE_LIKE_DEFAULTS | CREATE_TABLE_LIKE_DEFAULTS_SERIAL; }8656 DEFAULTS { $$ = CREATE_TABLE_LIKE_DEFAULTS | CREATE_TABLE_LIKE_DEFAULTS_SERIAL; }
8549 | CONSTRAINTS { $$ = CREATE_TABLE_LIKE_CONSTRAINTS; }8657 | CONSTRAINTS { $$ = CREATE_TABLE_LIKE_CONSTRAINTS; }
8658+ | IDENTITY_P { $$ = CREATE_TABLE_LIKE_IDENTITY; }
8550 | INDEXES { $$ = CREATE_TABLE_LIKE_INDEXES; }8659 | INDEXES { $$ = CREATE_TABLE_LIKE_INDEXES; }
8551 | STORAGE { $$ = CREATE_TABLE_LIKE_STORAGE; }8660 | STORAGE { $$ = CREATE_TABLE_LIKE_STORAGE; }
8552 | COMMENTS { $$ = CREATE_TABLE_LIKE_COMMENTS; }8661 | COMMENTS { $$ = CREATE_TABLE_LIKE_COMMENTS; }
@@ -8560,6 +8669,7 @@ TableLikeIncludingOption:
8560TableLikeExcludingOption:8669TableLikeExcludingOption:
8561 DEFAULTS { $$ = CREATE_TABLE_LIKE_DEFAULTS | CREATE_TABLE_LIKE_DEFAULTS_SERIAL; }8670 DEFAULTS { $$ = CREATE_TABLE_LIKE_DEFAULTS | CREATE_TABLE_LIKE_DEFAULTS_SERIAL; }
8562 | CONSTRAINTS { $$ = CREATE_TABLE_LIKE_CONSTRAINTS; }8671 | CONSTRAINTS { $$ = CREATE_TABLE_LIKE_CONSTRAINTS; }
8672+ | IDENTITY_P { $$ = CREATE_TABLE_LIKE_IDENTITY; }
8563 | INDEXES { $$ = CREATE_TABLE_LIKE_INDEXES; }8673 | INDEXES { $$ = CREATE_TABLE_LIKE_INDEXES; }
8564 | STORAGE { $$ = CREATE_TABLE_LIKE_STORAGE; }8674 | STORAGE { $$ = CREATE_TABLE_LIKE_STORAGE; }
8565 | COMMENTS { $$ = CREATE_TABLE_LIKE_COMMENTS; }8675 | COMMENTS { $$ = CREATE_TABLE_LIKE_COMMENTS; }
@@ -8571,8 +8681,13 @@ TableLikeExcludingOption:
8571 | ALL { $$ = CREATE_TABLE_LIKE_ALL; }8681 | ALL { $$ = CREATE_TABLE_LIKE_ALL; }
8572 ;8682 ;
8573 8683 
8684+OptParenthesizedSeqOptList:
8685+ '(' SeqOptList ')' { $$ = $2; }
8686+ | /*EMPTY*/ { $$ = NIL; }
8687+ ;
8688+ 
8574opt_internal_data: 8689opt_internal_data:
8575- INTERNAL DATA_P internal_data_body {$$ = $3;}8690+ INTERNAL DATA_P internal_data_body {$$ = $3;}
8576 | /* EMPTY */ {$$ = NULL;}8691 | /* EMPTY */ {$$ = NULL;}
8577 ;8692 ;
8578 8693 
@@ -10520,6 +10635,11 @@ SeqOptElem: CACHE NumericOnly
10520 {10635 {
10521 $$ = makeDefElem("owned_by", (Node *)$3);10636 $$ = makeDefElem("owned_by", (Node *)$3);
10522 }10637 }
10638+ | SEQUENCE NAME_P any_name
10639+ {
10640+ /* not documented, only used by gs_dump */
10641+ $$ = makeDefElem("sequence_name", (Node *)$3);
10642+ }
10523 | START_WITH NumericOnly10643 | START_WITH NumericOnly
10524 {10644 {
10525 $$ = makeDefElem("start", (Node *)$2);10645 $$ = makeDefElem("start", (Node *)$2);
@@ -18476,6 +18596,7 @@ parallel_partition_opt:
18476 {18596 {
18477 $$ = NULL;18597 $$ = NULL;
18478 }18598 }
18599+ ;
18479 18600 
18480colid_list:18601colid_list:
18481 ColId18602 ColId
@@ -24558,8 +24679,19 @@ insert_rest:
24558 $$->cols = NIL;24679 $$->cols = NIL;
24559 $$->selectStmt = $1;24680 $$->selectStmt = $1;
24560 $$->isRewritten = false;24681 $$->isRewritten = false;
24561- if (((SelectStmt*)$1)->valuesLists == NULL)24682+ if (((SelectStmt*)$1)->valuesLists == NULL) {
24562- $$->is_dist_insertselect = true;24683+ $$->is_dist_insertselect = true;
24684+ }
24685+ }
24686+ | OVERRIDING override_kind VALUE_P SelectStmt
24687+ {
24688+ $$ = makeNode(InsertStmt);
24689+ $$->cols = NIL;
24690+ $$->override = ($2 == OVERRIDING_USER_VALUE ? OVERRIDING_USER_VALUE : OVERRIDING_SYSTEM_VALUE);
24691+ $$->selectStmt = $4;
24692+ if (((SelectStmt*)$4)->valuesLists == NULL) {
24693+ $$->is_dist_insertselect = true;
24694+ }
24563 }24695 }
24564 | '(' insert_column_list ')' SelectStmt24696 | '(' insert_column_list ')' SelectStmt
24565 {24697 {
@@ -24567,19 +24699,38 @@ insert_rest:
24567 $$->cols = $2;24699 $$->cols = $2;
24568 $$->selectStmt = $4;24700 $$->selectStmt = $4;
24569 $$->isRewritten = false;24701 $$->isRewritten = false;
24570- if (((SelectStmt*)$4)->valuesLists == NULL)24702+ if (((SelectStmt*)$4)->valuesLists == NULL) {
24571- $$->is_dist_insertselect = true;24703+ $$->is_dist_insertselect = true;
24704+ }
24705+ }
24706+ | '(' insert_column_list ')' OVERRIDING override_kind VALUE_P SelectStmt
24707+ {
24708+ $$ = makeNode(InsertStmt);
24709+ $$->cols = $2;
24710+ $$->override = ($5 == OVERRIDING_USER_VALUE ? OVERRIDING_USER_VALUE : OVERRIDING_SYSTEM_VALUE);
24711+ $$->isRewritten = false;
24712+ $$->selectStmt = $7;
24713+ if (((SelectStmt*)$7)->valuesLists == NULL) {
24714+ $$->is_dist_insertselect = true;
24715+ }
24572 }24716 }
24573 | DEFAULT VALUES24717 | DEFAULT VALUES
24574 {24718 {
24575 $$ = makeNode(InsertStmt);24719 $$ = makeNode(InsertStmt);
24576 $$->cols = NIL;24720 $$->cols = NIL;
24721+ $$->override = OVERRIDING_NOT_SET; /* default values, not necessary overriding insert */
24577 $$->selectStmt = NULL;24722 $$->selectStmt = NULL;
24578 $$->isRewritten = false;24723 $$->isRewritten = false;
24579- $$->is_dist_insertselect = false;24724+ $$->is_dist_insertselect = false;
24580 }24725 }
24581 ;24726 ;
24582 24727 
24728+override_kind:
24729+ USER { $$ = OVERRIDING_USER_VALUE; }
24730+ | SYSTEM_P { $$ = OVERRIDING_SYSTEM_VALUE; }
24731+ ;
24732+ 
24733+ 
24583insert_column_list:24734insert_column_list:
24584 insert_column_item24735 insert_column_item
24585 { $$ = list_make1($1); }24736 { $$ = list_make1($1); }
@@ -24759,6 +24910,8 @@ opt_cancelable: CANCELABLE { $$ = T
24759 ;24910 ;
24760 24911 
24761opt_wait: WAIT Iconst { $$ = $2; }24912opt_wait: WAIT Iconst { $$ = $2; }
24913+ ;
24914+ 
24762opt_nowait_or_skip:24915opt_nowait_or_skip:
24763 NOWAIT { $$ = LockWaitError; }24916 NOWAIT { $$ = LockWaitError; }
24764 | SKIP LOCKED { $$ = LockWaitSkip; }24917 | SKIP LOCKED { $$ = LockWaitSkip; }
@@ -25000,7 +25153,7 @@ merge_update:
25000 {25153 {
25001 MergeWhenClause *n = makeNode(MergeWhenClause);25154 MergeWhenClause *n = makeNode(MergeWhenClause);
25002 n->targetList = $3;25155 n->targetList = $3;
25003- 25156+ n->override = OVERRIDING_NOT_SET;
25004 $$ = n;25157 $$ = n;
25005 }25158 }
25006 ;25159 ;
@@ -25010,22 +25163,39 @@ merge_insert:
25010 {25163 {
25011 MergeWhenClause *n = makeNode(MergeWhenClause);25164 MergeWhenClause *n = makeNode(MergeWhenClause);
25012 n->cols = NIL;25165 n->cols = NIL;
25166+ n->override = OVERRIDING_NOT_SET;
25013 n->values = $2;25167 n->values = $2;
25014- 25168+ $$ = n;
25169+ }
25170+ | INSERT OVERRIDING override_kind VALUE_P merge_values_clause
25171+ {
25172+ MergeWhenClause *n = makeNode(MergeWhenClause);
25173+ n->cols = NIL;
25174+ n->override = ($3 == OVERRIDING_USER_VALUE ? OVERRIDING_USER_VALUE : OVERRIDING_SYSTEM_VALUE);
25175+ n->values = $5;
25015 $$ = n;25176 $$ = n;
25016 }25177 }
25017 | INSERT '(' insert_column_list ')' merge_values_clause25178 | INSERT '(' insert_column_list ')' merge_values_clause
25018 {25179 {
25019 MergeWhenClause *n = makeNode(MergeWhenClause);25180 MergeWhenClause *n = makeNode(MergeWhenClause);
25020 n->cols = $3;25181 n->cols = $3;
25182+ n->override = OVERRIDING_NOT_SET;
25021 n->values = $5;25183 n->values = $5;
25022- 25184+ $$ = n;
25185+ }
25186+ | INSERT '(' insert_column_list ')' OVERRIDING override_kind VALUE_P merge_values_clause
25187+ {
25188+ MergeWhenClause *n = makeNode(MergeWhenClause);
25189+ n->cols = $3;
25190+ n->override = ($6 == OVERRIDING_USER_VALUE ? OVERRIDING_USER_VALUE : OVERRIDING_SYSTEM_VALUE);
25191+ n->values = $8;
25023 $$ = n;25192 $$ = n;
25024 }25193 }
25025 | INSERT DEFAULT VALUES25194 | INSERT DEFAULT VALUES
25026 {25195 {
25027 MergeWhenClause *n = makeNode(MergeWhenClause);25196 MergeWhenClause *n = makeNode(MergeWhenClause);
25028 n->cols = NIL;25197 n->cols = NIL;
25198+ n->override = OVERRIDING_NOT_SET;
25029 n->values = NIL;25199 n->values = NIL;
25030 $$ = n;25200 $$ = n;
25031 }25201 }
@@ -25182,8 +25352,7 @@ inline_view:
25182 * We now support both orderings, but prefer LIMIT/OFFSET before the locking clause.25352 * We now support both orderings, but prefer LIMIT/OFFSET before the locking clause.
25183 * 2002-08-28 bjm25353 * 2002-08-28 bjm
25184 */25354 */
25185-select_no_parens:25355+select_no_parens: simple_select { $$ = $1; }
25186- simple_select { $$ = $1; }
25187 | select_clause siblings_clause opt_select_limit25356 | select_clause siblings_clause opt_select_limit
25188 {25357 {
25189 SelectStmt* stmt = (SelectStmt *) $1;25358 SelectStmt* stmt = (SelectStmt *) $1;
@@ -29936,7 +30105,7 @@ func_application: func_name '(' func_arg_list opt_sort_clause ')'
29936 ListCell* lc = list_head($3);30105 ListCell* lc = list_head($3);
29937 Node* n1 = (Node*)lfirst(lc);30106 Node* n1 = (Node*)lfirst(lc);
29938 if (IsA(n1, ColumnRef)) {30107 if (IsA(n1, ColumnRef)) {
29939- char* lobname = lobname = strVal(linitial(((ColumnRef*)n1)->fields));30108+ char* lobname = strVal(linitial(((ColumnRef*)n1)->fields));
29940 Node* funcname = (Node*)lfirst(list_tail($1));30109 Node* funcname = (Node*)lfirst(list_tail($1));
29941 if (strcmp(strVal(funcname), "createtemporary") == 0) {30110 if (strcmp(strVal(funcname), "createtemporary") == 0) {
29942 if (list_length($4) == 2) {30111 if (list_length($4) == 2) {
@@ -32706,9 +32875,10 @@ unreserved_keyword:
32706 | OPTION32875 | OPTION
32707 | OPTIONALLY32876 | OPTIONALLY
32708 | OPTIONS32877 | OPTIONS
32878+ | OUTFILE
32709 | ORDINALITY32879 | ORDINALITY
32710 | OVER32880 | OVER
32711- | OUTFILE32881+ | OVERRIDING
32712 | OWNED32882 | OWNED
32713 | OWNER32883 | OWNER
32714 | PACKAGE32884 | PACKAGE
@@ -33186,7 +33356,7 @@ reserved_keyword:
33186 | REFERENCES33356 | REFERENCES
33187 | REJECT_P33357 | REJECT_P
33188 | RETURNING33358 | RETURNING
33189- | ROWNUM33359+ | ROWNUM
33190 | SHARE_MEMORY33360 | SHARE_MEMORY
33191 | SELECT33361 | SELECT
33192 | SESSION_USER33362 | SESSION_USER
@@ -1428,6 +1428,7 @@ Node* transformFromClauseItem(ParseState* pstate, Node* n, RangeTblEntry** top_r
1428 ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),1428 ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1429 errmsg("UPDATE/DELETE/INSERT through subquery is only supported in A-format database")));1429 errmsg("UPDATE/DELETE/INSERT through subquery is only supported in A-format database")));
1430 }1430 }
1431+ 
1431 /* add startinfo if needed */1432 /* add startinfo if needed */
1432 if (pstate->p_addStartInfo) {1433 if (pstate->p_addStartInfo) {
1433 AddStartWithTargetRelInfo(pstate, sw_backup, rte, rtr);1434 AddStartWithTargetRelInfo(pstate, sw_backup, rte, rtr);
@@ -544,7 +544,7 @@ Node *transformExprRecurse(ParseState *pstate, Node *expr)
544 result = transformSubLink(pstate, (SubLink*)expr);544 result = transformSubLink(pstate, (SubLink*)expr);
545 break;545 break;
546 546 
547- case T_SelectIntoVarList:547+ case T_SelectIntoVarList:
548 result = transformSelectIntoVarList(pstate, (SelectIntoVarList*)expr);548 result = transformSelectIntoVarList(pstate, (SelectIntoVarList*)expr);
549 break;549 break;
550 550 
@@ -133,7 +133,6 @@ extern void hint_scanner_yyerror(const char* msg, yyscan_t yyscanner);
133extern Datum GetDatumFromString(Oid typeOid, int4 typeMod, char* value);133extern Datum GetDatumFromString(Oid typeOid, int4 typeMod, char* value);
134extern Const* makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue,134extern Const* makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue,
135 bool constisnull, bool constbyval, Cursor_Data* vars = NULL);135 bool constisnull, bool constbyval, Cursor_Data* vars = NULL);
136-extern Numeric int64_to_numeric(int64 v);
137 136 
138static bool IsScanUseDesthint(void* val1, void* val2);137static bool IsScanUseDesthint(void* val1, void* val2);
139 138 
@@ -1159,6 +1159,8 @@ Query* transformMergeStmt(ParseState* pstate, MergeStmt* stmt)
1159 List* save_varnamespace = NIL;1159 List* save_varnamespace = NIL;
1160 RangeTblEntry* sourceRelRTE = NULL;1160 RangeTblEntry* sourceRelRTE = NULL;
1161 1161 
1162+ action->override = mergeWhenClause->override;
1163+ 
1162 /*1164 /*
1163 * For MERGE INTO type SQL, in the RTE list, the object with index 1 is the target table, and the1165 * For MERGE INTO type SQL, in the RTE list, the object with index 1 is the target table, and the
1164 * object with index 2 is the source table (the index starts from 1).1166 * object with index 2 is the source table (the index starts from 1).
@@ -3067,6 +3067,7 @@ typedef struct ColVersionMap {
3067static ColVersionMap col_version_maps[] = {3067static ColVersionMap col_version_maps[] = {
3068 /* pg_attribute */3068 /* pg_attribute */
3069 {AttributeRelationId, Anum_pg_attribute_attdroppedname, FLUSH_LSN_FUN_VERSION_NUM},3069 {AttributeRelationId, Anum_pg_attribute_attdroppedname, FLUSH_LSN_FUN_VERSION_NUM},
3070+ {AttributeRelationId, Anum_pg_attribute_attidentity, PG_IDENTITY_VERSION_NUM},
3070 3071 
3071 /* pg_index */3072 /* pg_index */
3072 {IndexRelationId, Anum_pg_index_indisvisible, SRF_FUSION_VERSION_NUM},3073 {IndexRelationId, Anum_pg_index_indisvisible, SRF_FUSION_VERSION_NUM},
@@ -3379,7 +3380,7 @@ void get_rte_attribute_type(RangeTblEntry* rte, AttrNumber attnum, Oid* vartype,
3379 *vartype = att_tup->atttypid;3380 *vartype = att_tup->atttypid;
3380 *vartypmod = att_tup->atttypmod;3381 *vartypmod = att_tup->atttypmod;
3381 *varcollid = att_tup->attcollation;3382 *varcollid = att_tup->attcollation;
3382- if (kvtype != NULL && att_tup->attkvtype == ATT_KV_HIDE) {3383+ if (kvtype != NULL && GET_ATTR_KVTYPE(att_tup) == ATT_KV_HIDE) {
3383 *kvtype = ATT_KV_HIDE;3384 *kvtype = ATT_KV_HIDE;
3384 }3385 }
3385 ReleaseSysCache(tp);3386 ReleaseSysCache(tp);
@@ -3445,7 +3446,7 @@ void get_rte_attribute_type(RangeTblEntry* rte, AttrNumber attnum, Oid* vartype,
3445 *vartype = att_tup->atttypid;3446 *vartype = att_tup->atttypid;
3446 *vartypmod = att_tup->atttypmod;3447 *vartypmod = att_tup->atttypmod;
3447 *varcollid = att_tup->attcollation;3448 *varcollid = att_tup->attcollation;
3448- if (kvtype != NULL && att_tup->attkvtype == ATT_KV_HIDE) {3449+ if (kvtype != NULL && GET_ATTR_KVTYPE(att_tup) == ATT_KV_HIDE) {
3449 *kvtype = ATT_KV_HIDE;3450 *kvtype = ATT_KV_HIDE;
3450 }3451 }
3451 } else if (functypclass == TYPEFUNC_SCALAR) {3452 } else if (functypclass == TYPEFUNC_SCALAR) {
@@ -3797,7 +3798,7 @@ Oid attnumTypeId(Relation rd, int attid)
3797/*3798/*
3798 * given attribute id, return collation of that attribute3799 * given attribute id, return collation of that attribute
3799 *3800 *
3800- * This should only be used if the relation is already heap_open()'ed.3801+ * This should only be used if the relation is already heap_open()'ed.
3801 */3802 */
3802Oid attnumCollationId(Relation rd, int attid)3803Oid attnumCollationId(Relation rd, int attid)
3803{3804{
@@ -903,18 +903,6 @@ List* checkInsertTargets(ParseState* pstate, List* cols, List** attrnos)
903 }903 }
904}904}
905 905 
906-void checkIdentityColumn(ParseState* pstate, Relation rel, ResTarget* resTarget, int attrno, const char* op)
907-{
908- /* Cannot insert identity column in D format */
909- if (DB_IS_CMPT(D_FORMAT)
910- && OidIsValid(pg_get_serial_sequence_internal(RelationGetRelid(rel), attrno, true, NULL))) {
911- ereport(ERROR,
912- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
913- errmsg("Cannot %s identity column \"%s\"", op, resTarget->name),
914- parser_errposition(pstate, resTarget->location)));
915- }
916-}
917- 
918static List* checkRelationInsertTargets(ParseState* pstate, List* cols, List** attrnos)906static List* checkRelationInsertTargets(ParseState* pstate, List* cols, List** attrnos)
919{907{
920 *attrnos = NIL;908 *attrnos = NIL;
@@ -953,9 +941,10 @@ static List* checkRelationInsertTargets(ParseState* pstate, List* cols, List** a
953 if (is_blockchain_rel && strcmp(col->name, "hash") == 0) {941 if (is_blockchain_rel && strcmp(col->name, "hash") == 0) {
954 continue;942 continue;
955 }943 }
944+ 
956 /* skip the identity default value in D format */945 /* skip the identity default value in D format */
957- if (DB_IS_CMPT(D_FORMAT) && OidIsValid(pg_get_serial_sequence_internal(RelationGetRelid(targetrel),946+ if (DB_IS_CMPT(D_FORMAT) && OidIsValid(getIdentitySequence(RelationGetRelid(targetrel),
958- attr[i].attnum, true, NULL))) {947+ attr[i].attnum, true, true))) {
959 continue;948 continue;
960 }949 }
961 950 
@@ -988,12 +977,6 @@ static List* checkRelationInsertTargets(ParseState* pstate, List* cols, List** a
988 RelationGetRelationName(targetrel)),977 RelationGetRelationName(targetrel)),
989 parser_errposition(pstate, col->location)));978 parser_errposition(pstate, col->location)));
990 }979 }
991- /* In D format, Not allowed to insert identity column directly,
992- * except set identity_insert = on.
993- */
994- if (DB_IS_CMPT(D_FORMAT) && !u_sess->enable_identity_insert)
995- checkIdentityColumn(pstate, targetrel, col, attrno, "insert");
996- 
997 /*980 /*
998 * Check for duplicates, but only of whole columns --- we allow981 * Check for duplicates, but only of whole columns --- we allow
999 * INSERT INTO foo (col.subcol1, col.subcol2)982 * INSERT INTO foo (col.subcol1, col.subcol2)
@@ -85,6 +85,34 @@ static Oid convert_column_key_name(text *keyname);
85static AclMode convert_cmk_priv_string(text *priv_type_text);85static AclMode convert_cmk_priv_string(text *priv_type_text);
86static AclMode convert_cek_priv_string(text *priv_type_text);86static AclMode convert_cek_priv_string(text *priv_type_text);
87 87 
88+ 
89+static int g_authidNameData[] = {
90+ Anum_pg_authid_rolname, Anum_pg_authid_rolrespool, Natts_pg_authid
91+};
92+static int g_authidBool[] = {
93+ Anum_pg_authid_rolsuper, Anum_pg_authid_rolinherit, Anum_pg_authid_rolcreaterole,
94+ Anum_pg_authid_rolcreatedb, Anum_pg_authid_rolcatupdate, Anum_pg_authid_rolcanlogin,
95+ Anum_pg_authid_rolreplication, Anum_pg_authid_rolauditadmin, Anum_pg_authid_rolsystemadmin,
96+ Anum_pg_authid_roluseft, Anum_pg_authid_rolmonitoradmin, Anum_pg_authid_roloperatoradmin,
97+ Anum_pg_authid_rolpolicyadmin, Natts_pg_authid
98+};
99+static int g_authidText[] = {
100+ Anum_pg_authid_rolpassword, Anum_pg_authid_roltempspace, Anum_pg_authid_rolspillspace,
101+ Anum_pg_authid_rolspillspace, Anum_pg_authid_roltabspace, Natts_pg_authid
102+};
103+static int g_authidOid[] = {
104+ Anum_pg_authid_rolparentid, Anum_pg_authid_rolnodegroup, Natts_pg_authid
105+};
106+static int g_authidInt4[] = {
107+ Anum_pg_authid_rolconnlimit, Natts_pg_authid
108+};
109+static int g_authidTimeStamptz[] = {
110+ Anum_pg_authid_rolvalidbegin, Anum_pg_authid_rolvaliduntil, Natts_pg_authid
111+};
112+static int g_authidChar[] = {
113+ Anum_pg_authid_rolkind, Natts_pg_authid
114+};
115+ 
88const struct AclAction {116const struct AclAction {
89 char action; 117 char action;
90 AclMode read;118 AclMode read;
@@ -226,22 +254,22 @@ static bool Chargevalue(int* typeList, int index)
226 254 
227static void GetValueAccordingToTheType(cJSON* root, int index, char* key, Datum rawData) 255static void GetValueAccordingToTheType(cJSON* root, int index, char* key, Datum rawData)
228{256{
229- if (Chargevalue(Authid_Name_Data, index)) {257+ if (Chargevalue(g_authidNameData, index)) {
230 cJSON_AddStringToObject(root, key, DatumGetName(rawData)->data);258 cJSON_AddStringToObject(root, key, DatumGetName(rawData)->data);
231 return;259 return;
232 }260 }
233 261 
234- if (Chargevalue(Authid_Bool, index)) {262+ if (Chargevalue(g_authidBool, index)) {
235 cJSON_AddBoolToObject(root, key, BoolGetDatum(rawData));263 cJSON_AddBoolToObject(root, key, BoolGetDatum(rawData));
236 return;264 return;
237 }265 }
238 266 
239- if (Chargevalue(Authid_Text, index)) {267+ if (Chargevalue(g_authidText, index)) {
240 cJSON_AddStringToObject(root, key, TextDatumGetCString(rawData));268 cJSON_AddStringToObject(root, key, TextDatumGetCString(rawData));
241 return;269 return;
242 }270 }
243 271 
244- if (Chargevalue(Authid_Oid, index)) {272+ if (Chargevalue(g_authidOid, index)) {
245 Oid oid = DatumGetObjectId(rawData);273 Oid oid = DatumGetObjectId(rawData);
246 StringInfoData str;274 StringInfoData str;
247 initStringInfo(&str);275 initStringInfo(&str);
@@ -250,18 +278,18 @@ static void GetValueAccordingToTheType(cJSON* root, int index, char* key, Datum
250 return;278 return;
251 }279 }
252 280 
253- if (Chargevalue(Authid_Int4, index)) {281+ if (Chargevalue(g_authidInt4, index)) {
254 cJSON_AddNumberToObject(root, key, DatumGetInt32(rawData));282 cJSON_AddNumberToObject(root, key, DatumGetInt32(rawData));
255 return;283 return;
256 }284 }
257 285 
258- if (Chargevalue(Authid_TimeStamptz, index)) {286+ if (Chargevalue(g_authidTimeStamptz, index)) {
259 char* str = pstrdup(timestamptz_to_str(DatumGetTimestampTz(rawData)));287 char* str = pstrdup(timestamptz_to_str(DatumGetTimestampTz(rawData)));
260 cJSON_AddStringToObject(root, key, str);288 cJSON_AddStringToObject(root, key, str);
261 return;289 return;
262 }290 }
263 291 
264- if (Chargevalue(Authid_Char, index)) {292+ if (Chargevalue(g_authidChar, index)) {
265 char c = DatumGetChar(rawData);293 char c = DatumGetChar(rawData);
266 char str[2] = {c, '\0'};294 char str[2] = {c, '\0'};
267 char* ptr = str;295 char* ptr = str;
@@ -1843,13 +1843,6 @@ static char* numeric_to_cstring(Numeric n)
1843 return DatumGetCString(DirectFunctionCall1(numeric_out, d));1843 return DatumGetCString(DirectFunctionCall1(numeric_out, d));
1844}1844}
1845 1845 
1846-Numeric int64_to_numeric(int64 v)
1847-{
1848- Datum d = Int64GetDatum(v);
1849- 
1850- return DatumGetNumeric(DirectFunctionCall1(int8_numeric, d));
1851-}
1852- 
1853static bool numeric_is_less(Numeric a, Numeric b)1846static bool numeric_is_less(Numeric a, Numeric b)
1854{1847{
1855 Datum da = NumericGetDatum(a);1848 Datum da = NumericGetDatum(a);
@@ -72,6 +72,7 @@
72#include "utils/datetime.h"72#include "utils/datetime.h"
73#include "utils/formatting.h"73#include "utils/formatting.h"
74#include "utils/int8.h"74#include "utils/int8.h"
75+#include "utils/numeric.h"
75#include "utils/json.h"76#include "utils/json.h"
76#include "utils/jsonpath.h"77#include "utils/jsonpath.h"
77#include "utils/memutils.h"78#include "utils/memutils.h"
@@ -41,6 +41,7 @@
41#include "utils/gs_bitmap.h"41#include "utils/gs_bitmap.h"
42#include "utils/guc.h"42#include "utils/guc.h"
43#include "utils/int8.h"43#include "utils/int8.h"
44+#include "utils/int16.h"
44#include "utils/numeric.h"45#include "utils/numeric.h"
45#include "utils/sortsupport.h"46#include "utils/sortsupport.h"
46#include "vecexecutor/vechashtable.h"47#include "vecexecutor/vechashtable.h"
@@ -3282,6 +3283,21 @@ int64 numeric_int8_opt_error(Numeric num, bool can_ignore, bool *haveError)
3282 return result;3283 return result;
3283}3284}
3284 3285 
3286+ 
3287+Numeric int64_to_numeric(int64 v)
3288+{
3289+ Datum d = Int64GetDatum(v);
3290+ 
3291+ return DatumGetNumeric(DirectFunctionCall1(int8_numeric, d));
3292+}
3293+ 
3294+Numeric int128_to_numeric(int128 v)
3295+{
3296+ Datum d = Int128GetDatum(v);
3297+ 
3298+ return DatumGetNumeric(DirectFunctionCall1(int16_numeric, d));
3299+}
3300+ 
3285Datum numeric_pg_lsn(PG_FUNCTION_ARGS)3301Datum numeric_pg_lsn(PG_FUNCTION_ARGS)
3286{3302{
3287 Numeric num = PG_GETARG_NUMERIC(0);3303 Numeric num = PG_GETARG_NUMERIC(0);
@@ -1734,11 +1734,17 @@ static int get_table_attribute(
1734 int natts = get_relnatts(tableoid);1734 int natts = get_relnatts(tableoid);
1735 int i;1735 int i;
1736 int actual_atts = 0;1736 int actual_atts = 0;
1737+ int kvtype = ATT_KV_UNDEFINED;
1738+ char identity = '\0';
1739+ 
1737 for (i = 0; i < natts; i++) {1740 for (i = 0; i < natts; i++) {
1738 HeapTuple tp = SearchSysCache2(ATTNUM, ObjectIdGetDatum(tableoid), Int16GetDatum(i + 1));1741 HeapTuple tp = SearchSysCache2(ATTNUM, ObjectIdGetDatum(tableoid), Int16GetDatum(i + 1));
1739 if (HeapTupleIsValid(tp)) {1742 if (HeapTupleIsValid(tp)) {
1740 Form_pg_attribute att_tup = (Form_pg_attribute)GETSTRUCT(tp);1743 Form_pg_attribute att_tup = (Form_pg_attribute)GETSTRUCT(tp);
1741- if (att_tup->attkvtype == ATT_KV_HIDE) {1744+ kvtype = GET_ATTR_KVTYPE(att_tup);
1745+ identity = GET_ATTR_IDENTITY(att_tup);
1746+ 
1747+ if (kvtype == ATT_KV_HIDE) {
1742 ReleaseSysCache(tp);1748 ReleaseSysCache(tp);
1743 continue;1749 continue;
1744 }1750 }
@@ -1774,11 +1780,11 @@ static int get_table_attribute(
1774 } else {1780 } else {
1775 appendStringInfo(buf, "%s %s", quote_identifier(NameStr(att_tup->attname)), result);1781 appendStringInfo(buf, "%s %s", quote_identifier(NameStr(att_tup->attname)), result);
1776 }1782 }
1777- if (att_tup->attkvtype == ATT_KV_TAG)1783+ if (kvtype == ATT_KV_TAG)
1778 appendStringInfo(buf, " TSTag");1784 appendStringInfo(buf, " TSTag");
1779- else if (att_tup->attkvtype == ATT_KV_FIELD)1785+ else if (kvtype == ATT_KV_FIELD)
1780 appendStringInfo(buf, " TSField");1786 appendStringInfo(buf, " TSField");
1781- else if (att_tup->attkvtype == ATT_KV_TIMETAG)1787+ else if (kvtype == ATT_KV_TIMETAG)
1782 appendStringInfo(buf, " TSTime");1788 appendStringInfo(buf, " TSTime");
1783 /* Compression mode */1789 /* Compression mode */
1784 get_compression_mode(att_tup, buf);1790 get_compression_mode(att_tup, buf);
@@ -1821,7 +1827,25 @@ static int get_table_attribute(
1821 }1827 }
1822 }1828 }
1823 1829 
1824- if (att_tup->atthasdef) {1830+ /* identity column */
1831+ if (identity) {
1832+ /* identity in D format */
1833+ if (identity == ATTRIBUTE_IDENTITY_D) {
1834+ Oid seqid = getIdentitySequence(tableoid, att_tup->attnum, true, true);
1835+ if (OidIsValid(seqid)) {
1836+ sequence_values* sv = get_sequence_values(seqid);
1837+ appendStringInfo(buf, " IDENTITY (%s, %s)",
1838+ sv->start_value, sv->increment_by);
1839+ } else {
1840+ appendStringInfo(buf, " IDENTITY (%s, %s)",
1841+ "UNKNOWN", "UNKNOWN");
1842+ }
1843+ } else {
1844+ appendStringInfo(buf, " GENERATED %s AS IDENTITY",
1845+ identity == ATTRIBUTE_IDENTITY_ALWAYS ?
1846+ "ALWAYS" : "BY DEFAULT");
1847+ }
1848+ } else if (att_tup->atthasdef) {
1825 Form_pg_attrdef attrdef;1849 Form_pg_attrdef attrdef;
1826 Relation attrdefDesc;1850 Relation attrdefDesc;
1827 ScanKeyData skey[1];1851 ScanKeyData skey[1];
@@ -1961,7 +1985,7 @@ bool IsHideTagDistribute(Oid relOid)
1961 1985 
1962 pgxc_class = (Form_pgxc_class)GETSTRUCT(htup);1986 pgxc_class = (Form_pgxc_class)GETSTRUCT(htup);
1963 1987 
1964- if (pgxc_class->pcattnum.dim1 == 1 && get_kvtype(relOid, pgxc_class->pcattnum.values[0]) == ATT_KV_HIDE) {1988+ if (pgxc_class->pcattnum.dim1 == 1 && get_attkvtype(relOid, pgxc_class->pcattnum.values[0]) == ATT_KV_HIDE) {
1965 hide = true;1989 hide = true;
1966 }1990 }
1967 1991
@@ -4559,121 +4583,9 @@ Datum pg_check_authid(PG_FUNCTION_ARGS)
4559 }4583 }
4560}4584}
4561 4585 
4562-Oid pg_get_serial_sequence_internal(Oid tableOid, AttrNumber attnum, bool find_identity, char** out_seq_name)
4563-{
4564- Oid sequenceId = InvalidOid;
4565- Relation depRel;
4566- ScanKeyData key[3];
4567- SysScanDesc scan;
4568- HeapTuple tup;
4569- 
4570- /* Search the dependency table for the dependent sequence */
4571- depRel = heap_open(DependRelationId, AccessShareLock);
4572- 
4573- ScanKeyInit(
4574- &key[0], Anum_pg_depend_refclassid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationRelationId));
4575- ScanKeyInit(&key[1], Anum_pg_depend_refobjid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tableOid));
4576- ScanKeyInit(&key[2], Anum_pg_depend_refobjsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(attnum));
4577- 
4578- scan = systable_beginscan(depRel, DependReferenceIndexId, true, NULL, 3, key);
4579- 
4580- while (HeapTupleIsValid(tup = systable_getnext(scan))) {
4581- Form_pg_depend deprec = (Form_pg_depend)GETSTRUCT(tup);
4582- 
4583- /*
4584- * We assume any auto dependency of a sequence on a column must be
4585- * what we are looking for. (We need the relkind test because indexes
4586- * can also have auto dependencies on columns.)
4587- */
4588- if (deprec->classid == RelationRelationId && deprec->objsubid == 0 && deprec->deptype == DEPENDENCY_AUTO &&
4589- RELKIND_IS_SEQUENCE(get_rel_relkind(deprec->objid))) {
4590- if (find_identity) {
4591- char* relname = get_rel_name(deprec->objid);
4592- if (relname && StrEndWith(relname, "_seq_identity")) {
4593- sequenceId = deprec->objid;
4594- break;
4595- } else {
4596- continue;
4597- }
4598- }
4599- sequenceId = deprec->objid;
4600- break;
4601- }
4602- }
4603- 
4604- systable_endscan(scan);
4605- heap_close(depRel, AccessShareLock);
4606- 
4607- if (OidIsValid(sequenceId)) {
4608- HeapTuple classtup;
4609- Form_pg_class classtuple;
4610- char* nspname = NULL;
4611- 
4612- /* Get the sequence's pg_class entry */
4613- classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(sequenceId));
4614- if (!HeapTupleIsValid(classtup)) {
4615- if (find_identity) {
4616- return InvalidOid;
4617- }
4618- ereport(ERROR,
4619- (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("cache lookup failed for relation %u", sequenceId)));
4620- }
4621- 
4622- classtuple = (Form_pg_class)GETSTRUCT(classtup);
4623- 
4624- /* Get the namespace */
4625- nspname = get_namespace_name(classtuple->relnamespace);
4626- if (nspname == NULL) {
4627- if (find_identity) {
4628- return InvalidOid;
4629- }
4630- ereport(ERROR,
4631- (errcode(ERRCODE_CACHE_LOOKUP_FAILED),
4632- errmsg("cache lookup failed for namespace %u", classtuple->relnamespace)));
4633- }
4634- 
4635- /* And construct the result string */
4636- if (out_seq_name != NULL) {
4637- *out_seq_name = quote_qualified_identifier(nspname, NameStr(classtuple->relname));
4638- }
4639- 
4640- ReleaseSysCache(classtup);
4641- }
4642- 
4643- return sequenceId;
4644-}
4645- 
4646-/*
4647- * Get the table's identity sequence OID.
4648- */
4649-Oid get_table_identity(Oid tableOid)
4650-{
4651- Relation rel = nullptr;
4652- TupleDesc tupdesc = nullptr;
4653- AttrNumber attnum = 0;
4654- Oid seqid = InvalidOid;
4655- 
4656- rel = RelationIdGetRelation(tableOid);
4657- tupdesc = RelationGetDescr(rel);
4658- 
4659- for (attnum = 0; attnum < tupdesc->natts; attnum++) {
4660- Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum);
4661- if (attr->attisdropped) {
4662- continue;
4663- }
4664- seqid = pg_get_serial_sequence_internal(tableOid, attr->attnum, true, NULL);
4665- if (OidIsValid(seqid)) {
4666- break;
4667- }
4668- }
4669- 
4670- RelationClose(rel);
4671- return seqid;
4672-}
4673- 
4674/*4586/*
4675 * pg_get_serial_sequence4587 * pg_get_serial_sequence
4676- * Get the name of the sequence used by a serial column,4588+ * Get the name of the sequence used by a identity or serial column,
4677 * formatted suitably for passing to setval, nextval or currval.4589 * formatted suitably for passing to setval, nextval or currval.
4678 * First parameter is not treated as double-quoted, second parameter4590 * First parameter is not treated as double-quoted, second parameter
4679 * is --- see documentation for reason.4591 * is --- see documentation for reason.
@@ -4704,7 +4616,7 @@ Datum pg_get_serial_sequence(PG_FUNCTION_ARGS)
4704 4616 
4705 list_free_ext(names);4617 list_free_ext(names);
4706 4618 
4707- if (OidIsValid(pg_get_serial_sequence_internal(tableOid, attnum, false, &result))) {4619+ if (OidIsValid(getOwnedSequence(tableOid, attnum, &result))) {
4708 PG_RETURN_TEXT_P(string_to_text(result));4620 PG_RETURN_TEXT_P(string_to_text(result));
4709 }4621 }
4710 4622 
@@ -7894,6 +7806,15 @@ static void get_insert_query_def(Query* query, deparse_context* context)
7894 appendStringInfo(buf, ") ");7806 appendStringInfo(buf, ") ");
7895 }7807 }
7896 7808 
7809+ if (query->override) {
7810+ if (query->override == OVERRIDING_SYSTEM_VALUE) {
7811+ appendStringInfoString(buf, "OVERRIDING SYSTEM VALUE ");
7812+ }
7813+ else if (query->override == OVERRIDING_USER_VALUE) {
7814+ appendStringInfoString(buf, "OVERRIDING USER VALUE ");
7815+ }
7816+ }
7817+ 
7897 if (select_rte != NULL) {7818 if (select_rte != NULL) {
7898 /* Add the SELECT */7819 /* Add the SELECT */
7899 get_query_def(select_rte->subquery, buf, NIL, NULL, context->prettyFlags,7820 get_query_def(select_rte->subquery, buf, NIL, NULL, context->prettyFlags,
@@ -8568,7 +8489,7 @@ static void get_utility_query_def(Query* query, deparse_context* context)
8568 quote_identifier(coldef->colname),8489 quote_identifier(coldef->colname),
8569 format_type_with_typemod(tpname->typeOid, tpname->typemod));8490 format_type_with_typemod(tpname->typeOid, tpname->typemod));
8570 }8491 }
8571- if (DB_IS_CMPT(D_FORMAT) && coldef->is_identity) {8492+ if (DB_IS_CMPT(D_FORMAT) && coldef->identity) {
8572 Assert(context->seqValue != NULL);8493 Assert(context->seqValue != NULL);
8573 appendStringInfo(buf,8494 appendStringInfo(buf,
8574 " IDENTITY (%s, %s) ",8495 " IDENTITY (%s, %s) ",
@@ -9815,6 +9736,7 @@ static bool isSimpleNode(Node* node, Node* parentNode, int prettyFlags)
9815 case T_CoalesceExpr:9736 case T_CoalesceExpr:
9816 case T_MinMaxExpr:9737 case T_MinMaxExpr:
9817 case T_XmlExpr:9738 case T_XmlExpr:
9739+ case T_NextValueExpr:
9818 case T_NullIfExpr:9740 case T_NullIfExpr:
9819 case T_Aggref:9741 case T_Aggref:
9820 case T_WindowFunc:9742 case T_WindowFunc:
@@ -10974,6 +10896,19 @@ static void get_rule_expr(Node* node, deparse_context* context, bool showimplici
10974 appendStringInfo(buf, "CURRENT OF $%d", cexpr->cursor_param);10896 appendStringInfo(buf, "CURRENT OF $%d", cexpr->cursor_param);
10975 } break;10897 } break;
10976 10898 
10899+ case T_NextValueExpr: {
10900+ NextValueExpr *nvexpr = (NextValueExpr *) node;
10901+ /*
10902+ * This isn't exactly nextval(), but that seems close enough
10903+ * for EXPLAIN's purposes.
10904+ */
10905+ appendStringInfoString(buf, "nextval(");
10906+ simple_quote_literal(buf,
10907+ generate_relation_name(nvexpr->seqid,
10908+ NIL));
10909+ appendStringInfoChar(buf, ')');
10910+ } break;
10911+ 
10977 case T_List: {10912 case T_List: {
10978 char* sep = NULL;10913 char* sep = NULL;
10979 ListCell* l = NULL;10914 ListCell* l = NULL;
@@ -13713,30 +13648,3 @@ static void replace_cl_types_in_argtypes(Oid func_id, int numargs, Oid* argtypes
13713 ReleaseSysCache(gs_oldtup);13648 ReleaseSysCache(gs_oldtup);
13714 }13649 }
13715}13650}
13716- 
13717-Oid pg_get_serial_sequence_oid(text* tablename, text* columnname, bool find_identity)
13718-{
13719- RangeVar* tablerv = NULL;
13720- Oid tableOid;
13721- char* column = NULL;
13722- AttrNumber attnum;
13723- List* names = NIL;
13724- 
13725- /* Look up table name. */
13726- names = textToQualifiedNameList(tablename);
13727- tablerv = makeRangeVarFromNameList(names);
13728- tableOid = RangeVarGetRelid(tablerv, NoLock, false);
13729- 
13730- /* Get the number of the column */
13731- column = text_to_cstring(columnname);
13732- attnum = get_attnum(tableOid, column);
13733- if (attnum == InvalidAttrNumber)
13734- ereport(ERROR,
13735- (errcode(ERRCODE_UNDEFINED_COLUMN),
13736- errmsg("column \"%s\" of relation \"%s\" does not exist", column, tablerv->relname)));
13737- 
13738- pfree_ext(column);
13739- list_free_ext(names);
13740- 
13741- return pg_get_serial_sequence_internal(tableOid, attnum, find_identity, NULL);
13742-}
@@ -1474,7 +1474,8 @@ HeapTuple SearchBuiltinProcCacheMiss(int cache_id, int nkeys, Datum* arguments)
1474 }1474 }
1475}1475}
1476 1476 
1477-HeapTuple GetPgAttributeAttrTuple(TupleDesc tupleDesc, const Form_pg_attribute attr)1477+HeapTuple GetPgAttributeAttrTuple(TupleDesc tupleDesc, const Form_pg_attribute attr,
1478+ Form_pg_attribute_extra attrExtra)
1478{1479{
1479 Datum values[Natts_pg_attribute];1480 Datum values[Natts_pg_attribute];
1480 bool isnull[Natts_pg_attribute];1481 bool isnull[Natts_pg_attribute];
@@ -1504,8 +1505,10 @@ HeapTuple GetPgAttributeAttrTuple(TupleDesc tupleDesc, const Form_pg_attribute a
1504 values[Anum_pg_attribute_attcmprmode - 1] = Int8GetDatum(attr->attcmprmode);1505 values[Anum_pg_attribute_attcmprmode - 1] = Int8GetDatum(attr->attcmprmode);
1505 values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(attr->attinhcount);1506 values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(attr->attinhcount);
1506 values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attr->attcollation);1507 values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attr->attcollation);
1507- values[Anum_pg_attribute_attkvtype - 1] = Int8GetDatum(attr->attkvtype);1508+ 
1508- values[Anum_pg_attribute_attdroppedname - 1] = NameGetDatum(&(attr->attdroppedname));1509+ values[Anum_pg_attribute_attkvtype - 1] = Int8GetDatum(attrExtra->attkvtype);
1510+ values[Anum_pg_attribute_attdroppedname - 1] = NameGetDatum(&(attrExtra->attdroppedname));
1511+ values[Anum_pg_attribute_attidentity - 1] = CharGetDatum(attrExtra->attidentity);
1509 1512 
1510 /* start out with empty permissions and empty options */1513 /* start out with empty permissions and empty options */
1511 isnull[Anum_pg_attribute_attacl - 1] = true;1514 isnull[Anum_pg_attribute_attacl - 1] = true;
@@ -1528,6 +1531,8 @@ HeapTuple SearchPgAttributeCacheMiss(int cache_id, TupleDesc cc_tupdesc, int nke
1528 }1531 }
1529 const FormData_pg_attribute* catlogAttrs = catalogDesc.attrs;1532 const FormData_pg_attribute* catlogAttrs = catalogDesc.attrs;
1530 FormData_pg_attribute tempAttr;1533 FormData_pg_attribute tempAttr;
1534+ FormData_pg_attribute_extra attrExtra = {0};
1535+ 
1531 if (cache_id == ATTNUM) {1536 if (cache_id == ATTNUM) {
1532 int16 attNum = DatumGetInt16(arguments[1]);1537 int16 attNum = DatumGetInt16(arguments[1]);
1533 Form_pg_attribute attr;1538 Form_pg_attribute attr;
@@ -1545,14 +1550,14 @@ HeapTuple SearchPgAttributeCacheMiss(int cache_id, TupleDesc cc_tupdesc, int nke
1545 } else {1550 } else {
1546 return NULL;1551 return NULL;
1547 }1552 }
1548- return GetPgAttributeAttrTuple(cc_tupdesc, attr);1553+ return GetPgAttributeAttrTuple(cc_tupdesc, attr, &attrExtra);
1549 } else if (cache_id == ATTNAME) {1554 } else if (cache_id == ATTNAME) {
1550 Form_pg_attribute attr;1555 Form_pg_attribute attr;
1551 for (int16 attnum = 0; attnum < catalogDesc.natts; attnum++) {1556 for (int16 attnum = 0; attnum < catalogDesc.natts; attnum++) {
1552 tempAttr = catlogAttrs[attnum];1557 tempAttr = catlogAttrs[attnum];
1553 attr = &tempAttr;1558 attr = &tempAttr;
1554 if (strcmp(NameStr(*DatumGetName(arguments[1])), NameStr(attr->attname)) == 0) {1559 if (strcmp(NameStr(*DatumGetName(arguments[1])), NameStr(attr->attname)) == 0) {
1555- return GetPgAttributeAttrTuple(cc_tupdesc, attr);1560+ return GetPgAttributeAttrTuple(cc_tupdesc, attr, &attrExtra);
1556 }1561 }
1557 }1562 }
1558 attr = SystemAttributeByName(NameStr(*DatumGetName(arguments[1])), catalogDesc.hasoids);1563 attr = SystemAttributeByName(NameStr(*DatumGetName(arguments[1])), catalogDesc.hasoids);
@@ -1560,7 +1565,7 @@ HeapTuple SearchPgAttributeCacheMiss(int cache_id, TupleDesc cc_tupdesc, int nke
1560 return NULL;1565 return NULL;
1561 }1566 }
1562 attr->attrelid = relOid;1567 attr->attrelid = relOid;
1563- return GetPgAttributeAttrTuple(cc_tupdesc, attr);1568+ return GetPgAttributeAttrTuple(cc_tupdesc, attr, &attrExtra);
1564 } else {1569 } else {
1565 ereport(ERROR,1570 ereport(ERROR,
1566 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),1571 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -2302,6 +2307,8 @@ List* SearchPgAttributeCacheList(CatCache* cache, int nkey, Datum* arguments, Li
2302 Index hashIndex;2307 Index hashIndex;
2303 Form_pg_attribute attr;2308 Form_pg_attribute attr;
2304 FormData_pg_attribute tempAttr;2309 FormData_pg_attribute tempAttr;
2310+ FormData_pg_attribute_extra attrExtra = {0};
2311+ 
2305 if (attnum < catalogDesc.natts) {2312 if (attnum < catalogDesc.natts) {
2306 tempAttr = catlogAttrs[attnum];2313 tempAttr = catlogAttrs[attnum];
2307 attr = &tempAttr;2314 attr = &tempAttr;
@@ -2314,7 +2321,7 @@ List* SearchPgAttributeCacheList(CatCache* cache, int nkey, Datum* arguments, Li
2314 attr = SystemAttributeDefinition(-(index + 1), catalogDesc.hasoids, false, false);2321 attr = SystemAttributeDefinition(-(index + 1), catalogDesc.hasoids, false, false);
2315 attr->attrelid = relOid;2322 attr->attrelid = relOid;
2316 }2323 }
2317- heapTuple = GetPgAttributeAttrTuple(cache->cc_tupdesc, attr);2324+ heapTuple = GetPgAttributeAttrTuple(cache->cc_tupdesc, attr, &attrExtra);
2318 cTup = NULL;2325 cTup = NULL;
2319 hashValue = CatalogCacheComputeTupleHashValue(cache->id, cache->cc_keyno, cache->cc_tupdesc,2326 hashValue = CatalogCacheComputeTupleHashValue(cache->id, cache->cc_keyno, cache->cc_tupdesc,
2320 cache->cc_hashfunc, cache->cc_reloid, cache->cc_nkeys, heapTuple);2327 cache->cc_hashfunc, cache->cc_reloid, cache->cc_nkeys, heapTuple);
@@ -1234,6 +1234,8 @@ void GlobalSysTupCache::SearchPgAttributeCacheList(InsertCatListInfo *list_info)
1234 for (int16 attnum = 0; attnum < catalogDesc.natts + GetSysAttLength(hasBucketAttr); attnum++) {1234 for (int16 attnum = 0; attnum < catalogDesc.natts + GetSysAttLength(hasBucketAttr); attnum++) {
1235 Form_pg_attribute attr;1235 Form_pg_attribute attr;
1236 FormData_pg_attribute tempAttr;1236 FormData_pg_attribute tempAttr;
1237+ FormData_pg_attribute_extra attrExtra = {0};
1238+ 
1237 if (attnum < catalogDesc.natts) {1239 if (attnum < catalogDesc.natts) {
1238 tempAttr = catlogAttrs[attnum];1240 tempAttr = catlogAttrs[attnum];
1239 attr = &tempAttr;1241 attr = &tempAttr;
@@ -1246,7 +1248,7 @@ void GlobalSysTupCache::SearchPgAttributeCacheList(InsertCatListInfo *list_info)
1246 attr = SystemAttributeDefinition(-(index + 1), catalogDesc.hasoids, false, false);1248 attr = SystemAttributeDefinition(-(index + 1), catalogDesc.hasoids, false, false);
1247 attr->attrelid = relOid;1249 attr->attrelid = relOid;
1248 }1250 }
1249- HeapTuple ntp = GetPgAttributeAttrTuple(m_relinfo.cc_tupdesc, attr);1251+ HeapTuple ntp = GetPgAttributeAttrTuple(m_relinfo.cc_tupdesc, attr, &attrExtra);
1250 InsertCatTupInfo tup_info;1252 InsertCatTupInfo tup_info;
1251 tup_info.find_type = PGATTR_LIST_SKIP;1253 tup_info.find_type = PGATTR_LIST_SKIP;
1252 InitInsertCatTupInfo(&tup_info, ntp, list_info->arguments);1254 InitInsertCatTupInfo(&tup_info, ntp, list_info->arguments);
@@ -805,42 +805,47 @@ Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
805char* get_attname(Oid relid, AttrNumber attnum, bool allowDropped)805char* get_attname(Oid relid, AttrNumber attnum, bool allowDropped)
806{806{
807 HeapTuple tp;807 HeapTuple tp;
808+ char* attname = NULL;
809+ 
808 tp = SearchSysCache2(ATTNUM, ObjectIdGetDatum(relid), Int16GetDatum(attnum));810 tp = SearchSysCache2(ATTNUM, ObjectIdGetDatum(relid), Int16GetDatum(attnum));
809 if (HeapTupleIsValid(tp)) {811 if (HeapTupleIsValid(tp)) {
810 Form_pg_attribute att_tup = (Form_pg_attribute)GETSTRUCT(tp);812 Form_pg_attribute att_tup = (Form_pg_attribute)GETSTRUCT(tp);
811- char* result = NULL;
812 if (!att_tup->attisdropped) {813 if (!att_tup->attisdropped) {
813- result = pstrdup(NameStr(att_tup->attname));814+ attname = pstrdup(NameStr(att_tup->attname));
814 } else if (allowDropped && att_tup->attisdropped) {815 } else if (allowDropped && att_tup->attisdropped) {
815- result = pstrdup(NameStr(att_tup->attdroppedname));816+ attname = get_attdroppedname(relid, attnum);
816 }817 }
817 ReleaseSysCache(tp);818 ReleaseSysCache(tp);
818- return result;
819- } else {
820- return NULL;
821 }819 }
820+ 
821+ return attname;
822}822}
823 823 
824/*824/*
825- * get_kvtype825+ * get_attkvtype
826 * Given the relation id and the attribute number,826 * Given the relation id and the attribute number,
827 * return the field type(ATT_KV_UNDEFINED/ATT_KV_TAG/ATT_KV_FIELD/ATT_KV_TIME/ATT_KV_HIDE)827 * return the field type(ATT_KV_UNDEFINED/ATT_KV_TAG/ATT_KV_FIELD/ATT_KV_TIME/ATT_KV_HIDE)
828 * from the attribute relation.828 * from the attribute relation.
829 *829 *
830 * Note: -1 if no such attribute.830 * Note: -1 if no such attribute.
831 */831 */
832-int get_kvtype(Oid relid, AttrNumber attnum)832+int get_attkvtype(Oid relid, AttrNumber attnum)
833{833{
834 HeapTuple tp;834 HeapTuple tp;
835+ Datum kv;
836+ int kvtype = ATT_KV_UNDEFINED;
837+ bool isNull = false;
838+ 
835 tp = SearchSysCache2(ATTNUM, ObjectIdGetDatum(relid), Int16GetDatum(attnum));839 tp = SearchSysCache2(ATTNUM, ObjectIdGetDatum(relid), Int16GetDatum(attnum));
836 if (HeapTupleIsValid(tp)) {840 if (HeapTupleIsValid(tp)) {
837- Form_pg_attribute att_tup = (Form_pg_attribute)GETSTRUCT(tp);841+ kv = SysCacheGetAttr(ATTNUM, tp, Anum_pg_attribute_attkvtype, &isNull);
838- int kvtype = att_tup->attkvtype;842+ if (!isNull) {
843+ kvtype = DatumGetInt8(kv);
844+ }
839 ReleaseSysCache(tp);845 ReleaseSysCache(tp);
840- return kvtype;
841- } else {
842- return -1;
843 }846 }
847+ 
848+ return kvtype;
844}849}
845 850 
846/*851/*
@@ -872,16 +877,69 @@ char* get_relid_attribute_name(Oid relid, AttrNumber attnum, bool allowDropped)
872AttrNumber get_attnum(Oid relid, const char* attname)877AttrNumber get_attnum(Oid relid, const char* attname)
873{878{
874 HeapTuple tp;879 HeapTuple tp;
880+ Form_pg_attribute att_tup;
881+ AttrNumber result = InvalidAttrNumber;
882+ 
875 tp = SearchSysCacheAttName(relid, attname);883 tp = SearchSysCacheAttName(relid, attname);
876 if (HeapTupleIsValid(tp)) {884 if (HeapTupleIsValid(tp)) {
877- Form_pg_attribute att_tup = (Form_pg_attribute)GETSTRUCT(tp);885+ att_tup = (Form_pg_attribute)GETSTRUCT(tp);
878- AttrNumber result;
879 result = att_tup->attnum;886 result = att_tup->attnum;
880 ReleaseSysCache(tp);887 ReleaseSysCache(tp);
881- return result;
882- } else {
883- return InvalidAttrNumber;
884 }888 }
889+ 
890+ return result;
891+}
892+ 
893+char* get_attdroppedname(Oid relid, AttrNumber attnum)
894+{
895+ HeapTuple tp;
896+ Datum name;
897+ bool isNull;
898+ char* droppedName = NULL;
899+ 
900+ tp = SearchSysCache2(ATTNUM,
901+ ObjectIdGetDatum(relid),
902+ Int16GetDatum(attnum));
903+ if (HeapTupleIsValid(tp)) {
904+ name = SysCacheGetAttr(ATTNUM, tp, Anum_pg_attribute_attdroppedname, &isNull);
905+ if (!isNull) {
906+ droppedName = pstrdup(NameStr(*DatumGetName(name)));
907+ }
908+ ReleaseSysCache(tp);
909+ }
910+ 
911+ return droppedName;
912+}
913+ 
914+/*
915+ * get_attidentity
916+ *
917+ * Given the relation id and the attribute name,
918+ * return the "attidentity" field from the attribute relation.
919+ *
920+ * Returns '\0' if not found.
921+ *
922+ * Since no identity is represented by '\0', this can also be used as a
923+ * Boolean test.
924+ */
925+char get_attidentity(Oid relid, AttrNumber attnum)
926+{
927+ HeapTuple tp;
928+ Datum identity;
929+ bool isNull = false;
930+ char attidentity = '\0';
931+ tp = SearchSysCache2(ATTNUM,
932+ ObjectIdGetDatum(relid),
933+ Int16GetDatum(attnum));
934+ if (HeapTupleIsValid(tp)) {
935+ identity = SysCacheGetAttr(ATTNUM, tp, Anum_pg_attribute_attidentity, &isNull);
936+ if (!isNull) {
937+ attidentity = DatumGetChar(identity);
938+ }
939+ ReleaseSysCache(tp);
940+ }
941+ 
942+ return attidentity;
885}943}
886 944 
887/*945/*
@@ -1785,8 +1785,8 @@ static void RelationBuildTupleDesc(Relation relation, bool onlyLoadInitDefVal)
1785 ereport(eLevel,(errmsg("Catalog attribute %d for relation \"%s\" has been updated concurrently",1785 ereport(eLevel,(errmsg("Catalog attribute %d for relation \"%s\" has been updated concurrently",
1786 attp->attnum, RelationGetRelationName(relation))));1786 attp->attnum, RelationGetRelationName(relation))));
1787 }1787 }
1788- errno_t rc = memcpy_s(1788+ errno_t rc = memcpy_s(&relation->rd_att->attrs[attp->attnum - 1], ATTRIBUTE_FIXED_PART_SIZE,
1789- &relation->rd_att->attrs[attp->attnum - 1], ATTRIBUTE_FIXED_PART_SIZE, attp, ATTRIBUTE_FIXED_PART_SIZE);1789+ attp, ATTRIBUTE_FIXED_PART_SIZE);
1790 securec_check(rc, "\0", "\0");1790 securec_check(rc, "\0", "\0");
1791 }1791 }
1792 if (initdvals != NULL) {1792 if (initdvals != NULL) {
@@ -1829,7 +1829,7 @@ static void RelationBuildTupleDesc(Relation relation, bool onlyLoadInitDefVal)
1829 for (int i = 0; i < relation->rd_att->natts; i++) {1829 for (int i = 0; i < relation->rd_att->natts; i++) {
1830 if (relation->rd_att->attrs[i].attnum == 0) {1830 if (relation->rd_att->attrs[i].attnum == 0) {
1831 errno_t rc = memcpy_s(&relation->rd_att->attrs[i], ATTRIBUTE_FIXED_PART_SIZE,1831 errno_t rc = memcpy_s(&relation->rd_att->attrs[i], ATTRIBUTE_FIXED_PART_SIZE,
1832- attp, ATTRIBUTE_FIXED_PART_SIZE);1832+ attp, ATTRIBUTE_FIXED_PART_SIZE);
1833 securec_check(rc, "\0", "\0");1833 securec_check(rc, "\0", "\0");
1834 1834 
1835 if (initdvals != NULL) {1835 if (initdvals != NULL) {
@@ -2247,6 +2247,7 @@ static Relation CatalogRelationBuildDesc(const char* relationName, Oid relationR
2247 errno_t rc = EOK;2247 errno_t rc = EOK;
2248 rc = memcpy_s(&relation->rd_att->attrs[i], ATTRIBUTE_FIXED_PART_SIZE, &attrs[i], ATTRIBUTE_FIXED_PART_SIZE);2248 rc = memcpy_s(&relation->rd_att->attrs[i], ATTRIBUTE_FIXED_PART_SIZE, &attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
2249 securec_check(rc, "\0", "\0");2249 securec_check(rc, "\0", "\0");
2250+ 
2250 has_not_null = has_not_null || attrs[i].attnotnull;2251 has_not_null = has_not_null || attrs[i].attnotnull;
2251 /* make sure attcacheoff is valid */2252 /* make sure attcacheoff is valid */
2252 relation->rd_att->attrs[i].attcacheoff = -1;2253 relation->rd_att->attrs[i].attcacheoff = -1;
@@ -3348,7 +3349,7 @@ extern void formrdesc(const char* relationName, Oid relationReltype, bool isshar
3348 has_not_null = false;3349 has_not_null = false;
3349 for (i = 0; i < natts; i++) {3350 for (i = 0; i < natts; i++) {
3350 errno_t rc = memcpy_s(&relation->rd_att->attrs[i], ATTRIBUTE_FIXED_PART_SIZE,3351 errno_t rc = memcpy_s(&relation->rd_att->attrs[i], ATTRIBUTE_FIXED_PART_SIZE,
3351- &attrs[i], ATTRIBUTE_FIXED_PART_SIZE);3352+ &attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
3352 securec_check(rc, "", "");3353 securec_check(rc, "", "");
3353 has_not_null = has_not_null || attrs[i].attnotnull;3354 has_not_null = has_not_null || attrs[i].attnotnull;
3354 /* make sure attcacheoff is valid */3355 /* make sure attcacheoff is valid */
@@ -5027,8 +5028,6 @@ Relation RelationBuildLocalRelation(const char* relname, Oid relnamespace, Tuple
5027 */5028 */
5028 (void)MemoryContextSwitchTo(oldcxt);5029 (void)MemoryContextSwitchTo(oldcxt);
5029 5030 
5030- 
5031- 
5032 /*5031 /*
5033 * Caller expects us to pin the returned entry.5032 * Caller expects us to pin the returned entry.
5034 */5033 */
@@ -8791,7 +8790,6 @@ RelationMetaData* make_relmeta(Relation rel)
8791 8790 
8792 attr->attalign = rel->rd_att->attrs[i].attalign;8791 attr->attalign = rel->rd_att->attrs[i].attalign;
8793 attr->attbyval = rel->rd_att->attrs[i].attbyval;8792 attr->attbyval = rel->rd_att->attrs[i].attbyval;
8794- attr->attkvtype = rel->rd_att->attrs[i].attkvtype;
8795 attr->attcmprmode = rel->rd_att->attrs[i].attcmprmode;8793 attr->attcmprmode = rel->rd_att->attrs[i].attcmprmode;
8796 attr->attcollation = rel->rd_att->attrs[i].attcollation;8794 attr->attcollation = rel->rd_att->attrs[i].attcollation;
8797 attr->atthasdef = rel->rd_att->attrs[i].atthasdef;8795 attr->atthasdef = rel->rd_att->attrs[i].atthasdef;
@@ -8857,7 +8855,6 @@ Relation get_rel_from_meta(RelationMetaData* node)
8857 8855 
8858 rel->rd_att->attrs[i].attalign = attr->attalign;8856 rel->rd_att->attrs[i].attalign = attr->attalign;
8859 rel->rd_att->attrs[i].attbyval = attr->attbyval;8857 rel->rd_att->attrs[i].attbyval = attr->attbyval;
8860- rel->rd_att->attrs[i].attkvtype = attr->attkvtype;
8861 rel->rd_att->attrs[i].attcmprmode = attr->attcmprmode;8858 rel->rd_att->attrs[i].attcmprmode = attr->attcmprmode;
8862 rel->rd_att->attrs[i].attcollation = attr->attcollation;8859 rel->rd_att->attrs[i].attcollation = attr->attcollation;
8863 rel->rd_att->attrs[i].atthasdef = attr->atthasdef;8860 rel->rd_att->attrs[i].atthasdef = attr->atthasdef;
@@ -345,6 +345,7 @@ Section: Class 42 - Syntax Error or Access Rule Violation
34542P21 E ERRCODE_COLLATION_MISMATCH collation_mismatch34542P21 E ERRCODE_COLLATION_MISMATCH collation_mismatch
34642P22 E ERRCODE_INDETERMINATE_COLLATION indeterminate_collation34642P22 E ERRCODE_INDETERMINATE_COLLATION indeterminate_collation
34742809 E ERRCODE_WRONG_OBJECT_TYPE wrong_object_type34742809 E ERRCODE_WRONG_OBJECT_TYPE wrong_object_type
348+428C9 E ERRCODE_GENERATED_ALWAYS generated_always
34842P23 E ERRCODE_PARTITION_ERROR partition_error34942P23 E ERRCODE_PARTITION_ERROR partition_error
34942P24 E ERRCODE_INVALID_ATTRIBUTE invalid_attribute35042P24 E ERRCODE_INVALID_ATTRIBUTE invalid_attribute
35042P25 E ERRCODE_INVALID_AGG invalid_agg35142P25 E ERRCODE_INVALID_AGG invalid_agg
@@ -77,12 +77,13 @@ bool will_shutdown = false;
77 *77 *
78 ********************************************/78 ********************************************/
79 79 
80-const uint32 GRAND_VERSION_NUM = 93094;80+const uint32 GRAND_VERSION_NUM = 93101;
81 81 
82/********************************************82/********************************************
83 * 2.VERSION NUM FOR EACH FEATURE83 * 2.VERSION NUM FOR EACH FEATURE
84 * Please write indescending order.84 * Please write indescending order.
85 ********************************************/85 ********************************************/
86+const uint32 PG_IDENTITY_VERSION_NUM = 93101;
86const uint32 SUPPORT_CREATE_ACCESS_METHOD_VERSION_NUM = 93094;87const uint32 SUPPORT_CREATE_ACCESS_METHOD_VERSION_NUM = 93094;
87const uint32 NEON_VERSION_NUM = 93090;88const uint32 NEON_VERSION_NUM = 93090;
88const uint32 WITH_ORDINALITY_VERSION_NUM = 93089;89const uint32 WITH_ORDINALITY_VERSION_NUM = 93089;
@@ -96,7 +97,7 @@ const uint32 UPGRADE_SHARK_3_0_VERSION_NUM = 93070;
96const uint32 PGSTAT_LAST_SCAN_VERSION_NUM = 93065;97const uint32 PGSTAT_LAST_SCAN_VERSION_NUM = 93065;
97const uint32 INLINEVIEW_DML_VERSION_NUM = 93063;98const uint32 INLINEVIEW_DML_VERSION_NUM = 93063;
98const uint32 HALFVEC_VERSION_NUM = 93060;99const uint32 HALFVEC_VERSION_NUM = 93060;
99-const uint32 IDENTITY_VERSION_NUM = 93059;100+const uint32 D_IDENTITY_VERSION_NUM = 93059;
100const uint32 DISKANN_INDEX = 93058;101const uint32 DISKANN_INDEX = 93058;
101const uint32 INSTR_TRACE_VERSION_NUMBER = 93053;102const uint32 INSTR_TRACE_VERSION_NUMBER = 93053;
102const uint32 SELECT_STMT_HAS_ROTATE = 93047;103const uint32 SELECT_STMT_HAS_ROTATE = 93047;
@@ -398,7 +398,6 @@ extern THR_LOCAL bool stmt_contains_operator_plus;
398%type <str> character398%type <str> character
399%type <str> character_national399%type <str> character_national
400%type <str> extract_arg400%type <str> extract_arg
401-%type <str> opt_charset
402%type <boolean> opt_varying opt_timezone opt_no_inherit401%type <boolean> opt_varying opt_timezone opt_no_inherit
403 402 
404%type <ival> Iconst SignedIconst403%type <ival> Iconst SignedIconst
@@ -430,7 +429,6 @@ extern THR_LOCAL bool stmt_contains_operator_plus;
430 429 
431%type <node> func_application func_expr_common_subexpr430%type <node> func_application func_expr_common_subexpr
432%type <node> common_table_expr431%type <node> common_table_expr
433-%type <keep> keep_clause
434%type <with> with_clause opt_with_clause432%type <with> with_clause opt_with_clause
435%type <list> cte_list433%type <list> cte_list
436 434 
@@ -580,7 +578,7 @@ extern THR_LOCAL bool stmt_contains_operator_plus;
580 NOT NOTHING NOTIFY NOTNULL NOVALIDATE NOWAIT NTH_VALUE_P NULL_P NULLCOLS NULLIF NULLS_P NUMBER_P NUMERIC NUMSTR NVARCHAR NVARCHAR2 NVL578 NOT NOTHING NOTIFY NOTNULL NOVALIDATE NOWAIT NTH_VALUE_P NULL_P NULLCOLS NULLIF NULLS_P NUMBER_P NUMERIC NUMSTR NVARCHAR NVARCHAR2 NVL
581 579 
582 OBJECT_P OF OFF OFFSET OIDS ON ONLY OPERATOR OPTIMIZATION OPTION OPTIONALLY OPTIONS OR580 OBJECT_P OF OFF OFFSET OIDS ON ONLY OPERATOR OPTIMIZATION OPTION OPTIONALLY OPTIONS OR
583- ORDER ORDINALITY OUT_P OUTER_P OVER OVERLAPS OVERLAY OWNED OWNER OUTFILE581+ ORDER ORDINALITY OUT_P OUTER_P OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER OUTFILE
584 582 
585 PACKAGE PACKAGES PARALLEL_ENABLE PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PCTFREE PER_P PERCENT PERFORMANCE PERM PLACING PLAN PLANS POLICY POSITION583 PACKAGE PACKAGES PARALLEL_ENABLE PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PCTFREE PER_P PERCENT PERFORMANCE PERM PLACING PLAN PLANS POLICY POSITION
586 PIPELINED584 PIPELINED
@@ -9102,11 +9100,6 @@ opt_varying:
9102 | /*EMPTY*/ { $$ = FALSE; }9100 | /*EMPTY*/ { $$ = FALSE; }
9103 ;9101 ;
9104 9102 
9105-opt_charset:
9106- CHARACTER SET ColId { $$ = $3; }
9107- | /*EMPTY*/ { $$ = NULL; }
9108- ;
9109- 
9110/*9103/*
9111 * SQL92 date/time types9104 * SQL92 date/time types
9112 */9105 */
@@ -12190,6 +12183,7 @@ unreserved_keyword:
12190 | OPTIONALLY12183 | OPTIONALLY
12191 | OPTIONS12184 | OPTIONS
12192 | ORDINALITY12185 | ORDINALITY
12186+ | OVERRIDING
12193 | OWNED12187 | OWNED
12194 | OWNER12188 | OWNER
12195 | OUTFILE12189 | OUTFILE
@@ -375,7 +375,7 @@ static void append_array_varchar_delete(StringInfo sqlBuf);
375%type <plnode> assign_el375%type <plnode> assign_el
376%type <declhdr> decl_sect376%type <declhdr> decl_sect
377%type <varname> decl_varname declare_condname377%type <varname> decl_varname declare_condname
378-%type <list> decl_varname_list opt_subtype_range378+%type <list> decl_varname_list
379%type <boolean> decl_const decl_notnull exit_type379%type <boolean> decl_const decl_notnull exit_type
380%type <expr> decl_defval decl_rec_defval decl_cursor_query380%type <expr> decl_defval decl_rec_defval decl_cursor_query
381%type <dtype> decl_datatype opt_cursor_returntype subtype_base_type381%type <dtype> decl_datatype opt_cursor_returntype subtype_base_type
@@ -2328,10 +2328,7 @@ init_proc :
2328 {2328 {
2329 $$ = get_init_proc(yychar);2329 $$ = get_init_proc(yychar);
2330 yyclearin;2330 yyclearin;
2331- } 2331+ }
2332- 
2333-opt_subtype_range :
2334- { $$ = NIL; };
2335 2332 
2336record_attr_list : record_attr2333record_attr_list : record_attr
2337 {2334 {
@@ -5576,7 +5573,6 @@ stmt_execsql : K_ALTER
5576 {5573 {
5577 int tok = -1;5574 int tok = -1;
5578 bool FuncNoarg = false;5575 bool FuncNoarg = false;
5579- char* serverName = NULL;
5580 PLwdatum *objtypwdatum = NULL;5576 PLwdatum *objtypwdatum = NULL;
5581 PLwdatum objtypwdatumtemp;5577 PLwdatum objtypwdatumtemp;
5582 objtypwdatumtemp.datum = yylval.wdatum.datum;5578 objtypwdatumtemp.datum = yylval.wdatum.datum;
@@ -8722,8 +8718,9 @@ static void checkTypeName(List* nest_typnames, List* target_nest_typnames)
8722 bool found = false;8718 bool found = false;
8723 List* funcname = NIL;8719 List* funcname = NIL;
8724 FuncCandidateList clist = NULL;8720 FuncCandidateList clist = NULL;
8725- char *cp[3] = {0};8721+ const int SIZE = 3;
8726- 8722+ char *cp[SIZE] = {0};
8723+ 
8727 for (i = 0; i < target_nest_typnames->length; i++) {8724 for (i = 0; i < target_nest_typnames->length; i++) {
8728 if (target_ntype->layer == ntype->layer &&8725 if (target_ntype->layer == ntype->layer &&
8729 (target_ntype->index == -1 || target_ntype->index == ntype->index)) {8726 (target_ntype->index == -1 || target_ntype->index == ntype->index)) {
@@ -8757,8 +8754,8 @@ static void checkTypeName(List* nest_typnames, List* target_nest_typnames)
8757 continue;8754 continue;
8758 }8755 }
8759 8756 
8760- plpgsql_parser_funcname(ntype->typname, cp, 3);8757+ plpgsql_parser_funcname(ntype->typname, cp, SIZE);
8761- for (int i = 0; i < (sizeof(cp) / sizeof(cp[0]) - 1) ; i++) {8758+ for (int i = 0; i < SIZE; i++) {
8762 if (cp[i] && cp[i][0] != '\0') {8759 if (cp[i] && cp[i][0] != '\0') {
8763 if (i != 0) {8760 if (i != 0) {
8764 funcname = lappend(funcname, makeString(cp[i]));8761 funcname = lappend(funcname, makeString(cp[i]));
@@ -8782,7 +8779,8 @@ static void checkTypeName(List* nest_typnames, List* target_nest_typnames)
8782 errno_t rc = snprintf_s(mes, length, length -1, "%s\"%s\"", report_mes, ntype->typname);8779 errno_t rc = snprintf_s(mes, length, length -1, "%s\"%s\"", report_mes, ntype->typname);
8783 securec_check_ss(rc, "", "");8780 securec_check_ss(rc, "", "");
8784 InsertErrorMessage(mes, plpgsql_yylloc);8781 InsertErrorMessage(mes, plpgsql_yylloc);
8785- ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg(mes)));8782+ ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT),
8783+ errmsg("Wrong type of expression, should not use type \"%s\"", ntype->typname)));
8786 }8784 }
8787}8785}
8788 8786 
@@ -9006,7 +9004,7 @@ static bool construct_object_type(StringInfo ds, ArrayParseContext *context, Typ
9006 return construct_array_start(ds, context, type, tok, parenlevel, loc);9004 return construct_array_start(ds, context, type, tok, parenlevel, loc);
9007 }9005 }
9008 if (type->typtyp == TYPTYPE_ABSTRACT_OBJECT)9006 if (type->typtyp == TYPTYPE_ABSTRACT_OBJECT)
9009- appendStringInfo(ds, name_str);9007+ appendStringInfoString(ds, name_str);
9010 else9008 else
9011 appendStringInfo(ds, "ROW");9009 appendStringInfo(ds, "ROW");
9012 pfree_ext(name_str);9010 pfree_ext(name_str);
@@ -9186,7 +9184,6 @@ read_sql_construct6(int until,
9186 ArrayParseContext context;9184 ArrayParseContext context;
9187 List *idents = 0;9185 List *idents = 0;
9188 List* nest_typnames = NIL;9186 List* nest_typnames = NIL;
9189- int comma_cnt = 0;
9190 int typname_indexs[MAX_LAYER] = {0};9187 int typname_indexs[MAX_LAYER] = {0};
9191 const char left_bracket[2] = "[";9188 const char left_bracket[2] = "[";
9192 const char right_bracket[2] = "]";9189 const char right_bracket[2] = "]";
@@ -9199,7 +9196,7 @@ read_sql_construct6(int until,
9199 int left_brace_count = 0;9196 int left_brace_count = 0;
9200 int right_brace_count = 0;9197 int right_brace_count = 0;
9201 bool stop_count = false;9198 bool stop_count = false;
9202- int stop_tok;9199+ int stop_tok = -1;
9203 bool record_typename = false;9200 bool record_typename = false;
9204 int bracket_diff=0;9201 int bracket_diff=0;
9205 /* mark if there are 2 table of index by var call functions in an expr */9202 /* mark if there are 2 table of index by var call functions in an expr */
@@ -14112,7 +14109,6 @@ static Oid plpgsql_build_anonymous_subtype(char* typname, PLpgSQL_type* newp, co
14112 Form_pg_type baseType;14109 Form_pg_type baseType;
14113 ObjectAddress referenced;14110 ObjectAddress referenced;
14114 PLpgSQL_type* res = NULL;14111 PLpgSQL_type* res = NULL;
14115- SubTypeRange* typerange = NULL;
14116 14112 
14117 /* check is typname too long */14113 /* check is typname too long */
14118 if (strlen(typname) >= NAMEDATALEN) {14114 if (strlen(typname) >= NAMEDATALEN) {
@@ -14227,7 +14223,6 @@ plpgsql_build_function_package_subtype(char* typname, PLpgSQL_type* newp, const
14227 char* pkgtypname = NULL;14223 char* pkgtypname = NULL;
14228 char* schamaname = NULL;14224 char* schamaname = NULL;
14229 Oid pkgoid = InvalidOid;14225 Oid pkgoid = InvalidOid;
14230- SubTypeRange* typerange = NULL;
14231 char* casttypename = NULL;14226 char* casttypename = NULL;
14232 bool sameType = false;14227 bool sameType = false;
14233 14228 
@@ -14419,7 +14414,8 @@ check_labels(const char *start_label, const char *end_label, int end_location)
14419 ereport(errstate,14414 ereport(errstate,
14420 (errcode(ERRCODE_SYNTAX_ERROR),14415 (errcode(ERRCODE_SYNTAX_ERROR),
14421 errmsg("end label \"%s\" differs from block's label \"%s\"",14416 errmsg("end label \"%s\" differs from block's label \"%s\"",
14422- end_label, start_label),14417+ end_label == NULL ? "NULL" : end_label,
14418+ start_label == NULL ? "NULL" : start_label),
14423 parser_errposition(end_location)));14419 parser_errposition(end_location)));
14424 }14420 }
14425 }14421 }
@@ -706,6 +706,12 @@ void UniqueSql::JumbleExpr(pgssJumbleState* jstate, Node* node)
706 706 
707 break;707 break;
708 }708 }
709+ case T_NextValueExpr: {
710+ NextValueExpr* nve = (NextValueExpr*)node;
711+ APP_JUMB(nve->seqid);
712+ APP_JUMB(nve->typeId);
713+ break;
714+ }
709 case T_TargetEntry: {715 case T_TargetEntry: {
710 TargetEntry* tle = (TargetEntry*)node;716 TargetEntry* tle = (TargetEntry*)node;
711 APP_JUMB(tle->resno);717 APP_JUMB(tle->resno);
@@ -1552,9 +1552,11 @@ Oid make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, int lockMode)
1552 bool isNull = false;1552 bool isNull = false;
1553 int ss_c = 0;1553 int ss_c = 0;
1554 HashBucketInfo bucketinfo;1554 HashBucketInfo bucketinfo;
1555+ Form_pg_attribute_extra attrExtra;
1555 1556 
1556 OldHeap = heap_open(OIDOldHeap, lockMode);1557 OldHeap = heap_open(OIDOldHeap, lockMode);
1557 OldHeapDesc = RelationGetDescr(OldHeap);1558 OldHeapDesc = RelationGetDescr(OldHeap);
1559+ attrExtra = CreatePGAttributeExtra(OldHeapDesc);
1558 1560 
1559 /*1561 /*
1560 * Note that the NewHeap will not receive any of the defaults or1562 * Note that the NewHeap will not receive any of the defaults or
@@ -1616,7 +1618,9 @@ Oid make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, int lockMode)
1616 AccessExclusiveLock,1618 AccessExclusiveLock,
1617 NULL,1619 NULL,
1618 NIL,1620 NIL,
1619- OIDOldHeap);1621+ OIDOldHeap,
1622+ InvalidOid,
1623+ attrExtra);
1620 Assert(OIDNewHeap != InvalidOid);1624 Assert(OIDNewHeap != InvalidOid);
1621 1625 
1622 ReleaseSysCache(tuple);1626 ReleaseSysCache(tuple);
@@ -1691,6 +1695,8 @@ Oid makePartitionNewHeap(Relation partitionedTableRel, TupleDesc partTabHeapDesc
1691 bool isNull = false;1695 bool isNull = false;
1692 int ss_c = 0;1696 int ss_c = 0;
1693 HashBucketInfo bucketinfo;1697 HashBucketInfo bucketinfo;
1698+ Form_pg_attribute_extra attrExtra;
1699+ 
1694 OnlineDDLRelOperators* operators = ((OnlineDDLRelOperators*)u_sess->online_ddl_operators);1700 OnlineDDLRelOperators* operators = ((OnlineDDLRelOperators*)u_sess->online_ddl_operators);
1695 bool enableOnlineDDL = (operators != NULL && operators->getStatus() == ONLINE_DDL_STATUS_BASELINE_COPY);1701 bool enableOnlineDDL = (operators != NULL && operators->getStatus() == ONLINE_DDL_STATUS_BASELINE_COPY);
1696 LOCKMODE lockmode = enableOnlineDDL ? ShareUpdateExclusiveLock : AccessExclusiveLock;1702 LOCKMODE lockmode = enableOnlineDDL ? ShareUpdateExclusiveLock : AccessExclusiveLock;
@@ -1701,6 +1707,8 @@ Oid makePartitionNewHeap(Relation partitionedTableRel, TupleDesc partTabHeapDesc
1701 ss_c = snprintf_s(NewHeapName, sizeof(NewHeapName), sizeof(NewHeapName) - 1, "pg_temp_%u", oldPartOid);1707 ss_c = snprintf_s(NewHeapName, sizeof(NewHeapName), sizeof(NewHeapName) - 1, "pg_temp_%u", oldPartOid);
1702 securec_check_ss(ss_c, "\0", "\0");1708 securec_check_ss(ss_c, "\0", "\0");
1703 bucketinfo.bucketOid = RelationGetBucketOid(partitionedTableRel);1709 bucketinfo.bucketOid = RelationGetBucketOid(partitionedTableRel);
1710+ attrExtra = CreatePGAttributeExtra(partTabHeapDesc);
1711+ 
1704 OIDNewHeap = heap_create_with_catalog(NewHeapName,1712 OIDNewHeap = heap_create_with_catalog(NewHeapName,
1705 RelationGetNamespace(partitionedTableRel),1713 RelationGetNamespace(partitionedTableRel),
1706 NewTableSpace,1714 NewTableSpace,
@@ -1726,8 +1734,15 @@ Oid makePartitionNewHeap(Relation partitionedTableRel, TupleDesc partTabHeapDesc
1726 true,1734 true,
1727 NULL,1735 NULL,
1728 RelationGetStorageType(partitionedTableRel),1736 RelationGetStorageType(partitionedTableRel),
1729- lockmode);1737+ lockmode,
1738+ NULL,
1739+ NIL,
1740+ InvalidOid,
1741+ InvalidOid,
1742+ attrExtra);
1730 Assert(OIDNewHeap != InvalidOid);1743 Assert(OIDNewHeap != InvalidOid);
1744+ pfree_ext(attrExtra);
1745+ 
1731 /*1746 /*
1732 * Advance command counter so that the newly-created relation's catalog1747 * Advance command counter so that the newly-created relation's catalog
1733 * tuples will be visible to heap_open.1748 * tuples will be visible to heap_open.
@@ -5094,7 +5109,7 @@ void HbktTransferModifyPgAttributeTablebucketid(Oid indexOid)
5094 CatalogIndexState indstate;5109 CatalogIndexState indstate;
5095 indstate = CatalogOpenIndexes(attrel);5110 indstate = CatalogOpenIndexes(attrel);
5096 5111 
5097- InsertPgAttributeTuple(attrel, &attStruct, indstate);5112+ InsertPgAttributeTuple(attrel, &attStruct, NULL, indstate);
5098 5113 
5099 CatalogCloseIndexes(indstate);5114 CatalogCloseIndexes(indstate);
5100 heap_close(attrel, RowExclusiveLock);5115 heap_close(attrel, RowExclusiveLock);
@@ -1695,7 +1695,7 @@ void ProcessCopyOptions(CopyState cstate, bool is_from, List* options)
1695 if (cstate->fill_missing_fields)1695 if (cstate->fill_missing_fields)
1696 ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options")));1696 ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options")));
1697 else1697 else
1698- cstate->fill_missing_fields = defGetMixdInt(defel);1698+ cstate->fill_missing_fields = defGetMixdBoolean(defel);
1699 } else if (strcmp(defel->defname, "noescaping") == 0) {1699 } else if (strcmp(defel->defname, "noescaping") == 0) {
1700 if (noescapingSpecified)1700 if (noescapingSpecified)
1701 ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options")));1701 ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options")));
@@ -4777,6 +4777,7 @@ uint64 CopyFrom(CopyState cstate)
4777 */4777 */
4778 if (IS_PGXC_COORDINATOR && cstate->remoteCopyState && cstate->remoteCopyState->rel_loc) {4778 if (IS_PGXC_COORDINATOR && cstate->remoteCopyState && cstate->remoteCopyState->rel_loc) {
4779 FormData_pg_attribute* attr = tupDesc->attrs;4779 FormData_pg_attribute* attr = tupDesc->attrs;
4780+ int kvtype = ATT_KV_UNDEFINED;
4780 Oid* att_type = NULL;4781 Oid* att_type = NULL;
4781 RemoteCopyData* remoteCopyState = cstate->remoteCopyState;4782 RemoteCopyData* remoteCopyState = cstate->remoteCopyState;
4782 ExecNodes* exec_nodes = NULL;4783 ExecNodes* exec_nodes = NULL;
@@ -4797,9 +4798,10 @@ uint64 CopyFrom(CopyState cstate)
4797 TsRelWithImplDistColumn(attr, dcolNum)) {4798 TsRelWithImplDistColumn(attr, dcolNum)) {
4798 pseudoTsDistcol = true;4799 pseudoTsDistcol = true;
4799 for (int i = 0; i < tupDesc->natts; i++) {4800 for (int i = 0; i < tupDesc->natts; i++) {
4801+ kvtype = GET_ATTR_KVTYPE(&attr[i]);
4800 att_type[i] = attr[i].atttypid;4802 att_type[i] = attr[i].atttypid;
4801 /* collect all the tag columns info to taglist */4803 /* collect all the tag columns info to taglist */
4802- if (attr[i].attkvtype == ATT_KV_TAG) {4804+ if (kvtype == ATT_KV_TAG) {
4803 taglist = lappend_int(taglist, i);4805 taglist = lappend_int(taglist, i);
4804 }4806 }
4805 }4807 }
@@ -361,7 +361,7 @@ static void intorel_startup(DestReceiver* self, int operation, TupleDesc typeinf
361 col->is_from_type = false;361 col->is_from_type = false;
362 col->storage = 0;362 col->storage = 0;
363 col->generatedCol = '\0';363 col->generatedCol = '\0';
364- col->kvtype = attribute->attkvtype;364+ col->kvtype = GET_ATTR_KVTYPE(attribute);
365 col->cmprs_mode = attribute->attcmprmode;365 col->cmprs_mode = attribute->attcmprmode;
366 col->raw_default = NULL;366 col->raw_default = NULL;
367 col->update_default = NULL;367 col->update_default = NULL;
@@ -181,6 +181,8 @@ static char* RelationGetColumnDefault(Relation rel, AttrNumber attno,
181 181 
182static ObjTree* deparse_ColumnDef(Relation relation, List *dpcontext, bool composite,182static ObjTree* deparse_ColumnDef(Relation relation, List *dpcontext, bool composite,
183 ColumnDef *coldef, bool is_alter, List **exprs);183 ColumnDef *coldef, bool is_alter, List **exprs);
184+static ObjTree* deparse_ColumnIdentity(Oid seqrelid, char identity, bool alter_table);
185+static ObjTree* deparse_D_ColumnIdentity(Oid seqrelid, char identity, bool alter_table);
184static ObjTree* deparse_ColumnSetOptions(AlterTableCmd *subcmd);186static ObjTree* deparse_ColumnSetOptions(AlterTableCmd *subcmd);
185 187 
186static ObjTree* deparse_DefElem(DefElem *elem, bool is_reset);188static ObjTree* deparse_DefElem(DefElem *elem, bool is_reset);
@@ -194,6 +196,7 @@ static List* get_range_partition_maxvalues(List *boundary);
194static List* get_list_partition_maxvalues(List *boundary);196static List* get_list_partition_maxvalues(List *boundary);
195static ObjTree* deparse_RelSetOptions(AlterTableCmd *subcmd);197static ObjTree* deparse_RelSetOptions(AlterTableCmd *subcmd);
196 198 
199+static inline ObjElem* deparse_Seq_SeqName(sequence_values *seqdata, bool alter_table);
197static inline ObjElem* deparse_Seq_Cache(sequence_values *seqdata, bool alter_table);200static inline ObjElem* deparse_Seq_Cache(sequence_values *seqdata, bool alter_table);
198static inline ObjElem* deparse_Seq_Cycle(sequence_values *seqdata, bool alter_table);201static inline ObjElem* deparse_Seq_Cycle(sequence_values *seqdata, bool alter_table);
199static inline ObjElem* deparse_Seq_IncrementBy(sequence_values *seqdata, bool alter_table);202static inline ObjElem* deparse_Seq_IncrementBy(sequence_values *seqdata, bool alter_table);
@@ -1696,6 +1699,7 @@ static ObjTree* deparse_ColumnDef(Relation relation, List *dpcontext, bool compo
1696 bool saw_autoincrement;1699 bool saw_autoincrement;
1697 char* onupdate = NULL;1700 char* onupdate = NULL;
1698 ListCell *cell;1701 ListCell *cell;
1702+ Oid seqrelid = InvalidOid;
1699 1703 
1700 /*1704 /*
1701 * Inherited columns without local definitions must not be emitted.1705 * Inherited columns without local definitions must not be emitted.
@@ -1796,7 +1800,8 @@ static ObjTree* deparse_ColumnDef(Relation relation, List *dpcontext, bool compo
1796 if (attrForm->atthasdef &&1800 if (attrForm->atthasdef &&
1797 coldef->generatedCol != ATTRIBUTE_GENERATED_STORED &&1801 coldef->generatedCol != ATTRIBUTE_GENERATED_STORED &&
1798 coldef->generatedCol != ATTRIBUTE_GENERATED_PERSISTED &&1802 coldef->generatedCol != ATTRIBUTE_GENERATED_PERSISTED &&
1799- !saw_autoincrement) {1803+ !saw_autoincrement &&
1804+ !coldef->identity) {
1800 char *defstr = NULL;1805 char *defstr = NULL;
1801 1806 
1802 /* initdefval intend that default value is a constant expr,1807 /* initdefval intend that default value is a constant expr,
@@ -1877,6 +1882,24 @@ static ObjTree* deparse_ColumnDef(Relation relation, List *dpcontext, bool compo
1877 }1882 }
1878 append_object_object(ret, "%{collation}s", tmp_obj);1883 append_object_object(ret, "%{collation}s", tmp_obj);
1879 }1884 }
1885+ 
1886+ /* identity column */
1887+ if (coldef->identity) {
1888+ Oid attno = get_attnum(relid, coldef->colname);
1889+ seqrelid = getIdentitySequence(relid, attno, false, coldef->identity == ATTRIBUTE_IDENTITY_D);
1890+ }
1891+ 
1892+ if (OidIsValid(seqrelid)) {
1893+ if (coldef->identity == ATTRIBUTE_IDENTITY_D) {
1894+ tmp_obj = deparse_D_ColumnIdentity(seqrelid, coldef->identity, is_alter);
1895+ } else {
1896+ tmp_obj = deparse_ColumnIdentity(seqrelid, coldef->identity, is_alter);
1897+ }
1898+ 
1899+ if (tmp_obj) {
1900+ append_object_object(ret, "%{identity_column}s", tmp_obj);
1901+ }
1902+ }
1880 }1903 }
1881 1904 
1882 ReleaseSysCache(attrTup);1905 ReleaseSysCache(attrTup);
@@ -1884,6 +1907,98 @@ static ObjTree* deparse_ColumnDef(Relation relation, List *dpcontext, bool compo
1884 return ret;1907 return ret;
1885}1908}
1886 1909 
1910+/*
1911+ * deparse definition of column identity
1912+ * SET GENERATED %{option}s %{identity_type}s %{seq_definition: }s
1913+ * OR
1914+ * GENERATED %{option}s AS IDENTITY %{identity_type}s ( {%seq_definition: }s )
1915+ */
1916+static ObjTree* deparse_ColumnIdentity(Oid seqrelid, char identity, bool alter_table)
1917+{
1918+ ObjTree *ret;
1919+ ObjTree *ident_obj;
1920+ List *elems = NIL;
1921+ sequence_values *seqvalues;
1922+ char *identfmt;
1923+ char *objfmt;
1924+ 
1925+ if (alter_table) {
1926+ identfmt = "SET GENERATED";
1927+ objfmt = "%{option}s";
1928+ } else {
1929+ identfmt = "GENERATED";
1930+ objfmt = "%{option}s AS IDENTITY";
1931+ }
1932+ 
1933+ ident_obj = new_objtree(identfmt);
1934+ 
1935+ if (identity == ATTRIBUTE_IDENTITY_ALWAYS) {
1936+ append_string_object(ident_obj, objfmt, "option", "ALWAYS");
1937+ } else if (identity == ATTRIBUTE_IDENTITY_BY_DEFAULT) {
1938+ append_string_object(ident_obj, objfmt, "option", "BY DEFAULT");
1939+ } else {
1940+ append_not_present(ident_obj, NULL);
1941+ }
1942+ 
1943+ ret = new_objtree_VA("%{identity_type}s", 1,
1944+ "identity_type", ObjTypeObject, ident_obj);
1945+ 
1946+ seqvalues = get_sequence_values(seqrelid);
1947+ 
1948+ if (!alter_table) {
1949+ ObjElem *seqname_elem = deparse_Seq_SeqName(seqvalues, false);
1950+ if (seqname_elem) {
1951+ elems = lappend(elems, seqname_elem);
1952+ }
1953+ elems = lappend(elems, deparse_Seq_Cache(seqvalues, false));
1954+ elems = lappend(elems, deparse_Seq_Cycle(seqvalues, false));
1955+ elems = lappend(elems, deparse_Seq_IncrementBy(seqvalues, false));
1956+ elems = lappend(elems, deparse_Seq_Minvalue(seqvalues, false));
1957+ elems = lappend(elems, deparse_Seq_Maxvalue(seqvalues, false));
1958+ elems = lappend(elems, deparse_Seq_Startwith(seqvalues, false));
1959+ }
1960+ elems = lappend(elems, deparse_Seq_Restart(seqvalues->last_value));
1961+ /* we purposefully do not emit OWNED BY here */
1962+ if (alter_table) {
1963+ append_array_object(ret, "%{seq_definition: }s", elems);
1964+ } else {
1965+ append_array_object(ret, "( %{seq_definition: }s )", elems);
1966+ }
1967+ 
1968+ return ret;
1969+}
1970+ 
1971+/*
1972+ * Deparse the defintion of column identity(start, inc, sequence_name) for D mode.
1973+ *
1974+ * IDENTITY(%{identity_seed}s, %{identity_inc}s, %{identity_seqname}s)
1975+ */
1976+static ObjTree* deparse_D_ColumnIdentity(Oid seqrelid, char identity, bool alter_table)
1977+{
1978+ ObjTree *ret = NULL;
1979+ sequence_values *seqvalues = get_sequence_values(seqrelid);
1980+ bool has_seqname = false;
1981+ 
1982+ has_seqname = (seqvalues->sequence_name == NULL || strcmp(seqvalues->sequence_name, "") == 0);
1983+ 
1984+ if (!alter_table) {
1985+ ObjTree *tmp;
1986+ 
1987+ if (has_seqname) {
1988+ tmp = new_objtree_VA("IDENTITY(%{identity_seed}s, %{identity_inc}s, %{identity_seqname}s)", 3,
1989+ "identity_seed", ObjTypeString, seqvalues->start_value,
1990+ "identity_inc", ObjTypeString, seqvalues->increment_by,
1991+ "identity_seqname", ObjTypeString, seqvalues->sequence_name);
1992+ } else {
1993+ tmp = new_objtree_VA("IDENTITY(%{identity_seed}s, %{identity_inc}s)", 2,
1994+ "identity_seed", ObjTypeString, seqvalues->start_value,
1995+ "identity_inc", ObjTypeString, seqvalues->increment_by);
1996+ }
1997+ ret = new_objtree_VA("%{seq_definition}s", 1,
1998+ "seq_definition", ObjTypeObject, tmp);
1999+ }
2000+ return ret;
2001+}
1887 2002 
1888/*2003/*
1889 * Deparse DefElems2004 * Deparse DefElems
@@ -1952,6 +2067,26 @@ static ObjTree* deparse_OnCommitClause(OnCommitAction option)
1952 return ret;2067 return ret;
1953}2068}
1954 2069 
2070+/*
2071+ * Deparse the sequence SEQUENCE_NAME option
2072+ */
2073+static inline ObjElem* deparse_Seq_SeqName(sequence_values *seqdata, bool alter_table)
2074+{
2075+ ObjTree *ret;
2076+ const char *fmt;
2077+ 
2078+ if (seqdata->sequence_name == NULL ||
2079+ strcmp(seqdata->sequence_name, "") == 0) {
2080+ return NULL;
2081+ }
2082+ 
2083+ fmt = alter_table ? "SET SEQUENCE NAME %{value}s" : "SEQUENCE NAME %{value}s";
2084+ ret = new_objtree_VA(fmt, 2,
2085+ "clause", ObjTypeString, "sequence name",
2086+ "value", ObjTypeString, seqdata->sequence_name);
2087+ return new_object_object(ret);
2088+}
2089+ 
1955/*2090/*
1956 * Deparse the sequence CACHE option.2091 * Deparse the sequence CACHE option.
1957 *2092 *
@@ -2325,8 +2460,11 @@ static ObjTree* deparse_CreateSeqStmt(Oid objectId, Node *parsetree)
2325 sequence_values *seqvalues;2460 sequence_values *seqvalues;
2326 CreateSeqStmt *createSeqStmt = (CreateSeqStmt *) parsetree;2461 CreateSeqStmt *createSeqStmt = (CreateSeqStmt *) parsetree;
2327 2462 
2328- if (createSeqStmt->is_autoinc)2463+ if (createSeqStmt->forIdentity ||
2464+ createSeqStmt->forDIdentity ||
2465+ createSeqStmt->is_autoinc) {
2329 return NULL;2466 return NULL;
2467+ }
2330 2468 
2331 seqvalues = get_sequence_values(objectId);2469 seqvalues = get_sequence_values(objectId);
2332 2470 
@@ -2372,7 +2510,9 @@ static ObjTree* deparse_AlterSeqStmt(Oid objectId, Node *parsetree)
2372 sequence_values *seqvalues;2510 sequence_values *seqvalues;
2373 AlterSeqStmt *alterSeqStmt = (AlterSeqStmt *) parsetree;2511 AlterSeqStmt *alterSeqStmt = (AlterSeqStmt *) parsetree;
2374 2512 
2375- if (alterSeqStmt->is_autoinc) {2513+ if (alterSeqStmt->forIdentity ||
2514+ alterSeqStmt->forDIdentity ||
2515+ alterSeqStmt->is_autoinc) {
2376 return NULL;2516 return NULL;
2377 }2517 }
2378 2518 
@@ -4056,7 +4196,79 @@ static ObjTree* deparse_AlterRelation(CollectedCommand *cmd, ddl_deparse_context
4056 case AT_ReplaceRelOptions:4196 case AT_ReplaceRelOptions:
4057 /* Subtypes used for internal operations; nothing to do here */4197 /* Subtypes used for internal operations; nothing to do here */
4058 break;4198 break;
4199+ case AT_AddIdentity:
4200+ {
4201+ AttrNumber attnum;
4202+ Oid seqrelid;
4203+ ObjTree *seqdef = NULL;
4204+ ColumnDef *coldef = (ColumnDef *) subcmd->def;
4059 4205 
4206+ tmp_obj = new_objtree_VA("ALTER COLUMN %{column}I", 2,
4207+ "type", ObjTypeString, "add identity",
4208+ "column", ObjTypeString, subcmd->name);
4209+ attnum = get_attnum(RelationGetRelid(rel), subcmd->name);
4210+ seqrelid = getIdentitySequence(RelationGetRelid(rel), attnum, true, coldef->identity == ATTRIBUTE_IDENTITY_D);
4211+ 
4212+ if (OidIsValid(seqrelid)) {
4213+ if (coldef->identity == ATTRIBUTE_IDENTITY_D) {
4214+ seqdef = deparse_D_ColumnIdentity(seqrelid, coldef->identity, false);
4215+ } else {
4216+ seqdef = deparse_ColumnIdentity(seqrelid, coldef->identity, false);
4217+ }
4218+ 
4219+ if (seqdef) {
4220+ append_object_object(tmp_obj, "ADD %{identity_column}s", seqdef);
4221+ }
4222+ }
4223+ 
4224+ subcmds = lappend(subcmds, new_object_object(tmp_obj));
4225+ break;
4226+ }
4227+ case AT_SetIdentity:
4228+ {
4229+ DefElem *defel;
4230+ char identity = '\0';
4231+ ObjTree *seqdef = NULL;
4232+ AttrNumber attnum;
4233+ Oid seqrelid;
4234+ 
4235+ tmp_obj = new_objtree_VA("ALTER COLUMN %{column}I", 2,
4236+ "type", ObjTypeString, "set identity",
4237+ "column", ObjTypeString, subcmd->name);
4238+ ListCell *defcell;
4239+ foreach(defcell, (List *)subcmd->def) {
4240+ defel = (DefElem *)lfirst(defcell);
4241+ if (strcmp(defel->defname, "generated") == 0) {
4242+ identity = (char)defGetInt64(defel);
4243+ break;
4244+ }
4245+ }
4246+ 
4247+ attnum = get_attnum(RelationGetRelid(rel), subcmd->name);
4248+ seqrelid = getIdentitySequence(RelationGetRelid(rel), attnum, true, false);
4249+ 
4250+ if (OidIsValid(seqrelid)) {
4251+ seqdef = deparse_ColumnIdentity(seqrelid, identity, true);
4252+ }
4253+ 
4254+ if (seqdef) {
4255+ append_object_object(tmp_obj, "%{definition}s", seqdef);
4256+ }
4257+ 
4258+ subcmds = lappend(subcmds, new_object_object(tmp_obj));
4259+ break;
4260+ }
4261+ case AT_DropIdentity:
4262+ {
4263+ tmp_obj = new_objtree_VA("ALTER COLUMN %{column}I DROP IDENTITY", 2,
4264+ "type", ObjTypeString, "drop identity",
4265+ "column", ObjTypeString, subcmd->name);
4266+ append_string_object(tmp_obj, "%{if_exists}s",
4267+ "if_exists",
4268+ subcmd->missing_ok ? "IF EXISTS" : "");
4269+ subcmds = lappend(subcmds, new_object_object(tmp_obj));
4270+ break;
4271+ }
4060 case AT_AddColumnToView:4272 case AT_AddColumnToView:
4061 /* CREATE OR REPLACE VIEW -- nothing to do here */4273 /* CREATE OR REPLACE VIEW -- nothing to do here */
4062 break;4274 break;
@@ -4112,7 +4324,7 @@ static ObjTree* deparse_AlterRelation(CollectedCommand *cmd, ddl_deparse_context
4112 "statistics", ObjTypeInteger,4324 "statistics", ObjTypeInteger,
4113 intVal((Value *)subcmd->def));4325 intVal((Value *)subcmd->def));
4114 } else {4326 } else {
4115- tmp_obj = new_objtree_VA("ALTER COLUMN %{column}n SET STATISTICS PERCENT %{statistics}n", 4,4327+ tmp_obj = new_objtree_VA("ALTER COLUMN %{column}n SET STATISTICS PERCENT %{statistics}n", 3,
4116 "type", ObjTypeString, "set statistics",4328 "type", ObjTypeString, "set statistics",
4117 "column", ObjTypeString, subcmd->name,4329 "column", ObjTypeString, subcmd->name,
4118 "statistics", ObjTypeInteger,4330 "statistics", ObjTypeInteger,
@@ -164,13 +164,14 @@ bool defGetBoolean(DefElem* def)
164/*164/*
165* Extract a boolean/int mixed value from a DefElem.(copy from fill_missing_fields)165* Extract a boolean/int mixed value from a DefElem.(copy from fill_missing_fields)
166*/166*/
167-int defGetMixdInt(DefElem *def)167+int defGetMixdBoolean(DefElem *def)
168{168{
169 /*169 /*
170 * If no parameter given, assume "true" is meant.170 * If no parameter given, assume "true" is meant.
171 */171 */
172- if (def->arg == NULL)172+ if (def->arg == NULL) {
173 return 1;173 return 1;
174+ }
174 175 
175 /*176 /*
176 * Allow 0, 1, "true", "false", "on", "off", "one", "multi"177 * Allow 0, 1, "true", "false", "on", "off", "one", "multi"
@@ -194,24 +195,44 @@ int defGetMixdInt(DefElem *def)
194 * The set of strings accepted here should match up with the195 * The set of strings accepted here should match up with the
195 * grammar's opt_boolean production.196 * grammar's opt_boolean production.
196 */197 */
197- if (pg_strcasecmp(sval, "true") == 0)198+ if (pg_strcasecmp(sval, "true") == 0 ||
199+ pg_strcasecmp(sval, "on") == 0 ||
200+ pg_strcasecmp(sval, "one") == 0) {
198 return 1;201 return 1;
199- if (pg_strcasecmp(sval, "false") == 0)202+ } else if (pg_strcasecmp(sval, "false") == 0 ||
203+ pg_strcasecmp(sval, "off") == 0) {
200 return 0;204 return 0;
201- if (pg_strcasecmp(sval, "on") == 0)205+ } else if (pg_strcasecmp(sval, "multi") == 0) {
202- return 1;
203- if (pg_strcasecmp(sval, "off") == 0)
204- return 0;
205- if (pg_strcasecmp(sval, "one") == 0)
206- return 1;
207- if (pg_strcasecmp(sval, "multi") == 0)
208 return -1;206 return -1;
209- } break;207+ }
208+ } break;
210 }209 }
211 ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("%s requires a Boolean value", def->defname)));210 ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("%s requires a Boolean value", def->defname)));
212 return 0; /* keep compiler quiet */211 return 0; /* keep compiler quiet */
213}212}
214 213 
214+/*
215+ * Extract an int32 value from a DefElem.
216+ */
217+int32 defGetInt32(DefElem *def)
218+{
219+ if (def->arg == NULL)
220+ ereport(ERROR,
221+ (errcode(ERRCODE_SYNTAX_ERROR),
222+ errmsg("%s requires an integer value",
223+ def->defname)));
224+ switch (nodeTag(def->arg)) {
225+ case T_Integer:
226+ return (int32) intVal(def->arg);
227+ default:
228+ ereport(ERROR,
229+ (errcode(ERRCODE_SYNTAX_ERROR),
230+ errmsg("%s requires an integer value",
231+ def->defname)));
232+ }
233+ return 0; /* keep compiler quiet */
234+}
235+ 
215/*236/*
216 * Extract an int64 value from a DefElem.237 * Extract an int64 value from a DefElem.
217 */238 */
@@ -1318,7 +1318,7 @@ ColumnDef* makeColumnDef(const char* colname, char* coltype)
1318 ColumnDef* col = makeNode(ColumnDef);1318 ColumnDef* col = makeNode(ColumnDef);
1319 col->colname = pstrdup(colname);1319 col->colname = pstrdup(colname);
1320 col->typname = SystemTypeName(coltype);1320 col->typname = SystemTypeName(coltype);
1321- col->kvtype = 0;1321+ col->kvtype = ATT_KV_UNDEFINED;
1322 col->generatedCol = '\0';1322 col->generatedCol = '\0';
1323 col->inhcount = 0;1323 col->inhcount = 0;
1324 col->is_local = true;1324 col->is_local = true;
@@ -3999,10 +3999,8 @@ Oid GetFunctionNodeGroup(AlterFunctionStmt* stmt)
3999 3999 
4000static void checkAllowAlter(HeapTuple tup) {4000static void checkAllowAlter(HeapTuple tup) {
4001 Datum packageOidDatum;4001 Datum packageOidDatum;
4002- Datum prosecdef_datum;
4003 Oid packageOid = InvalidOid;4002 Oid packageOid = InvalidOid;
4004 bool isnull = false;4003 bool isnull = false;
4005- bool prosecdef = false;
4006 packageOidDatum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_packageid, &isnull);4004 packageOidDatum = SysCacheGetAttr(PROCOID, tup, Anum_pg_proc_packageid, &isnull);
4007 if (!isnull) {4005 if (!isnull) {
4008 packageOid = DatumGetObjectId(packageOidDatum);4006 packageOid = DatumGetObjectId(packageOidDatum);
@@ -77,14 +77,14 @@ static ObjectAddress AlterSequence(const AlterSeqStmt* stmt);
77#ifdef PGXC77#ifdef PGXC
78template<typename T_Form, typename T_Int, bool large>78template<typename T_Form, typename T_Int, bool large>
79static void init_params(List* options, bool isInit, bool isUseLocalSeq, void* newm_p, List** owned_by,79static void init_params(List* options, bool isInit, bool isUseLocalSeq, void* newm_p, List** owned_by,
80- bool* is_restart, bool* needSeqRewrite, bool isIdentity);80+ bool* is_restart, bool* needSeqRewrite, bool isIdentity, bool isDIdentity);
81#else81#else
82static void init_params(List* options, bool isInit, bool isUseLocalSeq, void* newm_p, List** owned_by,82static void init_params(List* options, bool isInit, bool isUseLocalSeq, void* newm_p, List** owned_by,
83- bool* needSeqRewrite, bool isIdentity);83+ bool* needSeqRewrite, bool isIdentity, bool isDIdentity);
84#endif84#endif
85template<typename T_Form, typename T_Int, bool large>85template<typename T_Form, typename T_Int, bool large>
86static void do_setval(Oid relid, int128 next, bool iscalled, bool skip_perm_check = false);86static void do_setval(Oid relid, int128 next, bool iscalled, bool skip_perm_check = false);
87-static void process_owned_by(const Relation seqrel, List* owned_by);87+static void process_owned_by(const Relation seqrel, List* owned_by, bool forIdentity);
88template<typename T_Form>88template<typename T_Form>
89static GTM_UUID get_uuid_from_tuple(const void* seq_p, const Relation rel, const HeapTuple seqtuple);89static GTM_UUID get_uuid_from_tuple(const void* seq_p, const Relation rel, const HeapTuple seqtuple);
90extern Oid searchSeqidFromExpr(Node* cooked_default);90extern Oid searchSeqidFromExpr(Node* cooked_default);
@@ -3346,7 +3346,7 @@ static List* MergeObjectTypeAttributes(List* schema, Oid supertypeid, int32 typm
3346 def->is_not_null = attribute->attnotnull;3346 def->is_not_null = attribute->attnotnull;
3347 def->is_from_type = false;3347 def->is_from_type = false;
3348 def->storage = attribute->attstorage;3348 def->storage = attribute->attstorage;
3349- def->kvtype = attribute->attkvtype;3349+ def->kvtype = GET_ATTR_KVTYPE(attribute);
3350 def->cmprs_mode = attribute->attcmprmode;3350 def->cmprs_mode = attribute->attcmprmode;
3351 def->raw_default = NULL;3351 def->raw_default = NULL;
3352 def->generatedCol = '\0';3352 def->generatedCol = '\0';
@@ -5731,6 +5731,9 @@ static bool cost_qual_eval_walker(Node* node, cost_qual_eval_context* context)
5731 5731 
5732 context->total.per_tuple += get_func_cost(get_opcode(opid)) * u_sess->attr.attr_sql.cpu_operator_cost;5732 context->total.per_tuple += get_func_cost(get_opcode(opid)) * u_sess->attr.attr_sql.cpu_operator_cost;
5733 }5733 }
5734+ } else if (IsA(node, NextValueExpr)) {
5735+ /* Treat all these as having cost 1 */
5736+ context->total.per_tuple += u_sess->attr.attr_sql.cpu_operator_cost;
5734 } else if (IsA(node, CurrentOfExpr)) {5737 } else if (IsA(node, CurrentOfExpr)) {
5735 /* Report high cost to prevent selection of anything but TID scan */5738 /* Report high cost to prevent selection of anything but TID scan */
5736 context->total.startup += g_instance.cost_cxt.disable_cost;5739 context->total.startup += g_instance.cost_cxt.disable_cost;
@@ -1144,6 +1144,9 @@ static bool contain_specified_functions_walker(Node* node, check_function_contex
1144 if (func_meet_check_conditon(expr->opfuncid, context))1144 if (func_meet_check_conditon(expr->opfuncid, context))
1145 return true;1145 return true;
1146 /* else fall through to check args */1146 /* else fall through to check args */
1147+ } else if (IsA(node, NextValueExpr)) {
1148+ /* NextValueExpr is mutable and volatile */
1149+ return true;
1147 } else if (IsA(node, ScalarArrayOpExpr)) {1150 } else if (IsA(node, ScalarArrayOpExpr)) {
1148 ScalarArrayOpExpr* expr = (ScalarArrayOpExpr*)node;1151 ScalarArrayOpExpr* expr = (ScalarArrayOpExpr*)node;
1149 1152 
@@ -1400,6 +1403,7 @@ static bool contain_leaky_functions_walker(Node* node, void* context)
1400 case T_RowExpr:1403 case T_RowExpr:
1401 case T_NullTest:1404 case T_NullTest:
1402 case T_BooleanTest:1405 case T_BooleanTest:
1406+ case T_NextValueExpr:
1403 case T_List:1407 case T_List:
1404 case T_HashFilter:1408 case T_HashFilter:
1405 case T_UserVar:1409 case T_UserVar:
@@ -965,9 +965,11 @@ static List* ts_get_taglist(Oid relid)
965 List* tag_name_list = NIL;965 List* tag_name_list = NIL;
966 bool valid_ts_table = false;966 bool valid_ts_table = false;
967 char* str = NULL;967 char* str = NULL;
968+ int kvtype = ATT_KV_UNDEFINED;
968 969 
969 for (int i = 0; i < tup_desc->natts; i++) {970 for (int i = 0; i < tup_desc->natts; i++) {
970- if (attr[i].attkvtype == ATT_KV_TAG && IsTypeDistributable(attr[i].atttypid)) {971+ kvtype = GET_ATTR_KVTYPE(&attr[i]);
972+ if (kvtype == ATT_KV_TAG && IsTypeDistributable(attr[i].atttypid)) {
971 str = pstrdup(NameStr(attr[i].attname));973 str = pstrdup(NameStr(attr[i].attname));
972 if (str != NULL) {974 if (str != NULL) {
973 tag_name_list = lappend(tag_name_list, makeString(str));975 tag_name_list = lappend(tag_name_list, makeString(str));
@@ -976,7 +978,7 @@ static List* ts_get_taglist(Oid relid)
976 errmsg("Timeseries relation %u cloud not find tag column %d", relid, i)));978 errmsg("Timeseries relation %u cloud not find tag column %d", relid, i)));
977 }979 }
978 }980 }
979- if (attr[i].attkvtype == ATT_KV_HIDE) {981+ if (kvtype == ATT_KV_HIDE) {
980 valid_ts_table = true;982 valid_ts_table = true;
981 }983 }
982 }984 }
@@ -766,7 +766,8 @@ static bool DropObjectsInSameNodeGroup(DropStmt* stmt)
766 } else if (OBJECT_IS_SEQUENCE(object_type)) {766 } else if (OBJECT_IS_SEQUENCE(object_type)) {
767 Oid tableId = InvalidOid;767 Oid tableId = InvalidOid;
768 int32 colId;768 int32 colId;
769- if (!sequenceIsOwned(address.objectId, &tableId, &colId))769+ if (!(sequenceIsOwned(address.objectId, DEPENDENCY_AUTO, &tableId, &colId) ||
770+ sequenceIsOwned(address.objectId, DEPENDENCY_INTERNAL, &tableId, &colId)))
770 goid = ins_group_oid;771 goid = ins_group_oid;
771 else772 else
772 goid = ng_get_baserel_groupoid(tableId, RELKIND_RELATION);773 goid = ng_get_baserel_groupoid(tableId, RELKIND_RELATION);
@@ -972,20 +973,21 @@ static ExecNodes* GetOwnedByNodes(Node* seq_stmt)
972static ExecNodes* GetSequenceNodes(RangeVar* sequence, bool missing_ok)973static ExecNodes* GetSequenceNodes(RangeVar* sequence, bool missing_ok)
973{974{
974 Oid goid;975 Oid goid;
975- Oid seq_id;976+ Oid seqId;
976- Oid table_id = InvalidOid;977+ Oid tableId = InvalidOid;
977- int32 col_id = 0;978+ int32 colId = 0;
978 979 
979- seq_id = RangeVarGetRelid(sequence, NoLock, missing_ok);980+ seqId = RangeVarGetRelid(sequence, NoLock, missing_ok);
980 981 
981- if (!OidIsValid(seq_id))982+ if (!OidIsValid(seqId))
982 return NULL;983 return NULL;
983 984 
984- if (!sequenceIsOwned(seq_id, &table_id, &col_id))985+ if (!(sequenceIsOwned(seqId, DEPENDENCY_AUTO, &tableId, &colId) ||
986+ sequenceIsOwned(seqId, DEPENDENCY_INTERNAL, &tableId, &colId))
985 return NULL;987 return NULL;
986 988 
987 /* Fetching group_oid for given relation */989 /* Fetching group_oid for given relation */
988- goid = get_pgxc_class_groupoid(table_id);990+ goid = get_pgxc_class_groupoid(tableId);
989 if (!OidIsValid(goid))991 if (!OidIsValid(goid))
990 return NULL;992 return NULL;
991 993 
@@ -1542,7 +1544,7 @@ static char* get_drop_seq_query_string(AlterTableStmt* stmt, Oid rel_id)
1542 1544 
1543 if (attr_list != NIL) {1545 if (attr_list != NIL) {
1544 StringInfoData str;1546 StringInfoData str;
1545- seq_list = getOwnedSequences(rel_id, attr_list);1547+ seq_list = getOwnedSequencesOfAttrList(rel_id, attr_list);
1546 list_free(attr_list);1548 list_free(attr_list);
1547 1549 
1548 if (seq_list != NULL) {1550 if (seq_list != NULL) {
@@ -5402,7 +5404,7 @@ ProcessUtilitySlow(Node *parse_tree,
5402 atstmt->relation->relname);5404 atstmt->relation->relname);
5403 5405 
5404 if (OidIsValid(rel_id)) {5406 if (OidIsValid(rel_id)) {
5405- TrForbidAccessRbObject(RelationRelationId, rel_id, atstmt->relation->relname);5407+ TrForbidAccessRbObject(RelationRelationId, rel_id, atstmt->relation->relname);
5406 /* Run parse analysis ... */5408 /* Run parse analysis ... */
5407 stmts = transformAlterTableStmt(rel_id, atstmt, query_string);5409 stmts = transformAlterTableStmt(rel_id, atstmt, query_string);
5408 /* ... ensure we have an event trigger context ... */5410 /* ... ensure we have an event trigger context ... */
@@ -5421,13 +5423,12 @@ ProcessUtilitySlow(Node *parse_tree,
5421 add_remote_query_4_alter_stmt(is_first_node, atstmt, query_string, &stmts, &drop_seq_string, &exec_nodes);5423 add_remote_query_4_alter_stmt(is_first_node, atstmt, query_string, &stmts, &drop_seq_string, &exec_nodes);
5422 }5424 }
5423#endif5425#endif
5424- 
5425 /* ... and do it */5426 /* ... and do it */
5426 foreach (l, stmts) {5427 foreach (l, stmts) {
5427 Node* stmt = (Node*)lfirst(l);5428 Node* stmt = (Node*)lfirst(l);
5428 5429 
5429 if (IsA(stmt, AlterTableStmt)) {5430 if (IsA(stmt, AlterTableStmt)) {
5430- /* Do the table alteration proper */5431+ /* Do the table alteration proper */
5431 AlterTable(rel_id, lockmode, (AlterTableStmt*)stmt);5432 AlterTable(rel_id, lockmode, (AlterTableStmt*)stmt);
5432 } else {5433 } else {
5433 /*5434 /*
@@ -968,8 +968,19 @@ ExecInitExprRec(Expr *node, ExprState *state,
968 scratch.d.scalararrayop.fn_addr = finfo->fn_addr;968 scratch.d.scalararrayop.fn_addr = finfo->fn_addr;
969 ExprEvalPushStep(state, &scratch);969 ExprEvalPushStep(state, &scratch);
970 }970 }
971- break;971+ break;
972- }972+ }
973+ case T_NextValueExpr:
974+ {
975+ NextValueExpr *nve = (NextValueExpr *) node;
976+ 
977+ scratch.opcode = EEOP_NEXTVALUEEXPR;
978+ scratch.d.nextvalueexpr.seqid = nve->seqid;
979+ scratch.d.nextvalueexpr.seqtypid = nve->typeId;
980+ 
981+ ExprEvalPushStep(state, &scratch);
982+ break;
983+ }
973 case T_BoolExpr:984 case T_BoolExpr:
974 {985 {
975 BoolExpr *boolexpr = (BoolExpr *) node;986 BoolExpr *boolexpr = (BoolExpr *) node;
@@ -1189,6 +1200,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
1189 ExprEvalPushStep(state, &scratch);1200 ExprEvalPushStep(state, &scratch);
1190 break;1201 break;
1191 }1202 }
1203+ 
1192 case T_RelabelType:1204 case T_RelabelType:
1193 {1205 {
1194 /* relabel doesn't need to do anything at runtime */1206 /* relabel doesn't need to do anything at runtime */
@@ -74,6 +74,7 @@
74#include "utils/typcache.h"74#include "utils/typcache.h"
75#include "utils/xml.h"75#include "utils/xml.h"
76#include "utils/elog.h"76#include "utils/elog.h"
77+#include "utils/numeric.h"
77#include "utils/expandeddatum.h"78#include "utils/expandeddatum.h"
78#include "access/tableam.h"79#include "access/tableam.h"
79#include "access/tupconvert.h"80#include "access/tupconvert.h"
@@ -643,6 +644,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull, ExprDoneCo
643 &&CASE_EEOP_CONVERT_ROWTYPE,644 &&CASE_EEOP_CONVERT_ROWTYPE,
644 &&CASE_EEOP_SCALARARRAYOP,645 &&CASE_EEOP_SCALARARRAYOP,
645 &&CASE_EEOP_HASHED_SCALARARRAYOP,646 &&CASE_EEOP_HASHED_SCALARARRAYOP,
647+ &&CASE_EEOP_NEXTVALUEEXPR,
646 &&CASE_EEOP_XMLEXPR,648 &&CASE_EEOP_XMLEXPR,
647 &&CASE_EEOP_AGGREF,649 &&CASE_EEOP_AGGREF,
648 &&CASE_EEOP_GROUPING_FUNC,650 &&CASE_EEOP_GROUPING_FUNC,
@@ -1735,6 +1737,17 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull, ExprDoneCo
1735 /* too complex for an inline implementation */1737 /* too complex for an inline implementation */
1736 ExecEvalHashedScalarArrayOp(state, op, econtext);1738 ExecEvalHashedScalarArrayOp(state, op, econtext);
1737 1739 
1740+ EEO_NEXT();
1741+ }
1742+ 
1743+ EEO_CASE(EEOP_NEXTVALUEEXPR)
1744+ {
1745+ /*
1746+ * Doesn't seem worthwhile to have an inline implementation
1747+ * efficiency-wise.
1748+ */
1749+ ExecEvalNextValueExpr(state, op);
1750+ 
1738 EEO_NEXT();1751 EEO_NEXT();
1739 }1752 }
1740 1753 
@@ -2729,21 +2742,65 @@ ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
2729 * If we get here, we suppose we must be dealing with CURRENT OF on a foreign2742 * If we get here, we suppose we must be dealing with CURRENT OF on a foreign
2730 * table whose FDW doesn't handle it, and complain accordingly.2743 * table whose FDW doesn't handle it, and complain accordingly.
2731 */2744 */
2732-void2745+void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op)
2733-ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op)
2734{2746{
2735 ereport(ERROR,2747 ereport(ERROR,
2736 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmodule(MOD_EXECUTOR), errmsg("CURRENT OF cannot be executed")));2748 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmodule(MOD_EXECUTOR), errmsg("CURRENT OF cannot be executed")));
2737 return; /* keep compiler quiet */2749 return; /* keep compiler quiet */
2738}2750}
2739 2751 
2752+/*
2753+ * Evaluate NextValueExpr.
2754+ */
2755+void ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op)
2756+{
2757+ int128 newval;
2758+ /*
2759+ * In D mode, the sequence created by
2760+ * the identity column can be independently deleted.
2761+ */
2762+ if (!OidIsValid(op->d.nextvalueexpr.seqid)) {
2763+ ereport(ERROR,
2764+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2765+ errmodule(MOD_EXECUTOR),
2766+ errmsg("no owned sequence found")));
2767+ }
2768+ 
2769+ newval = nextval_internal(op->d.nextvalueexpr.seqid, false);
2770+ switch (op->d.nextvalueexpr.seqtypid) {
2771+ case INT1OID:
2772+ *op->resvalue = Int8GetDatum((int8) newval);
2773+ break;
2774+ case INT2OID:
2775+ *op->resvalue = Int16GetDatum((int16) newval);
2776+ break;
2777+ case INT4OID:
2778+ *op->resvalue = Int32GetDatum((int32) newval);
2779+ break;
2780+ case INT8OID:
2781+ *op->resvalue = Int64GetDatum((int64) newval);
2782+ break;
2783+ case INT16OID:
2784+ *op->resvalue = Int128GetDatum((int128) newval);
2785+ case NUMERICOID:
2786+ *op->resvalue = NumericGetDatum(int128_to_numeric((int128) newval));
2787+ break;
2788+ default:
2789+ ereport(ERROR,
2790+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2791+ errmodule(MOD_EXECUTOR),
2792+ errmsg("unsupported sequence type %u", op->d.nextvalueexpr.seqtypid)));
2793+ }
2794+ *op->resnull = false;
2795+}
2796+ 
2740/*2797/*
2741 * Evaluate NullTest / IS NULL for rows.2798 * Evaluate NullTest / IS NULL for rows.
2742 */2799 */
2743void2800void
2744ExecEvalRowNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext)2801ExecEvalRowNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
2745{2802{
2746- ExecEvalRowNullInt(state, op, econtext, true);2803+ ExecEvalRowNullInt(state, op, econtext, true);
2747}2804}
2748 2805 
2749/*2806/*
@@ -2752,12 +2809,12 @@ ExecEvalRowNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
2752void2809void
2753ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext)2810ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
2754{2811{
2755- ExecEvalRowNullInt(state, op, econtext, false);2812+ ExecEvalRowNullInt(state, op, econtext, false);
2756}2813}
2757 2814 
2758void ExecEvalNan(ExprState *state, ExprEvalStep *op, ExprContext *econtext)2815void ExecEvalNan(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
2759{2816{
2760- ExecEvalNanInt(state, op, econtext, true);2817+ ExecEvalNanInt(state, op, econtext, true);
2761}2818}
2762 2819 
2763void ExecEvalNotNan(ExprState *state, ExprEvalStep *op, ExprContext *econtext)2820void ExecEvalNotNan(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
@@ -42,6 +42,7 @@
42#include "access/tableam.h"42#include "access/tableam.h"
43#include "catalog/pg_type.h"43#include "catalog/pg_type.h"
44#include "commands/typecmds.h"44#include "commands/typecmds.h"
45+#include "commands/sequence.h"
45#include "executor/exec/execdebug.h"46#include "executor/exec/execdebug.h"
46#include "executor/node/nodeSubplan.h"47#include "executor/node/nodeSubplan.h"
47#include "executor/node/nodeAgg.h"48#include "executor/node/nodeAgg.h"
@@ -58,6 +59,7 @@
58#include "utils/builtins.h"59#include "utils/builtins.h"
59#include "utils/lsyscache.h"60#include "utils/lsyscache.h"
60#include "utils/memutils.h"61#include "utils/memutils.h"
62+#include "utils/numeric.h"
61#include "utils/typcache.h"63#include "utils/typcache.h"
62#include "utils/xml.h"64#include "utils/xml.h"
63#include "access/hash.h"65#include "access/hash.h"
@@ -149,6 +151,7 @@ static Datum ExecEvalRelabelType(
149static Datum ExecEvalCoerceViaIO(CoerceViaIOState* iostate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);151static Datum ExecEvalCoerceViaIO(CoerceViaIOState* iostate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);
150static Datum ExecEvalArrayCoerceExpr(152static Datum ExecEvalArrayCoerceExpr(
151 ArrayCoerceExprState* astate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);153 ArrayCoerceExprState* astate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);
154+static Datum ExecEvalNextValueExpr(ExprState* exprstate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);
152static Datum ExecEvalCurrentOfExpr(ExprState* exprstate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);155static Datum ExecEvalCurrentOfExpr(ExprState* exprstate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);
153static Datum ExecEvalGroupingFuncExpr(156static Datum ExecEvalGroupingFuncExpr(
154 GroupingFuncExprState* gstate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);157 GroupingFuncExprState* gstate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);
@@ -5852,7 +5855,7 @@ static Datum ExecEvalArrayCoerceExpr(
5852}5855}
5853 5856 
5854/* ----------------------------------------------------------------5857/* ----------------------------------------------------------------
5855-* ExecEvalCurrentOfExpr5858+* ExecEvalCurrentOfExpr
5856*5859*
5857* The planner must convert CURRENT OF into a TidScan qualification.5860* The planner must convert CURRENT OF into a TidScan qualification.
5858* So, we have to be able to do ExecInitExpr on a CurrentOfExpr,5861* So, we have to be able to do ExecInitExpr on a CurrentOfExpr,
@@ -5866,6 +5869,63 @@ static Datum ExecEvalCurrentOfExpr(ExprState* exprstate, ExprContext* econtext,
5866 return 0; /* keep compiler quiet */5869 return 0; /* keep compiler quiet */
5867}5870}
5868 5871 
5872+/* ----------------------------------------------------------------
5873+* ExecEvalNextValueExpr
5874+* Evaluate NextValueExpr.
5875+* ----------------------------------------------------------------
5876+*/
5877+static Datum ExecEvalNextValueExpr(ExprState* exprstate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone)
5878+{
5879+ int128 newval;
5880+ Datum result = 0;
5881+ NextValueExpr* nve = (NextValueExpr*)exprstate->expr;
5882+ 
5883+ /*
5884+ * In D mode, the sequence created by
5885+ * the identity column can be independently deleted.
5886+ */
5887+ if (!OidIsValid(nve->seqid)) {
5888+ ereport(ERROR,
5889+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5890+ errmodule(MOD_EXECUTOR),
5891+ errmsg("no owned sequence found")));
5892+ }
5893+ 
5894+ newval = nextval_internal(nve->seqid, false);
5895+ switch (nve->typeId) {
5896+ case INT1OID:
5897+ result = Int8GetDatum((int8) newval);
5898+ break;
5899+ case INT2OID:
5900+ result = Int16GetDatum((int16) newval);
5901+ break;
5902+ case INT4OID:
5903+ result = Int32GetDatum((int32) newval);
5904+ break;
5905+ case INT8OID:
5906+ result = Int64GetDatum((int64) newval);
5907+ break;
5908+ case INT16OID:
5909+ result = Int128GetDatum((int128) newval);
5910+ break;
5911+ case NUMERICOID:
5912+ result = NumericGetDatum(int128_to_numeric((int128) newval));
5913+ break;
5914+ default:
5915+ ereport(ERROR,
5916+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5917+ errmodule(MOD_EXECUTOR),
5918+ errmsg("unsupported sequence type %u", nve->typeId)));
5919+ }
5920+ 
5921+ *isNull = false;
5922+ if (isDone) {
5923+ *isDone = ExprSingleResult;
5924+ }
5925+ return result;
5926+}
5927+ 
5928+ 
5869/* ----------------------------------------------------------------5929/* ----------------------------------------------------------------
5870 * ExecEvalPrefixText5930 * ExecEvalPrefixText
5871 * ----------------------------------------------------------------5931 * ----------------------------------------------------------------
@@ -6194,7 +6254,6 @@ ExprState* ExecInitExprByRecursionInternal(Expr* node, PlanState* parent)
6194 fstate->xprstate.is_flt_frame = false;6254 fstate->xprstate.is_flt_frame = false;
6195 fstate->xprstate.evalfunc = (ExprStateEvalFunc)ExecEvalFunc;6255 fstate->xprstate.evalfunc = (ExprStateEvalFunc)ExecEvalFunc;
6196 6256 
6197- 
6198 fstate->args = (List*)ExecInitExprByRecursion((Expr*)funcexpr->args, parent);6257 fstate->args = (List*)ExecInitExprByRecursion((Expr*)funcexpr->args, parent);
6199 fstate->func.fn_oid = InvalidOid; /* not initialized */6258 fstate->func.fn_oid = InvalidOid; /* not initialized */
6200 fstate->is_plpgsql_func_with_outparam = is_function_with_plpgsql_language_and_outparam(funcexpr->funcid);6259 fstate->is_plpgsql_func_with_outparam = is_function_with_plpgsql_language_and_outparam(funcexpr->funcid);
@@ -6245,6 +6304,11 @@ ExprState* ExecInitExprByRecursionInternal(Expr* node, PlanState* parent)
6245 sstate->element_type = InvalidOid; /* ditto */6304 sstate->element_type = InvalidOid; /* ditto */
6246 state = (ExprState*)sstate;6305 state = (ExprState*)sstate;
6247 } break;6306 } break;
6307+ case T_NextValueExpr: {
6308+ state = (ExprState*)makeNode(ExprState);
6309+ state->is_flt_frame = false;
6310+ state->evalfunc = ExecEvalNextValueExpr;
6311+ } break;
6248 case T_BoolExpr: {6312 case T_BoolExpr: {
6249 BoolExpr* boolexpr = (BoolExpr*)node;6313 BoolExpr* boolexpr = (BoolExpr*)node;
6250 BoolExprState* bstate = makeNode(BoolExprState);6314 BoolExprState* bstate = makeNode(BoolExprState);
@@ -6777,7 +6841,6 @@ ExprState* ExecInitExprByRecursionInternal(Expr* node, PlanState* parent)
6777 state = (ExprState*)dstate;6841 state = (ExprState*)dstate;
6778 } break;6842 } break;
6779 6843 
6780-
6781 default:6844 default:
6782 ereport(ERROR,6845 ereport(ERROR,
6783 (errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE),6846 (errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE),
@@ -1797,7 +1797,7 @@ Tuple ExecAutoIncrement(Relation rel, EState* estate, TupleTableSlot* slot, Tupl
1797 autoinc = estate->next_autoinc;1797 autoinc = estate->next_autoinc;
1798 estate->next_autoinc = 0;1798 estate->next_autoinc = 0;
1799 } else {1799 } else {
1800- autoinc = nextval_internal(cons_autoinc->seqoid);1800+ autoinc = nextval_internal(cons_autoinc->seqoid, true);
1801 }1801 }
1802 }1802 }
1803 1803 
@@ -3402,42 +3402,14 @@ static void checkSequenceForReplace(Relation rel)
3402{3402{
3403 Form_pg_attribute att_tup;3403 Form_pg_attribute att_tup;
3404 Oid seqOid = InvalidOid;3404 Oid seqOid = InvalidOid;
3405- static int tableNameSize = NAMEDATALEN * 2 + 2;
3406- char tableName[tableNameSize] = {0};
3407- 
3408- for (int attrno = 1; attrno <= rel->rd_att->natts; ++attrno) {
3409- att_tup = &rel->rd_att->attrs[attrno-1];
3410- errno_t rc;
3411- char *nspname = get_namespace_name(rel->rd_rel->relnamespace);
3412- text *tbname;
3413- text *attname;
3414 3405 
3406+ for (int attrnum = 1; attrnum <= rel->rd_att->natts; ++attrnum) {
3407+ att_tup = &rel->rd_att->attrs[attrnum-1];
3415 if (att_tup->attisdropped) {3408 if (att_tup->attisdropped) {
3416 continue;3409 continue;
3417 }3410 }
3418 3411 
3419- rc = memset_s(tableName, tableNameSize, 0, tableNameSize);3412+ seqOid = getOwnedSequence(RelationGetRelid(rel), attrnum, NULL);
3420- securec_check(rc, "\0", "\0");
3421- 
3422- if (nspname != NULL) {
3423- const char *sym = ".";
3424- int nspnameLen = strlen(nspname);
3425- int symLen = strlen(sym);
3426- int tbnameLen = strlen(rel->rd_rel->relname.data);
3427- rc = memcpy_s(&tableName[0], tableNameSize, nspname, nspnameLen);
3428- securec_check(rc, "\0", "\0");
3429- rc = memcpy_s(&tableName[nspnameLen], tableNameSize, sym, symLen);
3430- securec_check(rc, "\0", "\0");
3431- rc = memcpy_s(&tableName[nspnameLen + symLen], tableNameSize, rel->rd_rel->relname.data, tbnameLen);
3432- securec_check(rc, "\0", "\0");
3433- tableName[nspnameLen + symLen + tbnameLen] = 0;
3434- tbname = cstring_to_text(&tableName[0]);
3435- } else {
3436- tbname = cstring_to_text(rel->rd_rel->relname.data);
3437- }
3438- 
3439- attname = cstring_to_text(att_tup->attname.data);
3440- seqOid = pg_get_serial_sequence_oid(tbname, attname);
3441 if (OidIsValid(seqOid) && !CheckSeqOwnedByAutoInc(seqOid)) {3413 if (OidIsValid(seqOid) && !CheckSeqOwnedByAutoInc(seqOid)) {
3442 elog(ERROR, "REPLACE can not work on sequence!");3414 elog(ERROR, "REPLACE can not work on sequence!");
3443 }3415 }
@@ -776,12 +776,6 @@ bool ExecStartWithRowLevelQual(RecursiveUnionState* node, TupleTableSlot* dstSlo
776 return true;776 return true;
777}777}
778 778 
779-static void DiscardSWLastTuple(StartWithOpState *node)
780-{
781- node->sw_rownum--;
782- node->sw_numtuples--;
783-}
784- 
785static SWDfsOpState* InitSWDfsOpState()779static SWDfsOpState* InitSWDfsOpState()
786{780{
787 SWDfsOpState* state = (SWDfsOpState*)palloc0(sizeof(SWDfsOpState));781 SWDfsOpState* state = (SWDfsOpState*)palloc0(sizeof(SWDfsOpState));
@@ -333,7 +333,7 @@ static void opt_orderby(TsStoreScan* node, TsStoreScanState* scanstate)
333 att_target = (TargetEntry*)list_nth(target_list, scanstate->sort_by_time_colidx - 1);333 att_target = (TargetEntry*)list_nth(target_list, scanstate->sort_by_time_colidx - 1);
334 334 
335 for(int i = 0; i < tuple_desc->natts; i++) {335 for(int i = 0; i < tuple_desc->natts; i++) {
336- if (IsA(att_target->expr, Var) && tuple_desc->attrs[i].attkvtype == ATT_KV_TIMETAG &&336+ if (IsA(att_target->expr, Var) && GET_ATTR_KVTYPE(&tuple_desc->attrs[i]) == ATT_KV_TIMETAG &&
337 ((Var*)(att_target->expr))->varattno == tuple_desc->attrs[i].attnum) {337 ((Var*)(att_target->expr))->varattno == tuple_desc->attrs[i].attnum) {
338 scanstate->early_stop = true;338 scanstate->early_stop = true;
339 }339 }
@@ -290,6 +290,23 @@ TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc)
290 return desc;290 return desc;
291}291}
292 292 
293+Form_pg_attribute_extra CreatePGAttributeExtra(TupleDesc tupdesc)
294+{
295+ int i;
296+ char* droppedName = NULL;
297+ Form_pg_attribute_extra extra = (Form_pg_attribute_extra)palloc0(sizeof(FormData_pg_attribute_extra)
298+ * tupdesc->natts);
299+ for (i = 0; i < tupdesc->natts; ++i) {
300+ extra[i].attkvtype = GET_ATTR_KVTYPE(&tupdesc->attrs[i]);
301+ extra[i].attidentity = GET_ATTR_IDENTITY(&tupdesc->attrs[i]);
302+ droppedName = GET_ATTR_DROPPEDNAME(&tupdesc->attrs[i]);
303+ if (droppedName) {
304+ namestrcpy(&extra[i].attdroppedname, droppedName);
305+ }
306+ }
307+ return extra;
308+}
309+ 
293char GetGeneratedCol(TupleDesc tupdesc, int atti)310char GetGeneratedCol(TupleDesc tupdesc, int atti)
294{311{
295 if (!tupdesc->constr)312 if (!tupdesc->constr)
@@ -589,9 +606,6 @@ bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
589 if (attr1->attstorage != attr2->attstorage && !cl_skip) {606 if (attr1->attstorage != attr2->attstorage && !cl_skip) {
590 return false;607 return false;
591 }608 }
592- if (attr1->attkvtype != attr2->attkvtype) {
593- return false;
594- }
595 if (attr1->attcmprmode != attr2->attcmprmode) {609 if (attr1->attcmprmode != attr2->attcmprmode) {
596 return false;610 return false;
597 }611 }
@@ -775,9 +789,6 @@ bool opFusionReuseEqualTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
775 if (attr1->attstorage != attr2->attstorage && !cl_skip) {789 if (attr1->attstorage != attr2->attstorage && !cl_skip) {
776 return false;790 return false;
777 }791 }
778- if (attr1->attkvtype != attr2->attkvtype) {
779- return false;
780- }
781 if (attr1->attcmprmode != attr2->attcmprmode) {792 if (attr1->attcmprmode != attr2->attcmprmode) {
782 return false;793 return false;
783 }794 }
@@ -843,8 +854,6 @@ static bool ComparePgAttribute(Form_pg_attribute attr1, Form_pg_attribute attr2)
843 return false;854 return false;
844 if (attr1->attstorage != attr2->attstorage)855 if (attr1->attstorage != attr2->attstorage)
845 return false;856 return false;
846- if (attr1->attkvtype != attr2->attkvtype)
847- return false;
848 if (attr1->attcmprmode != attr2->attcmprmode)857 if (attr1->attcmprmode != attr2->attcmprmode)
849 return false;858 return false;
850 if (attr1->attalign != attr2->attalign)859 if (attr1->attalign != attr2->attalign)
@@ -862,6 +871,13 @@ static bool ComparePgAttribute(Form_pg_attribute attr1, Form_pg_attribute attr2)
862 return false;871 return false;
863 if (attr1->attcollation != attr2->attcollation)872 if (attr1->attcollation != attr2->attcollation)
864 return false;873 return false;
874+ 
875+ if (GET_ATTR_KVTYPE(attr1) != GET_ATTR_KVTYPE(attr2)) {
876+ return false;
877+ }
878+ if (GET_ATTR_IDENTITY(attr1) != GET_ATTR_IDENTITY(attr2)) {
879+ return false;
880+ }
865 /* attacl, attoptions and attfdwoptions are not even present... */881 /* attacl, attoptions and attfdwoptions are not even present... */
866 882 
867 return true;883 return true;
@@ -956,12 +972,13 @@ void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *
956 att->attisdropped = false;972 att->attisdropped = false;
957 att->attislocal = true;973 att->attislocal = true;
958 att->attinhcount = 0;974 att->attinhcount = 0;
959- att->attkvtype = ATT_KV_UNDEFINED; /* not specified */
960 att->attcmprmode = ATT_CMPR_UNDEFINED; /* not specified */975 att->attcmprmode = ATT_CMPR_UNDEFINED; /* not specified */
976+ 
961 /* attacl, attoptions and attfdwoptions are not present in tupledescs */977 /* attacl, attoptions and attfdwoptions are not present in tupledescs */
962 tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(oidtypeid));978 tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(oidtypeid));
963- if (!HeapTupleIsValid(tuple))979+ if (!HeapTupleIsValid(tuple)) {
964 ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("cache lookup failed for type %u", oidtypeid)));980 ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("cache lookup failed for type %u", oidtypeid)));
981+ }
965 typeForm = (Form_pg_type)GETSTRUCT(tuple);982 typeForm = (Form_pg_type)GETSTRUCT(tuple);
966 983 
967 att->atttypid = oidtypeid;984 att->atttypid = oidtypeid;
@@ -1032,7 +1049,9 @@ void VerifyAttrCompressMode(int8 mode, int attlen, const char *attname)
1032 errmsg("column \"%s\" cannot be applied %s compress mode", attname, errinfo)));1049 errmsg("column \"%s\" cannot be applied %s compress mode", attname, errinfo)));
1033}1050}
1034 1051 
1035-void copyDroppedAttribute(Form_pg_attribute target, Form_pg_attribute source)1052+void copyDroppedAttribute(Form_pg_attribute target, Form_pg_attribute source,
1053+ Form_pg_attribute_extra targetExtra,
1054+ Form_pg_attribute_extra sourceExtra)
1036{1055{
1037 char *attributeName = NameStr(source->attname);1056 char *attributeName = NameStr(source->attname);
1038 1057 
@@ -1052,10 +1071,13 @@ void copyDroppedAttribute(Form_pg_attribute target, Form_pg_attribute source)
1052 target->atthasdef = source->atthasdef;1071 target->atthasdef = source->atthasdef;
1053 target->attisdropped = source->attisdropped;1072 target->attisdropped = source->attisdropped;
1054 target->attislocal = source->attislocal;1073 target->attislocal = source->attislocal;
1055- target->attkvtype = source->attkvtype;
1056 target->attcmprmode = source->attcmprmode;1074 target->attcmprmode = source->attcmprmode;
1057 target->attinhcount = source->attinhcount;1075 target->attinhcount = source->attinhcount;
1058 target->attcollation = source->attcollation;1076 target->attcollation = source->attcollation;
1077+ 
1078+ targetExtra->attkvtype = sourceExtra->attkvtype;
1079+ targetExtra->attdroppedname = sourceExtra->attdroppedname;
1080+ targetExtra->attidentity = sourceExtra->attidentity;
1059}1081}
1060 1082 
1061int UpgradeAdaptAttr(Oid atttypid, ColumnDef *entry)1083int UpgradeAdaptAttr(Oid atttypid, ColumnDef *entry)
@@ -1103,7 +1125,8 @@ static void BlockColumnRelOption(const char *tableFormat, const Oid atttypid, co
1103 * TupleDesc if it wants OIDs. Also, tdtypeid will need to be filled in1125 * TupleDesc if it wants OIDs. Also, tdtypeid will need to be filled in
1104 * later on.1126 * later on.
1105 */1127 */
1106-TupleDesc BuildDescForRelation(List *schema, Node *orientedFrom, char relkind, Oid rel_coll_oid)1128+TupleDesc BuildDescForRelation(List *schema, Node *orientedFrom, char relkind,
1129+ Oid rel_coll_oid, Form_pg_attribute_extra* attrExtra)
1107{1130{
1108 int natts;1131 int natts;
1109 AttrNumber attnum = 0;1132 AttrNumber attnum = 0;
@@ -1116,16 +1139,18 @@ TupleDesc BuildDescForRelation(List *schema, Node *orientedFrom, char relkind, O
1116 Oid attcollation;1139 Oid attcollation;
1117 int attdim;1140 int attdim;
1118 const char *tableFormat = "";1141 const char *tableFormat = "";
1119- 1142+ Form_pg_attribute_extra extra;
1120- if (orientedFrom != NULL) {
1121- tableFormat = strVal(orientedFrom);
1122- }
1123 1143 
1124 /*1144 /*
1125 * allocate a new tuple descriptor1145 * allocate a new tuple descriptor
1126 */1146 */
1127 natts = list_length(schema);1147 natts = list_length(schema);
1128 desc = CreateTemplateTupleDesc(natts, false);1148 desc = CreateTemplateTupleDesc(natts, false);
1149+ extra = (Form_pg_attribute_extra)palloc0(sizeof(FormData_pg_attribute_extra) * natts);
1150+ 
1151+ if (orientedFrom != NULL) {
1152+ tableFormat = strVal(orientedFrom);
1153+ }
1129 1154 
1130 foreach (l, schema) {1155 foreach (l, schema) {
1131 ColumnDef *entry = (ColumnDef *)lfirst(l);1156 ColumnDef *entry = (ColumnDef *)lfirst(l);
@@ -1138,8 +1163,9 @@ TupleDesc BuildDescForRelation(List *schema, Node *orientedFrom, char relkind, O
1138 */1163 */
1139 attnum++;1164 attnum++;
1140 1165 
1141- if (u_sess->attr.attr_sql.enable_cluster_resize && entry->dropped_attr != NULL) {1166+ if (u_sess->attr.attr_sql.enable_cluster_resize && entry->droppedAttr != NULL) {
1142- copyDroppedAttribute(&desc->attrs[attnum - 1], entry->dropped_attr);1167+ copyDroppedAttribute(&desc->attrs[attnum - 1], entry->droppedAttr,
1168+ &extra[attnum - 1], entry->droppedAttrExtra);
1143 continue;1169 continue;
1144 }1170 }
1145 attname = entry->colname;1171 attname = entry->colname;
@@ -1212,6 +1238,8 @@ TupleDesc BuildDescForRelation(List *schema, Node *orientedFrom, char relkind, O
1212 1238 
1213 /* Fill in additional stuff not handled by TupleDescInitEntry */1239 /* Fill in additional stuff not handled by TupleDescInitEntry */
1214 desc->attrs[attnum - 1].attnotnull = entry->is_not_null;1240 desc->attrs[attnum - 1].attnotnull = entry->is_not_null;
1241+ extra[attnum - 1].attidentity = entry->identity;
1242+ 
1215 /*1243 /*
1216 * PG source code: has_not_null |= entry->is_not_null;1244 * PG source code: has_not_null |= entry->is_not_null;
1217 */1245 */
@@ -1219,10 +1247,9 @@ TupleDesc BuildDescForRelation(List *schema, Node *orientedFrom, char relkind, O
1219 desc->attrs[attnum - 1].attislocal = entry->is_local;1247 desc->attrs[attnum - 1].attislocal = entry->is_local;
1220 desc->attrs[attnum - 1].attinhcount = entry->inhcount;1248 desc->attrs[attnum - 1].attinhcount = entry->inhcount;
1221 1249 
1222- Form_pg_attribute thisatt = &desc->attrs[attnum - 1];1250+ extra[attnum - 1].attkvtype = entry->kvtype;
1223- thisatt->attkvtype = entry->kvtype;1251+ VerifyAttrCompressMode(entry->cmprs_mode, desc->attrs[attnum - 1].attlen, attname);
1224- VerifyAttrCompressMode(entry->cmprs_mode, thisatt->attlen, attname);1252+ desc->attrs[attnum - 1].attcmprmode = entry->cmprs_mode;
1225- thisatt->attcmprmode = entry->cmprs_mode;
1226 1253 
1227 BlockRowCompressRelOption(tableFormat, entry);1254 BlockRowCompressRelOption(tableFormat, entry);
1228 }1255 }
@@ -1242,6 +1269,12 @@ TupleDesc BuildDescForRelation(List *schema, Node *orientedFrom, char relkind, O
1242 desc->constr = NULL;1269 desc->constr = NULL;
1243 }1270 }
1244 1271 
1272+ if (attrExtra) {
1273+ *attrExtra = extra;
1274+ } else {
1275+ pfree_ext(extra);
1276+ }
1277+ 
1245 return desc;1278 return desc;
1246}1279}
1247 1280 
@@ -179,6 +179,7 @@ extern TupleDesc CreateTupleDesc(int natts, bool hasoid, Form_pg_attribute *attr
179extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc);179extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc);
180extern TupleDesc CreateTupleDescCopyExtend(TupleDesc tupdesc, int moreatts);180extern TupleDesc CreateTupleDescCopyExtend(TupleDesc tupdesc, int moreatts);
181extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc);181extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc);
182+extern Form_pg_attribute_extra CreatePGAttributeExtra(TupleDesc tupdesc);
182 183 
183extern void FreeTupleDesc(TupleDesc tupdesc, bool need_check = true);184extern void FreeTupleDesc(TupleDesc tupdesc, bool need_check = true);
184 185 
@@ -209,13 +210,15 @@ extern void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attribute_num
209extern void VerifyAttrCompressMode(int8 mode, int attlen, const char* attname);210extern void VerifyAttrCompressMode(int8 mode, int attlen, const char* attname);
210 211 
211extern TupleDesc BuildDescForRelation(List* schema, Node* oriented_from = NULL, char relkind = '\0',212extern TupleDesc BuildDescForRelation(List* schema, Node* oriented_from = NULL, char relkind = '\0',
212- Oid rel_coll_oid = InvalidOid);213+ Oid rel_coll_oid = InvalidOid, Form_pg_attribute_extra* attrExtra = NULL);
213 214 
214extern TupleDesc BuildDescFromLists(List* names, List* types, List* typmods, List* collations);215extern TupleDesc BuildDescFromLists(List* names, List* types, List* typmods, List* collations);
215 216 
216extern bool tupledesc_have_pck(TupleConstr* constr);217extern bool tupledesc_have_pck(TupleConstr* constr);
217 218 
218-extern void copyDroppedAttribute(Form_pg_attribute target, Form_pg_attribute source);219+extern void copyDroppedAttribute(Form_pg_attribute target, Form_pg_attribute source,
220+ Form_pg_attribute_extra targetExtra,
221+ Form_pg_attribute_extra sourceExtra);
219 222 
220extern char GetGeneratedCol(TupleDesc tupdesc, int atti);223extern char GetGeneratedCol(TupleDesc tupdesc, int atti);
221 224 
@@ -31,8 +31,8 @@
31 31 
32extern void AlterCStoreCreateTables(Oid relOid, Datum reloptions, CreateStmt *mainTblStmt);32extern void AlterCStoreCreateTables(Oid relOid, Datum reloptions, CreateStmt *mainTblStmt);
33 33 
34-extern bool CreateDeltaTable(Relation rel, Datum reloptions, bool isPartition, CreateStmt *mainTblStmt);34+extern bool CreateDeltaTable(Relation rel, Datum reloptions, bool isPartition, CreateStmt *mainTblStmt);
35-extern bool CreateCUDescTable(Relation rel, Datum reloptions, bool isPartition);35+extern bool CreateCUDescTable(Relation rel, Datum reloptions, bool isPartition);
36extern bool createDeltaTableForPartition(Oid relOid, Oid partOid, Datum reloptions, CreateStmt *mainTblStmt);36extern bool createDeltaTableForPartition(Oid relOid, Oid partOid, Datum reloptions, CreateStmt *mainTblStmt);
37extern bool createCUDescTableForPartition(Oid relOid, Oid partOid, Datum reloptions);37extern bool createCUDescTableForPartition(Oid relOid, Oid partOid, Datum reloptions);
38extern Datum AddInternalOption(Datum reloptions, int mask);38extern Datum AddInternalOption(Datum reloptions, int mask);
@@ -328,16 +328,16 @@ extern long changeDependencyFor(Oid classId,
328extern void changeDependenciesOf(Oid classId, Oid oldObjectId, Oid newObjectId);328extern void changeDependenciesOf(Oid classId, Oid oldObjectId, Oid newObjectId);
329extern void changeDependenciesOn(Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId);329extern void changeDependenciesOn(Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId);
330 330 
331-extern Oid getExtensionOfObject(Oid classId, Oid objectId);331+extern Oid getExtensionOfObject(Oid classId, Oid objectId);
332 332 
333-extern bool sequenceIsOwned(Oid seqId, Oid *tableId, int32 *colId);333+extern bool sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId);
334- 334+extern List *getOwnedSequences(Oid relid);
335-extern void markSequenceUnowned(Oid seqId);335+extern Oid getOwnedSequence(Oid relid, AttrNumber attnum, char** seqname);
336- 336+extern Oid getIdentitySequence(Oid relid, AttrNumber attnum, bool missing_ok, bool forIdentityOfD);
337-extern List *getOwnedSequences(Oid relid, List *attrList = NULL);337+extern Oid getIdentitySequenceForD(Oid relid, const char* attrName, char** outAttrName);
338+extern List* getOwnedSequencesOfAttrList(Oid relid, List* attrList);
338 339 
339extern Oid get_constraint_index(Oid constraintId);340extern Oid get_constraint_index(Oid constraintId);
340- 
341extern Oid get_index_constraint(Oid indexId);341extern Oid get_index_constraint(Oid indexId);
342 342 
343/* use for reindex concurrently */343/* use for reindex concurrently */
@@ -143,7 +143,8 @@ extern Oid heap_create_with_catalog(const char *relname,
143 ObjectAddress *typaddress= NULL,143 ObjectAddress *typaddress= NULL,
144 List* depend_extend = NIL,144 List* depend_extend = NIL,
145 Oid relrewrite = InvalidOid,145 Oid relrewrite = InvalidOid,
146- Oid typbasetype = InvalidOid);146+ Oid typbasetype = InvalidOid,
147+ Form_pg_attribute_extra attrExtra = NULL);
147 148 
148extern void heap_create_init_fork(Relation rel);149extern void heap_create_init_fork(Relation rel);
149 150 
@@ -190,7 +191,8 @@ extern void heap_truncate_one_rel(Relation rel);
190extern void heap_truncate_check_FKs(List *relations, bool tempTables);191extern void heap_truncate_check_FKs(List *relations, bool tempTables);
191extern List *heap_truncate_find_FKs(List *relationIds);192extern List *heap_truncate_find_FKs(List *relationIds);
192extern void InsertTablebucketidAttribute(Oid relOid);193extern void InsertTablebucketidAttribute(Oid relOid);
193-extern void InsertPgAttributeTuple(Relation pg_attribute_rel, Form_pg_attribute new_attribute, CatalogIndexState indstate);194+extern void InsertPgAttributeTuple(Relation pg_attribute_rel, Form_pg_attribute new_attribute,
195+ Form_pg_attribute_extra attrExtra, CatalogIndexState indstate);
194 196 
195extern void InsertPgClassTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Datum relacl,197extern void InsertPgClassTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Datum relacl,
196 Datum reloptions, char relkind, int2vector *bucketcol);198 Datum reloptions, char relkind, int2vector *bucketcol);
@@ -208,6 +210,8 @@ extern void DeleteSystemAttributeTuples(Oid relid);
208extern void RemoveAttributeById(Oid relid, AttrNumber attnum);210extern void RemoveAttributeById(Oid relid, AttrNumber attnum);
209extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, DropBehavior behavior, bool complain, bool internal);211extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, DropBehavior behavior, bool complain, bool internal);
210extern void RemoveAttrDefaultById(Oid attrdefId);212extern void RemoveAttrDefaultById(Oid attrdefId);
213+extern char HeapTupleGetIdentity(HeapTuple tuple, Relation attr);
214+extern HeapTuple HeapTupleModifyIdentity(HeapTuple tuple, Relation attr, char identtiy);
211 215 
212extern void CopyStatistics(Oid fromrelid, Oid torelid, char starelkind);216extern void CopyStatistics(Oid fromrelid, Oid torelid, char starelkind);
213 217 
@@ -220,7 +224,8 @@ extern Form_pg_attribute SystemAttributeByName(const char *attname, bool relhaso
220extern int GetSysAttLength(bool hasBucketAttr = true);224extern int GetSysAttLength(bool hasBucketAttr = true);
221 225 
222extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, bool allow_system_table_mods);226extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, bool allow_system_table_mods);
223-extern void CheckAttributeType(const char *attname, Oid atttypid, Oid attcollation, List *containing_rowtypes, bool allow_system_table_mods);227+extern void CheckAttributeType(const char *attname, Oid atttypid, Oid attcollation,
228+ List *containing_rowtypes, bool allow_system_table_mods);
224 229 
225#ifdef PGXC230#ifdef PGXC
226/* Functions related to distribution data of relations */231/* Functions related to distribution data of relations */
@@ -173,11 +173,15 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK
173 /* the value is not null only when ALTER TABLE ... ADD COLUMN call */173 /* the value is not null only when ALTER TABLE ... ADD COLUMN call */
174 bytea attinitdefval;174 bytea attinitdefval;
175 175 
176-#endif
177 /* the attribute type for kv storage: tag(1), field(2), time(3), hide(4) or default(0) */176 /* the attribute type for kv storage: tag(1), field(2), time(3), hide(4) or default(0) */
178 int1 attkvtype;177 int1 attkvtype;
179- /* name of dropped attribute */178+ 
180- NameData attdroppedname;179+ /* name of dropped attribute */
180+ NameData attdroppedname;
181+ 
182+ /* One of the ATTRIBUTE_IDENTITY_* constants below, or '\0' */
183+ char attidentity;
184+#endif
181} FormData_pg_attribute;185} FormData_pg_attribute;
182 186 
183/*187/*
@@ -187,7 +191,7 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK
187 * can access fields beyond attcollation except in a real tuple!191 * can access fields beyond attcollation except in a real tuple!
188 */192 */
189#define ATTRIBUTE_FIXED_PART_SIZE \193#define ATTRIBUTE_FIXED_PART_SIZE \
190- (offsetof(FormData_pg_attribute, attdroppedname) + sizeof(Oid))194+ (offsetof(FormData_pg_attribute, attcollation) + sizeof(Oid))
191 195 
192/* ----------------196/* ----------------
193 * Form_pg_attribute corresponds to a pointer to a tuple with197 * Form_pg_attribute corresponds to a pointer to a tuple with
@@ -196,11 +200,19 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK
196 */200 */
197typedef FormData_pg_attribute *Form_pg_attribute;201typedef FormData_pg_attribute *Form_pg_attribute;
198 202 
203+typedef struct formData_pg_attribute_extra {
204+ int1 attkvtype;
205+ char attidentity;
206+ NameData attdroppedname;
207+} FormData_pg_attribute_extra;
208+ 
209+typedef FormData_pg_attribute_extra *Form_pg_attribute_extra;
210+ 
199/* ----------------211/* ----------------
200 * compiler constants for pg_attribute212 * compiler constants for pg_attribute
201 * ----------------213 * ----------------
202 */214 */
203-#define Natts_pg_attribute 25215+#define Natts_pg_attribute 26
204#define Anum_pg_attribute_attrelid 1216#define Anum_pg_attribute_attrelid 1
205#define Anum_pg_attribute_attname 2217#define Anum_pg_attribute_attname 2
206#define Anum_pg_attribute_atttypid 3218#define Anum_pg_attribute_atttypid 3
@@ -226,6 +238,7 @@ typedef FormData_pg_attribute *Form_pg_attribute;
226#define Anum_pg_attribute_attinitdefval 23238#define Anum_pg_attribute_attinitdefval 23
227#define Anum_pg_attribute_attkvtype 24239#define Anum_pg_attribute_attkvtype 24
228#define Anum_pg_attribute_attdroppedname 25240#define Anum_pg_attribute_attdroppedname 25
241+#define Anum_pg_attribute_attidentity 26
229 242 
230/* ----------------243/* ----------------
231 * initial contents of pg_attribute244 * initial contents of pg_attribute
@@ -235,7 +248,9 @@ typedef FormData_pg_attribute *Form_pg_attribute;
235 * ----------------248 * ----------------
236 */249 */
237#define ATTRIBUTE_IDENTITY_ALWAYS 'a'250#define ATTRIBUTE_IDENTITY_ALWAYS 'a'
251+#define ATTRIBUTE_IDENTITY_BY_DEFAULT 'd'
238#define ATTRIBUTE_GENERATED_STORED 's'252#define ATTRIBUTE_GENERATED_STORED 's'
239#define ATTRIBUTE_GENERATED_PERSISTED 'p'253#define ATTRIBUTE_GENERATED_PERSISTED 'p'
254+#define ATTRIBUTE_IDENTITY_D 'm' /* identtiy column in D format */
240#endif /* PG_ATTRIBUTE_H */255#endif /* PG_ATTRIBUTE_H */
241 256 
@@ -124,34 +124,6 @@ typedef FormData_pg_authid *Form_pg_authid;
124#define Anum_pg_authid_rolpolicyadmin 26124#define Anum_pg_authid_rolpolicyadmin 26
125#define Anum_pg_authid_rolpasswordext 27125#define Anum_pg_authid_rolpasswordext 27
126 126 
127-static int Authid_Name_Data[] = {
128- Anum_pg_authid_rolname, Anum_pg_authid_rolrespool, Natts_pg_authid
129-};
130-static int Authid_Bool[] = {
131- Anum_pg_authid_rolsuper, Anum_pg_authid_rolinherit, Anum_pg_authid_rolcreaterole,
132- Anum_pg_authid_rolcreatedb, Anum_pg_authid_rolcatupdate, Anum_pg_authid_rolcanlogin,
133- Anum_pg_authid_rolreplication, Anum_pg_authid_rolauditadmin, Anum_pg_authid_rolsystemadmin,
134- Anum_pg_authid_roluseft, Anum_pg_authid_rolmonitoradmin, Anum_pg_authid_roloperatoradmin,
135- Anum_pg_authid_rolpolicyadmin, Natts_pg_authid
136-};
137-static int Authid_Text[] = {
138- Anum_pg_authid_rolpassword, Anum_pg_authid_roltempspace, Anum_pg_authid_rolspillspace,
139- Anum_pg_authid_rolspillspace, Anum_pg_authid_roltabspace, Natts_pg_authid
140-};
141-static int Authid_Oid[] = {
142- Anum_pg_authid_rolparentid, Anum_pg_authid_rolnodegroup, Natts_pg_authid
143-};
144-static int Authid_Int4[] = {
145- Anum_pg_authid_rolconnlimit, Natts_pg_authid
146-};
147-static int Authid_TimeStamptz[] = {
148- Anum_pg_authid_rolvalidbegin, Anum_pg_authid_rolvaliduntil, Natts_pg_authid
149-};
150-static int Authid_Char[] = {
151- Anum_pg_authid_rolkind, Natts_pg_authid
152-};
153- 
154- 
155/* ----------------127/* ----------------
156 * initial contents of pg_authid128 * initial contents of pg_authid
157 *129 *
@@ -163,7 +163,7 @@ typedef FormData_pg_class* Form_pg_class;
163 */163 */
164DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 0 0 0 0 0 f f p r 30 0 t f f f f 0 f f n 3 _null_ _null_ n 3 _null_ _null_ 1));164DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 0 0 0 0 0 f f p r 30 0 t f f f f 0 f f n 3 _null_ _null_ n 3 _null_ _null_ 1));
165DESCR("");165DESCR("");
166-DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 0 0 0 0 0 f f p r 25 0 f f f f f 0 f f n 3 _null_ _null_ n 3 _null_ _null_ 1));166+DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 0 0 0 0 0 f f p r 26 0 f f f f f 0 f f n 3 _null_ _null_ n 3 _null_ _null_ 1));
167DESCR("");167DESCR("");
168DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 0 0 0 0 0 f f p r 39 0 t f f f f 0 f f n 3 _null_ _null_ n 3 _null_ _null_ 1));168DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 0 0 0 0 0 f f p r 39 0 t f f f f 0 f f n 3 _null_ _null_ n 3 _null_ _null_ 1));
169DESCR("");169DESCR("");
@@ -0,0 +1,40 @@
1+DROP FUNCTION IF EXISTS pg_catalog.gs_catalog_attribute_records(
2+ oid, OUT oid, OUT name, OUT oid, OUT integer, OUT smallint, OUT smallint, OUT integer, OUT integer, OUT integer,
3+ OUT boolean, OUT "char", OUT "char", OUT boolean, OUT boolean, OUT boolean, OUT boolean, OUT tinyint, OUT integer,
4+ OUT oid, OUT aclitem[], OUT text[], OUT text[], OUT bytea, OUT tinyint, OUT name, OUT "char"
5+);
6+SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 8010;
7+CREATE FUNCTION pg_catalog.gs_catalog_attribute_records(
8+ IN relid oid,
9+ OUT attrelid oid,
10+ OUT attname name,
11+ OUT atttypid oid,
12+ OUT attstattarget integer,
13+ OUT attlen smallint,
14+ OUT attnum smallint,
15+ OUT attndims integer,
16+ OUT attcacheoff integer,
17+ OUT atttypmod integer,
18+ OUT attbyval boolean,
19+ OUT attstorage "char",
20+ OUT attalign "char",
21+ OUT attnotnull boolean,
22+ OUT atthasdef boolean,
23+ OUT attisdropped boolean,
24+ OUT attislocal boolean,
25+ OUT attcmprmode tinyint,
26+ OUT attinhcount integer,
27+ OUT attcollation oid,
28+ OUT attacl aclitem [],
29+ OUT attoptions text [],
30+ OUT attfdwoptions text [],
31+ OUT attinitdefval bytea,
32+ OUT attkvtype tinyint,
33+ OUT attdroppedname name
34+ ) RETURNS SETOF RECORD STRICT STABLE ROWS 1000 LANGUAGE INTERNAL NOT FENCED NOT SHIPPABLE AS 'gs_catalog_attribute_records';
35+ 
36+COMMENT ON FUNCTION pg_catalog.gs_catalog_attribute_records(
37+ oid, OUT oid, OUT name, OUT oid, OUT integer, OUT smallint, OUT smallint, OUT integer, OUT integer, OUT integer,
38+ OUT boolean, OUT "char", OUT "char", OUT boolean, OUT boolean, OUT boolean, OUT boolean, OUT tinyint, OUT integer,
39+ OUT oid, OUT aclitem[], OUT text[], OUT text[], OUT bytea, OUT tinyint, OUT name
40+) IS 'attribute description for catalog relation';
@@ -0,0 +1,40 @@
1+DROP FUNCTION IF EXISTS pg_catalog.gs_catalog_attribute_records(
2+ oid, OUT oid, OUT name, OUT oid, OUT integer, OUT smallint, OUT smallint, OUT integer, OUT integer, OUT integer,
3+ OUT boolean, OUT "char", OUT "char", OUT boolean, OUT boolean, OUT boolean, OUT boolean, OUT tinyint, OUT integer,
4+ OUT oid, OUT aclitem[], OUT text[], OUT text[], OUT bytea, OUT tinyint, OUT name, OUT "char"
5+);
6+SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 8010;
7+CREATE FUNCTION pg_catalog.gs_catalog_attribute_records(
8+ IN relid oid,
9+ OUT attrelid oid,
10+ OUT attname name,
11+ OUT atttypid oid,
12+ OUT attstattarget integer,
13+ OUT attlen smallint,
14+ OUT attnum smallint,
15+ OUT attndims integer,
16+ OUT attcacheoff integer,
17+ OUT atttypmod integer,
18+ OUT attbyval boolean,
19+ OUT attstorage "char",
20+ OUT attalign "char",
21+ OUT attnotnull boolean,
22+ OUT atthasdef boolean,
23+ OUT attisdropped boolean,
24+ OUT attislocal boolean,
25+ OUT attcmprmode tinyint,
26+ OUT attinhcount integer,
27+ OUT attcollation oid,
28+ OUT attacl aclitem [],
29+ OUT attoptions text [],
30+ OUT attfdwoptions text [],
31+ OUT attinitdefval bytea,
32+ OUT attkvtype tinyint,
33+ OUT attdroppedname name
34+ ) RETURNS SETOF RECORD STRICT STABLE ROWS 1000 LANGUAGE INTERNAL NOT FENCED NOT SHIPPABLE AS 'gs_catalog_attribute_records';
35+ 
36+COMMENT ON FUNCTION pg_catalog.gs_catalog_attribute_records(
37+ oid, OUT oid, OUT name, OUT oid, OUT integer, OUT smallint, OUT smallint, OUT integer, OUT integer, OUT integer,
38+ OUT boolean, OUT "char", OUT "char", OUT boolean, OUT boolean, OUT boolean, OUT boolean, OUT tinyint, OUT integer,
39+ OUT oid, OUT aclitem[], OUT text[], OUT text[], OUT bytea, OUT tinyint, OUT name
40+) IS 'attribute description for catalog relation';
@@ -0,0 +1,41 @@
1+DROP FUNCTION IF EXISTS pg_catalog.gs_catalog_attribute_records(
2+ oid, OUT oid, OUT name, OUT oid, OUT integer, OUT smallint, OUT smallint, OUT integer, OUT integer, OUT integer,
3+ OUT boolean, OUT "char", OUT "char", OUT boolean, OUT boolean, OUT boolean, OUT boolean, OUT tinyint, OUT integer,
4+ OUT oid, OUT aclitem[], OUT text[], OUT text[], OUT bytea, OUT tinyint, OUT name
5+);
6+SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 8010;
7+CREATE FUNCTION pg_catalog.gs_catalog_attribute_records(
8+ IN relid oid,
9+ OUT attrelid oid,
10+ OUT attname name,
11+ OUT atttypid oid,
12+ OUT attstattarget integer,
13+ OUT attlen smallint,
14+ OUT attnum smallint,
15+ OUT attndims integer,
16+ OUT attcacheoff integer,
17+ OUT atttypmod integer,
18+ OUT attbyval boolean,
19+ OUT attstorage "char",
20+ OUT attalign "char",
21+ OUT attnotnull boolean,
22+ OUT atthasdef boolean,
23+ OUT attisdropped boolean,
24+ OUT attislocal boolean,
25+ OUT attcmprmode tinyint,
26+ OUT attinhcount integer,
27+ OUT attcollation oid,
28+ OUT attacl aclitem [],
29+ OUT attoptions text [],
30+ OUT attfdwoptions text [],
31+ OUT attinitdefval bytea,
32+ OUT attkvtype tinyint,
33+ OUT attdroppedname name,
34+ OUT attidentity "char"
35+ ) RETURNS SETOF RECORD STRICT STABLE ROWS 1000 LANGUAGE INTERNAL NOT FENCED NOT SHIPPABLE AS 'gs_catalog_attribute_records';
36+ 
37+COMMENT ON FUNCTION pg_catalog.gs_catalog_attribute_records(
38+ oid, OUT oid, OUT name, OUT oid, OUT integer, OUT smallint, OUT smallint, OUT integer, OUT integer, OUT integer,
39+ OUT boolean, OUT "char", OUT "char", OUT boolean, OUT boolean, OUT boolean, OUT boolean, OUT tinyint, OUT integer,
40+ OUT oid, OUT aclitem[], OUT text[], OUT text[], OUT bytea, OUT tinyint, OUT name, OUT "char"
41+) IS 'attribute description for catalog relation';
@@ -0,0 +1,41 @@
1+DROP FUNCTION IF EXISTS pg_catalog.gs_catalog_attribute_records(
2+ oid, OUT oid, OUT name, OUT oid, OUT integer, OUT smallint, OUT smallint, OUT integer, OUT integer, OUT integer,
3+ OUT boolean, OUT "char", OUT "char", OUT boolean, OUT boolean, OUT boolean, OUT boolean, OUT tinyint, OUT integer,
4+ OUT oid, OUT aclitem[], OUT text[], OUT text[], OUT bytea, OUT tinyint, OUT name
5+);
6+SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 8010;
7+CREATE FUNCTION pg_catalog.gs_catalog_attribute_records(
8+ IN relid oid,
9+ OUT attrelid oid,
10+ OUT attname name,
11+ OUT atttypid oid,
12+ OUT attstattarget integer,
13+ OUT attlen smallint,
14+ OUT attnum smallint,
15+ OUT attndims integer,
16+ OUT attcacheoff integer,
17+ OUT atttypmod integer,
18+ OUT attbyval boolean,
19+ OUT attstorage "char",
20+ OUT attalign "char",
21+ OUT attnotnull boolean,
22+ OUT atthasdef boolean,
23+ OUT attisdropped boolean,
24+ OUT attislocal boolean,
25+ OUT attcmprmode tinyint,
26+ OUT attinhcount integer,
27+ OUT attcollation oid,
28+ OUT attacl aclitem [],
29+ OUT attoptions text [],
30+ OUT attfdwoptions text [],
31+ OUT attinitdefval bytea,
32+ OUT attkvtype tinyint,
33+ OUT attdroppedname name,
34+ OUT attidentity "char"
35+ ) RETURNS SETOF RECORD STRICT STABLE ROWS 1000 LANGUAGE INTERNAL NOT FENCED NOT SHIPPABLE AS 'gs_catalog_attribute_records';
36+ 
37+COMMENT ON FUNCTION pg_catalog.gs_catalog_attribute_records(
38+ oid, OUT oid, OUT name, OUT oid, OUT integer, OUT smallint, OUT smallint, OUT integer, OUT integer, OUT integer,
39+ OUT boolean, OUT "char", OUT "char", OUT boolean, OUT boolean, OUT boolean, OUT boolean, OUT tinyint, OUT integer,
40+ OUT oid, OUT aclitem[], OUT text[], OUT text[], OUT bytea, OUT tinyint, OUT name, OUT "char"
41+) IS 'attribute description for catalog relation';
@@ -191,7 +191,8 @@ extern char* get_am_name(Oid amoid);
191extern char* defGetString(DefElem* def);191extern char* defGetString(DefElem* def);
192extern double defGetNumeric(DefElem* def);192extern double defGetNumeric(DefElem* def);
193extern bool defGetBoolean(DefElem* def);193extern bool defGetBoolean(DefElem* def);
194-extern int defGetMixdInt(DefElem *def);194+extern int defGetMixdBoolean(DefElem *def);
195+extern int32 defGetInt32(DefElem* def);
195extern int64 defGetInt64(DefElem* def);196extern int64 defGetInt64(DefElem* def);
196extern List* defGetQualifiedName(DefElem* def);197extern List* defGetQualifiedName(DefElem* def);
197extern TypeName* defGetTypeName(DefElem* def);198extern TypeName* defGetTypeName(DefElem* def);
@@ -190,7 +190,7 @@ extern Datum pg_sequence_parameters(PG_FUNCTION_ARGS);
190extern Datum pg_sequence_all_parameters(PG_FUNCTION_ARGS);190extern Datum pg_sequence_all_parameters(PG_FUNCTION_ARGS);
191extern Datum pg_sequence_last_value(PG_FUNCTION_ARGS);191extern Datum pg_sequence_last_value(PG_FUNCTION_ARGS);
192 192 
193-extern int128 nextval_internal(Oid relid);193+extern int128 nextval_internal(Oid relid, bool checkPermissions);
194extern void autoinc_setval(Oid relid, int128 next, bool iscalled);194extern void autoinc_setval(Oid relid, int128 next, bool iscalled);
195extern int128 autoinc_get_nextval(Oid relid);195extern int128 autoinc_get_nextval(Oid relid);
196extern bool CheckSeqOwnedByAutoInc(Oid seqoid);196extern bool CheckSeqOwnedByAutoInc(Oid seqoid);
@@ -274,7 +274,6 @@ extern SeqTable GetSessSeqElm(Oid relid);
274extern char* GetGlobalSeqNameForUpdate(Relation seqrel, char** dbname, char** schemaname);274extern char* GetGlobalSeqNameForUpdate(Relation seqrel, char** dbname, char** schemaname);
275extern uint32 RelidGetHash(Oid seq_relid);275extern uint32 RelidGetHash(Oid seq_relid);
276extern SeqTable GetGlobalSeqElm(Oid relid, GlobalSeqInfoHashBucket* bucket);276extern SeqTable GetGlobalSeqElm(Oid relid, GlobalSeqInfoHashBucket* bucket);
277-extern Oid pg_get_serial_sequence_oid(text* tablename, text* columnname, bool find_identity = false);
278extern bool StrEndWith(const char *str, const char *suffix);277extern bool StrEndWith(const char *str, const char *suffix);
279typedef void (*InvokeNextvalHookType) (Oid relid, int128 val);278typedef void (*InvokeNextvalHookType) (Oid relid, int128 val);
280 279 
@@ -54,10 +54,9 @@
54#define AT_PASS_ADD_COL 5 /* ADD COLUMN */54#define AT_PASS_ADD_COL 5 /* ADD COLUMN */
55#define AT_PASS_ADD_INDEX 6 /* ADD indexes */55#define AT_PASS_ADD_INDEX 6 /* ADD indexes */
56#define AT_PASS_ADD_CONSTR 7 /* ADD constraints, defaults */56#define AT_PASS_ADD_CONSTR 7 /* ADD constraints, defaults */
57- 
58#define AT_PASS_ADD_PARTITION 857#define AT_PASS_ADD_PARTITION 8
59- 
60#define AT_PASS_MISC 9 /* other stuff */58#define AT_PASS_MISC 9 /* other stuff */
59+ 
61#ifdef PGXC60#ifdef PGXC
62#define AT_PASS_DISTRIB 10 /* Redistribution pass */61#define AT_PASS_DISTRIB 10 /* Redistribution pass */
63#define AT_COMMENT 1162#define AT_COMMENT 11
@@ -314,13 +313,12 @@ extern void spq_btbuild_update_pg_class(Relation heap, Relation index);
314#endif313#endif
315typedef void (*InvokePreDropColumnHookType) (Relation rel, AttrNumber attnum);314typedef void (*InvokePreDropColumnHookType) (Relation rel, AttrNumber attnum);
316extern bool IsComputedColumn(Oid adrelid, int2 asnum);315extern bool IsComputedColumn(Oid adrelid, int2 asnum);
317- 
318-extern void SetRelAutoIncrement(Relation rel, TupleDesc desc, int128 autoinc);
319-extern void CopyTempAutoIncrement(Relation oldrel, Relation newrel);
320-extern void UpdateValueModifyFirstAfter(NewColumnValue *ex, Datum* values, bool* isnull);
321-extern void SetRelAutoIncrement(Relation rel, TupleDesc desc, int128 autoinc);
322-extern void CopyTempAutoIncrement(Relation oldrel, Relation newrel);
323extern void UpdateGeneratedColumnIsnull(AlteredTableInfo* tab, bool* isnull, bool has_generated);316extern void UpdateGeneratedColumnIsnull(AlteredTableInfo* tab, bool* isnull, bool has_generated);
317+extern void UpdateValueModifyFirstAfter(NewColumnValue *ex, Datum* values, bool* isnull);
318+ 
319+extern void CopyTempAutoIncrement(Relation oldrel, Relation newrel);
320+extern void SetRelAutoIncrement(Relation rel, TupleDesc desc, int128 autoinc);
321+extern void CopyTempAutoIncrement(Relation oldrel, Relation newrel);
324extern int128 EvaluateAutoIncrement(Relation rel, TupleDesc desc, AttrNumber attnum, Datum* value, bool* is_null);322extern int128 EvaluateAutoIncrement(Relation rel, TupleDesc desc, AttrNumber attnum, Datum* value, bool* is_null);
325extern bool OnlineDDLCheckSetCompressOptFeasible(Relation rel, List* defList, AlterTableType operation,323extern bool OnlineDDLCheckSetCompressOptFeasible(Relation rel, List* defList, AlterTableType operation,
326 LOCKMODE lockmode, AlteredTableInfo* tab);324 LOCKMODE lockmode, AlteredTableInfo* tab);
@@ -38,12 +38,13 @@
38/*****************************************************************************38/*****************************************************************************
39 * Backend version and inplace upgrade staffs39 * Backend version and inplace upgrade staffs
40 *****************************************************************************/40 *****************************************************************************/
41+extern const uint32 PG_IDENTITY_VERSION_NUM;
41extern const uint32 LSG_VERSION_NUM;42extern const uint32 LSG_VERSION_NUM;
42extern const uint32 RABITQ_VERSION_NUM;43extern const uint32 RABITQ_VERSION_NUM;
43extern const uint32 UHEAP_LOCK_VERSION_NUM;44extern const uint32 UHEAP_LOCK_VERSION_NUM;
44extern const uint32 PGSTAT_LAST_SCAN_VERSION_NUM;45extern const uint32 PGSTAT_LAST_SCAN_VERSION_NUM;
45extern const uint32 INLINEVIEW_DML_VERSION_NUM;46extern const uint32 INLINEVIEW_DML_VERSION_NUM;
46-extern const uint32 IDENTITY_VERSION_NUM;47+extern const uint32 D_IDENTITY_VERSION_NUM;
47extern const uint32 COMPUTED_COLUMNS_VERSION_NUMBER;48extern const uint32 COMPUTED_COLUMNS_VERSION_NUMBER;
48extern const uint32 SWCB_OPTIMIZATION_VERSION_NUM;49extern const uint32 SWCB_OPTIMIZATION_VERSION_NUM;
49extern const uint32 SUPPORT_D_FORMAT_DATABASE;50extern const uint32 SUPPORT_D_FORMAT_DATABASE;
@@ -375,7 +376,7 @@ static const struct behavior_compat_entry restrict_nonsystem_relation_kind[OPT_R
375 376 
376/* similar with SUPPORT_D_FORMAT_DATABASE_MACRO */377/* similar with SUPPORT_D_FORMAT_DATABASE_MACRO */
377#define IDENTITY_VERSION_NUM_MACRO \378#define IDENTITY_VERSION_NUM_MACRO \
378- (t_thrd.proc->workingVersionNum >= IDENTITY_VERSION_NUM || \379+ (t_thrd.proc->workingVersionNum >= D_IDENTITY_VERSION_NUM || \
379 (t_thrd.proc->workingVersionNum >= 92976 && \380 (t_thrd.proc->workingVersionNum >= 92976 && \
380 t_thrd.proc->workingVersionNum < 93000))381 t_thrd.proc->workingVersionNum < 93000))
381 382 
@@ -215,6 +215,7 @@ typedef enum ExprEvalOp
215 EEOP_CONVERT_ROWTYPE,215 EEOP_CONVERT_ROWTYPE,
216 EEOP_SCALARARRAYOP,216 EEOP_SCALARARRAYOP,
217 EEOP_HASHED_SCALARARRAYOP,217 EEOP_HASHED_SCALARARRAYOP,
218+ EEOP_NEXTVALUEEXPR,
218 EEOP_XMLEXPR,219 EEOP_XMLEXPR,
219 EEOP_AGGREF,220 EEOP_AGGREF,
220 EEOP_GROUPING_FUNC,221 EEOP_GROUPING_FUNC,
@@ -579,6 +580,12 @@ typedef struct ExprEvalStep
579 ScalarArrayOpExpr *saop;580 ScalarArrayOpExpr *saop;
580 } hashedscalararrayop;581 } hashedscalararrayop;
581 582 
583+ /* for EEOP_NEXTVALUEEXPR */
584+ struct {
585+ Oid seqid; /* sequence id of identity column */
586+ Oid seqtypid; /* sequence type id */
587+ } nextvalueexpr;
588+ 
582 /* for EEOP_XMLEXPR */589 /* for EEOP_XMLEXPR */
583 struct590 struct
584 {591 {
@@ -754,6 +761,7 @@ extern void ExecEvalParamExec(ExprState *state, ExprEvalStep *op,
754extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op,761extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op,
755 ExprContext *econtext);762 ExprContext *econtext);
756extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op);763extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op);
764+extern void ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op);
757extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op,765extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op,
758 ExprContext *econtext);766 ExprContext *econtext);
759extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op,767extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op,
@@ -275,6 +275,7 @@ typedef enum NodeTag {
275 T_CoerceToDomainValue,275 T_CoerceToDomainValue,
276 T_SetToDefault,276 T_SetToDefault,
277 T_CurrentOfExpr,277 T_CurrentOfExpr,
278+ T_NextValueExpr,
278 T_TargetEntry,279 T_TargetEntry,
279 T_RangeTblRef,280 T_RangeTblRef,
280 T_JoinExpr,281 T_JoinExpr,
@@ -888,6 +888,12 @@ typedef struct ShutdownStmt {
888 case CONSTR_GENERATED: \888 case CONSTR_GENERATED: \
889 tname = "GENERATED COL"; \889 tname = "GENERATED COL"; \
890 break; \890 break; \
891+ case CONSTR_GENERATED_IDENTITY: \
892+ tname = "GENERATED AS IDENTITY"; \
893+ break; \
894+ case CONSTR_D_IDENTITY: \
895+ tname = "IDENTITY"; \
896+ break; \
891 case CONSTR_AUTO_INCREMENT: \897 case CONSTR_AUTO_INCREMENT: \
892 tname = "AUTO_INCREMENT"; \898 tname = "AUTO_INCREMENT"; \
893 break; \899 break; \
@@ -1214,6 +1220,8 @@ typedef struct CreateSeqStmt {
1214 bool is_large;1220 bool is_large;
1215 bool missing_ok; /* skip error if a Sequence is exists */1221 bool missing_ok; /* skip error if a Sequence is exists */
1216 bool is_autoinc;1222 bool is_autoinc;
1223+ bool forIdentity; /* create underlying sequence for identity column */
1224+ bool forDIdentity; /* identity in D format */
1217} CreateSeqStmt;1225} CreateSeqStmt;
1218 1226 
1219typedef struct AlterSeqStmt {1227typedef struct AlterSeqStmt {
@@ -1226,6 +1234,8 @@ typedef struct AlterSeqStmt {
1226#endif1234#endif
1227 bool is_large; /* Indicates if this is a large or normal sequence */1235 bool is_large; /* Indicates if this is a large or normal sequence */
1228 bool is_autoinc;1236 bool is_autoinc;
1237+ bool forIdentity; /* alter underlying sequence for identity column */
1238+ bool forDIdentity; /* identity in D format */
1229} AlterSeqStmt;1239} AlterSeqStmt;
1230 1240 
1231/* ----------------------1241/* ----------------------
@@ -40,6 +40,14 @@
40/* Sort ordering options for ORDER BY and CREATE INDEX */40/* Sort ordering options for ORDER BY and CREATE INDEX */
41typedef enum RoleLockType { DO_NOTHING, LOCK_ROLE, UNLOCK_ROLE } RoleLockType;41typedef enum RoleLockType { DO_NOTHING, LOCK_ROLE, UNLOCK_ROLE } RoleLockType;
42 42 
43+/* overriding clause type */
44+typedef enum OverridingKind
45+{
46+ OVERRIDING_NOT_SET = 0,
47+ OVERRIDING_USER_VALUE,
48+ OVERRIDING_SYSTEM_VALUE
49+} OverridingKind;
50+ 
43/*51/*
44 * When a command can act on several kinds of objects with only one52 * When a command can act on several kinds of objects with only one
45 * parse structure required, use these constants to designate the53 * parse structure required, use these constants to designate the
@@ -490,6 +498,7 @@ typedef struct InsertStmt {
490 List *returningList; /* list of expressions to return */498 List *returningList; /* list of expressions to return */
491 WithClause *withClause; /* WITH clause */499 WithClause *withClause; /* WITH clause */
492 UpsertClause *upsertClause; /* DUPLICATE KEY UPDATE clause */500 UpsertClause *upsertClause; /* DUPLICATE KEY UPDATE clause */
501+ OverridingKind override; /* OVERRIDING clause */
493 HintState *hintState;502 HintState *hintState;
494 bool isReplace;503 bool isReplace;
495 List *targetList;504 List *targetList;
@@ -986,6 +995,9 @@ typedef enum AlterTableType {
986 AT_UnImcstored,995 AT_UnImcstored,
987 AT_ModifyPartitionImcstored,996 AT_ModifyPartitionImcstored,
988 AT_ModifyPartitionUnImcstored,997 AT_ModifyPartitionUnImcstored,
998+ AT_AddIdentity, /* ADD IDENTITY */
999+ AT_SetIdentity, /* SET identity column options */
1000+ AT_DropIdentity, /* DROP IDENTITY */
989} AlterTableType;1001} AlterTableType;
990 1002 
991typedef enum AlterTableStatProperty { /* Additional Property for AlterTableCmd */1003typedef enum AlterTableStatProperty { /* Additional Property for AlterTableCmd */
@@ -1165,11 +1177,13 @@ typedef struct ColumnDef {
1165 bool is_not_null; /* NOT NULL constraint specified? */1177 bool is_not_null; /* NOT NULL constraint specified? */
1166 bool is_from_type; /* column definition came from table type */1178 bool is_from_type; /* column definition came from table type */
1167 bool is_serial; /* column is serial type or not */1179 bool is_serial; /* column is serial type or not */
1168- bool is_identity; /* column is identity or not */
1169 char storage; /* attstorage setting, or 0 for default */1180 char storage; /* attstorage setting, or 0 for default */
1170 int8 cmprs_mode; /* compression method applied to this column */1181 int8 cmprs_mode; /* compression method applied to this column */
1171 Node *raw_default; /* default value (untransformed parse tree) */1182 Node *raw_default; /* default value (untransformed parse tree) */
1172 Node *cooked_default; /* default value (transformed expr tree) */1183 Node *cooked_default; /* default value (transformed expr tree) */
1184+ char identity; /* attidentity setting */
1185+ RangeVar *identitySequence; /* to store identity sequence name for
1186+ * ALTER TABLE ... ADD COLUMN */
1173 CollateClause *collClause; /* untransformed COLLATE spec, if any */1187 CollateClause *collClause; /* untransformed COLLATE spec, if any */
1174 Oid collOid; /* collation OID (InvalidOid if not set) */1188 Oid collOid; /* collation OID (InvalidOid if not set) */
1175 List *constraints; /* other constraints on column */1189 List *constraints; /* other constraints on column */
@@ -1177,7 +1191,8 @@ typedef struct ColumnDef {
1177 List *columnOptions; /* b compatiblity options */1191 List *columnOptions; /* b compatiblity options */
1178 ClientLogicColumnRef *clientLogicColumnRef;1192 ClientLogicColumnRef *clientLogicColumnRef;
1179 Position *position;1193 Position *position;
1180- Form_pg_attribute dropped_attr; /* strcuture for dropped attribute during create table like OE */1194+ Form_pg_attribute droppedAttr; /* strcuture for dropped attribute during create table like OE */
1195+ Form_pg_attribute_extra droppedAttrExtra; /* dropped attribute */
1181 char generatedCol; /* generated column setting */1196 char generatedCol; /* generated column setting */
1182 Node *update_default;1197 Node *update_default;
1183 char *initdefval;1198 char *initdefval;
@@ -1448,8 +1463,9 @@ typedef enum ConstrType { /* types of constraints */
1448 CONSTR_ATTR_DEFERRED,1463 CONSTR_ATTR_DEFERRED,
1449 CONSTR_ATTR_IMMEDIATE,1464 CONSTR_ATTR_IMMEDIATE,
1450 CONSTR_GENERATED,1465 CONSTR_GENERATED,
1466+ CONSTR_GENERATED_IDENTITY, /* generated xx as identity */
1451 CONSTR_AUTO_INCREMENT,1467 CONSTR_AUTO_INCREMENT,
1452- CONSTR_IDENTITY1468+ CONSTR_D_IDENTITY /* identity in D format */
1453} ConstrType;1469} ConstrType;
1454 1470 
1455typedef struct Constraint {1471typedef struct Constraint {
@@ -1517,7 +1533,7 @@ typedef struct TableLikeClause {
1517 bits32 options; /* OR of TableLikeOption flags */1533 bits32 options; /* OR of TableLikeOption flags */
1518} TableLikeClause;1534} TableLikeClause;
1519 1535 
1520-#define MAX_TABLE_LIKE_OPTIONS (11)1536+#define MAX_TABLE_LIKE_OPTIONS (12)
1521typedef enum TableLikeOption {1537typedef enum TableLikeOption {
1522 CREATE_TABLE_LIKE_DEFAULTS = 1 << 0,1538 CREATE_TABLE_LIKE_DEFAULTS = 1 << 0,
1523 CREATE_TABLE_LIKE_CONSTRAINTS = 1 << 1,1539 CREATE_TABLE_LIKE_CONSTRAINTS = 1 << 1,
@@ -1530,6 +1546,7 @@ typedef enum TableLikeOption {
1530 CREATE_TABLE_LIKE_OIDS = 1 << 8,1546 CREATE_TABLE_LIKE_OIDS = 1 << 8,
1531 CREATE_TABLE_LIKE_DEFAULTS_SERIAL = 1 << 9, /* Backward compatibility. Inherits serial defaults by default. */1547 CREATE_TABLE_LIKE_DEFAULTS_SERIAL = 1 << 9, /* Backward compatibility. Inherits serial defaults by default. */
1532 CREATE_TABLE_LIKE_GENERATED = 1 << 10,1548 CREATE_TABLE_LIKE_GENERATED = 1 << 10,
1549+ CREATE_TABLE_LIKE_IDENTITY = 1 << 11,
1533 CREATE_TABLE_LIKE_ALL = 0x7FFFFFFF1550 CREATE_TABLE_LIKE_ALL = 0x7FFFFFFF
1534} TableLikeOption;1551} TableLikeOption;
1535 1552 
@@ -2048,7 +2065,6 @@ typedef struct A_Const {
2048 int location; /* token location, or -1 if unknown */2065 int location; /* token location, or -1 if unknown */
2049} A_Const;2066} A_Const;
2050 2067 
2051- 
2052/* Possible sources of a Query */2068/* Possible sources of a Query */
2053typedef enum QuerySource {2069typedef enum QuerySource {
2054 QSRC_ORIGINAL, /* original parsetree (explicit query) */2070 QSRC_ORIGINAL, /* original parsetree (explicit query) */
@@ -2172,6 +2188,8 @@ typedef struct Query {
2172 2188 
2173 List* rowMarks; /* a list of RowMarkClause's */2189 List* rowMarks; /* a list of RowMarkClause's */
2174 2190 
2191+ OverridingKind override; /* OVERRIDING clause */
2192+ 
2175 Node* setOperations; /* set-operation tree if this is top level of2193 Node* setOperations; /* set-operation tree if this is top level of
2176 * a UNION/INTERSECT/EXCEPT query */2194 * a UNION/INTERSECT/EXCEPT query */
2177 2195 
@@ -2320,6 +2338,7 @@ typedef struct MergeWhenClause {
2320 CmdType commandType; /* INSERT/UPDATE/DELETE */2338 CmdType commandType; /* INSERT/UPDATE/DELETE */
2321 Node *condition; /* WHERE conditions (raw parser) */2339 Node *condition; /* WHERE conditions (raw parser) */
2322 List *targetList; /* INSERT/UPDATE targetlist */2340 List *targetList; /* INSERT/UPDATE targetlist */
2341+ OverridingKind override; /* OVERRIDING clause */
2323 /* the following members are only useful for INSERT action */2342 /* the following members are only useful for INSERT action */
2324 List *cols; /* optional: names of the target columns */2343 List *cols; /* optional: names of the target columns */
2325 List *values; /* VALUES to INSERT, or NULL */2344 List *values; /* VALUES to INSERT, or NULL */
@@ -2334,6 +2353,7 @@ typedef struct MergeAction {
2334 Node *qual; /* transformed WHERE conditions */2353 Node *qual; /* transformed WHERE conditions */
2335 CmdType commandType; /* INSERT/UPDATE/DELETE */2354 CmdType commandType; /* INSERT/UPDATE/DELETE */
2336 List *targetList; /* the target list (of ResTarget) */2355 List *targetList; /* the target list (of ResTarget) */
2356+ OverridingKind override; /* OVERRIDING clause */
2337 /*2357 /*
2338 * the replaced targetlist after simple subquery pullup. In stream plan,2358 * the replaced targetlist after simple subquery pullup. In stream plan,
2339 * we don't do the replacement to targetlist and quals, but this pulluped2359 * we don't do the replacement to targetlist and quals, but this pulluped
@@ -239,6 +239,19 @@ typedef struct Const {
239 Cursor_Data cursor_data;239 Cursor_Data cursor_data;
240} Const;240} Const;
241 241 
242+/*
243+ * NextValueExpr - get next value from sequence
244+ *
245+ * This has the same effect as calling the nextval() function, but it does not
246+ * check permissions on the sequence. This is used for identity columns,
247+ * where the sequence is an implicit dependency without its own permissions.
248+ */
249+typedef struct NextValueExpr {
250+ Expr xpr;
251+ Oid seqid;
252+ Oid typeId;
253+} NextValueExpr;
254+ 
242/* ----------------255/* ----------------
243 * Param256 * Param
244 * paramkind - specifies the kind of parameter. The possible values257 * paramkind - specifies the kind of parameter. The possible values
@@ -476,6 +476,7 @@ PG_KEYWORD("outfile", OUTFILE, UNRESERVED_KEYWORD)
476PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD)476PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD)
477PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD)477PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD)
478PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD)478PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD)
479+PG_KEYWORD("overriding", OVERRIDING, UNRESERVED_KEYWORD)
479PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD)480PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD)
480PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD)481PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD)
481PG_KEYWORD("package", PACKAGE, UNRESERVED_KEYWORD)482PG_KEYWORD("package", PACKAGE, UNRESERVED_KEYWORD)