* Split TABLE[(COLUMNS)] into TABLE and [(COLUMNS)] portions. When you * finish using them, pg_free(*table). *columns is a pointer into "spec", * possibly to its NUL terminator. */
| 32 | * possibly to its NUL terminator. |
| 33 | */ |
| 34 | void |
| 35 | splitTableColumnsSpec(const char *spec, int encoding, |
| 36 | char **table, const char **columns) |
| 37 | { |
| 38 | bool inquotes = false; |
| 39 | const char *cp = spec; |
| 40 | |
| 41 | /* |
| 42 | * Find the first '(' not identifier-quoted. Based on |
| 43 | * dequote_downcase_identifier(). |
| 44 | */ |
| 45 | while (*cp && (*cp != '(' || inquotes)) |
| 46 | { |
| 47 | if (*cp == '"') |
| 48 | { |
| 49 | if (inquotes && cp[1] == '"') |
| 50 | cp++; /* pair does not affect quoting */ |
| 51 | else |
| 52 | inquotes = !inquotes; |
| 53 | cp++; |
| 54 | } |
| 55 | else |
| 56 | cp += PQmblenBounded(cp, encoding); |
| 57 | } |
| 58 | *table = pnstrdup(spec, cp - spec); |
| 59 | *columns = cp; |
| 60 | } |
| 61 | |
| 62 | /* |
| 63 | * Break apart TABLE[(COLUMNS)] of "spec". With the reset_val of search_path |
no test coverage detected