MCPcopy Create free account
hub / github.com/apache/cloudberry / checkWellFormedRecursion

Function checkWellFormedRecursion

src/backend/parser/parse_cte.c:849–943  ·  view source on GitHub ↗

* Check that recursive queries are well-formed. */

Source from the content-addressed store, hash-verified

847 * Check that recursive queries are well-formed.
848 */
849static void
850checkWellFormedRecursion(CteState *cstate)
851{
852 int i;
853
854 for (i = 0; i < cstate->numitems; i++)
855 {
856 CommonTableExpr *cte = cstate->items[i].cte;
857 SelectStmt *stmt = (SelectStmt *) cte->ctequery;
858
859 Assert(!IsA(stmt, Query)); /* not analyzed yet */
860
861 /* Ignore items that weren't found to be recursive */
862 if (!cte->cterecursive)
863 continue;
864
865 /* Must be a SELECT statement */
866 if (!IsA(stmt, SelectStmt))
867 ereport(ERROR,
868 (errcode(ERRCODE_INVALID_RECURSION),
869 errmsg("recursive query \"%s\" must not contain data-modifying statements",
870 cte->ctename),
871 parser_errposition(cstate->pstate, cte->location)));
872
873 /* Must have top-level UNION */
874 if (stmt->op != SETOP_UNION)
875 ereport(ERROR,
876 (errcode(ERRCODE_INVALID_RECURSION),
877 errmsg("recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term",
878 cte->ctename),
879 parser_errposition(cstate->pstate, cte->location)));
880
881 /* The left-hand operand mustn't contain self-reference at all */
882 cstate->curitem = i;
883 cstate->innerwiths = NIL;
884 cstate->selfrefcount = 0;
885 cstate->context = RECURSION_NONRECURSIVETERM;
886 checkWellFormedRecursionWalker((Node *) stmt->larg, cstate);
887 Assert(cstate->innerwiths == NIL);
888
889 /* Right-hand operand should contain one reference in a valid place */
890 cstate->curitem = i;
891 cstate->innerwiths = NIL;
892 cstate->selfrefcount = 0;
893 cstate->context = RECURSION_OK;
894 checkWellFormedRecursionWalker((Node *) stmt->rarg, cstate);
895 Assert(cstate->innerwiths == NIL);
896 if (cstate->selfrefcount != 1) /* shouldn't happen */
897 elog(ERROR, "missing recursive reference");
898
899 /* WITH mustn't contain self-reference, either */
900 if (stmt->withClause)
901 {
902 cstate->curitem = i;
903 cstate->innerwiths = NIL;
904 cstate->selfrefcount = 0;
905 cstate->context = RECURSION_SUBLINK;
906 checkWellFormedRecursionWalker((Node *) stmt->withClause->ctes,

Callers 1

transformWithClauseFunction · 0.85

Calls 5

parser_errpositionFunction · 0.85
exprLocationFunction · 0.85
errcodeFunction · 0.50
errmsgFunction · 0.50

Tested by

no test coverage detected