207{
210 int nargs;
215 int nkeys;
224 bool isnull;
227 int ret;
229 r;
231
232#ifdef DEBUG_QUERY
233 elog(
DEBUG4,
"check_foreign_key: Enter Function");
234#endif
235
236
237
238
239
240
242
243 elog(
ERROR,
"check_foreign_key: not fired by trigger manager");
244
245
247
248 elog(
ERROR,
"check_foreign_key: must be fired for row");
249
250
252
253 elog(
ERROR,
"check_foreign_key: cannot process INSERT events");
254
256
257 elog(
ERROR,
"check_foreign_key: must be fired by AFTER trigger");
258
259
261
262
263
264
265
268 {
269 newtuple = trigdata->tg_newtuple;
271 }
272 trigger = trigdata->tg_trigger;
275
276 if (nargs < 5)
277
278
279 elog(
ERROR,
"check_foreign_key: too short %d (< 5) list of arguments", nargs);
280
283
284 elog(
ERROR,
"check_foreign_key: %d (< 1) number of references specified",
nrefs);
286 if (action != 'r' && action != 'c' && action != 's')
287
288 elog(
ERROR,
"check_foreign_key: invalid action %s", args[1]);
289 nargs -= 2;
292 if (nkeys <= 0 || nargs != (
nrefs + nkeys * (
nrefs + 1)))
293
294 elog(
ERROR,
"check_foreign_key: invalid number of arguments %d for %d references",
296
297 rel = trigdata->tg_relation;
299
300
302
303
304
305
306
308
309
311
312
313 for (
i = 0;
i < nkeys;
i++)
314 {
315
317
318
319 if (fnumber <= 0)
322 errmsg(
"there is no attribute \"%s\" in relation \"%s\"",
324
325
327
328
329
330
331
332
333 if (isnull)
334 {
337 }
338
339
340
341
342
343
344 if (newtuple !=
NULL)
345 {
348
349
351
356 }
357
358
360 }
362 nargs -= nkeys;
365
367
368 for (r = 0; r <
nrefs; r++)
369 {
372
374
376
377
378
379
380
381
382
383
384
385
386
387 if (action == 'r')
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407 else if (action == 'c')
408 {
410 {
413 int k;
414
416 for (k = 1; k <= nkeys; k++)
417 {
421
425 if (k < nkeys)
427 }
429 }
430 else
431
433 }
434
435
436
437
438
439
440
441 else if (action == 's')
442 {
444 for (
i = 1;
i <= nkeys;
i++)
445 {
449 }
451 }
452
453
454 for (
i = 1;
i <= nkeys;
i++)
455 {
459 }
460
461
464
466
468
470
471#ifdef DEBUG_QUERY
473#endif
474
476 }
477
478
479
480
482 {
485 }
486
487
488
489
490 for (r = 0; r <
nrefs; r++)
491 {
492
493
494
495
496 int tcount = (
action ==
'r') ? 1 : 0;
497
499
501
502
503 if (ret < 0)
506 errmsg(
"SPI_execp returned %d", ret)));
507
508
509 if (action == 'r')
510 {
511
515 errmsg(
"\"%s\": tuple is referenced in \"%s\"",
517 }
518 else
519 {
520#ifdef REFINT_VERBOSE
522
523 if (action == 'c')
525 else
527
530#endif
531 }
533 }
534
536
538}
#define Assert(condition)
static DataChecksumsWorkerOperation operation
int errcode(int sqlerrcode)
#define ereport(elevel,...)
void pfree(void *pointer)
int32 pg_strtoint32(const char *s)
static unsigned char pg_ascii_tolower(unsigned char ch)
#define PointerGetDatum(X)
char * quote_literal_cstr(const char *rawstr)
int SPI_fnumber(TupleDesc tupdesc, const char *fname)
Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber)
const char * SPI_result_code_string(int code)
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount)
char * SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
char * SPI_getrelname(Relation rel)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void initStringInfo(StringInfo str)
static void * fn(void *arg)
#define CALLED_AS_TRIGGER(fcinfo)
#define TRIGGER_FIRED_FOR_ROW(event)
#define TRIGGER_FIRED_AFTER(event)
#define TRIGGER_FIRED_BY_INSERT(event)
#define TRIGGER_FIRED_BY_UPDATE(event)