Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
c7d2ce7b
Commit
c7d2ce7b
authored
Feb 14, 2001
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Repair problems with duplicate index names generated when CREATE TABLE
specifies redundant UNIQUE conditions.
parent
4a66f9dd
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
76 additions
and
73 deletions
+76
-73
src/backend/parser/analyze.c
src/backend/parser/analyze.c
+76
-73
No files found.
src/backend/parser/analyze.c
View file @
c7d2ce7b
...
...
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: analyze.c,v 1.1
79 2001/02/14 21:35:01
tgl Exp $
* $Id: analyze.c,v 1.1
80 2001/02/14 23:32:38
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -606,7 +606,8 @@ makeObjectName(char *name1, char *name2, char *typename)
}
static
char
*
CreateIndexName
(
char
*
table_name
,
char
*
column_name
,
char
*
label
,
List
*
indices
)
CreateIndexName
(
char
*
table_name
,
char
*
column_name
,
char
*
label
,
List
*
indices
)
{
int
pass
=
0
;
char
*
iname
=
NULL
;
...
...
@@ -617,7 +618,8 @@ CreateIndexName(char *table_name, char *column_name, char *label, List *indices)
* The type name for makeObjectName is label, or labelN if that's
* necessary to prevent collisions among multiple indexes for the same
* table. Note there is no check for collisions with already-existing
* indexes; this ought to be rethought someday.
* indexes, only among the indexes we're about to create now; this ought
* to be improved someday.
*/
strcpy
(
typename
,
label
);
...
...
@@ -629,14 +631,15 @@ CreateIndexName(char *table_name, char *column_name, char *label, List *indices)
{
IndexStmt
*
index
=
lfirst
(
ilist
);
if
(
strcmp
(
iname
,
index
->
idxname
)
==
0
)
if
(
index
->
idxname
!=
NULL
&&
strcmp
(
iname
,
index
->
idxname
)
==
0
)
break
;
}
/* ran through entire list? then no name conflict found so done */
if
(
ilist
==
NIL
)
break
;
/*
the last one conflicted
, so try a new name component */
/*
found a conflict
, so try a new name component */
pfree
(
iname
);
sprintf
(
typename
,
"%s%d"
,
label
,
++
pass
);
}
...
...
@@ -745,9 +748,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
constraint
=
makeNode
(
Constraint
);
constraint
->
contype
=
CONSTR_UNIQUE
;
constraint
->
name
=
makeObjectName
(
stmt
->
relname
,
column
->
colname
,
"key"
);
constraint
->
name
=
NULL
;
/* assign later */
column
->
constraints
=
lappend
(
column
->
constraints
,
constraint
);
...
...
@@ -919,13 +920,9 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
stmt
->
constraints
=
constraints
;
/* Now run through the "deferred list" to complete the query transformation.
* For PRIMARY KEYs, mark each column as NOT NULL and create an index.
* For UNIQUE, create an index as for PRIMARY KEYS, but do not insist on NOT NULL.
*
* Note that this code does not currently look for all possible redundant cases
* and either ignore or stop with warning. The create might fail later when
* names for indices turn out to be duplicated, or a user might have specified
* extra useless indices which might hurt performance. - thomas 1997-12-08
* For PRIMARY KEY, mark each column as NOT NULL and create an index.
* For UNIQUE, create an index as for PRIMARY KEY, but do not insist on
* NOT NULL.
*/
while
(
dlist
!=
NIL
)
{
...
...
@@ -943,7 +940,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
if
(
pkey
!=
NULL
)
elog
(
ERROR
,
"CREATE TABLE/PRIMARY KEY multiple primary keys"
" for table '%s' are not allowed"
,
stmt
->
relname
);
pkey
=
(
IndexStmt
*
)
index
;
pkey
=
index
;
}
if
(
constraint
->
name
!=
NULL
)
...
...
@@ -951,7 +948,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
else
if
(
constraint
->
contype
==
CONSTR_PRIMARY
)
index
->
idxname
=
makeObjectName
(
stmt
->
relname
,
NULL
,
"pkey"
);
else
index
->
idxname
=
NULL
;
index
->
idxname
=
NULL
;
/* will set it later */
index
->
relname
=
stmt
->
relname
;
index
->
accessMethod
=
"btree"
;
...
...
@@ -995,10 +992,10 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
int
count
;
Assert
(
IsA
(
inh
,
String
));
rel
=
heap_openr
(
inh
->
val
.
str
,
AccessShareLock
);
rel
=
heap_openr
(
strVal
(
inh
)
,
AccessShareLock
);
if
(
rel
->
rd_rel
->
relkind
!=
RELKIND_RELATION
)
elog
(
ERROR
,
"inherited table
\"
%s
\"
is not a relation"
,
inh
->
val
.
str
);
strVal
(
inh
)
);
for
(
count
=
0
;
count
<
rel
->
rd_att
->
natts
;
count
++
)
{
Form_pg_attribute
inhattr
=
rel
->
rd_att
->
attrs
[
count
];
...
...
@@ -1020,7 +1017,8 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
* error if the inherited column won't be NOT NULL.
* (Would a NOTICE be more reasonable?)
*/
if
(
!
inhattr
->
attnotnull
)
if
(
constraint
->
contype
==
CONSTR_PRIMARY
&&
!
inhattr
->
attnotnull
)
elog
(
ERROR
,
"inherited attribute
\"
%s
\"
cannot be a PRIMARY KEY because it is not marked NOT NULL"
,
inhname
);
break
;
...
...
@@ -1041,78 +1039,85 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
iparam
->
args
=
NIL
;
iparam
->
class
=
NULL
;
index
->
indexParams
=
lappend
(
index
->
indexParams
,
iparam
);
if
(
index
->
idxname
==
NULL
)
index
->
idxname
=
CreateIndexName
(
stmt
->
relname
,
iparam
->
name
,
"key"
,
ilist
);
}
if
(
index
->
idxname
==
NULL
)
/* should not happen */
elog
(
ERROR
,
"CREATE TABLE: failed to make implicit index name"
);
ilist
=
lappend
(
ilist
,
index
);
dlist
=
lnext
(
dlist
);
}
/* OK, now finally, if there is a primary key, then make sure that there aren't any redundant
* unique indices defined on columns. This can arise if someone specifies UNIQUE explicitly
* or if a SERIAL column was defined along with a table PRIMARY KEY constraint.
* - thomas 1999-05-11
*/
/*
* Scan the index list and remove any redundant index specifications.
* This can happen if, for instance, the user writes SERIAL PRIMARY KEY
* or SERIAL UNIQUE. A strict reading of SQL92 would suggest raising
* an error instead, but that strikes me as too anal-retentive.
* - tgl 2001-02-14
*/
dlist
=
ilist
;
ilist
=
NIL
;
if
(
pkey
!=
NULL
)
{
dlist
=
ilist
;
ilist
=
NIL
;
while
(
dlist
!=
NIL
)
{
List
*
pcols
,
*
icols
;
int
plen
,
ilen
;
int
keep
=
TRUE
;
index
=
lfirst
(
dlist
);
pcols
=
pkey
->
indexParams
;
icols
=
index
->
indexParams
;
/* Make sure we keep the PKEY index in preference to others... */
ilist
=
makeList1
(
pkey
);
}
while
(
dlist
!=
NIL
)
{
index
=
lfirst
(
dlist
);
plen
=
length
(
pcols
);
ilen
=
length
(
icols
);
/* if it's pkey, it's already in ilist */
if
(
index
!=
pkey
)
{
bool
keep
=
true
;
List
*
priorlist
;
/* Not the same as the primary key? Then we should look... */
if
((
index
!=
pkey
)
&&
(
ilen
==
plen
))
foreach
(
priorlist
,
ilist
)
{
keep
=
FALSE
;
while
((
pcols
!=
NIL
)
&&
(
icols
!=
NIL
))
{
IndexElem
*
pcol
=
lfirst
(
pcols
);
IndexElem
*
icol
=
lfirst
(
icols
);
char
*
pname
=
pcol
->
name
;
char
*
iname
=
icol
->
name
;
IndexStmt
*
priorindex
=
lfirst
(
priorlist
);
/* different names? then no match... */
if
(
strcmp
(
iname
,
pname
)
!=
0
)
{
keep
=
TRUE
;
break
;
}
pcols
=
lnext
(
pcols
);
icols
=
lnext
(
icols
);
if
(
equal
(
index
->
indexParams
,
priorindex
->
indexParams
))
{
/*
* If the prior index is as yet unnamed, and this one
* is named, then transfer the name to the prior index.
* This ensures that if we have named and unnamed
* constraints, we'll use (at least one of) the names
* for the index.
*/
if
(
priorindex
->
idxname
==
NULL
)
priorindex
->
idxname
=
index
->
idxname
;
keep
=
false
;
break
;
}
}
if
(
keep
)
ilist
=
lappend
(
ilist
,
index
);
dlist
=
lnext
(
dlist
);
}
dlist
=
lnext
(
dlist
);
}
/*
* Finally, select unique names for all not-previously-named indices,
* and display notice messages.
*/
dlist
=
ilist
;
while
(
dlist
!=
NIL
)
{
index
=
lfirst
(
dlist
);
if
(
index
->
idxname
==
NULL
&&
index
->
indexParams
!=
NIL
)
{
iparam
=
lfirst
(
index
->
indexParams
);
index
->
idxname
=
CreateIndexName
(
stmt
->
relname
,
iparam
->
name
,
"key"
,
ilist
);
}
if
(
index
->
idxname
==
NULL
)
/* should not happen */
elog
(
ERROR
,
"CREATE TABLE: failed to make implicit index name"
);
elog
(
NOTICE
,
"CREATE TABLE/%s will create implicit index '%s' for table '%s'"
,
(
index
->
primary
?
"PRIMARY KEY"
:
"UNIQUE"
),
index
->
idxname
,
stmt
->
relname
);
dlist
=
lnext
(
dlist
);
}
...
...
@@ -1123,7 +1128,6 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
/*
* Now process the FOREIGN KEY constraints and add appropriate queries
* to the extras_after statements list.
*
*/
if
(
fkconstraints
!=
NIL
)
{
...
...
@@ -1173,16 +1177,15 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
List
*
inhRelnames
=
stmt
->
inhRelnames
;
Relation
rel
;
foreach
(
inher
,
inhRelnames
)
{
int
count
=
0
;
Value
*
inh
=
lfirst
(
inher
);
i
f
(
inh
->
type
!=
T_String
)
{
elog
(
ERROR
,
"inherited table name list returns a non-string"
);
}
rel
=
heap_openr
(
inh
->
val
.
str
,
AccessShareLock
);
i
nt
count
;
Assert
(
IsA
(
inh
,
String
));
rel
=
heap_openr
(
strVal
(
inh
)
,
AccessShareLock
);
if
(
rel
->
rd_rel
->
relkind
!=
RELKIND_RELATION
)
elog
(
ERROR
,
"inherited table
\"
%s
\"
is not a relation"
,
inh
->
val
.
str
);
for
(
;
count
<
rel
->
rd_att
->
natts
;
count
++
)
{
strVal
(
inh
)
);
for
(
count
=
0
;
count
<
rel
->
rd_att
->
natts
;
count
++
)
{
char
*
name
=
NameStr
(
rel
->
rd_att
->
attrs
[
count
]
->
attname
);
if
(
strcmp
(
fkattr
->
name
,
name
)
==
0
)
{
found
=
1
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment