DEFAULT handling
Use for 'selct .. into ..' copy of TupleDesc (without constraints) #ifdef NOT_USED for resetVarAttrLenForCreateTable (just free tupdesc copy)
This commit is contained in:
parent
b5b3e03e34
commit
ed2c54b240
@ -26,7 +26,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.17 1997/08/19 21:31:00 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.18 1997/08/22 03:12:16 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -73,6 +73,8 @@ static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid,
|
|||||||
static void ExecReplace(TupleTableSlot *slot, ItemPointer tupleid,
|
static void ExecReplace(TupleTableSlot *slot, ItemPointer tupleid,
|
||||||
EState *estate, Query *parseTree);
|
EState *estate, Query *parseTree);
|
||||||
|
|
||||||
|
static HeapTuple ExecAttrDefault (Relation rel, HeapTuple tuple);
|
||||||
|
|
||||||
/* end of local decls */
|
/* end of local decls */
|
||||||
|
|
||||||
#ifdef QUERY_LIMIT
|
#ifdef QUERY_LIMIT
|
||||||
@ -513,6 +515,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
|
|||||||
char *intoName;
|
char *intoName;
|
||||||
char archiveMode;
|
char archiveMode;
|
||||||
Oid intoRelationId;
|
Oid intoRelationId;
|
||||||
|
TupleDesc tupdesc;
|
||||||
|
|
||||||
if (!parseTree->isPortal) {
|
if (!parseTree->isPortal) {
|
||||||
/*
|
/*
|
||||||
@ -530,16 +533,23 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
|
|||||||
intoName = parseTree->into;
|
intoName = parseTree->into;
|
||||||
archiveMode = 'n';
|
archiveMode = 'n';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* have to copy tupType to get rid of constraints
|
||||||
|
*/
|
||||||
|
tupdesc = CreateTupleDescCopy (tupType);
|
||||||
|
|
||||||
/* fixup to prevent zero-length columns in create */
|
/* fixup to prevent zero-length columns in create */
|
||||||
setVarAttrLenForCreateTable(tupType, targetList, rangeTable);
|
setVarAttrLenForCreateTable(tupdesc, targetList, rangeTable);
|
||||||
|
|
||||||
intoRelationId = heap_create(intoName,
|
intoRelationId = heap_create(intoName,
|
||||||
intoName, /* not used */
|
intoName, /* not used */
|
||||||
archiveMode,
|
archiveMode,
|
||||||
DEFAULT_SMGR,
|
DEFAULT_SMGR,
|
||||||
tupType);
|
tupdesc);
|
||||||
|
#ifdef NOT_USED /* it's copy ... */
|
||||||
resetVarAttrLenForCreateTable(tupType);
|
resetVarAttrLenForCreateTable(tupdesc);
|
||||||
|
#endif
|
||||||
|
FreeTupleDesc (tupdesc);
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* XXX rather than having to call setheapoverride(true)
|
* XXX rather than having to call setheapoverride(true)
|
||||||
@ -918,15 +928,33 @@ ExecAppend(TupleTableSlot *slot,
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (resultRelationDesc->rd_att->constr && resultRelationDesc->rd_att->constr->has_not_null)
|
if ( resultRelationDesc->rd_att->constr )
|
||||||
|
{
|
||||||
|
if ( resultRelationDesc->rd_att->constr->num_defval > 0 )
|
||||||
|
{
|
||||||
|
HeapTuple newtuple;
|
||||||
|
|
||||||
|
newtuple = ExecAttrDefault (resultRelationDesc, tuple);
|
||||||
|
|
||||||
|
if ( newtuple != tuple )
|
||||||
|
{
|
||||||
|
Assert ( slot->ttc_shouldFree );
|
||||||
|
slot->val = tuple = newtuple;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( resultRelationDesc->rd_att->constr->has_not_null )
|
||||||
{
|
{
|
||||||
int attrChk;
|
int attrChk;
|
||||||
for (attrChk = 1; attrChk <= resultRelationDesc->rd_att->natts; attrChk++) {
|
|
||||||
|
for (attrChk = 1; attrChk <= resultRelationDesc->rd_att->natts; attrChk++)
|
||||||
|
{
|
||||||
if (resultRelationDesc->rd_att->attrs[attrChk-1]->attnotnull && heap_attisnull(tuple,attrChk))
|
if (resultRelationDesc->rd_att->attrs[attrChk-1]->attnotnull && heap_attisnull(tuple,attrChk))
|
||||||
elog(WARN,"ExecAppend: Fail to add null value in not null attribute %s",
|
elog(WARN,"ExecAppend: Fail to add null value in not null attribute %s",
|
||||||
resultRelationDesc->rd_att->attrs[attrChk-1]->attname.data);
|
resultRelationDesc->rd_att->attrs[attrChk-1]->attname.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* insert the tuple
|
* insert the tuple
|
||||||
@ -1106,3 +1134,57 @@ ExecReplace(TupleTableSlot *slot,
|
|||||||
ExecInsertIndexTuples(slot, &(tuple->t_ctid), estate, true);
|
ExecInsertIndexTuples(slot, &(tuple->t_ctid), estate, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HeapTuple
|
||||||
|
ExecAttrDefault (Relation rel, HeapTuple tuple)
|
||||||
|
{
|
||||||
|
int ndef = rel->rd_att->constr->num_defval;
|
||||||
|
AttrDefault *attrdef = rel->rd_att->constr->defval;
|
||||||
|
ExprContext *econtext = makeNode(ExprContext);
|
||||||
|
Node *expr;
|
||||||
|
bool isnull;
|
||||||
|
bool isdone;
|
||||||
|
Datum val;
|
||||||
|
Datum *replValue = NULL;
|
||||||
|
char *replNull = NULL;
|
||||||
|
char *repl = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ndef; i++)
|
||||||
|
{
|
||||||
|
if ( !heap_attisnull (tuple, attrdef[i].adnum) )
|
||||||
|
continue;
|
||||||
|
expr = (Node*) stringToNode (attrdef[i].adbin);
|
||||||
|
econtext->ecxt_scantuple = NULL; /* scan tuple slot */
|
||||||
|
econtext->ecxt_innertuple = NULL; /* inner tuple slot */
|
||||||
|
econtext->ecxt_outertuple = NULL; /* outer tuple slot */
|
||||||
|
econtext->ecxt_relation = NULL; /* relation */
|
||||||
|
econtext->ecxt_relid = 0; /* relid */
|
||||||
|
econtext->ecxt_param_list_info = NULL; /* param list info */
|
||||||
|
econtext->ecxt_range_table = NULL; /* range table */
|
||||||
|
|
||||||
|
val = ExecEvalExpr (expr, econtext, &isnull, &isdone);
|
||||||
|
|
||||||
|
if ( isnull )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( repl == NULL )
|
||||||
|
{
|
||||||
|
repl = (char*) palloc (rel->rd_att->natts * sizeof (char));
|
||||||
|
replNull = (char*) palloc (rel->rd_att->natts * sizeof (char));
|
||||||
|
replValue = (Datum*) palloc (rel->rd_att->natts * sizeof (Datum));
|
||||||
|
memset (repl, ' ', rel->rd_att->natts * sizeof (char));
|
||||||
|
}
|
||||||
|
|
||||||
|
repl[attrdef[i].adnum - 1] = 'r';
|
||||||
|
replNull[attrdef[i].adnum - 1] = ' ';
|
||||||
|
replValue[attrdef[i].adnum - 1] = val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( repl == NULL )
|
||||||
|
return (tuple);
|
||||||
|
|
||||||
|
return (heap_modifytuple (tuple, InvalidBuffer, rel, replValue, replNull, repl));
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.13 1997/08/21 03:01:42 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.14 1997/08/22 03:12:19 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1182,6 +1182,7 @@ setVarAttrLenForCreateTable(TupleDesc tupType, List *targetList,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NOT_USED /* look at execMain.c */
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
* resetVarAttrLenForCreateTable -
|
* resetVarAttrLenForCreateTable -
|
||||||
* called when we do a SELECT * INTO TABLE tab
|
* called when we do a SELECT * INTO TABLE tab
|
||||||
@ -1202,3 +1203,4 @@ resetVarAttrLenForCreateTable(TupleDesc tupType)
|
|||||||
tupType->attrs[varno]->attlen = -1;
|
tupType->attrs[varno]->attlen = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user