Datum pg_database_size_name(PG_FUNCTION_ARGS) { int64 size = 0; Name dbName = PG_GETARG_NAME(0); Oid dbOid = get_database_oid(NameStr(*dbName)); if (!OidIsValid(dbOid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist", NameStr(*dbName)))); size = calculate_database_size(dbOid); PG_RETURN_INT64(size); }
Datum pg_file_write(PG_FUNCTION_ARGS) { FILE *f; char *filename; text *data; int64 count = 0; requireSuperuser(); filename = convert_and_check_filename(PG_GETARG_TEXT_P(0), false); data = PG_GETARG_TEXT_P(1); if (!PG_GETARG_BOOL(2)) { struct stat fst; if (stat(filename, &fst) >= 0) ereport(ERROR, (ERRCODE_DUPLICATE_FILE, errmsg("file \"%s\" exists", filename))); f = fopen(filename, "wb"); } else f = fopen(filename, "ab"); if (!f) ereport(ERROR, (errcode_for_file_access(), errmsg("could not open file \"%s\" for writing: %m", filename))); if (VARSIZE(data) != 0) { count = fwrite(VARDATA(data), 1, VARSIZE(data) - VARHDRSZ, f); if (count != VARSIZE(data) - VARHDRSZ) ereport(ERROR, (errcode_for_file_access(), errmsg("could not write file \"%s\": %m", filename))); } fclose(f); PG_RETURN_INT64(count); }
Datum pg_relation_size(PG_FUNCTION_ARGS) { Oid relOid = PG_GETARG_OID(0); text *forkName = PG_GETARG_TEXT_P(1); Relation rel; int64 size; rel = relation_open(relOid, AccessShareLock); size = calculate_relation_size(&(rel->rd_node), rel->rd_backend, forkname_to_number(text_to_cstring(forkName))); relation_close(rel, AccessShareLock); PG_RETURN_INT64(size); }
Datum lo_lseek64(PG_FUNCTION_ARGS) { int32 fd = PG_GETARG_INT32(0); int64 offset = PG_GETARG_INT64(1); int32 whence = PG_GETARG_INT32(2); int64 status; if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); status = inv_seek(cookies[fd], offset, whence); PG_RETURN_INT64(status); }
/* * SQL-callable function to clean the insert pending list */ Datum gin_clean_pending_list(PG_FUNCTION_ARGS) { Oid indexoid = PG_GETARG_OID(0); Relation indexRel = index_open(indexoid, AccessShareLock); IndexBulkDeleteResult stats; GinState ginstate; if (RecoveryInProgress()) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("recovery is in progress"), errhint("GIN pending list cannot be cleaned up during recovery."))); /* Must be a GIN index */ if (indexRel->rd_rel->relkind != RELKIND_INDEX || indexRel->rd_rel->relam != GIN_AM_OID) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a GIN index", RelationGetRelationName(indexRel)))); /* * Reject attempts to read non-local temporary relations; we would be * likely to get wrong data since we have no visibility into the owning * session's local buffers. */ if (RELATION_IS_OTHER_TEMP(indexRel)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot access temporary indexes of other sessions"))); /* User must own the index (comparable to privileges needed for VACUUM) */ if (!pg_class_ownercheck(indexoid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, RelationGetRelationName(indexRel)); memset(&stats, 0, sizeof(stats)); initGinState(&ginstate, indexRel); ginInsertCleanup(&ginstate, true, true, &stats); index_close(indexRel, AccessShareLock); PG_RETURN_INT64((int64) stats.pages_deleted); }
/* * citus_total_relation_size accepts a table name and returns a distributed table * and its indexes' total relation size. */ Datum citus_total_relation_size(PG_FUNCTION_ARGS) { Oid relationId = PG_GETARG_OID(0); uint64 totalRelationSize = 0; char *tableSizeFunction = PG_TOTAL_RELATION_SIZE_FUNCTION; CheckCitusVersion(ERROR); if (CStoreTable(relationId)) { tableSizeFunction = CSTORE_TABLE_SIZE_FUNCTION; } totalRelationSize = DistributedTableSize(relationId, tableSizeFunction); PG_RETURN_INT64(totalRelationSize); }
Datum pg_file_length(PG_FUNCTION_ARGS) { text *filename_t = PG_GETARG_TEXT_P(0); char *filename; struct stat fst; requireSuperuser(); filename = convert_and_check_filename(filename_t); if (stat(filename, &fst) < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not stat file \"%s\": %m", filename))); PG_RETURN_INT64((int64) fst.st_size); }
Datum int48div(PG_FUNCTION_ARGS) { int32 arg1 = PG_GETARG_INT32(0); int64 arg2 = PG_GETARG_INT64(1); 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(); } /* No overflow is possible */ PG_RETURN_INT64((int64) arg1 / arg2); }
Datum pgheal_ang2ipix_nest(PG_FUNCTION_ARGS) { q3c_ipix_t nside = PG_GETARG_INT64(0); q3c_coord_t ra = PG_GETARG_FLOAT8(1); q3c_coord_t dec = PG_GETARG_FLOAT8(2); q3c_ipix_t ipix; q3c_coord_t theta; q3c_coord_t phi; if ((!isfinite(ra))||(!isfinite(dec))) { PG_RETURN_NULL(); } get_theta_phi(ra,dec, &theta, &phi); nside_check(nside); angle_check(theta); ang2pix_nest(nside, theta, phi, &ipix); PG_RETURN_INT64(ipix); }
Datum get_purge_id(PG_FUNCTION_ARGS) { VarChar *vis_base64 = PG_GETARG_VARCHAR_P(0); visibility_handle_t *vis = deserialize_vis(vis_base64); if (!vis) { PG_RETURN_BOOL(false); } char *error = NULL; purge_info_t purge_info; purge_info.id = -1; ezbake_get_purge_info(vis, &purge_info, &error); if (error) { ereport(ERROR, (errmsg("Error getting the purge info from visibility! %s", error))); free(error); } ezbake_visibility_handle_free(vis); PG_RETURN_INT64(purge_info.id); }
/* * hashgetbitmap() -- get all tuples at once */ Datum hashgetbitmap(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0); TIDBitmap *tbm = (TIDBitmap *) PG_GETARG_POINTER(1); HashScanOpaque so = (HashScanOpaque) scan->opaque; bool res; int64 ntids = 0; res = _hash_first(scan, ForwardScanDirection); while (res) { bool add_tuple; /* * Skip killed tuples if asked to. */ if (scan->ignore_killed_tuples) { Page page; OffsetNumber offnum; offnum = ItemPointerGetOffsetNumber(&(so->hashso_curpos)); page = BufferGetPage(so->hashso_curbuf); add_tuple = !ItemIdIsDead(PageGetItemId(page, offnum)); } else add_tuple = true; /* Save tuple ID, and continue scanning */ if (add_tuple) { /* Note we mark the tuple ID as requiring recheck */ tbm_add_tuples(tbm, &(so->hashso_heappos), 1, true); ntids++; } res = _hash_next(scan, ForwardScanDirection); } PG_RETURN_INT64(ntids); }
Datum int8_dist(PG_FUNCTION_ARGS) { int64 a = PG_GETARG_INT64(0); int64 b = PG_GETARG_INT64(1); int64 r; int64 ra; r = a - b; ra = Abs(r); /* Overflow check. */ if (ra < 0 || (!SAMESIGN(a, b) && !SAMESIGN(r, a))) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); PG_RETURN_INT64(ra); }
Datum pg_stat_get_db_conflict_all(PG_FUNCTION_ARGS) { Oid dbid = PG_GETARG_OID(0); int64 result; PgStat_StatDBEntry *dbentry; if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) result = 0; else result = (int64) ( dbentry->n_conflict_tablespace + dbentry->n_conflict_lock + dbentry->n_conflict_snapshot + dbentry->n_conflict_bufferpin + dbentry->n_conflict_startup_deadlock); PG_RETURN_INT64(result); }
Datum int8inc(PG_FUNCTION_ARGS) { /* * When int8 is pass-by-reference, we provide this special case to avoid * palloc overhead for COUNT(): when called as an aggregate, we know that * the argument is modifiable local storage, so just update it in-place. * (If int8 is pass-by-value, then of course this is useless as well as * incorrect, so just ifdef it out.) */ #ifndef USE_FLOAT8_BYVAL /* controls int8 too */ if (AggCheckCallContext(fcinfo, NULL)) { int64 *arg = (int64 *) PG_GETARG_POINTER(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"))); *arg = result; PG_RETURN_POINTER(arg); } else #endif { /* Not called as an aggregate, so just do it the dumb way */ 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 pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS) { Oid relid = PG_GETARG_OID(0); int64 result; PgStat_TableStatus *tabentry; PgStat_TableXactStatus *trans; if ((tabentry = find_tabstat_entry(relid)) == NULL) result = 0; else { result = tabentry->t_counts.t_tuples_deleted; /* live subtransactions' counts aren't in t_tuples_deleted yet */ for (trans = tabentry->trans; trans != NULL; trans = trans->upper) result += trans->tuples_deleted; } PG_RETURN_INT64(result); }
Datum int82pl(PG_FUNCTION_ARGS) { int64 arg1 = PG_GETARG_INT64(0); int16 arg2 = PG_GETARG_INT16(1); int64 result; result = arg1 + arg2; /* * Overflow check. If the inputs are of different signs then their sum * cannot overflow. If the inputs are of the same sign, their sum had * better be that sign too. */ if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1)) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); PG_RETURN_INT64(result); }
Datum relation_size(PG_FUNCTION_ARGS) { text *relname = PG_GETARG_TEXT_P(0); RangeVar *relrv; Relation relation; Oid relnodeOid; Oid tblspcOid; relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname, "relation_size")); relation = relation_openrv(relrv, AccessShareLock); tblspcOid = relation->rd_rel->reltablespace; relnodeOid = relation->rd_rel->relfilenode; relation_close(relation, AccessShareLock); PG_RETURN_INT64(calculate_relation_size(tblspcOid, relnodeOid)); }
Datum pg_database_size_oid(PG_FUNCTION_ARGS) { int64 size = 0; Oid dbOid = PG_GETARG_OID(0); size = calculate_database_size(dbOid); if (Gp_role == GP_ROLE_DISPATCH) { StringInfoData buffer; initStringInfo(&buffer); appendStringInfo(&buffer, "select sum(pg_database_size(%u))::int8 from gp_dist_random('gp_id');", dbOid); size += get_size_from_segDBs(buffer.data); } PG_RETURN_INT64(size); }
Datum int82mi(PG_FUNCTION_ARGS) { int64 arg1 = PG_GETARG_INT64(0); int16 arg2 = PG_GETARG_INT16(1); int64 result; result = arg1 - arg2; /* * Overflow check. If the inputs are of the same sign then their * difference cannot overflow. If they are of different signs then the * result should be of the same sign as the first input. */ if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1)) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); PG_RETURN_INT64(result); }
/* No need for superuser checks in v1.5, see above */ Datum pg_relpagesbyid_v1_5(PG_FUNCTION_ARGS) { Oid relid = PG_GETARG_OID(0); int64 relpages; Relation rel; rel = relation_open(relid, AccessShareLock); /* only some relkinds have storage */ check_relation_relkind(rel); /* note: this will work OK on non-local temp tables */ relpages = RelationGetNumberOfBlocks(rel); relation_close(rel, AccessShareLock); PG_RETURN_INT64(relpages); }
/* * txid_current() returns int8 * * Return the current toplevel transaction ID as TXID * If the current transaction does not have one, one is assigned. */ Datum txid_current(PG_FUNCTION_ARGS) { txid val; TxidEpoch state; /* * Must prevent during recovery because if an xid is not assigned we try * to assign one, which would fail. Programs already rely on this function * to always return a valid current xid, so we should not change this to * return NULL or similar invalid xid. */ PreventCommandDuringRecovery("txid_current()"); load_xid_epoch(&state); val = convert_xid(GetTopTransactionId(), &state); PG_RETURN_INT64(val); }
Datum int8_add(PG_FUNCTION_ARGS) { int64 state1; int64 state2; /* * GUARD against an incorrectly defined SQL function by verifying * that the parameters are the types we are expecting: * int8_add(int64, int64) => int64 */ if (PG_NARGS() != 2) { elog(ERROR, "%s defined with %d arguments, expected 2", add_str, PG_NARGS() ); } if (get_fn_expr_argtype(fcinfo->flinfo, 0) != INT8OID || get_fn_expr_argtype(fcinfo->flinfo, 1) != INT8OID) { elog(ERROR, "%s defined with invalid types, expected (int8, int8)", add_str ); } if (get_fn_expr_rettype(fcinfo->flinfo) != INT8OID) { elog(ERROR, "%s defined with invalid return type, expected int8", add_str ); } /* * GUARD against NULL input: * - IF both are null return NULL * - otherwise treat NULL as a zero value */ if (PG_ARGISNULL(0) && PG_ARGISNULL(1)) PG_RETURN_NULL(); state1 = PG_ARGISNULL(0) ? 0 : PG_GETARG_INT64(0); state2 = PG_ARGISNULL(1) ? 0 : PG_GETARG_INT64(1); /* Do the math and return the result */ PG_RETURN_INT64(state1 + state2); }
/* * Note: nextval with a text argument is no longer exported as a pg_proc * entry, but we keep it around to ease porting of C code that may have * called the function directly. */ Datum nextval(PG_FUNCTION_ARGS) { text *seqin = PG_GETARG_TEXT_P(0); RangeVar *sequence; Oid relid; sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin)); /* * XXX: This is not safe in the presence of concurrent DDL, but acquiring * a lock here is more expensive than letting nextval_internal do it, * since the latter maintains a cache that keeps us from hitting the lock * manager more than once per transaction. It's not clear whether the * performance penalty is material in practice, but for now, we do it this * way. */ relid = RangeVarGetRelid(sequence, NoLock, false); PG_RETURN_INT64(nextval_internal(relid)); }
Datum pgstrom_sum_int8_accum(PG_FUNCTION_ARGS) { int64 newval; if (PG_ARGISNULL(0)) { if (PG_ARGISNULL(1)) PG_RETURN_NULL(); /* still no non-null */ /* This is the first non-null input. */ newval = PG_GETARG_INT64(1); } else { newval = PG_GETARG_INT64(0); if (!PG_ARGISNULL(1)) newval += PG_GETARG_INT64(1); } PG_RETURN_INT64(newval); }
Datum count_distinct(PG_FUNCTION_ARGS) { element_set_t * eset; CHECK_AGG_CONTEXT("count_distinct", fcinfo); if (PG_ARGISNULL(0)) PG_RETURN_NULL(); eset = (element_set_t *)PG_GETARG_POINTER(0); /* do the compaction */ compact_set(eset, false); #if DEBUG_PROFILE print_set_stats(eset); #endif PG_RETURN_INT64(eset->nall); }
Datum pg_tablespace_size_name(PG_FUNCTION_ARGS) { int64 size = 0; Name tblspcName = PG_GETARG_NAME(0); Oid tblspcOid = get_tablespace_oid(NameStr(*tblspcName), false); size = calculate_tablespace_size(tblspcOid); if (Gp_role == GP_ROLE_DISPATCH) { StringInfoData buffer; initStringInfo(&buffer); appendStringInfo(&buffer, "select sum(pg_tablespace_size('%s'))::int8 from gp_dist_random('gp_id');", NameStr(*tblspcName)); size += get_size_from_segDBs(buffer.data); } PG_RETURN_INT64(size); }
Datum pg_relpagesbyid(PG_FUNCTION_ARGS) { Oid relid = PG_GETARG_OID(0); int64 relpages; Relation rel; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to use pgstattuple functions")))); rel = relation_open(relid, AccessShareLock); /* note: this will work OK on non-local temp tables */ relpages = RelationGetNumberOfBlocks(rel); relation_close(rel, AccessShareLock); PG_RETURN_INT64(relpages); }
/* No need for superuser checks in v1.5, see above */ Datum pg_relpages_v1_5(PG_FUNCTION_ARGS) { text *relname = PG_GETARG_TEXT_PP(0); int64 relpages; Relation rel; RangeVar *relrv; relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); rel = relation_openrv(relrv, AccessShareLock); /* only some relkinds have storage */ check_relation_relkind(rel); /* note: this will work OK on non-local temp tables */ relpages = RelationGetNumberOfBlocks(rel); relation_close(rel, AccessShareLock); PG_RETURN_INT64(relpages); }
Datum pg_tablespace_size_oid(PG_FUNCTION_ARGS) { Oid tblspcOid = PG_GETARG_OID(0); int64 size; size = calculate_tablespace_size(tblspcOid); if (Gp_role == GP_ROLE_DISPATCH) { char *sql; sql = psprintf("select pg_catalog.pg_tablespace_size(%u)", tblspcOid); size += get_size_from_segDBs(sql); } if (size < 0) PG_RETURN_NULL(); PG_RETURN_INT64(size); }
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); }