Re: [HACKERS] extension for sql update

Поиск
Список
Период
Сортировка
От Bruce Momjian
Тема Re: [HACKERS] extension for sql update
Дата
Msg-id 200609022055.k82KtJF02060@momjian.us
обсуждение исходный текст
Ответы Re: [HACKERS] extension for sql update  (Susanne Ebrecht <miracee@miracee.de>)
Список pgsql-patches
Susanne Ebrecht wrote:
> >>>>>> Is it too hard to rip it back out once the full row support
> >>>>>> arrives?  That seems speculation at best anyway.
> >>>>>>
> >>>>> That's what I was thinking.  Glad someone else replied.  ;-)
> >>>>>
> >>>> If you're looking for votes, +1. I'll gladly take a subset of the
> >>>> SQL standard UPDATE table SET (...) = (...) over having nothing.
> >>>>
> >>> +1 here, too. :)
> >>>
> >>>
> >> +1
> >>
> >
> > I am working now to get this into 8.2.
> >
> >
> I am glad to read this. But what does it mean to me? Shall I change the
> patch someway?

I have merged your patch into current CVS and applied it; attached.
There was quite a bit of code drift.  One drift area was the new
RETURNING clause;  that was easy to fix.  A more complex case is the
code no longer has values as ResTargets --- it is a simple a_expr list,
so I changed the critical assignment in gram.y from:

        res_col->val = (Node *)copyObject(res_val->val);

to:

    res_col->val = (Node *)copyObject(res_val);

Hope that is OK.  Without that fix, it crashed.  I also merged your SGML
syntax and grammer addition into the exiting UPDATE main entry.

--
  Bruce Momjian   bruce@momjian.us
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +
Index: doc/src/sgml/ref/update.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/update.sgml,v
retrieving revision 1.38
retrieving revision 1.39
diff -c -r1.38 -r1.39
*** doc/src/sgml/ref/update.sgml    12 Aug 2006 02:52:03 -0000    1.38
--- doc/src/sgml/ref/update.sgml    2 Sep 2006 20:34:47 -0000    1.39
***************
*** 21,27 ****
   <refsynopsisdiv>
  <synopsis>
  UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ [ AS ] <replaceable
class="parameter">alias</replaceable>] 
!     SET <replaceable class="PARAMETER">column</replaceable> = { <replaceable
class="PARAMETER">expression</replaceable>| DEFAULT } [, ...] 
      [ FROM <replaceable class="PARAMETER">fromlist</replaceable> ]
      [ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
      [ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ AS <replaceable
class="parameter">output_name</replaceable>] [, ...] ] 
--- 21,28 ----
   <refsynopsisdiv>
  <synopsis>
  UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ [ AS ] <replaceable
class="parameter">alias</replaceable>] 
!     [ SET <replaceable class="PARAMETER">column</replaceable> = { <replaceable
class="PARAMETER">expression</replaceable>| DEFAULT } [, ...] | 
!       SET ( <replaceable class="PARAMETER">column</replaceable> [, ...] ) = ( { <replaceable
class="PARAMETER">expression</replaceable>| DEFAULT } [, ...] ) [, ...] ] 
      [ FROM <replaceable class="PARAMETER">fromlist</replaceable> ]
      [ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
      [ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ AS <replaceable
class="parameter">output_name</replaceable>] [, ...] ] 
***************
*** 251,256 ****
--- 252,261 ----
  UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
    WHERE city = 'San Francisco' AND date = '2003-07-03';
  </programlisting>
+ <programlisting>
+ UPDATE weather SET (temp_lo, temp_hi, prcp) = (temp_lo+1, temp_lo+15, DEFAULT)
+   WHERE city = 'San Francisco' AND date = '2003-07-03';
+ </programlisting>
    </para>

    <para>
Index: src/backend/parser/gram.y
===================================================================
RCS file: /cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.560
retrieving revision 2.562
diff -c -r2.560 -r2.562
*** src/backend/parser/gram.y    2 Sep 2006 18:17:17 -0000    2.560
--- src/backend/parser/gram.y    2 Sep 2006 20:52:01 -0000    2.562
***************
*** 237,243 ****
                  name_list from_clause from_list opt_array_bounds
                  qualified_name_list any_name any_name_list
                  any_operator expr_list attrs
!                 target_list update_target_list insert_column_list
                  values_list def_list indirection opt_indirection
                  group_clause TriggerFuncArgs select_limit
                  opt_select_limit opclass_item_list
--- 237,244 ----
                  name_list from_clause from_list opt_array_bounds
                  qualified_name_list any_name any_name_list
                  any_operator expr_list attrs
!                 target_list update_col_list update_target_list
!                 update_value_list set_opt insert_column_list
                  values_list def_list indirection opt_indirection
                  group_clause TriggerFuncArgs select_limit
                  opt_select_limit opclass_item_list
***************
*** 308,314 ****
  %type <jexpr>    joined_table
  %type <range>    relation_expr
  %type <range>    relation_expr_opt_alias
! %type <target>    target_el update_target_el insert_column_item

  %type <typnam>    Typename SimpleTypename ConstTypename
                  GenericType Numeric opt_float
--- 309,316 ----
  %type <jexpr>    joined_table
  %type <range>    relation_expr
  %type <range>    relation_expr_opt_alias
! %type <target>    target_el update_target_el update_col_list_el insert_column_item
! %type <list>    update_target_lists_list update_target_lists_el

  %type <typnam>    Typename SimpleTypename ConstTypename
                  GenericType Numeric opt_float
***************
*** 5524,5530 ****
   *****************************************************************************/

  UpdateStmt: UPDATE relation_expr_opt_alias
!             SET update_target_list
              from_clause
              where_clause
              returning_clause
--- 5526,5532 ----
   *****************************************************************************/

  UpdateStmt: UPDATE relation_expr_opt_alias
!             SET set_opt
              from_clause
              where_clause
              returning_clause
***************
*** 5539,5544 ****
--- 5541,5551 ----
                  }
          ;

+ set_opt:
+             update_target_list                        { $$ = $1; }
+             | update_target_lists_list                { $$ = $1; }
+         ;
+

  /*****************************************************************************
   *
***************
*** 5941,5946 ****
--- 5948,6007 ----
              | DEFAULT                { $$ = (Node *) makeNode(SetToDefault); }
          ;

+ update_target_lists_list:
+             update_target_lists_el { $$ = $1; }
+             | update_target_lists_list ',' update_target_lists_el { $$ = list_concat($1, $3); }
+         ;
+
+ update_target_lists_el:
+             '(' update_col_list ')' '=' '(' update_value_list ')'
+                 {
+                     ListCell *col_cell;
+                     ListCell *val_cell;
+
+                     if (list_length($2) != list_length($6))
+                     {
+                         ereport(ERROR,
+                             (errcode(ERRCODE_SYNTAX_ERROR),
+                              errmsg("number of columns does not match to number of values")));
+                     }
+
+                     for (col_cell = list_head($2), val_cell = list_head($6);
+                          col_cell != NULL && val_cell != NULL;
+                          col_cell = lnext(col_cell), val_cell = lnext(val_cell))
+                     {
+                         /* merge update_value_list with update_col_list */
+                         ResTarget *res_col = (ResTarget *) lfirst(col_cell);
+                         Node *res_val = (Node *) lfirst(val_cell);
+
+                         res_col->val = (Node *)copyObject(res_val);
+                     }
+
+                     $$ = $2;
+                 }
+         ;
+
+ update_col_list:
+             update_col_list_el { $$ = list_make1($1); }
+             | update_col_list ',' update_col_list_el { $$ = lappend($1, $3); }
+         ;
+
+ update_col_list_el:
+             ColId opt_indirection
+                 {
+                     $$ = makeNode(ResTarget);
+                     $$->name = $1;
+                     $$->indirection = $2;
+                     $$->val = NULL;
+                     $$->location = @1;
+                 }
+         ;
+
+ update_value_list:
+             values_item { $$ = list_make1($1); }
+             | update_value_list ',' values_item { $$ = lappend($1, $3); }
+         ;
+

  /*****************************************************************************
   *
***************
*** 8253,8259 ****
          ;

  update_target_list:
!             update_target_el                        { $$ = list_make1($1); }
              | update_target_list ',' update_target_el { $$ = lappend($1,$3); }
          ;

--- 8314,8320 ----
          ;

  update_target_list:
!             update_target_el              { $$ = list_make1($1); }
              | update_target_list ',' update_target_el { $$ = lappend($1,$3); }
          ;


В списке pgsql-patches по дате отправления:

Предыдущее
От: Bruce Momjian
Дата:
Сообщение: Re: Patch for - Change FETCH/MOVE to use int8
Следующее
От: Joe Conway
Дата:
Сообщение: Re: [Fwd: dblink patch - Asynchronous queries and parallel