int pbc_pattern_unpack(struct pbc_pattern *pat, struct pbc_slice *s, void * output) { pbc_ctx _ctx; int r = _pbcC_open(_ctx, s->buffer, s->len); if (r <= 0) { _pbcC_close(_ctx); return r+1; } set_default(pat, output); struct context * ctx = (struct context *)_ctx; int i; for (i=0;i<ctx->number;i++) { struct _pattern_field * f = bsearch_pattern(pat, ctx->a[i].id); if (f) { char * out = (char *)output + f->offset; if (unpack_field(f->ctype , f->ptype , ctx->buffer , &ctx->a[i], out) != 0) { pbc_pattern_close_arrays(pat, output); _pbcC_close(_ctx); return -i-1; } } } _pbcC_close(_ctx); return 0; }
static int unpack_array(int ptype, char *buffer, struct atom * a, pbc_array _array) { pbc_var var; int r = unpack_field(CTYPE_VAR, ptype, buffer, a , var); if (r !=0 ) return r; _pbcA_push(_array , var); return 0; }
static Datum dbms_pipe_unpack_message(PG_FUNCTION_ARGS, message_data_type dtype) { Oid tupType; void *ptr; message_data_type type; int32 size; Datum result; message_data_type next_type; if (input_buffer == NULL || input_buffer->items_count <= 0 || input_buffer->next == NULL || input_buffer->next->type == IT_NO_MORE_ITEMS) PG_RETURN_NULL(); next_type = input_buffer->next->type; if (next_type != dtype) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("datatype mismatch"), errdetail("unpack unexpected type: %d", next_type))); ptr = unpack_field(input_buffer, &type, &size, &tupType); Assert(ptr != NULL); switch (type) { case IT_TIMESTAMPTZ: result = TimestampTzGetDatum(*(TimestampTz*)ptr); break; case IT_DATE: result = DateADTGetDatum(*(DateADT*)ptr); break; case IT_VARCHAR: case IT_NUMBER: case IT_BYTEA: result = PointerGetDatum(cstring_to_text_with_len(ptr, size)); break; case IT_RECORD: { #if PG_VERSION_NUM >= 120000 LOCAL_FCINFO(info, 3); #else FunctionCallInfoData info_data; FunctionCallInfo info = &info_data; #endif StringInfoData buf; text *data = cstring_to_text_with_len(ptr, size); buf.data = VARDATA(data); buf.len = VARSIZE(data) - VARHDRSZ; buf.maxlen = buf.len; buf.cursor = 0; /* * Normally one would call record_recv() using DirectFunctionCall3, * but that does not work since record_recv wants to cache some data * using fcinfo->flinfo->fn_extra. So we need to pass it our own * flinfo parameter. */ InitFunctionCallInfoData(*info, fcinfo->flinfo, 3, InvalidOid, NULL, NULL); init_args_3(info, PointerGetDatum(&buf), ObjectIdGetDatum(tupType), Int32GetDatum(-1)); result = record_recv(info); break; } default: elog(ERROR, "unexpected type: %d", type); result = (Datum) 0; /* keep compiler quiet */ } if (input_buffer->items_count == 0) { pfree(input_buffer); input_buffer = NULL; } PG_RETURN_DATUM(result); }