67 #include "catalog/schemapg.h"
84 #include "utils/fmgroids.h"
93 #define RELCACHE_INIT_FILEMAGIC 0x573266
99 #if defined(RECOVER_RELATION_BUILD_MEMORY) && (RECOVER_RELATION_BUILD_MEMORY != 0)
100 #define MAYBE_RECOVER_RELATION_BUILD_MEMORY 1
102 #define RECOVER_RELATION_BUILD_MEMORY 0
103 #ifdef DISCARD_CACHES_ENABLED
104 #define MAYBE_RECOVER_RELATION_BUILD_MEMORY 1
184 #define MAX_EOXACT_LIST 32
189 #define EOXactListAdd(rel) \
191 if (eoxact_list_len < MAX_EOXACT_LIST) \
192 eoxact_list[eoxact_list_len++] = (rel)->rd_id; \
194 eoxact_list_overflowed = true; \
209 #define RelationCacheInsert(RELATION, replace_allowed) \
211 RelIdCacheEnt *hentry; bool found; \
212 hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
213 &((RELATION)->rd_id), \
214 HASH_ENTER, &found); \
218 Relation _old_rel = hentry->reldesc; \
219 Assert(replace_allowed); \
220 hentry->reldesc = (RELATION); \
221 if (RelationHasReferenceCountZero(_old_rel)) \
222 RelationDestroyRelation(_old_rel, false); \
223 else if (!IsBootstrapProcessingMode()) \
224 elog(WARNING, "leaking still-referenced relcache entry for \"%s\"", \
225 RelationGetRelationName(_old_rel)); \
228 hentry->reldesc = (RELATION); \
231 #define RelationIdCacheLookup(ID, RELATION) \
233 RelIdCacheEnt *hentry; \
234 hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
238 RELATION = hentry->reldesc; \
243 #define RelationCacheDelete(RELATION) \
245 RelIdCacheEnt *hentry; \
246 hentry = (RelIdCacheEnt *) hash_search(RelationIdCache, \
247 &((RELATION)->rd_id), \
248 HASH_REMOVE, NULL); \
249 if (hentry == NULL) \
250 elog(WARNING, "failed to delete relcache entry for OID %u", \
251 (RELATION)->rd_id); \
283 #ifdef USE_ASSERT_CHECKING
284 static void AssertPendingSyncConsistency(
Relation relation);
293 static void formrdesc(
const char *relationName,
Oid relationReltype,
352 elog(
FATAL,
"cannot read pg_class without having selected a database");
377 if (force_non_historic)
397 return pg_class_tuple;
441 relation->
rd_rel = relationForm;
473 switch (relation->
rd_rel->relkind)
475 case RELKIND_RELATION:
476 case RELKIND_TOASTVALUE:
478 case RELKIND_MATVIEW:
479 case RELKIND_PARTITIONED_TABLE:
483 case RELKIND_PARTITIONED_INDEX:
532 relation->
rd_rel->reltype ? relation->
rd_rel->reltype : RECORDOID;
546 Anum_pg_attribute_attrelid,
550 Anum_pg_attribute_attnum,
561 AttributeRelidNumIndexId,
580 elog(
ERROR,
"invalid attribute number %d for relation \"%s\"",
588 if (attp->attnotnull)
590 if (attp->attgenerated == ATTRIBUTE_GENERATED_STORED)
596 if (attp->atthasmissing)
603 Anum_pg_attribute_attmissingval,
604 pg_attribute_desc->
rd_att,
614 if (attrmiss == NULL)
617 relation->
rd_rel->relnatts *
658 elog(
ERROR,
"pg_attribute catalog is missing %d attribute(s) for relation OID %u",
666 #ifdef USE_ASSERT_CHECKING
690 relation->
rd_rel->relchecks > 0)
701 if (relation->
rd_rel->relchecks > 0)
768 Anum_pg_rewrite_ev_class,
783 RewriteRelRulenameIndexId,
799 rule->ruleId = rewrite_form->oid;
801 rule->event = rewrite_form->ev_type -
'0';
802 rule->enabled = rewrite_form->ev_enabled;
803 rule->isInstead = rewrite_form->is_instead;
812 Anum_pg_rewrite_ev_action,
823 Anum_pg_rewrite_ev_qual,
842 relation->
rd_rel->relkind == RELKIND_VIEW &&
846 check_as_user = relation->
rd_rel->relowner;
862 if (numlocks >= maxlocks)
940 else if (rlock2 != NULL)
985 else if (policy2 != NULL)
1002 if (rsdesc1 == NULL && rsdesc2 == NULL)
1005 if ((rsdesc1 != NULL && rsdesc2 == NULL) ||
1006 (rsdesc1 == NULL && rsdesc2 != NULL))
1040 int in_progress_offset;
1061 #ifdef MAYBE_RECOVER_RELATION_BUILD_MEMORY
1068 "RelationBuildDesc workspace",
1099 #ifdef MAYBE_RECOVER_RELATION_BUILD_MEMORY
1117 Assert(relid == targetRelId);
1140 switch (relation->
rd_rel->relpersistence)
1142 case RELPERSISTENCE_UNLOGGED:
1143 case RELPERSISTENCE_PERMANENT:
1147 case RELPERSISTENCE_TEMP:
1175 elog(
ERROR,
"invalid relpersistence: %c",
1176 relation->
rd_rel->relpersistence);
1204 if (relation->
rd_rel->relkind == RELKIND_INDEX ||
1205 relation->
rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
1207 else if (RELKIND_HAS_TABLE_AM(relation->
rd_rel->relkind) ||
1208 relation->
rd_rel->relkind == RELKIND_SEQUENCE)
1222 if (relation->
rd_rel->relhasrules)
1230 if (relation->
rd_rel->relhastriggers)
1235 if (relation->
rd_rel->relrowsecurity)
1291 #ifdef MAYBE_RECOVER_RELATION_BUILD_MEMORY
1316 if (!RELKIND_HAS_STORAGE(relation->
rd_rel->relkind))
1319 if (relation->
rd_rel->reltablespace)
1328 if (relation->
rd_rel->relfilenode)
1351 elog(
ERROR,
"could not find pg_class entry for %u",
1355 relation->
rd_rel->reltablespace = physrel->reltablespace;
1356 relation->
rd_rel->relfilenode = physrel->relfilenode;
1367 relation->
rd_rel->relisshared);
1369 elog(
ERROR,
"could not find relation mapping for relation \"%s\", OID %u",
1422 Datum indclassDatum;
1423 Datum indoptionDatum;
1442 elog(
ERROR,
"cache lookup failed for index %u",
1456 elog(
ERROR,
"cache lookup failed for access method %u",
1457 relation->
rd_rel->relam);
1464 elog(
ERROR,
"relnatts disagrees with indnatts for index %u",
1497 int nsupport = indnatts * amsupport;
1522 Anum_pg_index_indcollation,
1535 Anum_pg_index_indclass,
1548 amsupport, indnkeyatts);
1554 Anum_pg_index_indoption,
1597 for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
1609 opFamily[attIndex] = opcentry->
opcfamily;
1610 opcInType[attIndex] = opcentry->
opcintype;
1611 if (maxSupportNumber > 0)
1612 memcpy(&indexSupport[attIndex * maxSupportNumber],
1672 opcentry->
valid =
false;
1690 #ifdef DISCARD_CACHES_ENABLED
1692 opcentry->
valid =
false;
1695 if (opcentry->
valid)
1713 (operatorClassOid != OID_BTREE_OPS_OID &&
1714 operatorClassOid != INT2_BTREE_OPS_OID);
1723 Anum_pg_opclass_oid,
1734 opcentry->
opcfamily = opclassform->opcfamily;
1735 opcentry->
opcintype = opclassform->opcintype;
1738 elog(
ERROR,
"could not find tuple for opclass %u", operatorClassOid);
1750 Anum_pg_amproc_amprocfamily,
1754 Anum_pg_amproc_amproclefttype,
1758 Anum_pg_amproc_amprocrighttype,
1769 if (amprocform->amprocnum <= 0 ||
1771 elog(
ERROR,
"invalid amproc number %d for opclass %u",
1772 amprocform->amprocnum, operatorClassOid);
1782 opcentry->
valid =
true;
1806 if (relation->
rd_rel->relkind == RELKIND_SEQUENCE)
1834 elog(
ERROR,
"cache lookup failed for access method %u",
1835 relation->
rd_rel->relam);
1911 relation->
rd_rel->relnamespace = PG_CATALOG_NAMESPACE;
1912 relation->
rd_rel->reltype = relationReltype;
1918 relation->
rd_rel->relisshared = isshared;
1920 relation->
rd_rel->reltablespace = GLOBALTABLESPACE_OID;
1923 relation->
rd_rel->relpersistence = RELPERSISTENCE_PERMANENT;
1926 relation->
rd_rel->relispopulated =
true;
1928 relation->
rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
1929 relation->
rd_rel->relpages = 0;
1930 relation->
rd_rel->reltuples = -1;
1931 relation->
rd_rel->relallvisible = 0;
1932 relation->
rd_rel->relkind = RELKIND_RELATION;
1934 relation->
rd_rel->relam = HEAP_TABLE_AM_OID;
1952 has_not_null =
false;
1953 for (
i = 0;
i < natts;
i++)
1958 has_not_null |= attrs[
i].attnotnull;
2005 relation->
rd_rel->relam = HEAP_TABLE_AM_OID;
2014 relation->
rd_rel->relhasindex =
false;
2019 relation->
rd_rel->relhasindex =
true;
2084 if (rd->
rd_rel->relkind == RELKIND_INDEX ||
2085 rd->
rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
2181 #ifdef RELCACHE_FORCE_RELEASE
2225 relation->
rd_rel->relkind == RELKIND_PARTITIONED_INDEX) &&
2259 elog(
ERROR,
"could not find pg_class tuple for index %u",
2288 elog(
ERROR,
"cache lookup failed for index %u",
2299 relation->
rd_index->indnullsnotdistinct =
index->indnullsnotdistinct;
2353 if (relation->
rd_rel->relkind == RELKIND_INDEX)
2435 if (remember_tupdesc)
2546 if ((relation->
rd_rel->relkind == RELKIND_INDEX ||
2547 relation->
rd_rel->relkind == RELKIND_PARTITIONED_INDEX) &&
2663 elog(
ERROR,
"relation %u deleted while still in use", save_relid);
2677 keep_partkey = (relation->
rd_partkey != NULL);
2689 #define SWAPFIELD(fldtype, fldname) \
2691 fldtype _tmp = newrel->fldname; \
2692 newrel->fldname = relation->fldname; \
2693 relation->fldname = _tmp; \
2844 elog(
ERROR,
"relation %u is still open", rid);
2999 rebuildFirstList =
lcons(relation, rebuildFirstList);
3001 rebuildFirstList =
lappend(rebuildFirstList, relation);
3003 rebuildList =
lcons(relation, rebuildList);
3005 rebuildList =
lappend(rebuildList, relation);
3017 foreach(l, rebuildFirstList)
3023 foreach(l, rebuildList)
3083 #ifdef USE_ASSERT_CHECKING
3085 AssertPendingSyncConsistency(
Relation relation)
3087 bool relcache_verdict =
3090 RELKIND_HAS_STORAGE(relation->
rd_rel->relkind)) ||
3126 rels =
palloc(maxrels *
sizeof(*rels));
3134 if (locallock->
nLocks <= 0)
3143 if (nrels >= maxrels)
3146 rels =
repalloc(rels, maxrels *
sizeof(*rels));
3153 AssertPendingSyncConsistency(idhentry->
reldesc);
3155 for (
i = 0;
i < nrels;
i++)
3218 if (idhentry != NULL)
3250 bool clear_relcache =
false;
3266 #ifdef USE_ASSERT_CHECKING
3269 int expected_refcnt;
3316 elog(
WARNING,
"cannot remove relcache entry for \"%s\" because it has nonzero refcount",
3356 mySubid, parentSubid);
3367 if (idhentry != NULL)
3369 mySubid, parentSubid);
3426 elog(
WARNING,
"cannot remove relcache entry for \"%s\" because it has nonzero refcount",
3474 bool shared_relation,
3475 bool mapped_relation,
3476 char relpersistence,
3481 int natts = tupDesc->
natts;
3496 case DatabaseRelationId:
3497 case AuthIdRelationId:
3498 case AuthMemRelationId:
3499 case RelationRelationId:
3500 case AttributeRelationId:
3501 case ProcedureRelationId:
3502 case TypeRelationId:
3517 elog(
ERROR,
"shared_relation flag for \"%s\" does not match IsSharedRelation(%u)",
3521 Assert(mapped_relation || !shared_relation);
3559 has_not_null =
false;
3560 for (
i = 0;
i < natts;
i++)
3565 datt->attidentity = satt->attidentity;
3566 datt->attgenerated = satt->attgenerated;
3567 datt->attnotnull = satt->attnotnull;
3568 has_not_null |= satt->attnotnull;
3585 rel->
rd_rel->relnamespace = relnamespace;
3587 rel->
rd_rel->relkind = relkind;
3588 rel->
rd_rel->relnatts = natts;
3591 rel->
rd_rel->relowner = BOOTSTRAP_SUPERUSERID;
3594 rel->
rd_rel->relpersistence = relpersistence;
3595 switch (relpersistence)
3597 case RELPERSISTENCE_UNLOGGED:
3598 case RELPERSISTENCE_PERMANENT:
3602 case RELPERSISTENCE_TEMP:
3608 elog(
ERROR,
"invalid relpersistence: %c", relpersistence);
3613 if (relkind == RELKIND_MATVIEW)
3614 rel->
rd_rel->relispopulated =
false;
3616 rel->
rd_rel->relispopulated =
true;
3620 (relkind == RELKIND_RELATION ||
3621 relkind == RELKIND_MATVIEW ||
3622 relkind == RELKIND_PARTITIONED_TABLE))
3623 rel->
rd_rel->relreplident = REPLICA_IDENTITY_DEFAULT;
3625 rel->
rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
3632 rel->
rd_rel->relisshared = shared_relation;
3636 for (
i = 0;
i < natts;
i++)
3639 rel->
rd_rel->reltablespace = reltablespace;
3641 if (mapped_relation)
3648 rel->
rd_rel->relfilenode = relfilenumber;
3654 rel->
rd_rel->relam = accessmtd;
3663 if (RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_SEQUENCE)
3726 else if (relation->
rd_rel->relkind == RELKIND_INDEX)
3730 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3731 errmsg(
"index relfilenumber value not set when in binary upgrade mode")));
3736 else if (relation->
rd_rel->relkind == RELKIND_RELATION)
3740 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3741 errmsg(
"heap relfilenumber value not set when in binary upgrade mode")));
3748 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3749 errmsg(
"unexpected request for new relfilenumber in binary upgrade mode")));
3759 elog(
ERROR,
"could not find tuple for relation %u",
3805 newrlocator.
relNumber = newrelfilenumber;
3807 if (RELKIND_HAS_TABLE_AM(relation->
rd_rel->relkind))
3811 &freezeXid, &minmulti);
3813 else if (RELKIND_HAS_STORAGE(relation->
rd_rel->relkind))
3824 elog(
ERROR,
"relation \"%s\" does not have storage",
3843 Assert(classform->relfrozenxid == freezeXid);
3844 Assert(classform->relminmxid == minmulti);
3845 Assert(classform->relpersistence == persistence);
3858 relation->
rd_rel->relisshared,
3867 classform->relfilenode = newrelfilenumber;
3870 if (relation->
rd_rel->relkind != RELKIND_SEQUENCE)
3872 classform->relpages = 0;
3873 classform->reltuples = -1;
3874 classform->relallvisible = 0;
3876 classform->relfrozenxid = freezeXid;
3877 classform->relminmxid = minmulti;
3878 classform->relpersistence = persistence;
3932 #define INITRELCACHESIZE 400
4008 formrdesc(
"pg_database", DatabaseRelation_Rowtype_Id,
true,
4010 formrdesc(
"pg_authid", AuthIdRelation_Rowtype_Id,
true,
4012 formrdesc(
"pg_auth_members", AuthMemRelation_Rowtype_Id,
true,
4014 formrdesc(
"pg_shseclabel", SharedSecLabelRelation_Rowtype_Id,
true,
4016 formrdesc(
"pg_subscription", SubscriptionRelation_Rowtype_Id,
true,
4019 #define NUM_CRITICAL_SHARED_RELS 5
4065 needNewCacheFile =
true;
4067 formrdesc(
"pg_class", RelationRelation_Rowtype_Id,
false,
4069 formrdesc(
"pg_attribute", AttributeRelation_Rowtype_Id,
false,
4071 formrdesc(
"pg_proc", ProcedureRelation_Rowtype_Id,
false,
4073 formrdesc(
"pg_type", TypeRelation_Rowtype_Id,
false,
4076 #define NUM_CRITICAL_LOCAL_RELS 4
4113 RelationRelationId);
4115 AttributeRelationId);
4119 OperatorClassRelationId);
4121 AccessMethodProcedureRelationId);
4127 #define NUM_CRITICAL_LOCAL_INDEXES 7
4147 DatabaseRelationId);
4149 DatabaseRelationId);
4157 SharedSecLabelRelationId);
4159 #define NUM_CRITICAL_SHARED_INDEXES 6
4185 bool restart =
false;
4203 elog(
FATAL,
"cache lookup failed for relation %u",
4231 elog(
ERROR,
"invalid relowner in pg_class entry for \"%s\"",
4249 relation->
rd_rel->relhasrules =
false;
4252 if (relation->
rd_rel->relhastriggers && relation->
trigdesc == NULL)
4256 relation->
rd_rel->relhastriggers =
false;
4277 (RELKIND_HAS_TABLE_AM(relation->
rd_rel->relkind) || relation->
rd_rel->relkind == RELKIND_SEQUENCE))
4300 if (needNewCacheFile)
4337 elog(
PANIC,
"could not open critical system index %u", indexoid);
4371 for (
i = 0;
i < natts;
i++)
4394 if (pgclassdesc == NULL)
4407 if (pgindexdesc == NULL)
4440 Anum_pg_attrdef_adrelid,
4457 elog(
WARNING,
"unexpected pg_attrdef record found for attribute %d of relation \"%s\"",
4463 Anum_pg_attrdef_adbin,
4466 elog(
WARNING,
"null adbin for attribute %d of relation \"%s\"",
4473 attrdef[found].
adnum = adform->adnum;
4484 elog(
WARNING,
"%d pg_attrdef record(s) missing for relation \"%s\"",
4522 int ncheck = relation->
rd_rel->relchecks;
4536 Anum_pg_constraint_conrelid,
4551 if (conform->contype != CONSTRAINT_CHECK)
4555 if (found >= ncheck)
4557 elog(
WARNING,
"unexpected pg_constraint record found for relation \"%s\"",
4562 check[found].
ccvalid = conform->convalidated;
4569 Anum_pg_constraint_conbin,
4570 conrel->
rd_att, &isnull);
4588 if (found != ncheck)
4589 elog(
WARNING,
"%d pg_constraint record(s) missing for relation \"%s\"",
4646 if (!relation->
rd_rel->relhastriggers &&
4647 relation->
rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
4660 Anum_pg_constraint_conrelid,
4674 if (constraint->contype != CONSTRAINT_FOREIGN)
4678 info->
conoid = constraint->oid;
4679 info->
conrelid = constraint->conrelid;
4680 info->
confrelid = constraint->confrelid;
4686 NULL, NULL, NULL, NULL);
4689 result =
lappend(result, info);
4748 char replident = relation->
rd_rel->relreplident;
4767 Anum_pg_index_indrelid,
4785 if (!
index->indislive)
4796 if (!
index->indisunique ||
4797 !
index->indimmediate ||
4819 if (
index->indisprimary &&
4820 (
index->indisvalid ||
4821 relation->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
4822 pkeyIndex =
index->indexrelid;
4824 if (!
index->indisvalid)
4828 if (
index->indisreplident)
4829 candidateIndex =
index->indexrelid;
4844 if (replident == REPLICA_IDENTITY_DEFAULT &&
OidIsValid(pkeyIndex))
4846 else if (replident == REPLICA_IDENTITY_INDEX &&
OidIsValid(candidateIndex))
4908 Anum_pg_statistic_ext_stxrelid,
5019 Anum_pg_index_indexprs,
5071 Anum_pg_index_indexprs,
5081 foreach(lc, rawExprs)
5132 Anum_pg_index_indpred,
5206 List *newindexoidlist;
5228 elog(
ERROR,
"unknown attrKind %u", attrKind);
5243 if (indexoidlist ==
NIL)
5267 pkindexattrs = NULL;
5268 idindexattrs = NULL;
5269 hotblockingattrs = NULL;
5270 summarizedattrs = NULL;
5271 foreach(l, indexoidlist)
5277 Node *indexExpressions;
5278 Node *indexPredicate;
5301 indexExpressions = NULL;
5308 indexPredicate = NULL;
5311 isKey = indexDesc->
rd_index->indisunique &&
5312 indexExpressions == NULL &&
5313 indexPredicate == NULL;
5316 isPK = (indexOid == relpkindex);
5319 isIDKey = (indexOid == relreplindex);
5327 attrs = &summarizedattrs;
5329 attrs = &hotblockingattrs;
5332 for (
i = 0;
i < indexDesc->
rd_index->indnatts;
i++)
5334 int attrnum = indexDesc->
rd_index->indkey.values[
i];
5355 if (isKey && i < indexDesc->rd_index->indnkeyatts)
5359 if (isPK && i < indexDesc->rd_index->indnkeyatts)
5363 if (isIDKey && i < indexDesc->rd_index->indnkeyatts)
5385 if (
equal(indexoidlist, newindexoidlist) &&
5442 return pkindexattrs;
5444 return idindexattrs;
5446 return hotblockingattrs;
5448 return summarizedattrs;
5450 elog(
ERROR,
"unknown attrKind %u", attrKind);
5500 elog(
ERROR,
"could not open relation with OID %u",
5504 for (
i = 0;
i < indexDesc->
rd_index->indnatts;
i++)
5506 int attrnum = indexDesc->
rd_index->indkey.values[
i];
5514 if (i < indexDesc->rd_index->indnkeyatts)
5532 return idindexattrs;
5565 *operators = ops = (
Oid *)
palloc(
sizeof(
Oid) * indnkeyatts);
5566 *procs = funcs = (
Oid *)
palloc(
sizeof(
Oid) * indnkeyatts);
5572 memcpy(ops, indexRelation->
rd_exclops,
sizeof(
Oid) * indnkeyatts);
5573 memcpy(funcs, indexRelation->
rd_exclprocs,
sizeof(
Oid) * indnkeyatts);
5588 Anum_pg_constraint_conrelid,
5606 if (conform->contype != CONSTRAINT_EXCLUSION ||
5612 elog(
ERROR,
"unexpected exclusion constraint record found for rel %s",
5618 Anum_pg_constraint_conexclop,
5619 conrel->
rd_att, &isnull);
5621 elog(
ERROR,
"null conexclop for rel %s",
5627 nelem != indnkeyatts ||
5630 elog(
ERROR,
"conexclop is not a 1-D Oid array");
5639 elog(
ERROR,
"exclusion constraint record missing for rel %s",
5643 for (
i = 0;
i < indnkeyatts;
i++)
5650 elog(
ERROR,
"could not find strategy for operator %u in family %u",
5659 memcpy(indexRelation->
rd_exclops, ops,
sizeof(
Oid) * indnkeyatts);
5660 memcpy(indexRelation->
rd_exclprocs, funcs,
sizeof(
Oid) * indnkeyatts);
5717 if (relation->
rd_rel->relispartition)
5722 foreach(lc, ancestors)
5735 foreach(lc, puboids)
5744 elog(
ERROR,
"cache lookup failed for publication %u", pubid);
5760 if (!pubform->puballtables &&
5761 (pubform->pubupdate || pubform->pubdelete) &&
5763 pubform->pubviaroot))
5765 if (pubform->pubupdate)
5767 if (pubform->pubdelete)
5777 if (!pubform->puballtables &&
5778 (pubform->pubupdate || pubform->pubdelete) &&
5780 pubform->pubviaroot))
5782 if (pubform->pubupdate)
5784 if (pubform->pubdelete)