|
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 | * |
|