当默认值节点为FuncExpr时,若可以转换为Const,则取Const为默认值
This commit is contained in:
@ -118,6 +118,13 @@ static void AddDefaultExprNode(ParseState* pstate)
|
||||
int fieldCnt = rdAtt->natts;
|
||||
refState->constValues = (Const**)palloc0(sizeof(Const) * fieldCnt);
|
||||
|
||||
eval_const_expressions_context context;
|
||||
context.boundParams = nullptr;
|
||||
context.root = nullptr;
|
||||
context.active_fns = NIL;
|
||||
context.case_val = NULL;
|
||||
context.estimate = false;
|
||||
|
||||
for (int i = 0; i < fieldCnt; ++i) {
|
||||
Form_pg_attribute attTup = rdAtt->attrs[i];
|
||||
if (IsAutoIncrementColumn(rdAtt, i + 1)) {
|
||||
@ -126,9 +133,21 @@ static void AddDefaultExprNode(ParseState* pstate)
|
||||
} else if (ISGENERATEDCOL(rdAtt, i)) {
|
||||
refState->constValues[i] = nullptr;
|
||||
} else {
|
||||
Node* expr = build_column_default(relation, i + 1, true);
|
||||
if (expr && IsA(expr, Const)) {
|
||||
refState->constValues[i] = (Const*)expr;
|
||||
Node* node = build_column_default(relation, i + 1, true);
|
||||
if (node == nullptr) {
|
||||
refState->constValues[i] = nullptr;
|
||||
} else if (IsA(node, Const)) {
|
||||
refState->constValues[i] = (Const*)node;
|
||||
} else if (IsA(node, FuncExpr)) {
|
||||
FuncExpr* expr = (FuncExpr*)node;
|
||||
List* args = expr->args;
|
||||
Expr* simple = simplify_function(expr->funcid, expr->funcresulttype, exprTypmod((const Node*)expr),
|
||||
expr->funccollid, expr->inputcollid, &args, true, false, &context);
|
||||
if (simple && IsA(simple, Const)) {
|
||||
refState->constValues[i] = (Const*)simple;
|
||||
} else {
|
||||
refState->constValues[i] = nullptr;
|
||||
}
|
||||
} else {
|
||||
refState->constValues[i] = nullptr;
|
||||
}
|
||||
|
||||
@ -64,14 +64,6 @@ typedef struct {
|
||||
AggClauseCosts* costs;
|
||||
} count_agg_clauses_context;
|
||||
|
||||
typedef struct {
|
||||
ParamListInfo boundParams;
|
||||
PlannerInfo* root;
|
||||
List* active_fns;
|
||||
Node* case_val;
|
||||
bool estimate;
|
||||
} eval_const_expressions_context;
|
||||
|
||||
typedef struct {
|
||||
int nargs;
|
||||
List* args;
|
||||
@ -125,8 +117,6 @@ static List* simplify_or_arguments(
|
||||
static List* simplify_and_arguments(
|
||||
List* args, eval_const_expressions_context* context, bool* haveNull, bool* forceFalse);
|
||||
static Node* simplify_boolean_equality(Oid opno, List* args);
|
||||
static Expr* simplify_function(Oid funcid, Oid result_type, int32 result_typmod, Oid result_collid, Oid input_collid,
|
||||
List** args_p, bool process_args, bool allow_non_const, eval_const_expressions_context* context);
|
||||
static List* expand_function_arguments(List* args, Oid result_type, HeapTuple func_tuple);
|
||||
static List* reorder_function_arguments(List* args, HeapTuple func_tuple);
|
||||
static List* add_function_defaults(List* args, HeapTuple func_tuple);
|
||||
@ -3665,7 +3655,7 @@ static Node* simplify_boolean_equality(Oid opno, List* args)
|
||||
* will be done even if simplification of the function call itself is not
|
||||
* possible.
|
||||
*/
|
||||
static Expr* simplify_function(Oid funcid, Oid result_type, int32 result_typmod, Oid result_collid, Oid input_collid,
|
||||
Expr* simplify_function(Oid funcid, Oid result_type, int32 result_typmod, Oid result_collid, Oid input_collid,
|
||||
List** args_p, bool process_args, bool allow_non_const, eval_const_expressions_context* context)
|
||||
{
|
||||
List* args = *args_p;
|
||||
|
||||
@ -42,6 +42,14 @@ typedef struct {
|
||||
List* activeWindows;
|
||||
} WindowLists;
|
||||
|
||||
typedef struct {
|
||||
ParamListInfo boundParams;
|
||||
PlannerInfo* root;
|
||||
List* active_fns;
|
||||
Node* case_val;
|
||||
bool estimate;
|
||||
} eval_const_expressions_context;
|
||||
|
||||
typedef enum { UNIQUE_CONSTRAINT, NOT_NULL_CONSTRAINT } constraintType;
|
||||
|
||||
extern Expr* make_opclause(
|
||||
@ -145,5 +153,7 @@ static inline void ExcludeRownumExpr(ParseState* pstate, Node* expr)
|
||||
extern List* get_quals_lists(Node *jtnode);
|
||||
|
||||
extern bool isTableofType(Oid typeOid, Oid* base_oid, Oid* indexbyType);
|
||||
extern Expr* simplify_function(Oid funcid, Oid result_type, int32 result_typmod, Oid result_collid, Oid input_collid,
|
||||
List** args_p, bool process_args, bool allow_non_const, eval_const_expressions_context* context);
|
||||
|
||||
#endif /* CLAUSES_H */
|
||||
|
||||
@ -172,5 +172,163 @@ select * from with_var;
|
||||
|
||||
drop function with_var_func;
|
||||
drop table with_var;
|
||||
-- test num type
|
||||
create table num_default_t (
|
||||
n serial,
|
||||
c1 int default 1,
|
||||
c2 int,
|
||||
c3 tinyint default 3,
|
||||
c4 tinyint,
|
||||
c5 smallint default 5,
|
||||
c6 smallint,
|
||||
c7 integer default 7,
|
||||
c8 integer,
|
||||
c9 binary_integer default 9,
|
||||
c10 bigint default 10,
|
||||
c11 bigint,
|
||||
c12 boolean default true,
|
||||
c13 boolean,
|
||||
c14 numeric default 14.,
|
||||
c15 numeric(10, 3) default 15.,
|
||||
c16 decimal default 16,
|
||||
c17 decimal(10, 2) default 17,
|
||||
c18 double precision default 18,
|
||||
c19 float8,
|
||||
c20 float default 100 / 10,
|
||||
c21 float default 20 * (100 + 2) - 3,
|
||||
c22 float default random(),
|
||||
c23 float default random() * 100,
|
||||
c24 float
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "num_default_t_n_seq" for serial column "num_default_t.n"
|
||||
insert into num_default_t values(1);
|
||||
insert into num_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
|
||||
c21, c22, c23, c24);
|
||||
insert into num_default_t values(3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
|
||||
c21, c22, c23, c20);
|
||||
insert into num_default_t(n, c23, c24) values(4, default, c23);
|
||||
select 3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21
|
||||
from num_default_t;
|
||||
?column? | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | c13 | c14 | c15 | c16 | c17 | c18 | c19 | c20 | c21
|
||||
----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+--------+-----+-------+-----+-----+-----+------
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | 10 | 2037
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | | 2037
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | | 2037
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | 10 | 2037
|
||||
(4 rows)
|
||||
|
||||
select (c23 = c24) as equal from num_default_t where n = 4;
|
||||
equal
|
||||
-------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
select (c22 is null) as c22_is_null, (c23 is null) as c23_is_null from num_default_t where n = 2 or n = 3;
|
||||
c22_is_null | c23_is_null
|
||||
-------------+-------------
|
||||
t | t
|
||||
t | t
|
||||
(2 rows)
|
||||
|
||||
select (c22 is not null) as c22_is_not_null, (c23 is not null) as c23_is_not_null from num_default_t where n = 1;
|
||||
c22_is_not_null | c23_is_not_null
|
||||
-----------------+-----------------
|
||||
t | t
|
||||
(1 row)
|
||||
|
||||
-- test char type
|
||||
create table char_default_t(
|
||||
n serial,
|
||||
c1 char(10) default 'char20',
|
||||
c2 char(10),
|
||||
c3 varchar(10) default 'vc3',
|
||||
c4 varchar(20),
|
||||
c5 varchar2(10) default 'vc210',
|
||||
c6 varchar2(20),
|
||||
c7 nchar(5) default 'c31',
|
||||
c8 nchar(5),
|
||||
c9 nvarchar2(5) default 'c33',
|
||||
c10 nvarchar(5) default 'c34',
|
||||
c11 varchar(20) default concat('hello', ' world'),
|
||||
c12 varchar(20)
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "char_default_t_n_seq" for serial column "char_default_t.n"
|
||||
insert into char_default_t values(1);
|
||||
insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);
|
||||
insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);
|
||||
select * from char_default_t;
|
||||
n | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12
|
||||
---+------------+----+-----+---------+-------+----+-------+----+-----+-----+-------------+-------------
|
||||
1 | char20 | | vc3 | | vc210 | | c31 | | c33 | c34 | hello world |
|
||||
2 | char20 | | vc3 | | vc210 | | c31 | | c33 | c34 | |
|
||||
3 | char20 | | vc3 | vc3 vc4 | vc210 | | c31 | | c33 | c34 | hello world | hello world
|
||||
(3 rows)
|
||||
|
||||
-- test time type
|
||||
create table time_default_t(
|
||||
n serial,
|
||||
c1 timestamp default '2022-12-12 22:22:22',
|
||||
c2 timestamp,
|
||||
c3 date default '2022-12-12',
|
||||
c4 date,
|
||||
c5 time default '22:22:22',
|
||||
c6 date default current_date,
|
||||
c7 date,
|
||||
c8 timestamp default current_timestamp,
|
||||
c9 timestamp,
|
||||
c10 time default current_time,
|
||||
c11 time,
|
||||
c12 time with time zone default current_time,
|
||||
c13 time
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "time_default_t_n_seq" for serial column "time_default_t.n"
|
||||
insert into time_default_t values(1);
|
||||
insert into time_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13);
|
||||
insert into time_default_t values(3, default, c1, default, c3, default, default, c6,
|
||||
default, c8, default, c10, default, c12);
|
||||
select n, c1, c2, c3, c4, c5 from time_default_t;
|
||||
n | c1 | c2 | c3 | c4 | c5
|
||||
---+--------------------------+--------------------------+------------+------------+----------
|
||||
1 | Mon Dec 12 22:22:22 2022 | | 12-12-2022 | | 22:22:22
|
||||
2 | Mon Dec 12 22:22:22 2022 | | 12-12-2022 | | 22:22:22
|
||||
3 | Mon Dec 12 22:22:22 2022 | Mon Dec 12 22:22:22 2022 | 12-12-2022 | 12-12-2022 | 22:22:22
|
||||
(3 rows)
|
||||
|
||||
select (c6 is not null) as c6_is_not_null,
|
||||
(c8 is not null) as c8_is_not_null,
|
||||
(c10 is not null) as c10_is_not_null,
|
||||
(c12 is not null) as c12_is_not_null
|
||||
from time_default_t where n = 1 or n = 3;
|
||||
c6_is_not_null | c8_is_not_null | c10_is_not_null | c12_is_not_null
|
||||
----------------+----------------+-----------------+-----------------
|
||||
t | t | t | t
|
||||
t | t | t | t
|
||||
(2 rows)
|
||||
|
||||
select (c6 is not null) c6_is_not_null,
|
||||
(c8 is null) as c8_is_null,
|
||||
(c10 is null) as c10_is_null,
|
||||
(c12 is null) as c12_is_null
|
||||
from time_default_t where n = 2;
|
||||
c6_is_not_null | c8_is_null | c10_is_null | c12_is_null
|
||||
----------------+------------+-------------+-------------
|
||||
t | t | t | t
|
||||
(1 row)
|
||||
|
||||
select (c1=c2) as c1c2,
|
||||
(c3=c4) as c3c4,
|
||||
(c6=c7) as c6c7,
|
||||
(c8=c9) as c8c9,
|
||||
(c10=c11) as c10c11,
|
||||
(c12=c13) as c12c13
|
||||
from time_default_t where n = 3;
|
||||
c1c2 | c3c4 | c6c7 | c8c9 | c10c11 | c12c13
|
||||
------+------+------+------+--------+--------
|
||||
t | t | t | t | t | t
|
||||
(1 row)
|
||||
|
||||
\c postgres
|
||||
drop database rightref;
|
||||
|
||||
@ -82,6 +82,121 @@ select * from with_var;
|
||||
drop function with_var_func;
|
||||
drop table with_var;
|
||||
|
||||
-- test num type
|
||||
create table num_default_t (
|
||||
n serial,
|
||||
c1 int default 1,
|
||||
c2 int,
|
||||
c3 tinyint default 3,
|
||||
c4 tinyint,
|
||||
c5 smallint default 5,
|
||||
c6 smallint,
|
||||
c7 integer default 7,
|
||||
c8 integer,
|
||||
c9 binary_integer default 9,
|
||||
c10 bigint default 10,
|
||||
c11 bigint,
|
||||
c12 boolean default true,
|
||||
c13 boolean,
|
||||
c14 numeric default 14.,
|
||||
c15 numeric(10, 3) default 15.,
|
||||
c16 decimal default 16,
|
||||
c17 decimal(10, 2) default 17,
|
||||
c18 double precision default 18,
|
||||
c19 float8,
|
||||
c20 float default 100 / 10,
|
||||
c21 float default 20 * (100 + 2) - 3,
|
||||
c22 float default random(),
|
||||
c23 float default random() * 100,
|
||||
c24 float
|
||||
);
|
||||
|
||||
insert into num_default_t values(1);
|
||||
insert into num_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
|
||||
c21, c22, c23, c24);
|
||||
insert into num_default_t values(3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
|
||||
c21, c22, c23, c20);
|
||||
insert into num_default_t(n, c23, c24) values(4, default, c23);
|
||||
|
||||
select 3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21
|
||||
from num_default_t;
|
||||
|
||||
select (c23 = c24) as equal from num_default_t where n = 4;
|
||||
select (c22 is null) as c22_is_null, (c23 is null) as c23_is_null from num_default_t where n = 2 or n = 3;
|
||||
select (c22 is not null) as c22_is_not_null, (c23 is not null) as c23_is_not_null from num_default_t where n = 1;
|
||||
|
||||
|
||||
-- test char type
|
||||
create table char_default_t(
|
||||
n serial,
|
||||
c1 char(10) default 'char20',
|
||||
c2 char(10),
|
||||
c3 varchar(10) default 'vc3',
|
||||
c4 varchar(20),
|
||||
c5 varchar2(10) default 'vc210',
|
||||
c6 varchar2(20),
|
||||
c7 nchar(5) default 'c31',
|
||||
c8 nchar(5),
|
||||
c9 nvarchar2(5) default 'c33',
|
||||
c10 nvarchar(5) default 'c34',
|
||||
c11 varchar(20) default concat('hello', ' world'),
|
||||
c12 varchar(20)
|
||||
);
|
||||
|
||||
insert into char_default_t values(1);
|
||||
insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);
|
||||
insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);
|
||||
|
||||
select * from char_default_t;
|
||||
|
||||
-- test time type
|
||||
create table time_default_t(
|
||||
n serial,
|
||||
c1 timestamp default '2022-12-12 22:22:22',
|
||||
c2 timestamp,
|
||||
c3 date default '2022-12-12',
|
||||
c4 date,
|
||||
c5 time default '22:22:22',
|
||||
c6 date default current_date,
|
||||
c7 date,
|
||||
c8 timestamp default current_timestamp,
|
||||
c9 timestamp,
|
||||
c10 time default current_time,
|
||||
c11 time,
|
||||
c12 time with time zone default current_time,
|
||||
c13 time
|
||||
);
|
||||
|
||||
insert into time_default_t values(1);
|
||||
insert into time_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13);
|
||||
insert into time_default_t values(3, default, c1, default, c3, default, default, c6,
|
||||
default, c8, default, c10, default, c12);
|
||||
|
||||
select n, c1, c2, c3, c4, c5 from time_default_t;
|
||||
|
||||
select (c6 is not null) as c6_is_not_null,
|
||||
(c8 is not null) as c8_is_not_null,
|
||||
(c10 is not null) as c10_is_not_null,
|
||||
(c12 is not null) as c12_is_not_null
|
||||
from time_default_t where n = 1 or n = 3;
|
||||
|
||||
select (c6 is not null) c6_is_not_null,
|
||||
(c8 is null) as c8_is_null,
|
||||
(c10 is null) as c10_is_null,
|
||||
(c12 is null) as c12_is_null
|
||||
from time_default_t where n = 2;
|
||||
|
||||
select (c1=c2) as c1c2,
|
||||
(c3=c4) as c3c4,
|
||||
(c6=c7) as c6c7,
|
||||
(c8=c9) as c8c9,
|
||||
(c10=c11) as c10c11,
|
||||
(c12=c13) as c12c13
|
||||
from time_default_t where n = 3;
|
||||
|
||||
\c postgres
|
||||
|
||||
drop database rightref;
|
||||
|
||||
Reference in New Issue
Block a user