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

Commitf91feba

Browse files
committed
Modify pg_stat_get_activity to build a tuplestore
This updates pg_stat_get_activity() to build a tuplestore for itsresults instead of using the old-style multiple-call method. Thissimplifies the function, though that wasn't the primary motivation forthe change, which is that we may turn it into a helper function whichcan filter the results (or not) much more easily.
1 parent4b342fb commitf91feba

File tree

1 file changed

+67
-127
lines changed

1 file changed

+67
-127
lines changed

‎src/backend/utils/adt/pgstatfuncs.c

Lines changed: 67 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -524,137 +524,75 @@ pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
524524
}
525525
}
526526

527+
/*
528+
* Returns activity of PG backends.
529+
*/
527530
Datum
528531
pg_stat_get_activity(PG_FUNCTION_ARGS)
529532
{
530-
FuncCallContext*funcctx;
531-
532-
if (SRF_IS_FIRSTCALL())
533-
{
534-
MemoryContextoldcontext;
535-
TupleDesctupdesc;
536-
537-
funcctx=SRF_FIRSTCALL_INIT();
538-
539-
oldcontext=MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
540-
541-
tupdesc=CreateTemplateTupleDesc(22, false);
542-
TupleDescInitEntry(tupdesc, (AttrNumber)1,"datid",
543-
OIDOID,-1,0);
544-
TupleDescInitEntry(tupdesc, (AttrNumber)2,"pid",
545-
INT4OID,-1,0);
546-
TupleDescInitEntry(tupdesc, (AttrNumber)3,"usesysid",
547-
OIDOID,-1,0);
548-
TupleDescInitEntry(tupdesc, (AttrNumber)4,"application_name",
549-
TEXTOID,-1,0);
550-
TupleDescInitEntry(tupdesc, (AttrNumber)5,"state",
551-
TEXTOID,-1,0);
552-
TupleDescInitEntry(tupdesc, (AttrNumber)6,"query",
553-
TEXTOID,-1,0);
554-
TupleDescInitEntry(tupdesc, (AttrNumber)7,"waiting",
555-
BOOLOID,-1,0);
556-
TupleDescInitEntry(tupdesc, (AttrNumber)8,"act_start",
557-
TIMESTAMPTZOID,-1,0);
558-
TupleDescInitEntry(tupdesc, (AttrNumber)9,"query_start",
559-
TIMESTAMPTZOID,-1,0);
560-
TupleDescInitEntry(tupdesc, (AttrNumber)10,"backend_start",
561-
TIMESTAMPTZOID,-1,0);
562-
TupleDescInitEntry(tupdesc, (AttrNumber)11,"state_change",
563-
TIMESTAMPTZOID,-1,0);
564-
TupleDescInitEntry(tupdesc, (AttrNumber)12,"client_addr",
565-
INETOID,-1,0);
566-
TupleDescInitEntry(tupdesc, (AttrNumber)13,"client_hostname",
567-
TEXTOID,-1,0);
568-
TupleDescInitEntry(tupdesc, (AttrNumber)14,"client_port",
569-
INT4OID,-1,0);
570-
TupleDescInitEntry(tupdesc, (AttrNumber)15,"backend_xid",
571-
XIDOID,-1,0);
572-
TupleDescInitEntry(tupdesc, (AttrNumber)16,"backend_xmin",
573-
XIDOID,-1,0);
574-
TupleDescInitEntry(tupdesc, (AttrNumber)17,"ssl",
575-
BOOLOID,-1,0);
576-
TupleDescInitEntry(tupdesc, (AttrNumber)18,"sslversion",
577-
TEXTOID,-1,0);
578-
TupleDescInitEntry(tupdesc, (AttrNumber)19,"sslcipher",
579-
TEXTOID,-1,0);
580-
TupleDescInitEntry(tupdesc, (AttrNumber)20,"sslbits",
581-
INT4OID,-1,0);
582-
TupleDescInitEntry(tupdesc, (AttrNumber)21,"sslcompression",
583-
BOOLOID,-1,0);
584-
TupleDescInitEntry(tupdesc, (AttrNumber)22,"sslclientdn",
585-
TEXTOID,-1,0);
586-
587-
funcctx->tuple_desc=BlessTupleDesc(tupdesc);
588-
589-
funcctx->user_fctx=palloc0(sizeof(int));
590-
if (PG_ARGISNULL(0))
591-
{
592-
/* Get all backends */
593-
funcctx->max_calls=pgstat_fetch_stat_numbackends();
594-
}
595-
else
596-
{
597-
/*
598-
* Get one backend - locate by pid.
599-
*
600-
* We lookup the backend early, so we can return zero rows if it
601-
* doesn't exist, instead of returning a single row full of NULLs.
602-
*/
603-
intpid=PG_GETARG_INT32(0);
604-
inti;
605-
intn=pgstat_fetch_stat_numbackends();
606-
607-
for (i=1;i <=n;i++)
608-
{
609-
PgBackendStatus*be=pgstat_fetch_stat_beentry(i);
610-
611-
if (be)
612-
{
613-
if (be->st_procpid==pid)
614-
{
615-
*(int*) (funcctx->user_fctx)=i;
616-
break;
617-
}
618-
}
619-
}
620-
621-
if (*(int*) (funcctx->user_fctx)==0)
622-
/* Pid not found, return zero rows */
623-
funcctx->max_calls=0;
624-
else
625-
funcctx->max_calls=1;
626-
}
627-
628-
MemoryContextSwitchTo(oldcontext);
629-
}
630-
631-
/* stuff done on every call of the function */
632-
funcctx=SRF_PERCALL_SETUP();
633-
634-
if (funcctx->call_cntr<funcctx->max_calls)
533+
#definePG_STAT_GET_ACTIVITY_COLS22
534+
intnum_backends=pgstat_fetch_stat_numbackends();
535+
intcurr_backend;
536+
intpid=PG_ARGISNULL(0) ?-1 :PG_GETARG_INT32(0);
537+
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
538+
TupleDesctupdesc;
539+
Tuplestorestate*tupstore;
540+
MemoryContextper_query_ctx;
541+
MemoryContextoldcontext;
542+
543+
/* check to see if caller supports us returning a tuplestore */
544+
if (rsinfo==NULL|| !IsA(rsinfo,ReturnSetInfo))
545+
ereport(ERROR,
546+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
547+
errmsg("set-valued function called in context that cannot accept a set")));
548+
if (!(rsinfo->allowedModes&SFRM_Materialize))
549+
ereport(ERROR,
550+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
551+
errmsg("materialize mode required, but it is not " \
552+
"allowed in this context")));
553+
554+
/* Build a tuple descriptor for our result type */
555+
if (get_call_result_type(fcinfo,NULL,&tupdesc)!=TYPEFUNC_COMPOSITE)
556+
elog(ERROR,"return type must be a row type");
557+
558+
per_query_ctx=rsinfo->econtext->ecxt_per_query_memory;
559+
oldcontext=MemoryContextSwitchTo(per_query_ctx);
560+
561+
tupstore=tuplestore_begin_heap(true, false,work_mem);
562+
rsinfo->returnMode=SFRM_Materialize;
563+
rsinfo->setResult=tupstore;
564+
rsinfo->setDesc=tupdesc;
565+
566+
MemoryContextSwitchTo(oldcontext);
567+
568+
/* 1-based index */
569+
for (curr_backend=1;curr_backend <=num_backends;curr_backend++)
635570
{
636571
/* for each row */
637-
Datumvalues[22];
638-
boolnulls[22];
639-
HeapTupletuple;
572+
Datumvalues[PG_STAT_GET_ACTIVITY_COLS];
573+
boolnulls[PG_STAT_GET_ACTIVITY_COLS];
640574
LocalPgBackendStatus*local_beentry;
641575
PgBackendStatus*beentry;
642576

643577
MemSet(values,0,sizeof(values));
644578
MemSet(nulls,0,sizeof(nulls));
645579

646-
if (*(int*) (funcctx->user_fctx)>0)
647-
{
648-
/* Get specific pid slot */
649-
local_beentry=pgstat_fetch_stat_local_beentry(*(int*) (funcctx->user_fctx));
650-
beentry=&local_beentry->backendStatus;
651-
}
652-
else
580+
if (pid!=-1)
653581
{
654-
/* Get the next one in the list */
655-
local_beentry=pgstat_fetch_stat_local_beentry(funcctx->call_cntr+1);/* 1-based index */
656-
beentry=&local_beentry->backendStatus;
582+
/* Skip any which are not the one we're looking for. */
583+
PgBackendStatus*be=pgstat_fetch_stat_beentry(curr_backend);
584+
585+
if (!be||be->st_procpid!=pid)
586+
continue;
587+
657588
}
589+
590+
/* Get the next one in the list */
591+
local_beentry=pgstat_fetch_stat_local_beentry(curr_backend);
592+
if (!local_beentry)
593+
continue;
594+
595+
beentry=&local_beentry->backendStatus;
658596
if (!beentry)
659597
{
660598
inti;
@@ -665,8 +603,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
665603
nulls[5]= false;
666604
values[5]=CStringGetTextDatum("<backend information not available>");
667605

668-
tuple=heap_form_tuple(funcctx->tuple_desc,values,nulls);
669-
SRF_RETURN_NEXT(funcctx,HeapTupleGetDatum(tuple));
606+
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
607+
continue;
670608
}
671609

672610
/* Values available to all callers */
@@ -839,15 +777,17 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
839777
nulls[13]= true;
840778
}
841779

842-
tuple=heap_form_tuple(funcctx->tuple_desc,values,nulls);
780+
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
843781

844-
SRF_RETURN_NEXT(funcctx,HeapTupleGetDatum(tuple));
845-
}
846-
else
847-
{
848-
/* nothing left */
849-
SRF_RETURN_DONE(funcctx);
782+
/* If only a single backend was requested, and we found it, break. */
783+
if (pid!=-1)
784+
break;
850785
}
786+
787+
/* clean up and return the tuplestore */
788+
tuplestore_donestoring(tupstore);
789+
790+
return (Datum)0;
851791
}
852792

853793

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp