PostgreSQL Source Code: src/backend/rewrite/rewriteSearchCycle.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

15

16#include "catalog/pg_operator_d.h"

17#include "catalog/pg_type_d.h"

26#include "utils/fmgroids.h"

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

118{

121

123 rowexpr->row_typeid = RECORDOID;

126

127 foreach(lc, col_list)

128 {

130

131 for (int i = 0; i < list_length(cte->ctecolnames); i++)

132 {

134

135 if (strcmp(colname, colname2) == 0)

136 {

137 Var *var;

138

143 0);

145 rowexpr->colnames = lappend(rowexpr->colnames, makeString(colname));

146 break;

147 }

148 }

149 }

150

151 return rowexpr;

152}

153

154

155

156

157

160{

162

164 arr->array_typeid = RECORDARRAYOID;

165 arr->element_typeid = RECORDOID;

168

169 return (Expr *) arr;

170}

171

172

173

174

175

176

177

178

181{

184

186 arr->array_typeid = RECORDARRAYOID;

187 arr->element_typeid = RECORDOID;

190

191 fexpr = makeFuncExpr(F_ARRAY_CAT, RECORDARRAYOID,

193 arr),

195

196 return (Expr *) fexpr;

197}

198

199

200

201

204{

207 int rti1,

208 rti2;

210 *rte2,

211 *newrte;

213 *newq2;

214 Query *newsubquery;

221 RowExpr *cycle_col_rowexpr = NULL;

222 RowExpr *search_col_rowexpr = NULL;

224 int cte_rtindex = -1;

225

226 Assert(cte->search_clause || cte->cycle_clause);

227

229

231

232

233

234

235

239

242

245

248

249

250

251

252 if (cte->search_clause)

253 {

254 if (cte->search_clause->search_breadth_first)

255 search_seq_type = RECORDOID;

256 else

257 search_seq_type = RECORDARRAYOID;

258 }

259

260

261

262

263 if (cte->search_clause)

264 sqc_attno = list_length(cte->ctecolnames) + 1;

265 if (cte->cycle_clause)

266 {

267 cmc_attno = list_length(cte->ctecolnames) + 1;

268 cpa_attno = list_length(cte->ctecolnames) + 2;

269 if (cte->search_clause)

270 {

271 cmc_attno++;

272 cpa_attno++;

273 }

274 }

275

276

277

278

281 newq1->canSetTag = true;

282

285 newrte->alias = makeAlias("*TLOCRN*", cte->ctecolnames);

286 newrte->eref = newrte->alias;

289 newrte->subquery = newsubquery;

290 newrte->inFromCl = true;

292

296

297

298

299

300 for (int i = 0; i < list_length(cte->ctecolnames); i++)

301 {

302 Var *var;

303

308 0);

313 }

314

315 if (cte->search_clause)

316 {

318

319 search_col_rowexpr = make_path_rowexpr(cte, cte->search_clause->search_col_list);

320 if (cte->search_clause->search_breadth_first)

321 {

324 search_col_rowexpr->args);

325 search_col_rowexpr->colnames = lcons(makeString("*DEPTH*"), search_col_rowexpr->colnames);

326 texpr = (Expr *) search_col_rowexpr;

327 }

328 else

332 cte->search_clause->search_seq_column,

333 false);

335 }

336 if (cte->cycle_clause)

337 {

340 cte->cycle_clause->cycle_mark_column,

341 false);

343 cycle_col_rowexpr = make_path_rowexpr(cte, cte->cycle_clause->cycle_col_list);

346 cte->cycle_clause->cycle_path_column,

347 false);

349 }

350

352

353 if (cte->search_clause)

354 {

355 rte1->eref->colnames = lappend(rte1->eref->colnames, makeString(cte->search_clause->search_seq_column));

356 }

357 if (cte->cycle_clause)

358 {

359 rte1->eref->colnames = lappend(rte1->eref->colnames, makeString(cte->cycle_clause->cycle_mark_column));

360 rte1->eref->colnames = lappend(rte1->eref->colnames, makeString(cte->cycle_clause->cycle_path_column));

361 }

362

363

364

365

368 newq2->canSetTag = true;

369

373 if (cte->search_clause)

374 {

375 ewcl = lappend(ewcl, makeString(cte->search_clause->search_seq_column));

376 }

377 if (cte->cycle_clause)

378 {

379 ewcl = lappend(ewcl, makeString(cte->cycle_clause->cycle_mark_column));

380 ewcl = lappend(ewcl, makeString(cte->cycle_clause->cycle_path_column));

381 }

382 newrte->alias = makeAlias("*TROCRN*", ewcl);

383 newrte->eref = newrte->alias;

384

385

386

387

388

389

390

391

392

393

394

396 {

398

400 strcmp(cte->ctename, e->ctename) == 0 &&

401 e->ctelevelsup == 2)

402 {

403 cte_rtindex = rti;

404 break;

405 }

406 }

407 if (cte_rtindex <= 0)

409 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

410 errmsg("with a SEARCH or CYCLE clause, the recursive reference to WITH query \"%s\" must be at the top level of its right-hand SELECT",

412

415

416

417

418

419 if (cte->search_clause)

420 {

421 Var *var;

422

423

424 var = makeVar(cte_rtindex, sqc_attno,

428 cte->search_clause->search_seq_column,

429 false);

431 }

432 if (cte->cycle_clause)

433 {

434 Var *var;

435

436

437 var = makeVar(cte_rtindex, cmc_attno,

438 cte->cycle_clause->cycle_mark_type,

439 cte->cycle_clause->cycle_mark_typmod,

440 cte->cycle_clause->cycle_mark_collation, 0);

443 cte->cycle_clause->cycle_mark_column,

444 false);

446

447

448 var = makeVar(cte_rtindex, cpa_attno,

452 cte->cycle_clause->cycle_path_column,

453 false);

455 }

456

457 newrte->subquery = newsubquery;

458 newrte->inFromCl = true;

460

463

464 if (cte->cycle_clause)

465 {

467

468

469

470

471 expr = make_opclause(cte->cycle_clause->cycle_mark_neop, BOOLOID, false,

473 cte->cycle_clause->cycle_mark_type,

474 cte->cycle_clause->cycle_mark_typmod,

475 cte->cycle_clause->cycle_mark_collation, 0),

476 (Expr *) cte->cycle_clause->cycle_mark_value,

478 cte->cycle_clause->cycle_mark_collation);

479

481 }

482 else

484

485

486

487

488 for (int i = 0; i < list_length(cte->ctecolnames); i++)

489 {

490 Var *var;

491

496 0);

501 }

502

503 if (cte->search_clause)

504 {

506

507 if (cte->search_clause->search_breadth_first)

508 {

511

512

513

514

515

516 search_col_rowexpr = copyObject(search_col_rowexpr);

517

519 fs->arg = (Expr *) makeVar(1, sqc_attno, RECORDOID, -1, 0, 0);

521 fs->resulttype = INT8OID;

522 fs->resulttypmod = -1;

523

525

527

528 texpr = (Expr *) search_col_rowexpr;

529 }

530 else

531 {

532

533

534

536 }

539 cte->search_clause->search_seq_column,

540 false);

542 }

543

544 if (cte->cycle_clause)

545 {

549

550

551

552

553

556 saoe->opno = RECORD_EQ_OP;

557 saoe->useOr = true;

559 makeVar(1, cpa_attno, RECORDARRAYOID, -1, 0, 0));

560

563 caseexpr->casetype = cte->cycle_clause->cycle_mark_type;

564 caseexpr->casecollid = cte->cycle_clause->cycle_mark_collation;

567 casewhen->expr = (Expr *) saoe;

568 casewhen->result = (Expr *) cte->cycle_clause->cycle_mark_value;

570 caseexpr->defresult = (Expr *) cte->cycle_clause->cycle_mark_default;

571

574 cte->cycle_clause->cycle_mark_column,

575 false);

577

578

579

580

583 cte->cycle_clause->cycle_path_column,

584 false);

586 }

587

589

590 if (cte->search_clause)

591 {

592 rte2->eref->colnames = lappend(rte2->eref->colnames, makeString(cte->search_clause->search_seq_column));

593 }

594 if (cte->cycle_clause)

595 {

596 rte2->eref->colnames = lappend(rte2->eref->colnames, makeString(cte->cycle_clause->cycle_mark_column));

597 rte2->eref->colnames = lappend(rte2->eref->colnames, makeString(cte->cycle_clause->cycle_path_column));

598 }

599

600

601

602

603 if (cte->search_clause)

604 {

605 sos->colTypes = lappend_oid(sos->colTypes, search_seq_type);

606 sos->colTypmods = lappend_int(sos->colTypmods, -1);

608 if (!sos->all)

609 sos->groupClauses = lappend(sos->groupClauses,

611 }

612 if (cte->cycle_clause)

613 {

614 sos->colTypes = lappend_oid(sos->colTypes, cte->cycle_clause->cycle_mark_type);

615 sos->colTypmods = lappend_int(sos->colTypmods, cte->cycle_clause->cycle_mark_typmod);

616 sos->colCollations = lappend_oid(sos->colCollations, cte->cycle_clause->cycle_mark_collation);

617 if (!sos->all)

618 sos->groupClauses = lappend(sos->groupClauses,

620

621 sos->colTypes = lappend_oid(sos->colTypes, RECORDARRAYOID);

622 sos->colTypmods = lappend_int(sos->colTypmods, -1);

624 if (!sos->all)

625 sos->groupClauses = lappend(sos->groupClauses,

627 }

628

629

630

631

632 if (cte->search_clause)

633 {

638 cte->search_clause->search_seq_column,

639 false));

640 }

641 if (cte->cycle_clause)

642 {

645 cte->cycle_clause->cycle_mark_type,

646 cte->cycle_clause->cycle_mark_typmod,

647 cte->cycle_clause->cycle_mark_collation, 0),

649 cte->cycle_clause->cycle_mark_column,

650 false));

655 cte->cycle_clause->cycle_path_column,

656 false));

657 }

658

659

660

661

662 cte->ctecolnames = ewcl;

663 if (cte->search_clause)

664 {

665 cte->ctecoltypes = lappend_oid(cte->ctecoltypes, search_seq_type);

666 cte->ctecoltypmods = lappend_int(cte->ctecoltypmods, -1);

668 }

669 if (cte->cycle_clause)

670 {

671 cte->ctecoltypes = lappend_oid(cte->ctecoltypes, cte->cycle_clause->cycle_mark_type);

672 cte->ctecoltypmods = lappend_int(cte->ctecoltypmods, cte->cycle_clause->cycle_mark_typmod);

673 cte->ctecolcollations = lappend_oid(cte->ctecolcollations, cte->cycle_clause->cycle_mark_collation);

674

675 cte->ctecoltypes = lappend_oid(cte->ctecoltypes, RECORDARRAYOID);

676 cte->ctecoltypmods = lappend_int(cte->ctecoltypmods, -1);

678 }

679

680 return cte;

681}

#define InvalidAttrNumber

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

Datum Int64GetDatum(int64 X)

Assert(PointerIsAligned(start, uint64))

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

List * lappend_int(List *list, int datum)

List * lappend_oid(List *list, Oid datum)

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

Alias * makeAlias(const char *aliasname, List *colnames)

FromExpr * makeFromExpr(List *fromlist, Node *quals)

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

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

FuncExpr * makeFuncExpr(Oid funcid, Oid rettype, List *args, Oid funccollid, Oid inputcollid, CoercionForm fformat)

Expr * make_opclause(Oid opno, Oid opresulttype, bool opretset, Expr *leftop, Expr *rightop, Oid opcollid, Oid inputcollid)

Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)

#define castNode(_type_, nodeptr)

SortGroupClause * makeSortGroupClauseForSetOp(Oid rescoltype, bool require_hash)

#define rt_fetch(rangetable_index, rangetable)

static int list_length(const List *l)

static Oid list_nth_oid(const List *list, int n)

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

#define list_nth_node(type, list, n)

#define list_make2(x1, x2)

static int list_nth_int(const List *list, int n)

void IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, int min_sublevels_up)

static RowExpr * make_path_rowexpr(const CommonTableExpr *cte, const List *col_list)

static Expr * make_path_initial_array(RowExpr *rowexpr)

static Expr * make_path_cat_expr(RowExpr *rowexpr, AttrNumber path_varattno)

CommonTableExpr * rewriteSearchAndCycle(CommonTableExpr *cte)

String * makeString(char *str)