]> granicus.if.org Git - postgresql/commitdiff
Add INSERT(..., DEFAULT, ).
authorBruce Momjian <bruce@momjian.us>
Fri, 5 Apr 2002 11:56:55 +0000 (11:56 +0000)
committerBruce Momjian <bruce@momjian.us>
Fri, 5 Apr 2002 11:56:55 +0000 (11:56 +0000)
Rod Taylor

src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/analyze.c
src/backend/parser/gram.y
src/backend/parser/parse_target.c
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/test/regress/expected/insert.out [new file with mode: 0644]
src/test/regress/parallel_schedule
src/test/regress/serial_schedule
src/test/regress/sql/insert.sql [new file with mode: 0644]

index 055e3c371e23e8c46d66fba52e44a4db186d1f10..b633b02b79d29bcfee773d80215f2d63c193f0da 100644 (file)
@@ -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",
index fee607419a5351a98fe81a207cba2ad168ec3f50..eceb8cb36f796e0aa0acb660dac9f6e8df433a51 100644 (file)
@@ -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",
index 080392b97f540c8c61c4380bd8738b44d308c7fc..0de9c5bb851b86f1bf2f87d5ebaec9518b90a1a5 100644 (file)
@@ -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);
        }
index 4e2c2e70336b8163d672c0b8f5fcf86b8c54360d..6ba8766e1ac173cfe40c5e4c750a7ed3fbdd97e0 100644 (file)
@@ -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
index 3ffef8e617abd02996f331c510f43a47af59cba3..e8e82a45c3b9d09ee65388eab049546bae5eed50 100644 (file)
@@ -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,
index 34510c0d792c81f32226d5c0dee0df4ff26d41ed..ff03eb122845722e46089176cf21046d08afdae7 100644 (file)
@@ -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)
index 4cccc6a7d2a7536aea0bfc080eff403849a09176..e2b0d9f38f3d43b1d060a16d732e8e1814890a1a 100644 (file)
@@ -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 (file)
index 0000000..f068876
--- /dev/null
@@ -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;
index cd9d2d5260aca99ee1626ed5a088ea600f889119..c28d4c66eb4ad8261c7f7a9f44dbdd76c4f3671c 100644 (file)
@@ -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
index c56b3561c2f3ab458129604d1c4513be58df60b3..58a9a3b944921688bf83725cdb1df8ffc89a4f6c 100644 (file)
@@ -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 (file)
index 0000000..5d42c87
--- /dev/null
@@ -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;