Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8444775

Browse files
committed
error messages fixed
1 parent da38676 commit 8444775

File tree

2 files changed

+55
-42
lines changed

2 files changed

+55
-42
lines changed

init.sql

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -935,8 +935,7 @@ LANGUAGE C;
935935
CREATE OR REPLACE FUNCTION @extschema@.create_fk(
936936
fk_table REGCLASS,
937937
fk_attr TEXT,
938-
pk_table REGCLASS,
939-
pk_attr TEXT)
938+
pk_table REGCLASS)
940939
RETURNS VOID AS 'pg_pathman', 'create_fk_constraint'
941940
LANGUAGE C STRICT;
942941

src/ref_integrity.c

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,18 @@ static CompareHashEntry *ri_HashCompareOp(Oid eq_opr, Oid typeid);
155155

156156
static void quoteOneName(char *buffer, const char *name);
157157
static void quoteRelationName(char *buffer, Relation rel);
158-
static void ri_ReportViolation(const ConstraintInfo *riinfo, Relation fk_rel);
158+
static void ri_ReportViolation(const ConstraintInfo *riinfo,
159+
Relation rel,
160+
Datum key,
161+
Oid keytype,
162+
bool onfk);
159163
static SPIPlanPtr FetchPreparedPlan(QueryKey *key);
160164
static void BuildQueryKey(QueryKey *key, Oid relid, Oid partid);
161165
static void SavePreparedPlan(QueryKey *key, SPIPlanPtr plan);
162166
static Oid transformFkeyCheckAttrs(Relation pkrel, int16 attnum, Oid *opclass);
163-
static void create_fk_constraint_internal(Oid fk_table, AttrNumber fk_attnum, Oid pk_table, AttrNumber pk_attnum);
167+
static void create_fk_constraint_internal(Oid fk_table,
168+
AttrNumber fk_attnum,
169+
Oid pk_table);
164170
static void createForeignKeyTriggers(Relation rel, Oid refRelOid,
165171
Oid constraintOid, Oid indexOid);
166172
static HeapTuple get_index_for_key(Relation rel, AttrNumber attnum, Oid *index_id);
@@ -1013,21 +1019,10 @@ ri_PlanCheck(const char *querystr,
10131019
bool cache_plan)
10141020
{
10151021
SPIPlanPtr qplan;
1016-
// Relation query_rel;
10171022
Oid save_userid;
10181023
int save_sec_context;
10191024
Oid argtypes[1] = {argtype};
10201025

1021-
/*
1022-
* Use the query type code to determine whether the query is run against
1023-
* the PK or FK table; we'll do the check as that table's owner
1024-
*/
1025-
// if (qkey->constr_queryno <= RI_PLAN_LAST_ON_PK)
1026-
// query_rel = pk_rel;
1027-
// else
1028-
// query_rel = fk_rel;
1029-
// query_rel = pk_rel;
1030-
10311026
/* Switch to proper UID to perform check as */
10321027
GetUserIdAndSecContext(&save_userid, &save_sec_context);
10331028
SetUserIdAndSecContext(RelationGetForm(query_rel)->relowner,
@@ -1056,12 +1051,6 @@ ri_PlanCheck(const char *querystr,
10561051
/*
10571052
* Perform a query to enforce an RI restriction
10581053
*/
1059-
// static bool
1060-
// ri_PerformCheck(const RI_ConstraintInfo *riinfo,
1061-
// RI_QueryKey *qkey, SPIPlanPtr qplan,
1062-
// Relation fk_rel, Relation pk_rel,
1063-
// HeapTuple old_tuple, HeapTuple new_tuple,
1064-
// bool detectNewRows, int expect_OK)
10651054
static bool
10661055
ri_PerformCheck(const ConstraintInfo *riinfo,
10671056
SPIPlanPtr qplan,
@@ -1078,14 +1067,12 @@ ri_PerformCheck(const ConstraintInfo *riinfo,
10781067
int spi_result;
10791068
Oid save_userid;
10801069
int save_sec_context;
1081-
// Datum vals[RI_MAX_NUMKEYS * 2];
1082-
// char nulls[RI_MAX_NUMKEYS * 2];
1083-
Datum vals[1];
1070+
Datum key[1];
10841071
char nulls[1];
1072+
Oid keytype;
10851073
bool isnull = false;
10861074
AttrNumber attnum;
10871075

1088-
10891076
if (source_is_pk)
10901077
{
10911078
query_rel = pk_rel;
@@ -1099,9 +1086,12 @@ ri_PerformCheck(const ConstraintInfo *riinfo,
10991086
attnum = riinfo->fk_attnum;
11001087
}
11011088

1102-
vals[0] = heap_getattr(tuple, attnum, source_rel->rd_att, &isnull);
1089+
key[0] = heap_getattr(tuple, attnum, source_rel->rd_att, &isnull);
11031090
nulls[0] = isnull ? 'n' : ' ';
11041091

1092+
Assert(attnum <= source_rel->rd_att->natts);
1093+
keytype = source_rel->rd_att->attrs[attnum-1]->atttypid;
1094+
11051095
/*
11061096
* In READ COMMITTED mode, we just need to use an up-to-date regular
11071097
* snapshot, and we will see all rows that could be interesting. But in
@@ -1142,7 +1132,7 @@ ri_PerformCheck(const ConstraintInfo *riinfo,
11421132

11431133
/* Finally we can run the query. */
11441134
spi_result = SPI_execute_snapshot(qplan,
1145-
vals, nulls,
1135+
key, nulls,
11461136
test_snapshot, crosscheck_snapshot,
11471137
false, false, limit);
11481138

@@ -1160,7 +1150,7 @@ ri_PerformCheck(const ConstraintInfo *riinfo,
11601150
/* XXX wouldn't it be clearer to do this part at the caller? */
11611151
if ((SPI_processed == 0) != source_is_pk)
11621152
/* TODO: write a correct table name on DELETE and UPDATE from PK table */
1163-
ri_ReportViolation(riinfo, fk_rel);
1153+
ri_ReportViolation(riinfo, source_rel, key[0], keytype, !source_is_pk);
11641154

11651155
return SPI_processed != 0;
11661156
}
@@ -1201,13 +1191,32 @@ quoteRelationName(char *buffer, Relation rel)
12011191
}
12021192

12031193
static void
1204-
ri_ReportViolation(const ConstraintInfo *riinfo, Relation fk_rel)
1194+
ri_ReportViolation(const ConstraintInfo *riinfo,
1195+
Relation rel,
1196+
Datum key,
1197+
Oid keytype,
1198+
bool onfk)
12051199
{
1206-
ereport(ERROR,
1207-
(errcode(ERRCODE_FOREIGN_KEY_VIOLATION),
1208-
errmsg("insert or update on table \"%s\" violates foreign key constraint \"%s\"",
1209-
RelationGetRelationName(fk_rel),
1210-
NameStr(riinfo->conname))));
1200+
if (onfk)
1201+
ereport(ERROR,
1202+
(errcode(ERRCODE_FOREIGN_KEY_VIOLATION),
1203+
errmsg("insert or update on table \"%s\" violates foreign key constraint \"%s\"",
1204+
RelationGetRelationName(rel),
1205+
NameStr(riinfo->conname)),
1206+
errdetail("Key (%s)=(%s) is not present in table \"%s\".",
1207+
get_attname(riinfo->pk_relid, riinfo->pk_attnum),
1208+
datum_to_cstring(key, keytype),
1209+
RelationGetRelationName(rel))));
1210+
else
1211+
ereport(ERROR,
1212+
(errcode(ERRCODE_FOREIGN_KEY_VIOLATION),
1213+
errmsg("insert or update on table \"%s\" violates foreign key constraint \"%s\"",
1214+
RelationGetRelationName(rel),
1215+
NameStr(riinfo->conname)),
1216+
errdetail("Key (%s)=(%s) is still referenced from table \"%s\".",
1217+
get_attname(riinfo->fk_relid, riinfo->fk_attnum),
1218+
datum_to_cstring(key, keytype),
1219+
RelationGetRelationName(rel))));
12111220
}
12121221

12131222
static void
@@ -1244,18 +1253,19 @@ create_fk_constraint(PG_FUNCTION_ARGS)
12441253
Oid fk_table = PG_GETARG_OID(0);
12451254
Oid pk_table = PG_GETARG_OID(2);
12461255
char *fk_attr = TextDatumGetCString(PG_GETARG_TEXT_P(1));
1247-
char *pk_attr = TextDatumGetCString(PG_GETARG_TEXT_P(3));
12481256
AttrNumber fk_attnum = get_attnum(fk_table, fk_attr);
1249-
AttrNumber pk_attnum = get_attnum(pk_table, pk_attr);
12501257

1251-
create_fk_constraint_internal(fk_table, fk_attnum, pk_table, pk_attnum);
1258+
create_fk_constraint_internal(fk_table, fk_attnum, pk_table);
12521259

12531260
PG_RETURN_VOID();
12541261
}
12551262

12561263
static void
1257-
create_fk_constraint_internal(Oid fk_table, AttrNumber fk_attnum, Oid pk_table, AttrNumber pk_attnum)
1264+
create_fk_constraint_internal(Oid fk_table,
1265+
AttrNumber fk_attnum,
1266+
Oid pk_table)
12581267
{
1268+
const PartRelationInfo *prel;
12591269
Oid indexOid;
12601270
Oid opclass;
12611271
Oid fktypoid = get_atttype(fk_table, fk_attnum);
@@ -1276,19 +1286,23 @@ create_fk_constraint_internal(Oid fk_table, AttrNumber fk_attnum, Oid pk_table,
12761286
Oid opfamily;
12771287
Oid opcintype;
12781288

1279-
12801289
fkrel = heap_open(fk_table, ShareRowExclusiveLock);
12811290
pkrel = heap_open(pk_table, ShareRowExclusiveLock);
12821291

1292+
prel = get_pathman_relation_info(pk_table);
1293+
if (!prel)
1294+
elog(ERROR,
1295+
"table %s isn't partitioned by pg_pathman",
1296+
get_rel_name(pk_table));
1297+
12831298
fkname = ChooseConstraintName(RelationGetRelationName(fkrel),
12841299
get_attname(fk_table, fk_attnum),
12851300
"fkey",
12861301
RelationGetNamespace(fkrel),
12871302
NIL);
12881303

1289-
indexOid = transformFkeyCheckAttrs(pkrel, pk_attnum, &opclass);
1304+
indexOid = transformFkeyCheckAttrs(pkrel, prel->attnum, &opclass);
12901305

1291-
/* TODO: if index isn't exist then we should raise an exception! */
12921306
/* TODO: check permissions */
12931307

12941308
/* We need several fields out of the pg_opclass entry */
@@ -1350,7 +1364,7 @@ create_fk_constraint_internal(Oid fk_table, AttrNumber fk_attnum, Oid pk_table,
13501364
* constraint */
13511365
indexOid,
13521366
pk_table,
1353-
&pk_attnum,
1367+
&prel->attnum,
13541368
&pfeqop,
13551369
&ppeqop,
13561370
&ffeqop,

0 commit comments

Comments
 (0)