static bool gbt_dategt(const void *a, const void *b) { return DatumGetBool( DirectFunctionCall2(date_gt, DateADTGetDatum(*((DateADT *) a)), DateADTGetDatum(*((DateADT *) b))) ); }
bool type_is_domain(char *type_name, Oid *base_type) { bool rc; StringInfo query; SPI_connect(); query = makeStringInfo(); appendStringInfo(query, "SELECT typtype = 'd', typbasetype FROM pg_type WHERE typname = %s", TextDatumGetCString(DirectFunctionCall1(quote_literal, CStringGetTextDatum(type_name)))); if (SPI_execute(query->data, true, 1) != SPI_OK_SELECT) elog(ERROR, "Problem determing if %s is a domain with query: %s", type_name, query->data); if (SPI_processed == 0) { rc = false; } else { bool isnull; Datum d; d = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull); rc = isnull || DatumGetBool(d); d = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 2, &isnull); *base_type = isnull ? InvalidOid : DatumGetObjectId(d); } SPI_finish(); return rc; }
static bool array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree **found) { int num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la)); ltree *item = (ltree *) ARR_DATA_PTR(la); if (ARR_NDIM(la) > 1) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("array must be one-dimensional"))); if (array_contains_nulls(la)) ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("array must not contain nulls"))); if (found) *found = NULL; while (num > 0) { if (DatumGetBool(DirectFunctionCall2(callback, PointerGetDatum(item), PointerGetDatum(param)))) { if (found) *found = item; return true; } num--; item = NEXTVAL(item); } return false; }
static bool gbt_bitlt(const void *a, const void *b, Oid collation) { return DatumGetBool(DirectFunctionCall2(bitlt, PointerGetDatum(a), PointerGetDatum(b))); }
/* * execTuplesMatch * Return true if two tuples match in all the indicated fields. * * This actually implements SQL's notion of "not distinct". Two nulls * match, a null and a not-null don't match. * * slot1, slot2: the tuples to compare (must have same columns!) * numCols: the number of attributes to be examined * matchColIdx: array of attribute column numbers * eqFunctions: array of fmgr lookup info for the equality functions to use * evalContext: short-term memory context for executing the functions * * NB: evalContext is reset each time! */ bool execTuplesMatch(TupleTableSlot *slot1, TupleTableSlot *slot2, int numCols, AttrNumber *matchColIdx, FmgrInfo *eqfunctions, MemoryContext evalContext) { MemoryContext oldContext; bool result; int i; /* Reset and switch into the temp context. */ MemoryContextReset(evalContext); oldContext = MemoryContextSwitchTo(evalContext); /* * We cannot report a match without checking all the fields, but we can * report a non-match as soon as we find unequal fields. So, start * comparing at the last field (least significant sort key). That's the * most likely to be different if we are dealing with sorted input. */ result = true; for (i = numCols; --i >= 0;) { AttrNumber att = matchColIdx[i]; Datum attr1, attr2; bool isNull1, isNull2; attr1 = slot_getattr(slot1, att, &isNull1); attr2 = slot_getattr(slot2, att, &isNull2); if (isNull1 != isNull2) { result = false; /* one null and one not; they aren't equal */ break; } if (isNull1) continue; /* both are null, treat as equal */ /* Apply the type-specific equality function */ if (!DatumGetBool(FunctionCall2(&eqfunctions[i], attr1, attr2))) { result = false; /* they aren't equal */ break; } } MemoryContextSwitchTo(oldContext); return result; }
/* * tintervalov - returns true iff tinterval i1 (partially) overlaps i2 */ Datum tintervalov(PG_FUNCTION_ARGS) { TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0); TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1); if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL) PG_RETURN_BOOL(false); if (DatumGetBool(DirectFunctionCall2(abstimelt, AbsoluteTimeGetDatum(i1->data[1]), AbsoluteTimeGetDatum(i2->data[0]))) || DatumGetBool(DirectFunctionCall2(abstimegt, AbsoluteTimeGetDatum(i1->data[0]), AbsoluteTimeGetDatum(i2->data[1])))) PG_RETURN_BOOL(false); PG_RETURN_BOOL(true); }
static bool gbt_textlt(const void *a, const void *b) { return DatumGetBool(DirectFunctionCall2Coll(text_lt, DEFAULT_COLLATION_OID, PointerGetDatum(a), PointerGetDatum(b))); }
static bool gbt_textle(const void *a, const void *b, Oid collation) { return DatumGetBool(DirectFunctionCall2Coll(text_le, collation, PointerGetDatum(a), PointerGetDatum(b))); }
void GpPersistentRelationNode_GetValues( Datum *values, Oid *tablespaceOid, Oid *databaseOid, Oid *relfilenodeOid, int32 *segmentFileNum, PersistentFileSysRelStorageMgr *relationStorageManager, PersistentFileSysState *persistentState, int64 *createMirrorDataLossTrackingSessionNum, MirroredObjectExistenceState *mirrorExistenceState, MirroredRelDataSynchronizationState *mirrorDataSynchronizationState, bool *mirrorBufpoolMarkedForScanIncrementalResync, int64 *mirrorBufpoolResyncChangedPageCount, XLogRecPtr *mirrorBufpoolResyncCkptLoc, BlockNumber *mirrorBufpoolResyncCkptBlockNum, int64 *mirrorAppendOnlyLossEof, int64 *mirrorAppendOnlyNewEof, PersistentFileSysRelBufpoolKind *relBufpoolKind, TransactionId *parentXid, int64 *persistentSerialNum) { *tablespaceOid = DatumGetObjectId(values[Anum_gp_persistent_relation_node_tablespace_oid - 1]); *databaseOid = DatumGetObjectId(values[Anum_gp_persistent_relation_node_database_oid - 1]); *relfilenodeOid = DatumGetObjectId(values[Anum_gp_persistent_relation_node_relfilenode_oid - 1]); *segmentFileNum = DatumGetInt32(values[Anum_gp_persistent_relation_node_segment_file_num - 1]); *relationStorageManager = (PersistentFileSysRelStorageMgr)DatumGetInt16(values[Anum_gp_persistent_relation_node_relation_storage_manager - 1]); *persistentState = (PersistentFileSysState)DatumGetInt16(values[Anum_gp_persistent_relation_node_persistent_state - 1]); *createMirrorDataLossTrackingSessionNum = DatumGetInt64(values[Anum_gp_persistent_relation_node_create_mirror_data_loss_tracking_session_num - 1]); *mirrorExistenceState = (MirroredObjectExistenceState)DatumGetInt16(values[Anum_gp_persistent_relation_node_mirror_existence_state - 1]); *mirrorDataSynchronizationState = (MirroredRelDataSynchronizationState)DatumGetInt16(values[Anum_gp_persistent_relation_node_mirror_data_synchronization_state - 1]); *mirrorBufpoolMarkedForScanIncrementalResync = DatumGetBool(values[Anum_gp_persistent_relation_node_mirror_bufpool_marked_for_scan_incremental_resync - 1]); *mirrorBufpoolResyncChangedPageCount = DatumGetInt64(values[Anum_gp_persistent_relation_node_mirror_bufpool_resync_changed_page_count - 1]); *mirrorBufpoolResyncCkptLoc = *((XLogRecPtr*) DatumGetPointer(values[Anum_gp_persistent_relation_node_mirror_bufpool_resync_ckpt_loc - 1])); *mirrorBufpoolResyncCkptBlockNum = (BlockNumber)DatumGetInt32(values[Anum_gp_persistent_relation_node_mirror_bufpool_resync_ckpt_block_num - 1]); *mirrorAppendOnlyLossEof = DatumGetInt64(values[Anum_gp_persistent_relation_node_mirror_append_only_loss_eof - 1]); *mirrorAppendOnlyNewEof = DatumGetInt64(values[Anum_gp_persistent_relation_node_mirror_append_only_new_eof - 1]); *relBufpoolKind = (PersistentFileSysRelBufpoolKind)DatumGetInt32(values[Anum_gp_persistent_relation_node_relation_bufpool_kind - 1]); *parentXid = (TransactionId)DatumGetInt32(values[Anum_gp_persistent_relation_node_parent_xid - 1]); *persistentSerialNum = DatumGetInt64(values[Anum_gp_persistent_relation_node_persistent_serial_num - 1]); }
/* * intinterval - returns true iff absolute date is in the tinterval */ Datum intinterval(PG_FUNCTION_ARGS) { AbsoluteTime t = PG_GETARG_ABSOLUTETIME(0); TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(1); if (tinterval->status == T_INTERVAL_VALID && t != INVALID_ABSTIME) { if (DatumGetBool(DirectFunctionCall2(abstimege, AbsoluteTimeGetDatum(t), AbsoluteTimeGetDatum(tinterval->data[0]))) && DatumGetBool(DirectFunctionCall2(abstimele, AbsoluteTimeGetDatum(t), AbsoluteTimeGetDatum(tinterval->data[1])))) PG_RETURN_BOOL(true); } PG_RETURN_BOOL(false); }
/** * Convert postgres Datum into a ConcreteValue object. */ AbstractValueSPtr AbstractPGValue::DatumToValue(bool inMemoryIsWritable, Oid inTypeID, Datum inDatum) const { // First check if datum is rowtype if (type_is_rowtype(inTypeID)) { HeapTupleHeader pgTuple = DatumGetHeapTupleHeader(inDatum); return AbstractValueSPtr(new PGValue<HeapTupleHeader>(pgTuple)); } else if (type_is_array(inTypeID)) { ArrayType *pgArray = DatumGetArrayTypeP(inDatum); if (ARR_NDIM(pgArray) != 1) throw std::invalid_argument("Multidimensional arrays not yet supported"); if (ARR_HASNULL(pgArray)) throw std::invalid_argument("Arrays with NULLs not yet supported"); switch (ARR_ELEMTYPE(pgArray)) { case FLOAT8OID: { MemHandleSPtr memoryHandle(new PGArrayHandle(pgArray)); if (inMemoryIsWritable) { return AbstractValueSPtr( new ConcreteValue<Array<double> >( Array<double>(memoryHandle, boost::extents[ ARR_DIMS(pgArray)[0] ]) ) ); } else { return AbstractValueSPtr( new ConcreteValue<Array_const<double> >( Array_const<double>(memoryHandle, boost::extents[ ARR_DIMS(pgArray)[0] ]) ) ); } } } } switch (inTypeID) { case BOOLOID: return AbstractValueSPtr( new ConcreteValue<bool>( DatumGetBool(inDatum) )); case INT2OID: return AbstractValueSPtr( new ConcreteValue<int16_t>( DatumGetInt16(inDatum) )); case INT4OID: return AbstractValueSPtr( new ConcreteValue<int32_t>( DatumGetInt32(inDatum) )); case INT8OID: return AbstractValueSPtr( new ConcreteValue<int64_t>( DatumGetInt64(inDatum) )); case FLOAT4OID: return AbstractValueSPtr( new ConcreteValue<float>( DatumGetFloat4(inDatum) )); case FLOAT8OID: return AbstractValueSPtr( new ConcreteValue<double>( DatumGetFloat8(inDatum) )); } return AbstractValueSPtr(); }
static bool gbt_tsle(const void *a, const void *b, FmgrInfo *flinfo) { const Timestamp *aa = (const Timestamp *) a; const Timestamp *bb = (const Timestamp *) b; return DatumGetBool(DirectFunctionCall2(timestamp_le, TimestampGetDatumFast(*aa), TimestampGetDatumFast(*bb))); }
static bool gbt_timelt(const void *a, const void *b) { const TimeADT *aa = (const TimeADT *) a; const TimeADT *bb = (const TimeADT *) b; return DatumGetBool(DirectFunctionCall2(time_lt, TimeADTGetDatumFast(*aa), TimeADTGetDatumFast(*bb))); }
static bool gbt_tslt(const void *a, const void *b) { const Timestamp *aa = (const Timestamp *) a; const Timestamp *bb = (const Timestamp *) b; return DatumGetBool(DirectFunctionCall2(timestamp_lt, TimestampGetDatumFast(*aa), TimestampGetDatumFast(*bb))); }
static inline bool ipaddr_comparison_bool(Datum d1, Datum d2, bool mismatch_af1, bool mismatch_af2, PGFunction ip4func, PGFunction ip6func) { IP_P ipp1 = DatumGetIP_P(d1); IP_P ipp2 = DatumGetIP_P(d2); IP ip1; IP ip2; int af1 = ip_unpack(ipp1, &ip1); int af2 = ip_unpack(ipp2, &ip2); bool retval; if (af1 != af2) { retval = (af1 > af2) ? mismatch_af1 : mismatch_af2; } else { switch (af1) { case PGSQL_AF_INET: retval = DatumGetBool(DirectFunctionCall2(ip4func, IP4GetDatum(ip1.ip4), IP4GetDatum(ip2.ip4))); break; case PGSQL_AF_INET6: retval = DatumGetBool(DirectFunctionCall2(ip6func, IP6PGetDatum(&ip1.ip6), IP6PGetDatum(&ip2.ip6))); break; default: ipaddr_internal_error(); } } if ((Pointer)ipp1 != DatumGetPointer(d1)) pfree(ipp1); if ((Pointer)ipp2 != DatumGetPointer(d2)) pfree(ipp2); return retval; }
Datum _int_different(PG_FUNCTION_ARGS) { PG_RETURN_BOOL(!DatumGetBool( DirectFunctionCall2( _int_same, PointerGetDatum(PG_GETARG_POINTER(0)), PointerGetDatum(PG_GETARG_POINTER(1)) ) )); }
/* * Turn a scalar Datum into JSON, appending the string to "result". * * Hand off a non-scalar datum to composite_to_json or array_to_json_internal * as appropriate. */ static void datum_to_json(Datum val, bool is_null, StringInfo result, TYPCATEGORY tcategory, Oid typoutputfunc) { char *outputstr; if (is_null) { appendStringInfoString(result, "null"); return; } switch (tcategory) { case TYPCATEGORY_ARRAY: array_to_json_internal(val, result, false); break; case TYPCATEGORY_COMPOSITE: composite_to_json(val, result, false); break; case TYPCATEGORY_BOOLEAN: if (DatumGetBool(val)) appendStringInfoString(result, "true"); else appendStringInfoString(result, "false"); break; case TYPCATEGORY_NUMERIC: outputstr = OidOutputFunctionCall(typoutputfunc, val); /* * Don't call escape_json here if it's a valid JSON number. * Numeric output should usually be a valid JSON number and JSON * numbers shouldn't be quoted. Quote cases like "Nan" and * "Infinity", however. */ if (strpbrk(outputstr, NON_NUMERIC_LETTER) == NULL) appendStringInfoString(result, outputstr); else escape_json(result, outputstr); pfree(outputstr); break; case TYPCATEGORY_JSON: /* JSON will already be escaped */ outputstr = OidOutputFunctionCall(typoutputfunc, val); appendStringInfoString(result, outputstr); pfree(outputstr); break; default: outputstr = OidOutputFunctionCall(typoutputfunc, val); escape_json(result, outputstr); pfree(outputstr); break; } }
Datum _int_contained(PG_FUNCTION_ARGS) { PG_RETURN_BOOL(DatumGetBool( DirectFunctionCall2( _int_contains, PointerGetDatum(PG_GETARG_POINTER(1)), PointerGetDatum(PG_GETARG_POINTER(0)) ) )); }
static void execute_pg_settings_logger(config_log_objects *objects) { int ret; bool isnull; StringInfoData buf; SetCurrentStatementStartTimestamp(); StartTransactionCommand(); SPI_connect(); PushActiveSnapshot(GetTransactionSnapshot()); pgstat_report_activity(STATE_RUNNING, "executing configuration logger function"); initStringInfo(&buf); appendStringInfo( &buf, "SELECT %s.%s()", config_log_schema, objects->function_name ); ret = SPI_execute(buf.data, false, 0); if (ret != SPI_OK_SELECT) { elog(FATAL, "SPI_execute failed: error code %d", ret); } if (SPI_processed != 1) { elog(FATAL, "not a singleton result"); } log_info("pg_settings_logger() executed"); if(DatumGetBool(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull))) { log_info("Configuration changes recorded"); } else { log_info("No configuration changes detected"); } SPI_finish(); PopActiveSnapshot(); CommitTransactionCommand(); pgstat_report_activity(STATE_IDLE, NULL); }
Interval * abs_interval(Interval *a) { static Interval zero = {0, 0, 0}; if (DatumGetBool(DirectFunctionCall2(interval_lt, IntervalPGetDatum(a), IntervalPGetDatum(&zero)))) a = DatumGetIntervalP(DirectFunctionCall1(interval_um, IntervalPGetDatum(a))); return a; }
static PyObject * PLyBool_FromBool(PLyDatumToOb *arg, Datum d) { /* * We would like to use Py_RETURN_TRUE and Py_RETURN_FALSE here for * generating SQL from trigger functions, but those are only supported in * Python >= 2.3, and we support older versions. * http://docs.python.org/api/boolObjects.html */ if (DatumGetBool(d)) return PyBool_FromLong(1); return PyBool_FromLong(0); }
/* ** Equality method */ Datum gbox_same(PG_FUNCTION_ARGS) { BOX *b1 = (BOX *) PG_GETARG_POINTER(0); BOX *b2 = (BOX *) PG_GETARG_POINTER(1); bool *result = (bool *) PG_GETARG_POINTER(2); if (b1 && b2) *result = DatumGetBool(DirectFunctionCall2(box_same, PointerGetDatum(b1), PointerGetDatum(b2))); else *result = (b1 == NULL && b2 == NULL) ? TRUE : FALSE; PG_RETURN_POINTER(result); }
/* * Test whether key1 matches key2. Since the equality functions may leak, * reset the temporary context at each call and do all equality calculation * in that context. */ static int build_match_key(const void *key1, const void *key2, Size keysize __attribute__((unused))) { Assert(key1); Assert(key2); BMBuildHashKey *keyData1 = (BMBuildHashKey*)key1; Datum *k1 = keyData1->attributeValueArr; bool *isNull1 = keyData1->isNullArr; BMBuildHashKey *keyData2 = (BMBuildHashKey*)key2; Datum *k2 = keyData2->attributeValueArr; bool *isNull2 = keyData2->isNullArr; int numKeys = cur_bmbuild->natts; int i; MemoryContext old; int result = 0; MemoryContextReset(cur_bmbuild->tmpcxt); old = MemoryContextSwitchTo(cur_bmbuild->tmpcxt); for(i = 0; i < numKeys; i++) { if (isNull1[i] && isNull2[i]) { /* both nulls -- treat as equal so we group them together */ } else if ( isNull1[i] || isNull2[i]) { /* one is null and one non-null -- this is inequal */ result = 1; break; } else { /* do the real comparison */ Datum attr1 = k1[i]; Datum attr2 = k2[i]; if (!DatumGetBool(FunctionCall2(&cur_bmbuild->eq_funcs[i], attr1, attr2))) { result = 1; /* they aren't equal */ break; } } } MemoryContextSwitchTo(old); return result; }
/* ---------------- * index_can_return - does index support index-only scans? * ---------------- */ bool index_can_return(Relation indexRelation) { FmgrInfo *procedure; RELATION_CHECKS; /* amcanreturn is optional; assume FALSE if not provided by AM */ if (!RegProcedureIsValid(indexRelation->rd_am->amcanreturn)) return false; GET_REL_PROCEDURE(amcanreturn); return DatumGetBool(FunctionCall1(procedure, PointerGetDatum(indexRelation))); }
static void override_fields(struct PgqTriggerEvent *ev) { TriggerData *tg = ev->tgdata; int res, i; char *val; /* no overrides */ if (!ev->tgargs) return; for (i = 0; i < EV_NFIELDS; i++) { if (!ev->tgargs->query[i]) continue; res = qb_execute(ev->tgargs->query[i], tg); if (res != SPI_OK_SELECT) elog(ERROR, "Override query failed"); if (SPI_processed != 1) elog(ERROR, "Expect 1 row from override query, got %d", SPI_processed); /* special handling for EV_WHEN */ if (i == EV_WHEN) { bool isnull; Oid oid = SPI_gettypeid(SPI_tuptable->tupdesc, 1); Datum res; if (oid != BOOLOID) elog(ERROR, "when= query result must be boolean, got=%u", oid); res = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull); if (isnull) elog(ERROR, "when= should not be NULL"); if (DatumGetBool(res) == 0) ev->skip_event = true; continue; } /* normal field */ val = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1); if (ev->field[i]) { pfree(ev->field[i]->data); pfree(ev->field[i]); ev->field[i] = NULL; } if (val) { ev->field[i] = pgq_init_varbuf(); appendStringInfoString(ev->field[i], val); } } }
/* * Compare the tuple and slot and check if they have equal values. * * We use binary datum comparison which might return false negatives but * that's the best we can do here as there may be multiple notions of * equality for the data types and table columns don't specify which one * to use. */ static bool tuple_equals_slot(TupleDesc desc, HeapTuple tup, TupleTableSlot *slot) { Datum values[MaxTupleAttributeNumber]; bool isnull[MaxTupleAttributeNumber]; int attrnum; heap_deform_tuple(tup, desc, values, isnull); /* Check equality of the attributes. */ for (attrnum = 0; attrnum < desc->natts; attrnum++) { Form_pg_attribute att; TypeCacheEntry *typentry; /* * If one value is NULL and other is not, then they are certainly not * equal */ if (isnull[attrnum] != slot->tts_isnull[attrnum]) return false; /* * If both are NULL, they can be considered equal. */ if (isnull[attrnum]) continue; att = TupleDescAttr(desc, attrnum); typentry = lookup_type_cache(att->atttypid, TYPECACHE_EQ_OPR_FINFO); if (!OidIsValid(typentry->eq_opr_finfo.fn_oid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("could not identify an equality operator for type %s", format_type_be(att->atttypid)))); if (!DatumGetBool(FunctionCall2(&typentry->eq_opr_finfo, values[attrnum], slot->tts_values[attrnum]))) return false; } return true; }
/* * _hash_checkqual -- does the index tuple satisfy the scan conditions? */ bool _hash_checkqual(IndexScanDesc scan, IndexTuple itup) { /* * Currently, we can't check any of the scan conditions since we do not * have the original index entry value to supply to the sk_func. Always * return true; we expect that hashgettuple already set the recheck flag * to make the main indexscan code do it. */ #ifdef NOT_USED TupleDesc tupdesc = RelationGetDescr(scan->indexRelation); ScanKey key = scan->keyData; int scanKeySize = scan->numberOfKeys; while (scanKeySize > 0) { Datum datum; bool isNull; Datum test; datum = index_getattr(itup, key->sk_attno, tupdesc, &isNull); /* assume sk_func is strict */ if (isNull) return false; if (key->sk_flags & SK_ISNULL) return false; test = FunctionCall2Coll(&key->sk_func, key->sk_collation, datum, key->sk_argument); if (!DatumGetBool(test)) return false; key++; scanKeySize--; } #endif return true; }
Datum ts_match_tq(PG_FUNCTION_ARGS) { TSVector vector; TSQuery query = PG_GETARG_TSQUERY(1); bool res; vector = DatumGetTSVector(DirectFunctionCall1(to_tsvector, PG_GETARG_DATUM(0))); res = DatumGetBool(DirectFunctionCall2(ts_match_vq, TSVectorGetDatum(vector), TSQueryGetDatum(query))); pfree(vector); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(res); }
/* * Turn a scalar Datum into JSON. Hand off a non-scalar datum to * composite_to_json or array_to_json_internal as appropriate. */ static inline void datum_to_json(Datum val, StringInfo result, TYPCATEGORY tcategory, Oid typoutputfunc) { char *outputstr; if (val == (Datum) NULL) { appendStringInfoString(result,"null"); return; } switch (tcategory) { case TYPCATEGORY_ARRAY: array_to_json_internal(val, result, false); break; case TYPCATEGORY_COMPOSITE: composite_to_json(val, result, false); break; case TYPCATEGORY_BOOLEAN: if (DatumGetBool(val)) appendStringInfoString(result,"true"); else appendStringInfoString(result,"false"); break; case TYPCATEGORY_NUMERIC: outputstr = OidOutputFunctionCall(typoutputfunc, val); /* * Don't call escape_json here. Numeric output should * be a valid JSON number and JSON numbers shouldn't * be quoted. */ appendStringInfoString(result, outputstr); pfree(outputstr); break; default: outputstr = OidOutputFunctionCall(typoutputfunc, val); escape_json(result, outputstr); pfree(outputstr); } }
/* * A helper function for calling a regular, binary logic, consistent function. */ static bool directBoolConsistentFn(GinScanKey key) { /* * Initialize recheckCurItem in case the consistentFn doesn't know it * should set it. The safe assumption in that case is to force recheck. */ key->recheckCurItem = true; return DatumGetBool(FunctionCall8Coll(key->consistentFmgrInfo, key->collation, PointerGetDatum(key->entryRes), UInt16GetDatum(key->strategy), key->query, UInt32GetDatum(key->nuserentries), PointerGetDatum(key->extra_data), PointerGetDatum(&key->recheckCurItem), PointerGetDatum(key->queryValues), PointerGetDatum(key->queryCategories))); }