copy-from-csv.pt 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. # Note that this file will not work on PG due to the lack of "strict" parsing
  2. # from the Rust CSV crate: https://github.com/BurntSushi/rust-csv/issues/77
  3. send
  4. Query {"query": "DROP TABLE IF EXISTS t"}
  5. ----
  6. until ignore=NoticeResponse
  7. ReadyForQuery
  8. ----
  9. CommandComplete {"tag":"DROP TABLE"}
  10. ReadyForQuery {"status":"I"}
  11. send
  12. Query {"query": "CREATE TABLE t (i INT8, t TEXT)"}
  13. ----
  14. until
  15. ReadyForQuery
  16. ----
  17. CommandComplete {"tag":"CREATE TABLE"}
  18. ReadyForQuery {"status":"I"}
  19. # Note that we cannot differentiate between empty string and the quoted empty
  20. # string, both of which will generate NULL in MZ.
  21. send
  22. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV)"}
  23. CopyData "1,one\n"
  24. CopyData "2,\"two\"\n"
  25. CopyData "3,\"\"\"three\"\"\"\n"
  26. CopyData "4,\"fo,ur\"\n"
  27. CopyData "5,\"\"\n"
  28. CopyData "6,\n"
  29. CopyData "7,\"seven\n"
  30. CopyData "8,eight\n"
  31. CopyDone
  32. Query {"query": "SELECT * FROM t ORDER BY i"}
  33. ----
  34. until
  35. ReadyForQuery
  36. ReadyForQuery
  37. ----
  38. CopyIn {"format":"text","column_formats":["text","text"]}
  39. CommandComplete {"tag":"COPY 7"}
  40. ReadyForQuery {"status":"I"}
  41. RowDescription {"fields":[{"name":"i"},{"name":"t"}]}
  42. DataRow {"fields":["1","one"]}
  43. DataRow {"fields":["2","two"]}
  44. DataRow {"fields":["3","\"three\""]}
  45. DataRow {"fields":["4","fo,ur"]}
  46. DataRow {"fields":["5","NULL"]}
  47. DataRow {"fields":["6","NULL"]}
  48. DataRow {"fields":["7","seven\n8,eight\n"]}
  49. CommandComplete {"tag":"SELECT 7"}
  50. ReadyForQuery {"status":"I"}
  51. # Change options. Note that:
  52. # - After receiving terminating char, no other data should be accepted
  53. # - Quoted end of copy markers are still processed as end of copy markers
  54. send
  55. Query {"query": "DELETE FROM t"}
  56. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV, QUOTE '|', ESCAPE '#', NULL 'NS', HEADER true)"}
  57. CopyData "Header,IsIgnored\n"
  58. CopyData "1,NS\n"
  59. CopyData "2,|two|\n"
  60. CopyData "3,|#|three#||\n"
  61. CopyData "4,|fo,ur|\n"
  62. CopyData "5,\"five\"\n"
  63. CopyData "6,||\n"
  64. CopyData "|\\.|\n"
  65. CopyData "invalid data"
  66. CopyDone
  67. Query {"query": "SELECT * FROM t ORDER BY i"}
  68. ----
  69. until
  70. ReadyForQuery
  71. ReadyForQuery
  72. ReadyForQuery
  73. ----
  74. CommandComplete {"tag":"DELETE 7"}
  75. ReadyForQuery {"status":"I"}
  76. CopyIn {"format":"text","column_formats":["text","text"]}
  77. CommandComplete {"tag":"COPY 6"}
  78. ReadyForQuery {"status":"I"}
  79. RowDescription {"fields":[{"name":"i"},{"name":"t"}]}
  80. DataRow {"fields":["1","NULL"]}
  81. DataRow {"fields":["2","two"]}
  82. DataRow {"fields":["3","|three|"]}
  83. DataRow {"fields":["4","fo,ur"]}
  84. DataRow {"fields":["5","\"five\""]}
  85. DataRow {"fields":["6",""]}
  86. CommandComplete {"tag":"SELECT 6"}
  87. ReadyForQuery {"status":"I"}
  88. send
  89. Query {"query": "DELETE FROM t"}
  90. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV, DELIMITER '#', ESCAPE '#')"}
  91. CopyData "1#\"one\"\n"
  92. CopyData "2#\"#\"two#\"\"\n"
  93. CopyData "3#\"thr##ee\"\n"
  94. CopyDone
  95. Query {"query": "SELECT * FROM t ORDER BY i"}
  96. ----
  97. until
  98. ReadyForQuery
  99. ReadyForQuery
  100. ReadyForQuery
  101. ----
  102. CommandComplete {"tag":"DELETE 6"}
  103. ReadyForQuery {"status":"I"}
  104. CopyIn {"format":"text","column_formats":["text","text"]}
  105. CommandComplete {"tag":"COPY 3"}
  106. ReadyForQuery {"status":"I"}
  107. RowDescription {"fields":[{"name":"i"},{"name":"t"}]}
  108. DataRow {"fields":["1","one"]}
  109. DataRow {"fields":["2","\"two\""]}
  110. DataRow {"fields":["3","thr#ee"]}
  111. CommandComplete {"tag":"SELECT 3"}
  112. ReadyForQuery {"status":"I"}
  113. # ESCAPE defaults to QUOTE if not provided, and exhibits same behavior as
  114. # default.
  115. send
  116. Query {"query": "DELETE FROM t"}
  117. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV, QUOTE '#')"}
  118. CopyData "1,#one#\n"
  119. CopyData "2,###two###\n"
  120. CopyData "3,#thr##ee#\n"
  121. CopyDone
  122. Query {"query": "SELECT * FROM t ORDER BY i"}
  123. ----
  124. until
  125. ReadyForQuery
  126. ReadyForQuery
  127. ReadyForQuery
  128. ----
  129. CommandComplete {"tag":"DELETE 3"}
  130. ReadyForQuery {"status":"I"}
  131. CopyIn {"format":"text","column_formats":["text","text"]}
  132. CommandComplete {"tag":"COPY 3"}
  133. ReadyForQuery {"status":"I"}
  134. RowDescription {"fields":[{"name":"i"},{"name":"t"}]}
  135. DataRow {"fields":["1","one"]}
  136. DataRow {"fields":["2","#two#"]}
  137. DataRow {"fields":["3","thr#ee"]}
  138. CommandComplete {"tag":"SELECT 3"}
  139. ReadyForQuery {"status":"I"}
  140. # Invalid data
  141. send
  142. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV)"}
  143. CopyData "1\n"
  144. CopyDone
  145. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV)"}
  146. CopyData "1,2,3\n"
  147. CopyDone
  148. ----
  149. until
  150. ErrorResponse
  151. ReadyForQuery
  152. ErrorResponse
  153. ReadyForQuery
  154. ----
  155. CopyIn {"format":"text","column_formats":["text","text"]}
  156. ErrorResponse {"fields":[{"typ":"S","value":"ERROR"},{"typ":"C","value":"22P04"},{"typ":"M","value":"missing data for column"}]}
  157. ReadyForQuery {"status":"I"}
  158. CopyIn {"format":"text","column_formats":["text","text"]}
  159. ErrorResponse {"fields":[{"typ":"S","value":"ERROR"},{"typ":"C","value":"22P04"},{"typ":"M","value":"extra data after last expected column"}]}
  160. ReadyForQuery {"status":"I"}
  161. send
  162. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV, DELIMITER '||')"}
  163. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV, QUOTE '||')"}
  164. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV, ESCAPE '||')"}
  165. ----
  166. until
  167. ErrorResponse
  168. ReadyForQuery
  169. ErrorResponse
  170. ReadyForQuery
  171. ErrorResponse
  172. ReadyForQuery
  173. ----
  174. ErrorResponse {"fields":[{"typ":"S","value":"ERROR"},{"typ":"C","value":"XX000"},{"typ":"M","value":"COPY delimiter must be a single one-byte character"}]}
  175. ReadyForQuery {"status":"I"}
  176. ErrorResponse {"fields":[{"typ":"S","value":"ERROR"},{"typ":"C","value":"XX000"},{"typ":"M","value":"COPY quote must be a single one-byte character"}]}
  177. ReadyForQuery {"status":"I"}
  178. ErrorResponse {"fields":[{"typ":"S","value":"ERROR"},{"typ":"C","value":"XX000"},{"typ":"M","value":"COPY escape must be a single one-byte character"}]}
  179. ReadyForQuery {"status":"I"}
  180. send
  181. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV, DELIMITER '\"')"}
  182. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV, QUOTE ',')"}
  183. Query {"query": "COPY t FROM STDIN WITH (FORMAT CSV, DELIMITER '!', QUOTE '!')"}
  184. ----
  185. until
  186. ErrorResponse
  187. ReadyForQuery
  188. ErrorResponse
  189. ReadyForQuery
  190. ErrorResponse
  191. ReadyForQuery
  192. ----
  193. ErrorResponse {"fields":[{"typ":"S","value":"ERROR"},{"typ":"C","value":"XX000"},{"typ":"M","value":"COPY delimiter and quote must be different"}]}
  194. ReadyForQuery {"status":"I"}
  195. ErrorResponse {"fields":[{"typ":"S","value":"ERROR"},{"typ":"C","value":"XX000"},{"typ":"M","value":"COPY delimiter and quote must be different"}]}
  196. ReadyForQuery {"status":"I"}
  197. ErrorResponse {"fields":[{"typ":"S","value":"ERROR"},{"typ":"C","value":"XX000"},{"typ":"M","value":"COPY delimiter and quote must be different"}]}
  198. ReadyForQuery {"status":"I"}