📄 utility.c
字号:
/*------------------------------------------------------------------------- * * utility.c * Contains functions which control the execution of the POSTGRES utility * commands. At one time acted as an interface between the Lisp and C * systems. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * $Header: /usr/local/cvsroot/pgsql/src/backend/tcop/utility.c,v 1.61 1999/05/25 16:11:43 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/xact.h"#include "access/heapam.h"#include "catalog/catalog.h"#include "catalog/pg_type.h"#include "commands/async.h"#include "commands/cluster.h"#include "commands/command.h"#include "commands/copy.h"#include "commands/creatinh.h"#include "commands/dbcommands.h"#include "commands/sequence.h"#include "commands/defrem.h"#include "commands/rename.h"#include "commands/view.h"#include "commands/version.h"#include "commands/vacuum.h"#include "commands/explain.h"#include "commands/trigger.h"#include "commands/proclang.h"#include "commands/variable.h"#include "nodes/parsenodes.h"#include "../backend/parser/parse.h"#include "utils/builtins.h"#include "utils/acl.h"#include "utils/palloc.h"#include "rewrite/rewriteRemove.h"#include "rewrite/rewriteDefine.h"#include "tcop/tcopdebug.h"#include "tcop/dest.h"#include "tcop/utility.h"#include "fmgr.h" /* For load_file() */#include "storage/fd.h"#include "utils/ps_status.h"#ifndef NO_SECURITY#include "miscadmin.h"#include "utils/acl.h"#include "utils/syscache.h"#endifvoid DefineUser(CreateUserStmt *stmt, CommandDest);void AlterUser(AlterUserStmt *stmt, CommandDest);void RemoveUser(char *username, CommandDest);/* ---------------- * CHECK_IF_ABORTED() is used to avoid doing unnecessary * processing within an aborted transaction block. * ---------------- */ /* we have to use IF because of the 'break' */#define CHECK_IF_ABORTED() \if (1) \{ \ if (IsAbortedTransactionBlockState()) \ { \ elog(NOTICE, "(transaction aborted): %s", \ "all queries ignored until end of transaction block"); \ commandTag = "*ABORT STATE*"; \ break; \ } \} else/* ---------------- * general utility function invoker * ---------------- */voidProcessUtility(Node *parsetree, CommandDest dest){ char *commandTag = NULL; char *relname; char *relationName; char *userName; userName = GetPgUserName(); switch (nodeTag(parsetree)) { /* * ******************************** transactions ******************************** * */ case T_TransactionStmt: { TransactionStmt *stmt = (TransactionStmt *) parsetree; switch (stmt->command) { case BEGIN_TRANS: PS_SET_STATUS(commandTag = "BEGIN"); CHECK_IF_ABORTED(); BeginTransactionBlock(); break; case END_TRANS: PS_SET_STATUS(commandTag = "END"); EndTransactionBlock(); break; case ABORT_TRANS: PS_SET_STATUS(commandTag = "ABORT"); UserAbortTransactionBlock(); break; } } break; /* * ******************************** portal manipulation ******************************** * */ case T_ClosePortalStmt: { ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree; PS_SET_STATUS(commandTag = "CLOSE"); CHECK_IF_ABORTED(); PerformPortalClose(stmt->portalname, dest); } break; case T_FetchStmt: { FetchStmt *stmt = (FetchStmt *) parsetree; char *portalName = stmt->portalname; bool forward; int count; PS_SET_STATUS(commandTag = (stmt->ismove) ? "MOVE" : "FETCH"); CHECK_IF_ABORTED(); forward = (bool) (stmt->direction == FORWARD); /* * parser ensures that count is >= 0 and 'fetch ALL' -> 0 */ count = stmt->howMany; PerformPortalFetch(portalName, forward, count, commandTag, (stmt->ismove) ? None : dest); /* /dev/null for MOVE */ } break; /* * ******************************** relation and attribute * manipulation ******************************** * */ case T_CreateStmt: PS_SET_STATUS(commandTag = "CREATE"); CHECK_IF_ABORTED(); DefineRelation((CreateStmt *) parsetree, RELKIND_RELATION); break; case T_DestroyStmt: { DestroyStmt *stmt = (DestroyStmt *) parsetree; List *arg; List *args = stmt->relNames; Relation rel; PS_SET_STATUS(commandTag = "DROP"); CHECK_IF_ABORTED(); foreach(arg, args) { relname = strVal(lfirst(arg)); if (!allowSystemTableMods && IsSystemRelationName(relname)) elog(ERROR, "class \"%s\" is a system catalog", relname); rel = heap_openr(relname); if (RelationIsValid(rel)) { if (stmt->sequence && rel->rd_rel->relkind != RELKIND_SEQUENCE) elog(ERROR, "Use DROP TABLE to drop table '%s'", relname); if (!(stmt->sequence) && rel->rd_rel->relkind == RELKIND_SEQUENCE) elog(ERROR, "Use DROP SEQUENCE to drop sequence '%s'", relname); heap_close(rel); }#ifndef NO_SECURITY if (!pg_ownercheck(userName, relname, RELNAME)) elog(ERROR, "you do not own class \"%s\"", relname);#endif } foreach(arg, args) { relname = strVal(lfirst(arg)); RemoveRelation(relname); } } break; case T_CopyStmt: { CopyStmt *stmt = (CopyStmt *) parsetree; PS_SET_STATUS(commandTag = "COPY"); CHECK_IF_ABORTED(); DoCopy(stmt->relname, stmt->binary, stmt->oids, (bool) (stmt->direction == FROM), (bool) (stmt->filename == NULL), /* * null filename means copy to/from stdout/stdin, rather * than to/from a file. */ stmt->filename, stmt->delimiter); } break; case T_AddAttrStmt: { AddAttrStmt *stmt = (AddAttrStmt *) parsetree; PS_SET_STATUS(commandTag = "ADD"); CHECK_IF_ABORTED(); /* * owner checking done in PerformAddAttribute (now * recursive) */ PerformAddAttribute(stmt->relname, userName, stmt->inh, (ColumnDef *) stmt->colDef); } break; /* * schema */ case T_RenameStmt: { RenameStmt *stmt = (RenameStmt *) parsetree; PS_SET_STATUS(commandTag = "RENAME"); CHECK_IF_ABORTED(); relname = stmt->relname; if (!allowSystemTableMods && IsSystemRelationName(relname)) elog(ERROR, "class \"%s\" is a system catalog", relname);#ifndef NO_SECURITY if (!pg_ownercheck(userName, relname, RELNAME)) elog(ERROR, "you do not own class \"%s\"", relname);#endif /* ---------------- * XXX using len == 3 to tell the difference * between "rename rel to newrel" and * "rename att in rel to newatt" will not * work soon because "rename type/operator/rule" * stuff is being added. - cim 10/24/90 * ---------------- * [another piece of amuzing but useless anecdote -- ay] */ if (stmt->column == NULL) { /* ---------------- * rename relation * * Note: we also rename the "type" tuple * corresponding to the relation. * ---------------- */ renamerel(relname, /* old name */ stmt->newname); /* new name */ TypeRename(relname, /* old name */ stmt->newname); /* new name */ } else { /* ---------------- * rename attribute * ---------------- */ renameatt(relname, /* relname */ stmt->column, /* old att name */ stmt->newname, /* new att name */ userName, stmt->inh); /* recursive? */ } } break; case T_ChangeACLStmt: { ChangeACLStmt *stmt = (ChangeACLStmt *) parsetree; List *i; AclItem *aip; unsigned modechg; PS_SET_STATUS(commandTag = "CHANGE"); CHECK_IF_ABORTED(); aip = stmt->aclitem; modechg = stmt->modechg;#ifndef NO_SECURITY foreach(i, stmt->relNames) { relname = strVal(lfirst(i)); if (!pg_ownercheck(userName, relname, RELNAME)) elog(ERROR, "you do not own class \"%s\"", relname); }#endif foreach(i, stmt->relNames) { relname = strVal(lfirst(i)); ChangeAcl(relname, aip, modechg); } } break; /* * ******************************** object creation / * destruction ******************************** * */ case T_DefineStmt: { DefineStmt *stmt = (DefineStmt *) parsetree; PS_SET_STATUS(commandTag = "CREATE"); CHECK_IF_ABORTED(); switch (stmt->defType) { case OPERATOR: DefineOperator(stmt->defname, /* operator name */ stmt->definition); /* rest */ break; case TYPE_P: DefineType(stmt->defname, stmt->definition); break; case AGGREGATE: DefineAggregate(stmt->defname, /* aggregate name */ stmt->definition); /* rest */ break; } } break; case T_ViewStmt: /* CREATE VIEW */ { ViewStmt *stmt = (ViewStmt *) parsetree; PS_SET_STATUS(commandTag = "CREATE"); CHECK_IF_ABORTED(); DefineView(stmt->viewname, stmt->query); /* retrieve parsetree */ } break; case T_ProcedureStmt: /* CREATE FUNCTION */ PS_SET_STATUS(commandTag = "CREATE"); CHECK_IF_ABORTED(); CreateFunction((ProcedureStmt *) parsetree, dest); /* everything */ break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -