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

Commit4be2018

Browse files
committed
Fix some problems in new plpgsql cursor operations, found while trying
to reverse-engineer documentation for them.
1 parentd4337f6 commit4be2018

File tree

4 files changed

+98
-155
lines changed

4 files changed

+98
-155
lines changed

‎src/pl/plpgsql/src/gram.y

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* procedural language
55
*
66
* IDENTIFICATION
7-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.27 2001/10/09 15:59:56 tgl Exp $
7+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.28 2001/11/15 23:31:09 tgl Exp $
88
*
99
* This software is copyrighted by Jan Wieck - Hamburg.
1010
*
@@ -351,14 +351,17 @@ decl_statement: decl_varname decl_const decl_datatype decl_notnull decl_defval
351351
{
352352
plpgsql_ns_rename($2, $4);
353353
}
354-
|decl_varnameK_CURSORdecl_cursor_argsdecl_is_fromK_SELECTdecl_cursor_query
354+
|decl_varnameK_CURSOR
355+
{ plpgsql_ns_push(NULL); }
356+
decl_cursor_argsdecl_is_fromK_SELECTdecl_cursor_query
355357
{
356358
PLpgSQL_var *new;
357359
PLpgSQL_expr *curname_def;
358360
charbuf[1024];
359361
char*cp1;
360362
char*cp2;
361363

364+
/* pop local namespace for cursor args*/
362365
plpgsql_ns_pop();
363366

364367
new = malloc(sizeof(PLpgSQL_var));
@@ -381,22 +384,21 @@ decl_statement: decl_varname decl_const decl_datatype decl_notnull decl_defval
381384
*cp2++ ='\\';
382385
*cp2++ = *cp1++;
383386
}
384-
*cp2++ ='\'';
385-
*cp2 ='\0';
387+
strcpy(cp2,"'::refcursor");
386388
curname_def->query = strdup(buf);
387389
new->default_val = curname_def;
388390

389391
new->datatype = plpgsql_parse_datatype("refcursor");
390392

391-
new->cursor_explicit_expr =$6;
392-
if ($3 ==NULL)
393+
new->cursor_explicit_expr =$7;
394+
if ($4 ==NULL)
393395
new->cursor_explicit_argrow = -1;
394396
else
395-
new->cursor_explicit_argrow =$3->rowno;
397+
new->cursor_explicit_argrow =$4->rowno;
396398

397399
plpgsql_adddatum((PLpgSQL_datum *)new);
398400
plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,new->varno,
399-
$1.name);
401+
$1.name);
400402
}
401403
;
402404

@@ -416,15 +418,17 @@ decl_cursor_args :
416418
{
417419
$$ =NULL;
418420
}
419-
|decl_cursor_openparendecl_cursor_arglist')'
421+
|'('decl_cursor_arglist')'
420422
{
423+
/* Copy the temp arrays to malloc'd storage*/
424+
int nfields =$2->nfields;
421425
char **ftmp;
422426
int *vtmp;
423427

424-
ftmp = malloc($2->nfields *sizeof(char *));
425-
vtmp = malloc($2->nfields *sizeof(int));
426-
memcpy(ftmp, $2->fieldnames,$2->nfields *sizeof(char *));
427-
memcpy(vtmp, $2->varnos,$2->nfields *sizeof(int));
428+
ftmp = malloc(nfields *sizeof(char *));
429+
vtmp = malloc(nfields *sizeof(int));
430+
memcpy(ftmp, $2->fieldnames, nfields *sizeof(char *));
431+
memcpy(vtmp, $2->varnos, nfields *sizeof(int));
428432

429433
pfree((char *)($2->fieldnames));
430434
pfree((char *)($2->varnos));
@@ -449,6 +453,12 @@ decl_cursor_arglist : decl_cursor_arg
449453
new->refname = strdup("*internal*");
450454
new->lineno = yylineno;
451455
new->rowtypeclass = InvalidOid;
456+
/*
457+
* We make temporary fieldnames/varnos arrays that
458+
* are much bigger than necessary. We will resize
459+
* them to just the needed size in the
460+
* decl_cursor_args production.
461+
*/
452462
new->fieldnames = palloc(1024 *sizeof(char *));
453463
new->varnos = palloc(1024 *sizeof(int));
454464
new->nfields =1;
@@ -464,6 +474,8 @@ decl_cursor_arglist : decl_cursor_arg
464474

465475
$1->fieldnames[i] =$3->refname;
466476
$1->varnos[i] =$3->varno;
477+
478+
$$ =$1;
467479
}
468480
;
469481

@@ -484,18 +496,12 @@ decl_cursor_arg : decl_varname decl_datatype
484496

485497
plpgsql_adddatum((PLpgSQL_datum *)new);
486498
plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR,new->varno,
487-
$1.name);
499+
$1.name);
488500

489501
$$ =new;
490502
}
491503
;
492504

493-
decl_cursor_openparen :'('
494-
{
495-
plpgsql_ns_push(NULL);
496-
}
497-
;
498-
499505
decl_is_from:K_IS|/* Oracle*/
500506
K_FOR;/* ANSI*/
501507

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 21 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.51 2001/11/13 02:05:27 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.52 2001/11/15 23:31:09 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -192,76 +192,12 @@ plpgsql_exec_function(PLpgSQL_function * func, FunctionCallInfo fcinfo)
192192
elog(NOTICE,"Error occurred while executing PL/pgSQL function %s",
193193
error_info_func->fn_name);
194194
if (error_info_stmt!=NULL)
195-
{
196-
char*stmttype;
197-
198-
switch (error_info_stmt->cmd_type)
199-
{
200-
casePLPGSQL_STMT_BLOCK:
201-
stmttype="blocks variable initialization";
202-
break;
203-
casePLPGSQL_STMT_ASSIGN:
204-
stmttype="assignment";
205-
break;
206-
casePLPGSQL_STMT_GETDIAG:
207-
stmttype="get diagnostics";
208-
break;
209-
casePLPGSQL_STMT_IF:
210-
stmttype="if";
211-
break;
212-
casePLPGSQL_STMT_LOOP:
213-
stmttype="loop";
214-
break;
215-
casePLPGSQL_STMT_WHILE:
216-
stmttype="while";
217-
break;
218-
casePLPGSQL_STMT_FORI:
219-
stmttype="for with integer loopvar";
220-
break;
221-
casePLPGSQL_STMT_FORS:
222-
stmttype="for over select rows";
223-
break;
224-
casePLPGSQL_STMT_SELECT:
225-
stmttype="select into variables";
226-
break;
227-
casePLPGSQL_STMT_EXIT:
228-
stmttype="exit";
229-
break;
230-
casePLPGSQL_STMT_RETURN:
231-
stmttype="return";
232-
break;
233-
casePLPGSQL_STMT_RAISE:
234-
stmttype="raise";
235-
break;
236-
casePLPGSQL_STMT_EXECSQL:
237-
stmttype="SQL statement";
238-
break;
239-
casePLPGSQL_STMT_DYNEXECUTE:
240-
stmttype="execute statement";
241-
break;
242-
casePLPGSQL_STMT_DYNFORS:
243-
stmttype="for over execute statement";
244-
break;
245-
casePLPGSQL_STMT_FETCH:
246-
stmttype="fetch";
247-
break;
248-
casePLPGSQL_STMT_CLOSE:
249-
stmttype="close";
250-
break;
251-
default:
252-
stmttype="unknown";
253-
break;
254-
}
255195
elog(NOTICE,"line %d at %s",error_info_stmt->lineno,
256-
stmttype);
257-
}
196+
plpgsql_stmt_typename(error_info_stmt));
197+
elseif (error_info_text!=NULL)
198+
elog(NOTICE,"%s",error_info_text);
258199
else
259-
{
260-
if (error_info_text!=NULL)
261-
elog(NOTICE,"%s",error_info_text);
262-
else
263-
elog(NOTICE,"no more error information available");
264-
}
200+
elog(NOTICE,"no more error information available");
265201

266202
error_info_func=NULL;
267203
error_info_stmt=NULL;
@@ -504,70 +440,12 @@ plpgsql_exec_trigger(PLpgSQL_function * func,
504440
elog(NOTICE,"Error occurred while executing PL/pgSQL function %s",
505441
error_info_func->fn_name);
506442
if (error_info_stmt!=NULL)
507-
{
508-
char*stmttype;
509-
510-
switch (error_info_stmt->cmd_type)
511-
{
512-
casePLPGSQL_STMT_BLOCK:
513-
stmttype="blocks variable initialization";
514-
break;
515-
casePLPGSQL_STMT_ASSIGN:
516-
stmttype="assignment";
517-
break;
518-
casePLPGSQL_STMT_GETDIAG:
519-
stmttype="get diagnostics";
520-
break;
521-
casePLPGSQL_STMT_IF:
522-
stmttype="if";
523-
break;
524-
casePLPGSQL_STMT_LOOP:
525-
stmttype="loop";
526-
break;
527-
casePLPGSQL_STMT_WHILE:
528-
stmttype="while";
529-
break;
530-
casePLPGSQL_STMT_FORI:
531-
stmttype="for with integer loopvar";
532-
break;
533-
casePLPGSQL_STMT_FORS:
534-
stmttype="for over select rows";
535-
break;
536-
casePLPGSQL_STMT_SELECT:
537-
stmttype="select into variables";
538-
break;
539-
casePLPGSQL_STMT_EXIT:
540-
stmttype="exit";
541-
break;
542-
casePLPGSQL_STMT_RETURN:
543-
stmttype="return";
544-
break;
545-
casePLPGSQL_STMT_RAISE:
546-
stmttype="raise";
547-
break;
548-
casePLPGSQL_STMT_EXECSQL:
549-
stmttype="SQL statement";
550-
break;
551-
casePLPGSQL_STMT_DYNEXECUTE:
552-
stmttype="execute statement";
553-
break;
554-
casePLPGSQL_STMT_DYNFORS:
555-
stmttype="for over execute statement";
556-
break;
557-
default:
558-
stmttype="unknown";
559-
break;
560-
}
561443
elog(NOTICE,"line %d at %s",error_info_stmt->lineno,
562-
stmttype);
563-
}
444+
plpgsql_stmt_typename(error_info_stmt));
445+
elseif (error_info_text!=NULL)
446+
elog(NOTICE,"%s",error_info_text);
564447
else
565-
{
566-
if (error_info_text!=NULL)
567-
elog(NOTICE,"%s",error_info_text);
568-
else
569-
elog(NOTICE,"no more error information available");
570-
}
448+
elog(NOTICE,"no more error information available");
571449

