Index: doc/src/sgml/ref/insert.sgml =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/insert.sgml,v retrieving revision 1.15 diff -c -r1.15 insert.sgml *** doc/src/sgml/ref/insert.sgml 2001/09/03 12:57:50 1.15 --- doc/src/sgml/ref/insert.sgml 2001/09/07 14:22:38 *************** *** 22,28 **** INSERT INTO table [ ( column [, ...] ) ] ! { DEFAULT VALUES | VALUES ( expression [, ...] ) | SELECT query } --- 22,30 ---- INSERT INTO table [ ( column [, ...] ) ] ! { DEFAULT VALUES | ! VALUES ( expression [, ...] ), [ ( expression [, ...] ), ... ] | ! SELECT query } *************** *** 126,135 **** ! INSERT allows one to insert new rows into a ! table. One can insert ! a single row at a time or several rows as a result of a query. ! The columns in the target list may be listed in any order. --- 128,137 ---- ! INSERT allows one to insert new rows into a table. One can ! insert either a single row or several rows. The rows to be inserted may be ! the result of a query. The columns in the target list may be listed in any ! order. *************** *** 182,187 **** --- 184,197 ---- INSERT INTO distributors (name) VALUES ('British Lion'); + + + + + Same as above except insert multiple rows into the table: + + + INSERT INTO distributors (name) VALUES ('Paramount'), ('MGM'), ('Alliance'); Index: src/backend/nodes/copyfuncs.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v retrieving revision 1.155 diff -c -r1.155 copyfuncs.c *** src/backend/nodes/copyfuncs.c 2001/08/26 16:55:59 1.155 --- src/backend/nodes/copyfuncs.c 2001/09/07 14:22:38 *************** *** 1795,1801 **** if (from->relname) newnode->relname = pstrdup(from->relname); Node_Copy(from, newnode, cols); - Node_Copy(from, newnode, targetList); Node_Copy(from, newnode, selectStmt); return newnode; --- 1795,1800 ---- Index: src/backend/nodes/equalfuncs.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v retrieving revision 1.103 diff -c -r1.103 equalfuncs.c *** src/backend/nodes/equalfuncs.c 2001/08/26 16:55:59 1.103 --- src/backend/nodes/equalfuncs.c 2001/09/07 14:22:38 *************** *** 636,643 **** return false; if (!equal(a->cols, b->cols)) return false; - if (!equal(a->targetList, b->targetList)) - return false; if (!equal(a->selectStmt, b->selectStmt)) return false; --- 636,641 ---- Index: src/backend/parser/analyze.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/parser/analyze.c,v retrieving revision 1.197 diff -c -r1.197 analyze.c *** src/backend/parser/analyze.c 2001/08/24 20:03:45 1.197 --- src/backend/parser/analyze.c 2001/09/07 14:22:38 *************** *** 347,352 **** --- 347,353 ---- */ qry->resultRelation = setTargetTable(pstate, stmt->relname, false, false); + qry->targetList = NIL; /* * Is it INSERT ... SELECT or INSERT ... VALUES? *************** *** 406,412 **** * constants. Otherwise this fails: INSERT INTO foo SELECT 'bar', * ... FROM baz */ - qry->targetList = NIL; foreach(tl, selectQuery->targetList) { TargetEntry *tle = (TargetEntry *) lfirst(tl); --- 407,412 ---- *************** *** 428,442 **** qry->targetList = lappend(qry->targetList, makeTargetEntry(resnode, expr)); } - } - else - { - - /* - * For INSERT ... VALUES, transform the given list of values to - * form a targetlist for the INSERT. - */ - qry->targetList = transformTargetList(pstate, stmt->targetList); } /* --- 428,433 ---- Index: src/backend/parser/gram.y =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/parser/gram.y,v retrieving revision 2.250 diff -c -r2.250 gram.y *** src/backend/parser/gram.y 2001/09/06 04:57:28 2.250 --- src/backend/parser/gram.y 2001/09/07 14:22:39 *************** *** 141,151 **** RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty, RuleStmt, SelectStmt, TransactionStmt, TruncateStmt, UnlistenStmt, UpdateStmt, VacuumStmt, VariableResetStmt, ! VariableSetStmt, VariableShowStmt, ViewStmt, CheckPointStmt %type select_no_parens, select_with_parens, select_clause, simple_select %type alter_column_default %type drop_behavior --- 141,153 ---- RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty, RuleStmt, SelectStmt, TransactionStmt, TruncateStmt, UnlistenStmt, UpdateStmt, VacuumStmt, VariableResetStmt, ! VariableSetStmt, VariableShowStmt, ViewStmt, CheckPointStmt, %type select_no_parens, select_with_parens, select_clause, simple_select + %type values_clause + %type alter_column_default %type drop_behavior *************** *** 3220,3261 **** } ; ! 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; } --- 3222,3272 ---- } ; ! insert_rest: VALUES values_clause { $$ = makeNode(InsertStmt); $$->cols = NIL; ! $$->selectStmt = $2; } | DEFAULT VALUES { $$ = makeNode(InsertStmt); $$->cols = NIL; $$->selectStmt = NULL; } | SelectStmt { $$ = makeNode(InsertStmt); $$->cols = NIL; $$->selectStmt = $1; } ! | '(' columnList ')' VALUES values_clause { $$ = makeNode(InsertStmt); $$->cols = $2; ! $$->selectStmt = $5; } | '(' columnList ')' SelectStmt { $$ = makeNode(InsertStmt); $$->cols = $2; $$->selectStmt = $4; } ; + + values_clause: values_clause ',' '(' target_list ')' + { + SelectStmt *n = makeNode(SelectStmt); + n->targetList = $4; + $$ = makeSetOp(SETOP_UNION, TRUE, $1, (Node *) n); + } + | '(' target_list ')' + { + SelectStmt *n = makeNode(SelectStmt); + n->targetList = $2; + $$ = (Node *) n; + } + ; opt_column_list: '(' columnList ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } Index: src/include/nodes/parsenodes.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/nodes/parsenodes.h,v retrieving revision 1.143 diff -c -r1.143 parsenodes.h *** src/include/nodes/parsenodes.h 2001/08/26 16:56:02 1.143 --- src/include/nodes/parsenodes.h 2001/09/07 14:22:39 *************** *** 806,816 **** List *cols; /* optional: names of the target columns */ /* ! * 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 ---- List *cols; /* optional: names of the target columns */ /* ! * An INSERT statement has *either* VALUES or SELECT, never both. ! * The parser turns a VALUES ... into a SELECT ... so for both, a ! * complete SelectStmt (or set-operation tree) is supplied. The only ! * time selectStmt is NULL is if INSERT ... DEFAULT VALUES is done. */ Node *selectStmt; /* the source SELECT */ } InsertStmt; Index: src/interfaces/ecpg/preproc/preproc.y =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/ecpg/preproc/preproc.y,v retrieving revision 1.152 diff -c -r1.152 preproc.y *** src/interfaces/ecpg/preproc/preproc.y 2001/08/19 09:21:44 1.152 --- src/interfaces/ecpg/preproc/preproc.y 2001/09/07 14:22:40 *************** *** 340,345 **** --- 340,346 ---- %type opt_force key_update CreateSchemaStmt PosIntStringConst %type IntConst PosIntConst grantee_list func_type %type select_limit opt_for_update_clause CheckPointStmt + %type values_list %type ECPGWhenever ECPGConnect connection_target ECPGOpen %type indicator ECPGExecute ECPGPrepare ecpg_using *************** *** 2371,2379 **** } ; ! insert_rest: VALUES '(' target_list ')' { ! $$ = cat_str(3, make_str("values("), $3, make_str(")")); } | DEFAULT VALUES { --- 2372,2380 ---- } ; ! insert_rest: VALUES values_list { ! $$ = cat_str(2, make_str("values "), $2); } | DEFAULT VALUES { *************** *** 2383,2395 **** { $$ = $1; } ! | '(' columnList ')' VALUES '(' target_list ')' { ! $$ = cat_str(5, make_str("("), $2, make_str(") values ("), $6, make_str(")")); } | '(' columnList ')' SelectStmt { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); } ; --- 2384,2406 ---- { $$ = $1; } ! | '(' columnList ')' VALUES values_list { ! $$ = cat_str(4, make_str("("), $2, make_str(") values "), $5); } | '(' columnList ')' SelectStmt { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); + } + ; + + values_list: values_list ',' '(' target_list ')' + { + $$ = cat_str(4, $1, make_str(", ("), $4, make_str(")")); + } + | '(' target_list ')' + { + $$ = cat_str(3, make_str("("), $2, make_str(")")); } ; Index: src/test/regress/parallel_schedule =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/test/regress/parallel_schedule,v retrieving revision 1.5 diff -c -r1.5 parallel_schedule *** src/test/regress/parallel_schedule 2001/06/12 16:34:27 1.5 --- src/test/regress/parallel_schedule 2001/09/07 14:22:40 *************** *** 37,43 **** # ---------- # The third group of parallel test # ---------- ! test: constraints triggers create_misc create_aggregate create_operator create_index inherit # Depends on the above test: create_view --- 37,43 ---- # ---------- # The third group of parallel test # ---------- ! test: constraints triggers create_misc create_aggregate create_operator create_index inherit insert # Depends on the above test: create_view Index: src/test/regress/serial_schedule =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/test/regress/serial_schedule,v retrieving revision 1.6 diff -c -r1.6 serial_schedule *** src/test/regress/serial_schedule 2001/06/12 16:34:27 1.6 --- src/test/regress/serial_schedule 2001/09/07 14:22:40 *************** *** 47,52 **** --- 47,53 ---- test: create_operator test: create_index test: inherit + test: insert test: create_view test: sanity_check test: errors