Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaa88e59

Browse files
committed
Rearrange order of operations in heap_create_with_catalog so that if
two transactions create the same table name concurrently, the one thatfails will complain about unique index pg_class_relname_index, rather thanabout pg_type_typname_index which'll confuse most people. Free sidebenefit: pg_class.reltype is correctly linked to the pg_type entry now.It's been zero in all but the preloaded pg_class entries since who knowswhen.
1 parentd8c4cb7 commitaa88e59

File tree

4 files changed

+107
-91
lines changed

4 files changed

+107
-91
lines changed

‎src/backend/catalog/heap.c

Lines changed: 68 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.158 2001/01/24 19:42:51 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.159 2001/02/12 20:07:21 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -68,15 +68,15 @@
6868

6969

7070
staticvoidAddNewRelationTuple(Relationpg_class_desc,
71-
Relationnew_rel_desc,Oidnew_rel_oid,
72-
intnatts,
73-
charrelkind,char*temp_relname);
71+
Relationnew_rel_desc,Oidnew_rel_oid,Oidnew_type_oid,
72+
intnatts,charrelkind,char*temp_relname);
7473
staticvoidDeleteAttributeTuples(Relationrel);
7574
staticvoidDeleteRelationTuple(Relationrel);
7675
staticvoidDeleteTypeTuple(Relationrel);
7776
staticvoidRelationRemoveIndexes(Relationrelation);
7877
staticvoidRelationRemoveInheritance(Relationrelation);
79-
staticvoidAddNewRelationType(char*typeName,Oidnew_rel_oid);
78+
staticvoidAddNewRelationType(char*typeName,Oidnew_rel_oid,
79+
Oidnew_type_oid);
8080
staticvoidStoreAttrDefault(Relationrel,AttrNumberattnum,char*adbin,
8181
boolupdatePgAttribute);
8282
staticvoidStoreRelCheck(Relationrel,char*ccname,char*ccbin);
@@ -317,6 +317,7 @@ heap_create(char *relname,
317317
strcpy(RelationGetPhysicalRelationName(rel),relname);
318318
rel->rd_rel->relkind=RELKIND_UNCATALOGED;
319319
rel->rd_rel->relnatts=natts;
320+
rel->rd_rel->reltype=InvalidOid;
320321
if (tupDesc->constr)
321322
rel->rd_rel->relchecks=tupDesc->constr->num_check;
322323

@@ -325,12 +326,6 @@ heap_create(char *relname,
325326

326327
RelationGetRelid(rel)=relid;
327328

328-
if (nailme)
329-
{
330-
/* for system relations, set the reltype field here */
331-
rel->rd_rel->reltype=relid;
332-
}
333-
334329
rel->rd_node.tblNode=tblNode;
335330
rel->rd_node.relNode=relid;
336331
rel->rd_rel->relfilenode=relid;
@@ -373,18 +368,17 @@ heap_storage_create(Relation rel)
373368
* performs a scan to ensure that no relation with the
374369
* same name already exists.
375370
*
376-
*3) heap_create_with_catalog() is called to create the new relation
377-
* on disk.
371+
*3) heap_create() is called to create the new relation on disk.
378372
*
379-
*4) TypeDefine() is called to define a new type corresponding
373+
*4) AddNewRelationTuple() is called to register the
374+
* relation in pg_class.
375+
*
376+
*5) TypeCreate() is called to define a new type corresponding
380377
* to the new relation.
381378
*
382-
*5) AddNewAttributeTuples() is called to register the
379+
*6) AddNewAttributeTuples() is called to register the
383380
* new relation's schema in pg_attribute.
384381
*
385-
*6) AddNewRelationTuple() is called to register the
386-
* relation itself in the catalogs.
387-
*
388382
*7) StoreConstraints is called ()- vadim 08/22/97
389383
*
390384
*8) the relations are closed and the new relation's oid
@@ -656,6 +650,7 @@ static void
656650
AddNewRelationTuple(Relationpg_class_desc,
657651
Relationnew_rel_desc,
658652
Oidnew_rel_oid,
653+
Oidnew_type_oid,
659654
intnatts,
660655
charrelkind,
661656
char*temp_relname)
@@ -665,7 +660,7 @@ AddNewRelationTuple(Relation pg_class_desc,
665660
Relationidescs[Num_pg_class_indices];
666661

667662
/* ----------------
668-
*first wemunge some of the information in our
663+
*first weupdate some of the information in our
669664
*uncataloged relation's relation descriptor.
670665
* ----------------
671666
*/
@@ -694,6 +689,7 @@ AddNewRelationTuple(Relation pg_class_desc,
694689
new_rel_reltup->reltuples=1000;
695690

696691
new_rel_reltup->relowner=GetUserId();
692+
new_rel_reltup->reltype=new_type_oid;
697693
new_rel_reltup->relkind=relkind;
698694
new_rel_reltup->relnatts=natts;
699695

@@ -705,6 +701,8 @@ AddNewRelationTuple(Relation pg_class_desc,
705701
tup=heap_addheader(Natts_pg_class_fixed,
706702
CLASS_TUPLE_SIZE,
707703
(char*)new_rel_reltup);
704+
705+
/* force tuple to have the desired OID */
708706
tup->t_data->t_oid=new_rel_oid;
709707

710708
/*
@@ -738,10 +736,8 @@ AddNewRelationTuple(Relation pg_class_desc,
738736
* --------------------------------
739737
*/
740738
staticvoid
741-
AddNewRelationType(char*typeName,Oidnew_rel_oid)
739+
AddNewRelationType(char*typeName,Oidnew_rel_oid,Oidnew_type_oid)
742740
{
743-
Oidnew_type_oid;
744-
745741
/*
746742
* The sizes are set to oid size because it makes implementing sets
747743
* MUCH easier, and no one (we hope) uses these fields to figure out
@@ -750,23 +746,25 @@ AddNewRelationType(char *typeName, Oid new_rel_oid)
750746
* actually get is the oid of a tuple in the pg_proc catalog, so the
751747
* size of the "set" is the size of an oid. Similarly, byval being
752748
* true makes sets much easier, and it isn't used by anything else.
753-
* Note the assumption that OIDs are the same size as int4s.
754-
*/
755-
new_type_oid=TypeCreate(typeName,/* type name */
756-
new_rel_oid,/* relation oid */
757-
sizeof(Oid),/* internal size */
758-
sizeof(Oid),/* external size */
759-
'c',/* type-type (catalog) */
760-
',',/* default array delimiter */
761-
"int4in",/* input procedure */
762-
"int4out",/* output procedure */
763-
"int4in",/* receive procedure */
764-
"int4out",/* send procedure */
765-
NULL,/* array element type - irrelevent */
766-
"-",/* default type value */
767-
(bool)1,/* passed by value */
768-
'i',/* default alignment */
769-
'p');/* Not TOASTable */
749+
*
750+
* XXX Note the assumption that OIDs are the same size as int4s.
751+
*/
752+
TypeCreate(typeName,/* type name */
753+
new_type_oid,/* preassigned oid for type */
754+
new_rel_oid,/* relation oid */
755+
sizeof(Oid),/* internal size */
756+
sizeof(Oid),/* external size */
757+
'c',/* type-type (catalog) */
758+
',',/* default array delimiter */
759+
"int4in",/* input procedure */
760+
"int4out",/* output procedure */
761+
"int4in",/* receive procedure */
762+
"int4out",/* send procedure */
763+
NULL,/* array element type - irrelevant */
764+
"-",/* default type value */
765+
true,/* passed by value */
766+
'i',/* default alignment */
767+
'p');/* Not TOASTable */
770768
}
771769

772770
/* --------------------------------
@@ -785,6 +783,7 @@ heap_create_with_catalog(char *relname,
785783
Relationpg_class_desc;
786784
Relationnew_rel_desc;
787785
Oidnew_rel_oid;
786+
Oidnew_type_oid;
788787
intnatts=tupdesc->natts;
789788
char*temp_relname=NULL;
790789

@@ -814,18 +813,10 @@ heap_create_with_catalog(char *relname,
814813
}
815814

816815
/* ----------------
817-
*RelnameFindRelid couldn't detect simultaneous
818-
*creation. Uniqueness will be really checked by unique
819-
*indexes of system tables but we couldn't check it here.
820-
*We have to postpone creating the disk file for this
821-
*relation.
822-
*Another boolean parameter "storage_create" was added
823-
*to heap_create() function. If the parameter is false
824-
*heap_create() only registers an uncataloged relation
825-
*to relation cache and heap_storage_create() should be
826-
*called later.
827-
*We could pull its relation oid from the newly formed
828-
*relation descriptor.
816+
*Tell heap_create not to create a physical file; we'll do that
817+
*below after all our catalog updates are done. (This isn't really
818+
*necessary anymore, but we may as well avoid the cycles of creating
819+
*and deleting the file in case we fail.)
829820
*
830821
*Note: The call to heap_create() changes relname for
831822
*temp tables; it becomes the true physical relname.
@@ -836,35 +827,47 @@ heap_create_with_catalog(char *relname,
836827
new_rel_desc=heap_create(relname,tupdesc,istemp, false,
837828
allow_system_table_mods);
838829

830+
/* Fetch the relation OID assigned by heap_create */
839831
new_rel_oid=new_rel_desc->rd_att->attrs[0]->attrelid;
840832

841-
/* ----------------
842-
*since defining a relation also defines a complex type,
843-
*we add a new system type corresponding to the new relation.
844-
* ----------------
845-
*/
846-
AddNewRelationType(relname,new_rel_oid);
833+
/* Assign an OID for the relation's tuple type */
834+
new_type_oid=newoid();
847835

848836
/* ----------------
849-
*now add tuples to pg_attribute for the attributes in
850-
*our new relation.
851-
* ----------------
852-
*/
853-
AddNewAttributeTuples(new_rel_oid,tupdesc);
854-
855-
/* ----------------
856-
*now update the information in pg_class.
837+
*now create an entry in pg_class for the relation.
838+
*
839+
*NOTE: we could get a unique-index failure here, in case someone else
840+
*is creating the same relation name in parallel but hadn't committed
841+
*yet when we checked for a duplicate name above.
857842
* ----------------
858843
*/
859844
pg_class_desc=heap_openr(RelationRelationName,RowExclusiveLock);
860845

861846
AddNewRelationTuple(pg_class_desc,
862847
new_rel_desc,
863848
new_rel_oid,
849+
new_type_oid,
864850
natts,
865851
relkind,
866852
temp_relname);
867853

854+
/* ----------------
855+
*since defining a relation also defines a complex type,
856+
*we add a new system type corresponding to the new relation.
857+
*
858+
*NOTE: we could get a unique-index failure here, in case the same name
859+
*has already been used for a type.
860+
* ----------------
861+
*/
862+
AddNewRelationType(relname,new_rel_oid,new_type_oid);
863+
864+
/* ----------------
865+
*now add tuples to pg_attribute for the attributes in
866+
*our new relation.
867+
* ----------------
868+
*/
869+
AddNewAttributeTuples(new_rel_oid,tupdesc);
870+
868871
StoreConstraints(new_rel_desc);
869872

870873
if (istemp)
@@ -912,7 +915,6 @@ heap_create_with_catalog(char *relname,
912915
*attribute catalog (needed?). (Anything else?)
913916
*
914917
*get proper relation from relation catalog (if not arg)
915-
*check if relation is vital (strcmp()/reltype?)
916918
*scan attribute catalog deleting attributes of reldesc
917919
*(necessary?)
918920
*delete relation from relation catalog

‎src/backend/catalog/pg_type.c

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.58 2001/01/24 19:42:52 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.59 2001/02/12 20:07:21 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -46,18 +46,17 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
4646
HeapScanDescscan;
4747
HeapTupletup;
4848
Oidtypoid;
49-
50-
staticScanKeyDatatypeKey[1]= {
51-
{0,Anum_pg_type_typname,F_NAMEEQ}
52-
};
49+
ScanKeyDatatypeKey[1];
5350

5451
/* ----------------
5552
*initialize the scan key and begin a scan of pg_type
5653
* ----------------
5754
*/
58-
fmgr_info(F_NAMEEQ,&typeKey[0].sk_func);
59-
typeKey[0].sk_nargs=typeKey[0].sk_func.fn_nargs;
60-
typeKey[0].sk_argument=PointerGetDatum(typeName);
55+
ScanKeyEntryInitialize(typeKey,
56+
0,
57+
Anum_pg_type_typname,
58+
F_NAMEEQ,
59+
PointerGetDatum(typeName));
6160

6261
scan=heap_beginscan(pg_type_desc,
6362
0,
@@ -269,10 +268,16 @@ TypeShellMake(char *typeName)
269268
*TypeCreate
270269
*
271270
*This does all the necessary work needed to define a new type.
271+
*
272+
* NOTE: if assignedTypeOid is not InvalidOid, then that OID is assigned to
273+
* the new type (which, therefore, cannot already exist as a shell type).
274+
* This hack is only intended for use in creating a relation's associated
275+
* type, where we need to have created the relation tuple already.
272276
* ----------------------------------------------------------------
273277
*/
274278
Oid
275279
TypeCreate(char*typeName,
280+
OidassignedTypeOid,
276281
OidrelationOid,/* only for 'c'atalog typeTypes */
277282
int16internalSize,
278283
int16externalSize,
@@ -292,35 +297,28 @@ TypeCreate(char *typeName,
292297
j;
293298
Relationpg_type_desc;
294299
HeapScanDescpg_type_scan;
295-
296300
OidtypeObjectId;
297301
OidelementObjectId=InvalidOid;
298-
299302
HeapTupletup;
300303
charnulls[Natts_pg_type];
301304
charreplaces[Natts_pg_type];
302305
Datumvalues[Natts_pg_type];
303-
304306
char*procname;
305307
char*procs[4];
306308
booldefined;
307309
NameDataname;
308310
TupleDesctupDesc;
309311
OidargList[FUNC_MAX_ARGS];
310-
311-
staticScanKeyDatatypeKey[1]= {
312-
{0,Anum_pg_type_typname,F_NAMEEQ}
313-
};
314-
315-
fmgr_info(F_NAMEEQ,&typeKey[0].sk_func);
316-
typeKey[0].sk_nargs=typeKey[0].sk_func.fn_nargs;
312+
ScanKeyDatatypeKey[1];
317313

318314
/* ----------------
319-
*check that the type is not already defined.
315+
*check that the type is not already defined. It might exist as
316+
*a shell type, however (but only if assignedTypeOid is not given).
320317
* ----------------
321318
*/
322319
typeObjectId=TypeGet(typeName,&defined);
323-
if (OidIsValid(typeObjectId)&&defined)
320+
if (OidIsValid(typeObjectId)&&
321+
(defined||assignedTypeOid!=InvalidOid))
324322
elog(ERROR,"TypeCreate: type %s already defined",typeName);
325323

326324
/* ----------------
@@ -468,7 +466,12 @@ TypeCreate(char *typeName,
468466
*/
469467
pg_type_desc=heap_openr(TypeRelationName,RowExclusiveLock);
470468

471-
typeKey[0].sk_argument=PointerGetDatum(typeName);
469+
ScanKeyEntryInitialize(typeKey,
470+
0,
471+
Anum_pg_type_typname,
472+
F_NAMEEQ,
473+
PointerGetDatum(typeName));
474+
472475
pg_type_scan=heap_beginscan(pg_type_desc,
473476
0,
474477
SnapshotSelf,/* cache? */
@@ -484,6 +487,10 @@ TypeCreate(char *typeName,
484487
tup=heap_getnext(pg_type_scan,0);
485488
if (HeapTupleIsValid(tup))
486489
{
490+
/* should not happen given prior test? */
491+
if (assignedTypeOid!=InvalidOid)
492+
elog(ERROR,"TypeCreate: type %s already defined",typeName);
493+
487494
tup=heap_modifytuple(tup,
488495
pg_type_desc,
489496
values,
@@ -502,6 +509,9 @@ TypeCreate(char *typeName,
502509
values,
503510
nulls);
504511

512+
/* preassign tuple Oid, if one was given */
513+
tup->t_data->t_oid=assignedTypeOid;
514+
505515
heap_insert(pg_type_desc,tup);
506516

507517
typeObjectId=tup->t_data->t_oid;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp