Postgres Dev.: Difference between revisions

From Earlham CS Department
Jump to navigation Jump to search
Purcebr (talk | contribs)
Purcebr (talk | contribs)
 
(11 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Postgres Internals Notes==
== Postgres Internals ==


=== Current Efforts ===
'''Bryan Purcell'''
'''Mikio Takizawa'''
'''CS430, May 2009'''
 
We have fix a bug listed on the Postgres TODO list.
 
<pre>Report the schema along table name in a referential failure error message</pre>
 
[http://wiki.postgresql.org/wiki/Todo#Referential_Integrity Described Here]
 
The bug is catagorized in referential integrity, however we have completed a system-wide change so schema names, or namespace names, are reported along with table names in various flavors of errors. We did not have time, however, to patch the regression suite to accept the new code. When the user types ''make check'' errors are generated because the newly qualified table printout is not expected.
 
The following includes some notes from the project along with the procedure for testing.
 
=== Notes ===


<pre>get_namespace_name(oid)</pre>
<pre>get_namespace_name(oid)</pre>
Line 20: Line 34:
ri_triggers.c houses all cases where fk constraints fail. There are 5 or 6 variations. The primary error message is the same in each case, and a detail section gets more specific about why the constraint blocked the SQL action.
ri_triggers.c houses all cases where fk constraints fail. There are 5 or 6 variations. The primary error message is the same in each case, and a detail section gets more specific about why the constraint blocked the SQL action.


Fixed error report in ri_triggers.c :
Sample error report generated from an fixed version of ri_triggers.c :


<pre>
<pre>
Line 30: Line 44:
</pre>
</pre>


The problem we have to figure out here is how to combine the namespace name and table name into a single variable. Adding another %s will require changing each localization file, along with the source code. Making such a substantial change probably won't be possible.
== Test Environment ==


== Test Environment ==
=== Foreign Keys ===


We have created a foreign key violation test enviroment. This this enviroment consists of two relations, where the a value in orders depends on a values in the table products. The query that causes our fk constraint failure is:
We have created a foreign key violation test enviroment. This this enviroment consists of two relations, where the a value in orders depends on a values in the table products. The query that causes our fk constraint failure is:
Line 48: Line 62:
DETAIL:  Key (product_no)=(23) is not present in table "products".</pre>
DETAIL:  Key (product_no)=(23) is not present in table "products".</pre>


All of the foreign key constraint error cases can be found in ri_triggers.c file. There are many other types of errors that will need to be modified, however, and we are working on a way to automate this process
=== Everything Else ===
 
While it's pretty easy to check the above case, it's much harder to sweep the entire system recreating errors to test our reformatting.
 
Instead of creating these cases yourself, run
 
<pre>make check</pre>
 
at the root directory to get a diff of the old table names, and the newly formatted table names. The make check will end in error because we have not patched the regression suite.


== Automation ==
== Automation ==


The bug description on the mailing list seemed to find this fix more tedious than outright difficult. Now that we've seen the fix work, it seems like a good idea to try to automate corrections across the whole system.
The bug description on the mailing list seemed to find this fix more tedious than outright difficult. Now that we've seen the fix work, it seems like a good idea to try to figure out all the relevant places to fix.


<pre>
<pre>
   1 #!/usr/bin/perl
   1 #!/usr/bin/perl
   2  
   2  
   3 open(FILE, "/Users/purcebr/Desktop/postgres/postgresql-8.3.7/src/backend/po/hu.po");
   3 open(FILE, "/Users/purcebr/Desktop/postgres/postgresql-8.3.7/src/backend/po/es.po");
   4  
   4  
   5 my $lines = <FILE>;
   5 my $lines = <FILE>;
   6  
   6 my $count = 0;
   7 while(<FILE>)
   7  
   8 {
  8 while(<FILE>)
  9
   9 {
  10         if($_ =~m/#:/) {
10
  11                 $filename = $_;
  11         if($_ =~m/#:/) {
  12         }
  12                 $filename = $_;
  13
  13         }
  14         if($_ =~ m/ table /) {
  14
  15                 print $filename,  $_, "\n";
  15         if((($_ =~ m/%s/) && ($_ =~m/\son\s/)) || ($_ =~ m/\stable\s/)) {
  16         }
  16                 print $count, ". ",  $filename,  $_, "\n";
  17
  17                $count = $count + 1;
  18 }
18         }
  19
  20 }
</pre>
</pre>


The script produces the following output. I manually deleted the messages we don't care about
Bryan's Change Locations


<pre>
<pre>
#: catalog/dependency.c:2301
0. #: access/heap/heapam.c:953
msgid "could not obtain lock on relation \"%s\""
 
1. #: access/heap/heapam.c:3109
msgid "could not obtain lock on row in relation \"%s\""
 
2. #: catalog/dependency.c:189 catalog/dependency.c:242
msgid "cannot drop %s because other objects depend on it"
 
3. #: catalog/dependency.c:375
msgid "failed to drop all objects depending on %s"
 
4. #: catalog/dependency.c:692 catalog/dependency.c:857
msgid "%s depends on %s"
 
8. #: catalog/dependency.c:2301
msgid "uncataloged table %s"
msgid "uncataloged table %s"


#: catalog/dependency.c:2305
9. #: catalog/dependency.c:2305
msgid "toast table %s"
msgid "toast table %s"


#: catalog/heap.c:1781
10. #: catalog/heap.c:1781
msgid "only table \"%s\" can be referenced in check constraint"
msgid "only table \"%s\" can be referenced in check constraint"


#: catalog/heap.c:2297
11. #: catalog/heap.c:2294
msgid "cannot truncate a table referenced in a foreign key constraint"
 
12. #: catalog/heap.c:2297
msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE."
msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE."


#: commands/analyze.c:167
13. #: catalog/pg_depend.c:207
msgid "cannot remove dependency on %s because it is a system object"
 
14. #: catalog/pg_shdepend.c:672
msgid "there are objects dependent on %s"
 
15. #: commands/analyze.c:167
msgid "skipping \"%s\" --- only table or database owner can analyze it"
msgid "skipping \"%s\" --- only table or database owner can analyze it"


#: commands/analyze.c:494
16. #: commands/analyze.c:494
msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s"
msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s"


#: commands/cluster.c:163 commands/tablecmds.c:5688
17. #: commands/cluster.c:149
msgid "there is no previously clustered index for table \"%s\""
 
18. #: commands/cluster.c:163 commands/tablecmds.c:5688
msgid "index \"%s\" for table \"%s\" does not exist"
msgid "index \"%s\" for table \"%s\" does not exist"


#: commands/cluster.c:367
19. #: commands/cluster.c:367
msgid "\"%s\" is not an index for table \"%s\""
msgid "\"%s\" is not an index for table \"%s\""


#: commands/trigger.c:1092
20. #: commands/cluster.c:380
msgid "cannot cluster on partial index \"%s\""
 
21. #: commands/cluster.c:386
"cannot cluster on index \"%s\" because access method does not support "
 
22. #: commands/cluster.c:406
"cannot cluster on index \"%s\" because access method does not handle null "
 
25. #: commands/trigger.c:1092
msgid "trigger \"%s\" for table \"%s\" does not exist"
msgid "trigger \"%s\" for table \"%s\" does not exist"


#: commands/comment.c:1125
26. #: commands/comment.c:1125
msgid "constraint \"%s\" for table \"%s\" does not exist"
msgid "constraint \"%s\" for table \"%s\" does not exist"


#: parser/parse_utilcmd.c:1066
27. #: parser/parse_utilcmd.c:1066
msgid "multiple primary keys for table \"%s\" are not allowed"
msgid "multiple primary keys for table \"%s\" are not allowed"


#: commands/indexcmds.c:431
28. #: commands/indexcmds.c:431
msgid "%s %s will create implicit index \"%s\" for table \"%s\""
msgid "%s %s will create implicit index \"%s\" for table \"%s\""


#: commands/indexcmds.c:1339
29. #: commands/indexcmds.c:1339
msgid "shared table \"%s\" can only be reindexed in stand-alone mode"
msgid "shared table \"%s\" can only be reindexed in stand-alone mode"


#: commands/tablecmds.c:580
32. #: commands/tablecmds.c:580
msgid "truncate cascades to table \"%s\""
msgid "truncate cascades to table \"%s\""


#: commands/tablecmds.c:2740
33. #: commands/tablecmds.c:2740
msgid "\"%s\" is not a table or view"
msgid "\"%s\" is not a table or view"


#: commands/tablecmds.c:2776 commands/tablecmds.c:3480
34. #: commands/tablecmds.c:2776 commands/tablecmds.c:3480
msgid "\"%s\" is not a table or index"
msgid "\"%s\" is not a table or index"


#: commands/tablecmds.c:2931
35. #: commands/tablecmds.c:2931
msgid "cannot alter table \"%s\" because column \"%s\".\"%s\" uses its rowtype"
msgid "cannot alter table \"%s\" because column \"%s\".\"%s\" uses its rowtype"


#: commands/tablecmds.c:3057 commands/tablecmds.c:6218
36. #: commands/tablecmds.c:3057 commands/tablecmds.c:6218
msgid "child table \"%s\" has different type for column \"%s\""
msgid "child table \"%s\" has different type for column \"%s\""


#: commands/tablecmds.c:4335
37. #: commands/tablecmds.c:4011
msgid "cannot reference temporary table from permanent table constraint"
 
38. #: commands/tablecmds.c:4018
msgid "cannot reference permanent table from temporary table constraint"
 
39. #: commands/tablecmds.c:4335
msgid "there is no primary key for referenced table \"%s\""
msgid "there is no primary key for referenced table \"%s\""


#: commands/tablecmds.c:4469
40. #: commands/tablecmds.c:4469
"there is no unique constraint matching given keys for referenced table \"%s\""
"there is no unique constraint matching given keys for referenced table \"%s\""


#: commands/tablecmds.c:5455 commands/tablecmds.c:6544
41. #: commands/tablecmds.c:5091
msgid "%s depends on column \"%s\""
 
42. #: commands/tablecmds.c:5455 commands/tablecmds.c:6544
msgid "Sequence \"%s\" is linked to table \"%s\"."
msgid "Sequence \"%s\" is linked to table \"%s\"."


#: commands/tablecmds.c:6120
43. #: commands/tablecmds.c:6120
msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs"
msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs"


#: commands/tablecmds.c:6225
44. #: commands/tablecmds.c:6225
msgid "column \"%s\" in child table must be marked NOT NULL"
msgid "column \"%s\" in child table must be marked NOT NULL"


#: commands/tablecmds.c:6241
45. #: commands/tablecmds.c:6241
msgid "child table is missing column \"%s\""
msgid "child table is missing column \"%s\""


#: commands/trigger.c:766
46. #: commands/tablecmds.c:6333
msgid "child table is missing constraint \"%s\""
 
</pre>
 
Mikio's Change Locations
 
<pre>
47. #: commands/tablespace.c:306 commands/tablespace.c:1289
msgid "could not set permissions on directory \"%s\": %m"
 
48. #: commands/trigger.c:766
msgid "trigger \"%s\" for table \"%s\" does not exist, skipping"
msgid "trigger \"%s\" for table \"%s\" does not exist, skipping"


#: commands/typecmds.c:1621
49. #: commands/typecmds.c:1621
msgid "column \"%s\" of table \"%s\" contains null values"
msgid "column \"%s\" of table \"%s\" contains null values"


#: commands/typecmds.c:1866
50. #: commands/typecmds.c:1866
"column \"%s\" of table \"%s\" contains values that violate the new constraint"
"column \"%s\" of table \"%s\" contains values that violate the new constraint"


#: commands/vacuum.c:1063
51. #: commands/typecmds.c:2146 commands/typecmds.c:2155
msgid "cannot use table references in domain check constraint"
 
54. #: commands/vacuum.c:1063
msgid "skipping \"%s\" --- only table or database owner can vacuum it"
msgid "skipping \"%s\" --- only table or database owner can vacuum it"


#: commands/vacuum.c:3321 commands/vacuum.c:3393
64. #: parser/parse_relation.c:2001
"index \"%s\" contains %.0f row versions, but table contains %.0f row versions"
 
#: commands/vacuumlazy.c:238
"automatic vacuum of table \"%s.%s.%s\": index scans: %d\n"
 
#: executor/execCurrent.c:96
msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\""
 
#: parser/parse_relation.c:2001
msgid "invalid reference to FROM-clause entry for table \"%s\""
msgid "invalid reference to FROM-clause entry for table \"%s\""


#: parser/parse_relation.c:2004 parser/parse_relation.c:2030
65. #: parser/parse_relation.c:2004 parser/parse_relation.c:2030
msgid "Perhaps you meant to reference the table alias \"%s\"."
msgid "Perhaps you meant to reference the table alias \"%s\"."


#: parser/parse_relation.c:2006 parser/parse_relation.c:2033
66. #: parser/parse_relation.c:2006 parser/parse_relation.c:2033
"There is an entry for table \"%s\", but it cannot be referenced from this "
"There is an entry for table \"%s\", but it cannot be referenced from this "


#: parser/parse_relation.c:2013
67. #: parser/parse_relation.c:2013
msgid "missing FROM-clause entry in subquery for table \"%s\""
msgid "missing FROM-clause entry in subquery for table \"%s\""


#: parser/parse_relation.c:2015
68. #: parser/parse_relation.c:2015
msgid "missing FROM-clause entry for table \"%s\""
msgid "missing FROM-clause entry for table \"%s\""


#: parser/parse_relation.c:2025
69. #: parser/parse_relation.c:2025
msgid "adding missing FROM-clause entry in subquery for table \"%s\""
msgid "adding missing FROM-clause entry in subquery for table \"%s\""


#: parser/parse_relation.c:2027
70. #: parser/parse_relation.c:2027
msgid "adding missing FROM-clause entry for table \"%s\""
msgid "adding missing FROM-clause entry for table \"%s\""


#: parser/parse_utilcmd.c:423 parser/parse_utilcmd.c:433
71. #: parser/parse_utilcmd.c:423 parser/parse_utilcmd.c:433
"conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\""
"conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\""


#: parser/parse_utilcmd.c:443
72. #: parser/parse_utilcmd.c:443
msgid "multiple default values specified for column \"%s\" of table \"%s\""
msgid "multiple default values specified for column \"%s\" of table \"%s\""


#: postmaster/autovacuum.c:2141
73. #: parser/parse_utilcmd.c:1355
"index expressions and predicates can refer only to the table being indexed"
 
74. #: postmaster/autovacuum.c:2141
msgid "automatic vacuum of table \"%s.%s.%s\""
msgid "automatic vacuum of table \"%s.%s.%s\""


#: postmaster/autovacuum.c:2144
75. #: postmaster/autovacuum.c:2144
msgid "automatic analyze of table \"%s.%s.%s\""
msgid "automatic analyze of table \"%s.%s.%s\""


#: rewrite/rewriteDefine.c:383
76. #: postmaster/pgstat.c:3020
msgid "database hash table corrupted during cleanup --- abort"
 
77. #: rewrite/rewriteDefine.c:383
msgid "could not convert table \"%s\" to a view because it is not empty"
msgid "could not convert table \"%s\" to a view because it is not empty"


#: rewrite/rewriteDefine.c:390
78. #: rewrite/rewriteDefine.c:390
msgid "could not convert table \"%s\" to a view because it has triggers"
msgid "could not convert table \"%s\" to a view because it has triggers"


#: rewrite/rewriteDefine.c:392
79. #: rewrite/rewriteDefine.c:392
"In particular, the table cannot be involved in any foreign key relationships."
"In particular, the table cannot be involved in any foreign key relationships."


#: rewrite/rewriteDefine.c:397
80. #: rewrite/rewriteDefine.c:397
msgid "could not convert table \"%s\" to a view because it has indexes"
msgid "could not convert table \"%s\" to a view because it has indexes"


#: rewrite/rewriteDefine.c:403
81. #: rewrite/rewriteDefine.c:403
msgid "could not convert table \"%s\" to a view because it has child tables"
msgid "could not convert table \"%s\" to a view because it has child tables"


#: utils/adt/ri_triggers.c:3451 utils/adt/ri_triggers.c:3488
82. #: rewrite/rewriteHandler.c:1697
msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\""
 
#: utils/adt/ri_triggers.c:3061
msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\""
 
#: utils/adt/ri_triggers.c:3490
msgid "Key (%s)=(%s) is not present in table \"%s\"."
 
#: utils/adt/ri_triggers.c:3496
"update or delete on table \"%s\" violates foreign key constraint \"%s\" on "
 
#: utils/adt/ri_triggers.c:3499
msgid "Key (%s)=(%s) is still referenced from table \"%s\"."
 
</pre>
 
The following is another list matched on %s, and \son\s to capture more vague references to relations.
 
<pre>
#: access/heap/heapam.c:953
msgid "could not obtain lock on relation \"%s\""
 
#: access/heap/heapam.c:3109
msgid "could not obtain lock on row in relation \"%s\""
 
#: catalog/dependency.c:189 catalog/dependency.c:242
msgid "cannot drop %s because other objects depend on it"
 
#: catalog/dependency.c:375
msgid "failed to drop all objects depending on %s"
 
#: catalog/dependency.c:692 catalog/dependency.c:857
msgid "%s depends on %s"
 
#: catalog/dependency.c:1864
msgid "constraint %s on "
 
#: catalog/dependency.c:2098
msgid "rule %s on "
 
#: catalog/dependency.c:2133
msgid "trigger %s on "
 
#: catalog/pg_depend.c:207
msgid "cannot remove dependency on %s because it is a system object"
 
#: catalog/pg_shdepend.c:672
msgid "there are objects dependent on %s"
 
#: commands/cluster.c:386
"cannot cluster on index \"%s\" because access method does not support "
 
#: commands/cluster.c:406
"cannot cluster on index \"%s\" because access method does not handle null "
 
#: commands/cluster.c:422
"cannot cluster on expressional index \"%s\" because its index access method "
 
#: commands/cluster.c:437
msgid "cannot cluster on invalid index \"%s\""
 
#: commands/tablecmds.c:5091
msgid "%s depends on column \"%s\""
 
#: rewrite/rewriteHandler.c:1697
msgid "cannot perform INSERT RETURNING on relation \"%s\""
msgid "cannot perform INSERT RETURNING on relation \"%s\""


#: rewrite/rewriteHandler.c:1704
83. #: rewrite/rewriteHandler.c:1704
msgid "cannot perform UPDATE RETURNING on relation \"%s\""
msgid "cannot perform UPDATE RETURNING on relation \"%s\""


#: rewrite/rewriteHandler.c:1711
84. #: rewrite/rewriteHandler.c:1711
msgid "cannot perform DELETE RETURNING on relation \"%s\""
msgid "cannot perform DELETE RETURNING on relation \"%s\""


#: storage/lmgr/deadlock.c:908
85. #: storage/lmgr/deadlock.c:908
msgid "Process %d waits for %s on %s; blocked by process %d."
msgid "Process %d waits for %s on %s; blocked by process %d."


#: storage/lmgr/proc.c:954
86. #: storage/lmgr/proc.c:954
"process %d avoided deadlock for %s on %s by rearranging queue order after %"
"process %d avoided deadlock for %s on %s by rearranging queue order after %"


#: storage/lmgr/proc.c:966
87. #: storage/lmgr/proc.c:966
"process %d detected deadlock while waiting for %s on %s after %ld.%03d ms"
"process %d detected deadlock while waiting for %s on %s after %ld.%03d ms"


#: storage/lmgr/proc.c:972
88. #: storage/lmgr/proc.c:972
msgid "process %d still waiting for %s on %s after %ld.%03d ms"
msgid "process %d still waiting for %s on %s after %ld.%03d ms"


#: storage/lmgr/proc.c:976
89. #: storage/lmgr/proc.c:976
msgid "process %d acquired %s on %s after %ld.%03d ms"
msgid "process %d acquired %s on %s after %ld.%03d ms"


#: storage/lmgr/proc.c:992
90. #: storage/lmgr/proc.c:992
msgid "process %d failed to acquire %s on %s after %ld.%03d ms"
msgid "process %d failed to acquire %s on %s after %ld.%03d ms"


#: utils/adt/ri_triggers.c:3451 utils/adt/ri_triggers.c:3488
98. #: utils/adt/ri_triggers.c:3451 utils/adt/ri_triggers.c:3488
msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\""
msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\""


#: utils/adt/ri_triggers.c:3061
99. #: utils/adt/ri_triggers.c:3061
msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\""
msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\""


#: utils/adt/ri_triggers.c:3418
100. #: utils/adt/ri_triggers.c:3418
"referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave "
"referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave "


#: utils/adt/ri_triggers.c:3496
101. #: utils/adt/ri_triggers.c:3490
msgid "Key (%s)=(%s) is not present in table \"%s\"."
 
102. #: utils/adt/ri_triggers.c:3496
"update or delete on table \"%s\" violates foreign key constraint \"%s\" on "
"update or delete on table \"%s\" violates foreign key constraint \"%s\" on "


103. #: utils/adt/ri_triggers.c:3499
msgid "Key (%s)=(%s) is still referenced from table \"%s\"."
</pre>
</pre>


Line 329: Line 349:
*What's the difference between a tablespace and a namespace?<font color = 'red'> - addressed </font>
*What's the difference between a tablespace and a namespace?<font color = 'red'> - addressed </font>
*Is there a way to take a namespace identifier and get a namespace ''object''? <font color = 'red'> - yep. it's a function called get_namespace_name(oid namespace_id)</font>
*Is there a way to take a namespace identifier and get a namespace ''object''? <font color = 'red'> - yep. it's a function called get_namespace_name(oid namespace_id)</font>
== Notes ==
*I skipped table alias. (miki)
== Who We Are ==
Bryan Purcell, purcebr[at]earlham[d0t]edu
Mikio Takizawa, takizmi[at]earlham[d0t]edu
CS430, May 2009

Latest revision as of 04:26, 6 May 2009

Postgres Internals

Bryan Purcell Mikio Takizawa CS430, May 2009

We have fix a bug listed on the Postgres TODO list.

Report the schema along table name in a referential failure error message

Described Here

The bug is catagorized in referential integrity, however we have completed a system-wide change so schema names, or namespace names, are reported along with table names in various flavors of errors. We did not have time, however, to patch the regression suite to accept the new code. When the user types make check errors are generated because the newly qualified table printout is not expected.

The following includes some notes from the project along with the procedure for testing.

Notes

get_namespace_name(oid)
  • Returns a character string representing the namespace name.
RelationGetRelationName(relation)
  • Prints out the name of the relation. This function is called directly in the printf of the error message in ri_triggers.c
relation->rd_rel->relnamespace
  • There's a member variable relnamespace in Form_pg_class data type.

It is of type id0, representing a unique namespace identifier. As a first stab, I just replaced the appearance of RelationGetRelationName(relation) with relation->rd_red->relnamespace and when the error occurs this number is printed.

  • fk violation error messages located in:
postgresql-8.3.7/src/backend/utils/adt/ri_triggers.c:

ri_triggers.c houses all cases where fk constraints fail. There are 5 or 6 variations. The primary error message is the same in each case, and a detail section gets more specific about why the constraint blocked the SQL action.

Sample error report generated from an fixed version of ri_triggers.c :

3487                                  errmsg("insert or update on table \"%s\" violates foreign key constraint \"%s\"",
3488                                                 strcat( strcat(get_namespace_name(fk_rel->rd_rel->relnamespace), "."), RelationGetRelationName(fk_rel)), constrname),
3489                                  errdetail("Key (%s)=(%s) is not present in table \"%s\".",
3490                                                    key_names, key_values,
3491                                                   strcat( strcat(get_namespace_name(fk_rel->rd_rel->relnamespace), "."), RelationGetRelationName(fk_rel)))));

Test Environment

Foreign Keys

We have created a foreign key violation test enviroment. This this enviroment consists of two relations, where the a value in orders depends on a values in the table products. The query that causes our fk constraint failure is:

INSERT INTO orders VALUES(0, 23, 23);

An error gets returned because the constraint was violated. Originally, only the relation name was reported. Our fix qualifies this table with its parent namespace. The error used to look like:

ERROR:  insert or update on table "orders" violates foreign key constraint "orders_product_no_fkey"
DETAIL:  Key (product_no)=(23) is not present in table "products".

Now it looks like:

ERROR:  insert or update on table "public.orders" violates foreign key constraint "orders_product_no_fkey"
DETAIL:  Key (product_no)=(23) is not present in table "products".

Everything Else

While it's pretty easy to check the above case, it's much harder to sweep the entire system recreating errors to test our reformatting.

Instead of creating these cases yourself, run

make check

at the root directory to get a diff of the old table names, and the newly formatted table names. The make check will end in error because we have not patched the regression suite.

Automation

The bug description on the mailing list seemed to find this fix more tedious than outright difficult. Now that we've seen the fix work, it seems like a good idea to try to figure out all the relevant places to fix.

  1 #!/usr/bin/perl
  2 
  3 open(FILE, "/Users/purcebr/Desktop/postgres/postgresql-8.3.7/src/backend/po/es.po");
  4 
  5 my $lines = <FILE>;
  6 my $count = 0;
  7 
  8 while(<FILE>)
  9 {
 10 
 11         if($_ =~m/#:/) {
 12                 $filename = $_;
 13         }
 14 
 15         if((($_ =~ m/%s/) && ($_ =~m/\son\s/)) || ($_ =~ m/\stable\s/)) {
 16                 print $count, ". ",  $filename,  $_, "\n";
 17                 $count = $count + 1;
 18         }
 19 
 20 }

Bryan's Change Locations

0. #: access/heap/heapam.c:953
msgid "could not obtain lock on relation \"%s\""

1. #: access/heap/heapam.c:3109
msgid "could not obtain lock on row in relation \"%s\""

2. #: catalog/dependency.c:189 catalog/dependency.c:242
msgid "cannot drop %s because other objects depend on it"

3. #: catalog/dependency.c:375
msgid "failed to drop all objects depending on %s"

4. #: catalog/dependency.c:692 catalog/dependency.c:857
msgid "%s depends on %s"

8. #: catalog/dependency.c:2301
msgid "uncataloged table %s"

9. #: catalog/dependency.c:2305
msgid "toast table %s"

10. #: catalog/heap.c:1781
msgid "only table \"%s\" can be referenced in check constraint"

11. #: catalog/heap.c:2294
msgid "cannot truncate a table referenced in a foreign key constraint"

12. #: catalog/heap.c:2297
msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE."

13. #: catalog/pg_depend.c:207
msgid "cannot remove dependency on %s because it is a system object"

14. #: catalog/pg_shdepend.c:672
msgid "there are objects dependent on %s"

15. #: commands/analyze.c:167
msgid "skipping \"%s\" --- only table or database owner can analyze it"

16. #: commands/analyze.c:494
msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s"

17. #: commands/cluster.c:149
msgid "there is no previously clustered index for table \"%s\""

18. #: commands/cluster.c:163 commands/tablecmds.c:5688
msgid "index \"%s\" for table \"%s\" does not exist"

19. #: commands/cluster.c:367
msgid "\"%s\" is not an index for table \"%s\""

20. #: commands/cluster.c:380
msgid "cannot cluster on partial index \"%s\""

21. #: commands/cluster.c:386
"cannot cluster on index \"%s\" because access method does not support "

22. #: commands/cluster.c:406
"cannot cluster on index \"%s\" because access method does not handle null "

25. #: commands/trigger.c:1092
msgid "trigger \"%s\" for table \"%s\" does not exist"

26. #: commands/comment.c:1125
msgid "constraint \"%s\" for table \"%s\" does not exist"

27. #: parser/parse_utilcmd.c:1066
msgid "multiple primary keys for table \"%s\" are not allowed"

28. #: commands/indexcmds.c:431
msgid "%s %s will create implicit index \"%s\" for table \"%s\""

29. #: commands/indexcmds.c:1339
msgid "shared table \"%s\" can only be reindexed in stand-alone mode"

32. #: commands/tablecmds.c:580
msgid "truncate cascades to table \"%s\""

33. #: commands/tablecmds.c:2740
msgid "\"%s\" is not a table or view"

34. #: commands/tablecmds.c:2776 commands/tablecmds.c:3480
msgid "\"%s\" is not a table or index"

35. #: commands/tablecmds.c:2931
msgid "cannot alter table \"%s\" because column \"%s\".\"%s\" uses its rowtype"

36. #: commands/tablecmds.c:3057 commands/tablecmds.c:6218
msgid "child table \"%s\" has different type for column \"%s\""

37. #: commands/tablecmds.c:4011
msgid "cannot reference temporary table from permanent table constraint"

38. #: commands/tablecmds.c:4018
msgid "cannot reference permanent table from temporary table constraint"

39. #: commands/tablecmds.c:4335
msgid "there is no primary key for referenced table \"%s\""

40. #: commands/tablecmds.c:4469
"there is no unique constraint matching given keys for referenced table \"%s\""

41. #: commands/tablecmds.c:5091
msgid "%s depends on column \"%s\""

42. #: commands/tablecmds.c:5455 commands/tablecmds.c:6544
msgid "Sequence \"%s\" is linked to table \"%s\"."

43. #: commands/tablecmds.c:6120
msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs"

44. #: commands/tablecmds.c:6225
msgid "column \"%s\" in child table must be marked NOT NULL"

45. #: commands/tablecmds.c:6241
msgid "child table is missing column \"%s\""

46. #: commands/tablecmds.c:6333
msgid "child table is missing constraint \"%s\""

Mikio's Change Locations

47. #: commands/tablespace.c:306 commands/tablespace.c:1289
msgid "could not set permissions on directory \"%s\": %m"

48. #: commands/trigger.c:766
msgid "trigger \"%s\" for table \"%s\" does not exist, skipping"

49. #: commands/typecmds.c:1621
msgid "column \"%s\" of table \"%s\" contains null values"

50. #: commands/typecmds.c:1866
"column \"%s\" of table \"%s\" contains values that violate the new constraint"

51. #: commands/typecmds.c:2146 commands/typecmds.c:2155
msgid "cannot use table references in domain check constraint"

54. #: commands/vacuum.c:1063
msgid "skipping \"%s\" --- only table or database owner can vacuum it"

64. #: parser/parse_relation.c:2001
msgid "invalid reference to FROM-clause entry for table \"%s\""

65. #: parser/parse_relation.c:2004 parser/parse_relation.c:2030
msgid "Perhaps you meant to reference the table alias \"%s\"."

66. #: parser/parse_relation.c:2006 parser/parse_relation.c:2033
"There is an entry for table \"%s\", but it cannot be referenced from this "

67. #: parser/parse_relation.c:2013
msgid "missing FROM-clause entry in subquery for table \"%s\""

68. #: parser/parse_relation.c:2015
msgid "missing FROM-clause entry for table \"%s\""

69. #: parser/parse_relation.c:2025
msgid "adding missing FROM-clause entry in subquery for table \"%s\""

70. #: parser/parse_relation.c:2027
msgid "adding missing FROM-clause entry for table \"%s\""

71. #: parser/parse_utilcmd.c:423 parser/parse_utilcmd.c:433
"conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\""

72. #: parser/parse_utilcmd.c:443
msgid "multiple default values specified for column \"%s\" of table \"%s\""

73. #: parser/parse_utilcmd.c:1355
"index expressions and predicates can refer only to the table being indexed"

74. #: postmaster/autovacuum.c:2141
msgid "automatic vacuum of table \"%s.%s.%s\""

75. #: postmaster/autovacuum.c:2144
msgid "automatic analyze of table \"%s.%s.%s\""

76. #: postmaster/pgstat.c:3020
msgid "database hash table corrupted during cleanup --- abort"

77. #: rewrite/rewriteDefine.c:383
msgid "could not convert table \"%s\" to a view because it is not empty"

78. #: rewrite/rewriteDefine.c:390
msgid "could not convert table \"%s\" to a view because it has triggers"

79. #: rewrite/rewriteDefine.c:392
"In particular, the table cannot be involved in any foreign key relationships."

80. #: rewrite/rewriteDefine.c:397
msgid "could not convert table \"%s\" to a view because it has indexes"

81. #: rewrite/rewriteDefine.c:403
msgid "could not convert table \"%s\" to a view because it has child tables"

82. #: rewrite/rewriteHandler.c:1697
msgid "cannot perform INSERT RETURNING on relation \"%s\""

83. #: rewrite/rewriteHandler.c:1704
msgid "cannot perform UPDATE RETURNING on relation \"%s\""

84. #: rewrite/rewriteHandler.c:1711
msgid "cannot perform DELETE RETURNING on relation \"%s\""

85. #: storage/lmgr/deadlock.c:908
msgid "Process %d waits for %s on %s; blocked by process %d."

86. #: storage/lmgr/proc.c:954
"process %d avoided deadlock for %s on %s by rearranging queue order after %"

87. #: storage/lmgr/proc.c:966
"process %d detected deadlock while waiting for %s on %s after %ld.%03d ms"

88. #: storage/lmgr/proc.c:972
msgid "process %d still waiting for %s on %s after %ld.%03d ms"

89. #: storage/lmgr/proc.c:976
msgid "process %d acquired %s on %s after %ld.%03d ms"

90. #: storage/lmgr/proc.c:992
msgid "process %d failed to acquire %s on %s after %ld.%03d ms"

98. #: utils/adt/ri_triggers.c:3451 utils/adt/ri_triggers.c:3488
msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\""

99. #: utils/adt/ri_triggers.c:3061
msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\""

100. #: utils/adt/ri_triggers.c:3418
"referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave "

101. #: utils/adt/ri_triggers.c:3490
msgid "Key (%s)=(%s) is not present in table \"%s\"."

102. #: utils/adt/ri_triggers.c:3496
"update or delete on table \"%s\" violates foreign key constraint \"%s\" on "

103. #: utils/adt/ri_triggers.c:3499
msgid "Key (%s)=(%s) is still referenced from table \"%s\"."

Open Questions

  • What's the difference between a tablespace and a namespace? - addressed
  • Is there a way to take a namespace identifier and get a namespace object? - yep. it's a function called get_namespace_name(oid namespace_id)

Notes

  • I skipped table alias. (miki)

Who We Are

Bryan Purcell, purcebr[at]earlham[d0t]edu

Mikio Takizawa, takizmi[at]earlham[d0t]edu

CS430, May 2009