00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "postgres.h"
00017
00018 #include <ctype.h>
00019 #include <fcntl.h>
00020 #include <unistd.h>
00021
00022 #include "access/heapam.h"
00023 #include "access/htup_details.h"
00024 #include "access/sysattr.h"
00025 #include "access/xact.h"
00026 #include "catalog/catalog.h"
00027 #include "catalog/indexing.h"
00028 #include "catalog/namespace.h"
00029 #include "catalog/pg_authid.h"
00030 #include "catalog/pg_database.h"
00031 #include "catalog/pg_db_role_setting.h"
00032 #include "catalog/pg_tablespace.h"
00033 #include "libpq/auth.h"
00034 #include "libpq/libpq-be.h"
00035 #include "mb/pg_wchar.h"
00036 #include "miscadmin.h"
00037 #include "pgstat.h"
00038 #include "postmaster/autovacuum.h"
00039 #include "postmaster/postmaster.h"
00040 #include "replication/walsender.h"
00041 #include "storage/bufmgr.h"
00042 #include "storage/fd.h"
00043 #include "storage/ipc.h"
00044 #include "storage/lmgr.h"
00045 #include "storage/procarray.h"
00046 #include "storage/procsignal.h"
00047 #include "storage/proc.h"
00048 #include "storage/sinvaladt.h"
00049 #include "storage/smgr.h"
00050 #include "tcop/tcopprot.h"
00051 #include "utils/acl.h"
00052 #include "utils/fmgroids.h"
00053 #include "utils/guc.h"
00054 #include "utils/pg_locale.h"
00055 #include "utils/portal.h"
00056 #include "utils/ps_status.h"
00057 #include "utils/snapmgr.h"
00058 #include "utils/syscache.h"
00059 #include "utils/timeout.h"
00060 #include "utils/tqual.h"
00061
00062
00063 static HeapTuple GetDatabaseTuple(const char *dbname);
00064 static HeapTuple GetDatabaseTupleByOid(Oid dboid);
00065 static void PerformAuthentication(Port *port);
00066 static void CheckMyDatabase(const char *name, bool am_superuser);
00067 static void InitCommunication(void);
00068 static void ShutdownPostgres(int code, Datum arg);
00069 static void StatementTimeoutHandler(void);
00070 static void LockTimeoutHandler(void);
00071 static bool ThereIsAtLeastOneRole(void);
00072 static void process_startup_options(Port *port, bool am_superuser);
00073 static void process_settings(Oid databaseid, Oid roleid);
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 static HeapTuple
00091 GetDatabaseTuple(const char *dbname)
00092 {
00093 HeapTuple tuple;
00094 Relation relation;
00095 SysScanDesc scan;
00096 ScanKeyData key[1];
00097
00098
00099
00100
00101 ScanKeyInit(&key[0],
00102 Anum_pg_database_datname,
00103 BTEqualStrategyNumber, F_NAMEEQ,
00104 CStringGetDatum(dbname));
00105
00106
00107
00108
00109
00110
00111 relation = heap_open(DatabaseRelationId, AccessShareLock);
00112 scan = systable_beginscan(relation, DatabaseNameIndexId,
00113 criticalSharedRelcachesBuilt,
00114 SnapshotNow,
00115 1, key);
00116
00117 tuple = systable_getnext(scan);
00118
00119
00120 if (HeapTupleIsValid(tuple))
00121 tuple = heap_copytuple(tuple);
00122
00123
00124 systable_endscan(scan);
00125 heap_close(relation, AccessShareLock);
00126
00127 return tuple;
00128 }
00129
00130
00131
00132
00133 static HeapTuple
00134 GetDatabaseTupleByOid(Oid dboid)
00135 {
00136 HeapTuple tuple;
00137 Relation relation;
00138 SysScanDesc scan;
00139 ScanKeyData key[1];
00140
00141
00142
00143
00144 ScanKeyInit(&key[0],
00145 ObjectIdAttributeNumber,
00146 BTEqualStrategyNumber, F_OIDEQ,
00147 ObjectIdGetDatum(dboid));
00148
00149
00150
00151
00152
00153
00154 relation = heap_open(DatabaseRelationId, AccessShareLock);
00155 scan = systable_beginscan(relation, DatabaseOidIndexId,
00156 criticalSharedRelcachesBuilt,
00157 SnapshotNow,
00158 1, key);
00159
00160 tuple = systable_getnext(scan);
00161
00162
00163 if (HeapTupleIsValid(tuple))
00164 tuple = heap_copytuple(tuple);
00165
00166
00167 systable_endscan(scan);
00168 heap_close(relation, AccessShareLock);
00169
00170 return tuple;
00171 }
00172
00173
00174
00175
00176
00177
00178
00179 static void
00180 PerformAuthentication(Port *port)
00181 {
00182
00183 ClientAuthInProgress = true;
00184
00185
00186
00187
00188
00189
00190
00191 #ifdef EXEC_BACKEND
00192 if (!load_hba())
00193 {
00194
00195
00196
00197
00198 ereport(FATAL,
00199 (errmsg("could not load pg_hba.conf")));
00200 }
00201
00202 if (!load_ident())
00203 {
00204
00205
00206
00207
00208
00209
00210 }
00211 #endif
00212
00213
00214
00215
00216
00217
00218 enable_timeout_after(STATEMENT_TIMEOUT, AuthenticationTimeout * 1000);
00219
00220
00221
00222
00223 ClientAuthentication(port);
00224
00225
00226
00227
00228 disable_timeout(STATEMENT_TIMEOUT, false);
00229
00230 if (Log_connections)
00231 {
00232 if (am_walsender)
00233 ereport(LOG,
00234 (errmsg("replication connection authorized: user=%s",
00235 port->user_name)));
00236 else
00237 ereport(LOG,
00238 (errmsg("connection authorized: user=%s database=%s",
00239 port->user_name, port->database_name)));
00240 }
00241
00242 set_ps_display("startup", false);
00243
00244 ClientAuthInProgress = false;
00245 }
00246
00247
00248
00249
00250
00251 static void
00252 CheckMyDatabase(const char *name, bool am_superuser)
00253 {
00254 HeapTuple tup;
00255 Form_pg_database dbform;
00256 char *collate;
00257 char *ctype;
00258
00259
00260 tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
00261 if (!HeapTupleIsValid(tup))
00262 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
00263 dbform = (Form_pg_database) GETSTRUCT(tup);
00264
00265
00266 if (strcmp(name, NameStr(dbform->datname)) != 0)
00267 ereport(FATAL,
00268 (errcode(ERRCODE_UNDEFINED_DATABASE),
00269 errmsg("database \"%s\" has disappeared from pg_database",
00270 name),
00271 errdetail("Database OID %u now seems to belong to \"%s\".",
00272 MyDatabaseId, NameStr(dbform->datname))));
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 if (IsUnderPostmaster && !IsAutoVacuumWorkerProcess())
00284 {
00285
00286
00287
00288 if (!dbform->datallowconn)
00289 ereport(FATAL,
00290 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
00291 errmsg("database \"%s\" is not currently accepting connections",
00292 name)));
00293
00294
00295
00296
00297
00298
00299 if (!am_superuser &&
00300 pg_database_aclcheck(MyDatabaseId, GetUserId(),
00301 ACL_CONNECT) != ACLCHECK_OK)
00302 ereport(FATAL,
00303 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
00304 errmsg("permission denied for database \"%s\"", name),
00305 errdetail("User does not have CONNECT privilege.")));
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 if (dbform->datconnlimit >= 0 &&
00318 !am_superuser &&
00319 CountDBBackends(MyDatabaseId) > dbform->datconnlimit)
00320 ereport(FATAL,
00321 (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
00322 errmsg("too many connections for database \"%s\"",
00323 name)));
00324 }
00325
00326
00327
00328
00329
00330 SetDatabaseEncoding(dbform->encoding);
00331
00332 SetConfigOption("server_encoding", GetDatabaseEncodingName(),
00333 PGC_INTERNAL, PGC_S_OVERRIDE);
00334
00335 SetConfigOption("client_encoding", GetDatabaseEncodingName(),
00336 PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
00337
00338
00339 collate = NameStr(dbform->datcollate);
00340 ctype = NameStr(dbform->datctype);
00341
00342 if (pg_perm_setlocale(LC_COLLATE, collate) == NULL)
00343 ereport(FATAL,
00344 (errmsg("database locale is incompatible with operating system"),
00345 errdetail("The database was initialized with LC_COLLATE \"%s\", "
00346 " which is not recognized by setlocale().", collate),
00347 errhint("Recreate the database with another locale or install the missing locale.")));
00348
00349 if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL)
00350 ereport(FATAL,
00351 (errmsg("database locale is incompatible with operating system"),
00352 errdetail("The database was initialized with LC_CTYPE \"%s\", "
00353 " which is not recognized by setlocale().", ctype),
00354 errhint("Recreate the database with another locale or install the missing locale.")));
00355
00356
00357 SetConfigOption("lc_collate", collate, PGC_INTERNAL, PGC_S_OVERRIDE);
00358 SetConfigOption("lc_ctype", ctype, PGC_INTERNAL, PGC_S_OVERRIDE);
00359
00360
00361 #ifdef ENABLE_NLS
00362 pg_bind_textdomain_codeset(textdomain(NULL));
00363 #endif
00364
00365 ReleaseSysCache(tup);
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 static void
00378 InitCommunication(void)
00379 {
00380
00381
00382
00383 if (!IsUnderPostmaster)
00384 {
00385
00386
00387
00388
00389 CreateSharedMemoryAndSemaphores(true, 0);
00390 }
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 void
00409 pg_split_opts(char **argv, int *argcp, char *optstr)
00410 {
00411 while (*optstr)
00412 {
00413 while (isspace((unsigned char) *optstr))
00414 optstr++;
00415 if (*optstr == '\0')
00416 break;
00417 argv[(*argcp)++] = optstr;
00418 while (*optstr && !isspace((unsigned char) *optstr))
00419 optstr++;
00420 if (*optstr)
00421 *optstr++ = '\0';
00422 }
00423 }
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 void
00438 InitializeMaxBackends(void)
00439 {
00440 Assert(MaxBackends == 0);
00441
00442
00443 MaxBackends = MaxConnections + autovacuum_max_workers + 1 +
00444 GetNumShmemAttachedBgworkers();
00445
00446
00447 if (MaxBackends > MAX_BACKENDS)
00448 elog(ERROR, "too many backends configured");
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 void
00460 BaseInit(void)
00461 {
00462
00463
00464
00465
00466 InitCommunication();
00467 DebugFileOpen();
00468
00469
00470 InitFileAccess();
00471 smgrinit();
00472 InitBufferPoolAccess();
00473 }
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 void
00498 InitPostgres(const char *in_dbname, Oid dboid, const char *username,
00499 char *out_dbname)
00500 {
00501 bool bootstrap = IsBootstrapProcessingMode();
00502 bool am_superuser;
00503 char *fullpath;
00504 char dbname[NAMEDATALEN];
00505
00506 elog(DEBUG3, "InitPostgres");
00507
00508
00509
00510
00511
00512
00513 InitProcessPhase2();
00514
00515
00516
00517
00518
00519
00520
00521 MyBackendId = InvalidBackendId;
00522
00523 SharedInvalBackendInit(false);
00524
00525 if (MyBackendId > MaxBackends || MyBackendId <= 0)
00526 elog(FATAL, "bad backend ID: %d", MyBackendId);
00527
00528
00529 ProcSignalInit(MyBackendId);
00530
00531
00532
00533
00534
00535 if (!bootstrap)
00536 {
00537 RegisterTimeout(DEADLOCK_TIMEOUT, CheckDeadLock);
00538 RegisterTimeout(STATEMENT_TIMEOUT, StatementTimeoutHandler);
00539 RegisterTimeout(LOCK_TIMEOUT, LockTimeoutHandler);
00540 }
00541
00542
00543
00544
00545 InitBufferPoolBackend();
00546
00547
00548
00549
00550 if (IsUnderPostmaster)
00551 {
00552
00553
00554
00555
00556
00557
00558 (void) RecoveryInProgress();
00559 }
00560 else
00561 {
00562
00563
00564
00565
00566
00567 StartupXLOG();
00568 on_shmem_exit(ShutdownXLOG, 0);
00569 }
00570
00571
00572
00573
00574
00575
00576
00577 RelationCacheInitialize();
00578 InitCatalogCache();
00579 InitPlanCache();
00580
00581
00582 EnablePortalManager();
00583
00584
00585 if (!bootstrap)
00586 pgstat_initialize();
00587
00588
00589
00590
00591
00592 RelationCacheInitializePhase2();
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 on_shmem_exit(ShutdownPostgres, 0);
00604
00605
00606 if (IsAutoVacuumLauncherProcess())
00607 return;
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 if (!bootstrap)
00618 {
00619
00620 SetCurrentStatementStartTimestamp();
00621 StartTransactionCommand();
00622
00623
00624
00625
00626
00627
00628
00629 XactIsoLevel = XACT_READ_COMMITTED;
00630
00631 (void) GetTransactionSnapshot();
00632 }
00633
00634
00635
00636
00637
00638
00639
00640
00641 if (bootstrap || IsAutoVacuumWorkerProcess())
00642 {
00643 InitializeSessionUserIdStandalone();
00644 am_superuser = true;
00645 }
00646 else if (!IsUnderPostmaster)
00647 {
00648 InitializeSessionUserIdStandalone();
00649 am_superuser = true;
00650 if (!ThereIsAtLeastOneRole())
00651 ereport(WARNING,
00652 (errcode(ERRCODE_UNDEFINED_OBJECT),
00653 errmsg("no roles are defined in this database system"),
00654 errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
00655 username)));
00656 }
00657 else if (IsBackgroundWorker)
00658 {
00659 if (username == NULL)
00660 {
00661 InitializeSessionUserIdStandalone();
00662 am_superuser = true;
00663 }
00664 else
00665 {
00666 InitializeSessionUserId(username);
00667 am_superuser = superuser();
00668 }
00669 }
00670 else
00671 {
00672
00673 Assert(MyProcPort != NULL);
00674 PerformAuthentication(MyProcPort);
00675 InitializeSessionUserId(username);
00676 am_superuser = superuser();
00677 }
00678
00679
00680
00681
00682
00683 if ((!am_superuser || am_walsender) &&
00684 MyProcPort != NULL &&
00685 MyProcPort->canAcceptConnections == CAC_WAITBACKUP)
00686 {
00687 if (am_walsender)
00688 ereport(FATAL,
00689 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
00690 errmsg("new replication connections are not allowed during database shutdown")));
00691 else
00692 ereport(FATAL,
00693 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
00694 errmsg("must be superuser to connect during database shutdown")));
00695 }
00696
00697
00698
00699
00700 if (IsBinaryUpgrade && !am_superuser)
00701 {
00702 ereport(FATAL,
00703 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
00704 errmsg("must be superuser to connect in binary upgrade mode")));
00705 }
00706
00707
00708
00709
00710
00711
00712
00713 if ((!am_superuser || am_walsender) &&
00714 ReservedBackends > 0 &&
00715 !HaveNFreeProcs(ReservedBackends))
00716 ereport(FATAL,
00717 (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
00718 errmsg("remaining connection slots are reserved for non-replication superuser connections")));
00719
00720
00721
00722
00723
00724
00725 if (am_walsender)
00726 {
00727 Assert(!bootstrap);
00728
00729 if (!superuser() && !has_rolreplication(GetUserId()))
00730 ereport(FATAL,
00731 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
00732 errmsg("must be superuser or replication role to start walsender")));
00733
00734
00735 if (MyProcPort != NULL)
00736 process_startup_options(MyProcPort, am_superuser);
00737
00738
00739 if (PostAuthDelay > 0)
00740 pg_usleep(PostAuthDelay * 1000000L);
00741
00742
00743 InitializeClientEncoding();
00744
00745
00746 pgstat_bestart();
00747
00748
00749 CommitTransactionCommand();
00750
00751 return;
00752 }
00753
00754
00755
00756
00757
00758
00759
00760
00761 if (bootstrap)
00762 {
00763 MyDatabaseId = TemplateDbOid;
00764 MyDatabaseTableSpace = DEFAULTTABLESPACE_OID;
00765 }
00766 else if (in_dbname != NULL)
00767 {
00768 HeapTuple tuple;
00769 Form_pg_database dbform;
00770
00771 tuple = GetDatabaseTuple(in_dbname);
00772 if (!HeapTupleIsValid(tuple))
00773 ereport(FATAL,
00774 (errcode(ERRCODE_UNDEFINED_DATABASE),
00775 errmsg("database \"%s\" does not exist", in_dbname)));
00776 dbform = (Form_pg_database) GETSTRUCT(tuple);
00777 MyDatabaseId = HeapTupleGetOid(tuple);
00778 MyDatabaseTableSpace = dbform->dattablespace;
00779
00780 strlcpy(dbname, in_dbname, sizeof(dbname));
00781 }
00782 else
00783 {
00784
00785 HeapTuple tuple;
00786 Form_pg_database dbform;
00787
00788 tuple = GetDatabaseTupleByOid(dboid);
00789 if (!HeapTupleIsValid(tuple))
00790 ereport(FATAL,
00791 (errcode(ERRCODE_UNDEFINED_DATABASE),
00792 errmsg("database %u does not exist", dboid)));
00793 dbform = (Form_pg_database) GETSTRUCT(tuple);
00794 MyDatabaseId = HeapTupleGetOid(tuple);
00795 MyDatabaseTableSpace = dbform->dattablespace;
00796 Assert(MyDatabaseId == dboid);
00797 strlcpy(dbname, NameStr(dbform->datname), sizeof(dbname));
00798
00799 if (out_dbname)
00800 strcpy(out_dbname, dbname);
00801 }
00802
00803
00804
00805 MyProc->databaseId = MyDatabaseId;
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 if (!bootstrap)
00825 LockSharedObject(DatabaseRelationId, MyDatabaseId, 0,
00826 RowExclusiveLock);
00827
00828
00829
00830
00831
00832
00833 if (!bootstrap)
00834 {
00835 HeapTuple tuple;
00836
00837 tuple = GetDatabaseTuple(dbname);
00838 if (!HeapTupleIsValid(tuple) ||
00839 MyDatabaseId != HeapTupleGetOid(tuple) ||
00840 MyDatabaseTableSpace != ((Form_pg_database) GETSTRUCT(tuple))->dattablespace)
00841 ereport(FATAL,
00842 (errcode(ERRCODE_UNDEFINED_DATABASE),
00843 errmsg("database \"%s\" does not exist", dbname),
00844 errdetail("It seems to have just been dropped or renamed.")));
00845 }
00846
00847
00848
00849
00850
00851 fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace);
00852
00853 if (!bootstrap)
00854 {
00855 if (access(fullpath, F_OK) == -1)
00856 {
00857 if (errno == ENOENT)
00858 ereport(FATAL,
00859 (errcode(ERRCODE_UNDEFINED_DATABASE),
00860 errmsg("database \"%s\" does not exist",
00861 dbname),
00862 errdetail("The database subdirectory \"%s\" is missing.",
00863 fullpath)));
00864 else
00865 ereport(FATAL,
00866 (errcode_for_file_access(),
00867 errmsg("could not access directory \"%s\": %m",
00868 fullpath)));
00869 }
00870
00871 ValidatePgVersion(fullpath);
00872 }
00873
00874 SetDatabasePath(fullpath);
00875
00876
00877
00878
00879
00880
00881
00882 RelationCacheInitializePhase3();
00883
00884
00885 initialize_acl();
00886
00887
00888
00889
00890
00891
00892
00893 if (!bootstrap)
00894 CheckMyDatabase(dbname, am_superuser);
00895
00896
00897
00898
00899
00900
00901 if (MyProcPort != NULL)
00902 process_startup_options(MyProcPort, am_superuser);
00903
00904
00905 process_settings(MyDatabaseId, GetSessionUserId());
00906
00907
00908 if (PostAuthDelay > 0)
00909 pg_usleep(PostAuthDelay * 1000000L);
00910
00911
00912
00913
00914
00915
00916
00917 InitializeSearchPath();
00918
00919
00920 InitializeClientEncoding();
00921
00922
00923 if (!bootstrap)
00924 pgstat_bestart();
00925
00926
00927 if (!bootstrap)
00928 CommitTransactionCommand();
00929 }
00930
00931
00932
00933
00934
00935 static void
00936 process_startup_options(Port *port, bool am_superuser)
00937 {
00938 GucContext gucctx;
00939 ListCell *gucopts;
00940
00941 gucctx = am_superuser ? PGC_SUSET : PGC_BACKEND;
00942
00943
00944
00945
00946
00947 if (port->cmdline_options != NULL)
00948 {
00949
00950
00951
00952
00953
00954 char **av;
00955 int maxac;
00956 int ac;
00957
00958 maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;
00959
00960 av = (char **) palloc(maxac * sizeof(char *));
00961 ac = 0;
00962
00963 av[ac++] = "postgres";
00964
00965
00966 pg_split_opts(av, &ac, port->cmdline_options);
00967
00968 av[ac] = NULL;
00969
00970 Assert(ac < maxac);
00971
00972 (void) process_postgres_switches(ac, av, gucctx, NULL);
00973 }
00974
00975
00976
00977
00978
00979 gucopts = list_head(port->guc_options);
00980 while (gucopts)
00981 {
00982 char *name;
00983 char *value;
00984
00985 name = lfirst(gucopts);
00986 gucopts = lnext(gucopts);
00987
00988 value = lfirst(gucopts);
00989 gucopts = lnext(gucopts);
00990
00991 SetConfigOption(name, value, gucctx, PGC_S_CLIENT);
00992 }
00993 }
00994
00995
00996
00997
00998
00999
01000
01001 static void
01002 process_settings(Oid databaseid, Oid roleid)
01003 {
01004 Relation relsetting;
01005
01006 if (!IsUnderPostmaster)
01007 return;
01008
01009 relsetting = heap_open(DbRoleSettingRelationId, AccessShareLock);
01010
01011
01012 ApplySetting(databaseid, roleid, relsetting, PGC_S_DATABASE_USER);
01013 ApplySetting(InvalidOid, roleid, relsetting, PGC_S_USER);
01014 ApplySetting(databaseid, InvalidOid, relsetting, PGC_S_DATABASE);
01015 ApplySetting(InvalidOid, InvalidOid, relsetting, PGC_S_GLOBAL);
01016
01017 heap_close(relsetting, AccessShareLock);
01018 }
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030 static void
01031 ShutdownPostgres(int code, Datum arg)
01032 {
01033
01034 AbortOutOfAnyTransaction();
01035
01036
01037
01038
01039
01040 LockReleaseAll(USER_LOCKMETHOD, true);
01041 }
01042
01043
01044
01045
01046
01047 static void
01048 StatementTimeoutHandler(void)
01049 {
01050 #ifdef HAVE_SETSID
01051
01052 kill(-MyProcPid, SIGINT);
01053 #endif
01054 kill(MyProcPid, SIGINT);
01055 }
01056
01057
01058
01059
01060
01061
01062
01063 static void
01064 LockTimeoutHandler(void)
01065 {
01066 #ifdef HAVE_SETSID
01067
01068 kill(-MyProcPid, SIGINT);
01069 #endif
01070 kill(MyProcPid, SIGINT);
01071 }
01072
01073
01074
01075
01076
01077 static bool
01078 ThereIsAtLeastOneRole(void)
01079 {
01080 Relation pg_authid_rel;
01081 HeapScanDesc scan;
01082 bool result;
01083
01084 pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock);
01085
01086 scan = heap_beginscan(pg_authid_rel, SnapshotNow, 0, NULL);
01087 result = (heap_getnext(scan, ForwardScanDirection) != NULL);
01088
01089 heap_endscan(scan);
01090 heap_close(pg_authid_rel, AccessShareLock);
01091
01092 return result;
01093 }