Merge lp:~ubuntu-branches/ubuntu/oneiric/postgresql-pljava/oneiric-201109061811 into lp:ubuntu/oneiric/postgresql-pljava
- Oneiric (11.10)
- oneiric-201109061811
- Merge into oneiric
Status: | Rejected |
---|---|
Rejected by: | Martin Pitt |
Proposed branch: | lp:~ubuntu-branches/ubuntu/oneiric/postgresql-pljava/oneiric-201109061811 |
Merge into: | lp:ubuntu/oneiric/postgresql-pljava |
Diff against target: |
1026 lines (+1009/-0) (has conflicts) 2 files modified
.pc/9.1_api.patch/src/C/pljava/Backend.c (+935/-0) debian/patches/9.1_api.patch (+74/-0) Conflict adding file .pc/9.1_api.patch. Moved existing file to .pc/9.1_api.patch.moved. Conflict adding file debian/patches/9.1_api.patch. Moved existing file to debian/patches/9.1_api.patch.moved. |
To merge this branch: | bzr merge lp:~ubuntu-branches/ubuntu/oneiric/postgresql-pljava/oneiric-201109061811 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Didier Roche-Tolomelli | Disapprove | ||
Ubuntu branches | Pending | ||
Review via email: mp+74276@code.launchpad.net |
Commit message
Description of the change
The package importer has detected a possible inconsistency between the package history in the archve and the history in bzr. As the archive is authoritative the importer has made lp:ubuntu/oneiric/postgresql-pljava reflect what is in the archive and the old bzr branch has been pushed to lp:~ubuntu-branches/ubuntu/oneiric/postgresql-pljava/oneiric-201109061811. This merge proposal was created so that an Ubuntu developer can review the situations and perform a merge/upload if necessary. There are three typical cases where this can happen.
1. Where someone pushes a change to bzr and someone else uploads the package without that change. This is the reason that this check is done by the importer. If this appears to be the case then a merge/upload should be done if the changes that were in bzr are still desirable.
2. The importer incorrectly detected the above situation when someone made a change in bzr and then uploaded it.
3. The importer incorrectly detected the above situation when someone just uploaded a package and didn't touch bzr.
If this case doesn't appear to be the first situation then set the status of the merge proposal to "Rejected" and help avoid the problem in future by filing a bug at https:/
(this is an automatically generated message)
Unmerged revisions
- 10. By Martin Pitt
-
releasing version 1.4.2-4ubuntu1
- 9. By Martin Pitt
-
Add 9.1_api.patch: Port to 9.1 API.
- 8. By Martin Pitt
-
debian/pgversions: Build for 9.1 only. Regenerate debian/control.
Preview Diff
1 | === added directory '.pc/9.1_api.patch' | |||
2 | === renamed directory '.pc/9.1_api.patch' => '.pc/9.1_api.patch.moved' | |||
3 | === added file '.pc/9.1_api.patch/.timestamp' | |||
4 | === added directory '.pc/9.1_api.patch/src' | |||
5 | === added directory '.pc/9.1_api.patch/src/C' | |||
6 | === added directory '.pc/9.1_api.patch/src/C/pljava' | |||
7 | === added file '.pc/9.1_api.patch/src/C/pljava/Backend.c' | |||
8 | --- .pc/9.1_api.patch/src/C/pljava/Backend.c 1970-01-01 00:00:00 +0000 | |||
9 | +++ .pc/9.1_api.patch/src/C/pljava/Backend.c 2011-09-06 19:13:35 +0000 | |||
10 | @@ -0,0 +1,935 @@ | |||
11 | 1 | /* | ||
12 | 2 | * Copyright (c) 2004, 2005, 2006 TADA AB - Taby Sweden | ||
13 | 3 | * Distributed under the terms shown in the file COPYRIGHT | ||
14 | 4 | * found in the root folder of this project or at | ||
15 | 5 | * http://eng.tada.se/osprojects/COPYRIGHT.html | ||
16 | 6 | * | ||
17 | 7 | * @author Thomas Hallgren | ||
18 | 8 | */ | ||
19 | 9 | #include <postgres.h> | ||
20 | 10 | #include <miscadmin.h> | ||
21 | 11 | #ifndef WIN32 | ||
22 | 12 | #include <libpq/pqsignal.h> | ||
23 | 13 | #endif | ||
24 | 14 | #include <executor/spi.h> | ||
25 | 15 | #include <commands/trigger.h> | ||
26 | 16 | #include <utils/elog.h> | ||
27 | 17 | #include <utils/guc.h> | ||
28 | 18 | #include <fmgr.h> | ||
29 | 19 | #include <access/heapam.h> | ||
30 | 20 | #include <utils/syscache.h> | ||
31 | 21 | #include <catalog/catalog.h> | ||
32 | 22 | #include <catalog/pg_proc.h> | ||
33 | 23 | #include <catalog/pg_type.h> | ||
34 | 24 | #include <storage/ipc.h> | ||
35 | 25 | #include <storage/proc.h> | ||
36 | 26 | #include <stdio.h> | ||
37 | 27 | #include <ctype.h> | ||
38 | 28 | #include <unistd.h> | ||
39 | 29 | |||
40 | 30 | #include "org_postgresql_pljava_internal_Backend.h" | ||
41 | 31 | #include "pljava/Invocation.h" | ||
42 | 32 | #include "pljava/Function.h" | ||
43 | 33 | #include "pljava/HashMap.h" | ||
44 | 34 | #include "pljava/Exception.h" | ||
45 | 35 | #include "pljava/Backend.h" | ||
46 | 36 | #include "pljava/Session.h" | ||
47 | 37 | #include "pljava/SPI.h" | ||
48 | 38 | #include "pljava/type/String.h" | ||
49 | 39 | /* Example format: "/usr/local/pgsql/lib" */ | ||
50 | 40 | #ifndef PKGLIBDIR | ||
51 | 41 | #error "PKGLIBDIR needs to be defined to compile this file." | ||
52 | 42 | #endif | ||
53 | 43 | |||
54 | 44 | /* Include the 'magic block' that PostgreSQL 8.2 and up will use to ensure | ||
55 | 45 | * that a module is not loaded into an incompatible server. | ||
56 | 46 | */ | ||
57 | 47 | #ifdef PG_MODULE_MAGIC | ||
58 | 48 | PG_MODULE_MAGIC; | ||
59 | 49 | #endif | ||
60 | 50 | |||
61 | 51 | #define LOCAL_REFERENCE_COUNT 128 | ||
62 | 52 | |||
63 | 53 | jlong mainThreadId; | ||
64 | 54 | |||
65 | 55 | static JavaVM* s_javaVM = 0; | ||
66 | 56 | static jclass s_Backend_class; | ||
67 | 57 | static jmethodID s_setTrusted; | ||
68 | 58 | static char* vmoptions; | ||
69 | 59 | static char* classpath; | ||
70 | 60 | static int statementCacheSize; | ||
71 | 61 | static bool pljavaDebug; | ||
72 | 62 | static bool pljavaReleaseLingeringSavepoints; | ||
73 | 63 | static bool s_currentTrust; | ||
74 | 64 | static int s_javaLogLevel; | ||
75 | 65 | |||
76 | 66 | bool integerDateTimes = false; | ||
77 | 67 | |||
78 | 68 | extern void Invocation_initialize(void); | ||
79 | 69 | extern void Exception_initialize(void); | ||
80 | 70 | extern void Exception_initialize2(void); | ||
81 | 71 | extern void HashMap_initialize(void); | ||
82 | 72 | extern void SPI_initialize(void); | ||
83 | 73 | extern void Type_initialize(void); | ||
84 | 74 | extern void Function_initialize(void); | ||
85 | 75 | extern void Session_initialize(void); | ||
86 | 76 | extern void PgSavepoint_initialize(void); | ||
87 | 77 | extern void XactListener_initialize(void); | ||
88 | 78 | extern void SubXactListener_initialize(void); | ||
89 | 79 | extern void SQLInputFromChunk_initialize(void); | ||
90 | 80 | extern void SQLOutputToChunk_initialize(void); | ||
91 | 81 | extern void SQLInputFromTuple_initialize(void); | ||
92 | 82 | extern void SQLOutputToTuple_initialize(void); | ||
93 | 83 | |||
94 | 84 | static void initPLJavaClasses(void) | ||
95 | 85 | { | ||
96 | 86 | jfieldID tlField; | ||
97 | 87 | JNINativeMethod backendMethods[] = | ||
98 | 88 | { | ||
99 | 89 | { | ||
100 | 90 | "isCallingJava", | ||
101 | 91 | "()Z", | ||
102 | 92 | Java_org_postgresql_pljava_internal_Backend_isCallingJava | ||
103 | 93 | }, | ||
104 | 94 | { | ||
105 | 95 | "isReleaseLingeringSavepoints", | ||
106 | 96 | "()Z", | ||
107 | 97 | Java_org_postgresql_pljava_internal_Backend_isReleaseLingeringSavepoints | ||
108 | 98 | }, | ||
109 | 99 | { | ||
110 | 100 | "_getConfigOption", | ||
111 | 101 | "(Ljava/lang/String;)Ljava/lang/String;", | ||
112 | 102 | Java_org_postgresql_pljava_internal_Backend__1getConfigOption | ||
113 | 103 | }, | ||
114 | 104 | { | ||
115 | 105 | "_getStatementCacheSize", | ||
116 | 106 | "()I", | ||
117 | 107 | Java_org_postgresql_pljava_internal_Backend__1getStatementCacheSize | ||
118 | 108 | }, | ||
119 | 109 | { | ||
120 | 110 | "_log", | ||
121 | 111 | "(ILjava/lang/String;)V", | ||
122 | 112 | Java_org_postgresql_pljava_internal_Backend__1log | ||
123 | 113 | }, | ||
124 | 114 | { | ||
125 | 115 | "_clearFunctionCache", | ||
126 | 116 | "()V", | ||
127 | 117 | Java_org_postgresql_pljava_internal_Backend__1clearFunctionCache | ||
128 | 118 | }, | ||
129 | 119 | { 0, 0, 0 } | ||
130 | 120 | }; | ||
131 | 121 | |||
132 | 122 | Exception_initialize(); | ||
133 | 123 | |||
134 | 124 | elog(DEBUG1, "Getting Backend class pljava.jar"); | ||
135 | 125 | s_Backend_class = PgObject_getJavaClass("org/postgresql/pljava/internal/Backend"); | ||
136 | 126 | elog(DEBUG1, "Backend class was there"); | ||
137 | 127 | PgObject_registerNatives2(s_Backend_class, backendMethods); | ||
138 | 128 | |||
139 | 129 | tlField = PgObject_getStaticJavaField(s_Backend_class, "THREADLOCK", "Ljava/lang/Object;"); | ||
140 | 130 | JNI_setThreadLock(JNI_getStaticObjectField(s_Backend_class, tlField)); | ||
141 | 131 | |||
142 | 132 | Invocation_initialize(); | ||
143 | 133 | Exception_initialize2(); | ||
144 | 134 | SPI_initialize(); | ||
145 | 135 | Type_initialize(); | ||
146 | 136 | Function_initialize(); | ||
147 | 137 | Session_initialize(); | ||
148 | 138 | PgSavepoint_initialize(); | ||
149 | 139 | XactListener_initialize(); | ||
150 | 140 | SubXactListener_initialize(); | ||
151 | 141 | SQLInputFromChunk_initialize(); | ||
152 | 142 | SQLOutputToChunk_initialize(); | ||
153 | 143 | SQLInputFromTuple_initialize(); | ||
154 | 144 | SQLOutputToTuple_initialize(); | ||
155 | 145 | |||
156 | 146 | s_setTrusted = PgObject_getStaticJavaMethod(s_Backend_class, "setTrusted", "(Z)V"); | ||
157 | 147 | } | ||
158 | 148 | |||
159 | 149 | /** | ||
160 | 150 | * Initialize security | ||
161 | 151 | */ | ||
162 | 152 | void Backend_setJavaSecurity(bool trusted) | ||
163 | 153 | { | ||
164 | 154 | if(trusted != s_currentTrust) | ||
165 | 155 | { | ||
166 | 156 | /* GCJ has major issues here. Real work on SecurityManager and | ||
167 | 157 | * related classes has just started in version 4.0.0. | ||
168 | 158 | */ | ||
169 | 159 | #ifndef GCJ | ||
170 | 160 | JNI_callStaticVoidMethod(s_Backend_class, s_setTrusted, (jboolean)trusted); | ||
171 | 161 | if(JNI_exceptionCheck()) | ||
172 | 162 | { | ||
173 | 163 | JNI_exceptionDescribe(); | ||
174 | 164 | JNI_exceptionClear(); | ||
175 | 165 | ereport(ERROR, ( | ||
176 | 166 | errcode(ERRCODE_INTERNAL_ERROR), | ||
177 | 167 | errmsg("Unable to initialize java security"))); | ||
178 | 168 | } | ||
179 | 169 | #endif | ||
180 | 170 | s_currentTrust = trusted; | ||
181 | 171 | } | ||
182 | 172 | } | ||
183 | 173 | |||
184 | 174 | int Backend_setJavaLogLevel(int logLevel) | ||
185 | 175 | { | ||
186 | 176 | int oldLevel = s_javaLogLevel; | ||
187 | 177 | s_javaLogLevel = logLevel; | ||
188 | 178 | return oldLevel; | ||
189 | 179 | } | ||
190 | 180 | |||
191 | 181 | /** | ||
192 | 182 | * Special purpose logging function called from JNI when verbose is enabled. | ||
193 | 183 | */ | ||
194 | 184 | static jint JNICALL my_vfprintf(FILE* fp, const char* format, va_list args) | ||
195 | 185 | { | ||
196 | 186 | char buf[1024]; | ||
197 | 187 | char* ep; | ||
198 | 188 | char* bp = buf; | ||
199 | 189 | |||
200 | 190 | vsnprintf(buf, sizeof(buf), format, args); | ||
201 | 191 | |||
202 | 192 | /* Trim off trailing newline and other whitespace. | ||
203 | 193 | */ | ||
204 | 194 | ep = bp + strlen(bp) - 1; | ||
205 | 195 | while(ep >= bp && isspace(*ep)) | ||
206 | 196 | --ep; | ||
207 | 197 | ++ep; | ||
208 | 198 | *ep = 0; | ||
209 | 199 | |||
210 | 200 | elog(s_javaLogLevel, buf); | ||
211 | 201 | return 0; | ||
212 | 202 | } | ||
213 | 203 | |||
214 | 204 | /* | ||
215 | 205 | * Append those parts of path that has not yet been appended. The HashMap unique is | ||
216 | 206 | * keeping track of what has been appended already. First appended part will be | ||
217 | 207 | * prefixed with prefix. | ||
218 | 208 | */ | ||
219 | 209 | static void appendPathParts(const char* path, StringInfoData* bld, HashMap unique, const char* prefix) | ||
220 | 210 | { | ||
221 | 211 | StringInfoData buf; | ||
222 | 212 | if(path == 0 || strlen(path) == 0) | ||
223 | 213 | return; | ||
224 | 214 | |||
225 | 215 | for (;;) | ||
226 | 216 | { | ||
227 | 217 | char* pathPart; | ||
228 | 218 | size_t len; | ||
229 | 219 | if(*path == 0) | ||
230 | 220 | break; | ||
231 | 221 | |||
232 | 222 | len = strcspn(path, ";:"); | ||
233 | 223 | |||
234 | 224 | if(len == 1 && *(path+1) == ':' && isalnum(*path)) | ||
235 | 225 | /* | ||
236 | 226 | * Windows drive designator, leave it "as is". | ||
237 | 227 | */ | ||
238 | 228 | len = strcspn(path+2, ";:") + 2; | ||
239 | 229 | else | ||
240 | 230 | if(len == 0) | ||
241 | 231 | { | ||
242 | 232 | /* Ignore zero length components. | ||
243 | 233 | */ | ||
244 | 234 | ++path; | ||
245 | 235 | continue; | ||
246 | 236 | } | ||
247 | 237 | |||
248 | 238 | initStringInfo(&buf); | ||
249 | 239 | if(*path == '$') | ||
250 | 240 | { | ||
251 | 241 | if(len == 7 || (strcspn(path, "/\\") == 7 && strncmp(path, "$libdir", 7) == 0)) | ||
252 | 242 | { | ||
253 | 243 | len -= 7; | ||
254 | 244 | path += 7; | ||
255 | 245 | appendStringInfo(&buf, PKGLIBDIR); | ||
256 | 246 | } | ||
257 | 247 | else | ||
258 | 248 | ereport(ERROR, ( | ||
259 | 249 | errcode(ERRCODE_INVALID_NAME), | ||
260 | 250 | errmsg("invalid macro name '%*s' in dynamic library path", (int)len, path))); | ||
261 | 251 | } | ||
262 | 252 | |||
263 | 253 | if(len > 0) | ||
264 | 254 | { | ||
265 | 255 | appendBinaryStringInfo(&buf, path, len); | ||
266 | 256 | path += len; | ||
267 | 257 | } | ||
268 | 258 | |||
269 | 259 | pathPart = buf.data; | ||
270 | 260 | if(HashMap_getByString(unique, pathPart) == 0) | ||
271 | 261 | { | ||
272 | 262 | if(HashMap_size(unique) == 0) | ||
273 | 263 | appendStringInfo(bld, prefix); | ||
274 | 264 | else | ||
275 | 265 | #if defined(WIN32) | ||
276 | 266 | appendStringInfoChar(bld, ';'); | ||
277 | 267 | #else | ||
278 | 268 | appendStringInfoChar(bld, ':'); | ||
279 | 269 | #endif | ||
280 | 270 | appendStringInfo(bld, pathPart); | ||
281 | 271 | HashMap_putByString(unique, pathPart, (void*)1); | ||
282 | 272 | } | ||
283 | 273 | pfree(pathPart); | ||
284 | 274 | if(*path == 0) | ||
285 | 275 | break; | ||
286 | 276 | ++path; /* Skip ':' */ | ||
287 | 277 | } | ||
288 | 278 | } | ||
289 | 279 | |||
290 | 280 | /* | ||
291 | 281 | * Get the CLASSPATH. Result is always freshly palloc'd. | ||
292 | 282 | */ | ||
293 | 283 | static char* getClassPath(const char* prefix) | ||
294 | 284 | { | ||
295 | 285 | char* path; | ||
296 | 286 | HashMap unique = HashMap_create(13, CurrentMemoryContext); | ||
297 | 287 | StringInfoData buf; | ||
298 | 288 | initStringInfo(&buf); | ||
299 | 289 | appendPathParts(classpath, &buf, unique, prefix); | ||
300 | 290 | appendPathParts(getenv("CLASSPATH"), &buf, unique, prefix); | ||
301 | 291 | PgObject_free((PgObject)unique); | ||
302 | 292 | path = buf.data; | ||
303 | 293 | if(strlen(path) == 0) | ||
304 | 294 | { | ||
305 | 295 | pfree(path); | ||
306 | 296 | path = 0; | ||
307 | 297 | } | ||
308 | 298 | return path; | ||
309 | 299 | } | ||
310 | 300 | |||
311 | 301 | #if !defined(WIN32) | ||
312 | 302 | |||
313 | 303 | static void pljavaStatementCancelHandler(int signum) | ||
314 | 304 | { | ||
315 | 305 | if(!proc_exit_inprogress) | ||
316 | 306 | { | ||
317 | 307 | /* Never service the interrupt immediately. In order to find out if | ||
318 | 308 | * its safe, we would need to know what kind of threading mechanism | ||
319 | 309 | * the VM uses. That would count for a lot of conditional code. | ||
320 | 310 | */ | ||
321 | 311 | QueryCancelPending = true; | ||
322 | 312 | InterruptPending = true; | ||
323 | 313 | } | ||
324 | 314 | } | ||
325 | 315 | |||
326 | 316 | static void pljavaDieHandler(int signum) | ||
327 | 317 | { | ||
328 | 318 | if(!proc_exit_inprogress) | ||
329 | 319 | { | ||
330 | 320 | /* Never service the interrupt immediately. In order to find out if | ||
331 | 321 | * its safe, we would need to know what kind of threading mechanism | ||
332 | 322 | * the VM uses. That would count for a lot of conditional code. | ||
333 | 323 | */ | ||
334 | 324 | ProcDiePending = true; | ||
335 | 325 | InterruptPending = true; | ||
336 | 326 | } | ||
337 | 327 | } | ||
338 | 328 | |||
339 | 329 | static void pljavaQuickDieHandler(int signum) | ||
340 | 330 | { | ||
341 | 331 | /* Just die. No ereporting here since we don't know what thread this is. | ||
342 | 332 | */ | ||
343 | 333 | exit(1); | ||
344 | 334 | } | ||
345 | 335 | |||
346 | 336 | static sigjmp_buf recoverBuf; | ||
347 | 337 | static void terminationTimeoutHandler(int signum) | ||
348 | 338 | { | ||
349 | 339 | kill(MyProcPid, SIGQUIT); | ||
350 | 340 | |||
351 | 341 | /* Some sleep to get the SIGQUIT a chance to generate | ||
352 | 342 | * the needed output. | ||
353 | 343 | */ | ||
354 | 344 | pg_usleep(1); | ||
355 | 345 | |||
356 | 346 | /* JavaVM did not die within the alloted time | ||
357 | 347 | */ | ||
358 | 348 | siglongjmp(recoverBuf, 1); | ||
359 | 349 | } | ||
360 | 350 | #endif | ||
361 | 351 | |||
362 | 352 | /* | ||
363 | 353 | * proc_exit callback to tear down the JVM | ||
364 | 354 | */ | ||
365 | 355 | static void _destroyJavaVM(int status, Datum dummy) | ||
366 | 356 | { | ||
367 | 357 | if(s_javaVM != 0) | ||
368 | 358 | { | ||
369 | 359 | Invocation ctx; | ||
370 | 360 | #if !defined(WIN32) | ||
371 | 361 | pqsigfunc saveSigAlrm; | ||
372 | 362 | |||
373 | 363 | Invocation_pushInvocation(&ctx, false); | ||
374 | 364 | if(sigsetjmp(recoverBuf, 1) != 0) | ||
375 | 365 | { | ||
376 | 366 | elog(DEBUG1, "JavaVM destroyed with force"); | ||
377 | 367 | s_javaVM = 0; | ||
378 | 368 | return; | ||
379 | 369 | } | ||
380 | 370 | |||
381 | 371 | saveSigAlrm = pqsignal(SIGALRM, terminationTimeoutHandler); | ||
382 | 372 | enable_sig_alarm(5000, false); | ||
383 | 373 | |||
384 | 374 | elog(DEBUG1, "Destroying JavaVM..."); | ||
385 | 375 | JNI_destroyVM(s_javaVM); | ||
386 | 376 | disable_sig_alarm(false); | ||
387 | 377 | pqsignal(SIGALRM, saveSigAlrm); | ||
388 | 378 | #else | ||
389 | 379 | Invocation_pushInvocation(&ctx, false); | ||
390 | 380 | elog(DEBUG1, "Destroying JavaVM..."); | ||
391 | 381 | JNI_destroyVM(s_javaVM); | ||
392 | 382 | #endif | ||
393 | 383 | elog(DEBUG1, "JavaVM destroyed"); | ||
394 | 384 | s_javaVM = 0; | ||
395 | 385 | currentInvocation = 0; | ||
396 | 386 | } | ||
397 | 387 | } | ||
398 | 388 | |||
399 | 389 | typedef struct { | ||
400 | 390 | JavaVMOption* options; | ||
401 | 391 | unsigned int size; | ||
402 | 392 | unsigned int capacity; | ||
403 | 393 | } JVMOptList; | ||
404 | 394 | |||
405 | 395 | static void JVMOptList_init(JVMOptList* jol) | ||
406 | 396 | { | ||
407 | 397 | jol->options = (JavaVMOption*)palloc(10 * sizeof(JavaVMOption)); | ||
408 | 398 | jol->size = 0; | ||
409 | 399 | jol->capacity = 10; | ||
410 | 400 | } | ||
411 | 401 | |||
412 | 402 | static void JVMOptList_delete(JVMOptList* jol) | ||
413 | 403 | { | ||
414 | 404 | JavaVMOption* opt = jol->options; | ||
415 | 405 | JavaVMOption* top = opt + jol->size; | ||
416 | 406 | while(opt < top) | ||
417 | 407 | { | ||
418 | 408 | pfree(opt->optionString); | ||
419 | 409 | opt++; | ||
420 | 410 | } | ||
421 | 411 | pfree(jol->options); | ||
422 | 412 | } | ||
423 | 413 | |||
424 | 414 | static void JVMOptList_add(JVMOptList* jol, const char* optString, void* extraInfo, bool mustCopy) | ||
425 | 415 | { | ||
426 | 416 | JavaVMOption* added; | ||
427 | 417 | |||
428 | 418 | int newPos = jol->size; | ||
429 | 419 | if(newPos >= jol->capacity) | ||
430 | 420 | { | ||
431 | 421 | int newCap = jol->capacity * 2; | ||
432 | 422 | JavaVMOption* newOpts = (JavaVMOption*)palloc(newCap * sizeof(JavaVMOption)); | ||
433 | 423 | memcpy(newOpts, jol->options, newPos * sizeof(JavaVMOption)); | ||
434 | 424 | pfree(jol->options); | ||
435 | 425 | jol->options = newOpts; | ||
436 | 426 | jol->capacity = newCap; | ||
437 | 427 | } | ||
438 | 428 | added = jol->options + newPos; | ||
439 | 429 | if(mustCopy) | ||
440 | 430 | optString = pstrdup(optString); | ||
441 | 431 | |||
442 | 432 | added->optionString = (char*)optString; | ||
443 | 433 | added->extraInfo = extraInfo; | ||
444 | 434 | jol->size++; | ||
445 | 435 | |||
446 | 436 | elog(DEBUG1, "Added JVM option string \"%s\"", optString); | ||
447 | 437 | } | ||
448 | 438 | |||
449 | 439 | /* Split JVM options. The string is split on whitespace unless the | ||
450 | 440 | * whitespace is found within a string or is escaped by backslash. A | ||
451 | 441 | * backslash escaped quote is not considered a string delimiter. | ||
452 | 442 | */ | ||
453 | 443 | static void addUserJVMOptions(JVMOptList* optList) | ||
454 | 444 | { | ||
455 | 445 | const char* cp = vmoptions; | ||
456 | 446 | |||
457 | 447 | if(cp != NULL) | ||
458 | 448 | { | ||
459 | 449 | StringInfoData buf; | ||
460 | 450 | char quote = 0; | ||
461 | 451 | char c; | ||
462 | 452 | |||
463 | 453 | initStringInfo(&buf); | ||
464 | 454 | for(;;) | ||
465 | 455 | { | ||
466 | 456 | c = *cp++; | ||
467 | 457 | switch(c) | ||
468 | 458 | { | ||
469 | 459 | case 0: | ||
470 | 460 | break; | ||
471 | 461 | |||
472 | 462 | case '"': | ||
473 | 463 | case '\'': | ||
474 | 464 | if(quote == c) | ||
475 | 465 | quote = 0; | ||
476 | 466 | else | ||
477 | 467 | quote = c; | ||
478 | 468 | appendStringInfoChar(&buf, c); | ||
479 | 469 | continue; | ||
480 | 470 | |||
481 | 471 | case '\\': | ||
482 | 472 | appendStringInfoChar(&buf, '\\'); | ||
483 | 473 | c = *cp++; /* Interpret next character verbatim */ | ||
484 | 474 | if(c == 0) | ||
485 | 475 | break; | ||
486 | 476 | appendStringInfoChar(&buf, c); | ||
487 | 477 | continue; | ||
488 | 478 | |||
489 | 479 | default: | ||
490 | 480 | if(quote == 0 && isspace((int)c)) | ||
491 | 481 | { | ||
492 | 482 | while((c = *cp++) != 0) | ||
493 | 483 | { | ||
494 | 484 | if(!isspace((int)c)) | ||
495 | 485 | break; | ||
496 | 486 | } | ||
497 | 487 | |||
498 | 488 | if(c == 0) | ||
499 | 489 | break; | ||
500 | 490 | |||
501 | 491 | if(c != '-') | ||
502 | 492 | appendStringInfoChar(&buf, ' '); | ||
503 | 493 | else if(buf.len > 0) | ||
504 | 494 | { | ||
505 | 495 | /* Whitespace followed by '-' triggers new | ||
506 | 496 | * option declaration. | ||
507 | 497 | */ | ||
508 | 498 | JVMOptList_add(optList, buf.data, 0, true); | ||
509 | 499 | buf.len = 0; | ||
510 | 500 | buf.data[0] = 0; | ||
511 | 501 | } | ||
512 | 502 | } | ||
513 | 503 | appendStringInfoChar(&buf, c); | ||
514 | 504 | continue; | ||
515 | 505 | } | ||
516 | 506 | break; | ||
517 | 507 | } | ||
518 | 508 | if(buf.len > 0) | ||
519 | 509 | JVMOptList_add(optList, buf.data, 0, true); | ||
520 | 510 | pfree(buf.data); | ||
521 | 511 | } | ||
522 | 512 | } | ||
523 | 513 | |||
524 | 514 | /** | ||
525 | 515 | * Initialize the session | ||
526 | 516 | */ | ||
527 | 517 | static void initJavaSession(void) | ||
528 | 518 | { | ||
529 | 519 | jclass sessionClass = PgObject_getJavaClass("org/postgresql/pljava/internal/Session"); | ||
530 | 520 | jmethodID init = PgObject_getStaticJavaMethod(sessionClass, "init", "()J"); | ||
531 | 521 | mainThreadId = JNI_callStaticLongMethod(sessionClass, init); | ||
532 | 522 | JNI_deleteLocalRef(sessionClass); | ||
533 | 523 | |||
534 | 524 | if(JNI_exceptionCheck()) | ||
535 | 525 | { | ||
536 | 526 | JNI_exceptionDescribe(); | ||
537 | 527 | JNI_exceptionClear(); | ||
538 | 528 | ereport(ERROR, ( | ||
539 | 529 | errcode(ERRCODE_INTERNAL_ERROR), | ||
540 | 530 | errmsg("Unable to initialize java session"))); | ||
541 | 531 | } | ||
542 | 532 | } | ||
543 | 533 | |||
544 | 534 | static void checkIntTimeType(void) | ||
545 | 535 | { | ||
546 | 536 | #if (PGSQL_MAJOR_VER > 8) | ||
547 | 537 | const char* idt = GetConfigOption("integer_datetimes", true); | ||
548 | 538 | #else | ||
549 | 539 | const char* idt = GetConfigOption("integer_datetimes"); | ||
550 | 540 | #endif | ||
551 | 541 | |||
552 | 542 | integerDateTimes = (strcmp(idt, "on") == 0); | ||
553 | 543 | elog(DEBUG1, integerDateTimes ? "Using integer_datetimes" : "Not using integer_datetimes"); | ||
554 | 544 | } | ||
555 | 545 | |||
556 | 546 | static bool s_firstTimeInit = true; | ||
557 | 547 | |||
558 | 548 | static void initializeJavaVM(void) | ||
559 | 549 | { | ||
560 | 550 | jboolean jstat; | ||
561 | 551 | JavaVMInitArgs vm_args; | ||
562 | 552 | JVMOptList optList; | ||
563 | 553 | |||
564 | 554 | JVMOptList_init(&optList); | ||
565 | 555 | |||
566 | 556 | if(s_firstTimeInit) | ||
567 | 557 | { | ||
568 | 558 | s_firstTimeInit = false; | ||
569 | 559 | s_javaLogLevel = INFO; | ||
570 | 560 | |||
571 | 561 | checkIntTimeType(); | ||
572 | 562 | HashMap_initialize(); | ||
573 | 563 | |||
574 | 564 | DefineCustomStringVariable( | ||
575 | 565 | "pljava.vmoptions", | ||
576 | 566 | "Options sent to the JVM when it is created", | ||
577 | 567 | NULL, | ||
578 | 568 | &vmoptions, | ||
579 | 569 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
580 | 570 | NULL, | ||
581 | 571 | #endif | ||
582 | 572 | PGC_USERSET, | ||
583 | 573 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
584 | 574 | 0, | ||
585 | 575 | #endif | ||
586 | 576 | NULL, NULL); | ||
587 | 577 | |||
588 | 578 | DefineCustomStringVariable( | ||
589 | 579 | "pljava.classpath", | ||
590 | 580 | "Classpath used by the JVM", | ||
591 | 581 | NULL, | ||
592 | 582 | &classpath, | ||
593 | 583 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
594 | 584 | NULL, | ||
595 | 585 | #endif | ||
596 | 586 | PGC_USERSET, | ||
597 | 587 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
598 | 588 | 0, | ||
599 | 589 | #endif | ||
600 | 590 | NULL, NULL); | ||
601 | 591 | |||
602 | 592 | DefineCustomBoolVariable( | ||
603 | 593 | "pljava.debug", | ||
604 | 594 | "Stop the backend to attach a debugger", | ||
605 | 595 | NULL, | ||
606 | 596 | &pljavaDebug, | ||
607 | 597 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
608 | 598 | false, | ||
609 | 599 | #endif | ||
610 | 600 | PGC_USERSET, | ||
611 | 601 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
612 | 602 | 0, | ||
613 | 603 | #endif | ||
614 | 604 | NULL, NULL); | ||
615 | 605 | |||
616 | 606 | DefineCustomIntVariable( | ||
617 | 607 | "pljava.statement_cache_size", | ||
618 | 608 | "Size of the prepared statement MRU cache", | ||
619 | 609 | NULL, | ||
620 | 610 | &statementCacheSize, | ||
621 | 611 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
622 | 612 | 11, | ||
623 | 613 | #endif | ||
624 | 614 | 0, 512, | ||
625 | 615 | PGC_USERSET, | ||
626 | 616 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
627 | 617 | 0, | ||
628 | 618 | #endif | ||
629 | 619 | NULL, NULL); | ||
630 | 620 | |||
631 | 621 | DefineCustomBoolVariable( | ||
632 | 622 | "pljava.release_lingering_savepoints", | ||
633 | 623 | "If true, lingering savepoints will be released on function exit. If false, the will be rolled back", | ||
634 | 624 | NULL, | ||
635 | 625 | &pljavaReleaseLingeringSavepoints, | ||
636 | 626 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
637 | 627 | false, | ||
638 | 628 | #endif | ||
639 | 629 | PGC_USERSET, | ||
640 | 630 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
641 | 631 | 0, | ||
642 | 632 | #endif | ||
643 | 633 | NULL, NULL); | ||
644 | 634 | |||
645 | 635 | EmitWarningsOnPlaceholders("pljava"); | ||
646 | 636 | s_firstTimeInit = false; | ||
647 | 637 | } | ||
648 | 638 | |||
649 | 639 | #ifdef PLJAVA_DEBUG | ||
650 | 640 | /* Hard setting for debug. Don't forget to recompile... | ||
651 | 641 | */ | ||
652 | 642 | pljavaDebug = 1; | ||
653 | 643 | #endif | ||
654 | 644 | |||
655 | 645 | addUserJVMOptions(&optList); | ||
656 | 646 | effectiveClassPath = getClassPath("-Djava.class.path="); | ||
657 | 647 | if(effectiveClassPath != 0) | ||
658 | 648 | { | ||
659 | 649 | JVMOptList_add(&optList, effectiveClassPath, 0, true); | ||
660 | 650 | } | ||
661 | 651 | |||
662 | 652 | /** | ||
663 | 653 | * As stipulated by JRT-2003 | ||
664 | 654 | */ | ||
665 | 655 | JVMOptList_add(&optList, | ||
666 | 656 | "-Dsqlj.defaultconnection=jdbc:default:connection", | ||
667 | 657 | 0, true); | ||
668 | 658 | |||
669 | 659 | JVMOptList_add(&optList, "vfprintf", (void*)my_vfprintf, true); | ||
670 | 660 | #ifndef GCJ | ||
671 | 661 | JVMOptList_add(&optList, "-Xrs", 0, true); | ||
672 | 662 | #endif | ||
673 | 663 | if(pljavaDebug) | ||
674 | 664 | { | ||
675 | 665 | elog(INFO, "Backend pid = %d. Attach the debugger and set pljavaDebug to false to continue", getpid()); | ||
676 | 666 | while(pljavaDebug) | ||
677 | 667 | pg_usleep(1000000L); | ||
678 | 668 | } | ||
679 | 669 | |||
680 | 670 | vm_args.nOptions = optList.size; | ||
681 | 671 | vm_args.options = optList.options; | ||
682 | 672 | vm_args.version = JNI_VERSION_1_4; | ||
683 | 673 | vm_args.ignoreUnrecognized = JNI_FALSE; | ||
684 | 674 | |||
685 | 675 | elog(DEBUG1, "Creating JavaVM"); | ||
686 | 676 | |||
687 | 677 | jstat = JNI_createVM(&s_javaVM, &vm_args); | ||
688 | 678 | |||
689 | 679 | if(jstat == JNI_OK && JNI_exceptionCheck()) | ||
690 | 680 | { | ||
691 | 681 | JNI_exceptionDescribe(); | ||
692 | 682 | JNI_exceptionClear(); | ||
693 | 683 | jstat = JNI_ERR; | ||
694 | 684 | } | ||
695 | 685 | JVMOptList_delete(&optList); | ||
696 | 686 | |||
697 | 687 | if(jstat != JNI_OK) | ||
698 | 688 | ereport(ERROR, (errmsg("Failed to create Java VM"))); | ||
699 | 689 | |||
700 | 690 | #if !defined(WIN32) | ||
701 | 691 | pqsignal(SIGINT, pljavaStatementCancelHandler); | ||
702 | 692 | pqsignal(SIGTERM, pljavaDieHandler); | ||
703 | 693 | pqsignal(SIGQUIT, pljavaQuickDieHandler); | ||
704 | 694 | #endif | ||
705 | 695 | elog(DEBUG1, "JavaVM created"); | ||
706 | 696 | |||
707 | 697 | /* Register an on_proc_exit handler that destroys the VM | ||
708 | 698 | */ | ||
709 | 699 | on_proc_exit(_destroyJavaVM, 0); | ||
710 | 700 | initPLJavaClasses(); | ||
711 | 701 | initJavaSession(); | ||
712 | 702 | } | ||
713 | 703 | |||
714 | 704 | static Datum internalCallHandler(bool trusted, PG_FUNCTION_ARGS); | ||
715 | 705 | |||
716 | 706 | extern Datum javau_call_handler(PG_FUNCTION_ARGS); | ||
717 | 707 | PG_FUNCTION_INFO_V1(javau_call_handler); | ||
718 | 708 | |||
719 | 709 | /* | ||
720 | 710 | * This is the entry point for all untrusted calls. | ||
721 | 711 | */ | ||
722 | 712 | Datum javau_call_handler(PG_FUNCTION_ARGS) | ||
723 | 713 | { | ||
724 | 714 | return internalCallHandler(false, fcinfo); | ||
725 | 715 | } | ||
726 | 716 | |||
727 | 717 | extern Datum java_call_handler(PG_FUNCTION_ARGS); | ||
728 | 718 | PG_FUNCTION_INFO_V1(java_call_handler); | ||
729 | 719 | |||
730 | 720 | /* | ||
731 | 721 | * This is the entry point for all trusted calls. | ||
732 | 722 | */ | ||
733 | 723 | Datum java_call_handler(PG_FUNCTION_ARGS) | ||
734 | 724 | { | ||
735 | 725 | return internalCallHandler(true, fcinfo); | ||
736 | 726 | } | ||
737 | 727 | |||
738 | 728 | static Datum internalCallHandler(bool trusted, PG_FUNCTION_ARGS) | ||
739 | 729 | { | ||
740 | 730 | Invocation ctx; | ||
741 | 731 | Datum retval = 0; | ||
742 | 732 | |||
743 | 733 | if(s_javaVM == 0) | ||
744 | 734 | { | ||
745 | 735 | Invocation_pushBootContext(&ctx); | ||
746 | 736 | PG_TRY(); | ||
747 | 737 | { | ||
748 | 738 | initializeJavaVM(); | ||
749 | 739 | Invocation_popBootContext(); | ||
750 | 740 | } | ||
751 | 741 | PG_CATCH(); | ||
752 | 742 | { | ||
753 | 743 | Invocation_popBootContext(); | ||
754 | 744 | |||
755 | 745 | /* JVM initialization failed for some reason. Destroy | ||
756 | 746 | * the VM if it exists. Perhaps the user will try | ||
757 | 747 | * fixing the pljava.classpath and make a new attempt. | ||
758 | 748 | */ | ||
759 | 749 | _destroyJavaVM(0, 0); | ||
760 | 750 | |||
761 | 751 | /* We can't stay here... | ||
762 | 752 | */ | ||
763 | 753 | PG_RE_THROW(); | ||
764 | 754 | } | ||
765 | 755 | PG_END_TRY(); | ||
766 | 756 | |||
767 | 757 | /* Force initial setting | ||
768 | 758 | */ | ||
769 | 759 | s_currentTrust = !trusted; | ||
770 | 760 | } | ||
771 | 761 | |||
772 | 762 | Invocation_pushInvocation(&ctx, trusted); | ||
773 | 763 | PG_TRY(); | ||
774 | 764 | { | ||
775 | 765 | Function function = Function_getFunction(fcinfo); | ||
776 | 766 | if(CALLED_AS_TRIGGER(fcinfo)) | ||
777 | 767 | { | ||
778 | 768 | /* Called as a trigger procedure | ||
779 | 769 | */ | ||
780 | 770 | retval = Function_invokeTrigger(function, fcinfo); | ||
781 | 771 | } | ||
782 | 772 | else | ||
783 | 773 | { | ||
784 | 774 | /* Called as a function | ||
785 | 775 | */ | ||
786 | 776 | retval = Function_invoke(function, fcinfo); | ||
787 | 777 | } | ||
788 | 778 | Invocation_popInvocation(false); | ||
789 | 779 | } | ||
790 | 780 | PG_CATCH(); | ||
791 | 781 | { | ||
792 | 782 | Invocation_popInvocation(true); | ||
793 | 783 | PG_RE_THROW(); | ||
794 | 784 | } | ||
795 | 785 | PG_END_TRY(); | ||
796 | 786 | return retval; | ||
797 | 787 | } | ||
798 | 788 | |||
799 | 789 | /**************************************** | ||
800 | 790 | * JNI methods | ||
801 | 791 | ****************************************/ | ||
802 | 792 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) | ||
803 | 793 | { | ||
804 | 794 | return JNI_VERSION_1_4; | ||
805 | 795 | } | ||
806 | 796 | |||
807 | 797 | /* | ||
808 | 798 | * Class: org_postgresql_pljava_internal_Backend | ||
809 | 799 | * Method: _getConfigOption | ||
810 | 800 | * Signature: (Ljava/lang/String;)Ljava/lang/String; | ||
811 | 801 | */ | ||
812 | 802 | JNIEXPORT jstring JNICALL | ||
813 | 803 | JNICALL Java_org_postgresql_pljava_internal_Backend__1getConfigOption(JNIEnv* env, jclass cls, jstring jkey) | ||
814 | 804 | { | ||
815 | 805 | jstring result = 0; | ||
816 | 806 | |||
817 | 807 | BEGIN_NATIVE | ||
818 | 808 | char* key = String_createNTS(jkey); | ||
819 | 809 | if(key != 0) | ||
820 | 810 | { | ||
821 | 811 | PG_TRY(); | ||
822 | 812 | { | ||
823 | 813 | #if (PGSQL_MAJOR_VER > 8) | ||
824 | 814 | const char* value = GetConfigOption(key, true); | ||
825 | 815 | #else | ||
826 | 816 | const char* value = GetConfigOption(key); | ||
827 | 817 | #endif | ||
828 | 818 | |||
829 | 819 | pfree(key); | ||
830 | 820 | if(value != 0) | ||
831 | 821 | result = String_createJavaStringFromNTS(value); | ||
832 | 822 | } | ||
833 | 823 | PG_CATCH(); | ||
834 | 824 | { | ||
835 | 825 | Exception_throw_ERROR("GetConfigOption"); | ||
836 | 826 | } | ||
837 | 827 | PG_END_TRY(); | ||
838 | 828 | } | ||
839 | 829 | END_NATIVE | ||
840 | 830 | return result; | ||
841 | 831 | } | ||
842 | 832 | |||
843 | 833 | |||
844 | 834 | /* | ||
845 | 835 | * Class: org_postgresql_pljava_internal_Backend | ||
846 | 836 | * Method: _getStatementCacheSize | ||
847 | 837 | * Signature: ()I | ||
848 | 838 | */ | ||
849 | 839 | JNIEXPORT jint JNICALL | ||
850 | 840 | Java_org_postgresql_pljava_internal_Backend__1getStatementCacheSize(JNIEnv* env, jclass cls) | ||
851 | 841 | { | ||
852 | 842 | return statementCacheSize; | ||
853 | 843 | } | ||
854 | 844 | |||
855 | 845 | /* | ||
856 | 846 | * Class: org_postgresql_pljava_internal_Backend | ||
857 | 847 | * Method: _log | ||
858 | 848 | * Signature: (ILjava/lang/String;)V | ||
859 | 849 | */ | ||
860 | 850 | JNIEXPORT void JNICALL | ||
861 | 851 | JNICALL Java_org_postgresql_pljava_internal_Backend__1log(JNIEnv* env, jclass cls, jint logLevel, jstring jstr) | ||
862 | 852 | { | ||
863 | 853 | BEGIN_NATIVE_NO_ERRCHECK | ||
864 | 854 | char* str = String_createNTS(jstr); | ||
865 | 855 | if(str != 0) | ||
866 | 856 | { | ||
867 | 857 | /* elog uses printf formatting but the logger does not so we must escape all | ||
868 | 858 | * '%' in the string. | ||
869 | 859 | */ | ||
870 | 860 | char c; | ||
871 | 861 | const char* cp; | ||
872 | 862 | int percentCount = 0; | ||
873 | 863 | for(cp = str; (c = *cp) != 0; ++cp) | ||
874 | 864 | { | ||
875 | 865 | if(c == '%') | ||
876 | 866 | ++percentCount; | ||
877 | 867 | } | ||
878 | 868 | |||
879 | 869 | if(percentCount > 0) | ||
880 | 870 | { | ||
881 | 871 | /* Make room to expand all "%" to "%%" | ||
882 | 872 | */ | ||
883 | 873 | char* str2 = palloc((cp - str) + percentCount + 1); | ||
884 | 874 | char* cp2 = str2; | ||
885 | 875 | |||
886 | 876 | /* Expand... */ | ||
887 | 877 | for(cp = str; (c = *cp) != 0; ++cp) | ||
888 | 878 | { | ||
889 | 879 | if(c == '%') | ||
890 | 880 | *cp2++ = c; | ||
891 | 881 | *cp2++ = c; | ||
892 | 882 | } | ||
893 | 883 | *cp2 = 0; | ||
894 | 884 | pfree(str); | ||
895 | 885 | str = str2; | ||
896 | 886 | } | ||
897 | 887 | |||
898 | 888 | PG_TRY(); | ||
899 | 889 | { | ||
900 | 890 | elog(logLevel, str); | ||
901 | 891 | pfree(str); | ||
902 | 892 | } | ||
903 | 893 | PG_CATCH(); | ||
904 | 894 | { | ||
905 | 895 | Exception_throw_ERROR("ereport"); | ||
906 | 896 | } | ||
907 | 897 | PG_END_TRY(); | ||
908 | 898 | } | ||
909 | 899 | END_NATIVE | ||
910 | 900 | } | ||
911 | 901 | |||
912 | 902 | /* | ||
913 | 903 | * Class: org_postgresql_pljava_internal_Backend | ||
914 | 904 | * Method: isCallingJava | ||
915 | 905 | * Signature: ()Z | ||
916 | 906 | */ | ||
917 | 907 | JNIEXPORT jboolean JNICALL | ||
918 | 908 | Java_org_postgresql_pljava_internal_Backend_isCallingJava(JNIEnv* env, jclass cls) | ||
919 | 909 | { | ||
920 | 910 | return JNI_isCallingJava(); | ||
921 | 911 | } | ||
922 | 912 | |||
923 | 913 | /* | ||
924 | 914 | * Class: org_postgresql_pljava_internal_Backend | ||
925 | 915 | * Method: isReleaseLingeringSavepoints | ||
926 | 916 | * Signature: ()Z | ||
927 | 917 | */ | ||
928 | 918 | JNIEXPORT jboolean JNICALL | ||
929 | 919 | Java_org_postgresql_pljava_internal_Backend_isReleaseLingeringSavepoints(JNIEnv* env, jclass cls) | ||
930 | 920 | { | ||
931 | 921 | return pljavaReleaseLingeringSavepoints ? JNI_TRUE : JNI_FALSE; | ||
932 | 922 | } | ||
933 | 923 | |||
934 | 924 | /* | ||
935 | 925 | * Class: org_postgresql_pljava_internal_Backend | ||
936 | 926 | * Method: _clearFunctionCache | ||
937 | 927 | * Signature: ()V | ||
938 | 928 | */ | ||
939 | 929 | JNIEXPORT void JNICALL | ||
940 | 930 | Java_org_postgresql_pljava_internal_Backend__1clearFunctionCache(JNIEnv* env, jclass cls) | ||
941 | 931 | { | ||
942 | 932 | BEGIN_NATIVE_NO_ERRCHECK | ||
943 | 933 | Function_clearFunctionCache(); | ||
944 | 934 | END_NATIVE | ||
945 | 935 | } | ||
946 | 0 | 936 | ||
947 | === added file 'debian/patches/9.1_api.patch' | |||
948 | --- debian/patches/9.1_api.patch 1970-01-01 00:00:00 +0000 | |||
949 | +++ debian/patches/9.1_api.patch 2011-09-06 19:13:35 +0000 | |||
950 | @@ -0,0 +1,74 @@ | |||
951 | 1 | Description: Port to 9.1 API. | ||
952 | 2 | Author: Martin Pitt <martin.pitt@ubuntu.com> | ||
953 | 3 | Bug-Debian: http://bugs.debian.org/639461 | ||
954 | 4 | |||
955 | 5 | Index: postgresql-pljava/src/C/pljava/Backend.c | ||
956 | 6 | =================================================================== | ||
957 | 7 | --- postgresql-pljava.orig/src/C/pljava/Backend.c 2011-09-06 19:16:02.775995582 +0200 | ||
958 | 8 | +++ postgresql-pljava/src/C/pljava/Backend.c 2011-09-06 19:18:04.105996380 +0200 | ||
959 | 9 | @@ -534,9 +534,9 @@ | ||
960 | 10 | static void checkIntTimeType(void) | ||
961 | 11 | { | ||
962 | 12 | #if (PGSQL_MAJOR_VER > 8) | ||
963 | 13 | - const char* idt = GetConfigOption("integer_datetimes", true); | ||
964 | 14 | + const char* idt = GetConfigOption("integer_datetimes", true, false); | ||
965 | 15 | #else | ||
966 | 16 | - const char* idt = GetConfigOption("integer_datetimes"); | ||
967 | 17 | + const char* idt = GetConfigOption("integer_datetimes", false); | ||
968 | 18 | #endif | ||
969 | 19 | |||
970 | 20 | integerDateTimes = (strcmp(idt, "on") == 0); | ||
971 | 21 | @@ -573,7 +573,7 @@ | ||
972 | 22 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
973 | 23 | 0, | ||
974 | 24 | #endif | ||
975 | 25 | - NULL, NULL); | ||
976 | 26 | + NULL, NULL, NULL); | ||
977 | 27 | |||
978 | 28 | DefineCustomStringVariable( | ||
979 | 29 | "pljava.classpath", | ||
980 | 30 | @@ -587,7 +587,7 @@ | ||
981 | 31 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
982 | 32 | 0, | ||
983 | 33 | #endif | ||
984 | 34 | - NULL, NULL); | ||
985 | 35 | + NULL, NULL, NULL); | ||
986 | 36 | |||
987 | 37 | DefineCustomBoolVariable( | ||
988 | 38 | "pljava.debug", | ||
989 | 39 | @@ -601,7 +601,7 @@ | ||
990 | 40 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
991 | 41 | 0, | ||
992 | 42 | #endif | ||
993 | 43 | - NULL, NULL); | ||
994 | 44 | + NULL, NULL, NULL); | ||
995 | 45 | |||
996 | 46 | DefineCustomIntVariable( | ||
997 | 47 | "pljava.statement_cache_size", | ||
998 | 48 | @@ -616,7 +616,7 @@ | ||
999 | 49 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
1000 | 50 | 0, | ||
1001 | 51 | #endif | ||
1002 | 52 | - NULL, NULL); | ||
1003 | 53 | + NULL, NULL, NULL); | ||
1004 | 54 | |||
1005 | 55 | DefineCustomBoolVariable( | ||
1006 | 56 | "pljava.release_lingering_savepoints", | ||
1007 | 57 | @@ -630,7 +630,7 @@ | ||
1008 | 58 | #if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER > 3)) | ||
1009 | 59 | 0, | ||
1010 | 60 | #endif | ||
1011 | 61 | - NULL, NULL); | ||
1012 | 62 | + NULL, NULL, NULL); | ||
1013 | 63 | |||
1014 | 64 | EmitWarningsOnPlaceholders("pljava"); | ||
1015 | 65 | s_firstTimeInit = false; | ||
1016 | 66 | @@ -811,7 +811,7 @@ | ||
1017 | 67 | PG_TRY(); | ||
1018 | 68 | { | ||
1019 | 69 | #if (PGSQL_MAJOR_VER > 8) | ||
1020 | 70 | - const char* value = GetConfigOption(key, true); | ||
1021 | 71 | + const char* value = GetConfigOption(key, true, false); | ||
1022 | 72 | #else | ||
1023 | 73 | const char* value = GetConfigOption(key); | ||
1024 | 74 | #endif | ||
1025 | 0 | 75 | ||
1026 | === renamed file 'debian/patches/9.1_api.patch' => 'debian/patches/9.1_api.patch.moved' |
usual quilt 3 conflict