From a9ccc5de654889997acc55ccceb9d8565575fd2b Mon Sep 17 00:00:00 2001 From: suncan <1006949218@qq.com> Date: Tue, 13 Dec 2022 20:20:22 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E3=80=91server=E4=BB=93=E4=B8=BB?= =?UTF-8?q?=E9=94=AE=EF=BC=8C=E5=94=AF=E4=B8=80=E9=94=AE=E9=80=82=E9=85=8D?= =?UTF-8?q?index=5Foption?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/parser/gram.y | 323 ++++++++++++++++-- src/test/regress/expected/alter_table_000.out | 93 +++++ src/test/regress/expected/create_table.out | 87 +++++ src/test/regress/sql/alter_table_000.sql | 30 ++ src/test/regress/sql/create_table.sql | 24 ++ 5 files changed, 524 insertions(+), 33 deletions(-) diff --git a/src/common/backend/parser/gram.y b/src/common/backend/parser/gram.y index 430591b64..16848a3a2 100644 --- a/src/common/backend/parser/gram.y +++ b/src/common/backend/parser/gram.y @@ -267,6 +267,8 @@ static int GetFillerColIndex(char *filler_col_name, List *col_list); static void RemoveFillerCol(List *filler_list, List *col_list); static int errstate; static void CheckPartitionExpr(Node* expr, int* colCount); +static char* transformIndexOptions(List* list); +static void setAccessMethod(Constraint *n); static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStmt*n); %} @@ -444,7 +446,7 @@ static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStm %type TriggerWhen %type copy_file_name - database_name access_method_clause access_method attr_name + database_name access_method_clause access_method access_method_clause_without_keyword attr_name name namedata_string fdwName cursor_name file_name index_name cluster_index_specification pgxcnode_name pgxcgroup_name resource_pool_name workload_group_name @@ -509,7 +511,8 @@ static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStm /* b compatibility: comment start */ %type opt_index_options index_options opt_table_options table_options opt_column_options column_options -%type index_option table_option column_option +%type index_option table_option column_option table_index_option +%type opt_table_index_options table_index_options %type opt_part_options %type part_options @@ -661,7 +664,7 @@ static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStm %type constraints_set_mode %type OptRelative %type OptGPI -%type OptTableSpace OptConsTableSpace OptTableSpaceOwner LoggingStr size_clause OptMaxSize OptDatafileSize OptReuse OptAuto OptNextStr OptDatanodeName +%type OptTableSpace OptConsTableSpace OptConsTableSpaceWithEmpty OptTableSpaceOwner LoggingStr size_clause OptMaxSize OptDatafileSize OptReuse OptAuto OptNextStr OptDatanodeName %type opt_check_option %type opt_provider security_label @@ -4968,6 +4971,37 @@ index_option: } ; +opt_table_index_options: + /* EMPTY */ { $$ = NIL; } + | table_index_options { $$ = $1; } + ; +table_index_options: + table_index_option + { + BCompatibilityOptionSupportCheck(); + $$ = list_make1($1); + } + | table_index_options table_index_option + { + $$ = lcons($2, $1); + } + ; +table_index_option: + COMMENT opt_equal Sconst + { + CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_INDEX; + n->objname = NIL; + n->objargs = NIL; + n->comment = $3; + $$ = (Node*)n; + } + | USING IDENT + { + $$ = makeStringConst($2, -1); + } + ; + opt_table_options: /* EMPTY */ { $$ = NIL; } | table_options { $$ = $1; } @@ -7135,7 +7169,7 @@ ColConstraintElem: n->location = @1; $$ = (Node *)n; } - | UNIQUE opt_definition OptConsTableSpace InformationalConstraintElem + | UNIQUE opt_definition OptConsTableSpaceWithEmpty InformationalConstraintElem { Constraint *n = makeNode(Constraint); n->contype = CONSTR_UNIQUE; @@ -7147,7 +7181,7 @@ ColConstraintElem: n->inforConstraint = (InformationalConstraint *) $4; $$ = (Node *)n; } - | UNIQUE opt_definition OptConsTableSpace ENABLE_P InformationalConstraintElem + | UNIQUE opt_definition OptConsTableSpaceWithEmpty ENABLE_P InformationalConstraintElem { Constraint *n = makeNode(Constraint); n->contype = CONSTR_UNIQUE; @@ -7159,7 +7193,7 @@ ColConstraintElem: n->inforConstraint = (InformationalConstraint *) $5; $$ = (Node *)n; } - | PRIMARY KEY opt_definition OptConsTableSpace InformationalConstraintElem + | PRIMARY KEY opt_definition OptConsTableSpaceWithEmpty InformationalConstraintElem { Constraint *n = makeNode(Constraint); n->contype = CONSTR_PRIMARY; @@ -7171,7 +7205,7 @@ ColConstraintElem: n->inforConstraint = (InformationalConstraint *) $5; $$ = (Node *)n; } - | PRIMARY KEY opt_definition OptConsTableSpace ENABLE_P InformationalConstraintElem + | PRIMARY KEY opt_definition OptConsTableSpaceWithEmpty ENABLE_P InformationalConstraintElem { Constraint *n = makeNode(Constraint); n->contype = CONSTR_PRIMARY; @@ -7460,7 +7494,7 @@ internal_data_body: { * - thomas 1997-12-03 */ TableConstraint: - CONSTRAINT name ConstraintElem opt_index_options + CONSTRAINT name ConstraintElem { Constraint *n = (Constraint *) $3; Assert(IsA(n, Constraint)); @@ -7468,10 +7502,9 @@ TableConstraint: n->conname = $2; } n->location = @1; - n->constraintOptions = $4; $$ = (Node *) n; } - | CONSTRAINT ConstraintElem opt_index_options + | CONSTRAINT ConstraintElem { #ifdef ENABLE_MULTIPLE_NODES const char* message = "CONSTRAINT without constraint_name is not yet supported in distributed database."; @@ -7484,7 +7517,6 @@ TableConstraint: Constraint *n = (Constraint *) $2; Assert(IsA(n, Constraint)); n->location = @1; - n->constraintOptions = $3; $$ = (Node *) n; } else { const char* message = "CONSTRAINT without constraint_name is supported only in B-format database."; @@ -7497,16 +7529,15 @@ TableConstraint: $$ = NULL;/* not reached */ } } - | ConstraintElem opt_index_options + | ConstraintElem { Constraint *n = (Constraint *) $1; - n->constraintOptions = $2; $$ = (Node *) n; } ; ConstraintElem: - CHECK '(' a_expr ')' ConstraintAttributeSpec + CHECK '(' a_expr ')' ConstraintAttributeSpec opt_index_options { Constraint *n = makeNode(Constraint); n->contype = CONSTR_CHECK; @@ -7516,10 +7547,11 @@ ConstraintElem: processCASbits($5, @5, "CHECK", NULL, NULL, &n->skip_validation, &n->is_no_inherit, yyscanner); + n->constraintOptions = $6; n->initially_valid = !n->skip_validation; $$ = (Node *)n; } - | UNIQUE name access_method_clause '(' constraint_params ')' opt_c_include opt_definition OptConsTableSpace + | UNIQUE name access_method_clause_without_keyword '(' constraint_params ')' opt_c_include opt_definition OptConsTableSpace opt_table_index_options ConstraintAttributeSpec InformationalConstraintElem { #ifdef ENABLE_MULTIPLE_NODES @@ -7549,10 +7581,12 @@ ConstraintElem: n->options = $8; n->indexname = NULL; n->indexspace = $9; - processCASbits($10, @10, "UNIQUE", + n->constraintOptions = $10; + processCASbits($11, @11, "UNIQUE", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); - n->inforConstraint = (InformationalConstraint *) $11; /* informational constraint info */ + n->inforConstraint = (InformationalConstraint *) $12; /* informational constraint info */ + setAccessMethod(n); $$ = (Node *)n; } else { const char* message = "UNIQUE name is supported only in B-format database."; @@ -7566,7 +7600,56 @@ ConstraintElem: } } - | UNIQUE USING access_method '(' constraint_params ')' opt_c_include opt_definition OptConsTableSpace + | UNIQUE name access_method_clause_without_keyword '(' constraint_params ')' opt_c_include opt_definition opt_table_index_options + ConstraintAttributeSpec InformationalConstraintElem + { +#ifdef ENABLE_MULTIPLE_NODES + const char* message = "UNIQUE name is not yet supported in distributed database."; + InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc); + ereport(errstate, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("UNIQUE name is not yet supported in distributed database."))); +#endif + if (u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) { + if (strcasecmp($2, "index") == 0 || strcasecmp($2, "key") == 0) { + const char* message = "index/key cannot be used as unique name."; + InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc); + ereport(errstate, + (errmodule(MOD_PARSER), + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("index/key cannot be used as unique name."), + parser_errposition(@1))); + } + Constraint *n = makeNode(Constraint); + n->contype = CONSTR_UNIQUE; + n->location = @1; + n->conname = $2; + n->access_method = $3; + n->keys = $5; + n->including = $7; + n->options = $8; + n->indexname = NULL; + n->indexspace = NULL; + n->constraintOptions = $9; + processCASbits($10, @10, "UNIQUE", + &n->deferrable, &n->initdeferred, NULL, + NULL, yyscanner); + n->inforConstraint = (InformationalConstraint *) $11; /* informational constraint info */ + setAccessMethod(n); + $$ = (Node *)n; + } else { + const char* message = "UNIQUE name is supported only in B-format database."; + InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc); + ereport(errstate, + (errmodule(MOD_PARSER), + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("UNIQUE name is supported only in B-format database."), + parser_errposition(@1))); + $$ = NULL;/* not reached */ + } + + } + | UNIQUE USING IDENT '(' constraint_params ')' opt_c_include opt_definition OptConsTableSpace opt_table_index_options ConstraintAttributeSpec InformationalConstraintElem { #ifdef ENABLE_MULTIPLE_NODES @@ -7586,10 +7669,12 @@ ConstraintElem: n->options = $8; n->indexname = NULL; n->indexspace = $9; - processCASbits($10, @10, "UNIQUE", + n->constraintOptions = $10; + processCASbits($11, @11, "UNIQUE", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); - n->inforConstraint = (InformationalConstraint *) $11; /* informational constraint info */ + n->inforConstraint = (InformationalConstraint *) $12; /* informational constraint info */ + setAccessMethod(n); $$ = (Node *)n; } else { const char* message = "UNIQUE access_method_clause is supported only in B-format database."; @@ -7602,7 +7687,45 @@ ConstraintElem: $$ = NULL;/* not reached */ } } - | UNIQUE '(' constraint_params ')' opt_c_include opt_definition OptConsTableSpace + | UNIQUE USING IDENT '(' constraint_params ')' opt_c_include opt_definition opt_table_index_options + ConstraintAttributeSpec InformationalConstraintElem + { +#ifdef ENABLE_MULTIPLE_NODES + const char* message = "UNIQUE access_method_clause is not yet supported in distributed database."; + InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc); + ereport(errstate, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("UNIQUE access_method_clause is not yet supported in distributed database."))); +#endif + if (u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) { + Constraint *n = makeNode(Constraint); + n->contype = CONSTR_UNIQUE; + n->location = @1; + n->access_method = $3; + n->keys = $5; + n->including = $7; + n->options = $8; + n->indexname = NULL; + n->indexspace = NULL; + n->constraintOptions = $9; + processCASbits($10, @10, "UNIQUE", + &n->deferrable, &n->initdeferred, NULL, + NULL, yyscanner); + n->inforConstraint = (InformationalConstraint *) $11; /* informational constraint info */ + setAccessMethod(n); + $$ = (Node *)n; + } else { + const char* message = "UNIQUE access_method_clause is supported only in B-format database."; + InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc); + ereport(errstate, + (errmodule(MOD_PARSER), + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("UNIQUE access_method_clause is supported only in B-format database."), + parser_errposition(@1))); + $$ = NULL;/* not reached */ + } + } + | UNIQUE '(' constraint_params ')' opt_c_include opt_definition OptConsTableSpace opt_table_index_options ConstraintAttributeSpec InformationalConstraintElem { Constraint *n = makeNode(Constraint); @@ -7613,13 +7736,34 @@ ConstraintElem: n->options = $6; n->indexname = NULL; n->indexspace = $7; + n->constraintOptions = $8; + processCASbits($9, @9, "UNIQUE", + &n->deferrable, &n->initdeferred, NULL, + NULL, yyscanner); + n->inforConstraint = (InformationalConstraint *) $10; /* informational constraint info */ + setAccessMethod(n); + $$ = (Node *)n; + } + | UNIQUE '(' constraint_params ')' opt_c_include opt_definition opt_table_index_options + ConstraintAttributeSpec InformationalConstraintElem + { + Constraint *n = makeNode(Constraint); + n->contype = CONSTR_UNIQUE; + n->location = @1; + n->keys = $3; + n->including = $5; + n->options = $6; + n->indexname = NULL; + n->indexspace = NULL; + n->constraintOptions = $7; processCASbits($8, @8, "UNIQUE", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); n->inforConstraint = (InformationalConstraint *) $9; /* informational constraint info */ + setAccessMethod(n); $$ = (Node *)n; } - | UNIQUE ExistingIndex ConstraintAttributeSpec InformationalConstraintElem + | UNIQUE ExistingIndex ConstraintAttributeSpec InformationalConstraintElem opt_index_options { Constraint *n = makeNode(Constraint); n->contype = CONSTR_UNIQUE; @@ -7633,9 +7777,10 @@ ConstraintElem: &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); n->inforConstraint = (InformationalConstraint *) $4; /* informational constraint info */ + n->constraintOptions = $5; $$ = (Node *)n; } - | PRIMARY KEY USING access_method '(' constraint_params ')' opt_c_include opt_definition OptConsTableSpace + | PRIMARY KEY USING IDENT '(' constraint_params ')' opt_c_include opt_definition OptConsTableSpace opt_table_index_options ConstraintAttributeSpec InformationalConstraintElem { #ifdef ENABLE_MULTIPLE_NODES @@ -7655,10 +7800,12 @@ ConstraintElem: n->options = $9; n->indexname = NULL; n->indexspace = $10; - processCASbits($11, @11, "PRIMARY KEY", + n->constraintOptions = $11; + processCASbits($12, @12, "PRIMARY KEY", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); - n->inforConstraint = (InformationalConstraint *) $12; /* informational constraint info */ + n->inforConstraint = (InformationalConstraint *) $13; /* informational constraint info */ + setAccessMethod(n); $$ = (Node *)n; } else { const char* message = "PRIMARY KEY USING access_method is supported only in B-format database."; @@ -7671,7 +7818,45 @@ ConstraintElem: $$ = NULL;/* not reached */ } } - | PRIMARY KEY '(' constraint_params ')' opt_c_include opt_definition OptConsTableSpace + | PRIMARY KEY USING IDENT '(' constraint_params ')' opt_c_include opt_definition opt_table_index_options + ConstraintAttributeSpec InformationalConstraintElem + { +#ifdef ENABLE_MULTIPLE_NODES + const char* message = "PRIMARY KEY USING access_method is not yet supported in distributed database."; + InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc); + ereport(errstate, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("PRIMARY KEY USING access_method is not yet supported in distributed database."))); +#endif + if (u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) { + Constraint *n = makeNode(Constraint); + n->contype = CONSTR_PRIMARY; + n->location = @1; + n->access_method = $4; + n->keys = $6; + n->including = $8; + n->options = $9; + n->indexname = NULL; + n->indexspace = NULL; + n->constraintOptions = $10; + processCASbits($11, @11, "PRIMARY KEY", + &n->deferrable, &n->initdeferred, NULL, + NULL, yyscanner); + n->inforConstraint = (InformationalConstraint *) $12; /* informational constraint info */ + setAccessMethod(n); + $$ = (Node *)n; + } else { + const char* message = "PRIMARY KEY USING access_method is supported only in B-format database."; + InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc); + ereport(errstate, + (errmodule(MOD_PARSER), + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("PRIMARY KEY USING access_method is supported only in B-format database."), + parser_errposition(@1))); + $$ = NULL;/* not reached */ + } + } + | PRIMARY KEY '(' constraint_params ')' opt_c_include opt_definition OptConsTableSpace opt_table_index_options ConstraintAttributeSpec InformationalConstraintElem { Constraint *n = makeNode(Constraint); @@ -7682,13 +7867,34 @@ ConstraintElem: n->options = $7; n->indexname = NULL; n->indexspace = $8; + n->constraintOptions = $9; + processCASbits($10, @10, "PRIMARY KEY", + &n->deferrable, &n->initdeferred, NULL, + NULL, yyscanner); + n->inforConstraint = (InformationalConstraint *) $11; /* informational constraint info */ + setAccessMethod(n); + $$ = (Node *)n; + } + | PRIMARY KEY '(' constraint_params ')' opt_c_include opt_definition opt_table_index_options + ConstraintAttributeSpec InformationalConstraintElem + { + Constraint *n = makeNode(Constraint); + n->contype = CONSTR_PRIMARY; + n->location = @1; + n->keys = $4; + n->including = $6; + n->options = $7; + n->indexname = NULL; + n->indexspace = NULL; + n->constraintOptions = $8; processCASbits($9, @9, "PRIMARY KEY", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); n->inforConstraint = (InformationalConstraint *) $10; /* informational constraint info */ + setAccessMethod(n); $$ = (Node *)n; } - | PRIMARY KEY ExistingIndex ConstraintAttributeSpec InformationalConstraintElem + | PRIMARY KEY ExistingIndex ConstraintAttributeSpec InformationalConstraintElem opt_index_options { Constraint *n = makeNode(Constraint); n->contype = CONSTR_PRIMARY; @@ -7702,11 +7908,12 @@ ConstraintElem: &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); n->inforConstraint = (InformationalConstraint*) $5; /* informational constraint info */ + n->constraintOptions = $6; $$ = (Node *)n; } | EXCLUDE access_method_clause '(' ExclusionConstraintList ')' - opt_c_include opt_definition OptConsTableSpace ExclusionWhereClause - ConstraintAttributeSpec + opt_c_include opt_definition OptConsTableSpaceWithEmpty ExclusionWhereClause + ConstraintAttributeSpec opt_index_options { const char* message = "EXCLUDE constraint is not yet supported."; InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc); @@ -7726,10 +7933,11 @@ ConstraintElem: processCASbits($10, @10, "EXCLUDE", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); + n->constraintOptions = $11; $$ = (Node *)n; } | FOREIGN KEY name '(' columnList ')' REFERENCES qualified_name - opt_column_list key_match key_actions ConstraintAttributeSpec + opt_column_list key_match key_actions ConstraintAttributeSpec opt_index_options { #ifdef ENABLE_MULTIPLE_NODES const char* message = "FOREIGN KEY name ... REFERENCES constraint is not yet supported."; @@ -7754,6 +7962,7 @@ ConstraintElem: &n->skip_validation, NULL, yyscanner); n->initially_valid = !n->skip_validation; + n->constraintOptions = $13; $$ = (Node *)n; } else { const char* message = "FOREIGN KEY name is supported only in B-format database."; @@ -7767,7 +7976,7 @@ ConstraintElem: } } | FOREIGN KEY '(' columnList ')' REFERENCES qualified_name - opt_column_list key_match key_actions ConstraintAttributeSpec + opt_column_list key_match key_actions ConstraintAttributeSpec opt_index_options { #ifdef ENABLE_MULTIPLE_NODES const char* message = "FOREIGN KEY ... REFERENCES constraint is not yet supported."; @@ -7790,9 +7999,10 @@ ConstraintElem: &n->skip_validation, NULL, yyscanner); n->initially_valid = !n->skip_validation; + n->constraintOptions = $12; $$ = (Node *)n; } - | PARTIAL CLUSTER KEY '(' columnList ')' ConstraintAttributeSpec + | PARTIAL CLUSTER KEY '(' columnList ')' ConstraintAttributeSpec opt_index_options { Constraint *n = makeNode(Constraint); n->contype = CONSTR_CLUSTER; @@ -7801,6 +8011,7 @@ ConstraintElem: processCASbits($7, @7, "PARTIAL CLUSTER KEY", NULL, NULL, NULL, NULL, yyscanner); + n->constraintOptions = $8; $$ = (Node *)n; } ; @@ -8354,7 +8565,10 @@ OptSubClusterInternal: /* PGXC_END */ OptConsTableSpace: USING INDEX OptPartitionElement { $$ = $3; } - | /*EMPTY*/ { $$ = NULL; } + ; + +OptConsTableSpaceWithEmpty: USING INDEX OptPartitionElement { $$ = $3; } + | /*EMPTY*/ { $$ = NULL; } ; OptPartitionElement: @@ -13347,6 +13561,11 @@ access_method_clause: | /*EMPTY*/ { $$ = NULL; } ; +access_method_clause_without_keyword: + USING IDENT { $$ = $2; } + | /*EMPTY*/ { $$ = NULL; } + ; + index_params: index_elem { $$ = list_make1($1); } | index_params ',' index_elem { $$ = lappend($1, $3); } ; @@ -29139,6 +29358,44 @@ static void CheckPartitionExpr(Node* expr, int* colCount) } } +static char* transformIndexOptions(List* list) +{ + char* method = NULL; + ListCell* cell = NULL; + int first = 0; + + /* check every access method name in index_options, if not exist, return error */ + foreach (cell, list) { + void* pointer = lfirst(cell); + if (IsA(pointer, A_Const)) { + A_Const* con = (A_Const*) pointer; + if (IsA((Node*)&con->val, String)) { + /* return the last access method name */ + char* am = strVal(&con->val); + if (am && get_am_oid(am, false) && first < 1) { + method = am; + first++; + } + } + } + } + return method; +} + +static void setAccessMethod(Constraint *n) +{ + char* method = transformIndexOptions(n->constraintOptions); + if (method != NULL) { + /* check current index access method name is exist? If not, return error */ + if (n->access_method == NULL) { + n->access_method = method; + } else { + get_am_oid(n->access_method, false); + n->access_method = method; + } + } +} + /* * Must undefine this stuff before including scan.c, since it has different * definitions for these macros. diff --git a/src/test/regress/expected/alter_table_000.out b/src/test/regress/expected/alter_table_000.out index 3774ae619..21e136fa0 100644 --- a/src/test/regress/expected/alter_table_000.out +++ b/src/test/regress/expected/alter_table_000.out @@ -2755,4 +2755,97 @@ ERROR: index/key cannot be used as unique name. LINE 1: ...r table test_p_unique add constraint con_t_unique unique ind... ^ drop table test_p_unique; +create table test_primary(f11 int, f12 varchar(20), f13 bool); +alter table test_primary add primary key using btree(f11 desc, f12 asc) comment 'primary key' using btree; +NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "test_primary_pkey" for table "test_primary" +\d+ test_primary + Table "public.test_primary" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f11 | integer | not null | plain | | + f12 | character varying(20) | not null | extended | | + f13 | boolean | | plain | | +Indexes: + "test_primary_pkey" PRIMARY KEY, btree (f11 DESC, f12) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_primary; +create table test_primary(f11 int, f12 varchar(20), f13 bool); +alter table test_primary add primary key (f11 desc, f12 asc) comment 'primary key' using btree; +NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "test_primary_pkey" for table "test_primary" +\d+ test_primary + Table "public.test_primary" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f11 | integer | not null | plain | | + f12 | character varying(20) | not null | extended | | + f13 | boolean | | plain | | +Indexes: + "test_primary_pkey" PRIMARY KEY, btree (f11 DESC, f12) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_primary; +create table test_primary(f11 int, f12 varchar(20), f13 bool); +alter table test_primary add primary key using btree(f11 desc, f12 asc) comment 'primary key' using btree using btree; +NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "test_primary_pkey" for table "test_primary" +\d+ test_primary + Table "public.test_primary" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f11 | integer | not null | plain | | + f12 | character varying(20) | not null | extended | | + f13 | boolean | | plain | | +Indexes: + "test_primary_pkey" PRIMARY KEY, btree (f11 DESC, f12) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_primary; +create table test_unique(f31 int, f32 varchar(20)); +alter table test_unique add unique using btree(f31) comment 'unique index' using btree; +NOTICE: ALTER TABLE / ADD UNIQUE will create implicit index "test_unique_f31_key" for table "test_unique" +\d+ test_unique + Table "public.test_unique" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f31 | integer | | plain | | + f32 | character varying(20) | | extended | | +Indexes: + "test_unique_f31_key" UNIQUE CONSTRAINT, btree (f31) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_unique; +create table test_unique(f31 int, f32 varchar(20)); +alter table test_unique add unique (f31) comment 'unique index' using btree; +NOTICE: ALTER TABLE / ADD UNIQUE will create implicit index "test_unique_f31_key" for table "test_unique" +\d+ test_unique + Table "public.test_unique" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f31 | integer | | plain | | + f32 | character varying(20) | | extended | | +Indexes: + "test_unique_f31_key" UNIQUE CONSTRAINT, btree (f31) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_unique; +create table test_unique(f31 int, f32 varchar(20)); +alter table test_unique add unique using btree(f31) comment 'unique index' using btree using btree; +NOTICE: ALTER TABLE / ADD UNIQUE will create implicit index "test_unique_f31_key" for table "test_unique" +\d+ test_unique + Table "public.test_unique" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f31 | integer | | plain | | + f32 | character varying(20) | | extended | | +Indexes: + "test_unique_f31_key" UNIQUE CONSTRAINT, btree (f31) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_unique; \c postgres diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out index ecefa1f10..79494b281 100644 --- a/src/test/regress/expected/create_table.out +++ b/src/test/regress/expected/create_table.out @@ -2103,4 +2103,91 @@ PARTITION BY RANGE(f1) ERROR: index/key cannot be used as unique name. LINE 6: constraint con_t_unique unique index using btree(f1) ^ +create table test_unique(f31 int, f32 varchar(20), constraint con_t_unique unique using btree(f31, f32) comment 'unique index' using btree); +NOTICE: CREATE TABLE / UNIQUE will create implicit index "con_t_unique" for table "test_unique" +\d+ test_unique + Table "public.test_unique" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f31 | integer | | plain | | + f32 | character varying(20) | | extended | | +Indexes: + "con_t_unique" UNIQUE CONSTRAINT, btree (f31, f32) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_unique; +create table test_unique(f31 int, f32 varchar(20), constraint con_t_unique unique (f31, f32) comment 'unique index' using btree); +NOTICE: CREATE TABLE / UNIQUE will create implicit index "con_t_unique" for table "test_unique" +\d+ test_unique + Table "public.test_unique" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f31 | integer | | plain | | + f32 | character varying(20) | | extended | | +Indexes: + "con_t_unique" UNIQUE CONSTRAINT, btree (f31, f32) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_unique; +create table test_unique(f31 int, f32 varchar(20), constraint con_t_unique unique (f31, f32) comment 'unique index' using btree using btree); +NOTICE: CREATE TABLE / UNIQUE will create implicit index "con_t_unique" for table "test_unique" +\d+ test_unique + Table "public.test_unique" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f31 | integer | | plain | | + f32 | character varying(20) | | extended | | +Indexes: + "con_t_unique" UNIQUE CONSTRAINT, btree (f31, f32) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_unique; +create table test_primary(f11 int, f12 varchar(20), f13 bool, constraint con_t_pri primary key using btree(f11 desc, f12 asc) comment 'primary key' using btree); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "con_t_pri" for table "test_primary" +\d+ test_primary + Table "public.test_primary" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f11 | integer | not null | plain | | + f12 | character varying(20) | not null | extended | | + f13 | boolean | | plain | | +Indexes: + "con_t_pri" PRIMARY KEY, btree (f11 DESC, f12) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_primary; +create table test_primary(f11 int, f12 varchar(20), f13 bool, constraint con_t_pri primary key (f11 desc, f12 asc) comment 'primary key' using btree); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "con_t_pri" for table "test_primary" +\d+ test_primary + Table "public.test_primary" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f11 | integer | not null | plain | | + f12 | character varying(20) | not null | extended | | + f13 | boolean | | plain | | +Indexes: + "con_t_pri" PRIMARY KEY, btree (f11 DESC, f12) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_primary; +create table test_primary(f11 int, f12 varchar(20), f13 bool, constraint con_t_pri primary key using btree(f11 desc, f12 asc) comment 'primary key' using btree using btree); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "con_t_pri" for table "test_primary" +\d+ test_primary + Table "public.test_primary" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------+----------+--------------+------------- + f11 | integer | not null | plain | | + f12 | character varying(20) | not null | extended | | + f13 | boolean | | plain | | +Indexes: + "con_t_pri" PRIMARY KEY, btree (f11 DESC, f12) TABLESPACE pg_default +Has OIDs: no +Options: orientation=row, compression=no + +drop table test_primary; \c postgres diff --git a/src/test/regress/sql/alter_table_000.sql b/src/test/regress/sql/alter_table_000.sql index ad9aa85e1..916677ac8 100644 --- a/src/test/regress/sql/alter_table_000.sql +++ b/src/test/regress/sql/alter_table_000.sql @@ -1346,4 +1346,34 @@ alter table test_p_unique add constraint con_t_unique unique key using btree(f1) alter table test_p_unique add constraint con_t_unique unique index using btree(f1); drop table test_p_unique; +create table test_primary(f11 int, f12 varchar(20), f13 bool); +alter table test_primary add primary key using btree(f11 desc, f12 asc) comment 'primary key' using btree; +\d+ test_primary +drop table test_primary; + +create table test_primary(f11 int, f12 varchar(20), f13 bool); +alter table test_primary add primary key (f11 desc, f12 asc) comment 'primary key' using btree; +\d+ test_primary +drop table test_primary; + +create table test_primary(f11 int, f12 varchar(20), f13 bool); +alter table test_primary add primary key using btree(f11 desc, f12 asc) comment 'primary key' using btree using btree; +\d+ test_primary +drop table test_primary; + +create table test_unique(f31 int, f32 varchar(20)); +alter table test_unique add unique using btree(f31) comment 'unique index' using btree; +\d+ test_unique +drop table test_unique; + +create table test_unique(f31 int, f32 varchar(20)); +alter table test_unique add unique (f31) comment 'unique index' using btree; +\d+ test_unique +drop table test_unique; + +create table test_unique(f31 int, f32 varchar(20)); +alter table test_unique add unique using btree(f31) comment 'unique index' using btree using btree; +\d+ test_unique +drop table test_unique; + \c postgres \ No newline at end of file diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql index 5089c53b2..f3664446f 100644 --- a/src/test/regress/sql/create_table.sql +++ b/src/test/regress/sql/create_table.sql @@ -1446,4 +1446,28 @@ PARTITION BY RANGE(f1) PARTITION P4 VALUES LESS THAN(MAXVALUE) ); +create table test_unique(f31 int, f32 varchar(20), constraint con_t_unique unique using btree(f31, f32) comment 'unique index' using btree); +\d+ test_unique +drop table test_unique; + +create table test_unique(f31 int, f32 varchar(20), constraint con_t_unique unique (f31, f32) comment 'unique index' using btree); +\d+ test_unique +drop table test_unique; + +create table test_unique(f31 int, f32 varchar(20), constraint con_t_unique unique (f31, f32) comment 'unique index' using btree using btree); +\d+ test_unique +drop table test_unique; + +create table test_primary(f11 int, f12 varchar(20), f13 bool, constraint con_t_pri primary key using btree(f11 desc, f12 asc) comment 'primary key' using btree); +\d+ test_primary +drop table test_primary; + +create table test_primary(f11 int, f12 varchar(20), f13 bool, constraint con_t_pri primary key (f11 desc, f12 asc) comment 'primary key' using btree); +\d+ test_primary +drop table test_primary; + +create table test_primary(f11 int, f12 varchar(20), f13 bool, constraint con_t_pri primary key using btree(f11 desc, f12 asc) comment 'primary key' using btree using btree); +\d+ test_primary +drop table test_primary; + \c postgres