Re: TODO question - Mailing list pgsql-hackers

From Pavlo Baron
Subject Re: TODO question
Date
Msg-id 018001c18ff6$e5d93a30$6500a8c0@bw1
Whole thread Raw
In response to Re: TODO question  (Bruce Momjian <pgman@candle.pha.pa.us>)
Responses Re: TODO question
Re: TODO question
Re: TODO question
List pgsql-hackers
Bruce Momjian writes:
> Sure, ask away.  We will do our best.  In fact, adding a new node is
> pretty tricky.  There is a developer's FAQ item about it, number 7.  I
> assume you read that already.

hm...do you mean the current version of FAQ on the web? there are 2 seventh
items in the table of contents, both jumping to
----------------------------------------snip--------------------------------
-
7) I just added a field to a structure. What else should I do?
The structures passing around from the parser, rewrite, optimizer, and
executor require quite a bit of support. Most structures have support
routines in src/backend/nodes used to create, copy, read, and output those
structures. Make sure you add support for your new field to these files.
Find any other places the structure may need code for your new field. mkid
is helpful with this (see above).

----------------------------------------snap--------------------------------
-

Is that what you mean? It confuses me a bit, surely because I'm new here...
I didn't change any existing struct, and coudn't find any struct I which
could grow bacause of my new parsenode type. The type-enum contains a
corresponding range of values (I think, it was smth. starting with 700 upto
...) - I just added my new type here.
Or do I use a wrong copy of FAQ?

>
> I may be able to take you patch and add the needed node support stuff,
> and send the patch back to you so you can continue on it.

thanx. please, feel free - I attached my last patch to this email.
I see, that my patch provides the needed operation, but maybe it's not
enough and could cause some side effects. I'm looking forward to your
modifications (I hope it doesn't keep you from your current work, at least
not crucial). What I'm just interested in is, if my changes would be a
subset of your code or if what I did is an absolute b*-sh* ,)

rgds
Pavlo Baron


Index: src/backend/parser/parse_target.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/parse_target.c,v
retrieving revision 1.76
diff -c -r1.76 parse_target.c
*** src/backend/parser/parse_target.c 2001/11/05 17:46:26 1.76
--- src/backend/parser/parse_target.c 2001/12/28 23:13:43
***************
*** 60,65 ****
--- 60,77 ----  if (IsA(expr, Ident) &&((Ident *) expr)->isRel)   elog(ERROR, "You can't use relation names alone in
thetarget list, try
 
relation.*.");

+         /* pavlo (pb@pbit.org: 2001-12-27: handle the DEFAULT in INSERT
INTO foo VALUES (..., DEFAULT, ...))*/
+         if (IsA(expr, Default))
+         {
+                 if (pstate->p_target_relation->rd_att->attrs[(AttrNumber)
pstate->p_last_resno - 1]->atthasdef)
+                 {
+                         Const    *con = (Const *)
stringToNode(pstate->p_target_relation->rd_att->constr->defval[(AttrNumber)
pstate->p_last_resno - 1].adbin);
+                         expr = con;
+                 }
+                 else
+                         elog(ERROR, "no default value for column \"%s\"
found\nDEFAULT cannot be inserted", colname);
+         }
+  type_id = exprType(expr);  type_mod = exprTypmod(expr);

***************
*** 260,266 ****    {     tle->expr = CoerceTargetExpr(pstate, tle->expr, type_id,             attrtype, attrtypmod);
!     if (tle->expr == NULL)      elog(ERROR, "column \"%s\" is of type '%s'"        " but expression is of type '%s'"
   "\n\tYou will need to rewrite or cast the expression",
 
--- 272,278 ----    {     tle->expr = CoerceTargetExpr(pstate, tle->expr, type_id,             attrtype, attrtypmod);
!                                 if (tle->expr == NULL)      elog(ERROR, "column \"%s\" is of type '%s'"        " but
expressionis of type '%s'"      "\n\tYou will need to rewrite or cast the expression",
 
***************
*** 299,305 ****      int32 attrtypmod) {  if (can_coerce_type(1, &type_id, &attrtype))
!   expr = coerce_type(pstate, expr, type_id, attrtype, attrtypmod);
 #ifndef DISABLE_STRING_HACKS

--- 311,317 ----      int32 attrtypmod) {  if (can_coerce_type(1, &type_id, &attrtype))
!             expr = coerce_type(pstate, expr, type_id, attrtype,
attrtypmod);
 #ifndef DISABLE_STRING_HACKS

***************
*** 525,528 ****  }
  return strength;
! }
--- 537,540 ----  }
  return strength;
! }
\ No newline at end of file
Index: src/backend/parser/parse_expr.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/parse_expr.c,v
retrieving revision 1.105
diff -c -r1.105 parse_expr.c
*** src/backend/parser/parse_expr.c 2001/11/12 20:05:24 1.105
--- src/backend/parser/parse_expr.c 2001/12/28 23:15:08
***************
*** 121,126 ****
--- 121,131 ----      result = (Node *) make_const(val);     break;    }
+                 case T_Default: /* pavlo (pb@pbit.org): 2001-12-27:
transormation for the DEFAULT value for INSERT INTO foo VALUES (...,
DEFAULT, ...)*/
+                         {
+                                 result = (Default *) expr;
+                                 break;
+    }   case T_ParamNo:    {     ParamNo    *pno = (ParamNo *) expr;
***************
*** 1066,1069 ****  }  else   return typename->name;
! }
--- 1071,1074 ----  }  else   return typename->name;
! }
\ No newline at end of file
Index: src/backend/parser/gram.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.276
diff -c -r2.276 gram.y
*** src/backend/parser/gram.y 2001/12/09 04:39:39 2.276
--- src/backend/parser/gram.y 2001/12/28 23:15:39
***************
*** 195,201 ****   opt_column_list, columnList, opt_name_list,   sort_clause, sortby_list, index_params, index_list,
name_list,  from_clause, from_list, opt_array_bounds,
 
!   expr_list, attrs, target_list, update_target_list,   def_list, opt_indirection, group_clause, TriggerFuncArgs,
select_limit,opt_select_limit
 

--- 195,201 ----   opt_column_list, columnList, opt_name_list,   sort_clause, sortby_list, index_params, index_list,
name_list,  from_clause, from_list, opt_array_bounds,
 
!   expr_list, attrs, target_list, insert_target_list, update_target_list,   def_list, opt_indirection, group_clause,
TriggerFuncArgs,  select_limit, opt_select_limit
 

***************
*** 253,259 **** %type <node> table_ref %type <jexpr> joined_table %type <range> relation_expr
! %type <target> target_el, update_target_el %type <paramno> ParamNo
 %type <typnam> Typename, SimpleTypename, ConstTypename
--- 253,259 ---- %type <node> table_ref %type <jexpr> joined_table %type <range> relation_expr
! %type <target> target_el, update_target_el, insert_target_el %type <paramno> ParamNo
 %type <typnam> Typename, SimpleTypename, ConstTypename
***************
*** 3302,3308 ****     }   ;

! insert_rest:  VALUES '(' target_list ')'     {      $$ = makeNode(InsertStmt);      $$->cols = NIL;
--- 3302,3308 ----     }   ;

! insert_rest: VALUES '(' insert_target_list ')'     {      $$ = makeNode(InsertStmt);      $$->cols = NIL;
***************
*** 5482,5488 ****  *

****************************************************************************
*/

! /* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
 target_list:  target_list ',' target_el     { $$ = lappend($1, $3);  }
--- 5482,5488 ----  *

****************************************************************************
*/

! /* Target lists as found in SELECT ... */
 target_list:  target_list ',' target_el     { $$ = lappend($1, $3);  }
***************
*** 5490,5496 ****
--- 5490,5522 ----     { $$ = makeList1($1);  }   ;

+ /* Target lists as found in INSERT VALUES ( ... ) */
+
+ /* pavlo (pb@pbit.org): 2001-12-27: parse node based handling for the
DEFAULT value added;
+    now it's possible to INSERT INTO ... VALUES (..., FEFAULT, ...)!
+ */
+ insert_target_list:  insert_target_list ',' insert_target_el
+     { $$ = lappend($1, $3);  }
+   | insert_target_el
+     { $$ = makeList1($1);  }
+                 | insert_target_list ',' target_el
+     { $$ = lappend($1, $3);  }
+   | target_el
+     { $$ = makeList1($1);  }
+   ;
+
+ insert_target_el:  DEFAULT
+                                 {
+                                         Default *n = makeNode(Default);
+      $$ = makeNode(ResTarget);
+      $$->name = NULL;
+      $$->indirection = NULL;
+                                         $$->val = (Node *)n;
+     }
+                 ;
+ /* AS is not optional because shift/red conflict with unary ops */
+ target_el:  a_expr AS ColLabel     {      $$ = makeNode(ResTarget);
***************
*** 6380,6383 ****   strcpy(newval+1, oldval);   v->val.str = newval;  }
! }
--- 6406,6409 ----   strcpy(newval+1, oldval);   v->val.str = newval;  }
! }
\ No newline at end of file
Index: src/include/nodes/parsenodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/parsenodes.h,v
retrieving revision 1.151
diff -c -r1.151 parsenodes.h
*** src/include/nodes/parsenodes.h 2001/11/05 17:46:34 1.151
--- src/include/nodes/parsenodes.h 2001/12/28 23:16:30
***************
*** 1005,1010 ****
--- 1005,1019 ---- } A_Const;
 /*
+  * pavlo (pb@pbit.org): 2001.12.27:
+  * Default - the DEFAULT constant expression used in the target list of
INSERT INTO ... VALUES (..., DEFAULT, ...)
+  */
+ typedef struct Default
+ {
+  NodeTag  type;
+ } Default;
+
+ /*  * TypeCast - a CAST expression  *  * NOTE: for mostly historical reasons, A_Const and ParamNo parsenodes
contain
***************
*** 1355,1358 ****  */ typedef SortClause GroupClause;

! #endif   /* PARSENODES_H */
--- 1364,1367 ----  */ typedef SortClause GroupClause;

! #endif   /* PARSENODES_H */
\ No newline at end of file


pgsql-hackers by date:

Previous
From: Andrew McMillan
Date:
Subject: Re: [ADMIN] compression -Fx "problem"
Next
From: Tom Lane
Date:
Subject: Re: TODO question