mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-30 19:00:29 +08:00
Add INSERT(..., DEFAULT, ).
Rod Taylor
This commit is contained in:
parent
aab0b8f5eb
commit
97b4e5ad30
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 <node> table_ref
|
||||
%type <jexpr> joined_table
|
||||
%type <range> relation_expr
|
||||
%type <target> target_el, update_target_el
|
||||
%type <target> target_el, insert_target_el, update_target_el
|
||||
|
||||
%type <typnam> 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
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
*/
|
||||
|
20
src/test/regress/expected/insert.out
Normal file
20
src/test/regress/expected/insert.out
Normal file
@ -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;
|
@ -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
|
||||
|
@ -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
|
||||
|
12
src/test/regress/sql/insert.sql
Normal file
12
src/test/regress/sql/insert.sql
Normal file
@ -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;
|
Loading…
Reference in New Issue
Block a user