|
17 | 17 | *
|
18 | 18 | * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
19 | 19 | *
|
20 |
| - * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.47 2003/03/15 21:19:40 tgl Exp $ |
| 20 | + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.48 2003/03/27 19:25:40 tgl Exp $ |
21 | 21 | *
|
22 | 22 | * ----------
|
23 | 23 | */
|
|
37 | 37 | #include "executor/spi_priv.h"
|
38 | 38 | #include "optimizer/planmain.h"
|
39 | 39 | #include "parser/parse_oper.h"
|
| 40 | +#include "rewrite/rewriteHandler.h" |
40 | 41 | #include "utils/lsyscache.h"
|
41 | 42 | #include "miscadmin.h"
|
42 | 43 |
|
@@ -2315,10 +2316,8 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
|
2315 | 2316 | const char *qualsep;
|
2316 | 2317 | Oid queryoids[RI_MAX_NUMKEYS];
|
2317 | 2318 | Plan *spi_plan;
|
2318 |
| - AttrDefault *defval; |
2319 |
| - TargetEntry *spi_qptle; |
2320 |
| - int i, |
2321 |
| - j; |
| 2319 | + int i; |
| 2320 | + List *l; |
2322 | 2321 |
|
2323 | 2322 | /* ----------
|
2324 | 2323 | * The query string built is
|
@@ -2355,45 +2354,31 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
|
2355 | 2354 | */
|
2356 | 2355 | qplan = SPI_prepare(querystr, qkey.nkeypairs, queryoids);
|
2357 | 2356 |
|
2358 |
| - /* ---------- |
2359 |
| - * Here now follows very ugly code depending on internals |
2360 |
| - * of the SPI manager. |
2361 |
| - * |
2362 |
| - * EVIL EVIL EVIL (but must be - Jan) |
| 2357 | + /* |
| 2358 | + * Scan the plan's targetlist and replace the NULLs by |
| 2359 | + * appropriate column defaults, if any (if not, they stay |
| 2360 | + * NULL). |
2363 | 2361 | *
|
2364 |
| - * We replace the CONST NULL targetlist expressions |
2365 |
| - * in the generated plan by (any) default values found |
2366 |
| - * in the tuple constructor. |
2367 |
| - * ---------- |
| 2362 | + * XXX This is really ugly; it'd be better to use "UPDATE |
| 2363 | + * SET foo = DEFAULT", if we had it. |
2368 | 2364 | */
|
2369 | 2365 | spi_plan = (Plan *) lfirst(((_SPI_plan *) qplan)->ptlist);
|
2370 |
| - if (fk_rel->rd_att->constr != NULL) |
2371 |
| - defval = fk_rel->rd_att->constr->defval; |
2372 |
| - else |
2373 |
| - defval = NULL; |
2374 |
| - for (i = 0; i < qkey.nkeypairs && defval != NULL; i++) |
| 2366 | + foreach(l, spi_plan->targetlist) |
2375 | 2367 | {
|
2376 |
| - /* |
2377 |
| - * For each key attribute lookup the tuple constructor |
2378 |
| - * for a corresponding default value |
2379 |
| - */ |
2380 |
| - for (j = 0; j < fk_rel->rd_att->constr->num_defval; j++) |
| 2368 | + TargetEntry *tle = (TargetEntry *) lfirst(l); |
| 2369 | + Node *dfl; |
| 2370 | + |
| 2371 | + /* Ignore any junk columns or Var=Var columns */ |
| 2372 | + if (tle->resdom->resjunk) |
| 2373 | + continue; |
| 2374 | + if (IsA(tle->expr, Var)) |
| 2375 | + continue; |
| 2376 | + |
| 2377 | + dfl = build_column_default(fk_rel, tle->resdom->resno); |
| 2378 | + if (dfl) |
2381 | 2379 | {
|
2382 |
| - if (defval[j].adnum == |
2383 |
| - qkey.keypair[i][RI_KEYPAIR_FK_IDX]) |
2384 |
| - { |
2385 |
| - /* |
2386 |
| - * That's the one - push the expression from |
2387 |
| - * defval.adbin into the plan's targetlist |
2388 |
| - */ |
2389 |
| - spi_qptle = (TargetEntry *) |
2390 |
| - nth(defval[j].adnum - 1, |
2391 |
| - spi_plan->targetlist); |
2392 |
| - spi_qptle->expr = stringToNode(defval[j].adbin); |
2393 |
| - fix_opfuncids((Node *) spi_qptle->expr); |
2394 |
| - |
2395 |
| - break; |
2396 |
| - } |
| 2380 | + fix_opfuncids(dfl); |
| 2381 | + tle->expr = (Expr *) dfl; |
2397 | 2382 | }
|
2398 | 2383 | }
|
2399 | 2384 | }
|
@@ -2559,10 +2544,8 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
|
2559 | 2544 | const char *qualsep;
|
2560 | 2545 | Oid queryoids[RI_MAX_NUMKEYS];
|
2561 | 2546 | Plan *spi_plan;
|
2562 |
| - AttrDefault *defval; |
2563 |
| - TargetEntry *spi_qptle; |
2564 |
| - int i, |
2565 |
| - j; |
| 2547 | + int i; |
| 2548 | + List *l; |
2566 | 2549 |
|
2567 | 2550 | /* ----------
|
2568 | 2551 | * The query string built is
|
@@ -2610,50 +2593,30 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
|
2610 | 2593 | qplan = SPI_prepare(querystr, qkey.nkeypairs, queryoids);
|
2611 | 2594 |
|
2612 | 2595 | /*
|
2613 |
| - * Now replace the CONST NULL targetlist expressions in |
2614 |
| - * the generated plan by (any) default values found in the |
2615 |
| - * tuple constructor. |
| 2596 | + * Scan the plan's targetlist and replace the NULLs by |
| 2597 | + * appropriate column defaults, if any (if not, they stay |
| 2598 | + * NULL). |
| 2599 | + * |
| 2600 | + * XXX This is really ugly; it'd be better to use "UPDATE |
| 2601 | + * SET foo = DEFAULT", if we had it. |
2616 | 2602 | */
|
2617 | 2603 | spi_plan = (Plan *) lfirst(((_SPI_plan *) qplan)->ptlist);
|
2618 |
| - if (fk_rel->rd_att->constr != NULL) |
2619 |
| - defval = fk_rel->rd_att->constr->defval; |
2620 |
| - else |
2621 |
| - defval = NULL; |
2622 |
| - for (i = 0; i < qkey.nkeypairs && defval != NULL; i++) |
| 2604 | + foreach(l, spi_plan->targetlist) |
2623 | 2605 | {
|
2624 |
| - /* |
2625 |
| - * MATCH <unspecified> - only change columns |
2626 |
| - * corresponding to changed columns in pk_rel's key. |
2627 |
| - * This conditional must match the one in the loop |
2628 |
| - * above that built the SET attrn=NULL list. |
2629 |
| - */ |
2630 |
| - if (match_type == RI_MATCH_TYPE_FULL || |
2631 |
| - !ri_OneKeyEqual(pk_rel, i, old_row, |
2632 |
| - new_row, &qkey, RI_KEYPAIR_PK_IDX)) |
| 2606 | + TargetEntry *tle = (TargetEntry *) lfirst(l); |
| 2607 | + Node *dfl; |
| 2608 | + |
| 2609 | + /* Ignore any junk columns or Var=Var columns */ |
| 2610 | + if (tle->resdom->resjunk) |
| 2611 | + continue; |
| 2612 | + if (IsA(tle->expr, Var)) |
| 2613 | + continue; |
| 2614 | + |
| 2615 | + dfl = build_column_default(fk_rel, tle->resdom->resno); |
| 2616 | + if (dfl) |
2633 | 2617 | {
|
2634 |
| - /* |
2635 |
| - * For each key attribute lookup the tuple |
2636 |
| - * constructor for a corresponding default value |
2637 |
| - */ |
2638 |
| - for (j = 0; j < fk_rel->rd_att->constr->num_defval; j++) |
2639 |
| - { |
2640 |
| - if (defval[j].adnum == |
2641 |
| - qkey.keypair[i][RI_KEYPAIR_FK_IDX]) |
2642 |
| - { |
2643 |
| - /* |
2644 |
| - * That's the one - push the expression |
2645 |
| - * from defval.adbin into the plan's |
2646 |
| - * targetlist |
2647 |
| - */ |
2648 |
| - spi_qptle = (TargetEntry *) |
2649 |
| - nth(defval[j].adnum - 1, |
2650 |
| - spi_plan->targetlist); |
2651 |
| - spi_qptle->expr = stringToNode(defval[j].adbin); |
2652 |
| - fix_opfuncids((Node *) spi_qptle->expr); |
2653 |
| - |
2654 |
| - break; |
2655 |
| - } |
2656 |
| - } |
| 2618 | + fix_opfuncids(dfl); |
| 2619 | + tle->expr = (Expr *) dfl; |
2657 | 2620 | }
|
2658 | 2621 | }
|
2659 | 2622 | }
|
|
0 commit comments