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

Commit3477957

Browse files
committed
Update sequence-related functions to new fmgr style. Remove downcasing,
quote-stripping, and acl-checking tasks for these functions from theparser, and do them at function execution time instead. This fixesthe failure of pg_dump to produce correct output for nextval(Foo)used in a rule, and also eliminates the restriction that the argumentof these functions must be a parse-time constant.
1 parente9acba1 commit3477957

File tree

6 files changed

+113
-91
lines changed

6 files changed

+113
-91
lines changed

‎contrib/spi/autoinc.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11

22
#include"executor/spi.h"/* this is what you need to work with SPI */
33
#include"commands/trigger.h"/* -"- and triggers */
4+
#include"commands/sequence.h"/* for nextval() */
45

56
externDatumautoinc(PG_FUNCTION_ARGS);
6-
externint4nextval(structvarlena*seqin);
77

88
Datum
99
autoinc(PG_FUNCTION_ARGS)
@@ -53,7 +53,7 @@ autoinc(PG_FUNCTION_ARGS)
5353

5454
for (i=0;i<nargs;)
5555
{
56-
structvarlena*seqname;
56+
text*seqname;
5757
intattnum=SPI_fnumber(tupdesc,args[i]);
5858
int32val;
5959

@@ -74,9 +74,11 @@ autoinc(PG_FUNCTION_ARGS)
7474
i++;
7575
chattrs[chnattrs]=attnum;
7676
seqname=textin(args[i]);
77-
newvals[chnattrs]=Int32GetDatum(nextval(seqname));
77+
newvals[chnattrs]=DirectFunctionCall1(nextval,
78+
PointerGetDatum(seqname));
7879
if (DatumGetInt32(newvals[chnattrs])==0)
79-
newvals[chnattrs]=Int32GetDatum(nextval(seqname));
80+
newvals[chnattrs]=DirectFunctionCall1(nextval,
81+
PointerGetDatum(seqname));
8082
pfree(seqname);
8183
chnattrs++;
8284
i++;

‎src/backend/commands/sequence.c

Lines changed: 83 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*-------------------------------------------------------------------------
77
*/
88

9+
#include<ctype.h>
10+
911
#include"postgres.h"
1012

1113
#include"access/heapam.h"
@@ -54,6 +56,7 @@ typedef SeqTableData *SeqTable;
5456

5557
staticSeqTableseqtab=NULL;
5658

59+
staticchar*get_seq_name(text*seqin);
5760
staticSeqTableinit_sequence(char*caller,char*name);
5861
staticForm_pg_sequenceread_info(char*caller,SeqTableelm,Buffer*buf);
5962
staticvoidinit_params(CreateSeqStmt*seq,Form_pg_sequencenew);
@@ -181,29 +184,37 @@ DefineSequence(CreateSeqStmt *seq)
181184
}
182185

183186

