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

Commitca234c3

Browse files
committed
Instead of failing when the constructed name for a sequence,
index, etc is too long, truncate until it fits.
1 parent4cf595b commitca234c3

File tree

1 file changed

+92
-85
lines changed

1 file changed

+92
-85
lines changed

‎src/backend/parser/analyze.c

Lines changed: 92 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 1994, Regents of the University of California
77
*
8-
*$Id: analyze.c,v 1.109 1999/05/2522:04:25 momjian Exp $
8+
*$Id: analyze.c,v 1.110 1999/06/05 20:22:30 tgl Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
@@ -410,39 +410,79 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
410410
}
411411

412412
/*
413-
*makeTableName()
414-
*Create a table name from a list of fields.
413+
*makeObjectName()
414+
*
415+
*Create a name for an implicitly created index, sequence, constraint, etc.
416+
*
417+
*The parameters are: the original table name, the original field name, and
418+
*a "type" string (such as "seq" or "pkey"). The field name and/or type
419+
*can be NULL if not relevant.
420+
*
421+
*The result is a palloc'd string.
422+
*
423+
*The basic result we want is "name1_name2_type", omitting "_name2" or
424+
*"_type" when those parameters are NULL. However, we must generate
425+
*a name with less than NAMEDATALEN characters! So, we truncate one or
426+
*both names if necessary to make a short-enough string. The type part
427+
*is never truncated (so it had better be reasonably short).
428+
*
429+
*To reduce the probability of collisions, we might someday add more
430+
*smarts to this routine, like including some "hash" characters computed
431+
*from the truncated characters. Currently it seems best to keep it simple,
432+
*so that the generated names are easily predictable by a person.
415433
*/
416434
staticchar*
417-
makeTableName(void*elem,...)
435+
makeObjectName(char*name1,char*name2,char*typename)
418436
{
419-
va_listargs;
420-
421437
char*name;
422-
charbuf[NAMEDATALEN+1];
423-
424-
buf[0]='\0';
425-
426-
va_start(args,elem);
427-
428-
name=elem;
429-
while (name!=NULL)
438+
intoverhead=0;/* chars needed for type and underscores */
439+
intavailchars;/* chars available for name(s) */
440+
intname1chars;/* chars allocated to name1 */
441+
intname2chars;/* chars allocated to name2 */
442+
intndx;
443+
444+
name1chars=strlen(name1);
445+
if (name2)
430446
{
431-
/* not enough room for next part? then return nothing */
432-
if ((strlen(buf)+strlen(name)) >= (sizeof(buf)-1))
433-
returnNULL;
447+
name2chars=strlen(name2);
448+
overhead++;/* allow for separating underscore */
449+
}
450+
else
451+
name2chars=0;
452+
if (typename)
453+
overhead+=strlen(typename)+1;
434454

435-
if (strlen(buf)>0)
436-
strcat(buf,"_");
437-
strcat(buf,name);
455+
availchars=NAMEDATALEN-1-overhead;
438456

439-
name=va_arg(args,void*);
457+
/* If we must truncate, preferentially truncate the longer name.
458+
* This logic could be expressed without a loop, but it's simple and
459+
* obvious as a loop.
460+
*/
461+
while (name1chars+name2chars>availchars)
462+
{
463+
if (name1chars>name2chars)
464+
name1chars--;
465+
else
466+
name2chars--;
440467
}
441468

442-
va_end(args);
443-
444-
name=palloc(strlen(buf)+1);
445-
strcpy(name,buf);
469+
/* Now construct the string using the chosen lengths */
470+
name=palloc(name1chars+name2chars+overhead+1);
471+
strncpy(name,name1,name1chars);
472+
ndx=name1chars;
473+
if (name2)
474+
{
475+
name[ndx++]='_';
476+
strncpy(name+ndx,name2,name2chars);
477+
ndx+=name2chars;
478+
}
479+
if (typename)
480+
{
481+
name[ndx++]='_';
482+
strcpy(name+ndx,typename);
483+
}
484+
else
485+
name[ndx]='\0';
446486

447487
returnname;
448488
}
@@ -453,36 +493,32 @@ CreateIndexName(char *table_name, char *column_name, char *label, List *indices)
453493
intpass=0;
454494
char*iname=NULL;
455495
List*ilist;
456-
IndexStmt*index;
457-
charname2[NAMEDATALEN+1];
496+
chartypename[NAMEDATALEN];
497+
498+
/* The type name for makeObjectName is label, or labelN if that's
499+
* necessary to prevent collisions among multiple indexes for the same
500+
* table. Note there is no check for collisions with already-existing
501+
* indexes; this ought to be rethought someday.
502+
*/
503+
strcpy(typename,label);
458504

459-
/* use working storage, since we might be trying several possibilities */
460-
strcpy(name2,column_name);
461-
while (iname==NULL)
505+
for (;;)
462506
{
463-
iname=makeTableName(table_name,name2,label,NULL);
464-
/* unable to make a name at all? then quit */
465-
if (iname==NULL)
466-
break;
507+
iname=makeObjectName(table_name,column_name,typename);
467508

468-
ilist=indices;
469-
while (ilist!=NIL)
509+
foreach(ilist,indices)
470510
{
471-
index=lfirst(ilist);
511+
IndexStmt*index=lfirst(ilist);
472512
if (strcasecmp(iname,index->idxname)==0)
473513
break;
474-
475-
ilist=lnext(ilist);
476514
}
477515
/* ran through entire list? then no name conflict found so done */
478516
if (ilist==NIL)
479517
break;
480518

481519
/* the last one conflicted, so try a new name component */
482520
pfree(iname);
483-
iname=NULL;
484-
pass++;
485-
sprintf(name2,"%s_%d",column_name, (pass+1));
521+
sprintf(typename,"%s%d",label,++pass);
486522
}
487523

488524
returniname;
@@ -542,12 +578,8 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
542578
char*cstring;
543579
CreateSeqStmt*sequence;
544580

545-
sname=makeTableName(stmt->relname,column->colname,"seq",NULL);
546-
if (sname==NULL)
547-
elog(ERROR,"CREATE TABLE/SERIAL implicit sequence name must be less than %d characters"
548-
"\n\tSum of lengths of '%s' and '%s' must be less than %d",
549-
NAMEDATALEN,stmt->relname,column->colname, (NAMEDATALEN-5));
550-
581+
sname=makeObjectName(stmt->relname,column->colname,
582+
"seq");
551583
constraint=makeNode(Constraint);
552584
constraint->contype=CONSTR_DEFAULT;
553585
constraint->name=sname;
@@ -562,11 +594,9 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
562594

563595
constraint=makeNode(Constraint);
564596
constraint->contype=CONSTR_UNIQUE;
565-
constraint->name=makeTableName(stmt->relname,column->colname,"key",NULL);
566-
if (constraint->name==NULL)
567-
elog(ERROR,"CREATE TABLE/SERIAL implicit index name must be less than %d characters"
568-
"\n\tSum of lengths of '%s' and '%s' must be less than %d",
569-
NAMEDATALEN,stmt->relname,column->colname, (NAMEDATALEN-5));
597+
constraint->name=makeObjectName(stmt->relname,
598+
column->colname,
599+
"key");
570600
column->constraints=lappend(column->constraints,constraint);
571601

572602
sequence=makeNode(CreateSeqStmt);
@@ -616,23 +646,15 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
616646

617647
caseCONSTR_PRIMARY:
618648
if (constraint->name==NULL)
619-
constraint->name=makeTableName(stmt->relname,"pkey",NULL);
620-
if (constraint->name==NULL)
621-
elog(ERROR,"CREATE TABLE/PRIMARY KEY implicit index name must be less than %d characters"
622-
"\n\tLength of '%s' must be less than %d",
623-
NAMEDATALEN,stmt->relname, (NAMEDATALEN-6));
649+
constraint->name=makeObjectName(stmt->relname,NULL,"pkey");
624650
if (constraint->keys==NIL)
625651
constraint->keys=lappend(constraint->keys,column);
626652
dlist=lappend(dlist,constraint);
627653
break;
628654

629655
caseCONSTR_UNIQUE:
630656
if (constraint->name==NULL)
631-
constraint->name=makeTableName(stmt->relname,column->colname,"key",NULL);
632-
if (constraint->name==NULL)
633-
elog(ERROR,"CREATE TABLE/UNIQUE implicit index name must be less than %d characters"
634-
"\n\tLength of '%s' must be less than %d",
635-
NAMEDATALEN,stmt->relname, (NAMEDATALEN-5));
657+
constraint->name=makeObjectName(stmt->relname,column->colname,"key");
636658
if (constraint->keys==NIL)
637659
constraint->keys=lappend(constraint->keys,column);
638660
dlist=lappend(dlist,constraint);
@@ -641,11 +663,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
641663
caseCONSTR_CHECK:
642664
constraints=lappend(constraints,constraint);
643665
if (constraint->name==NULL)
644-
constraint->name=makeTableName(stmt->relname,column->colname,NULL);
645-
if (constraint->name==NULL)
646-
elog(ERROR,"CREATE TABLE/CHECK implicit constraint name must be less than %d characters"
647-
"\n\tSum of lengths of '%s' and '%s' must be less than %d",
648-
NAMEDATALEN,stmt->relname,column->colname, (NAMEDATALEN-1));
666+
constraint->name=makeObjectName(stmt->relname,column->colname,NULL);
649667
break;
650668

651669
default:
@@ -663,11 +681,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
663681
{
664682
caseCONSTR_PRIMARY:
665683
if (constraint->name==NULL)
666-
constraint->name=makeTableName(stmt->relname,"pkey",NULL);
667-
if (constraint->name==NULL)
668-
elog(ERROR,"CREATE TABLE/PRIMARY KEY implicit index name must be less than %d characters"
669-
"\n\tLength of '%s' must be less than %d",
670-
NAMEDATALEN,stmt->relname, (NAMEDATALEN-5));
684+
constraint->name=makeObjectName(stmt->relname,NULL,"pkey");
671685
dlist=lappend(dlist,constraint);
672686
break;
673687

@@ -728,15 +742,9 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
728742
}
729743

730744
if (constraint->name!=NULL)
731-
index->idxname=constraint->name;
745+
index->idxname=pstrdup(constraint->name);
732746
elseif (constraint->contype==CONSTR_PRIMARY)
733-
{
734-
index->idxname=makeTableName(stmt->relname,"pkey",NULL);
735-
if (index->idxname==NULL)
736-
elog(ERROR,"CREATE TABLE/PRIMARY KEY implicit index name must be less than %d characters"
737-
"\n\tLength of '%s' must be less than %d",
738-
NAMEDATALEN,stmt->relname, (NAMEDATALEN-5));
739-
}
747+
index->idxname=makeObjectName(stmt->relname,NULL,"pkey");
740748
else
741749
index->idxname=NULL;
742750

@@ -767,7 +775,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
767775
if (constraint->contype==CONSTR_PRIMARY)
768776
column->is_not_null= TRUE;
769777
iparam=makeNode(IndexElem);
770-
iparam->name=strcpy(palloc(strlen(column->colname)+1),column->colname);
778+
iparam->name=pstrdup(column->colname);
771779
iparam->args=NIL;
772780
iparam->class=NULL;
773781
iparam->typename=NULL;
@@ -779,9 +787,8 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
779787
keys=lnext(keys);
780788
}
781789

782-
if (index->idxname==NULL)
783-
elog(ERROR,"CREATE TABLE unable to construct implicit index for table '%s'"
784-
"; name too long",stmt->relname);
790+
if (index->idxname==NULL)/* should not happen */
791+
elog(ERROR,"CREATE TABLE: failed to make implicit index name");
785792

786793
ilist=lappend(ilist,index);
787794
dlist=lnext(dlist);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp