00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "postgres.h"
00020 #include "veil_datatypes.h"
00021 #include "utils/hsearch.h"
00022 #include "storage/shmem.h"
00023
00024 #include "veil_funcs.h"
00025
00026
00027
00028
00029
00030 #define SESSION_HASH_ELEMS 32
00031
00032
00033
00034
00035
00036
00037 static HTAB *session_hash = NULL;
00038
00039
00040
00041
00042
00043
00044 static HTAB *
00045 create_session_hash()
00046 {
00047 HASHCTL hashctl;
00048
00049
00050
00051 hashctl.keysize = HASH_KEYLEN;
00052 hashctl.entrysize = sizeof(VarEntry);
00053
00054 return hash_create("VEIL_SESSION",
00055 SESSION_HASH_ELEMS, &hashctl, HASH_ELEM);
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 VarEntry *
00071 vl_lookup_shared_variable(char *name)
00072 {
00073 VarEntry *var;
00074 HTAB *shared_hash = vl_get_shared_hash();
00075 bool found;
00076
00077 if (!session_hash) {
00078 session_hash = create_session_hash();
00079 }
00080
00081 var = (VarEntry *) hash_search(session_hash, (void *) name,
00082 HASH_FIND, &found);
00083 if (found) {
00084 ereport(ERROR,
00085 (errcode(ERRCODE_INTERNAL_ERROR),
00086 errmsg("attempt to redefine session variable %s", name),
00087 errdetail("You are trying to create shared variable %s "
00088 "but it already exists as a session variable.",
00089 name)));
00090 }
00091
00092 var = (VarEntry *) hash_search(shared_hash, (void *) name,
00093 HASH_ENTER, &found);
00094
00095 if (!var) {
00096 ereport(ERROR,
00097 (errcode(ERRCODE_INTERNAL_ERROR),
00098 errmsg("Out of memory for shared variables")));
00099 }
00100
00101 if (!found) {
00102
00103
00104
00105 var->obj = NULL;
00106 var->shared = true;
00107 }
00108
00109 return var;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 VarEntry *
00123 vl_lookup_variable(char *name)
00124 {
00125 VarEntry *var;
00126 HTAB *shared_hash = vl_get_shared_hash();
00127 bool found;
00128
00129 if (!session_hash) {
00130 session_hash = create_session_hash();
00131 }
00132
00133 var = (VarEntry *)hash_search(session_hash, (void *) name,
00134 HASH_FIND, &found);
00135 if (!var) {
00136
00137 var = (VarEntry *)hash_search(shared_hash, (void *) name,
00138 HASH_FIND, NULL);
00139 }
00140
00141
00142 if (!var) {
00143
00144 var = (VarEntry *) hash_search(session_hash, (void *) name,
00145 HASH_ENTER, &found);
00146 if (!var) {
00147 ereport(ERROR,
00148 (errcode(ERRCODE_INTERNAL_ERROR),
00149 errmsg("Out of memory for shared variables")));
00150 }
00151 var->obj = NULL;
00152 var->shared = false;
00153 }
00154 return var;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 veil_variable_t *
00168 vl_next_variable(veil_variable_t *prev)
00169 {
00170 static bool doing_shared;
00171 static HTAB *hash;
00172 static HASH_SEQ_STATUS status;
00173 static veil_variable_t result;
00174 VarEntry *var;
00175
00176 if (!session_hash) {
00177 session_hash = create_session_hash();
00178 }
00179
00180 if (!prev) {
00181 doing_shared = true;
00182
00183 hash = vl_get_shared_hash();
00184
00185 hash_seq_init(&status, hash);
00186 }
00187
00188 var = hash_seq_search(&status);
00189
00190 if (!var) {
00191
00192 if (doing_shared) {
00193
00194 doing_shared = false;
00195 hash = session_hash;
00196 hash_seq_init(&status, hash);
00197 var = hash_seq_search(&status);
00198 }
00199 }
00200
00201 if (var) {
00202
00203 result.name = var->key;
00204 result.shared = var->shared;
00205 if (var->obj) {
00206 result.type = vl_ObjTypeName(var->obj->type);
00207 }
00208 else {
00209 result.type = vl_ObjTypeName(OBJ_UNDEFINED);;
00210 }
00211 return &result;
00212 }
00213 else {
00214
00215 return NULL;
00216 }
00217 }
00218
00219
00220
00221
00222
00223
00224 void
00225 vl_ClearInt4Array(Int4Array *array)
00226 {
00227 int elems = 1 + array->arraymax - array->arrayzero;
00228 int i;
00229 for (i = 0; i < elems; i++) {
00230 array->array[i] = 0;
00231 }
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 Int4Array *
00247 vl_NewInt4Array(Int4Array *current, bool shared,
00248 int32 min, int32 max)
00249 {
00250 Int4Array *result = NULL;
00251 int elems = 1 + max - min;
00252
00253 if (current) {
00254 int cur_elems = 1 + current->arraymax - current->arrayzero;
00255 if (elems <= cur_elems) {
00256 vl_ClearInt4Array(current);
00257 result = current;
00258 }
00259 else {
00260 if (!shared) {
00261
00262 pfree(current);
00263 }
00264 }
00265 }
00266 if (!result) {
00267 if (shared) {
00268 result = vl_shmalloc(sizeof(Int4Array) + (sizeof(int32) * elems));
00269 }
00270 else {
00271 result = vl_malloc(sizeof(Int4Array) + (sizeof(int32) * elems));
00272 }
00273 }
00274 result->type = OBJ_INT4_ARRAY;
00275 result->arrayzero = min;
00276 result->arraymax = max;
00277
00278 return result;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 void
00290 vl_Int4ArraySet(Int4Array *array, int32 idx, int32 value)
00291 {
00292 if ((idx < array->arrayzero) ||
00293 (idx > array->arraymax))
00294 {
00295 ereport(ERROR,
00296 (errcode(ERRCODE_INTERNAL_ERROR),
00297 errmsg("Int4ArraySet range error"),
00298 errdetail("Index (%d) not in range %d..%d. ", idx,
00299 array->arrayzero, array->arraymax)));
00300 }
00301 array->array[idx - array->arrayzero] = value;
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 int32
00314 vl_Int4ArrayGet(Int4Array *array, int32 idx)
00315 {
00316 if ((idx < array->arrayzero) ||
00317 (idx > array->arraymax))
00318 {
00319 ereport(ERROR,
00320 (errcode(ERRCODE_INTERNAL_ERROR),
00321 errmsg("Int4ArrayGet range error"),
00322 errdetail("Index (%d) not in range %d..%d. ", idx,
00323 array->arrayzero, array->arraymax)));
00324 }
00325 return array->array[idx - array->arrayzero];
00326 }
00327