|
9 | 9 | *
|
10 | 10 | *
|
11 | 11 | * IDENTIFICATION
|
12 |
| - * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.112 2005/06/13 23:14:48 tgl Exp $ |
| 12 | + * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.113 2005/07/23 21:05:47 tgl Exp $ |
13 | 13 | *
|
14 | 14 | *-------------------------------------------------------------------------
|
15 | 15 | */
|
|
25 | 25 | #include "nodes/makefuncs.h"
|
26 | 26 | #include "optimizer/clauses.h"
|
27 | 27 | #include "optimizer/plancat.h"
|
| 28 | +#include "optimizer/prep.h" |
28 | 29 | #include "optimizer/tlist.h"
|
29 | 30 | #include "parser/parsetree.h"
|
30 | 31 | #include "parser/parse_expr.h"
|
@@ -359,6 +360,85 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
|
359 | 360 | }
|
360 | 361 | }
|
361 | 362 |
|
| 363 | + |
| 364 | +/* |
| 365 | + * get_relation_constraints |
| 366 | + * |
| 367 | + * Retrieve the CHECK constraint expressions of the given relation. |
| 368 | + * |
| 369 | + * Returns a List (possibly empty) of constraint expressions. Each one |
| 370 | + * has been canonicalized, and its Vars are changed to have the varno |
| 371 | + * indicated by rel->relid. This allows the expressions to be easily |
| 372 | + * compared to expressions taken from WHERE. |
| 373 | + * |
| 374 | + * Note: at present this is invoked at most once per relation per planner |
| 375 | + * run, and in many cases it won't be invoked at all, so there seems no |
| 376 | + * point in caching the data in RelOptInfo. |
| 377 | + */ |
| 378 | +List * |
| 379 | +get_relation_constraints(Oid relationObjectId, RelOptInfo *rel) |
| 380 | +{ |
| 381 | + List *result = NIL; |
| 382 | + Index varno = rel->relid; |
| 383 | + Relation relation; |
| 384 | + TupleConstr *constr; |
| 385 | + |
| 386 | + /* |
| 387 | + * We assume the relation has already been safely locked. |
| 388 | + */ |
| 389 | + relation = heap_open(relationObjectId, NoLock); |
| 390 | + |
| 391 | + constr = relation->rd_att->constr; |
| 392 | + if (constr != NULL) |
| 393 | + { |
| 394 | + int num_check = constr->num_check; |
| 395 | + int i; |
| 396 | + |
| 397 | + for (i = 0; i < num_check; i++) |
| 398 | + { |
| 399 | + Node *cexpr; |
| 400 | + |
| 401 | + cexpr = stringToNode(constr->check[i].ccbin); |
| 402 | + |
| 403 | + /* |
| 404 | + * Run each expression through const-simplification and |
| 405 | + * canonicalization. This is not just an optimization, but is |
| 406 | + * necessary, because we will be comparing it to |
| 407 | + * similarly-processed qual clauses, and may fail to detect valid |
| 408 | + * matches without this. This must match the processing done to |
| 409 | + * qual clauses in preprocess_expression()! (We can skip the |
| 410 | + * stuff involving subqueries, however, since we don't allow any |
| 411 | + * in check constraints.) |
| 412 | + */ |
| 413 | + cexpr = eval_const_expressions(cexpr); |
| 414 | + |
| 415 | + cexpr = (Node *) canonicalize_qual((Expr *) cexpr); |
| 416 | + |
| 417 | + /* |
| 418 | + * Also mark any coercion format fields as "don't care", so that |
| 419 | + * we can match to both explicit and implicit coercions. |
| 420 | + */ |
| 421 | + set_coercionform_dontcare(cexpr); |
| 422 | + |
| 423 | + /* Fix Vars to have the desired varno */ |
| 424 | + if (varno != 1) |
| 425 | + ChangeVarNodes(cexpr, 1, varno, 0); |
| 426 | + |
| 427 | + /* |
| 428 | + * Finally, convert to implicit-AND format (that is, a List) |
| 429 | + * and append the resulting item(s) to our output list. |
| 430 | + */ |
| 431 | + result = list_concat(result, |
| 432 | + make_ands_implicit((Expr *) cexpr)); |
| 433 | + } |
| 434 | + } |
| 435 | + |
| 436 | + heap_close(relation, NoLock); |
| 437 | + |
| 438 | + return result; |
| 439 | +} |
| 440 | + |
| 441 | + |
362 | 442 | /*
|
363 | 443 | * build_physical_tlist
|
364 | 444 | *
|
|
0 commit comments