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

Commitc59077d

Browse files
Jan WieckJan Wieck
Jan Wieck
authored and
Jan Wieck
committed
GET DIAGNOSTICS statement to PL/pgSQL to access SPI_processed
and SPI_return values. Patch from Philip Warner.Jan
1 parent4bfb75a commitc59077d

File tree

5 files changed

+236
-9
lines changed

5 files changed

+236
-9
lines changed

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

Lines changed: 106 additions & 3 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.11 2000/08/31 13:26:15 wieck Exp $
7+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.12 2000/09/05 09:02:18 wieck Exp $
88
*
99
* This software is copyrighted by Jan Wieck - Hamburg.
1010
*
@@ -113,12 +113,15 @@ staticPLpgSQL_expr*make_tupret_expr(PLpgSQL_row *row);
113113
%type<stmt>stmt_assign,stmt_if,stmt_loop,stmt_while,stmt_exit
114114
%type<stmt>stmt_return,stmt_raise,stmt_execsql,stmt_fori
115115
%type<stmt>stmt_fors,stmt_select,stmt_perform
116-
%type<stmt>stmt_dynexecute,stmt_dynfors
116+
%type<stmt>stmt_dynexecute,stmt_dynfors,stmt_getdiag
117117

118118
%type<dtlist>raise_params
119119
%type<ival>raise_level,raise_param
120120
%type<str>raise_msg
121121

122+
%type<dtlist>getdiag_items,getdiag_targets
123+
%type<ival>getdiag_item,getdiag_target
124+
122125
%type<ival>lno
123126

124127
/*
@@ -131,6 +134,7 @@ staticPLpgSQL_expr*make_tupret_expr(PLpgSQL_row *row);
131134
%tokenK_DEBUG
132135
%tokenK_DECLARE
133136
%tokenK_DEFAULT
137+
%tokenK_DIAGNOSTICS
134138
%tokenK_DOTDOT
135139
%tokenK_ELSE
136140
%tokenK_END
@@ -139,6 +143,7 @@ staticPLpgSQL_expr*make_tupret_expr(PLpgSQL_row *row);
139143
%tokenK_EXIT
140144
%tokenK_FOR
141145
%tokenK_FROM
146+
%tokenK_GET
142147
%tokenK_IF
143148
%tokenK_IN
144149
%tokenK_INTO
@@ -147,9 +152,11 @@ staticPLpgSQL_expr*make_tupret_expr(PLpgSQL_row *row);
147152
%tokenK_NOTICE
148153
%tokenK_NULL
149154
%tokenK_PERFORM
155+
%tokenK_PROCESSED
150156
%tokenK_RAISE
151157
%tokenK_RECORD
152158
%tokenK_RENAME
159+
%tokenK_RESULT
153160
%tokenK_RETURN
154161
%tokenK_REVERSE
155162
%tokenK_SELECT
@@ -371,7 +378,7 @@ decl_rowtype: T_ROW
371378

372379
decl_varname:T_WORD
373380
{
374-
$$.name = strdup(yytext);
381+
$$.name =plpgsql_tolower(strdup(yytext));
375382
$$.lineno = yylineno;
376383
}
377384
;
@@ -576,6 +583,8 @@ proc_stmt: pl_block
576583
{$$ =$1; }
577584
|stmt_perform
578585
{$$ =$1; }
586+
|stmt_getdiag
587+
{$$ =$1; }
579588
;
580589

581590
stmt_perform:K_PERFORMlnoexpr_until_semi
@@ -610,6 +619,100 @@ stmt_assign: assign_var lno K_ASSIGN expr_until_semi
610619
}
611620
;
612621

622+
stmt_getdiag:K_GETK_DIAGNOSTICSlnoK_SELECTgetdiag_itemsK_INTOgetdiag_targets';'
623+
{
624+
PLpgSQL_stmt_getdiag *new;
625+
626+
new = malloc(sizeof(PLpgSQL_stmt_getdiag));
627+
memset(new,0,sizeof(PLpgSQL_stmt_getdiag));
628+
629+
new->cmd_type = PLPGSQL_STMT_GETDIAG;
630+
new->lineno =$3;
631+
new->nitems =$5.nused;
632+
new->items = malloc(sizeof(int) *$5.nused);
633+
new->ntargets =$7.nused;
634+
new->targets = malloc(sizeof(int) *$7.nused);
635+
memcpy(new->items, $5.dtnums,sizeof(int) * $5.nused);
636+
memcpy(new->targets, $7.dtnums,sizeof(int) * $7.nused);
637+
638+
if (new->nitems !=new->ntargets) {
639+
plpgsql_error_lineno =new->lineno;
640+
plpgsql_comperrinfo();
641+
elog(ERROR,"number of diagnostic items does not match target list");
642+
};
643+
644+
$$ = (PLpgSQL_stmt *)new;
645+
}
646+
;
647+
648+
getdiag_items :getdiag_items','getdiag_item
649+
{
650+
if ($1.nused ==$1.nalloc) {
651+
$1.nalloc *=2;
652+
$1.dtnums = repalloc($1.dtnums,sizeof(int) *$1.nalloc);
653+
}
654+
$1.dtnums[$1.nused++] =$3;
655+
656+
$$.nalloc =$1.nalloc;
657+
$$.nused =$1.nused;
658+
$$.dtnums =$1.dtnums;
659+
}
660+
|getdiag_item
661+
{
662+
$$.nalloc =1;
663+
$$.nused =1;
664+
$$.dtnums = palloc(sizeof(int) *$$.nalloc);
665+
$$.dtnums[0] =$1;
666+
}
667+
;
668+
669+
getdiag_item :K_PROCESSED
670+
{
671+
$$ = PLPGSQL_GETDIAG_PROCESSED;
672+
}
673+
|K_RESULT
674+
{
675+
$$ = PLPGSQL_GETDIAG_RESULT;
676+
}
677+
;
678+
679+
getdiag_targets :getdiag_targets','getdiag_target
680+
{
681+
if ($1.nused ==$1.nalloc) {
682+
$1.nalloc *=2;
683+
$1.dtnums = repalloc($1.dtnums,sizeof(int) *$1.nalloc);
684+
}
685+
$1.dtnums[$1.nused++] =$3;
686+
687+
$$.nalloc =$1.nalloc;
688+
$$.nused =$1.nused;
689+
$$.dtnums =$1.dtnums;
690+
}
691+
|getdiag_target
692+
{
693+
$$.nalloc =1;
694+
$$.nused =1;
695+
$$.dtnums = palloc(sizeof(int) *$$.nalloc);
696+
$$.dtnums[0] =$1;
697+
}
698+
;
699+
700+
701+
getdiag_target :T_VARIABLE
702+
{
703+
if (yylval.var->isconst) {
704+
plpgsql_comperrinfo();
705+
elog(ERROR,"%s is declared CONSTANT; can not receive diagnostics", yylval.var->refname);
706+
}
707+
$$ = yylval.var->varno;
708+
}
709+
|T_RECFIELD
710+
{
711+
$$ = yylval.recfield->rfno;
712+
}
713+
;
714+
715+
613716
assign_var:T_VARIABLE
614717
{
615718
if (yylval.var->isconst) {

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

Lines changed: 56 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_exec.c,v 1.29 2000/08/31 13:26:16 wieck Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.30 2000/09/05 09:02:18 wieck Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -80,6 +80,8 @@ static int exec_stmt(PLpgSQL_execstate * estate,
8080
PLpgSQL_stmt*stmt);
8181
staticintexec_stmt_assign(PLpgSQL_execstate*estate,
8282
PLpgSQL_stmt_assign*stmt);
83+
staticintexec_stmt_getdiag(PLpgSQL_execstate*estate,
84+
PLpgSQL_stmt_getdiag*stmt);
8385
staticintexec_stmt_if(PLpgSQL_execstate*estate,
8486
PLpgSQL_stmt_if*stmt);
8587
staticintexec_stmt_loop(PLpgSQL_execstate*estate,
@@ -193,6 +195,9 @@ plpgsql_exec_function(PLpgSQL_function * func, FunctionCallInfo fcinfo)
193195
casePLPGSQL_STMT_ASSIGN:
194196
stmttype="assignment";
195197
break;
198+
casePLPGSQL_STMT_GETDIAG:
199+
stmttype="get diagnostics";
200+
break;
196201
casePLPGSQL_STMT_IF:
197202
stmttype="if";
198203
break;
@@ -502,6 +507,9 @@ plpgsql_exec_trigger(PLpgSQL_function * func,
502507
casePLPGSQL_STMT_ASSIGN:
503508
stmttype="assignment";
504509
break;
510+
casePLPGSQL_STMT_GETDIAG:
511+
stmttype="get diagnostics";
512+
break;
505513
casePLPGSQL_STMT_IF:
506514
stmttype="if";
507515
break;
@@ -971,6 +979,10 @@ exec_stmt(PLpgSQL_execstate * estate, PLpgSQL_stmt * stmt)
971979
rc=exec_stmt_assign(estate, (PLpgSQL_stmt_assign*)stmt);
972980
break;
973981

982+
casePLPGSQL_STMT_GETDIAG:
983+
rc=exec_stmt_getdiag(estate, (PLpgSQL_stmt_getdiag*)stmt);
984+
break;
985+
974986
casePLPGSQL_STMT_IF:
975987
rc=exec_stmt_if(estate, (PLpgSQL_stmt_if*)stmt);
976988
break;
@@ -1047,6 +1059,49 @@ exec_stmt_assign(PLpgSQL_execstate * estate, PLpgSQL_stmt_assign * stmt)
10471059
returnPLPGSQL_RC_OK;
10481060
}
10491061

1062+
/* ----------
1063+
* exec_stmt_getdiag Put internal PG information into
1064+
* specified variables.
1065+
* ----------
1066+
*/
1067+
staticint
1068+
exec_stmt_getdiag(PLpgSQL_execstate*estate,PLpgSQL_stmt_getdiag*stmt)
1069+
{
1070+
inti;
1071+
PLpgSQL_datum*var;
1072+
HeapTupletypeTup;
1073+
boolisnull= false;
1074+
1075+
for (i=0 ;i<stmt->nitems ;i++)
1076+
{
1077+
if ((stmt->targets[i] <=0))
1078+
break;
1079+
1080+
var= (estate->datums[stmt->targets[i]]);
1081+
1082+
if (var==NULL)
1083+
break;
1084+
1085+
switch (stmt->items[i])
1086+
{
1087+
casePLPGSQL_GETDIAG_PROCESSED:
1088+
1089+
exec_assign_value(estate,var, (Datum)SPI_processed,INT4OID,&isnull);
1090+
break;
1091+
1092+
casePLPGSQL_GETDIAG_RESULT:
1093+
1094+
exec_assign_value(estate,var, (Datum)SPI_result,INT4OID,&isnull);
1095+
break;
1096+
1097+
default:
1098+
1099+
elog(ERROR,"unknown attribute request %d in get_diagnostic",stmt->items[i]);
1100+
};
1101+
};
1102+
1103+
returnPLPGSQL_RC_OK;
1104+
}
10501105

