Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd40dbb7

Browse files
committed
Eliminate local inefficiencies in updateTargetListEntry, make_var, and
make_const --- don't repeat cache searches that aren't needed.
1 parent249f6b4 commitd40dbb7

File tree

4 files changed

+106
-76
lines changed

4 files changed

+106
-76
lines changed

‎src/backend/parser/analyze.c

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 1994, Regents of the University of California
77
*
8-
*$Id: analyze.c,v 1.121 1999/10/07 04:23:11 tgl Exp $
8+
*$Id: analyze.c,v 1.122 1999/11/01 05:06:21 tgl Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
@@ -253,6 +253,9 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
253253
Query*qry=makeNode(Query);
254254
Node*fromQual;
255255
List*icolumns;
256+
List*attrnos;
257+
List*attnos;
258+
intnumuseratts;
256259
List*tl;
257260
TupleDescrd_att;
258261

@@ -333,9 +336,11 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
333336
pstate->p_last_resno=pstate->p_target_relation->rd_rel->relnatts+1;
334337

335338
/* Validate stmt->cols list, or build default list if no list given */
336-
icolumns=makeTargetNames(pstate,stmt->cols);
339+
icolumns=checkInsertTargets(pstate,stmt->cols,&attrnos);
337340

338341
/* Prepare non-junk columns for assignment to target table */
342+
numuseratts=0;
343+
attnos=attrnos;
339344
foreach(tl,qry->targetList)
340345
{
341346
TargetEntry*tle= (TargetEntry*)lfirst(tl);
@@ -352,16 +357,30 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
352357
resnode->resno= (AttrNumber)pstate->p_last_resno++;
353358
continue;
354359
}
355-
if (icolumns==NIL)
360+
if (icolumns==NIL||attnos==NIL)
356361
elog(ERROR,"INSERT has more expressions than target columns");
357362
id= (Ident*)lfirst(icolumns);
358-
updateTargetListEntry(pstate,tle,id->name,id->indirection);
363+
updateTargetListEntry(pstate,tle,id->name,lfirsti(attnos),
364+
id->indirection);
365+
numuseratts++;
359366
icolumns=lnext(icolumns);
367+
attnos=lnext(attnos);
360368
}
361369

370+
/*
371+
* It is possible that the targetlist has fewer entries than were in
372+
* the columns list. We do not consider this an error (perhaps we
373+
* should, if the columns list was explictly given?). We must truncate
374+
* the attrnos list to only include the attrs actually provided,
375+
* else we will fail to apply defaults for them below.
376+
*/
377+
if (icolumns!=NIL)
378+
attrnos=ltruncate(numuseratts,attrnos);
379+
362380
/*
363381
* Add targetlist items to assign DEFAULT values to any columns that
364382
* have defaults and were not assigned to by the user.
383+
*
365384
* XXX wouldn't it make more sense to do this further downstream,
366385
* after the rule rewriter?
367386
*/
@@ -372,29 +391,20 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
372391
AttrDefault*defval=rd_att->constr->defval;
373392
intndef=rd_att->constr->num_defval;
374393

375-
while (ndef-->0)
394+
while (--ndef >=0)
376395
{
377-
Form_pg_attributethisatt=att[defval[ndef].adnum-1];
378-
TargetEntry*te;
396+
AttrNumberattrno=defval[ndef].adnum;
397+
Form_pg_attributethisatt=att[attrno-1];
398+
TargetEntry*te;
379399

380-
foreach(tl,qry->targetList)
381-
{
382-
TargetEntry*tle= (TargetEntry*)lfirst(tl);
383-
Resdom*resnode=tle->resdom;
384-
385-
if (resnode->resjunk)
386-
continue;/* ignore resjunk nodes */
387-
if (namestrcmp(&(thisatt->attname),resnode->resname)==0)
388-
break;
389-
}
390-
if (tl!=NIL)/* found TLE for this attr */
391-
continue;
400+
if (intMember((int)attrno,attrnos))
401+
continue;/* there was a user-specified value */
392402
/*
393403
* No user-supplied value, so add a targetentry with DEFAULT expr
394404
* and correct data for the target column.
395405
*/
396406
te=makeTargetEntry(
397-
makeResdom(defval[ndef].adnum,
407+
makeResdom(attrno,
398408
thisatt->atttypid,
399409
thisatt->atttypmod,
400410
pstrdup(nameout(&(thisatt->attname))),
@@ -405,7 +415,8 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
405415
* Make sure the value is coerced to the target column type
406416
* (might not be right type if it's not a constant!)
407417
*/
408-
updateTargetListEntry(pstate,te,te->resdom->resname,NIL);
418+
updateTargetListEntry(pstate,te,te->resdom->resname,attrno,
419+
NIL);
409420
}
410421
}
411422

@@ -1128,8 +1139,10 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
11281139
if (origTargetList==NIL)
11291140
elog(ERROR,"UPDATE target count mismatch --- internal error");
11301141
origTarget= (ResTarget*)lfirst(origTargetList);
1131-
updateTargetListEntry(pstate,tle,
1132-
origTarget->name,origTarget->indirection);
1142+
updateTargetListEntry(pstate,tle,origTarget->name,
1143+
attnameAttNum(pstate->p_target_relation,
1144+
origTarget->name),
1145+
origTarget->indirection);
11331146
origTargetList=lnext(origTargetList);
11341147
}
11351148
if (origTargetList!=NIL)

‎src/backend/parser/parse_node.c

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.31 1999/08/23 23:48:39 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.32 1999/11/01 05:06:21 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -176,11 +176,16 @@ make_op(char *opname, Node *ltree, Node *rtree)
176176
}/* make_op() */
177177

178178

179+
/*
180+
* make_var
181+
*Build a Var node for an attribute identified by name
182+
*/
179183
Var*
180184
make_var(ParseState*pstate,Oidrelid,char*refname,
181185
char*attrname)
182186
{
183-
Var*varnode;
187+
HeapTupletp;
188+
Form_pg_attributeatt_tup;
184189
intvnum,
185190
attid;
186191
Oidvartypeid;
@@ -189,16 +194,19 @@ make_var(ParseState *pstate, Oid relid, char *refname,
189194

190195
vnum=refnameRangeTablePosn(pstate,refname,&sublevels_up);
191196

192-
attid=get_attnum(relid,attrname);
193-
if (attid==InvalidAttrNumber)
197+
tp=SearchSysCacheTuple(ATTNAME,
198+
ObjectIdGetDatum(relid),
199+
PointerGetDatum(attrname),
200+
0,0);
201+
if (!HeapTupleIsValid(tp))
194202
elog(ERROR,"Relation %s does not have attribute %s",
195203
refname,attrname);
196-
vartypeid=get_atttype(relid,attid);
197-
type_mod=get_atttypmod(relid,attid);
198-
199-
varnode=makeVar(vnum,attid,vartypeid,type_mod,sublevels_up);
204+
att_tup=(Form_pg_attribute)GETSTRUCT(tp);
205+
attid=att_tup->attnum;
206+
vartypeid=att_tup->atttypid;
207+
type_mod=att_tup->atttypmod;
200208

201-
returnvarnode;
209+
returnmakeVar(vnum,attid,vartypeid,type_mod,sublevels_up);
202210
}
203211

204212
/*
@@ -380,67 +388,73 @@ transformArraySubscripts(ParseState *pstate,
380388
}
381389

382390
/*
383-
* make_const -
391+
* make_const
384392
*
385-
* - takes a lispvalue, (as returned to the yacc routine by the lexer)
386-
* extracts the type, and makes the appropriate type constant
387-
* by invoking the (c-callable) lisp routine c-make-const
388-
* via the lisp_call() mechanism
389-
*
390-
* eventually, produces a "const" lisp-struct as per nodedefs.cl
393+
*Convert a Value node (as returned by the grammar) to a Const node
394+
*of the "natural" type for the constant. For strings we produce
395+
*a constant of type UNKNOWN ---- representation is the same as text,
396+
*but this indicates to later type resolution that we're not sure that
397+
*it should be considered text.
391398
*/
392399
Const*
393400
make_const(Value*value)
394401
{
395-
Typetp;
396402
Datumval;
403+
Oidtypeid;
404+
inttypelen;
405+
booltypebyval;
397406
Const*con;
398407

399408
switch (nodeTag(value))
400409
{
401410
caseT_Integer:
402-
tp=typeidType(INT4OID);
403411
val=Int32GetDatum(intVal(value));
412+
413+
typeid=INT4OID;
414+
typelen=sizeof(int32);
415+
typebyval= true;
404416
break;
405417

406418
caseT_Float:
407419
{
408420
float64dummy;
409421

410-
tp=typeidType(FLOAT8OID);
411-
412422
dummy= (float64)palloc(sizeof(float64data));
413423
*dummy=floatVal(value);
414424

415425
val=Float64GetDatum(dummy);
426+
427+
typeid=FLOAT8OID;
428+
typelen=sizeof(float64data);
429+
typebyval= false;
416430
}
417431
break;
418432

419433
caseT_String:
420-
tp=typeidType(UNKNOWNOID);/* unknown for now, will
421-
* be type coerced */
422434
val=PointerGetDatum(textin(strVal(value)));
435+
436+
typeid=UNKNOWNOID;/* will be coerced later */
437+
typelen=-1;/* variable len */
438+
typebyval= false;
423439
break;
424440

425441
caseT_Null:
426442
default:
427-
{
428-
if (nodeTag(value)!=T_Null)
429-
elog(NOTICE,"make_const: unknown type %d\n",nodeTag(value));
443+
if (nodeTag(value)!=T_Null)
444+
elog(NOTICE,"make_const: unknown type %d\n",nodeTag(value));
430445

431-
/* null const */
432-
con=makeConst(0,0, (Datum)NULL, true, false, false, false);
433-
returncon;
434-
}
446+
/* return a null const */
447+
con=makeConst(0,0, (Datum)NULL, true, false, false, false);
448+
returncon;
435449
}
436450

437-
con=makeConst(typeTypeId(tp),
438-
typeLen(tp),
451+
con=makeConst(typeid,
452+
typelen,
439453
val,
440454
false,
441-
typeByVal(tp),
455+
typebyval,
442456
false,/* not a set */
443-
false);
457+
false);/* not coerced */
444458

445459
returncon;
446460
}

‎src/backend/parser/parse_target.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.46 1999/07/19 00:26:20 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.47 1999/11/01 05:06:21 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -162,27 +162,27 @@ transformTargetList(ParseState *pstate, List *targetlist)
162162
* pstateparse state
163163
* tletarget list entry to be modified
164164
* colnametarget column name (ie, name of attribute to be assigned to)
165+
* attrnotarget attribute number
165166
* indirectionsubscripts for target column, if any
166167
*/
167168
void
168169
updateTargetListEntry(ParseState*pstate,
169170
TargetEntry*tle,
170171
char*colname,
172+
intattrno,
171173
List*indirection)
172174
{
173175
Oidtype_id=exprType(tle->expr);/* type of value provided */
174176
Oidattrtype;/* type of target column */
175177
int32attrtypmod;
176178
Resdom*resnode=tle->resdom;
177179
Relationrd=pstate->p_target_relation;
178-
intresdomno;
179180

180181
Assert(rd!=NULL);
181-
resdomno=attnameAttNum(rd,colname);
182-
if (resdomno <=0)
182+
if (attrno <=0)
183183
elog(ERROR,"Cannot assign to system attribute '%s'",colname);
184-
attrtype=attnumTypeId(rd,resdomno);
185-
attrtypmod=rd->rd_att->attrs[resdomno-1]->atttypmod;
184+
attrtype=attnumTypeId(rd,attrno);
185+
attrtypmod=rd->rd_att->attrs[attrno-1]->atttypmod;
186186

187187
/*
188188
* If there are subscripts on the target column, prepare an
@@ -260,7 +260,7 @@ updateTargetListEntry(ParseState *pstate,
260260
resnode->restype=attrtype;
261261
resnode->restypmod=attrtypmod;
262262
resnode->resname=colname;
263-
resnode->resno= (AttrNumber)resdomno;
263+
resnode->resno= (AttrNumber)attrno;
264264
}
265265

266266

@@ -356,14 +356,17 @@ SizeTargetExpr(ParseState *pstate,
356356

357357

358358
/*
359-
*makeTargetNames -
359+
*checkInsertTargets -
360360
* generate a list of column names if not supplied or
361361
* test supplied column names to make sure they are in target table.
362+
* Also return an integer list of the columns' attribute numbers.
362363
* (used exclusively for inserts)
363364
*/
364365
List*
365-
makeTargetNames(ParseState*pstate,List*cols)
366+
checkInsertTargets(ParseState*pstate,List*cols,List**attrnos)
366367
{
368+
*attrnos=NIL;
369+
367370
if (cols==NIL)
368371
{
369372
/*
@@ -382,6 +385,7 @@ makeTargetNames(ParseState *pstate, List *cols)
382385
id->indirection=NIL;
383386
id->isRel= false;
384387
cols=lappend(cols,id);
388+
*attrnos=lappendi(*attrnos,i+1);
385389
}
386390
}
387391
else
@@ -394,17 +398,14 @@ makeTargetNames(ParseState *pstate, List *cols)
394398
foreach(tl,cols)
395399
{
396400
char*name= ((Ident*)lfirst(tl))->name;
397-
List*nxt;
401+
intattrno;
398402

399403
/* Lookup column name, elog on failure */
400-
attnameAttNum(pstate->p_target_relation,name);
404+
attrno=attnameAttNum(pstate->p_target_relation,name);
401405
/* Check for duplicates */
402-
foreach(nxt,lnext(tl))
403-
{
404-
if (strcmp(name, ((Ident*)lfirst(nxt))->name)==0)
405-
elog(ERROR,"Attribute '%s' specified more than once",
406-
name);
407-
}
406+
if (intMember(attrno,*attrnos))
407+
elog(ERROR,"Attribute '%s' specified more than once",name);
408+
*attrnos=lappendi(*attrnos,attrno);
408409
}
409410
}
410411

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp