|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.195 2008/05/12 20:02:00 alvherre Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.196 2008/06/01 17:32:48 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -36,6 +36,10 @@ static int_SPI_stack_depth = 0;/* allocated size of _SPI_stack */
|
36 | 36 | staticint_SPI_connected=-1;
|
37 | 37 | staticint_SPI_curid=-1;
|
38 | 38 |
|
| 39 | +staticPortalSPI_cursor_open_internal(constchar*name,SPIPlanPtrplan, |
| 40 | +Datum*Values,constchar*Nulls, |
| 41 | +boolread_only,intpflags); |
| 42 | + |
39 | 43 | staticvoid_SPI_prepare_plan(constchar*src,SPIPlanPtrplan,
|
40 | 44 | ParamListInfoboundParams);
|
41 | 45 |
|
@@ -916,6 +920,80 @@ Portal
|
916 | 920 | SPI_cursor_open(constchar*name,SPIPlanPtrplan,
|
917 | 921 | Datum*Values,constchar*Nulls,
|
918 | 922 | boolread_only)
|
| 923 | +{ |
| 924 | +returnSPI_cursor_open_internal(name,plan,Values,Nulls, |
| 925 | +read_only,0); |
| 926 | +} |
| 927 | + |
| 928 | + |
| 929 | +/* |
| 930 | + * SPI_cursor_open_with_args() |
| 931 | + * |
| 932 | + * Parse and plan a query and open it as a portal. Like SPI_execute_with_args, |
| 933 | + * we can tell the planner to rely on the parameter values as constants, |
| 934 | + * because the plan will only be used once. |
| 935 | + */ |
| 936 | +Portal |
| 937 | +SPI_cursor_open_with_args(constchar*name, |
| 938 | +constchar*src, |
| 939 | +intnargs,Oid*argtypes, |
| 940 | +Datum*Values,constchar*Nulls, |
| 941 | +boolread_only,intcursorOptions) |
| 942 | +{ |
| 943 | +Portalresult; |
| 944 | +_SPI_planplan; |
| 945 | +ParamListInfoparamLI; |
| 946 | + |
| 947 | +if (src==NULL||nargs<0) |
| 948 | +elog(ERROR,"SPI_cursor_open_with_args called with invalid arguments"); |
| 949 | + |
| 950 | +if (nargs>0&& (argtypes==NULL||Values==NULL)) |
| 951 | +elog(ERROR,"SPI_cursor_open_with_args called with missing parameters"); |
| 952 | + |
| 953 | +SPI_result=_SPI_begin_call(true); |
| 954 | +if (SPI_result<0) |
| 955 | +elog(ERROR,"SPI_cursor_open_with_args called while not connected"); |
| 956 | + |
| 957 | +memset(&plan,0,sizeof(_SPI_plan)); |
| 958 | +plan.magic=_SPI_PLAN_MAGIC; |
| 959 | +plan.cursor_options=cursorOptions; |
| 960 | +plan.nargs=nargs; |
| 961 | +plan.argtypes=argtypes; |
| 962 | + |
| 963 | +paramLI=_SPI_convert_params(nargs,argtypes, |
| 964 | +Values,Nulls, |
| 965 | +PARAM_FLAG_CONST); |
| 966 | + |
| 967 | +_SPI_prepare_plan(src,&plan,paramLI); |
| 968 | + |
| 969 | +/* We needn't copy the plan; SPI_cursor_open_internal will do so */ |
| 970 | + |
| 971 | +/* Adjust stack so that SPI_cursor_open_internal doesn't complain */ |
| 972 | +_SPI_curid--; |
| 973 | + |
| 974 | +/* SPI_cursor_open_internal must be called in procedure memory context */ |
| 975 | +_SPI_procmem(); |
| 976 | + |
| 977 | +result=SPI_cursor_open_internal(name,&plan,Values,Nulls, |
| 978 | +read_only,PARAM_FLAG_CONST); |
| 979 | + |
| 980 | +/* And clean up */ |
| 981 | +_SPI_curid++; |
| 982 | +_SPI_end_call(true); |
| 983 | + |
| 984 | +returnresult; |
| 985 | +} |
| 986 | + |
| 987 | + |
| 988 | +/* |
| 989 | + * SPI_cursor_open_internal() |
| 990 | + * |
| 991 | + *Common code for SPI_cursor_open and SPI_cursor_open_with_args |
| 992 | + */ |
| 993 | +staticPortal |
| 994 | +SPI_cursor_open_internal(constchar*name,SPIPlanPtrplan, |
| 995 | +Datum*Values,constchar*Nulls, |
| 996 | +boolread_only,intpflags) |
919 | 997 | {
|
920 | 998 | CachedPlanSource*plansource;
|
921 | 999 | CachedPlan*cplan;
|
@@ -997,7 +1075,7 @@ SPI_cursor_open(const char *name, SPIPlanPtr plan,
|
997 | 1075 | ParamExternData*prm=¶mLI->params[k];
|
998 | 1076 |
|
999 | 1077 | prm->ptype=plan->argtypes[k];
|
1000 |
| -prm->pflags=0; |
| 1078 | +prm->pflags=pflags; |
1001 | 1079 | prm->isnull= (Nulls&&Nulls[k]=='n');
|
1002 | 1080 | if (prm->isnull)
|
1003 | 1081 | {
|
@@ -1129,64 +1207,6 @@ SPI_cursor_open(const char *name, SPIPlanPtr plan,
|
1129 | 1207 | }
|
1130 | 1208 |
|
1131 | 1209 |
|
1132 |
| -/* |
1133 |
| - * SPI_cursor_open_with_args() |
1134 |
| - * |
1135 |
| - * Parse and plan a query and open it as a portal. Like SPI_execute_with_args, |
1136 |
| - * we can tell the planner to rely on the parameter values as constants, |
1137 |
| - * because the plan will only be used once. |
1138 |
| - */ |
1139 |
| -Portal |
1140 |
| -SPI_cursor_open_with_args(constchar*name, |
1141 |
| -constchar*src, |
1142 |
| -intnargs,Oid*argtypes, |
1143 |
| -Datum*Values,constchar*Nulls, |
1144 |
| -boolread_only,intcursorOptions) |
1145 |
| -{ |
1146 |
| -Portalresult; |
1147 |
| -_SPI_planplan; |
1148 |
| -ParamListInfoparamLI; |
1149 |
| - |
1150 |
| -if (src==NULL||nargs<0) |
1151 |
| -elog(ERROR,"SPI_cursor_open_with_args called with invalid arguments"); |
1152 |
| - |
1153 |
| -if (nargs>0&& (argtypes==NULL||Values==NULL)) |
1154 |
| -elog(ERROR,"SPI_cursor_open_with_args called with missing parameters"); |
1155 |
| - |
1156 |
| -SPI_result=_SPI_begin_call(true); |
1157 |
| -if (SPI_result<0) |
1158 |
| -elog(ERROR,"SPI_cursor_open_with_args called while not connected"); |
1159 |
| - |
1160 |
| -memset(&plan,0,sizeof(_SPI_plan)); |
1161 |
| -plan.magic=_SPI_PLAN_MAGIC; |
1162 |
| -plan.cursor_options=cursorOptions; |
1163 |
| -plan.nargs=nargs; |
1164 |
| -plan.argtypes=argtypes; |
1165 |
| - |
1166 |
| -paramLI=_SPI_convert_params(nargs,argtypes, |
1167 |
| -Values,Nulls, |
1168 |
| -PARAM_FLAG_CONST); |
1169 |
| - |
1170 |
| -_SPI_prepare_plan(src,&plan,paramLI); |
1171 |
| - |
1172 |
| -/* We needn't copy the plan; SPI_cursor_open will do so */ |
1173 |
| - |
1174 |
| -/* Adjust stack so that SPI_cursor_open doesn't complain */ |
1175 |
| -_SPI_curid--; |
1176 |
| - |
1177 |
| -/* SPI_cursor_open expects to be called in procedure memory context */ |
1178 |
| -_SPI_procmem(); |
1179 |
| - |
1180 |
| -result=SPI_cursor_open(name,&plan,Values,Nulls,read_only); |
1181 |
| - |
1182 |
| -/* And clean up */ |
1183 |
| -_SPI_curid++; |
1184 |
| -_SPI_end_call(true); |
1185 |
| - |
1186 |
| -returnresult; |
1187 |
| -} |
1188 |
| - |
1189 |
| - |
1190 | 1210 | /*
|
1191 | 1211 | * SPI_cursor_find()
|
1192 | 1212 | *
|
|