aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execAmi.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-03-10 03:53:52 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-03-10 03:53:52 +0000
commitaa83bc04e089e13f2746ba55720e5993268c46f5 (patch)
tree1b5c0082e22385789d3581792af4e1a823f835ba /src/backend/executor/execAmi.c
parentb9e8ffcd5d1a3d45b2f697ea944931f56367c86b (diff)
downloadpostgresql-aa83bc04e089e13f2746ba55720e5993268c46f5.tar.gz
postgresql-aa83bc04e089e13f2746ba55720e5993268c46f5.zip
Restructure parsetree representation of DECLARE CURSOR: now it's a
utility statement (DeclareCursorStmt) with a SELECT query dangling from it, rather than a SELECT query with a few unusual fields in it. Add code to determine whether a planned query can safely be run backwards. If DECLARE CURSOR specifies SCROLL, ensure that the plan can be run backwards by adding a Materialize plan node if it can't. Without SCROLL, you get an error if you try to fetch backwards from a cursor that can't handle it. (There is still some discussion about what the exact behavior should be, but this is necessary infrastructure in any case.) Along the way, make EXPLAIN DECLARE CURSOR work.
Diffstat (limited to 'src/backend/executor/execAmi.c')
-rw-r--r--src/backend/executor/execAmi.c60
1 files changed, 59 insertions, 1 deletions
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c
index b22ad763498..b189e3e94bc 100644
--- a/src/backend/executor/execAmi.c
+++ b/src/backend/executor/execAmi.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.69 2003/02/09 00:30:39 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.70 2003/03/10 03:53:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -281,3 +281,61 @@ ExecSupportsMarkRestore(NodeTag plantype)
return false;
}
+
+/*
+ * ExecSupportsBackwardScan - does a plan type support backwards scanning?
+ *
+ * Ideally, all plan types would support backwards scan, but that seems
+ * unlikely to happen soon. In some cases, a plan node passes the backwards
+ * scan down to its children, and so supports backwards scan only if its
+ * children do. Therefore, this routine must be passed a complete plan tree.
+ */
+bool
+ExecSupportsBackwardScan(Plan *node)
+{
+ if (node == NULL)
+ return false;
+
+ switch (nodeTag(node))
+ {
+ case T_Result:
+ if (outerPlan(node) != NULL)
+ return ExecSupportsBackwardScan(outerPlan(node));
+ else
+ return false;
+
+ case T_Append:
+ {
+ List *l;
+
+ foreach(l, ((Append *) node)->appendplans)
+ {
+ if (!ExecSupportsBackwardScan((Plan *) lfirst(l)))
+ return false;
+ }
+ return true;
+ }
+
+ case T_SeqScan:
+ case T_IndexScan:
+ case T_TidScan:
+ case T_FunctionScan:
+ return true;
+
+ case T_SubqueryScan:
+ return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan);
+
+ case T_Material:
+ case T_Sort:
+ return true;
+
+ case T_Unique:
+ return ExecSupportsBackwardScan(outerPlan(node));
+
+ case T_Limit:
+ return ExecSupportsBackwardScan(outerPlan(node));
+
+ default:
+ return false;
+ }
+}