10511106
/* ----------
10521107
* exec_stmt_ifEvaluate a bool expression and

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

Lines changed: 45 additions & 2 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_funcs.c,v 1.7 2000/08/31 13:26:16 wieck Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.8 2000/09/05 09:02:18 wieck Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -390,6 +390,7 @@ static void dump_raise(PLpgSQL_stmt_raise * stmt);
390390
staticvoiddump_execsql(PLpgSQL_stmt_execsql*stmt);
391391
staticvoiddump_dynexecute(PLpgSQL_stmt_dynexecute*stmt);
392392
staticvoiddump_dynfors(PLpgSQL_stmt_dynfors*stmt);
393+
staticvoiddump_getdiag(PLpgSQL_stmt_getdiag*stmt);
393394
staticvoiddump_expr(PLpgSQL_expr*expr);
394395

395396

@@ -450,6 +451,9 @@ dump_stmt(PLpgSQL_stmt * stmt)
450451
casePLPGSQL_STMT_DYNFORS:
451452
dump_dynfors((PLpgSQL_stmt_dynfors*)stmt);
452453
break;
454+
casePLPGSQL_STMT_GETDIAG:
455+
dump_getdiag((PLpgSQL_stmt_getdiag*)stmt);
456+
break;
453457
default:
454458
elog(ERROR,"plpgsql_dump: unknown cmd_type %d\n",stmt->cmd_type);
455459
break;
@@ -637,7 +641,7 @@ dump_return(PLpgSQL_stmt_return * stmt)
637641
{
638642
dump_ind();
639643
printf("RETURN ");
640-
if (stmt->retrecno >=0)
644+
if (stmt->retrecno>0)
641645
printf("record %d",stmt->retrecno);
642646
else
643647
{
@@ -698,6 +702,45 @@ dump_dynfors(PLpgSQL_stmt_dynfors * stmt)
698702
printf(" ENDFORS\n");
699703
}
700704

705+
staticvoid
706+
dump_getdiag(PLpgSQL_stmt_getdiag*stmt)
707+
{
708+
inti;
709+
710+
dump_ind();
711+
printf("GET DIAGNOSTICS SELECT ");
712+
for (i=0;i<stmt->nitems;i++)
713+
{
714+
if (i!=0)
715+
printf(", ");
716+
717+
switch (stmt->items[i])
718+
{
719+
casePLPGSQL_GETDIAG_PROCESSED:
720+
printf("PROCESSED");
721+
break;
722+
723+
casePLPGSQL_GETDIAG_RESULT:
724+
printf("RESULT");
725+
break;
726+
727+
default:
728+
printf("???");
729+
break;
730+
}
731+
}
732+
printf(" INTO ");
733+
for (i=0;i<stmt->ntargets;i++)
734+
{
735+
if (i!=0)
736+
printf(", ");
737+
738+
printf("{var %d}",stmt->targets[i]);
739+
}
740+
741+
printf("\n");
742+
}
743+
701744
staticvoid
702745
dump_expr(PLpgSQL_expr*expr)
703746
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp