static void process_edge_data(Datum callgraph_buffer_id) { int ret; HASH_SEQ_STATUS hst; EdgeHashElem *elem; SPIPlanPtr planptr; Datum args[7]; Oid argtypes[] = { INT8OID, OIDOID, OIDOID, OIDOID, INT8OID, FLOAT8OID, FLOAT8OID, InvalidOid }; /* Start by freezing the hash table. This saves us some trouble. */ hash_freeze(edge_hash_table); if ((ret = SPI_connect()) < 0) elog(ERROR, "could not connect to the SPI: %d", ret); planptr = SPI_prepare("INSERT INTO " " call_graph.CallGraphBuffer (CallGraphBufferID, TopLevelFunction, Caller, Callee, " " Calls, TotalTime, SelfTime) " " VALUES ($1, $2, $3, $4, $5, $6, $7) ", 7, argtypes); if (!planptr) elog(ERROR, "could not prepare an SPI plan for the INSERT into CallGraphBuffer"); args[0] = callgraph_buffer_id; args[1] = ObjectIdGetDatum(top_level_function_oid); hash_seq_init(&hst, edge_hash_table); while ((elem = hash_seq_search(&hst)) != NULL) { args[2] = ObjectIdGetDatum(elem->key.caller); args[3] = ObjectIdGetDatum(elem->key.callee); args[4] = Int8GetDatum(elem->num_calls); args[5] = Float8GetDatum(INSTR_TIME_GET_MILLISEC(elem->total_time)); args[6] = Float8GetDatum(INSTR_TIME_GET_MILLISEC(elem->self_time)); if ((ret = SPI_execp(planptr, args, NULL, 0)) < 0) elog(ERROR, "SPI_execp() failed: %d", ret); } SPI_finish(); }
bool array_next(array_iter *iter, Datum *value, bool *isna) { bits8 *nulls; if (iter->index >= iter->max) { *value = (Datum) 0; *isna = true; return false; } if (iter->index < 0) { *value = (Datum) 0; *isna = true; iter->index++; return true; } nulls = ARR_NULLBITMAP(iter->array); if (nulls && !(nulls[iter->index / 8] & (1 << (iter->index % 8)))) { *value = (Datum) 0; *isna = true; iter->index++; return true; } *isna = false; if (iter->typlen > 0) { /* fixed length */ if (iter->typlen <= 8) { switch (iter->typlen) { case 1: *value = Int8GetDatum(*((int8*) iter->ptr)); break; case 2: *value = Int16GetDatum(*((int16*) iter->ptr)); break; case 4: *value = Int32GetDatum(*((int16*) iter->ptr)); break; case 8: *value = Int64GetDatum(*((int16*) iter->ptr)); break; default: elog(ERROR, "unexpected data type"); break; } } else { *value = PointerGetDatum(iter->ptr); } iter->ptr += iter->typlen; } else { /* variable length */ *value = PointerGetDatum(iter->ptr); iter->ptr += VARSIZE(iter->ptr); } iter->ptr = (char*) att_align(iter->ptr, iter->typalign); iter->index++; return true; }