PostgreSQL Source Code: src/backend/optimizer/util/appendinfo.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

29

30

31typedef struct

32{

37

44

45

46

47

48

49

52 Index parentRTindex, Index childRTindex)

53{

55

62

63 return appinfo;

64}

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79static void

83{

89 int oldnatts = old_tupdesc->natts;

90 int newnatts = new_tupdesc->natts;

91 int old_attno;

92 int new_attno = 0;

93

94

96 appinfo->parent_colnos = pcolnos =

98

99 for (old_attno = 0; old_attno < oldnatts; old_attno++)

100 {

103 Oid atttypid;

105 Oid attcollation;

106

108 if (att->attisdropped)

109 {

110

112 continue;

113 }

115 atttypid = att->atttypid;

116 atttypmod = att->atttypmod;

117 attcollation = att->attcollation;

118

119

120

121

122

123 if (oldrelation == newrelation)

124 {

127 atttypid,

128 atttypmod,

129 attcollation,

130 0));

131 pcolnos[old_attno] = old_attno + 1;

132 continue;

133 }

134

135

136

137

138

139

140

141

142

143

144 if (new_attno >= newnatts ||

145 (att = TupleDescAttr(new_tupdesc, new_attno))->attisdropped ||

147 {

149

152 elog(ERROR, "could not find inherited attribute \"%s\" of relation \"%s\"",

155 Assert(new_attno >= 0 && new_attno < newnatts);

157

159 }

160

161

162 if (atttypid != att->atttypid || atttypmod != att->atttypmod)

164 (errcode(ERRCODE_INVALID_COLUMN_DEFINITION),

165 errmsg("attribute \"%s\" of relation \"%s\" does not match parent's type",

167 if (attcollation != att->attcollation)

169 (errcode(ERRCODE_INVALID_COLUMN_DEFINITION),

170 errmsg("attribute \"%s\" of relation \"%s\" does not match parent's collation",

172

175 atttypid,

176 atttypmod,

177 attcollation,

178 0));

179 pcolnos[new_attno] = old_attno + 1;

180 new_attno++;

181 }

182

184}

185

186

187

188

189

190

191

192

193

194

195

196

197

198

202{

204

208

209

210 Assert(nappinfos >= 1 && appinfos != NULL);

211

212

214

216}

217

221{

223 int nappinfos = context->nappinfos;

224 int cnt;

225

226 if (node == NULL)

227 return NULL;

229 {

232

234 return (Node *) var;

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265 for (cnt = 0; cnt < nappinfos; cnt++)

266 {

268 {

269 appinfo = appinfos[cnt];

270 break;

271 }

272 }

273

274 if (appinfo)

275 {

277

278 var->varnosyn = 0;

279 var->varattnosyn = 0;

281 {

282 Node *newnode;

283

285 elog(ERROR, "attribute %d of relation \"%s\" does not exist",

289 if (newnode == NULL)

290 elog(ERROR, "attribute %d of relation \"%s\" does not exist",

292 if (IsA(newnode, Var))

293 {

295 ((Var *) newnode)->varnullingrels = var->varnullingrels;

296 }

297 else

298 {

300 elog(ERROR, "failed to apply returningtype to a non-Var");

301 if (var->varnullingrels != NULL)

302 elog(ERROR, "failed to apply nullingrels to a non-Var");

303 }

304 return newnode;

305 }

307 {

308

309

310

311

312

313

315 {

318 {

320

325

327 return (Node *) r;

328 }

329 }

330 else

331 {

332

333

334

335

336

337

338

339

340

341

342

344 List *fields;

346

351 rowexpr->args = fields;

352 rowexpr->row_typeid = var->vartype;

354 rowexpr->colnames = copyObject(rte->eref->colnames);

356

358 elog(ERROR, "failed to apply returningtype to a non-Var");

359 if (var->varnullingrels != NULL)

360 elog(ERROR, "failed to apply nullingrels to a non-Var");

361

362 return (Node *) rowexpr;

363 }

364 }

365

366 }

368 {

369

370

371

372

373

374

375

376

378 Index leaf_relid = 0;

379

380 for (cnt = 0; cnt < nappinfos; cnt++)

381 {

383 leaf_result_relids))

384 {

385 if (leaf_relid)

386 elog(ERROR, "cannot translate to multiple leaf relids");

388 }

389 }

390

391 if (leaf_relid)

392 {

395

397 {

398

400

401 var->varno = leaf_relid;

402

403 Assert(var->varnullingrels == NULL);

404

405 var->varnosyn = 0;

406 var->varattnosyn = 0;

407 }

408 else

409 {

410

411

412

413

415 var->vartypmod,

416 var->varcollid);

417 }

418 }

419 }

420 return (Node *) var;

421 }

423 {

425

426 for (cnt = 0; cnt < nappinfos; cnt++)

427 {

429

431 {

433 break;

434 }

435 }

436 return (Node *) cexpr;

437 }

439 {

440

442

445 context);

446

448 {

450 nappinfos, appinfos);

451

452 }

453 return (Node *) phv;

454 }

455

460

461

462

463

464

465

467 {

470

471

472 memcpy(newinfo, oldinfo, sizeof(RestrictInfo));

473

474

477

478

479 newinfo->orclause = (Expr *)

481

482

498

499

500

501

502

503

504

505 newinfo->eval_cost.startup = -1;

506 newinfo->norm_selec = -1;

507 newinfo->outer_selec = -1;

508 newinfo->left_em = NULL;

509 newinfo->right_em = NULL;

510 newinfo->scansel_cache = NIL;

511 newinfo->left_bucketsize = -1;

512 newinfo->right_bucketsize = -1;

513 newinfo->left_mcvfreq = -1;

514 newinfo->right_mcvfreq = -1;

515

516 return (Node *) newinfo;

517 }

518

519

520

521

523 {

526

529 context);

530

533 context);

534

536

539 context);

540

541 return (Node *) newinfo;

542 }

543

544

545

546

548 {

551

552

553 memcpy(newtarget, oldtarget, sizeof(PathTarget));

554

557 context);

558

559 if (oldtarget->sortgrouprefs)

560 {

562

563 newtarget->sortgrouprefs = (Index *) palloc(nbytes);

564 memcpy(newtarget->sortgrouprefs, oldtarget->sortgrouprefs, nbytes);

565 }

566

567 return (Node *) newtarget;

568 }

569

570

571

572

573

576

579

581}

582

583

584

585

586

587

588

589

590

595{

597 int nappinfos;

598

599

600 if (childrel->parent != parentrel)

601 {

602 if (childrel->parent)

604 childrel->parent,

605 parentrel);

606 else

607 elog(ERROR, "childrel is not a child of parentrel");

608 }

609

610

612

614

616

617 return node;

618}

619

620

621

622

623

626{

628 int cnt;

629

630 for (cnt = 0; cnt < nappinfos; cnt++)

631 {

633

634

636 {

637

638 if (!result)

640

643 }

644 }

645

646

647 if (result)

648 return result;

649

650

651 return relids;

652}

653

654

655

656

657

662{

664 int nappinfos;

665

666

667

668

669

671 return relids;

672

673

674 if (childrel->parent != parentrel)

675 {

676 if (childrel->parent)

678 childrel->parent,

679 parentrel);

680 else

681 elog(ERROR, "childrel is not a child of parentrel");

682 }

683

684

686

688

690

691 return relids;

692}

693

694

695

696

697

700{

703

704

706

707

708 foreach(lc, attnums)

709 {

711 Var *childvar;

712

713

714 if (parentattno <= 0 ||

716 elog(ERROR, "attribute %d of relation \"%s\" does not exist",

719 if (childvar == NULL || IsA(childvar, Var))

720 elog(ERROR, "attribute %d of relation \"%s\" does not exist",

722

724 }

725 return result;

726}

727

728

729

730

731

734 Index child_relid, Index top_parent_relid)

735{

737

738 if (!appinfo)

739 elog(ERROR, "child rel %d not found in append_rel_array", child_relid);

740

741

742 if (appinfo->parent_relid != top_parent_relid)

745 top_parent_relid);

746

747

749}

750

751

752

753

754

755

756

757

758

759

760void

762 List **processed_tlist, List **update_colnos)

763{

764

766 if (relid == root->parse->resultRelation)

767 {

768

769

770

771

772 *processed_tlist = copyObject(root->processed_tlist);

773 if (update_colnos)

775 }

776 else

777 {

779 *processed_tlist = (List *)

781 (Node *) root->processed_tlist,

784 if (update_colnos)

785 *update_colnos =

787 relid,

788 root->parse->resultRelation);

789 }

790}

791

792

793

794

795

796

797

798

799

800

801

802

805{

807 int cnt = 0;

808 int i;

809

810

812

813 i = -1;

815 {

817

818 if (!appinfo)

819 {

820

822 continue;

823

824 elog(ERROR, "child rel %d not found in append_rel_array", i);

825 }

826

827 appinfos[cnt++] = appinfo;

828 }

829 *nappinfos = cnt;

830 return appinfos;

831}

832

833

834

835

836

837

838

839

840

841

842

843

844

845

846

847

848

849

850

851

852

853

854

855

856

857

858void

860 Index rtindex, const char *rowid_name)

861{

863 Var *rowid_var;

866

867

871 Assert(orig_var->varnullingrels == NULL);

872

873

874

875

876

877

878 if (rtindex == root->parse->resultRelation)

879 {

883 true);

884 root->processed_tlist = lappend(root->processed_tlist, tle);

885 return;

886 }

887

888

889

890

891

893 Assert(root->append_rel_array[rtindex] != NULL);

894

895

896

897

898

899

901

903

904

905 foreach(lc, root->row_identity_vars)

906 {

908 if (strcmp(rowid_name, ridinfo->rowidname) != 0)

909 continue;

911 {

912

914 return;

915 }

916 else

917 {

918

919 elog(ERROR, "conflicting uses of row-identity name \"%s\"",

920 rowid_name);

921 }

922 }

923

924

927

932

933 root->row_identity_vars = lappend(root->row_identity_vars, ridinfo);

934

935

937

938

942 true);

943 root->processed_tlist = lappend(root->processed_tlist, tle);

944}

945

946

947

948

949

950

951

952

953void

957{

958 CmdType commandType = root->parse->commandType;

959 char relkind = target_relation->rd_rel->relkind;

960 Var *var;

961

963

964 if (relkind == RELKIND_RELATION ||

965 relkind == RELKIND_MATVIEW ||

966 relkind == RELKIND_PARTITIONED_TABLE)

967 {

968

969

970

971

974 TIDOID,

975 -1,

977 0);

979 }

980 else if (relkind == RELKIND_FOREIGN_TABLE)

981 {

982

983

984

986

988

991 target_rte, target_relation);

992

993

994

995

996

997

998

999

1000

1001

1002

1003

1004

1005

1007 (target_relation->trigdesc &&

1010 {

1013 RECORDOID,

1014 -1,

1016 0);

1018 }

1019 }

1020}

1021

1022

1023

1024

1025

1026

1027

1028

1029

1030

1031

1032

1033

1034void

1036{

1038 int result_relation = parse->resultRelation;

1042

1043

1044

1045

1048 {

1050 return;

1051 }

1052 target_rte = rt_fetch(result_relation, parse->rtable);

1053 if (!target_rte->inh)

1054 {

1056 return;

1057 }

1058

1059

1060

1061

1062

1063

1064

1065

1066

1067

1068

1069

1070

1071

1072 if (root->row_identity_vars == NIL)

1073 {

1075

1078 target_rte, target_relation);

1081

1082 return;

1083 }

1084

1085

1086

1087

1088

1089

1090

1091

1093

1094 foreach(lc, root->processed_tlist)

1095 {

1098

1100 {

1103

1104 }

1105 }

1106}

void distribute_row_identity_vars(PlannerInfo *root)

void get_translated_update_targetlist(PlannerInfo *root, Index relid, List **processed_tlist, List **update_colnos)

AppendRelInfo ** find_appinfos_by_relids(PlannerInfo *root, Relids relids, int *nappinfos)

static void make_inh_translation_list(Relation oldrelation, Relation newrelation, Index newvarno, AppendRelInfo *appinfo)

Node * adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, AppendRelInfo **appinfos)

Relids adjust_child_relids_multilevel(PlannerInfo *root, Relids relids, RelOptInfo *childrel, RelOptInfo *parentrel)

List * adjust_inherited_attnums_multilevel(PlannerInfo *root, List *attnums, Index child_relid, Index top_parent_relid)

Node * adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, RelOptInfo *childrel, RelOptInfo *parentrel)

void add_row_identity_columns(PlannerInfo *root, Index rtindex, RangeTblEntry *target_rte, Relation target_relation)

static Node * adjust_appendrel_attrs_mutator(Node *node, adjust_appendrel_attrs_context *context)

AppendRelInfo * make_append_rel_info(Relation parentrel, Relation childrel, Index parentRTindex, Index childRTindex)

Relids adjust_child_relids(Relids relids, int nappinfos, AppendRelInfo **appinfos)

void add_row_identity_var(PlannerInfo *root, Var *orig_var, Index rtindex, const char *rowid_name)

List * adjust_inherited_attnums(List *attnums, AppendRelInfo *context)

#define InvalidAttrNumber

Bitmapset * bms_make_singleton(int x)

int bms_next_member(const Bitmapset *a, int prevbit)

Bitmapset * bms_del_member(Bitmapset *a, int x)

int bms_num_members(const Bitmapset *a)

bool bms_is_member(int x, const Bitmapset *a)

Bitmapset * bms_add_member(Bitmapset *a, int x)

bool bms_overlap(const Bitmapset *a, const Bitmapset *b)

Bitmapset * bms_copy(const Bitmapset *a)

#define OidIsValid(objectId)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

bool equal(const void *a, const void *b)

#define palloc_array(type, count)

FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)

Assert(PointerIsAligned(start, uint64))

#define HeapTupleIsValid(tuple)

static void * GETSTRUCT(const HeapTupleData *tuple)

void build_base_rel_tlists(PlannerInfo *root, List *final_tlist)

if(TABLE==NULL||TABLE_index==NULL)

List * lappend(List *list, void *datum)

List * lappend_int(List *list, int datum)

char * get_rel_name(Oid relid)

int32 get_typavgwidth(Oid typid, int32 typmod)

Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)

Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)

TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)

char * pstrdup(const char *in)

void pfree(void *pointer)

void * palloc0(Size size)

Oid exprType(const Node *expr)

int32 exprTypmod(const Node *expr)

#define expression_tree_mutator(n, m, c)

#define IsA(nodeptr, _type_)

#define rt_fetch(rangetable_index, rangetable)

FormData_pg_attribute * Form_pg_attribute

static int list_length(const List *l)

static void * list_nth(const List *list, int n)

static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)

#define RelationGetRelid(relation)

#define RelationGetDescr(relation)

#define RelationGetRelationName(relation)

RelOptInfo * find_base_rel(PlannerInfo *root, int relid)

RelOptInfo * find_base_rel_ignore_join(PlannerInfo *root, int relid)

AddForeignUpdateTargets_function AddForeignUpdateTargets

Relids leaf_result_relids

struct PathTarget * agg_input

struct PathTarget * target

struct PathTarget * reltarget

bool trig_delete_before_row

bool trig_delete_after_row

VarReturningType varreturningtype

AppendRelInfo ** appinfos

#define SelfItemPointerAttributeNumber

void ReleaseSysCache(HeapTuple tuple)

HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)

void table_close(Relation relation, LOCKMODE lockmode)

Relation table_open(Oid relationId, LOCKMODE lockmode)

static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)