mirror of
https://github.com/postgres/postgres.git
synced 2025-05-06 19:59:18 +03:00
Fetch information about DEFAULT/CHECK while openning a relation.
This commit is contained in:
parent
9b6d8878fd
commit
ac0029aa0b
157
src/backend/utils/cache/relcache.c
vendored
157
src/backend/utils/cache/relcache.c
vendored
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.18 1997/08/21 04:09:51 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.19 1997/08/22 03:35:44 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -82,6 +82,7 @@
|
|||||||
#include "catalog/pg_log.h"
|
#include "catalog/pg_log.h"
|
||||||
#include "catalog/pg_time.h"
|
#include "catalog/pg_time.h"
|
||||||
#include "catalog/pg_attrdef.h"
|
#include "catalog/pg_attrdef.h"
|
||||||
|
#include "catalog/pg_relcheck.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "fmgr.h"
|
#include "fmgr.h"
|
||||||
@ -260,6 +261,7 @@ static void build_tupdesc_ind(RelationBuildDescInfo buildinfo,
|
|||||||
static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo);
|
static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo);
|
||||||
static void IndexedAccessMethodInitialize(Relation relation);
|
static void IndexedAccessMethodInitialize(Relation relation);
|
||||||
static void AttrDefaultFetch (Relation relation);
|
static void AttrDefaultFetch (Relation relation);
|
||||||
|
static void RelCheckFetch (Relation relation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newlyCreatedRelns -
|
* newlyCreatedRelns -
|
||||||
@ -482,7 +484,7 @@ AllocateRelationDesc(u_int natts, Form_pg_class relp)
|
|||||||
* RelationBuildTupleDesc
|
* RelationBuildTupleDesc
|
||||||
*
|
*
|
||||||
* Form the relation's tuple descriptor from information in
|
* Form the relation's tuple descriptor from information in
|
||||||
* the pg_attribute system catalog.
|
* the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
|
||||||
* --------------------------------
|
* --------------------------------
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
@ -499,13 +501,7 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
|
|||||||
if (IsBootstrapProcessingMode())
|
if (IsBootstrapProcessingMode())
|
||||||
build_tupdesc_seq(buildinfo, relation, natts);
|
build_tupdesc_seq(buildinfo, relation, natts);
|
||||||
else
|
else
|
||||||
{
|
|
||||||
relation->rd_att->constr = (TupleConstr *) palloc(sizeof(TupleConstr));
|
|
||||||
relation->rd_att->constr->num_check = 0;
|
|
||||||
relation->rd_att->constr->num_defval = 0;
|
|
||||||
relation->rd_att->constr->has_not_null = false;
|
|
||||||
build_tupdesc_ind(buildinfo, relation, natts);
|
build_tupdesc_ind(buildinfo, relation, natts);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -580,10 +576,13 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
|
|||||||
Relation attrel;
|
Relation attrel;
|
||||||
HeapTuple atttup;
|
HeapTuple atttup;
|
||||||
AttributeTupleForm attp;
|
AttributeTupleForm attp;
|
||||||
|
TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
|
||||||
AttrDefault *attrdef = NULL;
|
AttrDefault *attrdef = NULL;
|
||||||
int ndef = 0;
|
int ndef = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
constr->has_not_null = false;
|
||||||
|
|
||||||
attrel = heap_openr(AttributeRelationName);
|
attrel = heap_openr(AttributeRelationName);
|
||||||
|
|
||||||
for (i = 1; i <= relation->rd_rel->relnatts; i++) {
|
for (i = 1; i <= relation->rd_rel->relnatts; i++) {
|
||||||
@ -604,7 +603,7 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
|
|||||||
|
|
||||||
/* Update if this attribute have a constraint */
|
/* Update if this attribute have a constraint */
|
||||||
if (attp->attnotnull)
|
if (attp->attnotnull)
|
||||||
relation->rd_att->constr->has_not_null = true;
|
constr->has_not_null = true;
|
||||||
|
|
||||||
if (attp->atthasdef)
|
if (attp->atthasdef)
|
||||||
{
|
{
|
||||||
@ -619,16 +618,39 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
heap_close(attrel);
|
heap_close(attrel);
|
||||||
|
|
||||||
if ( ndef > 0 )
|
if ( constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks )
|
||||||
{
|
{
|
||||||
if ( ndef > relation->rd_rel->relnatts )
|
relation->rd_att->constr = constr;
|
||||||
relation->rd_att->constr->defval = (AttrDefault*)
|
|
||||||
|
if ( ndef > 0 ) /* DEFAULTs */
|
||||||
|
{
|
||||||
|
if ( ndef < relation->rd_rel->relnatts )
|
||||||
|
constr->defval = (AttrDefault*)
|
||||||
repalloc (attrdef, ndef * sizeof (AttrDefault));
|
repalloc (attrdef, ndef * sizeof (AttrDefault));
|
||||||
|
else
|
||||||
|
constr->defval = attrdef;
|
||||||
|
constr->num_defval = ndef;
|
||||||
|
AttrDefaultFetch (relation);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
relation->rd_att->constr->defval = attrdef;
|
constr->num_defval = 0;
|
||||||
relation->rd_att->constr->num_defval = ndef;
|
|
||||||
AttrDefaultFetch (relation);
|
if ( relation->rd_rel->relchecks > 0 ) /* CHECKs */
|
||||||
|
{
|
||||||
|
constr->num_check = relation->rd_rel->relchecks;
|
||||||
|
constr->check = (ConstrCheck *) palloc (constr->num_check *
|
||||||
|
sizeof (ConstrCheck));
|
||||||
|
memset (constr->check, 0, constr->num_check * sizeof (ConstrCheck));
|
||||||
|
RelCheckFetch (relation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
constr->num_check = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pfree (constr);
|
||||||
|
relation->rd_att->constr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1252,8 +1274,6 @@ static void
|
|||||||
RelationFlushRelation(Relation *relationPtr,
|
RelationFlushRelation(Relation *relationPtr,
|
||||||
bool onlyFlushReferenceCountZero)
|
bool onlyFlushReferenceCountZero)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
AttributeTupleForm *p;
|
|
||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
Relation relation = *relationPtr;
|
Relation relation = *relationPtr;
|
||||||
|
|
||||||
@ -1268,14 +1288,8 @@ RelationFlushRelation(Relation *relationPtr,
|
|||||||
oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
|
oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
|
||||||
|
|
||||||
RelationCacheDelete(relation);
|
RelationCacheDelete(relation);
|
||||||
|
|
||||||
p = relation->rd_att->attrs;
|
FreeTupleDesc (relation->rd_att);
|
||||||
for (i = 0; i < relation->rd_rel->relnatts; i++, p++)
|
|
||||||
pfree (*p);
|
|
||||||
pfree (relation->rd_att->attrs);
|
|
||||||
if (relation->rd_att->constr)
|
|
||||||
pfree (relation->rd_att->constr);
|
|
||||||
pfree (relation->rd_att);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (relation->rd_rules) {
|
if (relation->rd_rules) {
|
||||||
@ -1641,8 +1655,9 @@ AttrDefaultFetch (Relation relation)
|
|||||||
pfree(indexRes);
|
pfree(indexRes);
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
continue;
|
continue;
|
||||||
|
found++;
|
||||||
adform = (Form_pg_attrdef) GETSTRUCT(tuple);
|
adform = (Form_pg_attrdef) GETSTRUCT(tuple);
|
||||||
for (i = 1; i <= ndef; i++)
|
for (i = 0; i < ndef; i++)
|
||||||
{
|
{
|
||||||
if ( adform->adnum != attrdef[i].adnum )
|
if ( adform->adnum != attrdef[i].adnum )
|
||||||
continue;
|
continue;
|
||||||
@ -1667,10 +1682,10 @@ AttrDefaultFetch (Relation relation)
|
|||||||
NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
|
NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
|
||||||
NAMEDATALEN, relation->rd_rel->relname.data);
|
NAMEDATALEN, relation->rd_rel->relname.data);
|
||||||
attrdef[i].adsrc = textout (val);
|
attrdef[i].adsrc = textout (val);
|
||||||
found++;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( i > ndef )
|
if ( i >= ndef )
|
||||||
elog (WARN, "AttrDefaultFetch: unexpected record found for attr %d in rel %.*s",
|
elog (WARN, "AttrDefaultFetch: unexpected record found for attr %d in rel %.*s",
|
||||||
adform->adnum,
|
adform->adnum,
|
||||||
NAMEDATALEN, relation->rd_rel->relname.data);
|
NAMEDATALEN, relation->rd_rel->relname.data);
|
||||||
@ -1689,6 +1704,88 @@ AttrDefaultFetch (Relation relation)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
RelCheckFetch (Relation relation)
|
||||||
|
{
|
||||||
|
ConstrCheck *check = relation->rd_att->constr->check;
|
||||||
|
int ncheck = relation->rd_att->constr->num_check;
|
||||||
|
Relation rcrel;
|
||||||
|
Relation irel;
|
||||||
|
ScanKeyData skey;
|
||||||
|
HeapTuple tuple;
|
||||||
|
IndexScanDesc sd;
|
||||||
|
RetrieveIndexResult indexRes;
|
||||||
|
Buffer buffer;
|
||||||
|
ItemPointer iptr;
|
||||||
|
Name rcname;
|
||||||
|
struct varlena *val;
|
||||||
|
bool isnull;
|
||||||
|
int found;
|
||||||
|
|
||||||
|
ScanKeyEntryInitialize(&skey,
|
||||||
|
(bits16)0x0,
|
||||||
|
(AttrNumber)1,
|
||||||
|
(RegProcedure)ObjectIdEqualRegProcedure,
|
||||||
|
ObjectIdGetDatum(relation->rd_id));
|
||||||
|
|
||||||
|
rcrel = heap_openr(RelCheckRelationName);
|
||||||
|
irel = index_openr(RelCheckIndex);
|
||||||
|
sd = index_beginscan(irel, false, 1, &skey);
|
||||||
|
tuple = (HeapTuple)NULL;
|
||||||
|
|
||||||
|
for (found = 0; ; )
|
||||||
|
{
|
||||||
|
indexRes = index_getnext(sd, ForwardScanDirection);
|
||||||
|
if (!indexRes)
|
||||||
|
break;
|
||||||
|
|
||||||
|
iptr = &indexRes->heap_iptr;
|
||||||
|
tuple = heap_fetch(rcrel, NowTimeQual, iptr, &buffer);
|
||||||
|
pfree(indexRes);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
continue;
|
||||||
|
if ( found == ncheck )
|
||||||
|
elog (WARN, "RelCheckFetch: unexpected record found for rel %.*s",
|
||||||
|
NAMEDATALEN, relation->rd_rel->relname.data);
|
||||||
|
|
||||||
|
rcname = (Name) fastgetattr (tuple,
|
||||||
|
Anum_pg_relcheck_rcname,
|
||||||
|
rcrel->rd_att, &isnull);
|
||||||
|
if ( isnull )
|
||||||
|
elog (WARN, "RelCheckFetch: rcname IS NULL for rel %.*s",
|
||||||
|
NAMEDATALEN, relation->rd_rel->relname.data);
|
||||||
|
check[found].ccname = nameout (rcname);
|
||||||
|
val = (struct varlena*) fastgetattr (tuple,
|
||||||
|
Anum_pg_relcheck_rcbin,
|
||||||
|
rcrel->rd_att, &isnull);
|
||||||
|
if ( isnull )
|
||||||
|
elog (WARN, "RelCheckFetch: rcbin IS NULL for rel %.*s",
|
||||||
|
NAMEDATALEN, relation->rd_rel->relname.data);
|
||||||
|
check[found].ccbin = textout (val);
|
||||||
|
val = (struct varlena*) fastgetattr (tuple,
|
||||||
|
Anum_pg_relcheck_rcsrc,
|
||||||
|
rcrel->rd_att, &isnull);
|
||||||
|
if ( isnull )
|
||||||
|
elog (WARN, "RelCheckFetch: rcsrc IS NULL for rel %.*s",
|
||||||
|
NAMEDATALEN, relation->rd_rel->relname.data);
|
||||||
|
check[found].ccsrc = textout (val);
|
||||||
|
found++;
|
||||||
|
|
||||||
|
ReleaseBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( found < ncheck )
|
||||||
|
elog (WARN, "RelCheckFetch: %d record not found for rel %.*s",
|
||||||
|
ncheck - found,
|
||||||
|
NAMEDATALEN, relation->rd_rel->relname.data);
|
||||||
|
|
||||||
|
index_endscan (sd);
|
||||||
|
pfree (sd);
|
||||||
|
index_close (irel);
|
||||||
|
heap_close (rcrel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* init_irels(), write_irels() -- handle special-case initialization of
|
* init_irels(), write_irels() -- handle special-case initialization of
|
||||||
* index relation descriptors.
|
* index relation descriptors.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user