Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaf0161e

Browse files
committed
Give a suitable HINT when an INSERT's data source is a RowExpr containing
the same number of columns expected by the insert. This suggests that therewere extra parentheses that converted the intended column list into a rowexpression.Original patch by Marko Tiikkaja, rather heavily editorialized by me.
1 parent48f0a28 commitaf0161e

File tree

1 file changed

+60
-1
lines changed

1 file changed

+60
-1
lines changed

‎src/backend/parser/analyze.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
1818
* Portions Copyright (c) 1994, Regents of the University of California
1919
*
20-
*$PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.403 2010/08/27 20:30:08 petere Exp $
20+
*$PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.404 2010/09/18 18:37:01 tgl Exp $
2121
*
2222
*-------------------------------------------------------------------------
2323
*/
@@ -47,6 +47,7 @@ static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
4747
staticQuery*transformInsertStmt(ParseState*pstate,InsertStmt*stmt);
4848
staticList*transformInsertRow(ParseState*pstate,List*exprlist,
4949
List*stmtcols,List*icolumns,List*attrnos);
50+
staticintcount_rowexpr_columns(ParseState*pstate,Node*expr);
5051
staticQuery*transformSelectStmt(ParseState*pstate,SelectStmt*stmt);
5152
staticQuery*transformValuesClause(ParseState*pstate,SelectStmt*stmt);
5253
staticQuery*transformSetOperationStmt(ParseState*pstate,SelectStmt*stmt);
@@ -726,12 +727,27 @@ transformInsertRow(ParseState *pstate, List *exprlist,
726727
list_length(icolumns))))));
727728
if (stmtcols!=NIL&&
728729
list_length(exprlist)<list_length(icolumns))
730+
{
731+
/*
732+
* We can get here for cases like INSERT ... SELECT (a,b,c) FROM ...
733+
* where the user accidentally created a RowExpr instead of separate
734+
* columns. Add a suitable hint if that seems to be the problem,
735+
* because the main error message is quite misleading for this case.
736+
* (If there's no stmtcols, you'll get something about data type
737+
* mismatch, which is less misleading so we don't worry about giving
738+
* a hint in that case.)
739+
*/
729740
ereport(ERROR,
730741
(errcode(ERRCODE_SYNTAX_ERROR),
731742
errmsg("INSERT has more target columns than expressions"),
743+
((list_length(exprlist)==1&&
744+
count_rowexpr_columns(pstate,linitial(exprlist))==
745+
list_length(icolumns)) ?
746+
errhint("The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?") :0),
732747
parser_errposition(pstate,
733748
exprLocation(list_nth(icolumns,
734749
list_length(exprlist))))));
750+
}
735751

736752
/*
737753
* Prepare columns for assignment to target table.
@@ -762,6 +778,49 @@ transformInsertRow(ParseState *pstate, List *exprlist,
762778
returnresult;
763779
}
764780

781+
/*
782+
* count_rowexpr_columns -
783+
* get number of columns contained in a ROW() expression;
784+
* return -1 if expression isn't a RowExpr or a Var referencing one.
785+
*
786+
* This is currently used only for hint purposes, so we aren't terribly
787+
* tense about recognizing all possible cases. The Var case is interesting
788+
* because that's what we'll get in the INSERT ... SELECT (...) case.
789+
*/
790+
staticint
791+
count_rowexpr_columns(ParseState*pstate,Node*expr)
792+
{
793+
if (expr==NULL)
794+
return-1;
795+
if (IsA(expr,RowExpr))
796+
returnlist_length(((RowExpr*)expr)->args);
797+
if (IsA(expr,Var))
798+
{
799+
Var*var= (Var*)expr;
800+
AttrNumberattnum=var->varattno;
801+
802+
if (attnum>0&&var->vartype==RECORDOID)
803+
{
804+
RangeTblEntry*rte;
805+
806+
rte=GetRTEByRangeTablePosn(pstate,var->varno,var->varlevelsup);
807+
if (rte->rtekind==RTE_SUBQUERY)
808+
{
809+
/* Subselect-in-FROM: examine sub-select's output expr */
810+
TargetEntry*ste=get_tle_by_resno(rte->subquery->targetList,
811+
attnum);
812+
813+
if (ste==NULL||ste->resjunk)
814+
return-1;
815+
expr= (Node*)ste->expr;
816+
if (IsA(expr,RowExpr))
817+
returnlist_length(((RowExpr*)expr)->args);
818+
}
819+
}
820+
}
821+
return-1;
822+
}
823+
765824

766825
/*
767826
* transformSelectStmt -

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp