PostgreSQL Source Code: src/backend/executor/nodeWindowAgg.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

35

57

58

59

60

61

63{

67 void *localmem;

68 int markptr;

69 int readptr;

70 int64 markpos;

71 int64 seekpos;

74

75

76

77

78

79

80

83

84

85

86

87

89{

90

93

95

97

99

100

101

102

103

106

107 bool plain_agg;

108 int aggno;

110

113

114

115

116

118{

119

123

124

125

126

127

128

132

133 int numFinalArgs;

134

135

136

137

140

141

142

143

146

147

148

149

150

157

158 int wfuncno;

159

160

162

163

166

168

169

170 bool restart;

172

185 Datum *result, bool *isnull);

186

190 Datum *result, bool *isnull);

191

195

201

206

211

213 int relpos, int seektype,

214 bool set_mark, bool *isnull,

215 bool *isout);

217 int64 abs_pos, bool *isnull,

218 bool *isout);

222 int64 pos, int argno);

224 int64 pos, int argno);

226 int64 pos, int argno, bool isnull);

227

228

229

230

231#define NN_UNKNOWN 0x00

232#define NN_NULL 0x01

233#define NN_NOTNULL 0x02

234#define NN_MASK 0x03

235#define NN_BITS_PER_MEMBER 2

236

237#define NN_ITEM_PER_VAR (BITS_PER_BYTE / NN_BITS_PER_MEMBER)

238

239#define NN_POS_TO_BYTES(pos) ((pos) / NN_ITEM_PER_VAR)

240

241#define NN_BYTES_TO_POS(bytes) ((bytes) * NN_ITEM_PER_VAR)

242

243#define NN_SHIFT(pos) ((pos) % NN_ITEM_PER_VAR) * NN_BITS_PER_MEMBER

244

245

246

247

248

249static void

253{

255

256

257

258

259

260

263

266 else

267 {

273 }

278}

279

280

281

282

283

284static void

288{

291 int numArguments = perfuncstate->numArguments;

294 int i;

298

300

301

302 if (filter)

303 {

304 bool isnull;

306

308 {

310 return;

311 }

312 }

313

314

315 i = 1;

316 foreach(arg, wfuncstate->args)

317 {

319

320 fcinfo->args[i].value = ExecEvalExpr(argstate, econtext,

321 &fcinfo->args[i].isnull);

322 i++;

323 }

324

326 {

327

328

329

330

331

332 for (i = 1; i <= numArguments; i++)

333 {

334 if (fcinfo->args[i].isnull)

335 {

337 return;

338 }

339 }

340

341

342

343

344

345

346

347

348

349

351 {

359 return;

360 }

361

363 {

364

365

366

367

368

369

370

371

374 return;

375 }

376 }

377

378

379

380

381

383 numArguments + 1,

385 (Node *) winstate, NULL);

386 fcinfo->args[0].value = peraggstate->transValue;

391

392

393

394

395

398 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

399 errmsg("moving-aggregate transition function must not return null")));

400

401

402

403

404

405

406

408

409

410

411

412

413

414

415

416

419 {

420 if (!fcinfo->isnull)

421 {

424 false,

427 ;

428 else

432 }

434 {

436 false,

439 else

441 }

442 }

443

447}

448

449

450

451

452

453

454

455

456

457

458

459

460

461static bool

465{

468 int numArguments = perfuncstate->numArguments;

471 int i;

475

477

478

479 if (filter)

480 {

481 bool isnull;

483

485 {

487 return true;

488 }

489 }

490

491

492 i = 1;

493 foreach(arg, wfuncstate->args)

494 {

496

497 fcinfo->args[i].value = ExecEvalExpr(argstate, econtext,

498 &fcinfo->args[i].isnull);

499 i++;

500 }

501

503 {

504

505

506

507

508

509 for (i = 1; i <= numArguments; i++)

510 {

511 if (fcinfo->args[i].isnull)

512 {

514 return true;

515 }

516 }

517 }

518

519

521

522

523

524

525

526

527

528

529

531 elog(ERROR, "aggregate transition value is NULL before inverse transition");

532

533

534

535

536

537

538

540 {

544 peraggstate);

545 return true;

546 }

547

548

549

550

551

552

554 numArguments + 1,

556 (Node *) winstate, NULL);

557 fcinfo->args[0].value = peraggstate->transValue;

562

563

564

565

566 if (fcinfo->isnull)

567 {

569 return false;

570 }

571

572

574

575

576

577

578

579

580

581

582

583

584

585

588 {

589 if (!fcinfo->isnull)

590 {

593 false,

596 ;

597 else

601 }

603 {

605 false,

608 else

610 }

611 }

612

616

617 return true;

618}

619

620

621

622

623

624static void

628 Datum *result, bool *isnull)

629{

631

633

634

635

636

638 {

640 int numFinalArgs = peraggstate->numFinalArgs;

641 bool anynull;

642 int i;

643

645 numFinalArgs,

647 (Node *) winstate, NULL);

648 fcinfo->args[0].value =

654

655

656 for (i = 1; i < numFinalArgs; i++)

657 {

658 fcinfo->args[i].value = (Datum) 0;

659 fcinfo->args[i].isnull = true;

660 anynull = true;

661 }

662

663 if (fcinfo->flinfo->fn_strict && anynull)

664 {

665

666 *result = (Datum) 0;

667 *isnull = true;

668 }

669 else

670 {

672

673 winstate->curaggcontext = peraggstate->aggcontext;

675 winstate->curaggcontext = NULL;

676 *isnull = fcinfo->isnull;

678 fcinfo->isnull,

680 }

681 }

682 else

683 {

684 *result =

689 }

690

692}

693

694

695

696

697

698

699

700

701

702

703

704

705static void

707{

709 int wfuncno,

710 numaggs,

711 numaggs_restart,

712 i;

713 int64 aggregatedupto_nonrestarted;

719

720 numaggs = winstate->numaggs;

721 if (numaggs == 0)

722 return;

723

724

729

730

731

732

733

734

735

736

737

738

739

740

741

742

743

744

745

746

747

748

749

750

751

752

753

754

755

756

757

758

759

760

761

762

763

764

765

766

767

768

769

770

771

772

773

774

775

776

777

778

781 elog(ERROR, "window frame head moved backward");

782

783

784

785

786

787

788

789

790

791

792

793

800 {

801 for (i = 0; i < numaggs; i++)

802 {

803 peraggstate = &winstate->peragg[i];

804 wfuncno = peraggstate->wfuncno;

807 }

808 return;

809 }

810

811

812

813

814

815

816

817

818

819

820

821

822

823

824

825

826 numaggs_restart = 0;

827 for (i = 0; i < numaggs; i++)

828 {

829 peraggstate = &winstate->peragg[i];

835 {

836 peraggstate->restart = true;

837 numaggs_restart++;

838 }

839 else

840 peraggstate->restart = false;

841 }

842

843

844

845

846

847

848

849

850 while (numaggs_restart < numaggs &&

852 {

853

854

855

856

858 temp_slot))

859 elog(ERROR, "could not re-fetch previously fetched frame row");

860

861

863

864

865

866

867

868 for (i = 0; i < numaggs; i++)

869 {

870 bool ok;

871

872 peraggstate = &winstate->peragg[i];

873 if (peraggstate->restart)

874 continue;

875

876 wfuncno = peraggstate->wfuncno;

878 &winstate->perfunc[wfuncno],

879 peraggstate);

880 if (!ok)

881 {

882

883 peraggstate->restart = true;

884 numaggs_restart++;

885 }

886 }

887

888

890

891

894 }

895

896

897

898

899

900

902

903

904

905

906

907 if (agg_winobj->markptr >= 0)

909

910

911

912

913

914

915

916

917

918

919

920 if (numaggs_restart > 0)

922 for (i = 0; i < numaggs; i++)

923 {

924 peraggstate = &winstate->peragg[i];

925

926

928 numaggs_restart == 0 ||

930

931 if (peraggstate->restart)

932 {

933 wfuncno = peraggstate->wfuncno;

935 &winstate->perfunc[wfuncno],

936 peraggstate);

937 }

939 {

944 }

945 }

946

947

948

949

950

951

952

953

954

955

956

957 aggregatedupto_nonrestarted = winstate->aggregatedupto;

958 if (numaggs_restart > 0 &&

960 {

963 }

964

965

966

967

968

969

970

971

972 for (;;)

973 {

974 int ret;

975

976

978 {

980 agg_row_slot))

981 break;

982 }

983

984

985

986

987

989 agg_row_slot, false);

990 if (ret < 0)

991 break;

992 if (ret == 0)

993 goto next_tuple;

994

995

997

998

999 for (i = 0; i < numaggs; i++)

1000 {

1001 peraggstate = &winstate->peragg[i];

1002

1003

1004 if (!peraggstate->restart &&

1005 winstate->aggregatedupto < aggregatedupto_nonrestarted)

1006 continue;

1007

1008 wfuncno = peraggstate->wfuncno;

1010 &winstate->perfunc[wfuncno],

1011 peraggstate);

1012 }

1013

1014next_tuple:

1015

1017

1018

1021 }

1022

1023

1024 Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);

1025

1026

1027

1028

1029 for (i = 0; i < numaggs; i++)

1030 {

1032 bool *isnull;

1033

1034 peraggstate = &winstate->peragg[i];

1035 wfuncno = peraggstate->wfuncno;

1039 &winstate->perfunc[wfuncno],

1040 peraggstate,

1041 result, isnull);

1042

1043

1044

1045

1046

1047

1048

1049

1051 {

1058 }

1059 else

1060 {

1062 }

1064 }

1065}

1066

1067

1068

1069

1070

1071

1072

1073

1074

1075

1076static void

1078 Datum *result, bool *isnull)

1079{

1082

1084

1085

1086

1087

1088

1089

1090

1094 (Node *) perfuncstate->winobj, NULL);

1095

1096 for (int argno = 0; argno < perfuncstate->numArguments; argno++)

1097 fcinfo->args[argno].isnull = true;

1098

1100

1102 *isnull = fcinfo->isnull;

1103

1104

1105

1106

1107

1108

1109

1110

1111 if (!perfuncstate->resulttypeByVal && !fcinfo->isnull &&

1116

1118}

1119

1120

1121

1122

1123

1124

1125

1126

1127

1130{

1133 int numfuncs = winstate->numfuncs;

1134

1135

1137

1138

1140

1141

1142

1143

1144

1145

1146 winstate->current_ptr = 0;

1147

1148

1150

1151

1152 if (winstate->numaggs > 0)

1153 {

1155 int readptr_flags = 0;

1156

1157

1158

1159

1160

1163 {

1164

1166

1168 }

1169

1171 readptr_flags);

1172 }

1173

1174

1175 for (int i = 0; i < numfuncs; i++)

1176 {

1178

1180 {

1182

1184 0);

1187 }

1188 }

1189

1190

1191

1192

1193

1194

1195

1196

1197

1199

1201 {

1212 }

1213

1214

1215

1216

1217

1218

1219

1220

1222

1226 {

1229 }

1230}

1231

1232

1233

1234

1235

1236static void

1238{

1240 int numfuncs = winstate->numfuncs;

1241

1254 winstate->grouptailpos = -1;

1260

1261

1262

1263

1264

1266 {

1268

1271 else

1272 {

1273

1276 return;

1277 }

1278 }

1279

1280

1283

1285

1286 if (winstate->numaggs > 0)

1287 {

1289

1290

1291 agg_winobj->markpos = -1;

1292 agg_winobj->seekpos = -1;

1293

1294

1297 }

1298

1299

1300 for (int i = 0; i < numfuncs; i++)

1301 {

1303

1305 {

1307

1310

1311

1314 {

1316

1317 for (int j = 0; j < numargs; j++)

1318 {

1320

1321 if (n > 0)

1324 }

1325 }

1326 }

1327 }

1328

1329

1330

1331

1332

1335}

1336

1337

1338

1339

1340

1341static void

1343{

1348

1350 return;

1352 return;

1353

1354

1355

1356

1357

1358

1359

1361 {

1364

1365 pos = -1;

1366 }

1367

1368

1369

1370

1371

1372

1373

1374

1375

1377 pos = -1;

1378

1380

1381

1383

1384 while (winstate->spooled_rows <= pos || pos == -1)

1385 {

1388 {

1389

1392 break;

1393 }

1394

1396 {

1398

1401

1402

1404 {

1405

1406

1407

1411 break;

1412 }

1413 }

1414

1415

1416

1417

1418

1420 {

1421

1424 }

1425 }

1426

1428}

1429

1430

1431

1432

1433

1434

1435static void

1437{

1438 int i;

1439

1440 for (i = 0; i < winstate->numfuncs; i++)

1441 {

1443

1444

1445 if (perfuncstate->winobj)

1447 }

1448

1449

1450

1451

1452

1453

1454

1457 for (i = 0; i < winstate->numaggs; i++)

1458 {

1461 }

1462

1463 if (winstate->buffer)

1467}

1468

1469

1470

1471

1472

1473

1474

1475

1476

1477

1478

1479

1480

1481

1482

1483

1484

1485static int

1487 bool fetch_tuple)

1488{

1491

1492 Assert(pos >= 0);

1493

1494

1495

1496

1497

1499 if (pos < winstate->frameheadpos)

1500 return 0;

1501

1502

1503

1504

1505

1506

1508 {

1510 {

1511

1513 return -1;

1514 }

1516 {

1517

1519 {

1520 if (fetch_tuple)

1522 return -1;

1524 return -1;

1525 }

1526 }

1527 else

1529 }

1531 {

1533 {

1535

1536

1538 offset = -offset;

1539

1540 if (pos > winstate->currentpos + offset)

1541 return -1;

1542 }

1544 {

1545

1548 return -1;

1549 }

1550 else

1552 }

1553

1554

1556 {

1558 return 0;

1559 }

1563 {

1565

1566

1568 return 0;

1569

1571 {

1573 if (pos < winstate->grouptailpos)

1574 return 0;

1575 }

1576 }

1577

1578

1579 return 1;

1580}

1581

1582

1583

1584

1585

1586

1587

1588

1589

1590

1591

1592static void

1594{

1598

1600 return;

1601

1602

1604

1606 {

1607

1610 }

1612 {

1614 {

1615

1618 }

1620 {

1621

1623 {

1627 return;

1628 }

1629

1630

1631

1632

1633

1634

1635

1636

1641 {

1642

1645 elog(ERROR, "unexpected end of tuplestore");

1646 }

1647

1649 {

1652 break;

1653

1658 break;

1659 }

1661 }

1662 else

1664 }

1666 {

1668 {

1669

1671

1673 offset = -offset;

1674

1676

1680 {

1681

1685 }

1687 }

1689 {

1690

1691

1692

1693

1694

1695

1696

1697

1698 int sortCol = node->ordColIdx[0];

1699 bool sub,

1700 less;

1701

1702

1704

1705

1707 sub = true;

1708 else

1709 sub = false;

1710 less = false;

1711

1713 {

1714 sub = !sub;

1715 less = true;

1716 }

1717

1722 {

1723

1726 elog(ERROR, "unexpected end of tuplestore");

1727 }

1728

1730 {

1732 currval;

1733 bool headisnull,

1734 currisnull;

1735

1737 &headisnull);

1739 &currisnull);

1740 if (headisnull || currisnull)

1741 {

1742

1744 {

1745

1746 if (!headisnull || currisnull)

1747 break;

1748 }

1749 else

1750 {

1751

1752 if (headisnull || !currisnull)

1753 break;

1754 }

1755 }

1756 else

1757 {

1760 headval,

1761 currval,

1765 break;

1766 }

1767

1772 break;

1773 }

1775 }

1777 {

1778

1779

1780

1781

1782

1783

1784

1785

1787 int64 minheadgroup;

1788

1790 minheadgroup = winstate->currentgroup - offset;

1791 else

1792 minheadgroup = winstate->currentgroup + offset;

1793

1798 {

1799

1802 elog(ERROR, "unexpected end of tuplestore");

1803 }

1804

1806 {

1808 break;

1810

1815 break;

1819 }

1822 }

1823 else

1825 }

1826 else

1828

1830}

1831

1832

1833

1834

1835

1836

1837

1838

1839

1840

1841

1842static void

1844{

1848

1850 return;

1851

1852

1854

1856 {

1857

1861 }

1863 {

1865 {

1866

1869 }

1871 {

1872

1874 {

1879 return;

1880 }

1881

1882

1883

1884

1885

1886

1887

1888

1889

1894 {

1895

1898 elog(ERROR, "unexpected end of tuplestore");

1899 }

1900

1902 {

1906 break;

1907

1912 break;

1913 }

1915 }

1916 else

1918 }

1920 {

1922 {

1923

1925

1927 offset = -offset;

1928

1930

1934 {

1935

1939 }

1941 }

1943 {

1944

1945

1946

1947

1948

1949

1950

1951

1952 int sortCol = node->ordColIdx[0];

1953 bool sub,

1954 less;

1955

1956

1958

1959

1961 sub = true;

1962 else

1963 sub = false;

1964 less = true;

1965

1967 {

1968 sub = !sub;

1969 less = false;

1970 }

1971

1976 {

1977

1980 elog(ERROR, "unexpected end of tuplestore");

1981 }

1982

1984 {

1986 currval;

1987 bool tailisnull,

1988 currisnull;

1989

1991 &tailisnull);

1993 &currisnull);

1994 if (tailisnull || currisnull)

1995 {

1996

1998 {

1999

2000 if (!tailisnull)

2001 break;

2002 }

2003 else

2004 {

2005

2006 if (!currisnull)

2007 break;

2008 }

2009 }

2010 else

2011 {

2014 tailval,

2015 currval,

2019 break;

2020 }

2021

2026 break;

2027 }

2029 }

2031 {

2032

2033

2034

2035

2036

2037

2038

2039

2041 int64 maxtailgroup;

2042

2044 maxtailgroup = winstate->currentgroup - offset;

2045 else

2046 maxtailgroup = winstate->currentgroup + offset;

2047

2052 {

2053

2056 elog(ERROR, "unexpected end of tuplestore");

2057 }

2058

2060 {

2062 break;

2064

2069 break;

2073 }

2076 }

2077 else

2079 }

2080 else

2082

2084}

2085

2086

2087

2088

2089

2090

2091

2092static void

2094{

2097

2099 return;

2100

2101

2103

2104

2106 {

2111 return;

2112 }

2113

2114

2115

2116

2117

2118

2119

2120

2124 for (;;)

2125 {

2126

2131 break;

2135 break;

2136 }

2139

2141}

2142

2143

2144

2145

2146

2147

2150{

2155 bool isnull;

2157 bool byval;

2158

2159

2161

2163

2165 {

2168 econtext,

2169 &isnull);

2170 if (isnull)

2172 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

2173 errmsg("frame starting offset must not be null")));

2174

2177 &byval);

2180 {

2181

2183

2184 if (offset < 0)

2186 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),

2187 errmsg("frame starting offset must not be negative")));

2188 }

2189 }

2190

2192 {

2195 econtext,

2196 &isnull);

2197 if (isnull)

2199 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

2200 errmsg("frame ending offset must not be null")));

2201

2204 &byval);

2207 {

2208

2210

2211 if (offset < 0)

2213 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),

2214 errmsg("frame ending offset must not be negative")));

2215 }

2216 }

2218}

2219

2220

2221

2222

2223

2224

2225

2226

2227

2228

2231{

2235 int i;

2236 int numfuncs;

2237

2239

2241 return NULL;

2242

2243

2244

2245

2246

2247

2250

2251

2252 for (;;)

2253 {

2255 {

2256

2258

2259 }

2260 else

2261 {

2262

2264

2267

2268 }

2269

2270

2271

2272

2273

2275

2276

2279 {

2281

2283 {

2286

2287

2289 }

2290 else

2291 {

2292

2294 return NULL;

2295 }

2296 }

2297

2298

2300

2301

2303

2304

2305

2306

2307

2308

2309

2310

2311

2312

2313

2314

2315

2316

2317

2318

2324 {

2328 elog(ERROR, "unexpected end of tuplestore");

2331 {

2335 }

2337 }

2338 else

2339 {

2342 elog(ERROR, "unexpected end of tuplestore");

2343 }

2344

2345

2347 {

2348

2349

2350

2351 numfuncs = winstate->numfuncs;

2352 for (i = 0; i < numfuncs; i++)

2353 {

2355

2357 continue;

2361 }

2362

2363

2364

2365

2366 if (winstate->numaggs > 0)

2368 }

2369

2370

2371

2372

2373

2374

2375

2376

2377

2378

2379

2386

2387

2388

2389

2391

2392

2393

2394

2395

2396

2398

2400

2402 {

2404

2405

2406

2407

2408

2410 {

2411

2412

2413

2414

2415

2416

2417

2418

2419

2420

2422 {

2423

2424

2425

2426

2427

2428

2429

2430

2431

2432

2433 numfuncs = winstate->numfuncs;

2434 for (i = 0; i < numfuncs; i++)

2435 {

2438 }

2439

2440

2441

2442

2443

2444

2445

2447 {

2449 continue;

2450 }

2451 else

2452 {

2454 }

2455 }

2456 else

2457 {

2458

2459

2460

2461

2463 return NULL;

2464 }

2465 }

2466

2467

2468

2469

2471 {

2473 continue;

2474 }

2475

2476 break;

2477 }

2478

2479

2480

2481

2482

2484 break;

2485 }

2486

2487 return slot;

2488}

2489

2490

2491

2492

2493

2494

2495

2496

2499{

2507 int numfuncs,

2508 wfuncno,

2509 numaggs,

2510 aggno;

2513

2514

2516

2517

2518

2519

2524

2525

2527

2528

2529

2530

2531

2532

2537

2538

2541 "WindowAgg Partition",

2543

2544

2545

2546

2547

2548

2549

2552 "WindowAgg Aggregates",

2554

2555

2557

2558

2561

2562

2563

2564

2565

2566

2567

2568

2571

2572

2573

2574

2575

2576

2578

2579

2581

2582

2583

2584

2587

2588

2589

2590

2591

2594

2595

2599

2600

2601

2602

2611

2612

2613

2614

2615

2616

2618

2620 {

2631 }

2632

2633

2634

2635

2638

2639

2644 node->partColIdx,

2645 node->partOperators,

2646 node->partCollations,

2647 &winstate->ss.ps);

2648

2653 node->ordColIdx,

2654 node->ordOperators,

2655 node->ordCollations,

2656 &winstate->ss.ps);

2657

2658

2659

2660

2661 numfuncs = winstate->numfuncs;

2662 numaggs = winstate->numaggs;

2666

2667

2668

2669

2672 winstate->perfunc = perfunc;

2673 winstate->peragg = peragg;

2674

2675 wfuncno = -1;

2676 aggno = -1;

2677 foreach(l, winstate->funcs)

2678 {

2683 int i;

2684

2685 if (wfunc->winref != node->winref)

2686 elog(ERROR, "WindowFunc with winref %u assigned to WindowAgg with winref %u",

2688

2689

2690

2691

2692

2693 for (i = 0; i <= wfuncno; i++)

2694 {

2695 if (equal(wfunc, perfunc[i].wfunc) &&

2697 break;

2698 }

2699 if (i <= wfuncno && wfunc->ignore_nulls == perfunc[i].ignore_nulls)

2700 {

2701

2703 continue;

2704 }

2705

2706

2707 perfuncstate = &perfunc[++wfuncno];

2708

2709

2710 wfuncstate->wfuncno = wfuncno;

2711

2712

2719

2720

2721 perfuncstate->wfuncstate = wfuncstate;

2722 perfuncstate->wfunc = wfunc;

2724 perfuncstate->winCollation = wfunc->inputcollid;

2725

2729

2730

2731

2732

2733

2734 perfuncstate->plain_agg = wfunc->winagg;

2735 if (wfunc->winagg)

2736 {

2738

2739 perfuncstate->aggno = ++aggno;

2740 peraggstate = &winstate->peragg[aggno];

2742 peraggstate->wfuncno = wfuncno;

2743 }

2744 else

2745 {

2747

2748 winobj->winstate = winstate;

2751 perfuncstate->winobj = winobj;

2754

2755

2759 }

2760 }

2761

2762

2763 winstate->numfuncs = wfuncno + 1;

2764 winstate->numaggs = aggno + 1;

2765

2766

2767 if (winstate->numaggs > 0)

2768 {

2770

2771 agg_winobj->winstate = winstate;

2773 agg_winobj->localmem = NULL;

2774

2775 agg_winobj->markptr = -1;

2776 agg_winobj->readptr = -1;

2778 }

2779

2780

2782

2783

2788

2789

2797

2802

2803 return winstate;

2804}

2805

2806

2807

2808

2809

2810void

2812{

2814 int i;

2815

2816 if (node->buffer != NULL)

2817 {

2819

2820

2821 node->buffer = NULL;

2822 }

2823

2825

2827 {

2830 }

2833

2836

2839}

2840

2841

2842

2843

2844

2845void

2847{

2850

2853

2854

2856

2857

2867

2868

2871

2872

2873

2874

2875

2876 if (outerPlan->chgParam == NULL)

2878}

2879

2880

2881

2882

2883

2884

2888{

2890 int numArguments;

2893 Oid aggtranstype;

2896 bool use_ma_code;

2897 Oid transfn_oid,

2898 invtransfn_oid,

2899 finalfn_oid;

2900 bool finalextra;

2901 char finalmodify;

2902 Expr *transfnexpr,

2903 *invtransfnexpr,

2904 *finalfnexpr;

2905 Datum textInitVal;

2906 int i;

2908

2910

2911 i = 0;

2912 foreach(lc, wfunc->args)

2913 {

2915 }

2916

2919 elog(ERROR, "cache lookup failed for aggregate %u",

2922

2923

2924

2925

2926

2927

2928

2929

2930

2931

2932

2933

2934

2935

2936

2937

2938

2939

2940

2941 if (OidIsValid(aggform->aggminvtransfn))

2942 use_ma_code = false;

2943 else if (aggform->aggmfinalmodify == AGGMODIFY_READ_ONLY &&

2944 aggform->aggfinalmodify != AGGMODIFY_READ_ONLY)

2945 use_ma_code = true;

2947 use_ma_code = false;

2949 use_ma_code = false;

2951 use_ma_code = false;

2952 else

2953 use_ma_code = true;

2954 if (use_ma_code)

2955 {

2956 peraggstate->transfn_oid = transfn_oid = aggform->aggmtransfn;

2957 peraggstate->invtransfn_oid = invtransfn_oid = aggform->aggminvtransfn;

2958 peraggstate->finalfn_oid = finalfn_oid = aggform->aggmfinalfn;

2959 finalextra = aggform->aggmfinalextra;

2960 finalmodify = aggform->aggmfinalmodify;

2961 aggtranstype = aggform->aggmtranstype;

2962 initvalAttNo = Anum_pg_aggregate_aggminitval;

2963 }

2964 else

2965 {

2966 peraggstate->transfn_oid = transfn_oid = aggform->aggtransfn;

2968 peraggstate->finalfn_oid = finalfn_oid = aggform->aggfinalfn;

2969 finalextra = aggform->aggfinalextra;

2970 finalmodify = aggform->aggfinalmodify;

2971 aggtranstype = aggform->aggtranstype;

2972 initvalAttNo = Anum_pg_aggregate_agginitval;

2973 }

2974

2975

2976

2977

2978

2979

2980

2981 {

2983 Oid aggOwner;

2984

2988 elog(ERROR, "cache lookup failed for function %u",

2992

2993 aclresult = object_aclcheck(ProcedureRelationId, transfn_oid, aggOwner,

2999

3001 {

3002 aclresult = object_aclcheck(ProcedureRelationId, invtransfn_oid, aggOwner,

3008 }

3009

3011 {

3012 aclresult = object_aclcheck(ProcedureRelationId, finalfn_oid, aggOwner,

3018 }

3019 }

3020

3021

3022

3023

3024

3025

3026 if (finalmodify != AGGMODIFY_READ_ONLY)

3028 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

3029 errmsg("aggregate function %s does not support use as a window function",

3031

3032

3033 if (finalextra)

3034 peraggstate->numFinalArgs = numArguments + 1;

3035 else

3037

3038

3040 aggtranstype,

3041 inputTypes,

3042 numArguments);

3043

3044

3046 numArguments,

3047 0,

3048 false,

3049 aggtranstype,

3050 wfunc->inputcollid,

3051 transfn_oid,

3052 invtransfn_oid,

3053 &transfnexpr,

3054 &invtransfnexpr);

3055

3056

3059

3061 {

3064 }

3065

3067 {

3070 aggtranstype,

3071 wfunc->wintype,

3072 wfunc->inputcollid,

3073 finalfn_oid,

3074 &finalfnexpr);

3077 }

3078

3079

3086

3087

3088

3089

3090

3091 textInitVal = SysCacheGetAttr(AGGFNOID, aggTuple, initvalAttNo,

3093

3096 else

3098 aggtranstype);

3099

3100

3101

3102

3103

3104

3105

3106

3108 {

3109 if (numArguments < 1 ||

3112 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

3113 errmsg("aggregate %u needs to have compatible input type and transition type",

3115 }

3116

3117

3118

3119

3120

3121

3122

3123

3124

3128 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),

3129 errmsg("strictness of aggregate's forward and inverse transition functions must match")));

3130

3131

3132

3133

3134

3135

3136

3137

3138

3139

3140

3141

3142

3143

3144

3148 "WindowAgg Per Aggregate",

3150 else

3152

3154

3155 return peraggstate;

3156}

3157

3160{

3161 Oid typinput,

3162 typioparam;

3163 char *strInitVal;

3165

3169 typioparam, -1);

3170 pfree(strInitVal);

3171 return initVal;

3172}

3173

3174

3175

3176

3177

3178

3179

3180static bool

3183{

3186

3187

3189 return true;

3190

3191 econtext->ecxt_outertuple = slot1;

3192 econtext->ecxt_innertuple = slot2;

3194}

3195

3196

3197

3198

3199

3200

3201

3202

3203static bool

3205{

3208

3209

3211

3212

3213 if (pos < 0)

3214 return false;

3215

3216

3218

3220 return false;

3221

3222 if (pos < winobj->markpos)

3223 elog(ERROR, "cannot fetch row before WindowObject's mark position");

3224

3226

3228

3229

3230

3231

3232 if (winobj->seekpos < pos - 1)

3233 {

3235 pos - 1 - winobj->seekpos,

3236 true))

3237 elog(ERROR, "unexpected end of tuplestore");

3238 winobj->seekpos = pos - 1;

3239 }

3240 else if (winobj->seekpos > pos + 1)

3241 {

3243 winobj->seekpos - (pos + 1),

3244 false))

3245 elog(ERROR, "unexpected end of tuplestore");

3246 winobj->seekpos = pos + 1;

3247 }

3248 else if (winobj->seekpos == pos)

3249 {

3250

3251

3252

3253

3254

3255

3256

3259 }

3260

3261

3262

3263

3264

3265

3266

3267

3268

3269 if (winobj->seekpos > pos)

3270 {

3272 elog(ERROR, "unexpected end of tuplestore");

3274 }

3275 else

3276 {

3278 elog(ERROR, "unexpected end of tuplestore");

3280 }

3281

3283

3285

3286 return true;

3287}

3288

3289

3290

3291

3292

3295 int64 abs_pos, bool *isnull, bool *isout)

3296{

3300

3301 winstate = winobj->winstate;

3304 {

3305

3306 if (isout)

3307 *isout = true;

3308 *isnull = true;

3309 return (Datum) 0;

3310 }

3311

3312 if (isout)

3313 *isout = false;

3318 econtext, isnull);

3319}

3320

3321

3322

3323

3324

3325

3328 int relpos, int seektype, bool set_mark,

3329 bool *isnull, bool *isout)

3330{

3337 int notnull_offset;

3338 int notnull_relpos;

3339 int forward;

3340

3342 winstate = winobj->winstate;

3345 datum = (Datum) 0;

3346 notnull_offset = 0;

3347 notnull_relpos = abs(relpos);

3348

3349 switch (seektype)

3350 {

3352 elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame");

3353 abs_pos = mark_pos = 0;

3354 break;

3356

3357 if (relpos < 0)

3358 goto out_of_frame;

3362 forward = 1;

3363 break;

3365

3366 if (relpos > 0)

3367 goto out_of_frame;

3370 mark_pos = 0;

3371 forward = -1;

3372 break;

3373 default:

3374 elog(ERROR, "unrecognized window seek type: %d", seektype);

3375 abs_pos = mark_pos = 0;

3376 break;

3377 }

3378

3379

3380

3381

3382

3383 do

3384 {

3385 int inframe;

3386 int v;

3387

3388

3389

3390

3391

3392

3393 if (abs_pos < 0)

3394 goto out_of_frame;

3395

3396

3398 if (inframe == -1)

3399 goto out_of_frame;

3400 else if (inframe == 0)

3401 goto advance;

3402

3403 if (isout)

3404 *isout = false;

3405

3407 if (v == NN_NULL)

3408 goto advance;

3409

3410 else if (v == NN_UNKNOWN)

3411 {

3413 goto out_of_frame;

3414

3418 argno), econtext,

3419 isnull);

3420 if (!*isnull)

3421 notnull_offset++;

3422

3423

3425 }

3426 else

3427 {

3428 notnull_offset++;

3429 if (notnull_offset > notnull_relpos)

3430 {

3431

3433 goto out_of_frame;

3434

3439 econtext, isnull);

3440 }

3441 }

3442advance:

3443 abs_pos += forward;

3444 } while (notnull_offset <= notnull_relpos);

3445

3446 if (set_mark)

3448

3449 return datum;

3450

3451out_of_frame:

3452 if (isout)

3453 *isout = true;

3454 *isnull = true;

3455 return (Datum) 0;

3456}

3457

3458

3459

3460

3461

3462

3463static void

3465{

3467

3469 {

3472 }

3473}

3474

3475

3476

3477

3478

3479

3480

3481static void

3483{

3484

3485#define INIT_NOT_NULL_INFO_NUM 128

3486

3488 {

3489

3492

3493 for (;;)

3494 {

3497 Size newsize;

3498

3499 if (oldsize == 0)

3500

3501 {

3504 }

3505 else

3506 {

3507 newsize = oldsize * 2;

3510 }

3513 break;

3514 }

3516 }

3517}

3518

3519

3520

3521

3522

3523

3524

3527{

3531

3535 mb = mbp[bpos];

3537}

3538

3539

3540

3541

3542

3543

3544

3545

3546static void

3548{

3553 int shift;

3554

3558 mb = mbp[bpos];

3560 mb &= ~(NN_MASK << shift);

3561 mb |= (val << shift);

3562 mbp[bpos] = mb;

3563}

3564

3565

3566

3567

3568

3569

3570

3571

3572

3573

3574

3575

3576

3577void

3579 bool allowNullTreatment,

3581{

3584 {

3586

3588 elog(ERROR, "could not get function name");

3590 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

3591 errmsg("function %s does not allow RESPECT/IGNORE NULLS",

3593 }

3596}

3597

3598

3599

3600

3601

3602

3603

3604

3605

3606

3607

3608

3609

3610void *

3612{

3614 if (winobj->localmem == NULL)

3618}

3619

3620

3621

3622

3623

3624

3627{

3630}

3631

3632

3633

3634

3635

3636

3637

3638

3639

3642{

3646}

3647

3648

3649

3650

3651

3652

3653

3654

3655

3656

3657

3658void

3660{

3662

3664 winstate = winobj->winstate;

3665

3666 if (markpos < winobj->markpos)

3667 elog(ERROR, "cannot move WindowObject's mark position backward");

3669 if (markpos > winobj->markpos)

3670 {

3672 markpos - winobj->markpos,

3673 true);

3674 winobj->markpos = markpos;

3675 }

3677 if (markpos > winobj->seekpos)

3678 {

3680 markpos - winobj->seekpos,

3681 true);

3682 winobj->seekpos = markpos;

3683 }

3684}

3685

3686

3687

3688

3689

3690

3691

3692

3693bool

3695{

3700 bool res;

3701

3703 winstate = winobj->winstate;

3705

3706

3708 return true;

3709

3710

3711

3712

3713

3716

3719 pos1);

3722 pos2);

3723

3724 res = are_peers(winstate, slot1, slot2);

3725

3728

3729 return res;

3730}

3731

3732

3733

3734

3735

3736

3737

3738

3739

3740

3741

3742

3743

3744

3745

3746

3747

3748

3749

3752 int relpos, int seektype, bool set_mark,

3753 bool *isnull, bool *isout)

3754{

3759 bool null_treatment;

3760 int notnull_offset;

3761 int notnull_relpos;

3762 int forward;

3763 bool myisout;

3764

3766 winstate = winobj->winstate;

3767

3769

3770 switch (seektype)

3771 {

3773 if (null_treatment)

3775 else

3776 abs_pos = winstate->currentpos + relpos;

3777 break;

3779 if (null_treatment)

3780 abs_pos = 0;

3781 else

3782 abs_pos = relpos;

3783 break;

3786 abs_pos = winstate->spooled_rows - 1 + relpos;

3787 break;

3788 default:

3789 elog(ERROR, "unrecognized window seek type: %d", seektype);

3790 abs_pos = 0;

3791 break;

3792 }

3793

3794

3795 if (!null_treatment)

3796 {

3797

3799 abs_pos, isnull, &myisout);

3800 if (!myisout && set_mark)

3802 if (isout)

3803 *isout = myisout;

3804 return datum;

3805 }

3806

3807

3808 notnull_offset = 0;

3809 notnull_relpos = abs(relpos);

3810 forward = relpos > 0 ? 1 : -1;

3811 myisout = false;

3812 datum = 0;

3813

3814

3815

3816

3817

3818

3819

3820

3821

3824 else

3825 {

3826

3827

3828

3829

3830

3831 mark_pos = 0;

3832 }

3833

3834

3835

3836

3837

3838

3839 do

3840 {

3841 int nn_info;

3842

3843 abs_pos += forward;

3844 if (abs_pos < 0)

3845 break;

3846

3847

3849 if (nn_info == NN_NOTNULL)

3850 notnull_offset++;

3851 else if (nn_info == NN_NULL)

3852 continue;

3853 else

3854 {

3855

3856

3857

3858

3859

3860

3861

3863 abs_pos, isnull, &myisout);

3864 if (myisout)

3865 break;

3866 if (!*isnull)

3867 notnull_offset++;

3868

3870 }

3871 } while (notnull_offset < notnull_relpos);

3872

3873

3875 abs_pos, isnull, &myisout);

3876 if (!myisout && set_mark)

3878 if (isout)

3879 *isout = myisout;

3880

3881 return datum;

3882}

3883

3884

3885

3886

3887

3888

3889

3890

3891

3892

3893

3894

3895

3896

3897

3898

3899

3900

3901

3902

3903

3904

3905

3906

3907

3908

3909

3910

3911

3912

3913

3914

3915

3916

3919 int relpos, int seektype, bool set_mark,

3920 bool *isnull, bool *isout)

3921{

3927

3929 winstate = winobj->winstate;

3932

3935 set_mark, isnull, isout);

3936

3937 switch (seektype)

3938 {

3940 elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame");

3941 abs_pos = mark_pos = 0;

3942 break;

3944

3945 if (relpos < 0)

3946 goto out_of_frame;

3949 mark_pos = abs_pos;

3950

3951

3952

3953

3954

3955

3956

3957

3958

3959

3960

3961

3962

3964 {

3965 case 0:

3966

3967 break;

3969 if (abs_pos >= winstate->currentpos &&

3971 abs_pos++;

3972 break;

3977 {

3980

3981 abs_pos += winstate->grouptailpos - overlapstart;

3982 }

3983 break;

3988 {

3991

3992 if (abs_pos == overlapstart)

3994 else

3995 abs_pos += winstate->grouptailpos - overlapstart - 1;

3996 }

3997 break;

3998 default:

3999 elog(ERROR, "unrecognized frame option state: 0x%x",

4001 break;

4002 }

4003 break;

4005

4006 if (relpos > 0)

4007 goto out_of_frame;

4009 abs_pos = winstate->frametailpos - 1 + relpos;

4010

4011

4012

4013

4014

4015

4016

4017

4018

4019

4021 {

4022 case 0:

4023

4024 mark_pos = abs_pos;

4025 break;

4027 if (abs_pos <= winstate->currentpos &&

4029 abs_pos--;

4031 if (abs_pos < winstate->frameheadpos)

4032 goto out_of_frame;

4034 break;

4037 if (abs_pos < winstate->grouptailpos &&

4039 {

4042

4043 abs_pos -= overlapend - winstate->groupheadpos;

4044 }

4046 if (abs_pos < winstate->frameheadpos)

4047 goto out_of_frame;

4049 break;

4052 if (abs_pos < winstate->grouptailpos &&

4054 {

4057

4058 if (abs_pos == overlapend - 1)

4060 else

4061 abs_pos -= overlapend - 1 - winstate->groupheadpos;

4062 }

4064 if (abs_pos < winstate->frameheadpos)

4065 goto out_of_frame;

4067 break;

4068 default:

4069 elog(ERROR, "unrecognized frame option state: 0x%x",

4071 mark_pos = 0;

4072 break;

4073 }

4074 break;

4075 default:

4076 elog(ERROR, "unrecognized window seek type: %d", seektype);

4077 abs_pos = mark_pos = 0;

4078 break;

4079 }

4080

4082 goto out_of_frame;

4083

4084

4086 goto out_of_frame;

4087

4088 if (isout)

4089 *isout = false;

4090 if (set_mark)

4094 econtext, isnull);

4095

4096out_of_frame:

4097 if (isout)

4098 *isout = true;

4099 *isnull = true;

4100 return (Datum) 0;

4101}

4102

4103

4104

4105

4106

4107

4108

4109

4110

4111

4112

4113

4114

4115

4118{

4121

4123 winstate = winobj->winstate;

4124

4126

4129 econtext, isnull);

4130}

void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)

AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)

#define TextDatumGetCString(d)

#define MemSet(start, val, len)

#define OidIsValid(objectId)

bool contain_subplans(Node *clause)

bool contain_volatile_functions(Node *clause)

Datum datumCopy(Datum value, bool typByVal, int typLen)

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

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

void ExecReScan(PlanState *node)

ExprState * ExecInitExpr(Expr *node, PlanState *parent)

ExprState * ExecInitQual(List *qual, PlanState *parent)

ExprState * execTuplesMatchPrepare(TupleDesc desc, int numCols, const AttrNumber *keyColIdx, const Oid *eqOperators, const Oid *collations, PlanState *parent)

void ExecEndNode(PlanState *node)

PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)

const TupleTableSlotOps TTSOpsVirtual

TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)

void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)

const TupleTableSlotOps TTSOpsMinimalTuple

void ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate, const TupleTableSlotOps *tts_ops)

void ExecAssignExprContext(EState *estate, PlanState *planstate)

void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)

#define InstrCountFiltered1(node, delta)

#define outerPlanState(node)

@ WINDOWAGG_PASSTHROUGH_STRICT

#define EXEC_FLAG_BACKWARD

static TupleTableSlot * ExecProject(ProjectionInfo *projInfo)

#define ResetExprContext(econtext)

static bool ExecQual(ExprState *state, ExprContext *econtext)

static bool ExecQualAndReset(ExprState *state, ExprContext *econtext)

static TupleTableSlot * ExecProcNode(PlanState *node)

static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)

static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)

ExpandedObjectHeader * DatumGetEOHP(Datum d)

void DeleteExpandedObject(Datum d)

#define MakeExpandedObjectReadOnly(d, isnull, typlen)

#define DatumIsReadWriteExpandedObject(d, isnull, typlen)

#define palloc0_array(type, count)

void fmgr_info(Oid functionId, FmgrInfo *finfo)

Datum OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)

Datum FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5)

void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)

#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)

#define LOCAL_FCINFO(name, nargs)

#define FunctionCallInvoke(fcinfo)

#define fmgr_info_set_expr(expr, finfo)

Assert(PointerIsAligned(start, uint64))

#define HeapTupleIsValid(tuple)

static void * GETSTRUCT(const HeapTupleData *tuple)

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

void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)

void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)

char * get_func_name(Oid funcid)

void * repalloc0(void *pointer, Size oldsize, Size size)

void MemoryContextReset(MemoryContext context)

void * MemoryContextAllocZero(MemoryContext context, Size size)

void pfree(void *pointer)

void * palloc0(Size size)

MemoryContext CurrentMemoryContext

MemoryContext MemoryContextGetParent(MemoryContext context)

void MemoryContextDelete(MemoryContext context)

#define AllocSetContextCreate

#define ALLOCSET_DEFAULT_SIZES

#define CHECK_FOR_INTERRUPTS()

Oid exprType(const Node *expr)

Datum WinGetFuncArgInPartition(WindowObject winobj, int argno, int relpos, int seektype, bool set_mark, bool *isnull, bool *isout)

void * WinGetPartitionLocalMemory(WindowObject winobj, Size sz)

static void grow_notnull_info(WindowObject winobj, int64 pos, int argno)

#define INIT_NOT_NULL_INFO_NUM

static void begin_partition(WindowAggState *winstate)

struct WindowObjectData WindowObjectData

static void update_grouptailpos(WindowAggState *winstate)

Datum WinGetFuncArgInFrame(WindowObject winobj, int argno, int relpos, int seektype, bool set_mark, bool *isnull, bool *isout)

static TupleTableSlot * ExecWindowAgg(PlanState *pstate)

struct WindowStatePerAggData WindowStatePerAggData

static void init_notnull_info(WindowObject winobj, WindowStatePerFunc perfuncstate)

static Datum GetAggInitVal(Datum textInitVal, Oid transtype)

static void spool_tuples(WindowAggState *winstate, int64 pos)

static void advance_windowaggregate(WindowAggState *winstate, WindowStatePerFunc perfuncstate, WindowStatePerAgg peraggstate)

void ExecEndWindowAgg(WindowAggState *node)

static void eval_windowfunction(WindowAggState *winstate, WindowStatePerFunc perfuncstate, Datum *result, bool *isnull)

struct WindowStatePerFuncData WindowStatePerFuncData

static void put_notnull_info(WindowObject winobj, int64 pos, int argno, bool isnull)

static Datum ignorenulls_getfuncarginframe(WindowObject winobj, int argno, int relpos, int seektype, bool set_mark, bool *isnull, bool *isout)

static WindowStatePerAggData * initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc, WindowStatePerAgg peraggstate)

static void finalize_windowaggregate(WindowAggState *winstate, WindowStatePerFunc perfuncstate, WindowStatePerAgg peraggstate, Datum *result, bool *isnull)

static bool advance_windowaggregate_base(WindowAggState *winstate, WindowStatePerFunc perfuncstate, WindowStatePerAgg peraggstate)

static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)

static pg_noinline void prepare_tuplestore(WindowAggState *winstate)

void ExecReScanWindowAgg(WindowAggState *node)

int64 WinGetCurrentPosition(WindowObject winobj)

WindowAggState * ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)

bool WinRowsArePeers(WindowObject winobj, int64 pos1, int64 pos2)

static pg_noinline void calculate_frame_offsets(PlanState *pstate)

#define NN_BYTES_TO_POS(bytes)

void WinSetMarkPosition(WindowObject winobj, int64 markpos)

static void eval_windowaggregates(WindowAggState *winstate)

static uint8 get_notnull_info(WindowObject winobj, int64 pos, int argno)

#define NN_POS_TO_BYTES(pos)

static int row_is_in_frame(WindowObject winobj, int64 pos, TupleTableSlot *slot, bool fetch_tuple)

static void release_partition(WindowAggState *winstate)

static Datum gettuple_eval_partition(WindowObject winobj, int argno, int64 abs_pos, bool *isnull, bool *isout)

static void update_frametailpos(WindowAggState *winstate)

static void update_frameheadpos(WindowAggState *winstate)

static void initialize_windowaggregate(WindowAggState *winstate, WindowStatePerFunc perfuncstate, WindowStatePerAgg peraggstate)

void WinCheckAndInitializeNullTreatment(WindowObject winobj, bool allowNullTreatment, FunctionCallInfo fcinfo)

static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1, TupleTableSlot *slot2)

Datum WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)

int64 WinGetPartitionRowCount(WindowObject winobj)

#define castNode(_type_, nodeptr)

#define InvokeFunctionExecuteHook(objectId)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

void build_aggregate_finalfn_expr(Oid *agg_input_types, int num_finalfn_inputs, Oid agg_state_type, Oid agg_result_type, Oid agg_input_collation, Oid finalfn_oid, Expr **finalfnexpr)

Oid resolve_aggregate_transtype(Oid aggfuncid, Oid aggtranstype, Oid *inputTypes, int numArguments)

void build_aggregate_transfn_expr(Oid *agg_input_types, int agg_num_inputs, int agg_num_direct_inputs, bool agg_variadic, Oid agg_state_type, Oid agg_input_collation, Oid transfn_oid, Oid invtransfn_oid, Expr **transfnexpr, Expr **invtransfnexpr)

bool IsBinaryCoercible(Oid srctype, Oid targettype)

#define FRAMEOPTION_END_CURRENT_ROW

#define FRAMEOPTION_END_OFFSET

#define FRAMEOPTION_EXCLUDE_CURRENT_ROW

#define FRAMEOPTION_END_OFFSET_PRECEDING

#define FRAMEOPTION_START_UNBOUNDED_PRECEDING

#define FRAMEOPTION_START_CURRENT_ROW

#define FRAMEOPTION_START_OFFSET

#define FRAMEOPTION_EXCLUDE_TIES

#define FRAMEOPTION_RANGE

#define FRAMEOPTION_EXCLUDE_GROUP

#define FRAMEOPTION_GROUPS

#define FRAMEOPTION_END_UNBOUNDED_FOLLOWING

#define FRAMEOPTION_START_OFFSET_PRECEDING

#define FRAMEOPTION_EXCLUSION

FormData_pg_aggregate * Form_pg_aggregate

static int list_length(const List *l)

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

FormData_pg_proc * Form_pg_proc

static bool DatumGetBool(Datum X)

static int64 DatumGetInt64(Datum X)

static Datum BoolGetDatum(bool X)

static Datum ObjectIdGetDatum(Oid X)

static Pointer DatumGetPointer(Datum X)

#define PARSER_IGNORE_NULLS

char * format_procedure(Oid procedure_oid)

MemoryContext ecxt_per_tuple_memory

TupleTableSlot * ecxt_innertuple

TupleTableSlot * ecxt_scantuple

MemoryContext ecxt_per_query_memory

TupleTableSlot * ecxt_outertuple

const TupleTableSlotOps * outerops

ExprContext * ps_ExprContext

ProjectionInfo * ps_ProjInfo

ExecProcNodeMtd ExecProcNode

TupleTableSlot * ss_ScanTupleSlot

TupleDesc tts_tupleDescriptor

MemoryContext partcontext

TupleTableSlot * framehead_slot

FmgrInfo startInRangeFunc

TupleTableSlot * frametail_slot

ExprState * ordEqfunction

TupleTableSlot * temp_slot_2

TupleTableSlot * agg_row_slot

struct WindowObjectData * agg_winobj

WindowStatePerFunc perfunc

MemoryContext curaggcontext

ExprState * partEqfunction

TupleTableSlot * first_part_slot

TupleTableSlot * temp_slot_1

WindowAggState * winstate

WindowFuncExprState * wfuncstate

void ReleaseSysCache(HeapTuple tuple)

HeapTuple SearchSysCache1(int cacheId, Datum key1)

Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)

bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)

void tuplestore_puttupleslot(Tuplestorestate *state, TupleTableSlot *slot)

void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)

void tuplestore_clear(Tuplestorestate *state)

int tuplestore_alloc_read_pointer(Tuplestorestate *state, int eflags)

Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)

void tuplestore_trim(Tuplestorestate *state)

bool tuplestore_advance(Tuplestorestate *state, bool forward)

bool tuplestore_in_memory(Tuplestorestate *state)

void tuplestore_end(Tuplestorestate *state)

void tuplestore_set_eflags(Tuplestorestate *state, int eflags)

bool tuplestore_skiptuples(Tuplestorestate *state, int64 ntuples, bool forward)

static Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)

static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)

static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)

#define WindowObjectIsValid(winobj)

#define WINDOW_SEEK_CURRENT