!4906 修复ignore在sublink场景下失效的问题
Merge pull request !4906 from pengjiong/fix_col
This commit is contained in:
@ -2022,7 +2022,6 @@ static Query* transformInsertStmt(ParseState* pstate, InsertStmt* stmt)
|
|||||||
sub_pstate->p_resolve_unknowns = false;
|
sub_pstate->p_resolve_unknowns = false;
|
||||||
|
|
||||||
selectQuery = transformStmt(sub_pstate, stmt->selectStmt);
|
selectQuery = transformStmt(sub_pstate, stmt->selectStmt);
|
||||||
selectQuery->hasIgnore = stmt->hasIgnore;
|
|
||||||
Assert(selectQuery != NULL);
|
Assert(selectQuery != NULL);
|
||||||
|
|
||||||
free_parsestate(sub_pstate);
|
free_parsestate(sub_pstate);
|
||||||
@ -2386,6 +2385,7 @@ static Query* transformInsertStmt(ParseState* pstate, InsertStmt* stmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
assign_query_collations(pstate, qry);
|
assign_query_collations(pstate, qry);
|
||||||
|
assign_query_ignore_flag(pstate, qry);
|
||||||
|
|
||||||
CheckUnsupportInsertSelectClause(qry);
|
CheckUnsupportInsertSelectClause(qry);
|
||||||
|
|
||||||
@ -4277,6 +4277,7 @@ static Query* transformUpdateStmt(ParseState* pstate, UpdateStmt* stmt)
|
|||||||
UpdateParseCheck(pstate, (Node *)qry);
|
UpdateParseCheck(pstate, (Node *)qry);
|
||||||
|
|
||||||
assign_query_collations(pstate, qry);
|
assign_query_collations(pstate, qry);
|
||||||
|
assign_query_ignore_flag(pstate, qry);
|
||||||
qry->hintState = stmt->hintState;
|
qry->hintState = stmt->hintState;
|
||||||
qry->hasIgnore = stmt->hasIgnore;
|
qry->hasIgnore = stmt->hasIgnore;
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ static void unsupport_syntax_plus_outerjoin(const OperatorPlusProcessContext* ct
|
|||||||
static bool contain_JoinExpr(List* l);
|
static bool contain_JoinExpr(List* l);
|
||||||
static bool contain_AEXPR_AND_OR(Node* clause);
|
static bool contain_AEXPR_AND_OR(Node* clause);
|
||||||
static bool contain_AEXPR_AND_OR_walker(Node* node, void* context);
|
static bool contain_AEXPR_AND_OR_walker(Node* node, void* context);
|
||||||
|
static bool assign_query_ignore_flag_walker(Node* node, void *context);
|
||||||
|
|
||||||
bool getOperatorPlusFlag()
|
bool getOperatorPlusFlag()
|
||||||
{
|
{
|
||||||
@ -1007,3 +1008,45 @@ void transformOperatorPlus(ParseState* pstate, Node** whereClause)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* assign_query_ignore_flag
|
||||||
|
* Mark all query in the given Query with ignore information.
|
||||||
|
*
|
||||||
|
* Now only INSERT and UPDATE support ignore, so it only be called in
|
||||||
|
* InsertStmt and UpdateStmt.
|
||||||
|
*/
|
||||||
|
void assign_query_ignore_flag(ParseState* pstate, Query* query)
|
||||||
|
{
|
||||||
|
/* we only set ignore to true, cause false is default value. So if there is no ignore, we can return */
|
||||||
|
if (!pstate->p_has_ignore) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)query_tree_walker(query, (bool (*)())assign_query_ignore_flag_walker, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Walker for assign_query_ignore_flag
|
||||||
|
*
|
||||||
|
* Each expression found by query_tree_walker is processed independently.
|
||||||
|
* Note that query_tree_walker may pass us a whole List, such as the
|
||||||
|
* targetlist, in which case each subexpression must be processed
|
||||||
|
* independently.
|
||||||
|
*/
|
||||||
|
static bool assign_query_ignore_flag_walker(Node* node, void *context)
|
||||||
|
{
|
||||||
|
/* Need do nothing for empty subexpressions */
|
||||||
|
if (node == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsA(node, Query)) {
|
||||||
|
Query *query = (Query *) node;
|
||||||
|
|
||||||
|
/* set it to true and continue to traverse the query tree */
|
||||||
|
query->hasIgnore = true;
|
||||||
|
return query_tree_walker(query, (bool (*)())assign_query_ignore_flag_walker, NULL, 0);
|
||||||
|
}
|
||||||
|
return expression_tree_walker(node, (bool (*)())assign_query_ignore_flag_walker, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ extern void resetOperatorPlusFlag();
|
|||||||
extern void fixResTargetNameWithTableNameRef(Relation rd, RangeVar* rel, ResTarget* res);
|
extern void fixResTargetNameWithTableNameRef(Relation rd, RangeVar* rel, ResTarget* res);
|
||||||
extern void fixResTargetListWithTableNameRef(Relation rd, RangeVar* rel, List* clause_list);
|
extern void fixResTargetListWithTableNameRef(Relation rd, RangeVar* rel, List* clause_list);
|
||||||
extern void UpdateParseCheck(ParseState *pstate, Node *qry);
|
extern void UpdateParseCheck(ParseState *pstate, Node *qry);
|
||||||
|
extern void assign_query_ignore_flag(ParseState* pstate, Query* query);
|
||||||
#endif /* !FRONTEND_PARSER */
|
#endif /* !FRONTEND_PARSER */
|
||||||
|
|
||||||
extern bool getOperatorPlusFlag();
|
extern bool getOperatorPlusFlag();
|
||||||
|
@ -1188,7 +1188,7 @@ select * from varbit;
|
|||||||
|
|
||||||
reset sql_ignore_strategy;
|
reset sql_ignore_strategy;
|
||||||
drop table net, ran, hashvec, varbit;
|
drop table net, ran, hashvec, varbit;
|
||||||
-- insert + subquery
|
-- insert/update + subquery
|
||||||
create table t1(a int);
|
create table t1(a int);
|
||||||
insert /*+ ignore_error */ into t1 select 'abc'::time;
|
insert /*+ ignore_error */ into t1 select 'abc'::time;
|
||||||
WARNING: invalid input syntax for type time: "abc"
|
WARNING: invalid input syntax for type time: "abc"
|
||||||
@ -1197,6 +1197,21 @@ LINE 1: insert /*+ ignore_error */ into t1 select 'abc'::time;
|
|||||||
CONTEXT: referenced column: time
|
CONTEXT: referenced column: time
|
||||||
WARNING: column "a" is of type integer but expression is of type time without time zone. Data truncated automatically.
|
WARNING: column "a" is of type integer but expression is of type time without time zone. Data truncated automatically.
|
||||||
CONTEXT: referenced column: a
|
CONTEXT: referenced column: a
|
||||||
|
insert /*+ ignore_error */ into t1 select (select 'abc'::time);
|
||||||
|
WARNING: invalid input syntax for type time: "abc"
|
||||||
|
LINE 1: insert /*+ ignore_error */ into t1 select (select 'abc'::tim...
|
||||||
|
^
|
||||||
|
CONTEXT: referenced column: time
|
||||||
|
WARNING: column "a" is of type integer but expression is of type time without time zone. Data truncated automatically.
|
||||||
|
CONTEXT: referenced column: a
|
||||||
|
update /*+ ignore_error */ t1 set a =(select (select 'abc'::time));
|
||||||
|
WARNING: invalid input syntax for type time: "abc"
|
||||||
|
LINE 1: ...ate /*+ ignore_error */ t1 set a =(select (select 'abc'::tim...
|
||||||
|
^
|
||||||
|
CONTEXT: referenced column: time
|
||||||
|
referenced column: a
|
||||||
|
WARNING: column "a" is of type integer but expression is of type time without time zone. Data truncated automatically.
|
||||||
|
CONTEXT: referenced column: a
|
||||||
drop table t1;
|
drop table t1;
|
||||||
-- restore context
|
-- restore context
|
||||||
reset timezone;
|
reset timezone;
|
||||||
|
@ -317,9 +317,11 @@ reset sql_ignore_strategy;
|
|||||||
|
|
||||||
drop table net, ran, hashvec, varbit;
|
drop table net, ran, hashvec, varbit;
|
||||||
|
|
||||||
-- insert + subquery
|
-- insert/update + subquery
|
||||||
create table t1(a int);
|
create table t1(a int);
|
||||||
insert /*+ ignore_error */ into t1 select 'abc'::time;
|
insert /*+ ignore_error */ into t1 select 'abc'::time;
|
||||||
|
insert /*+ ignore_error */ into t1 select (select 'abc'::time);
|
||||||
|
update /*+ ignore_error */ t1 set a =(select (select 'abc'::time));
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
-- restore context
|
-- restore context
|
||||||
|
Reference in New Issue
Block a user