Files
openGauss-server/src/include/commands/sequence.h
2022-09-03 16:22:35 +08:00

245 lines
7.7 KiB
C

/* -------------------------------------------------------------------------
*
* sequence.h
* prototypes for sequence.c.
*
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 2021, openGauss Contributors
*
* src/include/commands/sequence.h
*
* -------------------------------------------------------------------------
*/
#ifndef SEQUENCE_H
#define SEQUENCE_H
#include "access/xlogreader.h"
#include "fmgr.h"
#include "lib/stringinfo.h"
#include "nodes/parsenodes.h"
#include "storage/smgr/relfilenode.h"
#ifdef PGXC
#include "utils/relcache.h"
#include "gtm/gtm_c.h"
#include "access/xact.h"
#include "optimizer/streamplan.h"
#include "pgxc/pgxcnode.h"
#include "tcop/utility.h"
#endif
#define INVALIDSEQUUID 0
// extern THR_LOCAL char *PGXCNodeName;
typedef int64 GTM_UUID;
typedef struct FormData_pg_sequence {
NameData sequence_name;
int64 last_value;
int64 start_value;
int64 increment_by;
int64 max_value;
int64 min_value;
int64 cache_value;
int64 log_cnt;
bool is_cycled;
bool is_called;
GTM_UUID uuid;
} FormData_pg_sequence;
typedef FormData_pg_sequence* Form_pg_sequence;
typedef struct FormData_pg_large_sequence {
NameData sequence_name;
int128 last_value;
int128 start_value;
int128 increment_by;
int128 max_value;
int128 min_value;
int128 cache_value;
int64 log_cnt;
bool is_cycled;
bool is_called;
GTM_UUID uuid;
} FormData_pg_large_sequence;
typedef FormData_pg_large_sequence* Form_pg_large_sequence;
/*
* Columns of a sequence relation
*/
#define SEQ_COL_NAME 1
#define SEQ_COL_LASTVAL 2
#define SEQ_COL_STARTVAL 3
#define SEQ_COL_INCBY 4
#define SEQ_COL_MAXVALUE 5
#define SEQ_COL_MINVALUE 6
#define SEQ_COL_CACHE 7
#define SEQ_COL_LOG 8
#define SEQ_COL_CYCLE 9
#define SEQ_COL_CALLED 10
#define SEQ_COL_UUID 11
#define SEQ_COL_FIRSTCOL SEQ_COL_NAME
#define SEQ_COL_LASTCOL SEQ_COL_UUID
#define GS_NUM_OF_BUCKETS 1024
/*
* The "special area" of a old version sequence's buffer page looks like this.
*/
/*
* We store a SeqTable item for every sequence we have touched in the current
* session. This is needed to hold onto nextval/currval state. (We can't
* rely on the relcache, since it's only, well, a cache, and may decide to
* discard entries.)
*
* XXX We use linear search to find pre-existing SeqTable entries. This is
* good when only a small number of sequences are touched in a session, but
* would suck with many different sequences. Perhaps use a hashtable someday.
*/
typedef struct SeqTableData {
struct SeqTableData* next; /* link to next SeqTable object */
Oid relid; /* pg_class OID of this sequence */
Oid filenode; /* last seen relfilenode of this sequence */
LocalTransactionId lxid; /* xact in which we last did a seq op */
bool last_valid; /* do we have a valid "last" value? */
bool is_cycled;
int128 last; /* value last returned by nextval */
int128 cached; /* last value already cached for nextval */
/* if last != cached, we have not used up all the cached values */
int128 increment; /* copy of sequence's increment field */
/* note that increment is zero until we first do read_seq_tuple() */
int128 minval;
int128 maxval;
int128 startval;
int64 uuid;
} SeqTableData;
typedef SeqTableData* SeqTable;
/* XLOG stuff */
#define XLOG_SEQ_LOG 0x00
/*
* The "special area" of a sequence's buffer page looks like this.
*/
#define SEQ_MAGIC 0x1717
typedef struct xl_seq_rec {
RelFileNodeOld node;
/* SEQUENCE TUPLE DATA FOLLOWS AT THE END */
} xl_seq_rec;
/*
* We don't want to log each fetching of a value from a sequence,
* so we pre-log a few fetches in advance. In the event of
* crash we can lose (skip over) as many values as we pre-logged.
*/
const int SEQ_LOG_VALS = 32;
/*
* The "special area" of a old version sequence's buffer page looks like this.
*/
typedef struct sequence_magic {
uint32 magic;
} sequence_magic;
extern Datum nextval(PG_FUNCTION_ARGS);
extern Datum nextval_oid(PG_FUNCTION_ARGS);
extern Datum currval_oid(PG_FUNCTION_ARGS);
extern Datum setval_oid(PG_FUNCTION_ARGS);
extern Datum setval3_oid(PG_FUNCTION_ARGS);
extern Datum lastval(PG_FUNCTION_ARGS);
extern Datum last_insert_id(PG_FUNCTION_ARGS);
extern Datum last_insert_id_no_args(PG_FUNCTION_ARGS);
extern Datum pg_sequence_parameters(PG_FUNCTION_ARGS);
extern Datum pg_sequence_last_value(PG_FUNCTION_ARGS);
extern int128 nextval_internal(Oid relid);
extern void autoinc_setval(Oid relid, int128 next, bool iscalled);
extern int128 autoinc_get_nextval(Oid relid);
extern bool CheckSeqOwnedByAutoInc(Oid seqoid);
extern void DefineSequenceWrapper(CreateSeqStmt* stmt);
extern void AlterSequenceWrapper(AlterSeqStmt* stmt);
extern void PreventAlterSeqInTransaction(bool isTopLevel, AlterSeqStmt* stmt);
extern void ResetSequence(Oid seq_relid, bool restart);
extern void seq_redo(XLogReaderState* rptr);
extern void seq_desc(StringInfo buf, XLogReaderState* record);
extern const char* seq_type_name(uint8 subtype);
extern GTM_UUID get_uuid_from_rel(Relation rel);
extern void lockNextvalOnCn(Oid relid);
extern void get_sequence_params(Relation rel, int64* uuid, int64* start, int64* increment, int64* maxvalue,
int64* minvalue, int64* cache, bool* cycle);
#ifdef PGXC
/*
* List of actions that registered the callback.
* This is listed here and not in sequence.c because callback can also
* be registered in dependency.c and tablecmds.c as sequences can be dropped
* or renamed in cascade.
*/
typedef enum { GTM_CREATE_SEQ, GTM_DROP_SEQ } GTM_SequenceDropType;
/*
* Arguments for callback of sequence drop on GTM
*/
typedef struct drop_sequence_callback_arg {
GTM_UUID seq_uuid;
GTM_SequenceDropType type;
GTM_SequenceKeyType key;
} drop_sequence_callback_arg;
/*
* Arguments for callback of sequence rename on GTM
*/
typedef struct rename_sequence_callback_arg {
char* newseqname;
char* oldseqname;
} rename_sequence_callback_arg;
typedef enum {
NDE_UNKNOWN = 0,
NDE_NUMERIC, /* expected numeric nextval */
NDE_BIGINT /* expected bigint nextval */
} nextval_default_expr_type_enum;
extern void delete_global_seq(Oid relid, Relation seqrel);
/* Sequence callbacks on GTM */
extern void register_sequence_rename_cb(const char* oldseqname, const char* newseqname);
extern void rename_sequence_cb(GTMEvent event, void* args);
extern void register_sequence_cb(GTM_UUID seq_uuid, GTM_SequenceDropType type);
extern void drop_sequence_cb(GTMEvent event, void* args);
extern bool IsTempSequence(Oid relid);
extern char* GetGlobalSeqName(Relation rel, const char* new_seqname, const char* new_schemaname);
extern char* gen_hybirdmsg_for_CreateSeqStmt(CreateSeqStmt* stmt, const char* queryString);
extern int64 gen_uuid(List* uuids);
extern char* gen_hybirdmsg_for_CreateSchemaStmt(CreateSchemaStmt* stmt, const char* queryString);
extern void gen_uuid_for_CreateStmt(CreateStmt* stmt, List* uuids);
extern void gen_uuid_for_CreateSchemaStmt(List* stmts, List* uuids);
extern void processUpdateSequenceMsg(List* nameList, int64 lastvalue);
extern void flushSequenceMsg();
extern void checkAndDoUpdateSequence();
#endif
/* Sequence util */
extern void fill_seq_with_data(Relation rel, HeapTuple tuple);
extern void ResetvalGlobal(Oid relid);
extern Relation lock_and_open_seq(SeqTable seq);
extern void init_sequence(Oid relid, SeqTable* p_elm, Relation* p_rel);
extern SeqTable GetSessSeqElm(Oid relid);
extern char* GetGlobalSeqNameForUpdate(Relation seqrel, char** dbname, char** schemaname);
extern uint32 RelidGetHash(Oid seq_relid);
extern SeqTable GetGlobalSeqElm(Oid relid, GlobalSeqInfoHashBucket* bucket);
#endif /* SEQUENCE_H */