| 522 | PG_FUNCTION_INFO_V1(xpath_table); |
| 523 | |
| 524 | Datum |
| 525 | xpath_table(PG_FUNCTION_ARGS) |
| 526 | { |
| 527 | /* Function parameters */ |
| 528 | char *pkeyfield = text_to_cstring(PG_GETARG_TEXT_PP(0)); |
| 529 | char *xmlfield = text_to_cstring(PG_GETARG_TEXT_PP(1)); |
| 530 | char *relname = text_to_cstring(PG_GETARG_TEXT_PP(2)); |
| 531 | char *xpathset = text_to_cstring(PG_GETARG_TEXT_PP(3)); |
| 532 | char *condition = text_to_cstring(PG_GETARG_TEXT_PP(4)); |
| 533 | |
| 534 | /* SPI (input tuple) support */ |
| 535 | SPITupleTable *tuptable; |
| 536 | HeapTuple spi_tuple; |
| 537 | TupleDesc spi_tupdesc; |
| 538 | |
| 539 | /* Output tuple (tuplestore) support */ |
| 540 | Tuplestorestate *tupstore = NULL; |
| 541 | TupleDesc ret_tupdesc; |
| 542 | HeapTuple ret_tuple; |
| 543 | |
| 544 | ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; |
| 545 | AttInMetadata *attinmeta; |
| 546 | MemoryContext per_query_ctx; |
| 547 | MemoryContext oldcontext; |
| 548 | |
| 549 | char **values; |
| 550 | xmlChar **xpaths; |
| 551 | char *pos; |
| 552 | const char *pathsep = "|"; |
| 553 | |
| 554 | int numpaths; |
| 555 | int ret; |
| 556 | uint64 proc; |
| 557 | int j; |
| 558 | int rownr; /* For issuing multiple rows from one original |
| 559 | * document */ |
| 560 | bool had_values; /* To determine end of nodeset results */ |
| 561 | StringInfoData query_buf; |
| 562 | PgXmlErrorContext *xmlerrcxt; |
| 563 | volatile xmlDocPtr doctree = NULL; |
| 564 | |
| 565 | /* We only have a valid tuple description in table function mode */ |
| 566 | if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) |
| 567 | ereport(ERROR, |
| 568 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 569 | errmsg("set-valued function called in context that cannot accept a set"))); |
| 570 | if (rsinfo->expectedDesc == NULL) |
| 571 | ereport(ERROR, |
| 572 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 573 | errmsg("xpath_table must be called as a table function"))); |
| 574 | |
| 575 | /* |
| 576 | * We want to materialise because it means that we don't have to carry |
| 577 | * libxml2 parser state between invocations of this function |
| 578 | */ |
| 579 | if (!(rsinfo->allowedModes & SFRM_Materialize)) |
| 580 | ereport(ERROR, |
| 581 | (errcode(ERRCODE_SYNTAX_ERROR), |
nothing calls this directly
no test coverage detected