From 97b4e5ad309b169886a218189804cede0a1eed26 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 5 Apr 2002 11:56:55 +0000 Subject: [PATCH] Add INSERT(..., DEFAULT, ). Rod Taylor --- src/backend/nodes/copyfuncs.c | 14 +++++++++++++- src/backend/nodes/equalfuncs.c | 11 ++++++++++- src/backend/parser/analyze.c | 24 ++++++++++++++++++++---- src/backend/parser/gram.y | 27 ++++++++++++++++++++++----- src/backend/parser/parse_target.c | 14 ++++++++++++-- src/include/nodes/nodes.h | 3 ++- src/include/nodes/parsenodes.h | 10 +++++++++- src/test/regress/expected/insert.out | 20 ++++++++++++++++++++ src/test/regress/parallel_schedule | 1 + src/test/regress/serial_schedule | 3 ++- src/test/regress/sql/insert.sql | 12 ++++++++++++ 11 files changed, 123 insertions(+), 16 deletions(-) create mode 100644 src/test/regress/expected/insert.out create mode 100644 src/test/regress/sql/insert.sql diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 055e3c371e..b633b02b79 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.174 2002/03/29 19:06:08 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.175 2002/04/05 11:56:48 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1947,6 +1947,15 @@ _copyFuncWithArgs(FuncWithArgs *from) return newnode; } +static InsertDefault * +_copyInsertDefault(InsertDefault *from) +{ + InsertDefault *newnode = makeNode(InsertDefault); + + return newnode; +} + + static ClosePortalStmt * _copyClosePortalStmt(ClosePortalStmt *from) { @@ -3055,6 +3064,9 @@ copyObject(void *from) case T_FuncWithArgs: retval = _copyFuncWithArgs(from); break; + case T_InsertDefault: + retval = _copyInsertDefault(from); + break; default: elog(ERROR, "copyObject: don't know how to copy node type %d", diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index fee607419a..eceb8cb36f 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.122 2002/03/29 19:06:08 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.123 2002/04/05 11:56:50 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -773,6 +773,12 @@ _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b) && equal(a->funcargs, b->funcargs); } +static bool +_equalInsertDefault(InsertDefault *a, InsertDefault *b) +{ + return true; +} + static bool _equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b) { @@ -2215,6 +2221,9 @@ equal(void *a, void *b) case T_FuncWithArgs: retval = _equalFuncWithArgs(a, b); break; + case T_InsertDefault: + retval = _equalInsertDefault(a, b); + break; default: elog(WARNING, "equal: don't know whether nodes of type %d are equal", diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 080392b97f..0de9c5bb85 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.226 2002/04/02 06:30:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.227 2002/04/05 11:56:51 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -518,13 +518,29 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt, TargetEntry *tle = (TargetEntry *) lfirst(tl); ResTarget *col; - Assert(!tle->resdom->resjunk); if (icolumns == NIL || attnos == NIL) elog(ERROR, "INSERT has more expressions than target columns"); col = (ResTarget *) lfirst(icolumns); - Assert(IsA(col, ResTarget)); - updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos), + + /* + * When the value is to be set to the column default we can simply + * drop it now and handle it later on using methods for missing + * columns. + */ + if (!IsA(tle, InsertDefault)) + { + Assert(IsA(col, ResTarget)); + Assert(!tle->resdom->resjunk); + updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos), col->indirection); + } + else + { + icolumns = lremove(icolumns, icolumns); + attnos = lremove(attnos, attnos); + qry->targetList = lremove(tle, qry->targetList); + } + icolumns = lnext(icolumns); attnos = lnext(attnos); } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 4e2c2e7033..6ba8766e1a 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.299 2002/04/01 04:35:38 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.300 2002/04/05 11:56:53 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -203,6 +203,7 @@ static bool set_name_needs_quotes(const char *name); from_clause, from_list, opt_array_bounds, qualified_name_list, any_name, any_name_list, expr_list, dotted_name, attrs, target_list, update_target_list, insert_column_list, + insert_target_list, def_list, opt_indirection, group_clause, TriggerFuncArgs, select_limit, opt_select_limit @@ -263,7 +264,7 @@ static bool set_name_needs_quotes(const char *name); %type table_ref %type joined_table %type relation_expr -%type target_el, update_target_el +%type target_el, insert_target_el, update_target_el %type Typename, SimpleTypename, ConstTypename GenericType, Numeric, Character, ConstDatetime, ConstInterval, Bit @@ -3504,7 +3505,7 @@ InsertStmt: INSERT INTO qualified_name insert_rest } ; -insert_rest: VALUES '(' target_list ')' +insert_rest: VALUES '(' insert_target_list ')' { $$ = makeNode(InsertStmt); $$->cols = NIL; @@ -3525,7 +3526,7 @@ insert_rest: VALUES '(' target_list ')' $$->targetList = NIL; $$->selectStmt = $1; } - | '(' insert_column_list ')' VALUES '(' target_list ')' + | '(' insert_column_list ')' VALUES '(' insert_target_list ')' { $$ = makeNode(InsertStmt); $$->cols = $2; @@ -5244,7 +5245,6 @@ c_expr: columnref s->val.type = T_String; s->val.val.str = "now"; s->typename = makeTypeName(xlateSqlType("text")); - d = makeTypeName(xlateSqlType("timetz")); if (($3 < 0) || ($3 > 13)) elog(ERROR,"CURRENT_TIME(%d) precision must be between %d and %d", @@ -5721,6 +5721,23 @@ update_target_el: ColId opt_indirection '=' a_expr } ; +insert_target_list: insert_target_list ',' insert_target_el + { $$ = lappend($1, $3); } + | insert_target_el + { $$ = makeList1($1); } + ; + +insert_target_el: target_el { $$ = $1; } + | DEFAULT { + InsertDefault *def = makeNode(InsertDefault); + $$ = makeNode(ResTarget); + $$->name = NULL; + $$->indirection = NULL; + $$->val = (Node *)def; + } + ; + + /***************************************************************************** * * Names and constants diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 3ffef8e617..e8e82a45c3 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.81 2002/04/02 08:51:52 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.82 2002/04/05 11:56:53 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -175,9 +175,19 @@ transformTargetList(ParseState *pstate, List *targetlist) false)); } } + else if (IsA(res->val, InsertDefault)) + { + InsertDefault *newnode = makeNode(InsertDefault); + + /* + * If this is a DEFAULT element, we make a junk entry + * which will get dropped on return to transformInsertStmt(). + */ + p_target = lappend(p_target, newnode); + } else { - /* Everything else but ColumnRef */ + /* Everything else but ColumnRef and InsertDefault */ p_target = lappend(p_target, transformTargetEntry(pstate, res->val, diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 34510c0d79..ff03eb1228 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: nodes.h,v 1.103 2002/03/22 02:56:36 tgl Exp $ + * $Id: nodes.h,v 1.104 2002/04/05 11:56:54 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -229,6 +229,7 @@ typedef enum NodeTag T_PrivGrantee, T_FuncWithArgs, T_PrivTarget, + T_InsertDefault, /* * TAGS FOR FUNCTION-CALL CONTEXT AND RESULTINFO NODES (see fmgr.h) diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 4cccc6a7d2..e2b0d9f38f 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.167 2002/04/01 04:35:40 tgl Exp $ + * $Id: parsenodes.h,v 1.168 2002/04/05 11:56:54 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -359,6 +359,14 @@ typedef struct ResTarget * assign */ } ResTarget; +/* + * Empty node used as a marker for Default Columns + */ +typedef struct InsertDefault +{ + NodeTag type; +} InsertDefault; + /* * SortGroupBy - for ORDER BY clause */ diff --git a/src/test/regress/expected/insert.out b/src/test/regress/expected/insert.out new file mode 100644 index 0000000000..f0688762f5 --- /dev/null +++ b/src/test/regress/expected/insert.out @@ -0,0 +1,20 @@ +-- +-- insert with DEFAULT in the target_list +-- +create table inserttest (col1 int4, col2 int4 NOT NULL, col3 text default 'testing'); +insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT, DEFAULT); +ERROR: ExecAppend: Fail to add null value in not null attribute col2 +insert into inserttest (col2, col3) values (3, DEFAULT); +insert into inserttest (col1, col2, col3) values (DEFAULT, 5, DEFAULT); +insert into inserttest values (DEFAULT, 5, 'test'); +insert into inserttest values (DEFAULT, 7); +select * from inserttest; + col1 | col2 | col3 +------+------+--------- + | 3 | testing + | 5 | testing + | 5 | test + | 7 | testing +(4 rows) + +drop table inserttest; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index cd9d2d5260..c28d4c66eb 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -21,6 +21,7 @@ test: horology # ---------- # These four each depend on the previous one # ---------- +test: insert test: create_function_1 test: create_type test: create_table diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index c56b3561c2..58a9a3b944 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -1,4 +1,4 @@ -# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.8 2002/03/19 02:18:24 momjian Exp $ +# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.9 2002/04/05 11:56:55 momjian Exp $ # This should probably be in an order similar to parallel_schedule. test: boolean test: char @@ -37,6 +37,7 @@ test: type_sanity test: opr_sanity test: geometry test: horology +test: insert test: create_function_1 test: create_type test: create_table diff --git a/src/test/regress/sql/insert.sql b/src/test/regress/sql/insert.sql new file mode 100644 index 0000000000..5d42c87649 --- /dev/null +++ b/src/test/regress/sql/insert.sql @@ -0,0 +1,12 @@ +-- +-- insert with DEFAULT in the target_list +-- +create table inserttest (col1 int4, col2 int4 NOT NULL, col3 text default 'testing'); +insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT, DEFAULT); +insert into inserttest (col2, col3) values (3, DEFAULT); +insert into inserttest (col1, col2, col3) values (DEFAULT, 5, DEFAULT); +insert into inserttest values (DEFAULT, 5, 'test'); +insert into inserttest values (DEFAULT, 7); + +select * from inserttest; +drop table inserttest;