Datum btint82cmp(PG_FUNCTION_ARGS) { int64 a = PG_GETARG_INT64(0); int16 b = PG_GETARG_INT16(1); if (a > b) PG_RETURN_INT32(A_GREATER_THAN_B); else if (a == b) PG_RETURN_INT32(0); else PG_RETURN_INT32(A_LESS_THAN_B); }
Datum int8div(PG_FUNCTION_ARGS) { int64 arg1 = PG_GETARG_INT64(0); int64 arg2 = PG_GETARG_INT64(1); int64 result; if (arg2 == 0) { ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); /* ensure compiler realizes we mustn't reach the division (gcc bug) */ PG_RETURN_NULL(); } /* * INT64_MIN / -1 is problematic, since the result can't be represented on * a two's-complement machine. Some machines produce INT64_MIN, some * produce zero, some throw an exception. We can dodge the problem by * recognizing that division by -1 is the same as negation. */ if (arg2 == -1) { result = -arg1; /* overflow check (needed for INT64_MIN) */ if (arg1 != 0 && SAMESIGN(result, arg1)) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); PG_RETURN_INT64(result); } /* No overflow is possible */ result = arg1 / arg2; PG_RETURN_INT64(result); }
Datum btint82cmp(PG_FUNCTION_ARGS) { int64 a = PG_GETARG_INT64(0); int16 b = PG_GETARG_INT16(1); if (a > b) PG_RETURN_INT32(1); else if (a == b) PG_RETURN_INT32(0); else PG_RETURN_INT32(-1); }
/* * pg_advisory_unlock_shared(int8) - release share lock on an int8 key * * Returns true if successful, false if lock was not held */ Datum pg_advisory_unlock_shared_int8(PG_FUNCTION_ARGS) { int64 key = PG_GETARG_INT64(0); LOCKTAG tag; bool res; SET_LOCKTAG_INT64(tag, key); res = LockRelease(&tag, ShareLock, true); PG_RETURN_BOOL(res); }
/* * Read a section of a file, returning it as bytea */ Datum pg_read_binary_file(PG_FUNCTION_ARGS) { text *filename_t = PG_GETARG_TEXT_P(0); int64 seek_offset = PG_GETARG_INT64(1); int64 bytes_to_read = PG_GETARG_INT64(2); char *filename; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to read files")))); filename = convert_and_check_filename(filename_t); if (bytes_to_read < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("requested length cannot be negative"))); PG_RETURN_BYTEA_P(read_binary_file(filename, seek_offset, bytes_to_read)); }
Datum btint48cmp(PG_FUNCTION_ARGS) { int32 a = PG_GETARG_INT32(0); int64 b = PG_GETARG_INT64(1); if (a > b) PG_RETURN_INT32(1); else if (a == b) PG_RETURN_INT32(0); else PG_RETURN_INT32(-1); }
/* * pg_try_advisory_lock_shared(int8) - acquire share lock on an int8 key, no wait * * Returns true if successful, false if lock not available */ Datum pg_try_advisory_lock_shared_int8(PG_FUNCTION_ARGS) { int64 key = PG_GETARG_INT64(0); LOCKTAG tag; LockAcquireResult res; SET_LOCKTAG_INT64(tag, key); res = LockAcquire(&tag, ShareLock, true, true); PG_RETURN_BOOL(res != LOCKACQUIRE_NOT_AVAIL); }
/* * pg_advisory_xact_lock_shared(int8) - acquire xact scoped * share lock on an int8 key */ Datum pg_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS) { int64 key = PG_GETARG_INT64(0); LOCKTAG tag; PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); (void) LockAcquire(&tag, ShareLock, false, false); PG_RETURN_VOID(); }
/* * Visibility map information for a single block of a relation, plus the * page-level information for the same block. */ Datum pg_visibility(PG_FUNCTION_ARGS) { Oid relid = PG_GETARG_OID(0); int64 blkno = PG_GETARG_INT64(1); int32 mapbits; Relation rel; Buffer vmbuffer = InvalidBuffer; Buffer buffer; Page page; TupleDesc tupdesc; Datum values[3]; bool nulls[3]; rel = relation_open(relid, AccessShareLock); if (blkno < 0 || blkno > MaxBlockNumber) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid block number"))); tupdesc = pg_visibility_tupdesc(false, true); MemSet(nulls, 0, sizeof(nulls)); mapbits = (int32) visibilitymap_get_status(rel, blkno, &vmbuffer); if (vmbuffer != InvalidBuffer) ReleaseBuffer(vmbuffer); values[0] = BoolGetDatum((mapbits & VISIBILITYMAP_ALL_VISIBLE) != 0); values[1] = BoolGetDatum((mapbits & VISIBILITYMAP_ALL_FROZEN) != 0); /* Here we have to explicitly check rel size ... */ if (blkno < RelationGetNumberOfBlocks(rel)) { buffer = ReadBuffer(rel, blkno); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = BufferGetPage(buffer); values[2] = BoolGetDatum(PageIsAllVisible(page)); UnlockReleaseBuffer(buffer); } else { /* As with the vismap, silently return 0 for pages past EOF */ values[2] = BoolGetDatum(false); } relation_close(rel, AccessShareLock); PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls))); }
/* * Read a section of a file, returning it as text * * This function is kept to support adminpack 1.0. */ Datum pg_read_file(PG_FUNCTION_ARGS) { text *filename_t = PG_GETARG_TEXT_PP(0); int64 seek_offset = 0; int64 bytes_to_read = -1; bool missing_ok = false; char *filename; text *result; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to read files with adminpack 1.0"), errhint("Consider using pg_file_read(), which is part of core, instead.")))); /* handle optional arguments */ if (PG_NARGS() >= 3) { seek_offset = PG_GETARG_INT64(1); bytes_to_read = PG_GETARG_INT64(2); if (bytes_to_read < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("requested length cannot be negative"))); } if (PG_NARGS() >= 4) missing_ok = PG_GETARG_BOOL(3); filename = convert_and_check_filename(filename_t); result = read_text_file(filename, seek_offset, bytes_to_read, missing_ok); if (result) PG_RETURN_TEXT_P(result); else PG_RETURN_NULL(); }
Datum linterp_int64(PG_FUNCTION_ARGS) { float8 y0; float8 y1; float8 p; float8 r; int64 result; bool eq_bounds = false; bool eq_abscissas = false; /* Common */ p = linterp_abscissa(fcinfo, &eq_bounds, &eq_abscissas); /* Ordinate type specific code*/ y0 = (float8)PG_GETARG_INT64(2); y1 = (float8)PG_GETARG_INT64(4); if ( eq_bounds ) { if ( eq_abscissas && y0 == y1 ) r = y0; else PG_RETURN_NULL(); } else { r = round(y0+p*(y1-y0)); if ( r < LONG_MIN || r > LONG_MAX ) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value \"%f\" is out of range for type bigint", r))); } result = (int64)r; PG_RETURN_INT64(result); }
/* * worker_apply_inter_shard_ddl_command extends table, index, or constraint names in * the given DDL command. The function then applies this extended DDL command * against the database. */ Datum worker_apply_inter_shard_ddl_command(PG_FUNCTION_ARGS) { uint64 leftShardId = PG_GETARG_INT64(0); text *leftShardSchemaNameText = PG_GETARG_TEXT_P(1); uint64 rightShardId = PG_GETARG_INT64(2); text *rightShardSchemaNameText = PG_GETARG_TEXT_P(3); text *ddlCommandText = PG_GETARG_TEXT_P(4); char *leftShardSchemaName = text_to_cstring(leftShardSchemaNameText); char *rightShardSchemaName = text_to_cstring(rightShardSchemaNameText); const char *ddlCommand = text_to_cstring(ddlCommandText); Node *ddlCommandNode = ParseTreeNode(ddlCommand); /* extend names in ddl command and apply extended command */ RelayEventExtendNamesForInterShardCommands(ddlCommandNode, leftShardId, leftShardSchemaName, rightShardId, rightShardSchemaName); ProcessUtility(ddlCommandNode, ddlCommand, PROCESS_UTILITY_TOPLEVEL, NULL, None_Receiver, NULL); PG_RETURN_VOID(); }
/* * pg_advisory_unlock(int8) - release exclusive lock on an int8 key * * Returns true if successful, false if lock was not held */ Datum pg_advisory_unlock_int8(PG_FUNCTION_ARGS) { int64 key = PG_GETARG_INT64(0); LOCKTAG tag; bool res; PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); res = LockRelease(&tag, ExclusiveLock, true); PG_RETURN_BOOL(res); }
/** * Put the given file in a cache, so that subsequent reads becomes faster. * There is no need to uncache files later, as this happens automatically. */ Datum cache_file(PG_FUNCTION_ARGS) { if ( PG_ARGISNULL(0) ) ereport(ERROR, (errcode( ERRCODE_RAISE_EXCEPTION ), errmsg("NULL argument not allowed"))); int64 id = PG_GETARG_INT64(0); // WARNING: // Do not use any postgres functionality within this macro // It will cause a resource leak. HANDLE_EXCEPTIONS(cacheFile(id)); PG_RETURN_NULL(); }
/* int8abs() * Absolute value */ Datum int8abs(PG_FUNCTION_ARGS) { int64 arg1 = PG_GETARG_INT64(0); int64 result; result = (arg1 < 0) ? -arg1 : arg1; /* overflow check (needed for INT64_MIN) */ if (result < 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); PG_RETURN_INT64(result); }
/* int8out() */ Datum int8out(PG_FUNCTION_ARGS) { int64 val = PG_GETARG_INT64(0); char *result; int len; char buf[MAXINT8LEN + 1]; if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, val)) < 0) elog(ERROR, "could not format int8"); result = pstrdup(buf); PG_RETURN_CSTRING(result); }
Datum int8um(PG_FUNCTION_ARGS) { int64 arg = PG_GETARG_INT64(0); int64 result; result = -arg; /* overflow check (needed for INT64_MIN) */ if (arg != 0 && SAMESIGN(result, arg)) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); PG_RETURN_INT64(result); }
/* * pg_try_advisory_xact_lock_shared(int8) - acquire xact scoped * share lock on an int8 key, no wait * * Returns true if successful, false if lock not available */ Datum pg_try_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS) { int64 key = PG_GETARG_INT64(0); LOCKTAG tag; LockAcquireResult res; PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); res = LockAcquire(&tag, ShareLock, false, true); PG_RETURN_BOOL(res != LOCKACQUIRE_NOT_AVAIL); }
Datum setval_mirror(PG_FUNCTION_ARGS) { Oid relid = PG_GETARG_OID(0); int64 next = PG_GETARG_INT64(1); int64 result; result = DatumGetInt64(DirectFunctionCall2(setval_oid, ObjectIdGetDatum(relid), Int64GetDatum(next))); saveSequenceUpdate(relid, result, true); PG_RETURN_INT64(result); }
Datum int8dec(PG_FUNCTION_ARGS) { int64 arg = PG_GETARG_INT64(0); int64 result; result = arg - 1; /* Overflow check */ if (result > 0 && arg < 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); PG_RETURN_INT64(result); }
Datum pgstrom_shmem_free_func(PG_FUNCTION_ARGS) { #ifdef PGSTROM_DEBUG void *address = (void *) PG_GETARG_INT64(0); pgstrom_shmem_free(address); PG_RETURN_BOOL(true); #else elog(ERROR, "%s is not implemented for production release", __FUNCTION__); PG_RETURN_NULL(); #endif }
/* * pgstrom_partial_covariance_float8 */ Datum pgstrom_partial_covariance_float8(PG_FUNCTION_ARGS) { ArrayType *state; Datum items[6]; items[0] = Float8GetDatum((double)PG_GETARG_INT64(0)); /* nrows(int8) */ items[1] = PG_GETARG_DATUM(1); /* sum of X */ items[2] = PG_GETARG_DATUM(2); /* sum of X^2 */ items[3] = PG_GETARG_DATUM(3); /* sum of Y */ items[4] = PG_GETARG_DATUM(4); /* sum of Y^2 */ items[5] = PG_GETARG_DATUM(5); /* sum of X*Y */ state = construct_array(items, 6, FLOAT8OID, sizeof(float8), FLOAT8PASSBYVAL, 'd'); PG_RETURN_ARRAYTYPE_P(state); }
Datum i8tooid(PG_FUNCTION_ARGS) { int64 arg = PG_GETARG_INT64(0); Oid result; result = (Oid) arg; /* Test for overflow by reverse-conversion. */ if ((int64) result != arg) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("OID out of range"))); PG_RETURN_OID(result); }
Datum int82(PG_FUNCTION_ARGS) { int64 arg = PG_GETARG_INT64(0); int16 result; result = (int16) arg; /* Test for overflow by reverse-conversion. */ if ((int64) result != arg) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range"))); PG_RETURN_INT16(result); }
Datum gbt_int8_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); int64 query = PG_GETARG_INT64(1); int64KEY *kkk = (int64KEY *) DatumGetPointer(entry->key); GBT_NUMKEY_R key; StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); key.lower = (GBT_NUMKEY *) & kkk->lower; key.upper = (GBT_NUMKEY *) & kkk->upper; PG_RETURN_BOOL( gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo) ); }
/* cash_div_int8() * Divide cash by 8-byte integer. */ Datum cash_div_int8(PG_FUNCTION_ARGS) { Cash c = PG_GETARG_CASH(0); int64 i = PG_GETARG_INT64(1); Cash result; if (i == 0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); result = c / i; PG_RETURN_CASH(result); }
Datum int8inc(PG_FUNCTION_ARGS) { /* Assume int8 is byval */ int64 arg = PG_GETARG_INT64(0); int64 result; result = arg + 1; /* Overflow check */ if (result < 0 && arg > 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); PG_RETURN_INT64(result); }
/* * Debugging facilities for shmem.c */ Datum pgstrom_shmem_alloc_func(PG_FUNCTION_ARGS) { #ifdef PGSTROM_DEBUG Size size = PG_GETARG_INT64(0); void *address; address = pgstrom_shmem_alloc(size); PG_RETURN_INT64((Size) address); #else elog(ERROR, "%s is not implemented for production release", __FUNCTION__); PG_RETURN_NULL(); #endif }
/* * task_tracker_cleanup_job finds all tasks for the given job, and cleans up * files, connections, and shared hash enties associated with these tasks. */ Datum task_tracker_cleanup_job(PG_FUNCTION_ARGS) { uint64 jobId = PG_GETARG_INT64(0); HASH_SEQ_STATUS status; WorkerTask *currentTask = NULL; StringInfo jobDirectoryName = NULL; StringInfo jobSchemaName = NULL; /* * We first clean up any open connections, and remove tasks belonging to * this job from the shared hash. */ LWLockAcquire(&WorkerTasksSharedState->taskHashLock, LW_EXCLUSIVE); hash_seq_init(&status, WorkerTasksSharedState->taskHash); currentTask = (WorkerTask *) hash_seq_search(&status); while (currentTask != NULL) { if (currentTask->jobId == jobId) { CleanupTask(currentTask); } currentTask = (WorkerTask *) hash_seq_search(&status); } LWLockRelease(&WorkerTasksSharedState->taskHashLock); /* * We then delete the job directory and schema, if they exist. This cleans * up all intermediate files and tables allocated for the job. Note that the * schema drop call can block if another process is creating the schema or * writing to a table within the schema. */ jobDirectoryName = JobDirectoryName(jobId); RemoveDirectory(jobDirectoryName); LockJobResource(jobId, AccessExclusiveLock); jobSchemaName = JobSchemaName(jobId); RemoveJobSchema(jobSchemaName); UnlockJobResource(jobId, AccessExclusiveLock); PG_RETURN_VOID(); }
/** * Implementation of sql function with the same name * * create function * read_float_from_file(id bigint, pos int) returns void * * read a float from the given file. pos is the index in the file, multiplied * by sizeof(float). This means that read_float_from_file(x, 4) will read bytes * [16,20), and return them as a float. */ Datum read_float_from_file(PG_FUNCTION_ARGS) { if ( PG_ARGISNULL(0) or PG_ARGISNULL(1) ) ereport(ERROR, (errcode( ERRCODE_RAISE_EXCEPTION ), errmsg("NULL argument not allowed"))); int64 id = PG_GETARG_INT64(0); int position = PG_GETARG_INT32(1); float ret = -1; // WARNING: // Do not use any postgres functionality within this macro // It will cause a resource leak. HANDLE_EXCEPTIONS(ret = readFloatFromFile(id, position)); PG_RETURN_FLOAT4(ret); }