static int gbt_intvkey_cmp(const void *a, const void *b) { return DatumGetInt32( DirectFunctionCall2(interval_cmp, IntervalPGetDatum(((Nsrt *) a)->t), IntervalPGetDatum(((Nsrt *) b)->t) ) ); }
static int gbt_intvkey_cmp(const void *a, const void *b) { intvKEY *ia = (intvKEY *) (((Nsrt *) a)->t); intvKEY *ib = (intvKEY *) (((Nsrt *) b)->t); int res; res = DatumGetInt32(DirectFunctionCall2(interval_cmp, IntervalPGetDatum(&ia->lower), IntervalPGetDatum(&ib->lower))); if (res == 0) return DatumGetInt32(DirectFunctionCall2(interval_cmp, IntervalPGetDatum(&ia->upper), IntervalPGetDatum(&ib->upper))); return res; }
Interval * abs_interval(Interval *a) { static Interval zero = {0, 0, 0}; if (DatumGetBool(DirectFunctionCall2(interval_lt, IntervalPGetDatum(a), IntervalPGetDatum(&zero)))) a = DatumGetIntervalP(DirectFunctionCall1(interval_um, IntervalPGetDatum(a))); return a; }
static Datum leftmostvalue_interval(void) { Interval *v = palloc(sizeof(Interval)); v->time = DT_NOBEGIN; v->day = 0; v->month = 0; return IntervalPGetDatum(v); }
static bool gbt_intvlt(const void *a, const void *b) { return DatumGetBool(DirectFunctionCall2(interval_lt, IntervalPGetDatum(a), IntervalPGetDatum(b))); }
Datum pg_stat_get_activity(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; TupleDesc tupdesc; int nattr = 16; funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); tupdesc = CreateTemplateTupleDesc(nattr, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "datid", OIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "procpid", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 3, "usesysid", OIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 4, "application_name", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 5, "current_query", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, "waiting", BOOLOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 7, "act_start", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 8, "query_start", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 9, "backend_start", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 10, "client_addr", INETOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 11, "client_port", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 12, "sess_id", INT4OID, -1, 0); /* GPDB */ if (nattr > 12) TupleDescInitEntry(tupdesc, (AttrNumber) 13, "waiting_for", TEXTOID, -1, 0); if (nattr > 13) { TupleDescInitEntry(tupdesc, (AttrNumber) 14, "rsgid", OIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 15, "rsgname", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 16, "rsgqueueduration", INTERVALOID, -1, 0); } funcctx->tuple_desc = BlessTupleDesc(tupdesc); funcctx->user_fctx = palloc0(sizeof(int)); if (PG_ARGISNULL(0)) { /* Get all backends */ funcctx->max_calls = pgstat_fetch_stat_numbackends(); } else { /* * Get one backend - locate by pid. * * We lookup the backend early, so we can return zero rows if it * doesn't exist, instead of returning a single row full of NULLs. */ int pid = PG_GETARG_INT32(0); int i; int n = pgstat_fetch_stat_numbackends(); for (i = 1; i <= n; i++) { PgBackendStatus *be = pgstat_fetch_stat_beentry(i); if (be) { if (be->st_procpid == pid) { *(int *) (funcctx->user_fctx) = i; break; } } } if (*(int *) (funcctx->user_fctx) == 0) /* Pid not found, return zero rows */ funcctx->max_calls = 0; else funcctx->max_calls = 1; } MemoryContextSwitchTo(oldcontext); } /* stuff done on every call of the function */ funcctx = SRF_PERCALL_SETUP(); if (funcctx->call_cntr < funcctx->max_calls) { /* for each row */ Datum values[16]; bool nulls[16]; HeapTuple tuple; PgBackendStatus *beentry; MemSet(values, 0, sizeof(values)); MemSet(nulls, 0, sizeof(nulls)); if (*(int *) (funcctx->user_fctx) > 0) { /* Get specific pid slot */ beentry = pgstat_fetch_stat_beentry(*(int *) (funcctx->user_fctx)); } else { /* Get the next one in the list */ beentry = pgstat_fetch_stat_beentry(funcctx->call_cntr + 1); /* 1-based index */ } if (!beentry) { int i; for (i = 0; i < sizeof(nulls) / sizeof(nulls[0]); i++) nulls[i] = true; nulls[4] = false; values[4] = CStringGetTextDatum("<backend information not available>"); tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple)); } /* Values available to all callers */ values[0] = ObjectIdGetDatum(beentry->st_databaseid); values[1] = Int32GetDatum(beentry->st_procpid); values[2] = ObjectIdGetDatum(beentry->st_userid); if (beentry->st_appname) values[3] = CStringGetTextDatum(beentry->st_appname); else nulls[3] = true; /* Values only available to same user or superuser */ if (superuser() || beentry->st_userid == GetUserId()) { SockAddr zero_clientaddr; bool waiting; if (*(beentry->st_activity) == '\0') { values[4] = CStringGetTextDatum("<command string not enabled>"); } else { values[4] = CStringGetTextDatum(beentry->st_activity); } waiting = beentry->st_waiting != PGBE_WAITING_NONE; values[5] = BoolGetDatum(beentry->st_waiting); if (beentry->st_xact_start_timestamp != 0) values[6] = TimestampTzGetDatum(beentry->st_xact_start_timestamp); else nulls[6] = true; if (beentry->st_activity_start_timestamp != 0) values[7] = TimestampTzGetDatum(beentry->st_activity_start_timestamp); else nulls[7] = true; if (beentry->st_proc_start_timestamp != 0) values[8] = TimestampTzGetDatum(beentry->st_proc_start_timestamp); else nulls[8] = true; /* A zeroed client addr means we don't know */ memset(&zero_clientaddr, 0, sizeof(zero_clientaddr)); if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr, sizeof(zero_clientaddr)) == 0) { nulls[9] = true; nulls[10] = true; } else { if (beentry->st_clientaddr.addr.ss_family == AF_INET #ifdef HAVE_IPV6 || beentry->st_clientaddr.addr.ss_family == AF_INET6 #endif ) { char remote_host[NI_MAXHOST]; char remote_port[NI_MAXSERV]; int ret; remote_host[0] = '\0'; remote_port[0] = '\0'; ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr, beentry->st_clientaddr.salen, remote_host, sizeof(remote_host), remote_port, sizeof(remote_port), NI_NUMERICHOST | NI_NUMERICSERV); if (ret) { nulls[9] = true; nulls[10] = true; } else { clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host); values[9] = DirectFunctionCall1(inet_in, CStringGetDatum(remote_host)); values[10] = Int32GetDatum(atoi(remote_port)); } } else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX) { /* * Unix sockets always reports NULL for host and -1 for * port, so it's possible to tell the difference to * connections we have no permissions to view, or with * errors. */ nulls[9] = true; values[10] = DatumGetInt32(-1); } else { /* Unknown address type, should never happen */ nulls[9] = true; nulls[10] = true; } } values[11] = Int32GetDatum(beentry->st_session_id); /* GPDB */ if (funcctx->tuple_desc->natts > 12) { char st_waiting = beentry->st_waiting; char *reason; reason = pgstat_waiting_string(st_waiting); if (reason != NULL) values[12] = CStringGetTextDatum(reason); else nulls[12] = true; } if (funcctx->tuple_desc->natts > 13) { Interval interval; MemSet(&interval, 0, sizeof(interval)); values[13] = ObjectIdGetDatum(0); values[14] = CStringGetTextDatum("default"); values[15] = IntervalPGetDatum(&interval); } } else { /* No permissions to view data about this session */ values[4] = CStringGetTextDatum("<insufficient privilege>"); nulls[5] = true; nulls[6] = true; nulls[7] = true; nulls[8] = true; nulls[9] = true; nulls[10] = true; values[11] = Int32GetDatum(beentry->st_session_id); if (funcctx->tuple_desc->natts > 12) nulls[12] = true; if (funcctx->tuple_desc->natts > 13) { nulls[13] = true; nulls[14] = true; nulls[15] = true; } } tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple)); } else { /* nothing left */ SRF_RETURN_DONE(funcctx); } }