未验证 提交 efba04ce 编写于 作者: W Wen Lin 提交者: GitHub

Fix a delimiter bug if external table has delimiter 'OFF', and the value of the column is 'O'.

Add a bool flag 'delim_off' for CopyStateData to indicate if delimiter is set to OFF or not.
上级 7792d42e
......@@ -1232,13 +1232,13 @@ ProcessCopyOptions(CopyState cstate,
{
bool format_specified = false;
ListCell *option;
bool delim_off = false;
/* Support external use for option sanity checking */
if (cstate == NULL)
cstate = (CopyStateData *) palloc0(sizeof(CopyStateData));
cstate->escape_off = false;
cstate->delim_off = false;
cstate->file_encoding = -1;
/* Extract options from the statement node tree */
......@@ -1291,7 +1291,7 @@ ProcessCopyOptions(CopyState cstate,
cstate->delim = defGetString(defel);
if (cstate->delim && pg_strcasecmp(cstate->delim, "off") == 0)
delim_off = true;
cstate->delim_off = true;
}
else if (strcmp(defel->defname, "null") == 0)
{
......@@ -1506,7 +1506,7 @@ ProcessCopyOptions(CopyState cstate,
* future-proofing. Likewise we disallow all digits though only octal
* digits are actually dangerous.
*/
if (!cstate->csv_mode && !delim_off &&
if (!cstate->csv_mode && !cstate->delim_off &&
strchr("\\.abcdefghijklmnopqrstuvwxyz0123456789",
cstate->delim[0]) != NULL)
ereport(ERROR,
......@@ -1534,7 +1534,7 @@ ProcessCopyOptions(CopyState cstate,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("COPY quote must be a single one-byte character")));
if (cstate->csv_mode && cstate->delim[0] == cstate->quote[0] && !delim_off)
if (cstate->csv_mode && cstate->delim[0] == cstate->quote[0] && !cstate->delim_off)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("COPY delimiter and quote must be different")));
......@@ -1609,7 +1609,7 @@ ProcessCopyOptions(CopyState cstate,
if (pg_database_encoding_max_length() == 1)
{
/* single byte encoding such as ascii, latinx and other */
if (strlen(cstate->delim) != 1 && !delim_off)
if (strlen(cstate->delim) != 1 && !cstate->delim_off)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("COPY delimiter must be a single one-byte character, or \'off\'")));
......@@ -1617,7 +1617,7 @@ ProcessCopyOptions(CopyState cstate,
else
{
/* multi byte encoding such as utf8 */
if ((strlen(cstate->delim) != 1 || IS_HIGHBIT_SET(cstate->delim[0])) && !delim_off )
if ((strlen(cstate->delim) != 1 || IS_HIGHBIT_SET(cstate->delim[0])) && !cstate->delim_off )
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("COPY delimiter must be a single one-byte character, or \'off\'")));
......@@ -1635,12 +1635,12 @@ ProcessCopyOptions(CopyState cstate,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("COPY delimiter cannot be backslash")));
if (strchr(cstate->null_print, cstate->delim[0]) != NULL && !delim_off)
if (strchr(cstate->null_print, cstate->delim[0]) != NULL && !cstate->delim_off)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("COPY delimiter must not appear in the NULL specification")));
if (delim_off)
if (cstate->delim_off)
{
/*
......@@ -6509,6 +6509,7 @@ CopyReadAttributesText(CopyState cstate, int stop_processing_at_field)
{
char delimc = cstate->delim[0];
char escapec = cstate->escape_off ? delimc : cstate->escape[0];
bool delim_off = cstate->delim_off;
int fieldno;
char *output_ptr;
char *cur_ptr;
......@@ -6594,7 +6595,7 @@ CopyReadAttributesText(CopyState cstate, int stop_processing_at_field)
if (cur_ptr >= line_end_ptr)
break;
c = *cur_ptr++;
if (c == delimc)
if (c == delimc && !delim_off)
{
found_delim = true;
break;
......@@ -6755,6 +6756,7 @@ static int
CopyReadAttributesCSV(CopyState cstate, int stop_processing_at_field)
{
char delimc = cstate->delim[0];
bool delim_off = cstate->delim_off;
char quotec = cstate->quote[0];
char escapec = cstate->escape[0];
int fieldno;
......@@ -6842,7 +6844,7 @@ CopyReadAttributesCSV(CopyState cstate, int stop_processing_at_field)
goto endfield;
c = *cur_ptr++;
/* unquoted field delimiter */
if (c == delimc)
if (c == delimc && !delim_off)
{
found_delim = true;
goto endfield;
......
......@@ -256,6 +256,8 @@ typedef struct CopyStateData
/* Information on the connections to QEs. */
CdbCopy *cdbCopy;
bool delim_off; /* delimiter is set to OFF? */
/* end Greenplum Database specific variables */
} CopyStateData;
......
......@@ -124,3 +124,24 @@ CREATE EXTERNAL WEB TABLE ext_delim_off ( junk text) execute 'echo hi' on master
-- Query the ext_delim_off table
SELECT * FROM ext_delim_off;
-- start_ignore
DROP EXTERNAL TABLE IF EXISTS ext_delimiter_off_text;
-- end_ignore
-- Create external table(format text) with delimiter off, and a row with 'O'
CREATE EXTERNAL WEB TABLE ext_delimiter_off_text
(a text) EXECUTE E'echo O' ON MASTER FORMAT 'text' (delimiter 'OFF') ENCODING 'UTF8';
SELECT * FROM ext_delimiter_off_text;
-- start_ignore
DROP EXTERNAL TABLE IF EXISTS ext_delimiter_off_csv;
-- end_ignore
-- Create external table(format csv) with delimiter off, and a row with 'O'
CREATE EXTERNAL WEB TABLE ext_delimiter_off_csv
(a text) EXECUTE E'echo O' ON MASTER FORMAT 'csv' (delimiter 'OFF') ENCODING 'UTF8';
SELECT * FROM ext_delimiter_off_csv;
......@@ -204,3 +204,34 @@ SELECT * FROM ext_delim_off;
------
hi
(1 row)
GP_IGNORE:-- start_ignore
GP_IGNORE:DROP EXTERNAL TABLE IF EXISTS ext_delimiter_off_text;
GP_IGNORE:DROP
GP_IGNORE:-- end_ignore
-- Create external table(format text) with delimiter off, and a row with 'O'
CREATE EXTERNAL WEB TABLE ext_delimiter_off_text (a text) EXECUTE E'echo O' ON MASTER FORMAT 'text' (delimiter 'OFF') ENCODING 'UTF8';
CREATE
SELECT * FROM ext_delimiter_off_text;
a
---
O
(1 row)
GP_IGNORE:-- start_ignore
GP_IGNORE:DROP EXTERNAL TABLE IF EXISTS ext_delimiter_off_csv;
GP_IGNORE:DROP
GP_IGNORE:-- end_ignore
-- Create external table(format csv) with delimiter off, and a row with 'O'
CREATE EXTERNAL WEB TABLE ext_delimiter_off_csv (a text) EXECUTE E'echo O' ON MASTER FORMAT 'csv' (delimiter 'OFF') ENCODING 'UTF8';
CREATE
SELECT * FROM ext_delimiter_off_csv;
a
---
O
(1 row)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册