Index: contrib/dblink/dblink.c =================================================================== RCS file: /projects/cvsroot/pgsql/contrib/dblink/dblink.c,v retrieving revision 1.70 diff -c -c -r1.70 dblink.c *** contrib/dblink/dblink.c 25 Mar 2008 22:42:41 -0000 1.70 --- contrib/dblink/dblink.c 25 Mar 2008 23:24:42 -0000 *************** *** 752,757 **** --- 752,758 ---- char *conname = NULL; remoteConn *rconn = NULL; bool fail = true; /* default to backward compatible */ + ReturnSetInfo *rsi; /* create a function context for cross-call persistence */ funcctx = SRF_FIRSTCALL_INIT(); *************** *** 826,831 **** --- 827,843 ---- elog(ERROR, "wrong number of arguments"); } + if (sql && rsi->qual) + { + char *quals = rsinfo_get_qual_str(rsi); + char *qualifiedQuery = palloc(strlen(sql) + strlen(" WHERE ") + + strlen(quals) + 1); + + sprintf(qualifiedQuery, "%s WHERE %s", sql, quals); + + sql = qualifiedQuery; + } + if (!conn) DBLINK_CONN_NOT_AVAIL; Index: src/backend/executor/execQual.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/executor/execQual.c,v retrieving revision 1.228 diff -c -c -r1.228 execQual.c *** src/backend/executor/execQual.c 25 Mar 2008 22:42:43 -0000 1.228 --- src/backend/executor/execQual.c 25 Mar 2008 23:24:43 -0000 *************** *** 45,50 **** --- 45,51 ---- #include "funcapi.h" #include "miscadmin.h" #include "nodes/makefuncs.h" + #include "optimizer/clauses.h" #include "optimizer/planmain.h" #include "parser/parse_expr.h" #include "utils/acl.h" *************** *** 1415,1420 **** --- 1416,1440 ---- return result; } + /* + * + * Get either an empty string or a batch of qualifiers. + * + */ + char * + rsinfo_get_qual_str(ReturnSetInfo *rsinfo) + { + Node *qual; + List *context; + + if (rsinfo->qual == NIL) + return pstrdup(""); + + qual = (Node *) make_ands_explicit(rsinfo->qual); + context = deparse_context_for_plan(NULL, NULL, rsinfo->rtable); + + return deparse_expression(qual, context, false, false); + } /* * ExecMakeTableFunctionResult *************** *** 1426,1431 **** --- 1446,1452 ---- Tuplestorestate * ExecMakeTableFunctionResult(ExprState *funcexpr, ExprContext *econtext, + List *qual, List *rtable, TupleDesc expectedDesc, TupleDesc *returnDesc) { *************** *** 1458,1463 **** --- 1479,1486 ---- InitFunctionCallInfoData(fcinfo, NULL, 0, NULL, (Node *) &rsinfo); rsinfo.type = T_ReturnSetInfo; rsinfo.econtext = econtext; + rsinfo.qual = qual; + rsinfo.rtable = rtable; rsinfo.expectedDesc = expectedDesc; rsinfo.allowedModes = (int) (SFRM_ValuePerCall | SFRM_Materialize); rsinfo.returnMode = SFRM_ValuePerCall; Index: src/backend/executor/nodeFunctionscan.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/executor/nodeFunctionscan.c,v retrieving revision 1.46 diff -c -c -r1.46 nodeFunctionscan.c *** src/backend/executor/nodeFunctionscan.c 29 Feb 2008 02:49:39 -0000 1.46 --- src/backend/executor/nodeFunctionscan.c 25 Mar 2008 23:24:43 -0000 *************** *** 68,73 **** --- 68,75 ---- node->tuplestorestate = tuplestorestate = ExecMakeTableFunctionResult(node->funcexpr, econtext, + node->ss.ps.plan->qual, + estate->es_range_table, node->tupdesc, &funcTupdesc); Index: src/include/executor/executor.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/executor/executor.h,v retrieving revision 1.146 diff -c -c -r1.146 executor.h *** src/include/executor/executor.h 1 Jan 2008 19:45:57 -0000 1.146 --- src/include/executor/executor.h 25 Mar 2008 23:24:43 -0000 *************** *** 171,176 **** --- 171,177 ---- ExprDoneCond *isDone); extern Tuplestorestate *ExecMakeTableFunctionResult(ExprState *funcexpr, ExprContext *econtext, + List *qual, List *rtable, TupleDesc expectedDesc, TupleDesc *returnDesc); extern Datum ExecEvalExprSwitchContext(ExprState *expression, ExprContext *econtext, *************** *** 182,187 **** --- 183,189 ---- extern int ExecCleanTargetListLength(List *targetlist); extern TupleTableSlot *ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone); + extern char *rsinfo_get_qual_str(ReturnSetInfo *rsinfo); /* * prototypes from functions in execScan.c Index: src/include/nodes/execnodes.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/nodes/execnodes.h,v retrieving revision 1.183 diff -c -c -r1.183 execnodes.h *** src/include/nodes/execnodes.h 1 Jan 2008 19:45:58 -0000 1.183 --- src/include/nodes/execnodes.h 25 Mar 2008 23:24:44 -0000 *************** *** 168,173 **** --- 168,175 ---- ExprContext *econtext; /* context function is being called in */ TupleDesc expectedDesc; /* tuple descriptor expected by caller */ int allowedModes; /* bitmask: return modes caller can handle */ + List *qual; /* any quals to be applied to result */ + List *rtable; /* result status from function (but pre-initialized by caller): */ SetFunctionReturnMode returnMode; /* actual return mode */ ExprDoneCond isDone; /* status for ValuePerCall mode */ Index: src/pl/plperl/plperl.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/pl/plperl/plperl.c,v retrieving revision 1.138 diff -c -c -r1.138 plperl.c *** src/pl/plperl/plperl.c 25 Mar 2008 22:42:45 -0000 1.138 --- src/pl/plperl/plperl.c 25 Mar 2008 23:24:44 -0000 *************** *** 1048,1060 **** int i; int count; SV *sv; ENTER; SAVETMPS; PUSHMARK(SP); ! XPUSHs(&PL_sv_undef); /* no trigger data */ for (i = 0; i < desc->nargs; i++) { --- 1048,1073 ---- int i; int count; SV *sv; + HV *hv; ENTER; SAVETMPS; PUSHMARK(SP); ! if (fcinfo->resultinfo && ((ReturnSetInfo *)fcinfo->resultinfo)->qual) ! { ! ReturnSetInfo *rsi = (ReturnSetInfo *)fcinfo->resultinfo; ! HV *hv = newHV(); ! ! hv_store_string(hv, "_quals", newSVstring(rsinfo_get_qual_str(rsi))); ! ! XPUSHs(newRV_noinc((SV *)hv)); ! } ! else ! { ! XPUSHs(&PL_sv_undef); /* no trigger or qual data */ ! } for (i = 0; i < desc->nargs; i++) {