mirror of
https://github.com/postgres/postgres.git
synced 2025-10-27 00:12:01 +03:00
Restructure some header files a bit, in particular heapam.h, by removing some
unnecessary #include lines in it. Also, move some tuple routine prototypes and macros to htup.h, which allows removal of heapam.h inclusion from some .c files. For this to work, a new header file access/sysattr.h needed to be created, initially containing attribute numbers of system columns, for pg_dump usage. While at it, make contrib ltree, intarray and hstore header files more consistent with our header style.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/genam.h,v 1.71 2008/04/12 23:14:21 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/genam.h,v 1.72 2008/05/12 00:00:53 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -16,9 +16,10 @@
|
||||
|
||||
#include "access/relscan.h"
|
||||
#include "access/sdir.h"
|
||||
#include "nodes/primnodes.h"
|
||||
#include "nodes/tidbitmap.h"
|
||||
#include "storage/buf.h"
|
||||
#include "storage/lock.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
/*
|
||||
* Struct for statistics returned by ambuild
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Copyright (c) 2006-2008, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/gin.h,v 1.18 2008/04/22 17:52:43 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/gin.h,v 1.19 2008/05/12 00:00:53 alvherre Exp $
|
||||
*--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -12,15 +12,13 @@
|
||||
#ifndef GIN_H
|
||||
#define GIN_H
|
||||
|
||||
#include "access/relscan.h"
|
||||
#include "access/skey.h"
|
||||
#include "access/xlog.h"
|
||||
#include "access/xlogdefs.h"
|
||||
#include "storage/bufpage.h"
|
||||
#include "storage/off.h"
|
||||
#include "utils/rel.h"
|
||||
#include "access/itup.h"
|
||||
#include "access/relscan.h"
|
||||
#include "fmgr.h"
|
||||
#include "storage/block.h"
|
||||
#include "storage/buf.h"
|
||||
#include "storage/off.h"
|
||||
#include "storage/relfilenode.h"
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/gist.h,v 1.59 2008/01/01 19:45:56 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/gist.h,v 1.60 2008/05/12 00:00:53 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "access/xlog.h"
|
||||
#include "access/xlogdefs.h"
|
||||
#include "storage/bufpage.h"
|
||||
#include "storage/off.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/gistscan.h,v 1.32 2008/01/01 19:45:56 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/gistscan.h,v 1.33 2008/05/12 00:00:53 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef GISTSCAN_H
|
||||
#define GISTSCAN_H
|
||||
|
||||
#include "access/relscan.h"
|
||||
#include "fmgr.h"
|
||||
|
||||
extern Datum gistbeginscan(PG_FUNCTION_ARGS);
|
||||
extern Datum gistrescan(PG_FUNCTION_ARGS);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.133 2008/04/03 17:12:27 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.134 2008/05/12 00:00:53 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -17,100 +17,10 @@
|
||||
#include "access/htup.h"
|
||||
#include "access/relscan.h"
|
||||
#include "access/sdir.h"
|
||||
#include "access/tupmacs.h"
|
||||
#include "access/xlogutils.h"
|
||||
#include "nodes/primnodes.h"
|
||||
#include "storage/block.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "utils/rel.h"
|
||||
#include "storage/lock.h"
|
||||
#include "utils/snapshot.h"
|
||||
|
||||
/* ----------------
|
||||
* fastgetattr
|
||||
*
|
||||
* Fetch a user attribute's value as a Datum (might be either a
|
||||
* value, or a pointer into the data area of the tuple).
|
||||
*
|
||||
* This must not be used when a system attribute might be requested.
|
||||
* Furthermore, the passed attnum MUST be valid. Use heap_getattr()
|
||||
* instead, if in doubt.
|
||||
*
|
||||
* This gets called many times, so we macro the cacheable and NULL
|
||||
* lookups, and call nocachegetattr() for the rest.
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
#if !defined(DISABLE_COMPLEX_MACRO)
|
||||
|
||||
#define fastgetattr(tup, attnum, tupleDesc, isnull) \
|
||||
( \
|
||||
AssertMacro((attnum) > 0), \
|
||||
(((isnull) != NULL) ? (*(isnull) = false) : (dummyret)NULL), \
|
||||
HeapTupleNoNulls(tup) ? \
|
||||
( \
|
||||
(tupleDesc)->attrs[(attnum)-1]->attcacheoff >= 0 ? \
|
||||
( \
|
||||
fetchatt((tupleDesc)->attrs[(attnum)-1], \
|
||||
(char *) (tup)->t_data + (tup)->t_data->t_hoff + \
|
||||
(tupleDesc)->attrs[(attnum)-1]->attcacheoff) \
|
||||
) \
|
||||
: \
|
||||
nocachegetattr((tup), (attnum), (tupleDesc), (isnull)) \
|
||||
) \
|
||||
: \
|
||||
( \
|
||||
att_isnull((attnum)-1, (tup)->t_data->t_bits) ? \
|
||||
( \
|
||||
(((isnull) != NULL) ? (*(isnull) = true) : (dummyret)NULL), \
|
||||
(Datum)NULL \
|
||||
) \
|
||||
: \
|
||||
( \
|
||||
nocachegetattr((tup), (attnum), (tupleDesc), (isnull)) \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
#else /* defined(DISABLE_COMPLEX_MACRO) */
|
||||
|
||||
extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
|
||||
bool *isnull);
|
||||
#endif /* defined(DISABLE_COMPLEX_MACRO) */
|
||||
|
||||
|
||||
/* ----------------
|
||||
* heap_getattr
|
||||
*
|
||||
* Extract an attribute of a heap tuple and return it as a Datum.
|
||||
* This works for either system or user attributes. The given attnum
|
||||
* is properly range-checked.
|
||||
*
|
||||
* If the field in question has a NULL value, we return a zero Datum
|
||||
* and set *isnull == true. Otherwise, we set *isnull == false.
|
||||
*
|
||||
* <tup> is the pointer to the heap tuple. <attnum> is the attribute
|
||||
* number of the column (field) caller wants. <tupleDesc> is a
|
||||
* pointer to the structure describing the row and all its fields.
|
||||
* ----------------
|
||||
*/
|
||||
#define heap_getattr(tup, attnum, tupleDesc, isnull) \
|
||||
( \
|
||||
AssertMacro((tup) != NULL), \
|
||||
( \
|
||||
((attnum) > 0) ? \
|
||||
( \
|
||||
((attnum) > (int) HeapTupleHeaderGetNatts((tup)->t_data)) ? \
|
||||
( \
|
||||
(((isnull) != NULL) ? (*(isnull) = true) : (dummyret)NULL), \
|
||||
(Datum)NULL \
|
||||
) \
|
||||
: \
|
||||
fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \
|
||||
) \
|
||||
: \
|
||||
heap_getsysattr((tup), (attnum), (tupleDesc), (isnull)) \
|
||||
) \
|
||||
)
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -207,48 +117,6 @@ extern XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer,
|
||||
OffsetNumber *offsets, int offcnt);
|
||||
extern XLogRecPtr log_newpage(RelFileNode *rnode, BlockNumber blk, Page page);
|
||||
|
||||
/* in common/heaptuple.c */
|
||||
extern Size heap_compute_data_size(TupleDesc tupleDesc,
|
||||
Datum *values, bool *isnull);
|
||||
extern void heap_fill_tuple(TupleDesc tupleDesc,
|
||||
Datum *values, bool *isnull,
|
||||
char *data, Size data_size,
|
||||
uint16 *infomask, bits8 *bit);
|
||||
extern bool heap_attisnull(HeapTuple tup, int attnum);
|
||||
extern Datum nocachegetattr(HeapTuple tup, int attnum,
|
||||
TupleDesc att, bool *isnull);
|
||||
extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
|
||||
bool *isnull);
|
||||
extern HeapTuple heap_copytuple(HeapTuple tuple);
|
||||
extern void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest);
|
||||
extern HeapTuple heap_form_tuple(TupleDesc tupleDescriptor,
|
||||
Datum *values, bool *isnull);
|
||||
extern HeapTuple heap_formtuple(TupleDesc tupleDescriptor,
|
||||
Datum *values, char *nulls);
|
||||
extern HeapTuple heap_modify_tuple(HeapTuple tuple,
|
||||
TupleDesc tupleDesc,
|
||||
Datum *replValues,
|
||||
bool *replIsnull,
|
||||
bool *doReplace);
|
||||
extern HeapTuple heap_modifytuple(HeapTuple tuple,
|
||||
TupleDesc tupleDesc,
|
||||
Datum *replValues,
|
||||
char *replNulls,
|
||||
char *replActions);
|
||||
extern void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
|
||||
Datum *values, bool *isnull);
|
||||
extern void heap_deformtuple(HeapTuple tuple, TupleDesc tupleDesc,
|
||||
Datum *values, char *nulls);
|
||||
extern void heap_freetuple(HeapTuple htup);
|
||||
extern MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor,
|
||||
Datum *values, bool *isnull);
|
||||
extern void heap_free_minimal_tuple(MinimalTuple mtup);
|
||||
extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup);
|
||||
extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup);
|
||||
extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup);
|
||||
extern HeapTuple heap_addheader(int natts, bool withoid,
|
||||
Size structlen, void *structure);
|
||||
|
||||
/* in heap/pruneheap.c */
|
||||
extern void heap_page_prune_opt(Relation relation, Buffer buffer,
|
||||
TransactionId OldestXmin);
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/htup.h,v 1.98 2008/01/01 19:45:56 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/htup.h,v 1.99 2008/05/12 00:00:53 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef HTUP_H
|
||||
#define HTUP_H
|
||||
|
||||
#include "access/tupdesc.h"
|
||||
#include "access/tupmacs.h"
|
||||
#include "storage/itemptr.h"
|
||||
#include "storage/relfilenode.h"
|
||||
|
||||
@@ -392,19 +394,6 @@ do { \
|
||||
#define MaxAttrSize (10 * 1024 * 1024)
|
||||
|
||||
|
||||
/*
|
||||
* Attribute numbers for the system-defined attributes
|
||||
*/
|
||||
#define SelfItemPointerAttributeNumber (-1)
|
||||
#define ObjectIdAttributeNumber (-2)
|
||||
#define MinTransactionIdAttributeNumber (-3)
|
||||
#define MinCommandIdAttributeNumber (-4)
|
||||
#define MaxTransactionIdAttributeNumber (-5)
|
||||
#define MaxCommandIdAttributeNumber (-6)
|
||||
#define TableOidAttributeNumber (-7)
|
||||
#define FirstLowInvalidHeapAttributeNumber (-8)
|
||||
|
||||
|
||||
/*
|
||||
* MinimalTuple is an alternative representation that is used for transient
|
||||
* tuples inside the executor, in places where transaction status information
|
||||
@@ -725,4 +714,132 @@ extern void HeapTupleHeaderAdjustCmax(HeapTupleHeader tup,
|
||||
CommandId *cmax,
|
||||
bool *iscombo);
|
||||
|
||||
/* ----------------
|
||||
* fastgetattr
|
||||
*
|
||||
* Fetch a user attribute's value as a Datum (might be either a
|
||||
* value, or a pointer into the data area of the tuple).
|
||||
*
|
||||
* This must not be used when a system attribute might be requested.
|
||||
* Furthermore, the passed attnum MUST be valid. Use heap_getattr()
|
||||
* instead, if in doubt.
|
||||
*
|
||||
* This gets called many times, so we macro the cacheable and NULL
|
||||
* lookups, and call nocachegetattr() for the rest.
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
#if !defined(DISABLE_COMPLEX_MACRO)
|
||||
|
||||
#define fastgetattr(tup, attnum, tupleDesc, isnull) \
|
||||
( \
|
||||
AssertMacro((attnum) > 0), \
|
||||
(((isnull) != NULL) ? (*(isnull) = false) : (dummyret)NULL), \
|
||||
HeapTupleNoNulls(tup) ? \
|
||||
( \
|
||||
(tupleDesc)->attrs[(attnum)-1]->attcacheoff >= 0 ? \
|
||||
( \
|
||||
fetchatt((tupleDesc)->attrs[(attnum)-1], \
|
||||
(char *) (tup)->t_data + (tup)->t_data->t_hoff + \
|
||||
(tupleDesc)->attrs[(attnum)-1]->attcacheoff) \
|
||||
) \
|
||||
: \
|
||||
nocachegetattr((tup), (attnum), (tupleDesc), (isnull)) \
|
||||
) \
|
||||
: \
|
||||
( \
|
||||
att_isnull((attnum)-1, (tup)->t_data->t_bits) ? \
|
||||
( \
|
||||
(((isnull) != NULL) ? (*(isnull) = true) : (dummyret)NULL), \
|
||||
(Datum)NULL \
|
||||
) \
|
||||
: \
|
||||
( \
|
||||
nocachegetattr((tup), (attnum), (tupleDesc), (isnull)) \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
#else /* defined(DISABLE_COMPLEX_MACRO) */
|
||||
|
||||
extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
|
||||
bool *isnull);
|
||||
#endif /* defined(DISABLE_COMPLEX_MACRO) */
|
||||
|
||||
|
||||
/* ----------------
|
||||
* heap_getattr
|
||||
*
|
||||
* Extract an attribute of a heap tuple and return it as a Datum.
|
||||
* This works for either system or user attributes. The given attnum
|
||||
* is properly range-checked.
|
||||
*
|
||||
* If the field in question has a NULL value, we return a zero Datum
|
||||
* and set *isnull == true. Otherwise, we set *isnull == false.
|
||||
*
|
||||
* <tup> is the pointer to the heap tuple. <attnum> is the attribute
|
||||
* number of the column (field) caller wants. <tupleDesc> is a
|
||||
* pointer to the structure describing the row and all its fields.
|
||||
* ----------------
|
||||
*/
|
||||
#define heap_getattr(tup, attnum, tupleDesc, isnull) \
|
||||
( \
|
||||
AssertMacro((tup) != NULL), \
|
||||
( \
|
||||
((attnum) > 0) ? \
|
||||
( \
|
||||
((attnum) > (int) HeapTupleHeaderGetNatts((tup)->t_data)) ? \
|
||||
( \
|
||||
(((isnull) != NULL) ? (*(isnull) = true) : (dummyret)NULL), \
|
||||
(Datum)NULL \
|
||||
) \
|
||||
: \
|
||||
fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \
|
||||
) \
|
||||
: \
|
||||
heap_getsysattr((tup), (attnum), (tupleDesc), (isnull)) \
|
||||
) \
|
||||
)
|
||||
|
||||
/* prototypes for functions in common/heaptuple.c */
|
||||
extern Size heap_compute_data_size(TupleDesc tupleDesc,
|
||||
Datum *values, bool *isnull);
|
||||
extern void heap_fill_tuple(TupleDesc tupleDesc,
|
||||
Datum *values, bool *isnull,
|
||||
char *data, Size data_size,
|
||||
uint16 *infomask, bits8 *bit);
|
||||
extern bool heap_attisnull(HeapTuple tup, int attnum);
|
||||
extern Datum nocachegetattr(HeapTuple tup, int attnum,
|
||||
TupleDesc att, bool *isnull);
|
||||
extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
|
||||
bool *isnull);
|
||||
extern HeapTuple heap_copytuple(HeapTuple tuple);
|
||||
extern void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest);
|
||||
extern HeapTuple heap_form_tuple(TupleDesc tupleDescriptor,
|
||||
Datum *values, bool *isnull);
|
||||
extern HeapTuple heap_formtuple(TupleDesc tupleDescriptor,
|
||||
Datum *values, char *nulls);
|
||||
extern HeapTuple heap_modify_tuple(HeapTuple tuple,
|
||||
TupleDesc tupleDesc,
|
||||
Datum *replValues,
|
||||
bool *replIsnull,
|
||||
bool *doReplace);
|
||||
extern HeapTuple heap_modifytuple(HeapTuple tuple,
|
||||
TupleDesc tupleDesc,
|
||||
Datum *replValues,
|
||||
char *replNulls,
|
||||
char *replActions);
|
||||
extern void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
|
||||
Datum *values, bool *isnull);
|
||||
extern void heap_deformtuple(HeapTuple tuple, TupleDesc tupleDesc,
|
||||
Datum *values, char *nulls);
|
||||
extern void heap_freetuple(HeapTuple htup);
|
||||
extern MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor,
|
||||
Datum *values, bool *isnull);
|
||||
extern void heap_free_minimal_tuple(MinimalTuple mtup);
|
||||
extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup);
|
||||
extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup);
|
||||
extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup);
|
||||
extern HeapTuple heap_addheader(int natts, bool withoid,
|
||||
Size structlen, void *structure);
|
||||
|
||||
#endif /* HTUP_H */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.64 2008/04/13 19:18:14 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.65 2008/05/12 00:00:53 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "access/htup.h"
|
||||
#include "access/skey.h"
|
||||
#include "storage/bufpage.h"
|
||||
#include "utils/rel.h"
|
||||
#include "utils/snapshot.h"
|
||||
|
||||
|
||||
|
||||
31
src/include/access/sysattr.h
Normal file
31
src/include/access/sysattr.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* sysattr.h
|
||||
* POSTGRES system attribute definitions.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/sysattr.h,v 1.1 2008/05/12 00:00:53 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef SYSATTR_H
|
||||
#define SYSATTR_H
|
||||
|
||||
|
||||
/*
|
||||
* Attribute numbers for the system-defined attributes
|
||||
*/
|
||||
#define SelfItemPointerAttributeNumber (-1)
|
||||
#define ObjectIdAttributeNumber (-2)
|
||||
#define MinTransactionIdAttributeNumber (-3)
|
||||
#define MinCommandIdAttributeNumber (-4)
|
||||
#define MaxTransactionIdAttributeNumber (-5)
|
||||
#define MaxCommandIdAttributeNumber (-6)
|
||||
#define TableOidAttributeNumber (-7)
|
||||
#define FirstLowInvalidHeapAttributeNumber (-8)
|
||||
|
||||
|
||||
#endif /* SYSATTR_H */
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/tuptoaster.h,v 1.38 2008/01/01 19:45:56 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/tuptoaster.h,v 1.39 2008/05/12 00:00:53 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "access/htup.h"
|
||||
#include "storage/bufpage.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
/*
|
||||
* This enables de-toasting of index entries. Needed until VACUUM is
|
||||
|
||||
Reference in New Issue
Block a user