184-
int4
185-
nextval(structvarlena*seqin)
187+
Datum
188+
nextval(PG_FUNCTION_ARGS)
186189
{
187-
char*seqname=textout(seqin);
190+
text*seqin=PG_GETARG_TEXT_P(0);
191+
char*seqname=get_seq_name(seqin);
188192
SeqTableelm;
189193
Bufferbuf;
190194
Form_pg_sequenceseq;
191-
int4incby,
195+
int32incby,
192196
maxv,
193197
minv,
194198
cache;
195-
int4result,
199+
int32result,
196200
next,
197201
rescnt=0;
198202

203+
#ifndefNO_SECURITY
204+
if (pg_aclcheck(seqname,getpgusername(),ACL_WR)!=ACLCHECK_OK)
205+
elog(ERROR,"%s.nextval: you don't have permissions to set sequence %s",
206+
seqname,seqname);
207+
#endif
208+
199209
/* open and AccessShareLock sequence */
200210
elm=init_sequence("nextval",seqname);
211+
201212
pfree(seqname);
202213

203214
if (elm->last!=elm->cached)/* some numbers were cached */
204215
{
205216
elm->last+=elm->increment;
206-
returnelm->last;
217+
PG_RETURN_INT32(elm->last);
207218
}
208219

209220
seq=read_info("nextval",elm,&buf);/* lock page' buffer and
@@ -225,8 +236,9 @@ nextval(struct varlena * seqin)
225236
* Check MAXVALUE for ascending sequences and MINVALUE for
226237
* descending sequences
227238
*/
228-
if (incby>0)/* ascending sequence */
239+
if (incby>0)
229240
{
241+
/* ascending sequence */
230242
if ((maxv >=0&&next>maxv-incby)||
231243
(maxv<0&&next+incby>maxv))
232244
{
@@ -241,8 +253,8 @@ nextval(struct varlena * seqin)
241253
next+=incby;
242254
}
243255
else
244-
/* descending sequence */
245256
{
257+
/* descending sequence */
246258
if ((minv<0&&next<minv-incby)||
247259
(minv >=0&&next+incby<minv))
248260
{
@@ -274,35 +286,43 @@ nextval(struct varlena * seqin)
274286
if (WriteBuffer(buf)==STATUS_ERROR)
275287
elog(ERROR,"%s.nextval: WriteBuffer failed",elm->name);
276288

277-
returnresult;
278-
289+
PG_RETURN_INT32(result);
279290
}
280291

281-
282-
int4
283-
currval(structvarlena*seqin)
292+
Datum
293+
currval(PG_FUNCTION_ARGS)
284294
{
285-
char*seqname=textout(seqin);
295+
text*seqin=PG_GETARG_TEXT_P(0);
296+
char*seqname=get_seq_name(seqin);
286297
SeqTableelm;
287-
int4result;
298+
int32result;
299+
300+
#ifndefNO_SECURITY
301+
if (pg_aclcheck(seqname,getpgusername(),ACL_RD)!=ACLCHECK_OK)
302+
elog(ERROR,"%s.currval: you don't have permissions to read sequence %s",
303+
seqname,seqname);
304+
#endif
288305

289306
/* open and AccessShareLock sequence */
290307
elm=init_sequence("currval",seqname);
291-
pfree(seqname);
292308

293309
if (elm->increment==0)/* nextval/read_info were not called */
294-
elog(ERROR,"%s.currval is not yet defined in this session",elm->name);
310+
elog(ERROR,"%s.currval is not yet defined in this session",
311+
seqname);
295312

296313
result=elm->last;
297314

298-
returnresult;
315+
pfree(seqname);
299316

317+
PG_RETURN_INT32(result);
300318
}
301319

302-
int4
303-
setval(structvarlena*seqin,int4next)
320+
Datum
321+
setval(PG_FUNCTION_ARGS)
304322
{
305-
char*seqname=textout(seqin);
323+
text*seqin=PG_GETARG_TEXT_P(0);
324+
int32next=PG_GETARG_INT32(1);
325+
char*seqname=get_seq_name(seqin);
306326
SeqTableelm;
307327
Bufferbuf;
308328
Form_pg_sequenceseq;
@@ -341,9 +361,49 @@ setval(struct varlena * seqin, int4 next)
341361
LockBuffer(buf,BUFFER_LOCK_UNLOCK);
342362

343363
if (WriteBuffer(buf)==STATUS_ERROR)
344-
elog(ERROR,"%s.settval: WriteBuffer failed",seqname);
364+
elog(ERROR,"%s.setval: WriteBuffer failed",seqname);
365+
366+
pfree(seqname);
345367

346-
returnnext;
368+
PG_RETURN_INT32(next);
369+
}
370+
371+
/*
372+
* Given a 'text' parameter to a sequence function, extract the actual
373+
* sequence name. We downcase the name if it's not double-quoted.
374+
*
375+
* This is a kluge, really --- should be able to write nextval(seqrel).
376+
*/
377+
staticchar*
378+
get_seq_name(text*seqin)
379+
{
380+
char*rawname=textout(seqin);
381+
intrawlen=strlen(rawname);
382+
char*seqname;
383+
384+
if (rawlen >=2&&
385+
rawname[0]=='\"'&&rawname[rawlen-1]=='\"')
386+
{
387+
/* strip off quotes, keep case */
388+
rawname[rawlen-1]='\0';
389+
seqname=pstrdup(rawname+1);
390+
pfree(rawname);
391+
}
392+
else
393+
{
394+
seqname=rawname;
395+
/*
396+
* It's important that this match the identifier downcasing code
397+
* used by backend/parser/scan.l.
398+
*/
399+
for (;*rawname;rawname++)
400+
{
401+
if (isascii((unsignedchar)*rawname)&&
402+
isupper(*rawname))
403+
*rawname=tolower(*rawname);
404+
}
405+
}
406+
returnseqname;
347407
}
348408

349409
staticForm_pg_sequence

‎src/backend/parser/parse_func.c

Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.82 2000/06/03 04:41:32 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.83 2000/06/11 20:08:00 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -709,56 +709,14 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
709709
}
710710

711711
/*
712-
* Sequence handling.
712+
* Special checks to disallow sequence functions with side-effects
713+
* in WHERE clauses. This is pretty much of a hack; why disallow these
714+
* when we have no way to check for side-effects of user-defined fns?
713715
*/
714-
if (funcid==F_NEXTVAL||
715-
funcid==F_CURRVAL||
716-
funcid==F_SETVAL)
717-
{
718-
Const*seq;
719-
char*seqrel;
720-
text*seqname;
721-
int32aclcheck_result=-1;
722-
723-
Assert(nargs== ((funcid==F_SETVAL) ?2 :1));
724-
seq= (Const*)lfirst(fargs);
725-
if (!IsA((Node*)seq,Const))
726-
elog(ERROR,"Only constant sequence names are acceptable for function '%s'",funcname);
727-
728-
seqrel=textout((text*)DatumGetPointer(seq->constvalue));
729-
/* Do we have nextval('"Aa"')? */
730-
if (strlen(seqrel) >=2&&
731-
seqrel[0]=='\"'&&seqrel[strlen(seqrel)-1]=='\"')
732-
{
733-
/* strip off quotes, keep case */
734-
seqrel=pstrdup(seqrel+1);
735-
seqrel[strlen(seqrel)-1]='\0';
736-
pfree(DatumGetPointer(seq->constvalue));
737-
seq->constvalue= (Datum)textin(seqrel);
738-
}
739-
else
740-
{
741-
pfree(seqrel);
742-
seqname=lower((text*)DatumGetPointer(seq->constvalue));
743-
pfree(DatumGetPointer(seq->constvalue));
744-
seq->constvalue=PointerGetDatum(seqname);
745-
seqrel=textout(seqname);
746-
}
747-
748-
if ((aclcheck_result=pg_aclcheck(seqrel,GetPgUserName(),
749-
(((funcid==F_NEXTVAL)|| (funcid==F_SETVAL)) ?
750-
ACL_WR :ACL_RD)))
751-
!=ACLCHECK_OK)
752-
elog(ERROR,"%s.%s: %s",
753-
seqrel,funcname,aclcheck_error_strings[aclcheck_result]);
754-
755-
pfree(seqrel);
756-
757-
if (funcid==F_NEXTVAL&&pstate->p_in_where_clause)
758-
elog(ERROR,"Sequence function nextval is not allowed in WHERE clauses");
759-
if (funcid==F_SETVAL&&pstate->p_in_where_clause)
760-
elog(ERROR,"Sequence function setval is not allowed in WHERE clauses");
761-
}
716+
if (funcid==F_NEXTVAL&&pstate->p_in_where_clause)
717+
elog(ERROR,"Sequence function nextval is not allowed in WHERE clauses");
718+
if (funcid==F_SETVAL&&pstate->p_in_where_clause)
719+
elog(ERROR,"Sequence function setval is not allowed in WHERE clauses");
762720

763721
expr=makeNode(Expr);
764722
expr->typeOid=rettype;

‎src/include/catalog/pg_proc.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: pg_proc.h,v 1.137 2000/06/09 01:11:10 tgl Exp $
10+
* $Id: pg_proc.h,v 1.138 2000/06/11 20:07:51 tgl Exp $
1111
*
1212
* NOTES
1313
* The script catalog/genbki.sh reads this file and generates .bki
@@ -2003,12 +2003,12 @@ DESCR("convert int8 to int8 (no-op)");
20032003

20042004

20052005
/* SEQUENCEs nextval & currval functions */
2006-
DATA(insertOID=1574 (nextvalPGUID11ftft1f23"25"10000100nextval- ));
2006+
DATA(insertOID=1574 (nextvalPGUID12ftft1f23"25"10000100nextval- ));
20072007
DESCR("sequence next value");
2008-
DATA(insertOID=1575 (currvalPGUID11ftft1f23"25"10000100currval- ));
2008+
DATA(insertOID=1575 (currvalPGUID12ftft1f23"25"10000100currval- ));
20092009
DESCR("sequence current value");
2010-
DATA(insertOID=1576 (setvalPGUID11ftft2f23"25 23"10000100setval- ));
2011-
DESCR("sequenceset value");
2010+
DATA(insertOID=1576 (setvalPGUID12ftft2f23"25 23"10000100setval- ));
2011+
DESCR("set sequence value");
20122012

20132013
DATA(insertOID=1579 (varbit_inPGUID11fttt1f1562"0"10000100varbit_in- ));
20142014
DESCR("(internal)");

‎src/include/commands/sequence.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
#ifndefSEQUENCE_H
1010
#defineSEQUENCE_H
1111

12+
#include"fmgr.h"
1213
#include"nodes/parsenodes.h"
1314

1415
/*
15-
* Columns of asequnece relation
16+
* Columns of asequence relation
1617
*/
1718

1819
#defineSEQ_COL_NAME1
@@ -27,10 +28,11 @@
2728
#defineSEQ_COL_FIRSTCOLSEQ_COL_NAME
2829
#defineSEQ_COL_LASTCOLSEQ_COL_CALLED
2930

31+
externDatumnextval(PG_FUNCTION_ARGS);
32+
externDatumcurrval(PG_FUNCTION_ARGS);
33+
externDatumsetval(PG_FUNCTION_ARGS);
34+
3035
externvoidDefineSequence(CreateSeqStmt*stmt);
31-
externint4nextval(structvarlena*seqname);
32-
externint4currval(structvarlena*seqname);
33-
externint4setval(structvarlena*seqname,int4next);
3436
externvoidCloseSequences(void);
3537

3638
#endif/* SEQUENCE_H */

‎src/test/regress/regress.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.38 2000/06/0507:29:22 tgl Exp $
2+
* $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.39 2000/06/11 20:07:44 tgl Exp $
33
*/
44

55
#include<float.h>/* faked on sunos */
@@ -8,6 +8,7 @@
88

99
#include"utils/geo_decls.h"/* includes <math.h> */
1010
#include"executor/executor.h"/* For GetAttributeByName */
11+
#include"commands/sequence.h"/* for nextval() */
1112

1213
#defineP_MAXDIG 12
1314
#defineLDELIM'('
@@ -420,8 +421,6 @@ funny_dup17(PG_FUNCTION_ARGS)
420421
externDatumttdummy(PG_FUNCTION_ARGS);
421422
int32set_ttdummy(int32on);
422423

423-
externint4nextval(structvarlena*seqin);
424-
425424
#defineTTDUMMY_INFINITY999999
426425

427426
staticvoid*splan=NULL;
@@ -528,9 +527,10 @@ ttdummy(PG_FUNCTION_ARGS)
528527
}
529528

530529
{
531-
structvarlena*seqname=textin("ttdummy_seq");
530+
text*seqname=textin("ttdummy_seq");
532531

533-
newoff=nextval(seqname);
532+
newoff=DirectFunctionCall1(nextval,
533+
PointerGetDatum(seqname));
534534
pfree(seqname);
535535
}
536536

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp