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: