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

Commitcfc5008

Browse files
committed
Adjust naming of indexes and their columns per recent discussion.
Index expression columns are now named after the FigureColname result fortheir expressions, rather than always being "pg_expression_N". Digits areappended to this name if needed to make the column name unique within theindex. (That happens for regular columns too, thus fixing the old problemthat CREATE INDEX fooi ON foo (f1, f1) fails. Before exclusion indexesthere was no real reason to do such a thing, but now maybe there is.)Default names for indexes and associated constraints now include the columnnames of all their columns, not only the first one as in previous practice.(Of course, this will be truncated as needed to fit in NAMEDATALEN. Also,pkey indexes retain the historical behavior of not naming specific columnsat all.)An example of the results:regression=# create table foo (f1 int, f2 text,regression(# exclude (f1 with =, lower(f2) with =));NOTICE: CREATE TABLE / EXCLUDE will create implicit index "foo_f1_lower_exclusion" for table "foo"CREATE TABLEregression=# \d foo_f1_lower_exclusionIndex "public.foo_f1_lower_exclusion" Column | Type | Definition--------+---------+------------ f1 | integer | f1 lower | text | lower(f2)btree, for table "public.foo"
1 parentb7d6795 commitcfc5008

File tree

18 files changed

+277
-104
lines changed

18 files changed

+277
-104
lines changed

‎src/backend/bootstrap/bootparse.y

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.101 2009/12/07 05:22:21 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.102 2009/12/23 02:35:18 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -323,6 +323,7 @@ boot_index_param:
323323
IndexElem *n = makeNode(IndexElem);
324324
n->name =$1;
325325
n->expr =NULL;
326+
n->indexcolname =NULL;
326327
n->opclass = list_make1(makeString($2));
327328
n->ordering = SORTBY_DEFAULT;
328329
n->nulls_ordering = SORTBY_NULLS_DEFAULT;

‎src/backend/catalog/index.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.326 2009/12/09 21:57:50 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.327 2009/12/23 02:35:18 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -82,6 +82,7 @@ typedef struct
8282
/* non-export function prototypes */
8383
staticTupleDescConstructTupleDescriptor(RelationheapRelation,
8484
IndexInfo*indexInfo,
85+
List*indexColNames,
8586
OidaccessMethodObjectId,
8687
Oid*classObjectId);
8788
staticvoidInitializeAttributeOids(RelationindexRelation,
@@ -117,10 +118,12 @@ static OidIndexGetRelation(Oid indexId);
117118
staticTupleDesc
118119
ConstructTupleDescriptor(RelationheapRelation,
119120
IndexInfo*indexInfo,
121+
List*indexColNames,
120122
OidaccessMethodObjectId,
121123
Oid*classObjectId)
122124
{
123125
intnumatts=indexInfo->ii_NumIndexAttrs;
126+
ListCell*colnames_item=list_head(indexColNames);
124127
ListCell*indexpr_item=list_head(indexInfo->ii_Expressions);
125128
HeapTupleamtuple;
126129
Form_pg_amamform;
@@ -216,12 +219,6 @@ ConstructTupleDescriptor(Relation heapRelation,
216219
indexkey= (Node*)lfirst(indexpr_item);
217220
indexpr_item=lnext(indexpr_item);
218221

219-
/*
220-
* Make the attribute's name "pg_expresssion_nnn" (maybe think of
221-
* something better later)
222-
*/
223-
sprintf(NameStr(to->attname),"pg_expression_%d",i+1);
224-
225222
/*
226223
* Lookup the expression type in pg_type for the type length etc.
227224
*/
@@ -268,6 +265,14 @@ ConstructTupleDescriptor(Relation heapRelation,
268265
*/
269266
to->attrelid=InvalidOid;
270267

268+
/*
269+
* Set the attribute name as specified by caller.
270+
*/
271+
if (colnames_item==NULL)/* shouldn't happen */
272+
elog(ERROR,"too few entries in colnames list");
273+
namestrcpy(&to->attname, (constchar*)lfirst(colnames_item));
274+
colnames_item=lnext(colnames_item);
275+
271276
/*
272277
* Check the opclass and index AM to see if either provides a keytype
273278
* (overriding the attribute type). Opclass takes precedence.
@@ -494,6 +499,7 @@ UpdateIndexRelation(Oid indexoid,
494499
*generate an OID for the index.During bootstrap this may be
495500
*nonzero to specify a preselected OID.
496501
* indexInfo: same info executor uses to insert into the index
502+
* indexColNames: column names to use for index (List of char *)
497503
* accessMethodObjectId: OID of index AM to use
498504
* tableSpaceId: OID of tablespace to use
499505
* classObjectId: array of index opclass OIDs, one per index column
@@ -517,6 +523,7 @@ index_create(Oid heapRelationId,
517523
constchar*indexRelationName,
518524
OidindexRelationId,
519525
IndexInfo*indexInfo,
526+
List*indexColNames,
520527
OidaccessMethodObjectId,
521528
OidtableSpaceId,
522529
Oid*classObjectId,
@@ -629,6 +636,7 @@ index_create(Oid heapRelationId,
629636
*/
630637
indexTupDesc=ConstructTupleDescriptor(heapRelation,
631638
indexInfo,
639+
indexColNames,
632640
accessMethodObjectId,
633641
classObjectId);
634642

‎src/backend/catalog/toasting.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.21 2009/12/07 05:22:21 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.22 2009/12/23 02:35:18 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -255,6 +255,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
255255

256256
toast_idxid=index_create(toast_relid,toast_idxname,toastIndexOid,
257257
indexInfo,
258+
list_make2("chunk_id","chunk_seq"),
258259
BTREE_AM_OID,
259260
rel->rd_rel->reltablespace,
260261
classObjectId,coloptions, (Datum)0,

‎src/backend/commands/indexcmds.c

Lines changed: 171 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.188 2009/12/07 05:22:21 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.189 2009/12/23 02:35:20 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -67,6 +67,7 @@ static void ComputeIndexAttrs(IndexInfo *indexInfo,
6767
boolisconstraint);
6868
staticOidGetIndexOpClass(List*opclass,OidattrType,
6969
char*accessMethodName,OidaccessMethodId);
70+
staticchar*ChooseIndexNameAddition(List*colnames);
7071
staticboolrelationHasPrimaryKey(Relationrel);
7172

7273

@@ -128,6 +129,7 @@ DefineIndex(RangeVar *heapRelation,
128129
OidrelationId;
129130
OidnamespaceId;
130131
OidtablespaceId;
132+
List*indexColNames;
131133
Relationrel;
132134
RelationindexRelation;
133135
HeapTupletuple;
@@ -247,37 +249,21 @@ DefineIndex(RangeVar *heapRelation,
247249
if (rel->rd_rel->relisshared)
248250
tablespaceId=GLOBALTABLESPACE_OID;
249251

252+
/*
253+
* Choose the index column names.
254+
*/
255+
indexColNames=ChooseIndexColumnNames(attributeList);
256+
250257
/*
251258
* Select name for index if caller didn't specify
252259
*/
253260
if (indexRelationName==NULL)
254-
{
255-
if (primary)
256-
{
257-
indexRelationName=ChooseRelationName(RelationGetRelationName(rel),
258-
NULL,
259-
"pkey",
260-
namespaceId);
261-
}
262-
elseif (exclusionOpNames!=NIL)
263-
{
264-
IndexElem*iparam= (IndexElem*)linitial(attributeList);
265-
266-
indexRelationName=ChooseRelationName(RelationGetRelationName(rel),
267-
iparam->name,
268-
"exclusion",
269-
namespaceId);
270-
}
271-
else
272-
{
273-
IndexElem*iparam= (IndexElem*)linitial(attributeList);
274-
275-
indexRelationName=ChooseRelationName(RelationGetRelationName(rel),
276-
iparam->name,
277-
"key",
278-
namespaceId);
279-
}
280-
}
261+
indexRelationName=ChooseIndexName(RelationGetRelationName(rel),
262+
namespaceId,
263+
indexColNames,
264+
exclusionOpNames,
265+
primary,
266+
isconstraint);
281267

282268
/*
283269
* look up the access method, verify it can handle the requested features
@@ -488,35 +474,30 @@ DefineIndex(RangeVar *heapRelation,
488474
SET_LOCKTAG_RELATION(heaplocktag,heaprelid.dbId,heaprelid.relId);
489475
heap_close(rel,NoLock);
490476

491-
if (!concurrent)
492-
{
493-
indexRelationId=
494-
index_create(relationId,indexRelationName,indexRelationId,
495-
indexInfo,accessMethodId,tablespaceId,classObjectId,
496-
coloptions,reloptions,primary,
497-
isconstraint,deferrable,initdeferred,
498-
allowSystemTableMods,skip_build,concurrent);
499-
500-
return;/* We're done, in the standard case */
501-
}
502-
503477
/*
504-
* For a concurrent build, we next insert the catalog entry and add
505-
* constraints. We don't build the index just yet; we must first make the
506-
* catalog entry so that the new index is visible to updating
507-
* transactions. That will prevent them from making incompatible HOT
508-
* updates. The new index will be marked not indisready and not
509-
* indisvalid, so that no one else tries to either insert into it or use
510-
* it for queries.We pass skip_build = true to prevent the build.
478+
* Make the catalog entries for the index, including constraints.
479+
* Then, if not skip_build || concurrent, actually build the index.
511480
*/
512481
indexRelationId=
513482
index_create(relationId,indexRelationName,indexRelationId,
514-
indexInfo,accessMethodId,tablespaceId,classObjectId,
483+
indexInfo,indexColNames,
484+
accessMethodId,tablespaceId,classObjectId,
515485
coloptions,reloptions,primary,
516486
isconstraint,deferrable,initdeferred,
517-
allowSystemTableMods, true,concurrent);
487+
allowSystemTableMods,
488+
skip_build||concurrent,
489+
concurrent);
490+
491+
if (!concurrent)
492+
return;/* We're done, in the standard case */
518493

519494
/*
495+
* For a concurrent build, it's important to make the catalog entries
496+
* visible to other transactions before we start to build the index.
497+
* That will prevent them from making incompatible HOT updates. The new
498+
* index will be marked not indisready and not indisvalid, so that no one
499+
* else tries to either insert into it or use it for queries.
500+
*
520501
* We must commit our current transaction so that the index becomes
521502
* visible; then start another. Note that all the data structures we just
522503
* built are lost in the commit. The only data we keep past here are the
@@ -1391,6 +1372,147 @@ ChooseRelationName(const char *name1, const char *name2,
13911372
returnrelname;
13921373
}
13931374

1375+
/*
1376+
* Select the name to be used for an index.
1377+
*
1378+
* The argument list is pretty ad-hoc :-(
1379+
*/
1380+
char*
1381+
ChooseIndexName(constchar*tabname,OidnamespaceId,
1382+
List*colnames,List*exclusionOpNames,
1383+
boolprimary,boolisconstraint)
1384+
{
1385+
char*indexname;
1386+
1387+
if (primary)
1388+
{
1389+
/* the primary key's name does not depend on the specific column(s) */
1390+
indexname=ChooseRelationName(tabname,
1391+
NULL,
1392+
"pkey",
1393+
namespaceId);
1394+
}
1395+
elseif (exclusionOpNames!=NIL)
1396+
{
1397+
indexname=ChooseRelationName(tabname,
1398+
ChooseIndexNameAddition(colnames),
1399+
"exclusion",
1400+
namespaceId);
1401+
}
1402+
elseif (isconstraint)
1403+
{
1404+
indexname=ChooseRelationName(tabname,
1405+
ChooseIndexNameAddition(colnames),
1406+
"key",
1407+
namespaceId);
1408+
}
1409+
else
1410+
{
1411+
indexname=ChooseRelationName(tabname,
1412+
ChooseIndexNameAddition(colnames),
1413+
"idx",
1414+
namespaceId);
1415+
}
1416+
1417+
returnindexname;
1418+
}
1419+
1420+
/*
1421+
* Generate "name2" for a new index given the list of column names for it
1422+
* (as produced by ChooseIndexColumnNames). This will be passed to
1423+
* ChooseRelationName along with the parent table name and a suitable label.
1424+
*
1425+
* We know that less than NAMEDATALEN characters will actually be used,
1426+
* so we can truncate the result once we've generated that many.
1427+
*/
1428+
staticchar*
1429+
ChooseIndexNameAddition(List*colnames)
1430+
{
1431+
charbuf[NAMEDATALEN*2];
1432+
intbuflen=0;
1433+
ListCell*lc;
1434+
1435+
buf[0]='\0';
1436+
foreach(lc,colnames)
1437+
{
1438+
constchar*name= (constchar*)lfirst(lc);
1439+
1440+
if (buflen>0)
1441+
buf[buflen++]='_';/* insert _ between names */
1442+
1443+
/*
1444+
* At this point we have buflen <= NAMEDATALEN. name should be less
1445+
* than NAMEDATALEN already, but use strlcpy for paranoia.
1446+
*/
1447+
strlcpy(buf+buflen,name,NAMEDATALEN);
1448+
buflen+=strlen(buf+buflen);
1449+
if (buflen >=NAMEDATALEN)
1450+
break;
1451+
}
1452+
returnpstrdup(buf);
1453+
}
1454+
1455+
/*
1456+
* Select the actual names to be used for the columns of an index, given the
1457+
* list of IndexElems for the columns. This is mostly about ensuring the
1458+
* names are unique so we don't get a conflicting-attribute-names error.
1459+
*
1460+
* Returns a List of plain strings (char *, not String nodes).
1461+
*/
1462+
List*
1463+
ChooseIndexColumnNames(List*indexElems)
1464+
{
1465+
List*result=NIL;
1466+
ListCell*lc;
1467+
1468+
foreach(lc,indexElems)
1469+
{
1470+
IndexElem*ielem= (IndexElem*)lfirst(lc);
1471+
constchar*origname;
1472+
constchar*curname;
1473+
inti;
1474+
charbuf[NAMEDATALEN];
1475+
1476+
/* Get the preliminary name from the IndexElem */
1477+
if (ielem->indexcolname)
1478+
origname=ielem->indexcolname;/* caller-specified name */
1479+
elseif (ielem->name)
1480+
origname=ielem->name;/* simple column reference */
1481+
else
1482+
origname="expr";/* default name for expression */
1483+
1484+
/* If it conflicts with any previous column, tweak it */
1485+
curname=origname;
1486+
for (i=1;;i++)
1487+
{
1488+
ListCell*lc2;
1489+
charnbuf[32];
1490+
intnlen;
1491+
1492+
foreach(lc2,result)
1493+
{
1494+
if (strcmp(curname, (char*)lfirst(lc2))==0)
1495+
break;
1496+
}
1497+
if (lc2==NULL)
1498+
break;/* found nonconflicting name */
1499+
1500+
sprintf(nbuf,"%d",i);
1501+
1502+
/* Ensure generated names are shorter than NAMEDATALEN */
1503+
nlen=pg_mbcliplen(origname,strlen(origname),
1504+
NAMEDATALEN-1-strlen(nbuf));
1505+
memcpy(buf,origname,nlen);
1506+
strcpy(buf+nlen,nbuf);
1507+
curname=buf;
1508+
}
1509+
1510+
/* And attach to the result list */
1511+
result=lappend(result,pstrdup(curname));
1512+
}
1513+
returnresult;
1514+
}
1515+
13941516
/*
13951517
* relationHasPrimaryKey -
13961518
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp