| 95 | */ |
| 96 | PG_FUNCTION_INFO_V1(svec_unnest); |
| 97 | Datum svec_unnest(PG_FUNCTION_ARGS) |
| 98 | { |
| 99 | FuncCallContext *funcctx; |
| 100 | svec_unnest_fctx *fctx; |
| 101 | MemoryContext oldcontext; |
| 102 | float8 result; |
| 103 | SvecType *svec; |
| 104 | int run_length=0; |
| 105 | |
| 106 | /* stuff done only on the first call of the function */ |
| 107 | if (SRF_IS_FIRSTCALL()) |
| 108 | { |
| 109 | /* create a function context for cross-call persistence */ |
| 110 | funcctx = SRF_FIRSTCALL_INIT(); |
| 111 | |
| 112 | /* switch to memory context appropriate for multiple |
| 113 | * function calls |
| 114 | */ |
| 115 | oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); |
| 116 | |
| 117 | /* allocate memory for user context */ |
| 118 | fctx = (svec_unnest_fctx *) |
| 119 | palloc(sizeof(svec_unnest_fctx)); |
| 120 | |
| 121 | svec = PG_GETARG_SVECTYPE_P(0); |
| 122 | fctx->sdata = sdata_from_svec(svec); |
| 123 | |
| 124 | /* set initial index into the sparse vector argument */ |
| 125 | fctx->dimension = svec->dimension; |
| 126 | if (fctx->dimension == -1) fctx->dimension = 1; |
| 127 | fctx->absolute_value_position = 0; |
| 128 | fctx->unique_value_position = 0; |
| 129 | fctx->index_position = fctx->sdata->index->data; |
| 130 | fctx->run_position = 1; |
| 131 | |
| 132 | funcctx->user_fctx = fctx; |
| 133 | |
| 134 | MemoryContextSwitchTo(oldcontext); |
| 135 | } |
| 136 | |
| 137 | /* stuff done on every call of the function */ |
| 138 | funcctx = SRF_PERCALL_SETUP(); |
| 139 | |
| 140 | fctx = funcctx->user_fctx; |
| 141 | |
| 142 | run_length = compword_to_int8(fctx->index_position); |
| 143 | |
| 144 | if (fctx->dimension > fctx->absolute_value_position) |
| 145 | { |
| 146 | result = ((float8 *)(fctx->sdata->vals->data)) |
| 147 | [fctx->unique_value_position]; |
| 148 | |
| 149 | fctx->absolute_value_position++; |
| 150 | fctx->run_position++; |
| 151 | if (fctx->run_position > run_length) |
| 152 | { |
| 153 | fctx->run_position = 1; |
| 154 | fctx->unique_value_position++; |
nothing calls this directly
no test coverage detected