* starts a copy command on a specific segment database. * * may pg_throw via elog/ereport. */
| 154 | * may pg_throw via elog/ereport. |
| 155 | */ |
| 156 | void |
| 157 | cdbCopyStart(CdbCopy *c, CopyStmt *stmt, int file_encoding) |
| 158 | { |
| 159 | int flags; |
| 160 | |
| 161 | stmt = copyObject(stmt); |
| 162 | |
| 163 | /* |
| 164 | * If the output needs to be in a different encoding, tell the segment. |
| 165 | * Normally, when we run normal queries, we keep the segment connections |
| 166 | * in database encoding, and do the encoding conversions in the QD, just |
| 167 | * before sending results to the client. But in COPY TO, we don't do |
| 168 | * any conversions to the data we receive from the segments, so they |
| 169 | * must produce the output in the correct encoding. |
| 170 | * |
| 171 | * We do this by adding "ENCODING 'xxx'" option to the options list of |
| 172 | * the CopyStmt that we dispatch. |
| 173 | */ |
| 174 | if (file_encoding != GetDatabaseEncoding()) |
| 175 | { |
| 176 | bool found; |
| 177 | ListCell *option; |
| 178 | |
| 179 | /* |
| 180 | * But first check if the encoding option is already in the options |
| 181 | * list (i.e the user specified it explicitly in the COPY command) |
| 182 | */ |
| 183 | found = false; |
| 184 | foreach(option, stmt->options) |
| 185 | { |
| 186 | DefElem *defel = (DefElem *) lfirst(option); |
| 187 | |
| 188 | if (strcmp(defel->defname, "encoding") == 0) |
| 189 | { |
| 190 | /* |
| 191 | * The 'file_encoding' came from the options, so they should match, but |
| 192 | * let's sanity-check. |
| 193 | */ |
| 194 | if (pg_char_to_encoding(defGetString(defel)) != file_encoding) |
| 195 | elog(ERROR, "encoding option in original COPY command does not match encoding being dispatched"); |
| 196 | found = true; |
| 197 | } |
| 198 | } |
| 199 | |
| 200 | if (!found) |
| 201 | { |
| 202 | const char *encname = pg_encoding_to_char(file_encoding); |
| 203 | |
| 204 | stmt->options = lappend(stmt->options, |
| 205 | makeDefElem("encoding", |
| 206 | (Node *) makeString(pstrdup(encname)), -1)); |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | flags = DF_WITH_SNAPSHOT | DF_CANCEL_ON_ERROR; |
| 211 | if (c->copy_in) |
| 212 | flags |= DF_NEED_TWO_PHASE; |
| 213 |
no test coverage detected