1. support '' as default value of set type

2. '' as set type value: compatible with MySQL
This commit is contained in:
chenjianwen
2022-11-21 15:09:53 +08:00
parent 51da41f78c
commit 33282790e7
4 changed files with 88 additions and 15 deletions

View File

@ -1134,7 +1134,7 @@ static void _outCommonRemoteQueryPart(StringInfo str, T* node)
appendStringInfo(str, " :rq_param_types");
}
for (i = 0; i < node->rq_num_params; i++) {
appendStringInfo(str, " %d", node->rq_param_types[i]);
appendStringInfo(str, " %d", node->rq_param_types[i]);
}
WRITE_BOOL_FIELD(rq_params_internal);
@ -2139,18 +2139,25 @@ static void _outConst(StringInfo str, Const* node)
} else {
Oid typoutput;
bool typIsVarlena = false;
/*
* For user-define type
*
* decode datum to string with Output functions identified by
* datatype since data type oid may be inconsistent on different
* nodes. the string will be translated to datum with inputfunction
* when we read the node string
/* For user-define set type: if the default value is ''(means empty
* set, not null), It should not be output as :udftypevalue <>.
* It will be taken as null value.
*/
appendStringInfo(str, " :udftypevalue ");
getTypeOutputInfo(node->consttype, &typoutput, &typIsVarlena);
_outToken(str, OidOutputFunctionCall(typoutput, node->constvalue));
if (type_is_set(node->consttype)) {
_outDatum(str, node->constvalue, node->constlen, node->constbyval);
} else {
/*
* For user-define type
*
* decode datum to string with Output functions identified by
* datatype since data type oid may be inconsistent on different
* nodes. the string will be translated to datum with inputfunction
* when we read the node string
*/
appendStringInfo(str, " :udftypevalue ");
getTypeOutputInfo(node->consttype, &typoutput, &typIsVarlena);
_outToken(str, OidOutputFunctionCall(typoutput, node->constvalue));
}
}
WRITE_CFGINFO_FIELD(consttype, constvalue);

View File

@ -1118,7 +1118,7 @@ static void preprocess_set_value(char *value, Oid settypoid, VarBit **result)
bool hasEmpty = false;
if (*value == '\0') {
hasEmpty = true;
return;
} else {
int len = strlen(value);
if (*value == ',' || *(value + len - 1) == ',') {
@ -1140,7 +1140,7 @@ static VarBit* get_set_in_result(Oid settypoid, char *setlabels)
VarBit *result = NULL;
char* next_token = NULL;
char* labels = pstrdup(setlabels);
preprocess_set_value(setlabels, settypoid, &result);
char* token = strtok_s(labels, SETLABELDELIMIT, &next_token);

View File

@ -4105,3 +4105,48 @@ select pg_catalog.pg_get_tabledef('t2');
WITH (orientation=row, compression=no);
(1 row)
-- test '' as set member
-- 1. define set type not include ''
drop table if exists t1;
create table t1 (c1 set('a', 'b') not null default '');
NOTICE: CREATE TABLE will create implicit set "t1_c1_set" for column "t1.c1"
insert into t1 values ('');
insert into t1 values (default);
select c1, c1+0 from t1; -- expect value 0
c1 | ?column?
----+----------
| 0
| 0
(2 rows)
insert into t1 values ('a,,b'); -- expect error
ERROR: invalid input value for set t1_c1_set: ''
LINE 1: insert into t1 values ('a,,b');
^
CONTEXT: referenced column: c1
-- 2. define set type include ''
drop table if exists t2;
create table t2 (c1 set('a', '', 'b') default '');
NOTICE: CREATE TABLE will create implicit set "t2_c1_set" for column "t2.c1"
insert into t2 values (''); -- expect value 0, not 2
insert into t2 values (default);
select c1, c1+0 from t2;
c1 | ?column?
----+----------
| 0
| 0
(2 rows)
insert into t2 values ('a,,b'); -- expect 2, not 0
insert into t2 values (',a,b'); -- expect 2, not 0
select c1, c1+0 from t2 order by 2;
c1 | ?column?
------+----------
| 0
| 0
a,,b | 7
a,,b | 7
(4 rows)
drop table t1;
drop table t2;

View File

@ -711,4 +711,25 @@ create table t2 (
c2 set('1', '', '3'),
c3 set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64')
);
select pg_catalog.pg_get_tabledef('t2');
select pg_catalog.pg_get_tabledef('t2');
-- test '' as set member
-- 1. define set type not include ''
drop table if exists t1;
create table t1 (c1 set('a', 'b') not null default '');
insert into t1 values ('');
insert into t1 values (default);
select c1, c1+0 from t1; -- expect value 0
insert into t1 values ('a,,b'); -- expect error
-- 2. define set type include ''
drop table if exists t2;
create table t2 (c1 set('a', '', 'b') default '');
insert into t2 values (''); -- expect value 0, not 2
insert into t2 values (default);
select c1, c1+0 from t2;
insert into t2 values ('a,,b'); -- expect 2, not 0
insert into t2 values (',a,b'); -- expect 2, not 0
select c1, c1+0 from t2 order by 2;
drop table t1;
drop table t2;