Commit 97b4e5ad authored by Bruce Momjian's avatar Bruce Momjian

Add INSERT(..., DEFAULT, ).

Rod Taylor
parent aab0b8f5
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -1947,6 +1947,15 @@ _copyFuncWithArgs(FuncWithArgs *from)
return newnode; return newnode;
} }
static InsertDefault *
_copyInsertDefault(InsertDefault *from)
{
InsertDefault *newnode = makeNode(InsertDefault);
return newnode;
}
static ClosePortalStmt * static ClosePortalStmt *
_copyClosePortalStmt(ClosePortalStmt *from) _copyClosePortalStmt(ClosePortalStmt *from)
{ {
...@@ -3055,6 +3064,9 @@ copyObject(void *from) ...@@ -3055,6 +3064,9 @@ copyObject(void *from)
case T_FuncWithArgs: case T_FuncWithArgs:
retval = _copyFuncWithArgs(from); retval = _copyFuncWithArgs(from);
break; break;
case T_InsertDefault:
retval = _copyInsertDefault(from);
break;
default: default:
elog(ERROR, "copyObject: don't know how to copy node type %d", elog(ERROR, "copyObject: don't know how to copy node type %d",
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -773,6 +773,12 @@ _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
&& equal(a->funcargs, b->funcargs); && equal(a->funcargs, b->funcargs);
} }
static bool
_equalInsertDefault(InsertDefault *a, InsertDefault *b)
{
return true;
}
static bool static bool
_equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b) _equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b)
{ {
...@@ -2215,6 +2221,9 @@ equal(void *a, void *b) ...@@ -2215,6 +2221,9 @@ equal(void *a, void *b)
case T_FuncWithArgs: case T_FuncWithArgs:
retval = _equalFuncWithArgs(a, b); retval = _equalFuncWithArgs(a, b);
break; break;
case T_InsertDefault:
retval = _equalInsertDefault(a, b);
break;
default: default:
elog(WARNING, "equal: don't know whether nodes of type %d are equal", elog(WARNING, "equal: don't know whether nodes of type %d are equal",
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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, ...@@ -518,13 +518,29 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
TargetEntry *tle = (TargetEntry *) lfirst(tl); TargetEntry *tle = (TargetEntry *) lfirst(tl);
ResTarget *col; ResTarget *col;
Assert(!tle->resdom->resjunk);
if (icolumns == NIL || attnos == NIL) if (icolumns == NIL || attnos == NIL)
elog(ERROR, "INSERT has more expressions than target columns"); elog(ERROR, "INSERT has more expressions than target columns");
col = (ResTarget *) lfirst(icolumns); col = (ResTarget *) lfirst(icolumns);
/*
* 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(IsA(col, ResTarget));
Assert(!tle->resdom->resjunk);
updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos), updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
col->indirection); col->indirection);
}
else
{
icolumns = lremove(icolumns, icolumns);
attnos = lremove(attnos, attnos);
qry->targetList = lremove(tle, qry->targetList);
}
icolumns = lnext(icolumns); icolumns = lnext(icolumns);
attnos = lnext(attnos); attnos = lnext(attnos);
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -203,6 +203,7 @@ static bool set_name_needs_quotes(const char *name); ...@@ -203,6 +203,7 @@ static bool set_name_needs_quotes(const char *name);
from_clause, from_list, opt_array_bounds, qualified_name_list, from_clause, from_list, opt_array_bounds, qualified_name_list,
any_name, any_name_list, expr_list, dotted_name, attrs, any_name, any_name_list, expr_list, dotted_name, attrs,
target_list, update_target_list, insert_column_list, target_list, update_target_list, insert_column_list,
insert_target_list,
def_list, opt_indirection, group_clause, TriggerFuncArgs, def_list, opt_indirection, group_clause, TriggerFuncArgs,
select_limit, opt_select_limit select_limit, opt_select_limit
...@@ -263,7 +264,7 @@ static bool set_name_needs_quotes(const char *name); ...@@ -263,7 +264,7 @@ static bool set_name_needs_quotes(const char *name);
%type <node> table_ref %type <node> table_ref
%type <jexpr> joined_table %type <jexpr> joined_table
%type <range> relation_expr %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 %type <typnam> Typename, SimpleTypename, ConstTypename
GenericType, Numeric, Character, ConstDatetime, ConstInterval, Bit GenericType, Numeric, Character, ConstDatetime, ConstInterval, Bit
...@@ -3504,7 +3505,7 @@ InsertStmt: INSERT INTO qualified_name insert_rest ...@@ -3504,7 +3505,7 @@ InsertStmt: INSERT INTO qualified_name insert_rest
} }
; ;
insert_rest: VALUES '(' target_list ')' insert_rest: VALUES '(' insert_target_list ')'
{ {
$$ = makeNode(InsertStmt); $$ = makeNode(InsertStmt);
$$->cols = NIL; $$->cols = NIL;
...@@ -3525,7 +3526,7 @@ insert_rest: VALUES '(' target_list ')' ...@@ -3525,7 +3526,7 @@ insert_rest: VALUES '(' target_list ')'
$$->targetList = NIL; $$->targetList = NIL;
$$->selectStmt = $1; $$->selectStmt = $1;
} }
| '(' insert_column_list ')' VALUES '(' target_list ')' | '(' insert_column_list ')' VALUES '(' insert_target_list ')'
{ {
$$ = makeNode(InsertStmt); $$ = makeNode(InsertStmt);
$$->cols = $2; $$->cols = $2;
...@@ -5244,7 +5245,6 @@ c_expr: columnref ...@@ -5244,7 +5245,6 @@ c_expr: columnref
s->val.type = T_String; s->val.type = T_String;
s->val.val.str = "now"; s->val.val.str = "now";
s->typename = makeTypeName(xlateSqlType("text")); s->typename = makeTypeName(xlateSqlType("text"));
d = makeTypeName(xlateSqlType("timetz")); d = makeTypeName(xlateSqlType("timetz"));
if (($3 < 0) || ($3 > 13)) if (($3 < 0) || ($3 > 13))
elog(ERROR,"CURRENT_TIME(%d) precision must be between %d and %d", elog(ERROR,"CURRENT_TIME(%d) precision must be between %d and %d",
...@@ -5721,6 +5721,23 @@ update_target_el: ColId opt_indirection '=' a_expr ...@@ -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 * Names and constants
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -175,9 +175,19 @@ transformTargetList(ParseState *pstate, List *targetlist)
false)); 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 else
{ {
/* Everything else but ColumnRef */ /* Everything else but ColumnRef and InsertDefault */
p_target = lappend(p_target, p_target = lappend(p_target,
transformTargetEntry(pstate, transformTargetEntry(pstate,
res->val, res->val,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -229,6 +229,7 @@ typedef enum NodeTag
T_PrivGrantee, T_PrivGrantee,
T_FuncWithArgs, T_FuncWithArgs,
T_PrivTarget, T_PrivTarget,
T_InsertDefault,
/* /*
* TAGS FOR FUNCTION-CALL CONTEXT AND RESULTINFO NODES (see fmgr.h) * TAGS FOR FUNCTION-CALL CONTEXT AND RESULTINFO NODES (see fmgr.h)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -359,6 +359,14 @@ typedef struct ResTarget
* assign */ * assign */
} ResTarget; } ResTarget;
/*
* Empty node used as a marker for Default Columns
*/
typedef struct InsertDefault
{
NodeTag type;
} InsertDefault;
/* /*
* SortGroupBy - for ORDER BY clause * SortGroupBy - for ORDER BY clause
*/ */
......
--
-- 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 ...@@ -21,6 +21,7 @@ test: horology
# ---------- # ----------
# These four each depend on the previous one # These four each depend on the previous one
# ---------- # ----------
test: insert
test: create_function_1 test: create_function_1
test: create_type test: create_type
test: create_table test: create_table
......
# $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. # This should probably be in an order similar to parallel_schedule.
test: boolean test: boolean
test: char test: char
...@@ -37,6 +37,7 @@ test: type_sanity ...@@ -37,6 +37,7 @@ test: type_sanity
test: opr_sanity test: opr_sanity
test: geometry test: geometry
test: horology test: horology
test: insert
test: create_function_1 test: create_function_1
test: create_type test: create_type
test: create_table test: create_table
......
--
-- 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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment