Commit a48ec6f
committed
Support outer references in reduce() fold bodies
Allow a reduce(acc = init, var IN list | body) fold body to reference
loop-invariant values from the enclosing query -- outer-query variables and
cypher() parameters -- in addition to the accumulator and element. These were
previously rejected with ERRCODE_FEATURE_NOT_SUPPORTED.
How it works
------------
The fold body is still compiled to a standalone expression evaluated by
age_reduce_transfn, so an outer reference (which cannot be evaluated there)
is captured at transform time and supplied as a value:
- After the accumulator and element are rewritten to PARAM_EXEC params 0 and
1, transform_cypher_reduce() walks the body and replaces each maximal
agtype-typed, loop-invariant subtree -- one that references an outer Var or
a cypher() $parameter but not the accumulator/element -- with a new
PARAM_EXEC param 2, 3, ... in body order.
- The captured expressions are passed to the aggregate as a trailing
agtype[] argument; age_reduce(agtype, text, agtype, agtype[]) and its
transition function gain this argument.
- age_reduce_transfn sizes its param array to 2 + the number of captures and
binds the captured values to params 2.. on every row. Because the captures
are evaluated in the outer query context as ordinary aggregate arguments, a
correlated capture is re-evaluated per group, so an outer value that varies
per row (for example under UNWIND) is folded with the correct value.
This keeps the no-core-patch design: the body is still a serialized standalone
expression, and the only new machinery is the captured-value plumbing.
Still rejected
--------------
Subqueries in the body (including a nested reduce()) and aggregate functions
remain unsupported and raise a clean ERRCODE_FEATURE_NOT_SUPPORTED error: a
subquery cannot be planned as a plain aggregate argument, and an aggregate in a
per-element fold is undefined per the openCypher specification.
Tests
-----
age_reduce gains an "Outer references in the fold body" section covering a
plain outer variable, an outer variable used as a multiplier, two distinct
outer variables, a property of an outer graph variable, the same outer variable
referenced more than once, a property of an outer map, a subexpression that
mixes an outer reference with the element (only the loop-invariant part is
captured), an outer reference inside a CASE branch of the body, a NULL outer
value propagating through the fold, multiple captures mixing a NULL and a
non-NULL outer value, an outer variable that changes per row (captured per
group), and a cypher() parameter supplied via a prepared statement. The
previously-rejected outer-variable case is moved out of the not-supported
section, which now covers a nested reduce() (any subquery in the body is
unsupported) and an aggregate in the body.
The same change also broadens the base reduce() coverage with value-type folds
(a float accumulator, negative numbers, a map accumulator passed through
unchanged, and list elements indexed in the body), function calls in the fold
body (a scalar function over the element and the list itself produced by a
function), reduce() composed with surrounding expressions (consumed by another
function and used in a comparison), and syntax-error checks for each required
piece of the form -- the "= init", ", var IN list", and "| body" clauses, plus
a rejected qualified iterator variable. 42/42 installcheck pass.
Co-authored-by: Copilot <copilot@github.com>
modified: age--1.7.0--y.y.y.sql
modified: regress/expected/age_reduce.out
modified: regress/sql/age_reduce.sql
modified: sql/age_aggregate.sql
modified: src/backend/parser/cypher_clause.c
modified: src/backend/utils/adt/agtype.c1 parent 92e48e9 commit a48ec6f
6 files changed
Lines changed: 738 additions & 51 deletions
File tree
- regress
- expected
- sql
- sql
- src/backend
- parser
- utils/adt
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1107 | 1107 | | |
1108 | 1108 | | |
1109 | 1109 | | |
1110 | | - | |
1111 | | - | |
1112 | | - | |
| 1110 | + | |
| 1111 | + | |
| 1112 | + | |
| 1113 | + | |
| 1114 | + | |
| 1115 | + | |
1113 | 1116 | | |
1114 | 1117 | | |
1115 | 1118 | | |
1116 | 1119 | | |
1117 | 1120 | | |
1118 | 1121 | | |
1119 | | - | |
1120 | | - | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
1121 | 1125 | | |
1122 | 1126 | | |
1123 | 1127 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
222 | 222 | | |
223 | 223 | | |
224 | 224 | | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 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 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
225 | 306 | | |
226 | 307 | | |
227 | 308 | | |
| |||
484 | 565 | | |
485 | 566 | | |
486 | 567 | | |
487 | | - | |
| 568 | + | |
488 | 569 | | |
489 | | - | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
490 | 573 | | |
491 | 574 | | |
492 | | - | |
| 575 | + | |
493 | 576 | | |
494 | | - | |
495 | | - | |
496 | | - | |
497 | | - | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
498 | 691 | | |
499 | 692 | | |
500 | 693 | | |
| |||
509 | 702 | | |
510 | 703 | | |
511 | 704 | | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 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 | + | |
512 | 756 | | |
513 | 757 | | |
514 | 758 | | |
| |||
0 commit comments