Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit defb10a

Browse files
committed
DEFAULT is handled by analyze.c now.
1 parent c927f80 commit defb10a

File tree

2 files changed

+87
-8
lines changed

2 files changed

+87
-8
lines changed

src/backend/executor/execMain.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
*
2828
* IDENTIFICATION
29-
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.26 1997/09/18 20:20:29 momjian Exp $
29+
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.27 1997/10/12 07:09:02 vadim Exp $
3030
*
3131
*-------------------------------------------------------------------------
3232
*/
@@ -1245,6 +1245,7 @@ ExecReplace(TupleTableSlot *slot,
12451245
ExecARUpdateTriggers(resultRelationDesc, tupleid, tuple);
12461246
}
12471247

1248+
#if 0
12481249
static HeapTuple
12491250
ExecAttrDefault(Relation rel, HeapTuple tuple)
12501251
{
@@ -1309,6 +1310,7 @@ ExecAttrDefault(Relation rel, HeapTuple tuple)
13091310
return (newtuple);
13101311

13111312
}
1313+
#endif
13121314

13131315
static char *
13141316
ExecRelCheck(Relation rel, HeapTuple tuple)
@@ -1375,8 +1377,10 @@ ExecConstraints(char *caller, Relation rel, HeapTuple tuple)
13751377

13761378
Assert(rel->rd_att->constr);
13771379

1380+
#if 0
13781381
if (rel->rd_att->constr->num_defval > 0)
13791382
newtuple = tuple = ExecAttrDefault(rel, tuple);
1383+
#endif
13801384

13811385
if (rel->rd_att->constr->has_not_null)
13821386
{

src/backend/parser/analyze.c

+82-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.44 1997/09/18 20:20:58 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.45 1997/10/12 07:09:20 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -303,6 +303,7 @@ static Query *
303303
transformInsertStmt(ParseState *pstate, AppendStmt *stmt)
304304
{
305305
Query *qry = makeNode(Query); /* make a new query tree */
306+
List *icolumns;
306307

307308
qry->commandType = CMD_INSERT;
308309
pstate->p_is_insert = true;
@@ -313,10 +314,74 @@ transformInsertStmt(ParseState *pstate, AppendStmt *stmt)
313314
qry->uniqueFlag = NULL;
314315

315316
/* fix the target list */
316-
pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
317-
317+
icolumns = pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
318+
318319
qry->targetList = transformTargetList(pstate, stmt->targetList);
319-
320+
321+
/* DEFAULT handling */
322+
if (length(qry->targetList) < pstate->p_target_relation->rd_att->natts &&
323+
pstate->p_target_relation->rd_att->constr &&
324+
pstate->p_target_relation->rd_att->constr->num_defval > 0)
325+
{
326+
AttributeTupleForm *att = pstate->p_target_relation->rd_att->attrs;
327+
AttrDefault *defval = pstate->p_target_relation->rd_att->constr->defval;
328+
int ndef = pstate->p_target_relation->rd_att->constr->num_defval;
329+
330+
/*
331+
* if stmt->cols == NIL then makeTargetNames returns list of all
332+
* attrs: have to shorter icolumns list...
333+
*/
334+
if (stmt->cols == NIL)
335+
{
336+
List *extrl;
337+
int i = length(qry->targetList);
338+
339+
foreach (extrl, icolumns)
340+
{
341+
if (--i <= 0)
342+
break;
343+
}
344+
freeList (lnext(extrl));
345+
lnext(extrl) = NIL;
346+
}
347+
348+
while (ndef-- > 0)
349+
{
350+
List *tl;
351+
Ident *id;
352+
TargetEntry *te;
353+
354+
foreach (tl, icolumns)
355+
{
356+
id = (Ident *) lfirst(tl);
357+
if (!namestrcmp(&(att[defval[ndef].adnum - 1]->attname), id->name))
358+
break;
359+
}
360+
if (tl != NIL) /* something given for this attr */
361+
continue;
362+
/*
363+
* Nothing given for this attr with DEFAULT expr, so
364+
* add new TargetEntry to qry->targetList.
365+
* Note, that we set resno to defval[ndef].adnum:
366+
* it's what transformTargetList()->make_targetlist_expr()
367+
* does for INSERT ... SELECT. But for INSERT ... VALUES
368+
* pstate->p_last_resno is used. It doesn't matter for
369+
* "normal" using (planner creates proper target list
370+
* in preptlist.c), but may break RULEs in some way.
371+
* It seems better to create proper target list here...
372+
*/
373+
te = makeNode(TargetEntry);
374+
te->resdom = makeResdom(defval[ndef].adnum,
375+
att[defval[ndef].adnum - 1]->atttypid,
376+
att[defval[ndef].adnum - 1]->attlen,
377+
pstrdup(nameout(&(att[defval[ndef].adnum - 1]->attname))),
378+
0, 0, 0);
379+
te->fjoin = NULL;
380+
te->expr = (Node *) stringToNode(defval[ndef].adbin);
381+
qry->targetList = lappend (qry->targetList, te);
382+
}
383+
}
384+
320385
/* fix where clause */
321386
qry->qual = transformWhereClause(pstate, stmt->whereClause);
322387

@@ -1098,10 +1163,20 @@ makeTargetNames(ParseState *pstate, List *cols)
10981163
}
10991164
}
11001165
else
1166+
{
11011167
foreach(tl, cols)
1102-
/* elog on failure */
1103-
varattno(pstate->p_target_relation, ((Ident *) lfirst(tl))->name);
1104-
1168+
{
1169+
List *nxt;
1170+
char *name = ((Ident *) lfirst(tl))->name;
1171+
1172+
/* elog on failure */
1173+
varattno(pstate->p_target_relation, name);
1174+
foreach(nxt, lnext(tl))
1175+
if (!strcmp(name, ((Ident *) lfirst(nxt))->name))
1176+
elog (WARN, "Attribute %s should be specified only once", name);
1177+
}
1178+
}
1179+
11051180
return cols;
11061181
}
11071182

0 commit comments

Comments
 (0)