* parse_ident - parse a SQL qualified identifier into separate identifiers. * When strict mode is active (second parameter), then any chars after * the last identifier are disallowed. */
| 710 | * the last identifier are disallowed. |
| 711 | */ |
| 712 | Datum |
| 713 | parse_ident(PG_FUNCTION_ARGS) |
| 714 | { |
| 715 | text *qualname = PG_GETARG_TEXT_PP(0); |
| 716 | bool strict = PG_GETARG_BOOL(1); |
| 717 | char *qualname_str = text_to_cstring(qualname); |
| 718 | ArrayBuildState *astate = NULL; |
| 719 | char *nextp; |
| 720 | bool after_dot = false; |
| 721 | |
| 722 | /* |
| 723 | * The code below scribbles on qualname_str in some cases, so we should |
| 724 | * reconvert qualname if we need to show the original string in error |
| 725 | * messages. |
| 726 | */ |
| 727 | nextp = qualname_str; |
| 728 | |
| 729 | /* skip leading whitespace */ |
| 730 | while (scanner_isspace(*nextp)) |
| 731 | nextp++; |
| 732 | |
| 733 | for (;;) |
| 734 | { |
| 735 | char *curname; |
| 736 | bool missing_ident = true; |
| 737 | |
| 738 | if (*nextp == '"') |
| 739 | { |
| 740 | char *endp; |
| 741 | |
| 742 | curname = nextp + 1; |
| 743 | for (;;) |
| 744 | { |
| 745 | endp = strchr(nextp + 1, '"'); |
| 746 | if (endp == NULL) |
| 747 | ereport(ERROR, |
| 748 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 749 | errmsg("string is not a valid identifier: \"%s\"", |
| 750 | text_to_cstring(qualname)), |
| 751 | errdetail("String has unclosed double quotes."))); |
| 752 | if (endp[1] != '"') |
| 753 | break; |
| 754 | memmove(endp, endp + 1, strlen(endp)); |
| 755 | nextp = endp; |
| 756 | } |
| 757 | nextp = endp + 1; |
| 758 | *endp = '\0'; |
| 759 | |
| 760 | if (endp - curname == 0) |
| 761 | ereport(ERROR, |
| 762 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 763 | errmsg("string is not a valid identifier: \"%s\"", |
| 764 | text_to_cstring(qualname)), |
| 765 | errdetail("Quoted identifier must not be empty."))); |
| 766 | |
| 767 | astate = accumArrayResult(astate, CStringGetTextDatum(curname), |
| 768 | false, TEXTOID, CurrentMemoryContext); |
| 769 | missing_ident = false; |
nothing calls this directly
no test coverage detected