* Process query response from the backend. * * If varprefix is not NULL, it's the variable name prefix where to store * the results of the *last* command (META_GSET) or *all* commands * (META_ASET). * * Returns true if everything is A-OK, false if any error occurs. */
| 2967 | * Returns true if everything is A-OK, false if any error occurs. |
| 2968 | */ |
| 2969 | static bool |
| 2970 | readCommandResponse(CState *st, MetaCommand meta, char *varprefix) |
| 2971 | { |
| 2972 | PGresult *res; |
| 2973 | PGresult *next_res; |
| 2974 | int qrynum = 0; |
| 2975 | |
| 2976 | /* |
| 2977 | * varprefix should be set only with \gset or \aset, and \endpipeline and |
| 2978 | * SQL commands do not need it. |
| 2979 | */ |
| 2980 | Assert((meta == META_NONE && varprefix == NULL) || |
| 2981 | ((meta == META_ENDPIPELINE) && varprefix == NULL) || |
| 2982 | ((meta == META_GSET || meta == META_ASET) && varprefix != NULL)); |
| 2983 | |
| 2984 | res = PQgetResult(st->con); |
| 2985 | |
| 2986 | while (res != NULL) |
| 2987 | { |
| 2988 | bool is_last; |
| 2989 | |
| 2990 | /* peek at the next result to know whether the current is last */ |
| 2991 | next_res = PQgetResult(st->con); |
| 2992 | is_last = (next_res == NULL); |
| 2993 | |
| 2994 | switch (PQresultStatus(res)) |
| 2995 | { |
| 2996 | case PGRES_COMMAND_OK: /* non-SELECT commands */ |
| 2997 | case PGRES_EMPTY_QUERY: /* may be used for testing no-op overhead */ |
| 2998 | if (is_last && meta == META_GSET) |
| 2999 | { |
| 3000 | pg_log_error("client %d script %d command %d query %d: expected one row, got %d", |
| 3001 | st->id, st->use_file, st->command, qrynum, 0); |
| 3002 | goto error; |
| 3003 | } |
| 3004 | break; |
| 3005 | |
| 3006 | case PGRES_TUPLES_OK: |
| 3007 | if ((is_last && meta == META_GSET) || meta == META_ASET) |
| 3008 | { |
| 3009 | int ntuples = PQntuples(res); |
| 3010 | |
| 3011 | if (meta == META_GSET && ntuples != 1) |
| 3012 | { |
| 3013 | /* under \gset, report the error */ |
| 3014 | pg_log_error("client %d script %d command %d query %d: expected one row, got %d", |
| 3015 | st->id, st->use_file, st->command, qrynum, PQntuples(res)); |
| 3016 | goto error; |
| 3017 | } |
| 3018 | else if (meta == META_ASET && ntuples <= 0) |
| 3019 | { |
| 3020 | /* coldly skip empty result under \aset */ |
| 3021 | break; |
| 3022 | } |
| 3023 | |
| 3024 | /* store results into variables */ |
| 3025 | for (int fld = 0; fld < PQnfields(res); fld++) |
| 3026 | { |
no test coverage detected