mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
DefineRelation: DEFAULT/CHECK handling
This commit is contained in:
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.13 1997/08/21 04:05:22 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.14 1997/08/22 03:03:56 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
static int checkAttrExists(char *attributeName,
|
static int checkAttrExists(char *attributeName,
|
||||||
char *attributeType, List *schema);
|
char *attributeType, List *schema);
|
||||||
static List *MergeAttributes(List *schema, List *supers);
|
static List *MergeAttributes(List *schema, List *supers, List **supconstr);
|
||||||
static void StoreCatalogInheritance(Oid relationId, List *supers);
|
static void StoreCatalogInheritance(Oid relationId, List *supers);
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
@ -46,15 +46,16 @@ static void StoreCatalogInheritance(Oid relationId, List *supers);
|
|||||||
void
|
void
|
||||||
DefineRelation(CreateStmt *stmt)
|
DefineRelation(CreateStmt *stmt)
|
||||||
{
|
{
|
||||||
char *relname = palloc(NAMEDATALEN);
|
char *relname = palloc(NAMEDATALEN);
|
||||||
List *schema = stmt->tableElts;
|
List *schema = stmt->tableElts;
|
||||||
int numberOfAttributes;
|
int numberOfAttributes;
|
||||||
Oid relationId;
|
Oid relationId;
|
||||||
char archChar;
|
char archChar;
|
||||||
List *inheritList = NULL;
|
List *inheritList = NULL;
|
||||||
char *archiveName = NULL;
|
char *archiveName = NULL;
|
||||||
TupleDesc descriptor;
|
TupleDesc descriptor;
|
||||||
int heaploc, archloc;
|
List *constraints;
|
||||||
|
int heaploc, archloc;
|
||||||
|
|
||||||
char* typename = NULL; /* the typename of this relation. not useod for now */
|
char* typename = NULL; /* the typename of this relation. not useod for now */
|
||||||
|
|
||||||
@ -116,7 +117,8 @@ DefineRelation(CreateStmt *stmt)
|
|||||||
* generate relation schema, including inherited attributes.
|
* generate relation schema, including inherited attributes.
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
schema = MergeAttributes(schema, inheritList);
|
schema = MergeAttributes(schema, inheritList, &constraints);
|
||||||
|
constraints = nconc (constraints, stmt->constraints);
|
||||||
|
|
||||||
numberOfAttributes = length(schema);
|
numberOfAttributes = length(schema);
|
||||||
if (numberOfAttributes <= 0) {
|
if (numberOfAttributes <= 0) {
|
||||||
@ -130,6 +132,55 @@ DefineRelation(CreateStmt *stmt)
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
descriptor = BuildDescForRelation(schema, relname);
|
descriptor = BuildDescForRelation(schema, relname);
|
||||||
|
|
||||||
|
if ( constraints != NIL )
|
||||||
|
{
|
||||||
|
List *entry;
|
||||||
|
int nconstr = length (constraints);
|
||||||
|
ConstrCheck *check = (ConstrCheck *) palloc (nconstr * sizeof (ConstrCheck));
|
||||||
|
int ncheck = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
foreach (entry, constraints)
|
||||||
|
{
|
||||||
|
ConstraintDef *cdef = (ConstraintDef *) lfirst (entry);
|
||||||
|
|
||||||
|
if ( cdef->type == CONSTR_CHECK )
|
||||||
|
{
|
||||||
|
if ( cdef->name != NULL )
|
||||||
|
{
|
||||||
|
for (i = 0; i < ncheck; i++)
|
||||||
|
{
|
||||||
|
if ( strcmp (check[i].ccname, cdef->name) == 0 )
|
||||||
|
elog (WARN, "DefineRelation: name (%s) of CHECK constraint duplicated", cdef->name);
|
||||||
|
}
|
||||||
|
check[ncheck].ccname = cdef->name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
check[ncheck].ccname = (char*) palloc (NAMEDATALEN);
|
||||||
|
sprintf (check[ncheck].ccname, "$%d", ncheck + 1);
|
||||||
|
}
|
||||||
|
check[ncheck].ccbin = NULL;
|
||||||
|
check[ncheck].ccsrc = (char*) cdef->def;
|
||||||
|
ncheck++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ncheck > 0 )
|
||||||
|
{
|
||||||
|
if ( ncheck < nconstr )
|
||||||
|
check = (ConstrCheck *) repalloc (check, ncheck * sizeof (ConstrCheck));
|
||||||
|
if ( descriptor->constr == NULL )
|
||||||
|
{
|
||||||
|
descriptor->constr = (TupleConstr *) palloc(sizeof(TupleConstr));
|
||||||
|
descriptor->constr->num_defval = 0;
|
||||||
|
descriptor->constr->has_not_null = false;
|
||||||
|
}
|
||||||
|
descriptor->constr->num_check = ncheck;
|
||||||
|
descriptor->constr->check = check;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
relationId = heap_create(relname,
|
relationId = heap_create(relname,
|
||||||
typename,
|
typename,
|
||||||
archChar,
|
archChar,
|
||||||
@ -138,11 +189,12 @@ DefineRelation(CreateStmt *stmt)
|
|||||||
|
|
||||||
StoreCatalogInheritance(relationId, inheritList);
|
StoreCatalogInheritance(relationId, inheritList);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* create an archive relation if necessary
|
* create an archive relation if necessary
|
||||||
* ----------------
|
|
||||||
*/
|
*/
|
||||||
if (archChar != 'n') {
|
if (archChar != 'n')
|
||||||
|
{
|
||||||
|
TupleDesc tupdesc;
|
||||||
/*
|
/*
|
||||||
* Need to create an archive relation for this heap relation.
|
* Need to create an archive relation for this heap relation.
|
||||||
* We cobble up the command by hand, and increment the command
|
* We cobble up the command by hand, and increment the command
|
||||||
@ -152,12 +204,15 @@ DefineRelation(CreateStmt *stmt)
|
|||||||
CommandCounterIncrement();
|
CommandCounterIncrement();
|
||||||
archiveName = MakeArchiveName(relationId);
|
archiveName = MakeArchiveName(relationId);
|
||||||
|
|
||||||
relationId = heap_create(archiveName,
|
tupdesc = CreateTupleDescCopy (descriptor); /* get rid of constraints */
|
||||||
typename,
|
(void) heap_create(archiveName,
|
||||||
'n', /* archive isn't archived */
|
typename,
|
||||||
archloc,
|
'n', /* archive isn't archived */
|
||||||
descriptor);
|
archloc,
|
||||||
|
tupdesc);
|
||||||
|
|
||||||
|
FreeTupleDesc (tupdesc);
|
||||||
|
FreeTupleDesc (descriptor);
|
||||||
pfree(archiveName);
|
pfree(archiveName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,10 +268,11 @@ RemoveRelation(char *name)
|
|||||||
* stud_emp {7:percent}
|
* stud_emp {7:percent}
|
||||||
*/
|
*/
|
||||||
static List *
|
static List *
|
||||||
MergeAttributes(List *schema, List *supers)
|
MergeAttributes(List *schema, List *supers, List **supconstr)
|
||||||
{
|
{
|
||||||
List *entry;
|
List *entry;
|
||||||
List *inhSchema = NIL;
|
List *inhSchema = NIL;
|
||||||
|
List *constraints = NIL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validates that there are no duplications.
|
* Validates that there are no duplications.
|
||||||
@ -258,6 +314,7 @@ MergeAttributes(List *schema, List *supers)
|
|||||||
List *partialResult = NIL;
|
List *partialResult = NIL;
|
||||||
AttrNumber attrno;
|
AttrNumber attrno;
|
||||||
TupleDesc tupleDesc;
|
TupleDesc tupleDesc;
|
||||||
|
TupleConstr *constr;
|
||||||
|
|
||||||
relation = heap_openr(name);
|
relation = heap_openr(name);
|
||||||
if (relation==NULL) {
|
if (relation==NULL) {
|
||||||
@ -271,12 +328,12 @@ MergeAttributes(List *schema, List *supers)
|
|||||||
name);
|
name);
|
||||||
}
|
}
|
||||||
tupleDesc = RelationGetTupleDescriptor(relation);
|
tupleDesc = RelationGetTupleDescriptor(relation);
|
||||||
|
constr = tupleDesc->constr;
|
||||||
|
|
||||||
for (attrno = relation->rd_rel->relnatts - 1; attrno >= 0; attrno--) {
|
for (attrno = relation->rd_rel->relnatts - 1; attrno >= 0; attrno--) {
|
||||||
AttributeTupleForm attribute = tupleDesc->attrs[attrno];
|
AttributeTupleForm attribute = tupleDesc->attrs[attrno];
|
||||||
char *attributeName;
|
char *attributeName;
|
||||||
char *attributeType;
|
char *attributeType;
|
||||||
TupleConstr constraints;
|
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
ColumnDef *def;
|
ColumnDef *def;
|
||||||
TypeName *typename;
|
TypeName *typename;
|
||||||
@ -285,7 +342,6 @@ MergeAttributes(List *schema, List *supers)
|
|||||||
* form name, type and constraints
|
* form name, type and constraints
|
||||||
*/
|
*/
|
||||||
attributeName = (attribute->attname).data;
|
attributeName = (attribute->attname).data;
|
||||||
constraints.has_not_null = attribute->attnotnull;
|
|
||||||
tuple =
|
tuple =
|
||||||
SearchSysCacheTuple(TYPOID,
|
SearchSysCacheTuple(TYPOID,
|
||||||
ObjectIdGetDatum(attribute->atttypid),
|
ObjectIdGetDatum(attribute->atttypid),
|
||||||
@ -313,10 +369,46 @@ MergeAttributes(List *schema, List *supers)
|
|||||||
def->colname = pstrdup(attributeName);
|
def->colname = pstrdup(attributeName);
|
||||||
typename->name = pstrdup(attributeType);
|
typename->name = pstrdup(attributeType);
|
||||||
def->typename = typename;
|
def->typename = typename;
|
||||||
def->is_not_null = constraints.has_not_null;
|
def->is_not_null = attribute->attnotnull;
|
||||||
|
def->defval = NULL;
|
||||||
|
if ( attribute->atthasdef )
|
||||||
|
{
|
||||||
|
AttrDefault *attrdef = constr->defval;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
Assert ( constr != NULL && constr->num_defval > 0 );
|
||||||
|
|
||||||
|
for (i = 0; i < constr->num_defval; i++)
|
||||||
|
{
|
||||||
|
if ( attrdef[i].adnum != attrno + 1 )
|
||||||
|
continue;
|
||||||
|
def->defval = pstrdup (attrdef[i].adsrc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Assert ( def->defval != NULL );
|
||||||
|
}
|
||||||
partialResult = lcons(def, partialResult);
|
partialResult = lcons(def, partialResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( constr && constr->num_check > 0 )
|
||||||
|
{
|
||||||
|
ConstrCheck *check = constr->check;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < constr->num_check; i++)
|
||||||
|
{
|
||||||
|
ConstraintDef *cdef = (ConstraintDef *) palloc (sizeof (ConstraintDef));
|
||||||
|
|
||||||
|
cdef->type = CONSTR_CHECK;
|
||||||
|
if ( check[i].ccname[0] == '$' )
|
||||||
|
cdef->name = NULL;
|
||||||
|
else
|
||||||
|
cdef->name = pstrdup (check[i].ccname);
|
||||||
|
cdef->def = (void*) pstrdup (check[i].ccsrc);
|
||||||
|
constraints = lappend (constraints, cdef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* iteration cleanup and result collection
|
* iteration cleanup and result collection
|
||||||
*/
|
*/
|
||||||
@ -333,7 +425,7 @@ MergeAttributes(List *schema, List *supers)
|
|||||||
* put the inherited schema before our the schema for this table
|
* put the inherited schema before our the schema for this table
|
||||||
*/
|
*/
|
||||||
schema = nconc(inhSchema, schema);
|
schema = nconc(inhSchema, schema);
|
||||||
|
*supconstr = constraints;
|
||||||
return (schema);
|
return (schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,4 +649,3 @@ MakeArchiveName(Oid relationId)
|
|||||||
|
|
||||||
return arch;
|
return arch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user