PostgreSQL Source Code: src/backend/catalog/pg_constraint.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

34#include "utils/fmgroids.h"

38

39

40

41

42

43

44

45

46

47

48

49

59 Oid relId,

83 bool is_internal)

84{

98 int i;

102

103

106

108

110

113

114

115

116

118 {

120

125 }

126 else

128

130 {

133

147

149 {

153 }

154 else

156 }

157 else

158 {

164 }

165

167 {

169

174 }

175 else

177

178

180 {

181 nulls[i] = false;

183 }

184

207

210 else

212

215 else

217

220 else

222

225 else

227

230 else

232

235 else

237

240 else

242

245 else

247

249

251

253

255

256

258

260 {

261

262

263

264

266

268 {

270 {

274 }

275 }

276 else

277 {

280 }

281 }

282

284 {

285

286

287

289

292 }

293

297

298

300

302 {

303

304

305

306

308

310 {

312 {

316 }

317 }

318 else

319 {

322 }

323 }

324

326 {

327

328

329

330

331

332

334

337 }

338

340 {

341

342

343

344

345

346

348

351

353 {

357 {

360 }

362 {

365 }

366 }

367 }

368

372

373

374

375

376

377

378

379

380

382 {

383

384

385

386

390 }

391

392

394 is_internal);

395

397}

398

399

400

401

402

403

404

405

406

407

408

409

410

411bool

413 const char *conname)

414{

415 bool found;

419

421

436

439

440

442

445

446 return found;

447}

448

449

450

451

452

453

454

455

456bool

458{

459 bool found;

463

465

470

475

478

480

483

484 return found;

485}

486

487

488

489

490

491

492

493

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511

512char *

516{

517 int pass = 0;

518 char *conname = NULL;

523 bool found;

525

527

528

529 if (label[0] != '\0')

531 else

533

534 for (;;)

535 {

537

538 found = false;

539

541 {

542 if (strcmp((char *) lfirst(l), conname) == 0)

543 {

544 found = true;

545 break;

546 }

547 }

548

549 if (!found)

550 {

555

560

563

565

567 }

568

569 if (!found)

570 break;

571

572

575 }

576

578

579 return conname;

580}

581

582

583

584

585

586

587

588

589

590

593{

596 retval = NULL;

599

606 true, NULL, 1, &key);

607

609 {

612

613

614

615

616

618 continue;

619

622 continue;

623

624

626 break;

627 }

628

631

632 return retval;

633}

634

635

636

637

638

639

640

652

653

654

655

656

659{

662 retval = NULL;

665

672 true, NULL, 1, &key);

673

675 {

677

678

679

680

682 continue;

683 if (!con->convalidated)

684 continue;

685

686

688 break;

689 }

690

693

694 return retval;

695}

696

697

698

699

700

703{

706

707

709

717 elog(ERROR, "conkey is not a 1-D smallint array");

718

719

720

722}

723

724

725

726

727

728

729

730

731

732

733

734

735

736

737

738

739

740

741bool

743 bool is_local, bool is_no_inherit, bool is_notvalid)

744{

746

749 {

753

756

757

758

759

760

761 if (is_no_inherit != conform->connoinherit)

764 errmsg("cannot change NO INHERIT status of NOT NULL constraint \"%s\" on relation \"%s\"",

766 errhint("You might need to make the existing constraint inheritable using %s.",

767 "ALTER TABLE ... ALTER CONSTRAINT ... INHERIT"));

768

769

770

771

772

776 errmsg("incompatible NOT VALID constraint \"%s\" on relation \"%s\"",

778 errhint("You might need to validate it using %s.",

779 "ALTER TABLE ... VALIDATE CONSTRAINT"));

780

781

782

783

784

785

786

787

792 errmsg("cannot create not-null constraint \"%s\" on column \"%s\" of table \"%s\"",

794 errdetail("A not-null constraint named \"%s\" already exists for this column.",

796

797 if (!is_local)

798 {

803 errmsg("too many inheritance parents"));

805 }

806 else if (conform->conislocal)

807 {

808 conform->conislocal = true;

810 }

811

814

816

817 return true;

818 }

819

820 return false;

821}

822

823

824

825

826

827

828

829

830

831

832

835{

841

849

851 {

854

856 continue;

858 continue;

859

861

863 {

865

867

871 cooked->attnum = colnum;

873 cooked->is_enforced = true;

874 cooked->skip_validation = conForm->convalidated;

875 cooked->is_local = true;

876 cooked->inhcount = 0;

878

880 }

881 else

882 {

884

892 false)));

897 notnulls = lappend(notnulls, constr);

898 }

899 }

900

903

904 return notnulls;

905}

906

907

908

909

910

911void

913{

917

919

922 elog(ERROR, "cache lookup failed for constraint %u", conId);

924

925

926

927

929 {

931

932

933

934

935

937

938

939

940

941

942

944 {

948

953 elog(ERROR, "cache lookup failed for relation %u",

954 con->conrelid);

956

959 else

960

961 elog(WARNING, "relation \"%s\" has relchecks = %d",

963

965

967

969 }

970

971

973 }

975 {

976

977

978

979

980

981

982 }

983 else

984 elog(ERROR, "constraint %u is not of a known type", conId);

985

986

988

989

992}

993

994

995

996

997

998

999

1000

1001

1002

1003

1004void

1006{

1010

1012

1015 elog(ERROR, "cache lookup failed for constraint %u", conId);

1017

1018

1019

1020

1023 con->conrelid,

1024 newname))

1027 errmsg("constraint \"%s\" for relation \"%s\" already exists",

1031 con->contypid,

1032 newname))

1035 errmsg("constraint \"%s\" for domain %s already exists",

1037

1038

1039 namestrcpy(&(con->conname), newname);

1040

1042

1044

1047}

1048

1049

1050

1051

1052

1053

1054

1055

1056void

1059{

1064

1066

1075

1077 NULL, 2, key);

1078

1080 {

1083

1085

1087 continue;

1088

1089

1091 {

1094

1096

1098

1099

1100

1101

1102

1103

1104 }

1105

1107

1109 }

1110

1112

1114}

1115

1116

1117

1118

1119

1120

1121

1122

1123

1124

1125void

1129{

1136

1144 {

1145

1148 elog(ERROR, "constraint %u already has a parent constraint",

1150

1156 errmsg("too many inheritance parents"));

1157

1159

1161

1163

1166

1169 }

1170 else

1171 {

1175

1176

1178

1180

1187 }

1188

1191}

1192

1193

1194

1195

1196

1197

1198

1201{

1207

1209

1222

1225

1226

1229

1231

1232

1236 errmsg("constraint \"%s\" for table \"%s\" does not exist",

1238

1240

1242}

1243

1244

1245

1246

1247

1248

1249

1250

1251

1252

1253

1254

1255

1259{

1265

1266

1268

1270

1283

1286

1287

1289 {

1291 bool isNull;

1292

1294

1295

1298 if (!isNull)

1299 {

1303 int i;

1304

1311 elog(ERROR, "conkey is not a 1-D smallint array");

1313

1314

1316 {

1319 }

1320 }

1321 }

1322

1324

1325

1329 errmsg("constraint \"%s\" for table \"%s\" does not exist",

1331

1333

1335}

1336

1337

1338

1339

1340

1341

1342

1343

1344

1347{

1353

1355

1362 true, NULL, 1, &key);

1364 {

1366

1368

1369

1373 continue;

1374

1376 {

1378 break;

1379 }

1380 }

1382

1385}

1386

1387

1388

1389

1390

1391

1394{

1400

1402

1415

1418

1419

1422

1424

1425

1429 errmsg("constraint \"%s\" for domain %s does not exist",

1431

1433

1435}

1436

1437

1438

1439

1440

1441

1442

1443

1444

1445

1446

1447

1448

1449

1450

1453{

1459

1460

1462

1463

1465

1470

1473

1475 {

1478 bool isNull;

1481 int numkeys;

1482 int i;

1483

1484

1486 continue;

1487

1488

1489

1490

1491

1492

1494 break;

1495

1496

1499 if (isNull)

1500 elog(ERROR, "null conkey for constraint %u",

1505 numkeys < 0 ||

1508 elog(ERROR, "conkey is not a 1-D smallint array");

1510

1511

1512 for (i = 0; i < numkeys; i++)

1513 {

1516 }

1518

1519

1520 break;

1521 }

1522

1524

1526

1528}

1529

1530

1531

1532

1533

1534

1535

1536

1537void

1540 Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs,

1542{

1544 bool isNull;

1546 int numkeys;

1547

1548

1549

1550

1551

1552

1559 elog(ERROR, "conkey is not a 1-D smallint array");

1562 elog(ERROR, "foreign key constraint cannot have %d columns", numkeys);

1565 pfree(arr);

1566

1571 ARR_DIMS(arr)[0] != numkeys ||

1574 elog(ERROR, "confkey is not a 1-D smallint array");

1577 pfree(arr);

1578

1579 if (pf_eq_oprs)

1580 {

1584

1586 ARR_DIMS(arr)[0] != numkeys ||

1589 elog(ERROR, "conpfeqop is not a 1-D Oid array");

1592 pfree(arr);

1593 }

1594

1595 if (pp_eq_oprs)

1596 {

1601 ARR_DIMS(arr)[0] != numkeys ||

1604 elog(ERROR, "conppeqop is not a 1-D Oid array");

1607 pfree(arr);

1608 }

1609

1610 if (ff_eq_oprs)

1611 {

1616 ARR_DIMS(arr)[0] != numkeys ||

1619 elog(ERROR, "conffeqop is not a 1-D Oid array");

1622 pfree(arr);

1623 }

1624

1625 if (fk_del_set_cols)

1626 {

1629 if (isNull)

1630 {

1632 }

1633 else

1634 {

1636

1641 elog(ERROR, "confdelsetcols is not a 1-D smallint array");

1645 pfree(arr);

1646

1648 }

1649 }

1650

1652}

1653

1654

1655

1656

1657

1658

1659

1660

1661

1662

1663

1664

1665

1666

1667void

1672{

1676

1677

1679 {

1683 errmsg("invalid type for PERIOD part of foreign key"),

1684 errdetail("Only range and multirange are supported."));

1685

1686 }

1687 else

1688 elog(ERROR, "cache lookup failed for opclass %u", opclass);

1689

1690

1691

1692

1693

1694

1695

1701

1702

1703

1704

1705

1706

1712

1713 switch (opcintype)

1714 {

1717 break;

1720 break;

1721 default:

1722 elog(ERROR, "unexpected opcintype: %u", opcintype);

1723 }

1724}

1725

1726

1727

1728

1729

1730

1731

1732

1733

1734

1735

1736

1737

1738

1739

1740

1741bool

1746{

1751

1752

1755 return false;

1756

1757

1760 {

1762

1764 gvar->varno == varno &&

1765 gvar->varlevelsup == varlevelsup)

1768 }

1769

1771 {

1772

1774 return true;

1775 }

1776

1777 return false;

1778}

#define DatumGetArrayTypeP(X)

ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)

#define InvalidAttrNumber

bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)

Bitmapset * bms_add_member(Bitmapset *a, int x)

static Datum values[MAXATTR]

#define CStringGetTextDatum(s)

#define Assert(condition)

#define OidIsValid(objectId)

Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)

void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)

void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool reverse_self)

bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)

void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)

ObjectAddresses * new_object_addresses(void)

void free_object_addresses(ObjectAddresses *addrs)

@ DEPENDENCY_PARTITION_PRI

@ DEPENDENCY_PARTITION_SEC

int errcode(int sqlerrcode)

int errhint(const char *fmt,...) pg_attribute_printf(1

int errdetail(const char *fmt,...) pg_attribute_printf(1

#define ereport(elevel,...)

#define palloc_object(type)

char * format_type_be(Oid type_oid)

void systable_endscan(SysScanDesc sysscan)

HeapTuple systable_getnext(SysScanDesc sysscan)

SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)

HeapTuple heap_copytuple(HeapTuple tuple)

HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)

void heap_freetuple(HeapTuple htup)

#define HeapTupleIsValid(tuple)

static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)

static void * GETSTRUCT(const HeapTupleData *tuple)

char * makeObjectName(const char *name1, const char *name2, const char *label)

void GetOperatorFromCompareType(Oid opclass, Oid rhstype, CompareType cmptype, Oid *opid, StrategyNumber *strat)

void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)

void CatalogTupleInsert(Relation heapRel, HeapTuple tup)

void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)

static bool pg_add_s16_overflow(int16 a, int16 b, int16 *result)

List * lappend(List *list, void *datum)

List * lappend_oid(List *list, Oid datum)

#define AccessExclusiveLock

char * get_rel_name(Oid relid)

AttrNumber get_attnum(Oid relid, const char *attname)

