Re: TODO question

From: "Pavlo Baron" <pb(at)pbit(dot)org>
To: "Bruce Momjian" <pgman(at)candle(dot)pha(dot)pa(dot)us>
Cc: "PostgreSQL-development" <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: TODO question
Date: 2001-12-29 09:28:34
Message-ID: 004401c1904b$33bdd3b0$6500a8c0@bw1
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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?
>
> Yes, that is the one. The steps for adding an entry to an existing
> structure is similar to add an entirely new one.

What structure could you suggest me to pick out and to follow in the code
which would be handled similarily to my "Default"? This one is a one-way
use'n'drop struct and wouldn't appear anywhere else.

>
> > > 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* ,)
>
> I think it would be a subset. I haven't looked at it closely yet,
> though.
>

oops, a new patch attached: the last one wouldn't compile because of missing
T_Default value I just forgot to diff-in (or out) - sorry

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 the target list, try
relation.*.");

+ /* pavlo (pb(at)pbit(dot)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 expression is 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(at)pbit(dot)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(at)pbit(dot)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(at)pbit(dot)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
Index: src/include/nodes/nodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/nodes.h,v
retrieving revision 1.96
diff -c -r1.96 nodes.h
*** src/include/nodes/nodes.h 2001/11/05 17:46:34 1.96
--- src/include/nodes/nodes.h 2001/12/29 09:23:37
***************
*** 222,227 ****
--- 222,228 ----
T_CaseWhen,
T_FkConstraint,
T_PrivGrantee,
+ T_Default, /* pavlo (pb(at)pbit(dot)org) : 2001.12.27: DEFAULT element of
the INSERT INTO target list*/

/*
* TAGS FOR FUNCTION-CALL CONTEXT AND RESULTINFO NODES (see fmgr.h)
***************
*** 365,368 ****
(jointype) == JOIN_FULL || \
(jointype) == JOIN_RIGHT)

! #endif /* NODES_H */
--- 366,369 ----
(jointype) == JOIN_FULL || \
(jointype) == JOIN_RIGHT)

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

Attachment Content-Type Size
patch.diff application/octet-stream 8.8 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Pavlo Baron 2001-12-29 12:09:58 Re: TODO question
Previous Message Thomas Lockhart 2001-12-29 08:09:39 Re: text -> time cast problem