Datum pgpool_remote_start(PG_FUNCTION_ARGS) { int r; char *remote_host = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0)))); char *remote_data_directory = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1)))); if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to use pgpool_remote_start function")))); snprintf(recovery_script, sizeof(recovery_script), "%s/%s %s %s", DataDir, REMOTE_START_FILE, remote_host, remote_data_directory); elog(DEBUG1, "recovery_script: %s", recovery_script); r = system(recovery_script); if (r != 0) { elog(ERROR, "pgpool_remote_start failed"); } PG_RETURN_BOOL(true); }
/* * Look to see if we have template information for the given language name. */ static PLTemplate * find_language_template(const char *languageName) { PLTemplate *result; Relation rel; SysScanDesc scan; ScanKeyData key; HeapTuple tup; rel = heap_open(PLTemplateRelationId, AccessShareLock); ScanKeyInit(&key, Anum_pg_pltemplate_tmplname, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(languageName)); scan = systable_beginscan(rel, PLTemplateNameIndexId, true, SnapshotNow, 1, &key); tup = systable_getnext(scan); if (HeapTupleIsValid(tup)) { Form_pg_pltemplate tmpl = (Form_pg_pltemplate) GETSTRUCT(tup); Datum datum; bool isnull; result = (PLTemplate *) palloc0(sizeof(PLTemplate)); result->tmpltrusted = tmpl->tmpltrusted; /* Remaining fields are variable-width so we need heap_getattr */ datum = heap_getattr(tup, Anum_pg_pltemplate_tmplhandler, RelationGetDescr(rel), &isnull); if (!isnull) result->tmplhandler = DatumGetCString(DirectFunctionCall1(textout, datum)); datum = heap_getattr(tup, Anum_pg_pltemplate_tmplvalidator, RelationGetDescr(rel), &isnull); if (!isnull) result->tmplvalidator = DatumGetCString(DirectFunctionCall1(textout, datum)); datum = heap_getattr(tup, Anum_pg_pltemplate_tmpllibrary, RelationGetDescr(rel), &isnull); if (!isnull) result->tmpllibrary = DatumGetCString(DirectFunctionCall1(textout, datum)); /* Ignore template if handler or library info is missing */ if (!result->tmplhandler || !result->tmpllibrary) result = NULL; } else result = NULL; systable_endscan(scan); heap_close(rel, AccessShareLock); return result; }
/* * DML Functions */ Datum pr_set(PG_FUNCTION_ARGS) { text * key_arg = PG_GETARG_TEXT_P(0); text * value_arg = PG_GETARG_TEXT_P(1); int expire = PG_GETARG_UINT32(2); int ret; char * key = NULL; char * value = NULL; if (!pgredis || !pgredis->redis_server) { elog(ERROR, "Unable to set, redis instance missing"); PG_RETURN_FALSE; } key = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(key_arg))); value = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(value_arg))); if (!key || !value) { elog(ERROR, "Key/value incomplete in pgredis set"); PG_RETURN_FALSE; } ret = credis_set(pgredis->redis_server, key, value); if (ret == CREDIS_OK) { ret = credis_expire(pgredis->redis_server, key, expire); } PG_RETURN_BOOL(ret == CREDIS_OK); }
/* * CheckInMemConstraintsPgType * Check uniqueness constraints for pg_type in-memory tuples upon insert */ static void CheckInMemConstraintsPgType(InMemHeapRelation relation, HeapTuple newTuple) { Assert(NULL != newTuple); Assert(NULL != relation); Assert(NULL != relation->rel); TupleDesc tupleDesc = relation->rel->rd_att; Oid relnamespaceNew = DatumGetObjectId(tuple_getattr(newTuple, tupleDesc, Anum_pg_type_typnamespace)); char *typnameNew = DatumGetCString(tuple_getattr(newTuple, tupleDesc, Anum_pg_type_typname)); for (int i = 0; i < relation->tupsize; i++) { HeapTuple tuple = relation->tuples[i].tuple; Assert(NULL != tuple); insist_log(HeapTupleGetOid(tuple) != HeapTupleGetOid(newTuple), "in-memory tuple with Oid = %d already exists in pg_type.", HeapTupleGetOid(tuple)); Oid relnamespace = DatumGetObjectId(tuple_getattr(tuple, tupleDesc, Anum_pg_type_typnamespace)); char *typname = DatumGetCString(tuple_getattr(tuple, tupleDesc, Anum_pg_type_typname)); size_t typnameLen = strlen(typname); insist_log(relnamespace != relnamespaceNew || typnameLen != strlen(typnameNew) || 0 != strncmp(typname, typnameNew, typnameLen), "in-memory tuple with typname = %s and typnamespace = %d already exists in pg_type.", typname, relnamespace); } }
/* * CheckInMemConstraintsPgNamespace * Check uniqueness constraints for pg_namespace in-memory tuples upon insert */ static void CheckInMemConstraintsPgNamespace(InMemHeapRelation relation, HeapTuple newTuple) { Assert(NULL != newTuple); Assert(NULL != relation); Assert(NULL != relation->rel); TupleDesc tupleDesc = relation->rel->rd_att; Oid nspdboidNew = DatumGetObjectId(tuple_getattr(newTuple, tupleDesc, Anum_pg_namespace_nspdboid)); char *nspnameNew = DatumGetCString(tuple_getattr(newTuple, tupleDesc, Anum_pg_namespace_nspname)); for (int i = 0; i < relation->tupsize; i++) { HeapTuple tuple = relation->tuples[i].tuple; Assert(NULL != tuple); insist_log(HeapTupleGetOid(tuple) != HeapTupleGetOid(newTuple), "in-memory tuple with Oid = %d already exists in pg_namespace.", HeapTupleGetOid(tuple)); Oid nspdboid = DatumGetObjectId(tuple_getattr(tuple, tupleDesc, Anum_pg_namespace_nspdboid)); char *nspname = DatumGetCString(tuple_getattr(tuple, tupleDesc, Anum_pg_namespace_nspname)); size_t nspnameLen = strlen(nspname); insist_log(nspdboid != nspdboidNew || nspnameLen != strlen(nspnameNew) || 0 != strncmp(nspname, nspnameNew, nspnameLen), "in-memory tuple with nspname = %s and nspdboid = %d already exists in pg_namespace.", nspname, nspdboid); } }
void dump_bvf1_inputs(ArrayType *broker_list_p, text *sector_name_p) { int ndim, nitems; int *dim; int16 typlen; bool typbyval; char typalign; int i; char *broker_list; ndim = ARR_NDIM(broker_list_p); dim = ARR_DIMS(broker_list_p); nitems = ArrayGetNItems(ndim, dim); get_typlenbyvalalign(ARR_ELEMTYPE(broker_list_p), &typlen, &typbyval, &typalign); broker_list = ARR_DATA_PTR(broker_list_p); elog(NOTICE, "BVF1: INPUTS START"); for (i = 0; i < nitems; i++) { elog(NOTICE, "BVF1: broker_list[%d] %s", i, DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(broker_list)))); broker_list = att_addlength_pointer(broker_list, typlen, broker_list); broker_list = (char *) att_align_nominal(broker_list, typalign); } elog(NOTICE, "BVF1: sector_name %s", DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(sector_name_p)))); elog(NOTICE, "BVF1: INPUTS END"); }
/* * tintervalout - converts an internal tinterval format to a string */ Datum tintervalout(PG_FUNCTION_ARGS) { TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(0); char *i_str, *p; i_str = (char *) palloc(T_INTERVAL_LEN); /* ["..." "..."] */ strcpy(i_str, "[\""); if (tinterval->status == T_INTERVAL_INVAL) strcat(i_str, INVALID_INTERVAL_STR); else { p = DatumGetCString(DirectFunctionCall1(abstimeout, AbsoluteTimeGetDatum(tinterval->data[0]))); strcat(i_str, p); pfree(p); strcat(i_str, "\" \""); p = DatumGetCString(DirectFunctionCall1(abstimeout, AbsoluteTimeGetDatum(tinterval->data[1]))); strcat(i_str, p); pfree(p); } strcat(i_str, "\"]"); PG_RETURN_CSTRING(i_str); }
Datum pgpool_recovery(PG_FUNCTION_ARGS) { int r; char *script = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0)))); char *remote_host = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1)))); char *remote_data_directory = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(2)))); if (!superuser()) #ifdef ERRCODE_INSUFFICIENT_PRIVILEGE ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to use pgpool_recovery function")))); #else elog(ERROR, "must be superuser to use pgpool_recovery function"); #endif if (PG_NARGS() >= 5) /* Pgpool-II 4.0 or later */ { char *remote_port = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(3)))); int recovery_node = PG_GETARG_INT32(4); snprintf(recovery_script, sizeof(recovery_script), "\"%s/%s\" \"%s\" \"%s\" \"%s\" \"%s\" %d", DataDir, script, DataDir, remote_host, remote_data_directory, remote_port, recovery_node); } else if (PG_NARGS() >= 4) /* Pgpool-II 3.4 - 3.7 */ { char *remote_port = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(3)))); snprintf(recovery_script, sizeof(recovery_script), "\"%s/%s\" \"%s\" \"%s\" \"%s\" \"%s\"", DataDir, script, DataDir, remote_host, remote_data_directory, remote_port); } else { snprintf(recovery_script, sizeof(recovery_script), "\"%s/%s\" \"%s\" \"%s\" \"%s\"", DataDir, script, DataDir, remote_host, remote_data_directory); } elog(DEBUG1, "recovery_script: %s", recovery_script); r = system(recovery_script); if (r != 0) { elog(ERROR, "pgpool_recovery failed"); } PG_RETURN_BOOL(true); }
Datum pgpool_pgctl(PG_FUNCTION_ARGS) { int r; char *action = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0)))); char *stop_mode = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1)))); char *pg_ctl; char *data_directory; if (!superuser()) #ifdef ERRCODE_INSUFFICIENT_PRIVILEGE ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to use pgpool_pgctl function")))); #else elog(ERROR, "must be superuser to use pgpool_pgctl function"); #endif #if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 90600) pg_ctl = GetConfigOptionByName("pgpool.pg_ctl", NULL, false); data_directory = GetConfigOptionByName("data_directory", NULL, false); #else pg_ctl = GetConfigOptionByName("pgpool.pg_ctl", NULL); data_directory = GetConfigOptionByName("data_directory", NULL); #endif if (strcmp(stop_mode, "") != 0) { snprintf(command_text, sizeof(command_text), "%s %s -D %s -m %s 2>/dev/null 1>/dev/null < /dev/null &", pg_ctl, action, data_directory, stop_mode); } else { snprintf(command_text, sizeof(command_text), "%s %s -D %s 2>/dev/null 1>/dev/null < /dev/null &", pg_ctl, action, data_directory); } elog(DEBUG1, "command_text: %s", command_text); r = system(command_text); if (strcmp(action, "reload") == 0 && r != 0) { elog(ERROR, "pgpool_pgctl failed"); } PG_RETURN_BOOL(true); }
static PyObject * PLyDecimal_FromNumeric(PLyDatumToOb *arg, Datum d) { static PyObject *decimal_constructor; char *str; PyObject *pyvalue; /* Try to import cdecimal. If it doesn't exist, fall back to decimal. */ if (!decimal_constructor) { PyObject *decimal_module; decimal_module = PyImport_ImportModule("cdecimal"); if (!decimal_module) { PyErr_Clear(); decimal_module = PyImport_ImportModule("decimal"); } if (!decimal_module) PLy_elog(ERROR, "could not import a module for Decimal constructor"); decimal_constructor = PyObject_GetAttrString(decimal_module, "Decimal"); if (!decimal_constructor) PLy_elog(ERROR, "no Decimal attribute in module"); } str = DatumGetCString(DirectFunctionCall1(numeric_out, d)); pyvalue = PyObject_CallFunction(decimal_constructor, "s", str); if (!pyvalue) PLy_elog(ERROR, "conversion from numeric to Decimal failed"); return pyvalue; }
static void fetch_restriction( HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info[4], Restrict_t *restriction) { restriction->id = pgr_SPI_getBigInt(tuple, tupdesc, info[0]); restriction->cost = pgr_SPI_getFloat8(tuple, tupdesc, info[1]); char *str = DatumGetCString( SPI_getvalue(*tuple, *tupdesc, info[2].colNumber)); // TODO(someone) because its text, no guarantee the text read is correct // move this code to c++ to tokenize the integers. int i = 0; for (i = 0; i < MAX_RULE_LENGTH; ++i) restriction->restricted_edges[i] = -1; str[0] = ','; if (str != NULL) { char *token = NULL; int i = 0; token = (char *)strtok(str, " ,"); while (token != NULL && i < MAX_RULE_LENGTH) { restriction->restricted_edges[i] = atoi(token); i++; token = (char *)strtok(NULL, " ,"); } } }
/* * Add typmod decoration to the basic type name */ static char * printTypmod(const char *typname, int32 typmod, Oid typmodout) { char *res; /* Shouldn't be called if typmod is -1 */ Assert(typmod >= 0); if (typmodout == InvalidOid) { /* Default behavior: just print the integer typmod with parens */ res = psnprintf(strlen(typname) + MAX_INT32_LEN + 3, "%s(%d)", typname, (int) typmod); } else { /* Use the type-specific typmodout procedure */ char *tmstr; tmstr = DatumGetCString(OidFunctionCall1(typmodout, Int32GetDatum(typmod))); res = psnprintf(strlen(typname) + strlen(tmstr) + 1, "%s%s", typname, tmstr); } return res; }
Datum binary_decode(PG_FUNCTION_ARGS) { text *data = PG_GETARG_TEXT_P(0); Datum name = PG_GETARG_DATUM(1); bytea *result; char *namebuf; int datalen, resultlen, res; struct pg_encoding *enc; datalen = VARSIZE(data) - VARHDRSZ; namebuf = DatumGetCString(DirectFunctionCall1(textout, name)); enc = pg_find_encoding(namebuf); if (enc == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("unrecognized encoding: \"%s\"", namebuf))); resultlen = enc->decode_len(VARDATA(data), datalen); result = palloc(VARHDRSZ + resultlen); res = enc->decode(VARDATA(data), datalen, VARDATA(result)); /* Make this FATAL 'cause we've trodden on memory ... */ if (res > resultlen) elog(FATAL, "overflow - decode estimate too small"); VARATT_SIZEP(result) = VARHDRSZ + res; PG_RETURN_BYTEA_P(result); }
Datum base36_cast_from_text(PG_FUNCTION_ARGS) { text *txt = PG_GETARG_TEXT_P(0); char *str = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(txt))); PG_RETURN_INT32(base36_from_str(str)); }
static void jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal) { switch (scalarVal->type) { case jbvNull: appendBinaryStringInfo(out, "null", 4); break; case jbvString: escape_json(out, pnstrdup(scalarVal->val.string.val, scalarVal->val.string.len)); break; case jbvNumeric: appendStringInfoString(out, DatumGetCString(DirectFunctionCall1(numeric_out, PointerGetDatum(scalarVal->val.numeric)))); break; case jbvBool: if (scalarVal->val.boolean) appendBinaryStringInfo(out, "true", 4); else appendBinaryStringInfo(out, "false", 5); break; default: elog(ERROR, "unknown jsonb scalar type"); } }
Datum pr_get(PG_FUNCTION_ARGS) { text * key_arg = PG_GETARG_TEXT_P(0); char * key = NULL; char * value = NULL; text * ret_val = NULL; int ret = 0; if (!pgredis || !pgredis->redis_server) { elog(ERROR, "Redis instance missing, unable to get"); PG_RETURN_NULL(); } if (!key_arg) PG_RETURN_NULL(); key = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(key_arg))); if (!key || strlen(key) == 0) PG_RETURN_NULL(); ret = credis_get(pgredis->redis_server, key, &value); if (ret == CREDIS_OK) { ret_val = (text *)palloc(strlen(value) + VARHDRSZ); SET_VARSIZE(ret_val, strlen(value) + VARHDRSZ); memcpy(VARDATA(ret_val), value, strlen(value)); PG_RETURN_TEXT_P(ret_val); } PG_RETURN_NULL(); }
Datum orafce_to_char_numeric(PG_FUNCTION_ARGS) { Numeric arg0 = PG_GETARG_NUMERIC(0); StringInfo buf = makeStringInfo(); struct lconv *lconv = PGLC_localeconv(); char *p; char *decimal = NULL; appendStringInfoString(buf, DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(arg0)))); for (p = buf->data; *p; p++) if (*p == '.') { *p = lconv->decimal_point[0]; decimal = p; /* save decimal point position for the next loop */ } /* Simulate the default Oracle to_char template (TM9 - Text Minimum) by removing unneeded digits after the decimal point; if no digits are left, then remove the decimal point too */ for (p = buf->data + buf->len - 1; decimal && p >= decimal; p--) { if (*p == '0' || *p == lconv->decimal_point[0]) *p = 0; else break; /* non-zero digit found, exit the loop */ } PG_RETURN_TEXT_P(cstring_to_text(buf->data)); }
static void formatTuple(StringInfo buf, HeapTuple tup, TupleDesc tupdesc, Oid *outputFunArray) { int i; for (i = 0; i < tupdesc->natts; i++) { bool isnull; Datum d = heap_getattr(tup, i+1, tupdesc, &isnull); if (d && !isnull) { Datum ds = OidFunctionCall1(outputFunArray[i], d); char *s = DatumGetCString(ds); char *name = NameStr(tupdesc->attrs[i]->attname); if (name && *name) appendStringInfo(buf, " %s=\"%.30s\"", name, s); else appendStringInfo(buf, " \"%.30s\"", s); pfree(s); } } appendStringInfoChar(buf, '\n'); }
char * SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) { Datum origval, val, result; bool isnull; Oid typoid, foutoid, typioparam; int32 typmod; bool typisvarlena; SPI_result = 0; if (fnumber > tuple->t_data->t_natts || fnumber == 0 || fnumber <= FirstLowInvalidHeapAttributeNumber) { SPI_result = SPI_ERROR_NOATTRIBUTE; return NULL; } origval = heap_getattr(tuple, fnumber, tupdesc, &isnull); if (isnull) return NULL; if (fnumber > 0) { typoid = tupdesc->attrs[fnumber - 1]->atttypid; typmod = tupdesc->attrs[fnumber - 1]->atttypmod; } else { typoid = (SystemAttributeDefinition(fnumber, true))->atttypid; typmod = -1; } getTypeOutputInfo(typoid, &foutoid, &typioparam, &typisvarlena); /* * If we have a toasted datum, forcibly detoast it here to avoid * memory leakage inside the type's output routine. */ if (typisvarlena) val = PointerGetDatum(PG_DETOAST_DATUM(origval)); else val = origval; result = OidFunctionCall3(foutoid, val, ObjectIdGetDatum(typioparam), Int32GetDatum(typmod)); /* Clean up detoasted copy, if any */ if (val != origval) pfree(DatumGetPointer(val)); return DatumGetCString(result); }
Datum metaphone(PG_FUNCTION_ARGS) { int reqlen; char *str_i; size_t str_i_len; char *metaph; text *result_text; int retval; str_i = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0)))); str_i_len = strlen(str_i); /* return an empty string if we receive one */ if (!(str_i_len > 0)) PG_RETURN_TEXT_P(GET_TEXT("")); if (str_i_len > MAX_METAPHONE_STRLEN) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("argument exceeds the maximum length of %d bytes", MAX_METAPHONE_STRLEN))); if (!(str_i_len > 0)) ereport(ERROR, (errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING), errmsg("argument is empty string"))); reqlen = PG_GETARG_INT32(1); if (reqlen > MAX_METAPHONE_STRLEN) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("output exceeds the maximum length of %d bytes", MAX_METAPHONE_STRLEN))); if (!(reqlen > 0)) ereport(ERROR, (errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING), errmsg("output cannot be empty string"))); retval = _metaphone(str_i, reqlen, &metaph); if (retval == META_SUCCESS) { result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(metaph))); PG_RETURN_TEXT_P(result_text); } else { /* internal error */ elog(ERROR, "metaphone: failure"); /* * Keep the compiler quiet */ PG_RETURN_NULL(); } }
/* There may be issues with toasted data here. I don't know enough to be sure.*/ Datum cube(PG_FUNCTION_ARGS) { char *cstring; cstring = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0)))); PG_RETURN_DATUM(DirectFunctionCall1(cube_in, PointerGetDatum(cstring))); }
char* pgr_SPI_getText(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info) { char* value = NULL; char* val = NULL; val = SPI_getvalue(*tuple, *tupdesc, info.colNumber); value = DatumGetCString(&val); pfree(val); return value; }
Datum pr_set_server(PG_FUNCTION_ARGS) { text * server_arg = PG_GETARG_TEXT_P(0); char * server; server = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(server_arg))); add_redis_server(server); PG_RETURN_NULL(); }
static jobject coerceScalarDatum(UDT self, Datum arg) { jobject result; int32 dataLen = Type_getLength((Type)self); jclass javaClass = Type_getJavaClass((Type)self); bool isJavaBasedScalar = 0 != self->toString; if(dataLen == -2) { /* Data is a zero terminated string */ jstring jstr = String_createJavaStringFromNTS(DatumGetCString(arg)); result = JNI_callStaticObjectMethod(javaClass, self->parse, jstr, self->sqlTypeName); JNI_deleteLocalRef(jstr); } else { char* data; jobject inputStream; if(dataLen == -1) { /* Data is a varlena struct */ bytea* bytes = DatumGetByteaP(arg); dataLen = VARSIZE(bytes) - VARHDRSZ; data = VARDATA(bytes); } else { bool passByValue = Type_isByValue((Type)self); /* Data is a binary chunk of size dataLen */ if (passByValue) { /* pass by value data is stored in the least * significant bits of a Datum. */ #ifdef WORDS_BIGENDIAN data = ((char *)(&arg)) + SIZEOF_DATUM - dataLen; #else data = ((char *)(&arg)); #endif } else { data = DatumGetPointer(arg); } } result = JNI_newObject(javaClass, self->init); inputStream = SQLInputFromChunk_create(data, dataLen, isJavaBasedScalar); JNI_callVoidMethod(result, self->readSQL, inputStream, self->sqlTypeName); SQLInputFromChunk_close(inputStream); } return result; }
/* * build_dummy_tuple * Generate a palloc'd HeapTuple that contains the specified key * columns, and NULLs for other columns. * * This is used to store the keys for negative cache entries and CatCList * entries, which don't have real tuples associated with them. */ static HeapTuple build_dummy_tuple(CatCache *cache, int nkeys, ScanKey skeys) { HeapTuple ntp; TupleDesc tupDesc = cache->cc_tupdesc; Datum *values; char *nulls; Oid tupOid = InvalidOid; NameData tempNames[4]; int i; values = (Datum *) palloc(tupDesc->natts * sizeof(Datum)); nulls = (char *) palloc(tupDesc->natts * sizeof(char)); memset(values, 0, tupDesc->natts * sizeof(Datum)); memset(nulls, 'n', tupDesc->natts * sizeof(char)); for (i = 0; i < nkeys; i++) { int attindex = cache->cc_key[i]; Datum keyval = skeys[i].sk_argument; if (attindex > 0) { /* * Here we must be careful in case the caller passed a C * string where a NAME is wanted: convert the given argument * to a correctly padded NAME. Otherwise the memcpy() done in * heap_formtuple could fall off the end of memory. */ if (cache->cc_isname[i]) { Name newval = &tempNames[i]; namestrcpy(newval, DatumGetCString(keyval)); keyval = NameGetDatum(newval); } values[attindex - 1] = keyval; nulls[attindex - 1] = ' '; } else { Assert(attindex == ObjectIdAttributeNumber); tupOid = DatumGetObjectId(keyval); } } ntp = heap_formtuple(tupDesc, values, nulls); if (tupOid != InvalidOid) HeapTupleSetOid(ntp, tupOid); pfree(values); pfree(nulls); return ntp; }
/* * This function performs checks for certain system tables to validate tuple * fetched from table has the key, using which it was fetched from index. */ static void CrossCheckTuple(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4, HeapTuple tuple) { Form_pg_class rd_rel; switch (cacheId) { case RELOID: if (HeapTupleGetOid(tuple) != DatumGetObjectId(key1)) { elog(ERROR, "pg_class_oid_index is broken, oid=%d is pointing to tuple with oid=%d (xmin:%u xmax:%u)", DatumGetObjectId(key1), HeapTupleGetOid(tuple), HeapTupleHeaderGetXmin((tuple)->t_data), HeapTupleHeaderGetXmax((tuple)->t_data)); } break; case RELNAMENSP: rd_rel = (Form_pg_class) GETSTRUCT(tuple); if (strncmp(rd_rel->relname.data, DatumGetCString(key1), NAMEDATALEN) != 0) { elog(ERROR, "pg_class_relname_nsp_index is broken, intended tuple with name \"%s\" fetched \"%s\"" " (xmin:%u xmax:%u)", DatumGetCString(key1), rd_rel->relname.data, HeapTupleHeaderGetXmin((tuple)->t_data), HeapTupleHeaderGetXmax((tuple)->t_data)); } break; case TYPEOID: if (HeapTupleGetOid(tuple) != DatumGetObjectId(key1)) { elog(ERROR, "pg_type_oid_index is broken, oid=%d is pointing to tuple with oid=%d (xmin:%u xmax:%u)", DatumGetObjectId(key1), HeapTupleGetOid(tuple), HeapTupleHeaderGetXmin((tuple)->t_data), HeapTupleHeaderGetXmax((tuple)->t_data)); } break; } }
/* * Validator for C language functions * * Make sure that the library file exists, is loadable, and contains * the specified link symbol. Also check for a valid function * information record. */ Datum fmgr_c_validator(PG_FUNCTION_ARGS) { Oid funcoid = PG_GETARG_OID(0); void *libraryhandle; HeapTuple tuple; Form_pg_proc proc; bool isnull; Datum tmp; char *prosrc; char *probin; /* * It'd be most consistent to skip the check if !check_function_bodies, * but the purpose of that switch is to be helpful for pg_dump loading, * and for pg_dump loading it's much better if we *do* check. */ tuple = SearchSysCache(PROCOID, ObjectIdGetDatum(funcoid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for function %u", funcoid); proc = (Form_pg_proc) GETSTRUCT(tuple); tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull); if (isnull) elog(ERROR, "null prosrc"); prosrc = DatumGetCString(DirectFunctionCall1(textout, tmp)); tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_probin, &isnull); if (isnull) elog(ERROR, "null probin"); probin = DatumGetCString(DirectFunctionCall1(textout, tmp)); (void) load_external_function(probin, prosrc, true, &libraryhandle); (void) fetch_finfo_record(libraryhandle, prosrc); ReleaseSysCache(tuple); PG_RETURN_VOID(); }
Datum set_timetravel(PG_FUNCTION_ARGS) { Name relname = PG_GETARG_NAME(0); int32 on = PG_GETARG_INT32(1); char *rname; char *d; char *s; int32 ret; TTOffList *p, *pp; for (pp = (p = &TTOff)->next; pp; pp = (p = pp)->next) { if (namestrcmp(relname, pp->name) == 0) break; } if (pp) { /* OFF currently */ if (on != 0) { /* turn ON */ p->next = pp->next; free(pp); } ret = 0; } else { /* ON currently */ if (on == 0) { /* turn OFF */ s = rname = DatumGetCString(DirectFunctionCall1(nameout, NameGetDatum(relname))); if (s) { pp = malloc(sizeof(TTOffList) + strlen(rname)); if (pp) { pp->next = NULL; p->next = pp; d = pp->name; while (*s) *d++ = tolower((unsigned char) *s++); *d = '\0'; } pfree(rname); } } ret = 1; } PG_RETURN_INT32(ret); }
jvalue _String_coerceDatum(Type self, Datum arg) { jvalue result; char* tmp = DatumGetCString(FunctionCall3( &((String)self)->textOutput, arg, ObjectIdGetDatum(((String)self)->elementType), Int32GetDatum(-1))); result.l = String_createJavaStringFromNTS(tmp); pfree(tmp); return result; }
/* * anyarray_out - output routine for pseudo-type ANYARRAY. * * We may as well allow this, since array_out will in fact work. * XCP needs to send from data nodes to coordinator values of that type. * To be able to restore values at the destination node we need to know * actual element type. */ Datum anyarray_out(PG_FUNCTION_ARGS) { #ifdef XCP /* * Output prefix: (type_namespace_name.typename) to look up actual element * type at the destination node then output in usual format for array */ ArrayType *v = PG_GETARG_ARRAYTYPE_P(0); Oid element_type = ARR_ELEMTYPE(v); Form_pg_type typeForm; HeapTuple typeTuple; char *typname, *typnspname; /* two identifiers, parenthesis, dot and trailing \0 */ char prefix[2*NAMEDATALEN+4], *retval, *newval; int prefixlen, retvallen; Datum array_out_result; MemoryContext save_context; save_context = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt); /* Figure out type name and type namespace */ typeTuple = SearchSysCache(TYPEOID, ObjectIdGetDatum(element_type), 0, 0, 0); if (!HeapTupleIsValid(typeTuple)) elog(ERROR, "cache lookup failed for type %u", element_type); typeForm = (Form_pg_type) GETSTRUCT(typeTuple); typname = NameStr(typeForm->typname); typnspname = get_namespace_name(typeForm->typnamespace); sprintf(prefix, "(%s.%s)", typnspname, typname); ReleaseSysCache(typeTuple); MemoryContextSwitchTo(save_context); /* Get standard output and make up prefixed result */ array_out_result = array_out(fcinfo); retval = DatumGetCString(array_out_result); prefixlen = strlen(prefix); retvallen = strlen(retval); newval = (char *) palloc(prefixlen + retvallen + 1); strcpy(newval, prefix); strcpy(newval + prefixlen, retval); pfree(retval); PG_RETURN_CSTRING(newval); #else return array_out(fcinfo); #endif }