bool get_opclass_opfamily_and_input_type(Oid opclass, Oid *opfamily, Oid *opcintype)

char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)

char * pstrdup(const char *in)

void pfree(void *pointer)

void namestrcpy(Name name, const char *str)

#define IsA(nodeptr, _type_)

#define InvokeObjectPostAlterHook(classId, objectId, subId)

#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)

#define ObjectAddressSet(addr, class_id, object_id)

#define ObjectAddressSubSet(addr, class_id, object_id, object_sub_id)

FormData_pg_class * Form_pg_class

Oid CreateConstraintEntry(const char *constraintName, Oid constraintNamespace, char constraintType, bool isDeferrable, bool isDeferred, bool isEnforced, bool isValidated, Oid parentConstrId, Oid relId, const int16 *constraintKey, int constraintNKeys, int constraintNTotalKeys, Oid domainId, Oid indexRelId, Oid foreignRelId, const int16 *foreignKey, const Oid *pfEqOp, const Oid *ppEqOp, const Oid *ffEqOp, int foreignNKeys, char foreignUpdateType, char foreignDeleteType, const int16 *fkDeleteSetCols, int numFkDeleteSetCols, char foreignMatchType, const Oid *exclOp, Node *conExpr, const char *conBin, bool conIsLocal, int16 conInhCount, bool conNoInherit, bool conPeriod, bool is_internal)

HeapTuple findNotNullConstraint(Oid relid, const char *colname)

bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, const char *conname)

void RemoveConstraintById(Oid conId)

bool AdjustNotNullInheritance(Oid relid, AttrNumber attnum, const char *new_conname, bool is_local, bool is_no_inherit, bool is_notvalid)

void FindFKPeriodOpers(Oid opclass, Oid *containedbyoperoid, Oid *aggedcontainedbyoperoid, Oid *intersectoperoid)

void RenameConstraintById(Oid conId, const char *newname)

Oid get_relation_idx_constraint_oid(Oid relationId, Oid indexId)

void ConstraintSetParentConstraint(Oid childConstrId, Oid parentConstrId, Oid childTableId)

Bitmapset * get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)

HeapTuple findDomainNotNullConstraint(Oid typid)

void DeconstructFkConstraintRow(HeapTuple tuple, int *numfks, AttrNumber *conkey, AttrNumber *confkey, Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs, int *num_fk_del_set_cols, AttrNumber *fk_del_set_cols)

HeapTuple findNotNullConstraintAttnum(Oid relid, AttrNumber attnum)

void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, Oid newNspId, bool isType, ObjectAddresses *objsMoved)

List * RelationGetNotNullConstraints(Oid relid, bool cooked, bool include_noinh)

bool ConstraintNameExists(const char *conname, Oid namespaceid)

char * ChooseConstraintName(const char *name1, const char *name2, const char *label, Oid namespaceid, List *others)

bool check_functional_grouping(Oid relid, Index varno, Index varlevelsup, List *grouping_columns, List **constraintDeps)

Bitmapset * get_relation_constraint_attnos(Oid relid, const char *conname, bool missing_ok, Oid *constraintOid)

Oid get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok)

AttrNumber extractNotNullColumn(HeapTuple constrTup)

Oid get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok)

END_CATALOG_STRUCT typedef FormData_pg_constraint * Form_pg_constraint

void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)

long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)

size_t strlcpy(char *dst, const char *src, size_t siz)

static Datum PointerGetDatum(const void *X)

static Datum Int16GetDatum(int16 X)

static Datum BoolGetDatum(bool X)

static Datum ObjectIdGetDatum(Oid X)

static Datum NameGetDatum(const NameData *X)

static Pointer DatumGetPointer(Datum X)

static Datum CStringGetDatum(const char *X)

static Datum CharGetDatum(char X)

#define RelationGetDescr(relation)

#define RelationGetRelationName(relation)

void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)

#define BTEqualStrategyNumber

#define ERRCODE_DUPLICATE_OBJECT

#define FirstLowInvalidHeapAttributeNumber

void ReleaseSysCache(HeapTuple tuple)

Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)

HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)

Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)

#define SearchSysCacheCopy1(cacheId, key1)

void table_close(Relation relation, LOCKMODE lockmode)

Relation table_open(Oid relationId, LOCKMODE lockmode)

String * makeString(char *str)