已关闭
[Feat] code of pg identity as identity #9227
XXXCA创建于 5月6日关闭于 7月23日
[Feat] code of pg identity as identity #9227
已关闭
共 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 DEBUG | 2383 | #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 | ||
| 1249 | int get_is_hidden(Oid rel_oid, char* colname) | 1235 | int get_is_hidden(Oid rel_oid, char* colname) |
| @@ -28,7 +28,7 @@ | |||
| 28 | */ | 28 | */ |
| 29 | %type <list> tsql_stmtmulti | 29 | %type <list> tsql_stmtmulti |
| 30 | 30 | ||
| 31 | -%type <list> identity_seed_increment | 31 | +%type <list> identity_seed_increment identity_seq_options |
| 32 | %type <node> DBCCCheckIdentStmt DBCCStmt tsql_stmt tsql_CreateProcedureStmt tsql_IndexStmt tsql_TransactionStmt tsql_InsertStmt | 32 | %type <node> DBCCCheckIdentStmt DBCCStmt tsql_stmt tsql_CreateProcedureStmt tsql_IndexStmt tsql_TransactionStmt tsql_InsertStmt |
| 33 | %type <node> tsql_UseStmt | 33 | %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_PERCENT | 34 | %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: { | |||
| 646 | ColConstraintElem: IDENTITY_P identity_seed_increment | 646 | ColConstraintElem: 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 | + | ||
| 781 | rotate_clause: | 791 | rotate_clause: |
| 782 | ROTATE '(' func_application_list rotate_for_clause rotate_in_clause ')' alias_clause %prec ROTATE | 792 | 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_P | 2147 | | OUTER_P |
| 2138 | | OUTFILE | 2148 | | OUTFILE |
| 2139 | | OVERLAY | 2149 | | OVERLAY |
| 2150 | + | OVERRIDING | ||
| 2140 | | OWNED | 2151 | | OWNED |
| 2141 | | OWNER | 2152 | | OWNER |
| 2142 | | PACKAGE | 2153 | | PACKAGE |
| @@ -2402,7 +2413,7 @@ direct_label_keyword: ABORT_P | |||
| 2402 | | UNTIL | 2413 | | UNTIL |
| 2403 | | UNUSABLE | 2414 | | UNUSABLE |
| 2404 | | UPDATE | 2415 | | UPDATE |
| 2405 | - | TSQL_UPDLOCK | 2416 | + | TSQL_UPDLOCK |
| 2406 | | USE_P | 2417 | | USE_P |
| 2407 | | USEEOF | 2418 | | USEEOF |
| 2408 | | USER | 2419 | | USER |
| @@ -3402,19 +3413,36 @@ tsql_UnsignedNumericOnly: Iconst { $$ = makeInteger($1); } | |||
| 3402 | | FCONST { $$ = makeFloat($1); } | 3413 | | FCONST { $$ = makeFloat($1); } |
| 3403 | 3414 | ||
| 3404 | 3415 | ||
| 3405 | - | ||
| 3406 | alter_table_cmd: | 3416 | alter_table_cmd: |
| 3407 | - TSQL_CONVERT TO convert_charset opt_collate | 3417 | + 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() arguments | 3448 | /* DATEDIFF() arguments |
| @@ -519,6 +519,7 @@ PG_KEYWORD("output", TSQL_OUTPUT, UNRESERVED_KEYWORD, DIRECT_LABEL) | |||
| 519 | PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD, AS_LABEL) | 519 | PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD, AS_LABEL) |
| 520 | PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) | 520 | PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) |
| 521 | PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD, DIRECT_LABEL) | 521 | PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD, DIRECT_LABEL) |
| 522 | +PG_KEYWORD("overriding", OVERRIDING, UNRESERVED_KEYWORD, DIRECT_LABEL) | ||
| 522 | PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD, DIRECT_LABEL) | 523 | PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD, DIRECT_LABEL) |
| 523 | PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD, DIRECT_LABEL) | 524 | PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD, DIRECT_LABEL) |
| 524 | PG_KEYWORD("package", PACKAGE, UNRESERVED_KEYWORD, DIRECT_LABEL) | 525 | PG_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 | else | 9243 | 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 to | 208 | * Convert a string value to an SQL string literal and append it to |
| 183 | * the given buffer. We assume the specified client_encoding and | 209 | * 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_NODES | 1849 | #ifndef ENABLE_MULTIPLE_NODES |
| 1801 | bool SetUppercaseAttributeNameToOff(PGconn* conn) | 1850 | bool SetUppercaseAttributeNameToOff(PGconn* conn) |
| 1802 | { | 1851 | { |
| @@ -98,6 +98,7 @@ extern char* binary_upgrade_newowner; | |||
| 98 | 98 | ||
| 99 | extern void init_parallel_dump_utils(void); | 99 | extern void init_parallel_dump_utils(void); |
| 100 | extern const char* fmtId(const char* identifier); | 100 | extern const char* fmtId(const char* identifier); |
| 101 | +extern const char* fmtQualifiedId(const char* schema, const char* id); | ||
| 101 | extern void appendStringLiteral(PQExpBuffer buf, const char* str, int encoding, bool std_strings); | 102 | extern void appendStringLiteral(PQExpBuffer buf, const char* str, int encoding, bool std_strings); |
| 102 | extern void appendStringLiteralConn(PQExpBuffer buf, const char* str, PGconn* conn); | 103 | extern void appendStringLiteralConn(PQExpBuffer buf, const char* str, PGconn* conn); |
| 103 | extern void appendStringLiteralDQ(PQExpBuffer buf, const char* str, const char* dqprefix); | 104 | extern void appendStringLiteralDQ(PQExpBuffer buf, const char* str, const char* dqprefix); |
| @@ -136,6 +137,7 @@ extern bool IsDir(const char* dirpath); | |||
| 136 | extern char* make_absolute_path(const char* path); | 137 | extern char* make_absolute_path(const char* path); |
| 137 | extern bool isExistsSQLResult(PGconn* conn, const char* sqlCmd); | 138 | extern bool isExistsSQLResult(PGconn* conn, const char* sqlCmd); |
| 138 | extern bool is_column_exists(PGconn* conn, Oid relid, const char* column_name); | 139 | extern 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_NODES | 141 | #ifndef ENABLE_MULTIPLE_NODES |
| 140 | extern bool SetUppercaseAttributeNameToOff(PGconn* conn); | 142 | extern bool SetUppercaseAttributeNameToOff(PGconn* conn); |
| 141 | #endif | 143 | #endif |
| @@ -147,34 +147,8 @@ static void ShutdownWorkersHard(ParallelStateN* pstate); | |||
| 147 | static void WaitForTerminatingWorkers(ParallelStateN* pstate); | 147 | static void WaitForTerminatingWorkers(ParallelStateN* pstate); |
| 148 | static void sigTermHandler(SIGNAL_ARGS); | 148 | static void sigTermHandler(SIGNAL_ARGS); |
| 149 | static void setup_cancel_handler(void); | 149 | static void setup_cancel_handler(void); |
| 150 | -static const char* fmtQualifiedId(const char* schema, const char* id); | ||
| 151 | static void archive_close_connection(int code, void* arg); | 150 | static 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 | #endif | 1704 | #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_CE | 1760 | #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 | #endif | 1778 | #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, composite | 1789 | * 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_CE | 1938 | #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 | #else | 1950 | #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_CE | 1986 | #ifdef HAVE_CE |
| 1964 | unsigned char *plaintext = NULL; | 1987 | unsigned char *plaintext = NULL; |
| 1965 | #endif | 1988 | #endif |
| 1966 | - if (strlen(default_value) != 0) { | 1989 | + if (strlen(defaultValue) != 0) { |
| 1967 | #ifdef HAVE_CE | 1990 | #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 | #endif | 2002 | #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_CE | 2050 | #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_CE | 2081 | + 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.h | 2106 | * 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 | * printACLColumn | 5486 | * 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 any | 5489 | + * The proper targetlist entry is appended to buf. Note lack of any |
| 5451 | * whitespace or comma decoration. | 5490 | * whitespace or comma decoration. |
| 5452 | */ | 5491 | */ |
| 5453 | static void printACLColumn(PQExpBuffer buf, const char* colname) | 5492 | static 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", NULL | 1168 | + "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 relation | 232 | // 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_attribute | 393 | # 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_attribute | 429 | # 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 when | 973 | * 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 | - * AddNewAttributeTuples | 1069 | + * AddNewAttributeTuples |
| 1061 | * | 1070 | * |
| 1062 | - * this registers the new relation's schema by adding | 1071 | + * this registers the new relation's schema by adding |
| 1063 | - * tuples to pg_attribute. | 1072 | + * tuples to pg_attribute. |
| 1064 | * -------------------------------- | 1073 | * -------------------------------- |
| 1065 | */ | 1074 | */ |
| 1066 | static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relkind, | 1075 | static 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 dependencies | 1117 | * 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 conflict | 3503 | * 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 bulkload | 3710 | * Remove error info table file for bulkload |
| 3665 | * there are problems in a rollback transaction | 3711 | * 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 null | 792 | ELSE null |
| 784 | END | 793 | 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.attnum | 812 | + 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 c | 1649 | FROM pg_namespace nc, pg_class c |
| 1640 | WHERE c.relnamespace = nc.oid | 1650 | 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 column | 709 | * 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 the | 711 | + * 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 column | 712 | * 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 should | 716 | * 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 be | 962 | * 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 indexes | 963 | * 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_index | 987 | * get_constraint_index |
| 809 | - * Given the OID of a unique or primary-key constraint, return the | 988 | + * 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 the | 991 | * 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 | |||
| 200 | F191 Referential delete actions YES | 200 | F191 Referential delete actions YES |
| 201 | F200 TRUNCATE TABLE statement YES | 201 | F200 TRUNCATE TABLE statement YES |
| 202 | F201 CAST function YES | 202 | F201 CAST function YES |
| 203 | -F202 TRUNCATE TABLE: identity column restart option NO | 203 | +F202 TRUNCATE TABLE: identity column restart option YES |
| 204 | F221 Explicit defaults YES | 204 | F221 Explicit defaults YES |
| 205 | F222 INSERT statement: DEFAULT VALUES clause YES | 205 | F222 INSERT statement: DEFAULT VALUES clause YES |
| 206 | F231 Privilege tables YES | 206 | F231 Privilege tables YES |
| @@ -241,9 +241,9 @@ F381 Extended schema manipulation 02 ALTER TABLE statement: ADD CONSTRAINT claus | |||
| 241 | F381 Extended schema manipulation 03 ALTER TABLE statement: DROP CONSTRAINT clause YES | 241 | F381 Extended schema manipulation 03 ALTER TABLE statement: DROP CONSTRAINT clause YES |
| 242 | F382 Alter column data type YES | 242 | F382 Alter column data type YES |
| 243 | F383 Set column not null clause YES | 243 | F383 Set column not null clause YES |
| 244 | -F384 Drop identity property clause NO | 244 | +F384 Drop identity property clause YES |
| 245 | F385 Drop column generation expression clause NO | 245 | F385 Drop column generation expression clause NO |
| 246 | -F386 Set identity column generation clause NO | 246 | +F386 Set identity column generation clause YES |
| 247 | F391 Long identifiers YES | 247 | F391 Long identifiers YES |
| 248 | F392 Unicode escapes in identifiers YES | 248 | F392 Unicode escapes in identifiers YES |
| 249 | F393 Unicode escapes in literals YES | 249 | F393 Unicode escapes in literals YES |
| @@ -420,11 +420,11 @@ T152 DISTINCT predicate with negation YES | |||
| 420 | T171 LIKE clause in table definition YES | 420 | T171 LIKE clause in table definition YES |
| 421 | T172 AS subquery clause in table definition YES | 421 | T172 AS subquery clause in table definition YES |
| 422 | T173 Extended LIKE clause in table definition YES | 422 | T173 Extended LIKE clause in table definition YES |
| 423 | -T174 Identity columns NO | 423 | +T174 Identity columns YES |
| 424 | T175 Generated columns NO | 424 | T175 Generated columns NO |
| 425 | T176 Sequence generator support YES alter sequence is partially supported | 425 | T176 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 |
| 428 | T180 System-versioned tables NO | 428 | T180 System-versioned tables NO |
| 429 | T181 Application-time period tables NO | 429 | T181 Application-time period tables NO |
| 430 | T191 Referential action RESTRICT YES | 430 | T191 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 | * _copyTargetEntry | 3594 | * _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 | + | ||
| 766 | static bool _equalTargetEntry(const TargetEntry* a, const TargetEntry* b) | 774 | static 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 PGXC | 2092 | #ifdef PGXC |
| 2082 | COMPARE_SCALAR_FIELD(is_serial); | 2093 | COMPARE_SCALAR_FIELD(is_serial); |
| 2083 | #endif | 2094 | #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 | + | ||
| 3335 | static void _outTargetEntry(StringInfo str, TargetEntry* node) | 3344 | static 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] >= FirstBootstrapObjectId | 6383 | 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 | * _readTargetEntry | 3260 | * _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_cmd | 471 | %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_cmd | 472 | modify_column_cmd reset_partition_cmd modify_partition_cmd |
| 473 | replica_identity add_column_first_after event_from_clause add_column_cmd | 473 | 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_cmds | 474 | +%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_behavior | 476 | %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_list | 482 | opt_pgxcnodes fields_options_list fields_options_fin lines_options_list |
| 483 | %type <defelt> createdb_opt_item alterdb_opt_item copy_opt_item characterset_option | 483 | %type <defelt> createdb_opt_item alterdb_opt_item copy_opt_item characterset_option |
| 484 | transaction_mode_item lines_option_item fields_options_item | 484 | transaction_mode_item lines_option_item fields_options_item |
| 485 | - create_extension_opt_item alter_extension_opt_item | 485 | + create_extension_opt_item alter_extension_opt_item alter_identity_column_option |
| 486 | start_opt preserve_opt rename_opt status_opt comments_opt action_opt | 486 | start_opt preserve_opt rename_opt status_opt comments_opt action_opt |
| 487 | end_opt definer_name_opt | 487 | 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_next | 658 | %type <ival> row_or_rows first_or_next |
| 659 | %type <boolean> opt_percent only_or_ties | 659 | %type <boolean> opt_percent only_or_ties |
| 660 | 660 | ||
| 661 | -%type <list> OptSeqOptList SeqOptList | 661 | +%type <list> OptSeqOptList SeqOptList OptParenthesizedSeqOptList |
| 662 | %type <boolean> ignNulls fromLast | 662 | %type <boolean> ignNulls fromLast |
| 663 | %type <defelt> SeqOptElem | 663 | %type <defelt> SeqOptElem |
| 664 | 664 | ||
| @@ -799,7 +799,8 @@ static bool is_temp_table(const char relpst); | |||
| 799 | %type <boolean> opt_if_not_exists | 799 | %type <boolean> opt_if_not_exists |
| 800 | %type <chr> OptCompress generated_column_option | 800 | %type <chr> OptCompress generated_column_option |
| 801 | %type <ival> KVType | 801 | %type <ival> KVType |
| 802 | -%type <ival> ColCmprsMode | 802 | +%type <ival> ColCmprsMode |
| 803 | +%type <ival> generated_when override_kind | ||
| 803 | %type <fun_src> subprogram_body | 804 | %type <fun_src> subprogram_body |
| 804 | %type <keyword> as_is as_empty | 805 | %type <keyword> as_is as_empty |
| 805 | %type <node> column_item opt_table_partitioning_clause | 806 | %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_item | 810 | range_start_end_item range_less_than_item list_partition_item hash_partition_item |
| 810 | subpartitioning_clause range_subpartitioning_clause hash_subpartitioning_clause | 811 | subpartitioning_clause range_subpartitioning_clause hash_subpartitioning_clause |
| 811 | list_subpartitioning_clause subpartition_item opt_subpartition_index_def | 812 | list_subpartitioning_clause subpartition_item opt_subpartition_index_def |
| 812 | - range_subpartition_index_list range_subpartition_index_item | 813 | + range_subpartition_index_list range_subpartition_index_item |
| 813 | %type <list> range_partition_definition_list list_partition_definition_list hash_partition_definition_list maxValueList listValueList | 814 | %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_list | 815 | 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_list | 816 | 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 NVL | 1001 | 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 OR | 1003 | 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 OUTFILE | 1004 | + 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 POSITION | 1006 | PACKAGE PACKAGES PARALLEL_ENABLE PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PCTFREE PER_P PERCENT PERFORMANCE PERM PLACING PLAN PLANS POLICY POSITION |
| 1006 | PIPELINED | 1007 | 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_cmds | 4072 | + | 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_behavior | 5134 | | 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 | + | ||
| 5640 | opt_drop_behavior: | 5719 | opt_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 ColConstraintElem | 7969 | 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 | #endif | 8452 | #endif |
| 8374 | } | 8453 | } |
| 8375 | - | GENERATED ALWAYS AS '(' a_expr ')' generated_column_option | 8454 | + | GENERATED generated_when AS '(' a_expr ')' generated_column_option |
| 8376 | { | 8455 | { |
| 8377 | #ifdef ENABLE_MULTIPLE_NODES | 8456 | #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 | #endif | 8462 | #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_actions | 8494 | | REFERENCES qualified_name opt_column_list key_match key_actions |
| 8392 | { | 8495 | { |
| 8393 | #ifdef ENABLE_MULTIPLE_NODES | 8496 | #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_P | 8516 | | 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 | + | ||
| 8435 | opt_unique_key: | 8543 | opt_unique_key: |
| 8436 | UNIQUE { $$ = NULL; } | 8544 | UNIQUE { $$ = NULL; } |
| 8437 | | UNIQUE KEY | 8545 | | UNIQUE KEY |
| @@ -8547,6 +8655,7 @@ TableLikeOptionList: | |||
| 8547 | TableLikeIncludingOption: | 8655 | TableLikeIncludingOption: |
| 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: | |||
| 8560 | TableLikeExcludingOption: | 8669 | TableLikeExcludingOption: |
| 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 | + | ||
| 8574 | opt_internal_data: | 8689 | opt_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 NumericOnly | 10643 | | 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 | ||
| 18480 | colid_list: | 18601 | colid_list: |
| 18481 | ColId | 18602 | 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 ')' SelectStmt | 24696 | | '(' 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 VALUES | 24717 | | 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 | + | ||
| 24583 | insert_column_list: | 24734 | insert_column_list: |
| 24584 | insert_column_item | 24735 | insert_column_item |
| 24585 | { $$ = list_make1($1); } | 24736 | { $$ = list_make1($1); } |
| @@ -24759,6 +24910,8 @@ opt_cancelable: CANCELABLE { $$ = T | |||
| 24759 | ; | 24910 | ; |
| 24760 | 24911 | ||
| 24761 | opt_wait: WAIT Iconst { $$ = $2; } | 24912 | opt_wait: WAIT Iconst { $$ = $2; } |
| 24913 | + ; | ||
| 24914 | + | ||
| 24762 | opt_nowait_or_skip: | 24915 | opt_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_clause | 25178 | | 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 VALUES | 25194 | | 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 bjm | 25353 | * 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_limit | 25356 | | 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 | | OPTION | 32875 | | OPTION |
| 32707 | | OPTIONALLY | 32876 | | OPTIONALLY |
| 32708 | | OPTIONS | 32877 | | OPTIONS |
| 32878 | + | OUTFILE | ||
| 32709 | | ORDINALITY | 32879 | | ORDINALITY |
| 32710 | | OVER | 32880 | | OVER |
| 32711 | - | OUTFILE | 32881 | + | OVERRIDING |
| 32712 | | OWNED | 32882 | | OWNED |
| 32713 | | OWNER | 32883 | | OWNER |
| 32714 | | PACKAGE | 32884 | | PACKAGE |
| @@ -33186,7 +33356,7 @@ reserved_keyword: | |||
| 33186 | | REFERENCES | 33356 | | REFERENCES |
| 33187 | | REJECT_P | 33357 | | REJECT_P |
| 33188 | | RETURNING | 33358 | | RETURNING |
| 33189 | - | ROWNUM | 33359 | + | ROWNUM |
| 33190 | | SHARE_MEMORY | 33360 | | SHARE_MEMORY |
| 33191 | | SELECT | 33361 | | SELECT |
| 33192 | | SESSION_USER | 33362 | | 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); | |||
| 133 | extern Datum GetDatumFromString(Oid typeOid, int4 typeMod, char* value); | 133 | extern Datum GetDatumFromString(Oid typeOid, int4 typeMod, char* value); |
| 134 | extern Const* makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, | 134 | extern 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 | ||
| 138 | static bool IsScanUseDesthint(void* val1, void* val2); | 137 | static 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 the | 1165 | * 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 { | |||
| 3067 | static ColVersionMap col_version_maps[] = { | 3067 | static 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 attribute | 3799 | * 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 | */ |
| 3802 | Oid attnumCollationId(Relation rd, int attid) | 3803 | Oid 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 | - | ||
| 918 | static List* checkRelationInsertTargets(ParseState* pstate, List* cols, List** attrnos) | 906 | static 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 allow | 981 | * 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); | |||
| 85 | static AclMode convert_cmk_priv_string(text *priv_type_text); | 85 | static AclMode convert_cmk_priv_string(text *priv_type_text); |
| 86 | static AclMode convert_cek_priv_string(text *priv_type_text); | 86 | static 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 | + | ||
| 88 | const struct AclAction { | 116 | const 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 | ||
| 227 | static void GetValueAccordingToTheType(cJSON* root, int index, char* key, Datum rawData) | 255 | static 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 | - | ||
| 1853 | static bool numeric_is_less(Numeric a, Numeric b) | 1846 | static 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 | + | ||
| 3285 | Datum numeric_pg_lsn(PG_FUNCTION_ARGS) | 3301 | Datum 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_sequence | 4587 | * 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 parameter | 4590 | * 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) | |||
| 805 | char* get_attname(Oid relid, AttrNumber attnum, bool allowDropped) | 805 | char* 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_kvtype | 825 | + * 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) | |||
| 872 | AttrNumber get_attnum(Oid relid, const char* attname) | 877 | AttrNumber 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 | |||
| 345 | 42P21 E ERRCODE_COLLATION_MISMATCH collation_mismatch | 345 | 42P21 E ERRCODE_COLLATION_MISMATCH collation_mismatch |
| 346 | 42P22 E ERRCODE_INDETERMINATE_COLLATION indeterminate_collation | 346 | 42P22 E ERRCODE_INDETERMINATE_COLLATION indeterminate_collation |
| 347 | 42809 E ERRCODE_WRONG_OBJECT_TYPE wrong_object_type | 347 | 42809 E ERRCODE_WRONG_OBJECT_TYPE wrong_object_type |
| 348 | +428C9 E ERRCODE_GENERATED_ALWAYS generated_always | ||
| 348 | 42P23 E ERRCODE_PARTITION_ERROR partition_error | 349 | 42P23 E ERRCODE_PARTITION_ERROR partition_error |
| 349 | 42P24 E ERRCODE_INVALID_ATTRIBUTE invalid_attribute | 350 | 42P24 E ERRCODE_INVALID_ATTRIBUTE invalid_attribute |
| 350 | 42P25 E ERRCODE_INVALID_AGG invalid_agg | 351 | 42P25 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 FEATURE | 83 | * 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; | ||
| 86 | const uint32 SUPPORT_CREATE_ACCESS_METHOD_VERSION_NUM = 93094; | 87 | const uint32 SUPPORT_CREATE_ACCESS_METHOD_VERSION_NUM = 93094; |
| 87 | const uint32 NEON_VERSION_NUM = 93090; | 88 | const uint32 NEON_VERSION_NUM = 93090; |
| 88 | const uint32 WITH_ORDINALITY_VERSION_NUM = 93089; | 89 | const uint32 WITH_ORDINALITY_VERSION_NUM = 93089; |
| @@ -96,7 +97,7 @@ const uint32 UPGRADE_SHARK_3_0_VERSION_NUM = 93070; | |||
| 96 | const uint32 PGSTAT_LAST_SCAN_VERSION_NUM = 93065; | 97 | const uint32 PGSTAT_LAST_SCAN_VERSION_NUM = 93065; |
| 97 | const uint32 INLINEVIEW_DML_VERSION_NUM = 93063; | 98 | const uint32 INLINEVIEW_DML_VERSION_NUM = 93063; |
| 98 | const uint32 HALFVEC_VERSION_NUM = 93060; | 99 | const uint32 HALFVEC_VERSION_NUM = 93060; |
| 99 | -const uint32 IDENTITY_VERSION_NUM = 93059; | 100 | +const uint32 D_IDENTITY_VERSION_NUM = 93059; |
| 100 | const uint32 DISKANN_INDEX = 93058; | 101 | const uint32 DISKANN_INDEX = 93058; |
| 101 | const uint32 INSTR_TRACE_VERSION_NUMBER = 93053; | 102 | const uint32 INSTR_TRACE_VERSION_NUMBER = 93053; |
| 102 | const uint32 SELECT_STMT_HAS_ROTATE = 93047; | 103 | const uint32 SELECT_STMT_HAS_ROTATE = 93047; |
| @@ -398,7 +398,6 @@ extern THR_LOCAL bool stmt_contains_operator_plus; | |||
| 398 | %type <str> character | 398 | %type <str> character |
| 399 | %type <str> character_national | 399 | %type <str> character_national |
| 400 | %type <str> extract_arg | 400 | %type <str> extract_arg |
| 401 | -%type <str> opt_charset | ||
| 402 | %type <boolean> opt_varying opt_timezone opt_no_inherit | 401 | %type <boolean> opt_varying opt_timezone opt_no_inherit |
| 403 | 402 | ||
| 404 | %type <ival> Iconst SignedIconst | 403 | %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_subexpr | 430 | %type <node> func_application func_expr_common_subexpr |
| 432 | %type <node> common_table_expr | 431 | %type <node> common_table_expr |
| 433 | -%type <keep> keep_clause | ||
| 434 | %type <with> with_clause opt_with_clause | 432 | %type <with> with_clause opt_with_clause |
| 435 | %type <list> cte_list | 433 | %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 NVL | 578 | 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 OR | 580 | 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 OUTFILE | 581 | + 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 POSITION | 583 | PACKAGE PACKAGES PARALLEL_ENABLE PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PCTFREE PER_P PERCENT PERFORMANCE PERM PLACING PLAN PLANS POLICY POSITION |
| 586 | PIPELINED | 584 | 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 types | 9104 | * SQL92 date/time types |
| 9112 | */ | 9105 | */ |
| @@ -12190,6 +12183,7 @@ unreserved_keyword: | |||
| 12190 | | OPTIONALLY | 12183 | | OPTIONALLY |
| 12191 | | OPTIONS | 12184 | | OPTIONS |
| 12192 | | ORDINALITY | 12185 | | ORDINALITY |
| 12186 | + | OVERRIDING | ||
| 12193 | | OWNED | 12187 | | OWNED |
| 12194 | | OWNER | 12188 | | OWNER |
| 12195 | | OUTFILE | 12189 | | OUTFILE |
| @@ -375,7 +375,7 @@ static void append_array_varchar_delete(StringInfo sqlBuf); | |||
| 375 | %type <plnode> assign_el | 375 | %type <plnode> assign_el |
| 376 | %type <declhdr> decl_sect | 376 | %type <declhdr> decl_sect |
| 377 | %type <varname> decl_varname declare_condname | 377 | %type <varname> decl_varname declare_condname |
| 378 | -%type <list> decl_varname_list opt_subtype_range | 378 | +%type <list> decl_varname_list |
| 379 | %type <boolean> decl_const decl_notnull exit_type | 379 | %type <boolean> decl_const decl_notnull exit_type |
| 380 | %type <expr> decl_defval decl_rec_defval decl_cursor_query | 380 | %type <expr> decl_defval decl_rec_defval decl_cursor_query |
| 381 | %type <dtype> decl_datatype opt_cursor_returntype subtype_base_type | 381 | %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 | ||
| 2336 | record_attr_list : record_attr | 2333 | record_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 | else | 9008 | 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 or | 1562 | * 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 catalog | 1747 | * 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 | else | 1697 | 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 | ||
| 182 | static ObjTree* deparse_ColumnDef(Relation relation, List *dpcontext, bool composite, | 182 | static 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); | ||
| 184 | static ObjTree* deparse_ColumnSetOptions(AlterTableCmd *subcmd); | 186 | static ObjTree* deparse_ColumnSetOptions(AlterTableCmd *subcmd); |
| 185 | 187 | ||
| 186 | static ObjTree* deparse_DefElem(DefElem *elem, bool is_reset); | 188 | static ObjTree* deparse_DefElem(DefElem *elem, bool is_reset); |
| @@ -194,6 +196,7 @@ static List* get_range_partition_maxvalues(List *boundary); | |||
| 194 | static List* get_list_partition_maxvalues(List *boundary); | 196 | static List* get_list_partition_maxvalues(List *boundary); |
| 195 | static ObjTree* deparse_RelSetOptions(AlterTableCmd *subcmd); | 197 | static ObjTree* deparse_RelSetOptions(AlterTableCmd *subcmd); |
| 196 | 198 | ||
| 199 | +static inline ObjElem* deparse_Seq_SeqName(sequence_values *seqdata, bool alter_table); | ||
| 197 | static inline ObjElem* deparse_Seq_Cache(sequence_values *seqdata, bool alter_table); | 200 | static inline ObjElem* deparse_Seq_Cache(sequence_values *seqdata, bool alter_table); |
| 198 | static inline ObjElem* deparse_Seq_Cycle(sequence_values *seqdata, bool alter_table); | 201 | static inline ObjElem* deparse_Seq_Cycle(sequence_values *seqdata, bool alter_table); |
| 199 | static inline ObjElem* deparse_Seq_IncrementBy(sequence_values *seqdata, bool alter_table); | 202 | static 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 DefElems | 2004 | * 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 the | 195 | * 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 | ||
| 4000 | static void checkAllowAlter(HeapTuple tup) { | 4000 | static 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 PGXC | 77 | #ifdef PGXC |
| 78 | template<typename T_Form, typename T_Int, bool large> | 78 | template<typename T_Form, typename T_Int, bool large> |
| 79 | static void init_params(List* options, bool isInit, bool isUseLocalSeq, void* newm_p, List** owned_by, | 79 | static 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 | #else | 81 | #else |
| 82 | static void init_params(List* options, bool isInit, bool isUseLocalSeq, void* newm_p, List** owned_by, | 82 | static 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 | #endif | 84 | #endif |
| 85 | template<typename T_Form, typename T_Int, bool large> | 85 | template<typename T_Form, typename T_Int, bool large> |
| 86 | static void do_setval(Oid relid, int128 next, bool iscalled, bool skip_perm_check = false); | 86 | static 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); |
| 88 | template<typename T_Form> | 88 | template<typename T_Form> |
| 89 | static GTM_UUID get_uuid_from_tuple(const void* seq_p, const Relation rel, const HeapTuple seqtuple); | 89 | static GTM_UUID get_uuid_from_tuple(const void* seq_p, const Relation rel, const HeapTuple seqtuple); |
| 90 | extern Oid searchSeqidFromExpr(Node* cooked_default); | 90 | extern 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 | else | 772 | 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) | |||
| 972 | static ExecNodes* GetSequenceNodes(RangeVar* sequence, bool missing_ok) | 973 | static 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 | #endif | 5425 | #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 foreign | 2742 | * 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 | -void | 2745 | +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 | */ |
| 2743 | void | 2800 | void |
| 2744 | ExecEvalRowNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext) | 2801 | ExecEvalRowNull(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) | |||
| 2752 | void | 2809 | void |
| 2753 | ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext) | 2810 | ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, ExprContext *econtext) |
| 2754 | { | 2811 | { |
| 2755 | - ExecEvalRowNullInt(state, op, econtext, false); | 2812 | + ExecEvalRowNullInt(state, op, econtext, false); |
| 2756 | } | 2813 | } |
| 2757 | 2814 | ||
| 2758 | void ExecEvalNan(ExprState *state, ExprEvalStep *op, ExprContext *econtext) | 2815 | void 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 | ||
| 2763 | void ExecEvalNotNan(ExprState *state, ExprEvalStep *op, ExprContext *econtext) | 2820 | void 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( | |||
| 149 | static Datum ExecEvalCoerceViaIO(CoerceViaIOState* iostate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone); | 151 | static Datum ExecEvalCoerceViaIO(CoerceViaIOState* iostate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone); |
| 150 | static Datum ExecEvalArrayCoerceExpr( | 152 | static 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); | ||
| 152 | static Datum ExecEvalCurrentOfExpr(ExprState* exprstate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone); | 155 | static Datum ExecEvalCurrentOfExpr(ExprState* exprstate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone); |
| 153 | static Datum ExecEvalGroupingFuncExpr( | 156 | static 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 | -* ExecEvalCurrentOfExpr | 5858 | +* 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 | * ExecEvalPrefixText | 5930 | * 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 | - | ||
| 785 | static SWDfsOpState* InitSWDfsOpState() | 779 | static 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 | + | ||
| 293 | char GetGeneratedCol(TupleDesc tupdesc, int atti) | 310 | char 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 | ||
| 1061 | int UpgradeAdaptAttr(Oid atttypid, ColumnDef *entry) | 1083 | int 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 in | 1125 | * 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 descriptor | 1145 | * 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 | |||
| 179 | extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc); | 179 | extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc); |
| 180 | extern TupleDesc CreateTupleDescCopyExtend(TupleDesc tupdesc, int moreatts); | 180 | extern TupleDesc CreateTupleDescCopyExtend(TupleDesc tupdesc, int moreatts); |
| 181 | extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc); | 181 | extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc); |
| 182 | +extern Form_pg_attribute_extra CreatePGAttributeExtra(TupleDesc tupdesc); | ||
| 182 | 183 | ||
| 183 | extern void FreeTupleDesc(TupleDesc tupdesc, bool need_check = true); | 184 | extern void FreeTupleDesc(TupleDesc tupdesc, bool need_check = true); |
| 184 | 185 | ||
| @@ -209,13 +210,15 @@ extern void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attribute_num | |||
| 209 | extern void VerifyAttrCompressMode(int8 mode, int attlen, const char* attname); | 210 | extern void VerifyAttrCompressMode(int8 mode, int attlen, const char* attname); |
| 210 | 211 | ||
| 211 | extern TupleDesc BuildDescForRelation(List* schema, Node* oriented_from = NULL, char relkind = '\0', | 212 | extern 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 | ||
| 214 | extern TupleDesc BuildDescFromLists(List* names, List* types, List* typmods, List* collations); | 215 | extern TupleDesc BuildDescFromLists(List* names, List* types, List* typmods, List* collations); |
| 215 | 216 | ||
| 216 | extern bool tupledesc_have_pck(TupleConstr* constr); | 217 | extern 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 | ||
| 220 | extern char GetGeneratedCol(TupleDesc tupdesc, int atti); | 223 | extern char GetGeneratedCol(TupleDesc tupdesc, int atti); |
| 221 | 224 | ||
| @@ -31,8 +31,8 @@ | |||
| 31 | 31 | ||
| 32 | extern void AlterCStoreCreateTables(Oid relOid, Datum reloptions, CreateStmt *mainTblStmt); | 32 | extern 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); |
| 36 | extern bool createDeltaTableForPartition(Oid relOid, Oid partOid, Datum reloptions, CreateStmt *mainTblStmt); | 36 | extern bool createDeltaTableForPartition(Oid relOid, Oid partOid, Datum reloptions, CreateStmt *mainTblStmt); |
| 37 | extern bool createCUDescTableForPartition(Oid relOid, Oid partOid, Datum reloptions); | 37 | extern bool createCUDescTableForPartition(Oid relOid, Oid partOid, Datum reloptions); |
| 38 | extern Datum AddInternalOption(Datum reloptions, int mask); | 38 | extern Datum AddInternalOption(Datum reloptions, int mask); |
| @@ -328,16 +328,16 @@ extern long changeDependencyFor(Oid classId, | |||
| 328 | extern void changeDependenciesOf(Oid classId, Oid oldObjectId, Oid newObjectId); | 328 | extern void changeDependenciesOf(Oid classId, Oid oldObjectId, Oid newObjectId); |
| 329 | extern void changeDependenciesOn(Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId); | 329 | extern 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 | ||
| 339 | extern Oid get_constraint_index(Oid constraintId); | 340 | extern Oid get_constraint_index(Oid constraintId); |
| 340 | - | ||
| 341 | extern Oid get_index_constraint(Oid indexId); | 341 | extern 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 | ||
| 148 | extern void heap_create_init_fork(Relation rel); | 149 | extern void heap_create_init_fork(Relation rel); |
| 149 | 150 | ||
| @@ -190,7 +191,8 @@ extern void heap_truncate_one_rel(Relation rel); | |||
| 190 | extern void heap_truncate_check_FKs(List *relations, bool tempTables); | 191 | extern void heap_truncate_check_FKs(List *relations, bool tempTables); |
| 191 | extern List *heap_truncate_find_FKs(List *relationIds); | 192 | extern List *heap_truncate_find_FKs(List *relationIds); |
| 192 | extern void InsertTablebucketidAttribute(Oid relOid); | 193 | extern 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 | ||
| 195 | extern void InsertPgClassTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Datum relacl, | 197 | extern 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); | |||
| 208 | extern void RemoveAttributeById(Oid relid, AttrNumber attnum); | 210 | extern void RemoveAttributeById(Oid relid, AttrNumber attnum); |
| 209 | extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, DropBehavior behavior, bool complain, bool internal); | 211 | extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, DropBehavior behavior, bool complain, bool internal); |
| 210 | extern void RemoveAttrDefaultById(Oid attrdefId); | 212 | extern void RemoveAttrDefaultById(Oid attrdefId); |
| 213 | +extern char HeapTupleGetIdentity(HeapTuple tuple, Relation attr); | ||
| 214 | +extern HeapTuple HeapTupleModifyIdentity(HeapTuple tuple, Relation attr, char identtiy); | ||
| 211 | 215 | ||
| 212 | extern void CopyStatistics(Oid fromrelid, Oid torelid, char starelkind); | 216 | extern void CopyStatistics(Oid fromrelid, Oid torelid, char starelkind); |
| 213 | 217 | ||
| @@ -220,7 +224,8 @@ extern Form_pg_attribute SystemAttributeByName(const char *attname, bool relhaso | |||
| 220 | extern int GetSysAttLength(bool hasBucketAttr = true); | 224 | extern int GetSysAttLength(bool hasBucketAttr = true); |
| 221 | 225 | ||
| 222 | extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, bool allow_system_table_mods); | 226 | extern 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 PGXC | 230 | #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 with | 197 | * 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 | */ |
| 197 | typedef FormData_pg_attribute *Form_pg_attribute; | 201 | typedef 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_attribute | 212 | * compiler constants for pg_attribute |
| 201 | * ---------------- | 213 | * ---------------- |
| 202 | */ | 214 | */ |
| 203 | -#define Natts_pg_attribute 25 | 215 | +#define Natts_pg_attribute 26 |
| 204 | #define Anum_pg_attribute_attrelid 1 | 216 | #define Anum_pg_attribute_attrelid 1 |
| 205 | #define Anum_pg_attribute_attname 2 | 217 | #define Anum_pg_attribute_attname 2 |
| 206 | #define Anum_pg_attribute_atttypid 3 | 218 | #define Anum_pg_attribute_atttypid 3 |
| @@ -226,6 +238,7 @@ typedef FormData_pg_attribute *Form_pg_attribute; | |||
| 226 | #define Anum_pg_attribute_attinitdefval 23 | 238 | #define Anum_pg_attribute_attinitdefval 23 |
| 227 | #define Anum_pg_attribute_attkvtype 24 | 239 | #define Anum_pg_attribute_attkvtype 24 |
| 228 | #define Anum_pg_attribute_attdroppedname 25 | 240 | #define Anum_pg_attribute_attdroppedname 25 |
| 241 | +#define Anum_pg_attribute_attidentity 26 | ||
| 229 | 242 | ||
| 230 | /* ---------------- | 243 | /* ---------------- |
| 231 | * initial contents of pg_attribute | 244 | * 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 26 | 124 | #define Anum_pg_authid_rolpolicyadmin 26 |
| 125 | #define Anum_pg_authid_rolpasswordext 27 | 125 | #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_authid | 128 | * initial contents of pg_authid |
| 157 | * | 129 | * |
| @@ -163,7 +163,7 @@ typedef FormData_pg_class* Form_pg_class; | |||
| 163 | */ | 163 | */ |
| 164 | DATA(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)); | 164 | DATA(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)); |
| 165 | DESCR(""); | 165 | DESCR(""); |
| 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)); |
| 167 | DESCR(""); | 167 | DESCR(""); |
| 168 | DATA(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)); | 168 | DATA(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)); |
| 169 | DESCR(""); | 169 | DESCR(""); |
Asrc/include/catalog/upgrade_sql/rollback_catalog_maindb/rollback-post_catalog_maindb_93_101.sql+40-0
| @@ -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'; | ||
Asrc/include/catalog/upgrade_sql/rollback_catalog_otherdb/rollback-post_catalog_otherdb_93_101.sql+40-0
| @@ -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'; | ||
Asrc/include/catalog/upgrade_sql/upgrade_catalog_otherdb/upgrade-post_catalog_otherdb_93_101.sql+41-0
| @@ -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); | |||
| 191 | extern char* defGetString(DefElem* def); | 191 | extern char* defGetString(DefElem* def); |
| 192 | extern double defGetNumeric(DefElem* def); | 192 | extern double defGetNumeric(DefElem* def); |
| 193 | extern bool defGetBoolean(DefElem* def); | 193 | extern bool defGetBoolean(DefElem* def); |
| 194 | -extern int defGetMixdInt(DefElem *def); | 194 | +extern int defGetMixdBoolean(DefElem *def); |
| 195 | +extern int32 defGetInt32(DefElem* def); | ||
| 195 | extern int64 defGetInt64(DefElem* def); | 196 | extern int64 defGetInt64(DefElem* def); |
| 196 | extern List* defGetQualifiedName(DefElem* def); | 197 | extern List* defGetQualifiedName(DefElem* def); |
| 197 | extern TypeName* defGetTypeName(DefElem* def); | 198 | extern TypeName* defGetTypeName(DefElem* def); |
| @@ -190,7 +190,7 @@ extern Datum pg_sequence_parameters(PG_FUNCTION_ARGS); | |||
| 190 | extern Datum pg_sequence_all_parameters(PG_FUNCTION_ARGS); | 190 | extern Datum pg_sequence_all_parameters(PG_FUNCTION_ARGS); |
| 191 | extern Datum pg_sequence_last_value(PG_FUNCTION_ARGS); | 191 | extern 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); |
| 194 | extern void autoinc_setval(Oid relid, int128 next, bool iscalled); | 194 | extern void autoinc_setval(Oid relid, int128 next, bool iscalled); |
| 195 | extern int128 autoinc_get_nextval(Oid relid); | 195 | extern int128 autoinc_get_nextval(Oid relid); |
| 196 | extern bool CheckSeqOwnedByAutoInc(Oid seqoid); | 196 | extern bool CheckSeqOwnedByAutoInc(Oid seqoid); |
| @@ -274,7 +274,6 @@ extern SeqTable GetSessSeqElm(Oid relid); | |||
| 274 | extern char* GetGlobalSeqNameForUpdate(Relation seqrel, char** dbname, char** schemaname); | 274 | extern char* GetGlobalSeqNameForUpdate(Relation seqrel, char** dbname, char** schemaname); |
| 275 | extern uint32 RelidGetHash(Oid seq_relid); | 275 | extern uint32 RelidGetHash(Oid seq_relid); |
| 276 | extern SeqTable GetGlobalSeqElm(Oid relid, GlobalSeqInfoHashBucket* bucket); | 276 | extern SeqTable GetGlobalSeqElm(Oid relid, GlobalSeqInfoHashBucket* bucket); |
| 277 | -extern Oid pg_get_serial_sequence_oid(text* tablename, text* columnname, bool find_identity = false); | ||
| 278 | extern bool StrEndWith(const char *str, const char *suffix); | 277 | extern bool StrEndWith(const char *str, const char *suffix); |
| 279 | typedef void (*InvokeNextvalHookType) (Oid relid, int128 val); | 278 | typedef 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 8 | 57 | #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 PGXC | 60 | #ifdef PGXC |
| 62 | #define AT_PASS_DISTRIB 10 /* Redistribution pass */ | 61 | #define AT_PASS_DISTRIB 10 /* Redistribution pass */ |
| 63 | #define AT_COMMENT 11 | 62 | #define AT_COMMENT 11 |
| @@ -314,13 +313,12 @@ extern void spq_btbuild_update_pg_class(Relation heap, Relation index); | |||
| 314 | #endif | 313 | #endif |
| 315 | typedef void (*InvokePreDropColumnHookType) (Relation rel, AttrNumber attnum); | 314 | typedef void (*InvokePreDropColumnHookType) (Relation rel, AttrNumber attnum); |
| 316 | extern bool IsComputedColumn(Oid adrelid, int2 asnum); | 315 | extern 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); | ||
| 323 | extern void UpdateGeneratedColumnIsnull(AlteredTableInfo* tab, bool* isnull, bool has_generated); | 316 | extern 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); | ||
| 324 | extern int128 EvaluateAutoIncrement(Relation rel, TupleDesc desc, AttrNumber attnum, Datum* value, bool* is_null); | 322 | extern int128 EvaluateAutoIncrement(Relation rel, TupleDesc desc, AttrNumber attnum, Datum* value, bool* is_null); |
| 325 | extern bool OnlineDDLCheckSetCompressOptFeasible(Relation rel, List* defList, AlterTableType operation, | 323 | extern 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 staffs | 39 | * Backend version and inplace upgrade staffs |
| 40 | *****************************************************************************/ | 40 | *****************************************************************************/ |
| 41 | +extern const uint32 PG_IDENTITY_VERSION_NUM; | ||
| 41 | extern const uint32 LSG_VERSION_NUM; | 42 | extern const uint32 LSG_VERSION_NUM; |
| 42 | extern const uint32 RABITQ_VERSION_NUM; | 43 | extern const uint32 RABITQ_VERSION_NUM; |
| 43 | extern const uint32 UHEAP_LOCK_VERSION_NUM; | 44 | extern const uint32 UHEAP_LOCK_VERSION_NUM; |
| 44 | extern const uint32 PGSTAT_LAST_SCAN_VERSION_NUM; | 45 | extern const uint32 PGSTAT_LAST_SCAN_VERSION_NUM; |
| 45 | extern const uint32 INLINEVIEW_DML_VERSION_NUM; | 46 | extern const uint32 INLINEVIEW_DML_VERSION_NUM; |
| 46 | -extern const uint32 IDENTITY_VERSION_NUM; | 47 | +extern const uint32 D_IDENTITY_VERSION_NUM; |
| 47 | extern const uint32 COMPUTED_COLUMNS_VERSION_NUMBER; | 48 | extern const uint32 COMPUTED_COLUMNS_VERSION_NUMBER; |
| 48 | extern const uint32 SWCB_OPTIMIZATION_VERSION_NUM; | 49 | extern const uint32 SWCB_OPTIMIZATION_VERSION_NUM; |
| 49 | extern const uint32 SUPPORT_D_FORMAT_DATABASE; | 50 | extern 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 | struct | 590 | struct |
| 584 | { | 591 | { |
| @@ -754,6 +761,7 @@ extern void ExecEvalParamExec(ExprState *state, ExprEvalStep *op, | |||
| 754 | extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, | 761 | extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, |
| 755 | ExprContext *econtext); | 762 | ExprContext *econtext); |
| 756 | extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op); | 763 | extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op); |
| 764 | +extern void ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op); | ||
| 757 | extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op, | 765 | extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op, |
| 758 | ExprContext *econtext); | 766 | ExprContext *econtext); |
| 759 | extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, | 767 | extern 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 | ||
| 1219 | typedef struct AlterSeqStmt { | 1227 | typedef struct AlterSeqStmt { |
| @@ -1226,6 +1234,8 @@ typedef struct AlterSeqStmt { | |||
| 1226 | #endif | 1234 | #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 */ |
| 41 | typedef enum RoleLockType { DO_NOTHING, LOCK_ROLE, UNLOCK_ROLE } RoleLockType; | 41 | typedef 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 one | 52 | * When a command can act on several kinds of objects with only one |
| 45 | * parse structure required, use these constants to designate the | 53 | * 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 | ||
| 991 | typedef enum AlterTableStatProperty { /* Additional Property for AlterTableCmd */ | 1003 | typedef 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_IDENTITY | 1468 | + CONSTR_D_IDENTITY /* identity in D format */ |
| 1453 | } ConstrType; | 1469 | } ConstrType; |
| 1454 | 1470 | ||
| 1455 | typedef struct Constraint { | 1471 | typedef 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) |
| 1521 | typedef enum TableLikeOption { | 1537 | typedef 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 = 0x7FFFFFFF | 1550 | 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 */ |
| 2053 | typedef enum QuerySource { | 2069 | typedef 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 of | 2193 | 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 pulluped | 2359 | * 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 | * Param | 256 | * Param |
| 244 | * paramkind - specifies the kind of parameter. The possible values | 257 | * paramkind - specifies the kind of parameter. The possible values |
| @@ -476,6 +476,7 @@ PG_KEYWORD("outfile", OUTFILE, UNRESERVED_KEYWORD) | |||
| 476 | PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD) | 476 | PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD) |
| 477 | PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD) | 477 | PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD) |
| 478 | PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD) | 478 | PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD) |
| 479 | +PG_KEYWORD("overriding", OVERRIDING, UNRESERVED_KEYWORD) | ||
| 479 | PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD) | 480 | PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD) |
| 480 | PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD) | 481 | PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD) |
| 481 | PG_KEYWORD("package", PACKAGE, UNRESERVED_KEYWORD) | 482 | PG_KEYWORD("package", PACKAGE, UNRESERVED_KEYWORD) |