Header And Logo

PostgreSQL
| The world's most advanced open source database.

misc.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * misc.c
00004  *
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/utils/adt/misc.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 #include "postgres.h"
00016 
00017 #include <sys/file.h>
00018 #include <signal.h>
00019 #include <dirent.h>
00020 #include <math.h>
00021 #include <unistd.h>
00022 
00023 #include "catalog/catalog.h"
00024 #include "catalog/pg_tablespace.h"
00025 #include "catalog/pg_type.h"
00026 #include "commands/dbcommands.h"
00027 #include "common/relpath.h"
00028 #include "funcapi.h"
00029 #include "miscadmin.h"
00030 #include "parser/keywords.h"
00031 #include "postmaster/syslogger.h"
00032 #include "rewrite/rewriteHandler.h"
00033 #include "storage/fd.h"
00034 #include "storage/pmsignal.h"
00035 #include "storage/proc.h"
00036 #include "storage/procarray.h"
00037 #include "utils/lsyscache.h"
00038 #include "tcop/tcopprot.h"
00039 #include "utils/builtins.h"
00040 #include "utils/timestamp.h"
00041 
00042 #define atooid(x)  ((Oid) strtoul((x), NULL, 10))
00043 
00044 
00045 /*
00046  * current_database()
00047  *  Expose the current database to the user
00048  */
00049 Datum
00050 current_database(PG_FUNCTION_ARGS)
00051 {
00052     Name        db;
00053 
00054     db = (Name) palloc(NAMEDATALEN);
00055 
00056     namestrcpy(db, get_database_name(MyDatabaseId));
00057     PG_RETURN_NAME(db);
00058 }
00059 
00060 
00061 /*
00062  * current_query()
00063  *  Expose the current query to the user (useful in stored procedures)
00064  *  We might want to use ActivePortal->sourceText someday.
00065  */
00066 Datum
00067 current_query(PG_FUNCTION_ARGS)
00068 {
00069     /* there is no easy way to access the more concise 'query_string' */
00070     if (debug_query_string)
00071         PG_RETURN_TEXT_P(cstring_to_text(debug_query_string));
00072     else
00073         PG_RETURN_NULL();
00074 }
00075 
00076 /*
00077  * Send a signal to another backend.
00078  *
00079  * The signal is delivered if the user is either a superuser or the same
00080  * role as the backend being signaled. For "dangerous" signals, an explicit
00081  * check for superuser needs to be done prior to calling this function.
00082  *
00083  * Returns 0 on success, 1 on general failure, and 2 on permission error.
00084  * In the event of a general failure (return code 1), a warning message will
00085  * be emitted. For permission errors, doing that is the responsibility of
00086  * the caller.
00087  */
00088 #define SIGNAL_BACKEND_SUCCESS 0
00089 #define SIGNAL_BACKEND_ERROR 1
00090 #define SIGNAL_BACKEND_NOPERMISSION 2
00091 static int
00092 pg_signal_backend(int pid, int sig)
00093 {
00094     PGPROC     *proc = BackendPidGetProc(pid);
00095 
00096     /*
00097      * BackendPidGetProc returns NULL if the pid isn't valid; but by the time
00098      * we reach kill(), a process for which we get a valid proc here might have
00099      * terminated on its own.  There's no way to acquire a lock on an arbitrary
00100      * process to prevent that. But since so far all the callers of this
00101      * mechanism involve some request for ending the process anyway, that it
00102      * might end on its own first is not a problem.
00103      */
00104     if (proc == NULL)
00105     {
00106         /*
00107          * This is just a warning so a loop-through-resultset will not abort
00108          * if one backend terminated on its own during the run.
00109          */
00110         ereport(WARNING,
00111                 (errmsg("PID %d is not a PostgreSQL server process", pid)));
00112         return SIGNAL_BACKEND_ERROR;
00113     }
00114 
00115     if (!(superuser() || proc->roleId == GetUserId()))
00116         return SIGNAL_BACKEND_NOPERMISSION;
00117 
00118     /*
00119      * Can the process we just validated above end, followed by the pid being
00120      * recycled for a new process, before reaching here?  Then we'd be trying
00121      * to kill the wrong thing.  Seems near impossible when sequential pid
00122      * assignment and wraparound is used.  Perhaps it could happen on a system
00123      * where pid re-use is randomized.  That race condition possibility seems
00124      * too unlikely to worry about.
00125      */
00126 
00127     /* If we have setsid(), signal the backend's whole process group */
00128 #ifdef HAVE_SETSID
00129     if (kill(-pid, sig))
00130 #else
00131     if (kill(pid, sig))
00132 #endif
00133     {
00134         /* Again, just a warning to allow loops */
00135         ereport(WARNING,
00136                 (errmsg("could not send signal to process %d: %m", pid)));
00137         return SIGNAL_BACKEND_ERROR;
00138     }
00139     return SIGNAL_BACKEND_SUCCESS;
00140 }
00141 
00142 /*
00143  * Signal to cancel a backend process.  This is allowed if you are superuser or
00144  * have the same role as the process being canceled.
00145  */
00146 Datum
00147 pg_cancel_backend(PG_FUNCTION_ARGS)
00148 {
00149     int         r = pg_signal_backend(PG_GETARG_INT32(0), SIGINT);
00150 
00151     if (r == SIGNAL_BACKEND_NOPERMISSION)
00152         ereport(ERROR,
00153                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
00154                  (errmsg("must be superuser or have the same role to cancel queries running in other server processes"))));
00155 
00156     PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS);
00157 }
00158 
00159 /*
00160  * Signal to terminate a backend process.  This is allowed if you are superuser
00161  * or have the same role as the process being terminated.
00162  */
00163 Datum
00164 pg_terminate_backend(PG_FUNCTION_ARGS)
00165 {
00166     int         r = pg_signal_backend(PG_GETARG_INT32(0), SIGTERM);
00167 
00168     if (r == SIGNAL_BACKEND_NOPERMISSION)
00169         ereport(ERROR,
00170                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
00171                  (errmsg("must be superuser or have the same role to terminate other server processes"))));
00172 
00173     PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS);
00174 }
00175 
00176 /*
00177  * Signal to reload the database configuration
00178  */
00179 Datum
00180 pg_reload_conf(PG_FUNCTION_ARGS)
00181 {
00182     if (!superuser())
00183         ereport(ERROR,
00184                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
00185                  (errmsg("must be superuser to signal the postmaster"))));
00186 
00187     if (kill(PostmasterPid, SIGHUP))
00188     {
00189         ereport(WARNING,
00190                 (errmsg("failed to send signal to postmaster: %m")));
00191         PG_RETURN_BOOL(false);
00192     }
00193 
00194     PG_RETURN_BOOL(true);
00195 }
00196 
00197 
00198 /*
00199  * Rotate log file
00200  */
00201 Datum
00202 pg_rotate_logfile(PG_FUNCTION_ARGS)
00203 {
00204     if (!superuser())
00205         ereport(ERROR,
00206                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
00207                  (errmsg("must be superuser to rotate log files"))));
00208 
00209     if (!Logging_collector)
00210     {
00211         ereport(WARNING,
00212         (errmsg("rotation not possible because log collection not active")));
00213         PG_RETURN_BOOL(false);
00214     }
00215 
00216     SendPostmasterSignal(PMSIGNAL_ROTATE_LOGFILE);
00217     PG_RETURN_BOOL(true);
00218 }
00219 
00220 /* Function to find out which databases make use of a tablespace */
00221 
00222 typedef struct
00223 {
00224     char       *location;
00225     DIR        *dirdesc;
00226 } ts_db_fctx;
00227 
00228 Datum
00229 pg_tablespace_databases(PG_FUNCTION_ARGS)
00230 {
00231     FuncCallContext *funcctx;
00232     struct dirent *de;
00233     ts_db_fctx *fctx;
00234 
00235     if (SRF_IS_FIRSTCALL())
00236     {
00237         MemoryContext oldcontext;
00238         Oid         tablespaceOid = PG_GETARG_OID(0);
00239 
00240         funcctx = SRF_FIRSTCALL_INIT();
00241         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
00242 
00243         fctx = palloc(sizeof(ts_db_fctx));
00244 
00245         /*
00246          * size = tablespace dirname length + dir sep char + oid + terminator
00247          */
00248         fctx->location = (char *) palloc(9 + 1 + OIDCHARS + 1 +
00249                                    strlen(TABLESPACE_VERSION_DIRECTORY) + 1);
00250         if (tablespaceOid == GLOBALTABLESPACE_OID)
00251         {
00252             fctx->dirdesc = NULL;
00253             ereport(WARNING,
00254                     (errmsg("global tablespace never has databases")));
00255         }
00256         else
00257         {
00258             if (tablespaceOid == DEFAULTTABLESPACE_OID)
00259                 sprintf(fctx->location, "base");
00260             else
00261                 sprintf(fctx->location, "pg_tblspc/%u/%s", tablespaceOid,
00262                         TABLESPACE_VERSION_DIRECTORY);
00263 
00264             fctx->dirdesc = AllocateDir(fctx->location);
00265 
00266             if (!fctx->dirdesc)
00267             {
00268                 /* the only expected error is ENOENT */
00269                 if (errno != ENOENT)
00270                     ereport(ERROR,
00271                             (errcode_for_file_access(),
00272                              errmsg("could not open directory \"%s\": %m",
00273                                     fctx->location)));
00274                 ereport(WARNING,
00275                       (errmsg("%u is not a tablespace OID", tablespaceOid)));
00276             }
00277         }
00278         funcctx->user_fctx = fctx;
00279         MemoryContextSwitchTo(oldcontext);
00280     }
00281 
00282     funcctx = SRF_PERCALL_SETUP();
00283     fctx = (ts_db_fctx *) funcctx->user_fctx;
00284 
00285     if (!fctx->dirdesc)         /* not a tablespace */
00286         SRF_RETURN_DONE(funcctx);
00287 
00288     while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
00289     {
00290         char       *subdir;
00291         DIR        *dirdesc;
00292         Oid         datOid = atooid(de->d_name);
00293 
00294         /* this test skips . and .., but is awfully weak */
00295         if (!datOid)
00296             continue;
00297 
00298         /* if database subdir is empty, don't report tablespace as used */
00299 
00300         /* size = path length + dir sep char + file name + terminator */
00301         subdir = palloc(strlen(fctx->location) + 1 + strlen(de->d_name) + 1);
00302         sprintf(subdir, "%s/%s", fctx->location, de->d_name);
00303         dirdesc = AllocateDir(subdir);
00304         while ((de = ReadDir(dirdesc, subdir)) != NULL)
00305         {
00306             if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
00307                 break;
00308         }
00309         FreeDir(dirdesc);
00310         pfree(subdir);
00311 
00312         if (!de)
00313             continue;           /* indeed, nothing in it */
00314 
00315         SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(datOid));
00316     }
00317 
00318     FreeDir(fctx->dirdesc);
00319     SRF_RETURN_DONE(funcctx);
00320 }
00321 
00322 
00323 /*
00324  * pg_tablespace_location - get location for a tablespace
00325  */
00326 Datum
00327 pg_tablespace_location(PG_FUNCTION_ARGS)
00328 {
00329     Oid         tablespaceOid = PG_GETARG_OID(0);
00330     char        sourcepath[MAXPGPATH];
00331     char        targetpath[MAXPGPATH];
00332     int         rllen;
00333 
00334     /*
00335      * It's useful to apply this function to pg_class.reltablespace, wherein
00336      * zero means "the database's default tablespace".  So, rather than
00337      * throwing an error for zero, we choose to assume that's what is meant.
00338      */
00339     if (tablespaceOid == InvalidOid)
00340         tablespaceOid = MyDatabaseTableSpace;
00341 
00342     /*
00343      * Return empty string for the cluster's default tablespaces
00344      */
00345     if (tablespaceOid == DEFAULTTABLESPACE_OID ||
00346         tablespaceOid == GLOBALTABLESPACE_OID)
00347         PG_RETURN_TEXT_P(cstring_to_text(""));
00348 
00349 #if defined(HAVE_READLINK) || defined(WIN32)
00350 
00351     /*
00352      * Find the location of the tablespace by reading the symbolic link that
00353      * is in pg_tblspc/<oid>.
00354      */
00355     snprintf(sourcepath, sizeof(sourcepath), "pg_tblspc/%u", tablespaceOid);
00356 
00357     rllen = readlink(sourcepath, targetpath, sizeof(targetpath));
00358     if (rllen < 0)
00359         ereport(ERROR,
00360                 (errmsg("could not read symbolic link \"%s\": %m",
00361                         sourcepath)));
00362     else if (rllen >= sizeof(targetpath))
00363         ereport(ERROR,
00364                 (errmsg("symbolic link \"%s\" target is too long",
00365                         sourcepath)));
00366     targetpath[rllen] = '\0';
00367 
00368     PG_RETURN_TEXT_P(cstring_to_text(targetpath));
00369 #else
00370     ereport(ERROR,
00371             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00372              errmsg("tablespaces are not supported on this platform")));
00373     PG_RETURN_NULL();
00374 #endif
00375 }
00376 
00377 /*
00378  * pg_sleep - delay for N seconds
00379  */
00380 Datum
00381 pg_sleep(PG_FUNCTION_ARGS)
00382 {
00383     float8      secs = PG_GETARG_FLOAT8(0);
00384     float8      endtime;
00385 
00386     /*
00387      * We break the requested sleep into segments of no more than 1 second, to
00388      * put an upper bound on how long it will take us to respond to a cancel
00389      * or die interrupt.  (Note that pg_usleep is interruptible by signals on
00390      * some platforms but not others.)  Also, this method avoids exposing
00391      * pg_usleep's upper bound on allowed delays.
00392      *
00393      * By computing the intended stop time initially, we avoid accumulation of
00394      * extra delay across multiple sleeps.  This also ensures we won't delay
00395      * less than the specified time if pg_usleep is interrupted by other
00396      * signals such as SIGHUP.
00397      */
00398 
00399 #ifdef HAVE_INT64_TIMESTAMP
00400 #define GetNowFloat()   ((float8) GetCurrentTimestamp() / 1000000.0)
00401 #else
00402 #define GetNowFloat()   GetCurrentTimestamp()
00403 #endif
00404 
00405     endtime = GetNowFloat() + secs;
00406 
00407     for (;;)
00408     {
00409         float8      delay;
00410 
00411         CHECK_FOR_INTERRUPTS();
00412         delay = endtime - GetNowFloat();
00413         if (delay >= 1.0)
00414             pg_usleep(1000000L);
00415         else if (delay > 0.0)
00416             pg_usleep((long) ceil(delay * 1000000.0));
00417         else
00418             break;
00419     }
00420 
00421     PG_RETURN_VOID();
00422 }
00423 
00424 /* Function to return the list of grammar keywords */
00425 Datum
00426 pg_get_keywords(PG_FUNCTION_ARGS)
00427 {
00428     FuncCallContext *funcctx;
00429 
00430     if (SRF_IS_FIRSTCALL())
00431     {
00432         MemoryContext oldcontext;
00433         TupleDesc   tupdesc;
00434 
00435         funcctx = SRF_FIRSTCALL_INIT();
00436         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
00437 
00438         tupdesc = CreateTemplateTupleDesc(3, false);
00439         TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
00440                            TEXTOID, -1, 0);
00441         TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode",
00442                            CHAROID, -1, 0);
00443         TupleDescInitEntry(tupdesc, (AttrNumber) 3, "catdesc",
00444                            TEXTOID, -1, 0);
00445 
00446         funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
00447 
00448         MemoryContextSwitchTo(oldcontext);
00449     }
00450 
00451     funcctx = SRF_PERCALL_SETUP();
00452 
00453     if (funcctx->call_cntr < NumScanKeywords)
00454     {
00455         char       *values[3];
00456         HeapTuple   tuple;
00457 
00458         /* cast-away-const is ugly but alternatives aren't much better */
00459         values[0] = (char *) ScanKeywords[funcctx->call_cntr].name;
00460 
00461         switch (ScanKeywords[funcctx->call_cntr].category)
00462         {
00463             case UNRESERVED_KEYWORD:
00464                 values[1] = "U";
00465                 values[2] = _("unreserved");
00466                 break;
00467             case COL_NAME_KEYWORD:
00468                 values[1] = "C";
00469                 values[2] = _("unreserved (cannot be function or type name)");
00470                 break;
00471             case TYPE_FUNC_NAME_KEYWORD:
00472                 values[1] = "T";
00473                 values[2] = _("reserved (can be function or type name)");
00474                 break;
00475             case RESERVED_KEYWORD:
00476                 values[1] = "R";
00477                 values[2] = _("reserved");
00478                 break;
00479             default:            /* shouldn't be possible */
00480                 values[1] = NULL;
00481                 values[2] = NULL;
00482                 break;
00483         }
00484 
00485         tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
00486 
00487         SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
00488     }
00489 
00490     SRF_RETURN_DONE(funcctx);
00491 }
00492 
00493 
00494 /*
00495  * Return the type of the argument.
00496  */
00497 Datum
00498 pg_typeof(PG_FUNCTION_ARGS)
00499 {
00500     PG_RETURN_OID(get_fn_expr_argtype(fcinfo->flinfo, 0));
00501 }
00502 
00503 
00504 /*
00505  * Implementation of the COLLATE FOR expression; returns the collation
00506  * of the argument.
00507  */
00508 Datum
00509 pg_collation_for(PG_FUNCTION_ARGS)
00510 {
00511     Oid         typeid;
00512     Oid         collid;
00513 
00514     typeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
00515     if (!typeid)
00516         PG_RETURN_NULL();
00517     if (!type_is_collatable(typeid) && typeid != UNKNOWNOID)
00518         ereport(ERROR,
00519                 (errcode(ERRCODE_DATATYPE_MISMATCH),
00520                  errmsg("collations are not supported by type %s",
00521                         format_type_be(typeid))));
00522 
00523     collid = PG_GET_COLLATION();
00524     if (!collid)
00525         PG_RETURN_NULL();
00526     PG_RETURN_TEXT_P(cstring_to_text(generate_collation_name(collid)));
00527 }
00528 
00529 
00530 /*
00531  * information_schema support functions
00532  *
00533  * Test whether a view (identified by pg_class OID) is insertable-into or
00534  * updatable.  The latter requires delete capability too.  This is an
00535  * artifact of the way the SQL standard defines the information_schema views:
00536  * if we defined separate functions for update and delete, we'd double the
00537  * work required to compute the view columns.
00538  *
00539  * These rely on relation_is_updatable(), which is in rewriteHandler.c.
00540  */
00541 Datum
00542 pg_view_is_insertable(PG_FUNCTION_ARGS)
00543 {
00544     Oid         viewoid = PG_GETARG_OID(0);
00545     int         req_events = (1 << CMD_INSERT);
00546 
00547     PG_RETURN_BOOL(relation_is_updatable(viewoid, req_events));
00548 }
00549 
00550 Datum
00551 pg_view_is_updatable(PG_FUNCTION_ARGS)
00552 {
00553     Oid         viewoid = PG_GETARG_OID(0);
00554     int         req_events = (1 << CMD_UPDATE) | (1 << CMD_DELETE);
00555 
00556     PG_RETURN_BOOL(relation_is_updatable(viewoid, req_events));
00557 }