forked from tada/pljava
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTuple.c
More file actions
161 lines (145 loc) · 3.88 KB
/
Copy pathTuple.c
File metadata and controls
161 lines (145 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
* Copyright (c) 2004, 2005, 2006 TADA AB - Taby Sweden
* Distributed under the terms shown in the file COPYRIGHT
* found in the root folder of this project or at
* http://eng.tada.se/osprojects/COPYRIGHT.html
*
* @author Thomas Hallgren
*/
#include <postgres.h>
#include <executor/spi.h>
#include <executor/tuptable.h>
#include "org_postgresql_pljava_internal_Tuple.h"
#include "pljava/Backend.h"
#include "pljava/Exception.h"
#include "pljava/type/Type_priv.h"
#include "pljava/type/Tuple.h"
#include "pljava/type/TupleDesc.h"
static jclass s_Tuple_class;
static jmethodID s_Tuple_init;
/*
* org.postgresql.pljava.type.Tuple type.
*/
jobject Tuple_create(HeapTuple ht)
{
jobject jht = 0;
if(ht != 0)
{
MemoryContext curr = MemoryContextSwitchTo(JavaMemoryContext);
jht = Tuple_internalCreate(ht, true);
MemoryContextSwitchTo(curr);
}
return jht;
}
jobjectArray Tuple_createArray(HeapTuple* vals, jint size, bool mustCopy)
{
jobjectArray tuples = JNI_newObjectArray(size, s_Tuple_class, 0);
while(--size >= 0)
{
jobject heapTuple = Tuple_internalCreate(vals[size], mustCopy);
JNI_setObjectArrayElement(tuples, size, heapTuple);
JNI_deleteLocalRef(heapTuple);
}
return tuples;
}
jobject Tuple_internalCreate(HeapTuple ht, bool mustCopy)
{
jobject jht;
Ptr2Long htH;
if(mustCopy)
ht = heap_copytuple(ht);
htH.longVal = 0L; /* ensure that the rest is zeroed out */
htH.ptrVal = ht;
jht = JNI_newObject(s_Tuple_class, s_Tuple_init, htH.longVal);
return jht;
}
static jvalue _Tuple_coerceDatum(Type self, Datum arg)
{
jvalue result;
result.l = Tuple_create((HeapTuple)DatumGetPointer(arg));
return result;
}
/* Make this datatype available to the postgres system.
*/
extern void Tuple_initialize(void);
void Tuple_initialize(void)
{
TypeClass cls;
JNINativeMethod methods[] = {
{
"_getObject",
"(JJI)Ljava/lang/Object;",
Java_org_postgresql_pljava_internal_Tuple__1getObject
},
{
"_free",
"(J)V",
Java_org_postgresql_pljava_internal_Tuple__1free
},
{ 0, 0, 0 }};
s_Tuple_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/internal/Tuple"));
PgObject_registerNatives2(s_Tuple_class, methods);
s_Tuple_init = PgObject_getJavaMethod(s_Tuple_class, "<init>", "(J)V");
cls = JavaWrapperClass_alloc("type.Tuple");
cls->JNISignature = "Lorg/postgresql/pljava/internal/Tuple;";
cls->javaTypeName = "org.postgresql.pljava.internal.Tuple";
cls->coerceDatum = _Tuple_coerceDatum;
Type_registerType("org.postgresql.pljava.internal.Tuple", TypeClass_allocInstance(cls, InvalidOid));
}
jobject
Tuple_getObject(TupleDesc tupleDesc, HeapTuple tuple, int index)
{
jobject result = 0;
PG_TRY();
{
Type type = TupleDesc_getColumnType(tupleDesc, index);
if(type != 0)
{
bool wasNull = false;
Datum binVal = SPI_getbinval(tuple, tupleDesc, (int)index, &wasNull);
if(!wasNull)
result = Type_coerceDatum(type, binVal).l;
}
}
PG_CATCH();
{
Exception_throw_ERROR("SPI_getbinval");
}
PG_END_TRY();
return result;
}
/****************************************
* JNI methods
****************************************/
/*
* Class: org_postgresql_pljava_internal_Tuple
* Method: _getObject
* Signature: (JJI)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_org_postgresql_pljava_internal_Tuple__1getObject(JNIEnv* env, jclass cls, jlong _this, jlong _tupleDesc, jint index)
{
jobject result = 0;
Ptr2Long p2l;
p2l.longVal = _this;
BEGIN_NATIVE
HeapTuple self = (HeapTuple)p2l.ptrVal;
p2l.longVal = _tupleDesc;
result = Tuple_getObject((TupleDesc)p2l.ptrVal, self, (int)index);
END_NATIVE
return result;
}
/*
* Class: org_postgresql_pljava_internal_Tuple
* Method: _free
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_org_postgresql_pljava_internal_Tuple__1free(JNIEnv* env, jobject _this, jlong pointer)
{
BEGIN_NATIVE_NO_ERRCHECK
Ptr2Long p2l;
p2l.longVal = pointer;
heap_freetuple(p2l.ptrVal);
END_NATIVE
}