mirror of https://github.com/citusdata/citus.git
209 lines
4.9 KiB
C
209 lines
4.9 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* qualify_sequence_stmt.c
|
|
* Functions specialized in fully qualifying all sequence statements. These
|
|
* functions are dispatched from qualify.c
|
|
*
|
|
* Fully qualifying sequence statements consists of adding the schema name
|
|
* to the subject of the sequence.
|
|
*
|
|
* Goal would be that the deparser functions for these statements can
|
|
* serialize the statement without any external lookups.
|
|
*
|
|
* Copyright (c), Citus Data, Inc.
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
#include "distributed/commands.h"
|
|
#include "distributed/deparser.h"
|
|
#include "distributed/listutils.h"
|
|
#include "distributed/version_compat.h"
|
|
#include "parser/parse_func.h"
|
|
#include "utils/lsyscache.h"
|
|
|
|
|
|
/*
|
|
* QualifyAlterSequenceOwnerStmt transforms a
|
|
* ALTER SEQUENCE .. OWNER TO ..
|
|
* statement in place and makes the sequence name fully qualified.
|
|
*/
|
|
void
|
|
QualifyAlterSequenceOwnerStmt(Node *node)
|
|
{
|
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
|
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE);
|
|
|
|
RangeVar *seq = stmt->relation;
|
|
|
|
if (seq->schemaname == NULL)
|
|
{
|
|
Oid seqOid = RangeVarGetRelid(seq, NoLock, stmt->missing_ok);
|
|
|
|
if (OidIsValid(seqOid))
|
|
{
|
|
Oid schemaOid = get_rel_namespace(seqOid);
|
|
seq->schemaname = get_namespace_name(schemaOid);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
|
|
/*
|
|
* QualifyAlterSequencePersistenceStmt transforms a
|
|
* ALTER SEQUENCE .. SET LOGGED/UNLOGGED
|
|
* statement in place and makes the sequence name fully qualified.
|
|
*/
|
|
void
|
|
QualifyAlterSequencePersistenceStmt(Node *node)
|
|
{
|
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
|
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE);
|
|
|
|
RangeVar *seq = stmt->relation;
|
|
|
|
if (seq->schemaname == NULL)
|
|
{
|
|
Oid seqOid = RangeVarGetRelid(seq, NoLock, stmt->missing_ok);
|
|
|
|
if (OidIsValid(seqOid))
|
|
{
|
|
Oid schemaOid = get_rel_namespace(seqOid);
|
|
seq->schemaname = get_namespace_name(schemaOid);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
* QualifyAlterSequenceSchemaStmt transforms a
|
|
* ALTER SEQUENCE .. SET SCHEMA ..
|
|
* statement in place and makes the sequence name fully qualified.
|
|
*/
|
|
void
|
|
QualifyAlterSequenceSchemaStmt(Node *node)
|
|
{
|
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
|
Assert(stmt->objectType == OBJECT_SEQUENCE);
|
|
|
|
RangeVar *seq = stmt->relation;
|
|
|
|
if (seq->schemaname == NULL)
|
|
{
|
|
Oid seqOid = RangeVarGetRelid(seq, NoLock, stmt->missing_ok);
|
|
|
|
if (OidIsValid(seqOid))
|
|
{
|
|
Oid schemaOid = get_rel_namespace(seqOid);
|
|
seq->schemaname = get_namespace_name(schemaOid);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* QualifyRenameSequenceStmt transforms a
|
|
* ALTER SEQUENCE .. RENAME TO ..
|
|
* statement in place and makes the sequence name fully qualified.
|
|
*/
|
|
void
|
|
QualifyRenameSequenceStmt(Node *node)
|
|
{
|
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
|
Assert(stmt->renameType == OBJECT_SEQUENCE);
|
|
|
|
RangeVar *seq = stmt->relation;
|
|
|
|
if (seq->schemaname == NULL)
|
|
{
|
|
Oid seqOid = RangeVarGetRelid(seq, NoLock, stmt->missing_ok);
|
|
|
|
if (OidIsValid(seqOid))
|
|
{
|
|
Oid schemaOid = get_rel_namespace(seqOid);
|
|
seq->schemaname = get_namespace_name(schemaOid);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* QualifyDropSequenceStmt transforms a DROP SEQUENCE
|
|
* statement in place and makes the sequence name fully qualified.
|
|
*/
|
|
void
|
|
QualifyDropSequenceStmt(Node *node)
|
|
{
|
|
DropStmt *stmt = castNode(DropStmt, node);
|
|
|
|
Assert(stmt->removeType == OBJECT_SEQUENCE);
|
|
|
|
List *objectNameListWithSchema = NIL;
|
|
List *objectNameList = NULL;
|
|
foreach_ptr(objectNameList, stmt->objects)
|
|
{
|
|
RangeVar *seq = makeRangeVarFromNameList(objectNameList);
|
|
|
|
if (seq->schemaname == NULL)
|
|
{
|
|
Oid seqOid = RangeVarGetRelid(seq, NoLock, stmt->missing_ok);
|
|
|
|
if (OidIsValid(seqOid))
|
|
{
|
|
Oid schemaOid = get_rel_namespace(seqOid);
|
|
seq->schemaname = get_namespace_name(schemaOid);
|
|
}
|
|
}
|
|
|
|
objectNameListWithSchema = lappend(objectNameListWithSchema,
|
|
MakeNameListFromRangeVar(seq));
|
|
}
|
|
|
|
stmt->objects = objectNameListWithSchema;
|
|
}
|
|
|
|
|
|
/*
|
|
* QualifyGrantOnSequenceStmt transforms a
|
|
* GRANT ON SEQUENCE ...
|
|
* statement in place and makes the sequence names fully qualified.
|
|
*/
|
|
void
|
|
QualifyGrantOnSequenceStmt(Node *node)
|
|
{
|
|
GrantStmt *stmt = castNode(GrantStmt, node);
|
|
Assert(stmt->objtype == OBJECT_SEQUENCE);
|
|
|
|
/*
|
|
* The other option would be GRANT ALL SEQUENCES ON SCHEMA ...
|
|
* For that we don't need to qualify
|
|
*/
|
|
if (stmt->targtype != ACL_TARGET_OBJECT)
|
|
{
|
|
return;
|
|
}
|
|
List *qualifiedSequenceRangeVars = NIL;
|
|
RangeVar *sequenceRangeVar = NULL;
|
|
foreach_ptr(sequenceRangeVar, stmt->objects)
|
|
{
|
|
if (sequenceRangeVar->schemaname == NULL)
|
|
{
|
|
Oid seqOid = RangeVarGetRelid(sequenceRangeVar, NoLock, false);
|
|
Oid schemaOid = get_rel_namespace(seqOid);
|
|
sequenceRangeVar->schemaname = get_namespace_name(schemaOid);
|
|
}
|
|
|
|
qualifiedSequenceRangeVars = lappend(qualifiedSequenceRangeVars,
|
|
sequenceRangeVar);
|
|
}
|
|
|
|
stmt->objects = qualifiedSequenceRangeVars;
|
|
}
|