572450
error_info_func=NULL;
573451
error_info_stmt=NULL;
@@ -2412,7 +2290,7 @@ exec_stmt_open(PLpgSQL_execstate * estate, PLpgSQL_stmt_open * stmt)
24122290
HeapTupletypetup;
24132291
Form_pg_typetypeStruct;
24142292
FmgrInfofinfo_output;
2415-
void*curplan=NULL;
2293+
void*curplan;
24162294

24172295
/* ----------
24182296
* We evaluate the string expression after the
@@ -2471,6 +2349,9 @@ exec_stmt_open(PLpgSQL_execstate * estate, PLpgSQL_stmt_open * stmt)
24712349
{
24722350
/* ----------
24732351
* This is an OPEN cursor
2352+
*
2353+
* Note: parser should already have checked that statement supplies
2354+
* args iff cursor needs them, but we check again to be safe.
24742355
* ----------
24752356
*/
24762357
if (stmt->argquery!=NULL)
@@ -2483,6 +2364,9 @@ exec_stmt_open(PLpgSQL_execstate * estate, PLpgSQL_stmt_open * stmt)
24832364
*/
24842365
PLpgSQL_stmt_selectset_args;
24852366

2367+
if (curvar->cursor_explicit_argrow<0)
2368+
elog(ERROR,"arguments given for cursor without arguments");
2369+
24862370
memset(&set_args,0,sizeof(set_args));
24872371
set_args.cmd_type=PLPGSQL_STMT_SELECT;
24882372
set_args.lineno=stmt->lineno;
@@ -2493,6 +2377,11 @@ exec_stmt_open(PLpgSQL_execstate * estate, PLpgSQL_stmt_open * stmt)
24932377
if (exec_stmt_select(estate,&set_args)!=PLPGSQL_RC_OK)
24942378
elog(ERROR,"open cursor failed during argument processing");
24952379
}
2380+
else
2381+
{
2382+
if (curvar->cursor_explicit_argrow >=0)
2383+
elog(ERROR,"arguments required for cursor");
2384+
}
24962385

24972386
query=curvar->cursor_explicit_expr;
24982387
if (query->plan==NULL)

‎src/pl/plpgsql/src/pl_funcs.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.16 2001/10/09 15:59:56 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.17 2001/11/15 23:31:09 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -360,7 +360,54 @@ plpgsql_tolower(char *s)
360360
}
361361

362362

363+
/*
364+
* Statement type as a string, for use in error messages etc.
365+
*/
366+
constchar*
367+
plpgsql_stmt_typename(PLpgSQL_stmt*stmt)
368+
{
369+
switch (stmt->cmd_type)
370+
{
371+
casePLPGSQL_STMT_BLOCK:
372+
return"block variables initialization";
373+
casePLPGSQL_STMT_ASSIGN:
374+
return"assignment";
375+
casePLPGSQL_STMT_IF:
376+
return"if";
377+
casePLPGSQL_STMT_LOOP:
378+
return"loop";
379+
casePLPGSQL_STMT_WHILE:
380+
return"while";
381+
casePLPGSQL_STMT_FORI:
382+
return"for with integer loopvar";
383+
casePLPGSQL_STMT_FORS:
384+
return"for over select rows";
385+
casePLPGSQL_STMT_SELECT:
386+
return"select into variables";
387+
casePLPGSQL_STMT_EXIT:
388+
return"exit";
389+
casePLPGSQL_STMT_RETURN:
390+
return"return";
391+
casePLPGSQL_STMT_RAISE:
392+
return"raise";
393+
casePLPGSQL_STMT_EXECSQL:
394+
return"SQL statement";
395+
casePLPGSQL_STMT_DYNEXECUTE:
396+
return"execute statement";
397+
casePLPGSQL_STMT_DYNFORS:
398+
return"for over execute statement";
399+
casePLPGSQL_STMT_GETDIAG:
400+
return"get diagnostics";
401+
casePLPGSQL_STMT_OPEN:
402+
return"open";
403+
casePLPGSQL_STMT_FETCH:
404+
return"fetch";
405+
casePLPGSQL_STMT_CLOSE:
406+
return"close";
407+
}
363408

409+
return"unknown";
410+
}
364411

365412

366413
/**********************************************************************

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp