Index: src/backend/executor/execMain.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/executor/execMain.c,v retrieving revision 1.144 diff -c -r1.144 execMain.c *** src/backend/executor/execMain.c 2001/06/22 19:16:22 1.144 --- src/backend/executor/execMain.c 2001/07/31 14:43:35 *************** *** 44,49 **** --- 44,50 ---- #include "parser/parsetree.h" #include "utils/acl.h" + extern unsigned TupleCount; /* decls for local routines only used within this module */ static TupleDesc InitPlan(CmdType operation, *************** *** 1145,1150 **** --- 1146,1152 ---- break; } + TupleCount++; /* * check our tuple count.. if we've processed the proper number * then quit, else loop again and process more tuples.. Index: src/backend/nodes/copyfuncs.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v retrieving revision 1.148 diff -c -r1.148 copyfuncs.c *** src/backend/nodes/copyfuncs.c 2001/07/16 19:07:37 1.148 --- src/backend/nodes/copyfuncs.c 2001/07/31 14:43:36 *************** *** 1798,1803 **** --- 1798,1804 ---- newnode->relname = pstrdup(from->relname); Node_Copy(from, newnode, cols); Node_Copy(from, newnode, targetList); + Node_Copy(from, newnode, tupleList); Node_Copy(from, newnode, selectStmt); return newnode; Index: src/backend/parser/analyze.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/parser/analyze.c,v retrieving revision 1.193 diff -c -r1.193 analyze.c *** src/backend/parser/analyze.c 2001/07/16 05:06:58 1.193 --- src/backend/parser/analyze.c 2001/07/31 14:43:36 *************** *** 426,432 **** --- 426,471 ---- } else { + /* + * If the tupleList is not null, then take the first entry of the list + * and assign it to the targetList. For each additional item on the + * tupleList, create a new node (by copying), remove item from the + * tupleList and assign the item to the targetList. Append this new + * node to the extras_after List. + */ + if (stmt->tupleList != NIL) + { + List *rte; + InsertStmt *newnode; + stmt->targetList = (List *) lfirst(stmt->tupleList); + stmt->tupleList = lnext(stmt->tupleList); + + while (stmt->tupleList != NIL) + { + rte = (List *) lfirst(stmt->tupleList); + newnode = makeNode(InsertStmt); + + /* + * Don't use standard object copy function because + * we don't want certain fields duplicated. + */ + if (stmt->relname) + newnode->relname = pstrdup(stmt->relname); + newnode->cols = copyObject(stmt->cols); + newnode->targetList = rte; + + if (extras_after == NIL) + extras_after = makeList1(newnode); + else + lappend(extras_after, newnode); + + stmt->tupleList = lnext(stmt->tupleList); + } + } + + Assert(stmt->tupleList == NIL); + /* * For INSERT ... VALUES, transform the given list of values to * form a targetlist for the INSERT. Index: src/backend/parser/gram.y =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/parser/gram.y,v retrieving revision 2.238 diff -c -r2.238 gram.y *** src/backend/parser/gram.y 2001/07/16 19:07:40 2.238 --- src/backend/parser/gram.y 2001/07/31 14:43:38 *************** *** 194,200 **** from_clause, from_list, opt_array_bounds, expr_list, attrs, target_list, update_target_list, def_list, opt_indirection, group_clause, TriggerFuncArgs, ! select_limit, opt_select_limit %type func_arg, func_return, func_type, aggr_argtype --- 194,200 ---- from_clause, from_list, opt_array_bounds, expr_list, attrs, target_list, update_target_list, def_list, opt_indirection, group_clause, TriggerFuncArgs, ! select_limit, opt_select_limit, tuple_list %type func_arg, func_return, func_type, aggr_argtype *************** *** 3206,3247 **** } ; ! insert_rest: VALUES '(' target_list ')' { $$ = makeNode(InsertStmt); $$->cols = NIL; ! $$->targetList = $3; $$->selectStmt = NULL; } | DEFAULT VALUES { $$ = makeNode(InsertStmt); $$->cols = NIL; ! $$->targetList = NIL; $$->selectStmt = NULL; } | SelectStmt { $$ = makeNode(InsertStmt); $$->cols = NIL; ! $$->targetList = NIL; $$->selectStmt = $1; } ! | '(' columnList ')' VALUES '(' target_list ')' { $$ = makeNode(InsertStmt); $$->cols = $2; ! $$->targetList = $6; $$->selectStmt = NULL; } | '(' columnList ')' SelectStmt { $$ = makeNode(InsertStmt); $$->cols = $2; ! $$->targetList = NIL; $$->selectStmt = $4; } ; opt_column_list: '(' columnList ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } --- 3206,3253 ---- } ; ! insert_rest: VALUES tuple_list { $$ = makeNode(InsertStmt); $$->cols = NIL; ! $$->tupleList = $2; $$->selectStmt = NULL; } | DEFAULT VALUES { $$ = makeNode(InsertStmt); $$->cols = NIL; ! $$->tupleList = NIL; $$->selectStmt = NULL; } | SelectStmt { $$ = makeNode(InsertStmt); $$->cols = NIL; ! $$->tupleList = NIL; $$->selectStmt = $1; } ! | '(' columnList ')' VALUES tuple_list { $$ = makeNode(InsertStmt); $$->cols = $2; ! $$->tupleList = $5; $$->selectStmt = NULL; } | '(' columnList ')' SelectStmt { $$ = makeNode(InsertStmt); $$->cols = $2; ! $$->tupleList = NIL; $$->selectStmt = $4; } ; + + tuple_list: tuple_list ',' '(' target_list ')' + { $$ = lappend($1, $4); } + | '(' target_list ')' + { $$ = makeList1($2); } + ; opt_column_list: '(' columnList ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } Index: src/backend/tcop/dest.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/tcop/dest.c,v retrieving revision 1.44 diff -c -r1.44 dest.c *** src/backend/tcop/dest.c 2001/03/22 06:16:17 1.44 --- src/backend/tcop/dest.c 2001/07/31 14:43:38 *************** *** 42,47 **** --- 42,48 ---- static char CommandInfo[32] = {0}; + unsigned TupleCount; /* ---------------- * dummy DestReceiver functions *************** *** 326,332 **** case CMD_INSERT: if (tuples > 1) lastoid = InvalidOid; ! sprintf(CommandInfo, " %u %u", lastoid, tuples); break; case CMD_DELETE: case CMD_UPDATE: --- 327,338 ---- case CMD_INSERT: if (tuples > 1) lastoid = InvalidOid; ! ! if (TupleCount == 1) { ! sprintf(CommandInfo, " %u %u", lastoid, tuples); ! } else { ! sprintf(CommandInfo, " %u %u", InvalidOid, TupleCount); ! } break; case CMD_DELETE: case CMD_UPDATE: Index: src/backend/tcop/postgres.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/tcop/postgres.c,v retrieving revision 1.228 diff -c -r1.228 postgres.c *** src/backend/tcop/postgres.c 2001/07/30 14:50:24 1.228 --- src/backend/tcop/postgres.c 2001/07/31 14:43:38 *************** *** 78,83 **** --- 78,85 ---- char *debug_query_string; /* used by pgmonitor */ + extern unsigned TupleCount; /* used by insert statements proper tuple counting */ + /* * for ps display */ *************** *** 743,748 **** --- 745,752 ---- * Switch back to execution context for planning and execution. */ MemoryContextSwitchTo(oldcontext); + + TupleCount = 0; /* * Inner loop handles the individual queries generated from a Index: src/include/nodes/parsenodes.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/nodes/parsenodes.h,v retrieving revision 1.136 diff -c -r1.136 parsenodes.h *** src/include/nodes/parsenodes.h 2001/07/16 19:07:40 1.136 --- src/include/nodes/parsenodes.h 2001/07/31 14:43:40 *************** *** 806,815 **** /* * An INSERT statement has *either* VALUES or SELECT, never both. If ! * VALUES, a targetList is supplied (empty for DEFAULT VALUES). If * SELECT, a complete SelectStmt (or set-operation tree) is supplied. */ ! List *targetList; /* the target list (of ResTarget) */ Node *selectStmt; /* the source SELECT */ } InsertStmt; --- 806,816 ---- /* * An INSERT statement has *either* VALUES or SELECT, never both. If ! * VALUES, a tupleList is supplied (empty for DEFAULT VALUES). If * SELECT, a complete SelectStmt (or set-operation tree) is supplied. */ ! List *tupleList; /* the list of tuples to insert (list of lists of ResTargets) */ ! List *targetList; /* targetList */ Node *selectStmt; /* the source SELECT */ } InsertStmt;