├── .github └── workflows │ └── regression.yml ├── .gitignore ├── COPYRIGHT ├── META.json ├── Makefile ├── README.rst ├── bin ├── .gitignore ├── Makefile ├── pg_repack.c └── pgut │ ├── pgut-fe.c │ ├── pgut-fe.h │ ├── pgut.c │ └── pgut.h ├── doc ├── .gitignore ├── Makefile ├── pg_repack.rst ├── pg_repack_jp.rst ├── release.rst └── style.css ├── lib ├── .gitignore ├── Makefile ├── exports.txt ├── pg_repack.control.in ├── pg_repack.sql.in ├── pgut │ ├── pgut-be.h │ ├── pgut-spi.c │ └── pgut-spi.h └── repack.c ├── msvc ├── bin.2010.vcxproj ├── bin.2010.vcxproj.filters ├── bin.vcproj ├── lib.2010.vcxproj ├── lib.2010.vcxproj.filters ├── lib.vcproj ├── pg_repack.2010.sln ├── pg_repack.sln └── readme.txt └── regress ├── Makefile ├── create_tablespaces.sh ├── expected ├── after-schema.out ├── after-schema_1.out ├── after-schema_2.out ├── error-on-invalid-idx.out ├── error-on-invalid-idx_1.out ├── get_order_by.out ├── init-extension.out ├── no-error-on-invalid-idx.out ├── no-error-on-invalid-idx_1.out ├── nosuper.out ├── nosuper_1.out ├── repack-check.out ├── repack-check_1.out ├── repack-check_2.out ├── repack-check_3.out ├── repack-run.out ├── repack-run_1.out ├── repack-setup.out ├── repack-setup_1.out ├── tablespace.out ├── tablespace_1.out ├── tablespace_2.out ├── tablespace_3.out ├── tablespace_4.out └── trigger.out └── sql ├── after-schema.sql ├── error-on-invalid-idx.sql ├── get_order_by.sql ├── init-extension.sql ├── no-error-on-invalid-idx.sql ├── nosuper.sql ├── repack-check.sql ├── repack-run.sql ├── repack-setup.sql ├── tablespace.sql └── trigger.sql /.github/workflows/regression.yml: -------------------------------------------------------------------------------- 1 | name: make installcheck 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | test: 6 | strategy: 7 | fail-fast: false 8 | matrix: 9 | pg: 10 | - 18 11 | - 17 12 | - 16 13 | - 15 14 | - 14 15 | - 13 16 | - 12 17 | - 11 18 | - 10 19 | - 9.6 20 | - 9.5 21 | 22 | name: PostgreSQL ${{ matrix.pg }} 23 | runs-on: ubuntu-latest 24 | container: pgxn/pgxn-tools 25 | steps: 26 | 27 | - name: Start PostgreSQL ${{ matrix.pg }} 28 | run: pg-start ${{ matrix.pg }} 29 | 30 | - name: Install build-dependencies 31 | run: apt-get install -y liblz4-dev libreadline-dev zlib1g-dev libzstd-dev 32 | 33 | - name: Install additional build-dependencies for 18+ 34 | if: ${{ matrix.pg >= 18 }} 35 | run: apt-get install -y libcurl4-openssl-dev 36 | 37 | - name: Check out the repo 38 | uses: actions/checkout@v3 39 | 40 | - name: Put pg_repack on PATH 41 | run: echo "$PWD/bin" >> $GITHUB_PATH 42 | 43 | - name: Create tablespaces 44 | run: bash regress/create_tablespaces.sh 45 | 46 | - name: Test on PostgreSQL ${{ matrix.pg }} 47 | run: pg-build-test 48 | 49 | - name: Show regression.diffs 50 | if: ${{ failure() }} 51 | run: cat regress/regression.diffs 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Global excludes across all subdirectories 2 | *.o 3 | *.so 4 | *.bc 5 | *.dylib 6 | regress/regression.diffs 7 | regress/regression.out 8 | regress/results/ 9 | dist/*.zip 10 | lib/exports.list 11 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION 2 | Portions Copyright (c) 2011, Itagaki Takahiro 3 | Portions Copyright (c) 2012-2020, The Reorg Development Team 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, 10 | this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | * Neither the name of the authors nor the names of its contributors may 15 | be used to endorse or promote products derived from this software 16 | without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /META.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pg_repack", 3 | "abstract": "PostgreSQL module for data reorganization", 4 | "description": "Reorganize tables in PostgreSQL databases with minimal locks", 5 | "version": "1.5.2", 6 | "maintainer": [ 7 | "Beena Emerson ", 8 | "Josh Kupershmidt ", 9 | "Masahiko Sawada ", 10 | "Daniele Varrazzo ", 11 | "Artur Zakirov ", 12 | "Andreas Scherbaum " 13 | ], 14 | "tags": [ "bloat", "maintenance", "vacuum", "cluster" ], 15 | "release_status": "stable", 16 | "license": "bsd", 17 | "provides": { 18 | "pg_repack": { 19 | "file": "lib/pg_repack.sql", 20 | "version": "1.5.2", 21 | "abstract": "Reorganize tables in PostgreSQL databases with minimal locks" 22 | } 23 | }, 24 | "prereqs": { 25 | "runtime": { 26 | "requires": { 27 | "PostgreSQL": "9.5.0" 28 | } 29 | } 30 | }, 31 | "resources": { 32 | "homepage": "https://reorg.github.io/pg_repack", 33 | "bugtracker": { 34 | "web": "https://github.com/reorg/pg_repack/issues" 35 | }, 36 | "repository": { 37 | "url": "git://github.com/reorg/pg_repack.git", 38 | "web": "https://github.com/reorg/pg_repack/", 39 | "type": "git" 40 | } 41 | }, 42 | "meta-spec": { 43 | "version": "1.0.0", 44 | "url": "https://pgxn.org/meta/spec.txt" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # pg_repack: Makefile 3 | # 4 | # Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION 5 | # Portions Copyright (c) 2011, Itagaki Takahiro 6 | # Portions Copyright (c) 2012-2020, The Reorg Development Team 7 | # 8 | 9 | PG_CONFIG ?= pg_config 10 | EXTENSION = pg_repack 11 | 12 | .PHONY: dist/$(EXTENSION)-$(EXTVERSION).zip 13 | 14 | # Pull out PostgreSQL version number from pg_config 15 | VERSION := $(shell $(PG_CONFIG) --version | sed 's/.* \([[:digit:].]\{1,\}\).*/\1/') 16 | ifeq ("$(VERSION)","") 17 | $(error pg_config not found) 18 | endif 19 | 20 | # PostgreSQL version as a number, e.g. 9.1.4 -> 901 21 | INTVERSION := $(shell echo $$(($$(echo $(VERSION).0 | sed 's/\([[:digit:]]\{1,\}\)\.\([[:digit:]]\{1,\}\).*/\1*100+\2/')))) 22 | 23 | # The version number of the library 24 | EXTVERSION = $(shell grep '"version":' META.json | head -1 \ 25 | | sed -e 's/[ ]*"version":[ ]*"\(.*\)",/\1/') 26 | 27 | # NOTE: keep consistent with META.json 28 | ifeq ($(shell echo $$(($(INTVERSION) < 904))),1) 29 | $(error $(EXTENSION) requires PostgreSQL 9.4 or later. This is $(VERSION)) 30 | endif 31 | 32 | SUBDIRS = bin lib regress 33 | 34 | all install installdirs uninstall distprep clean distclean maintainer-clean debug: 35 | @for dir in $(SUBDIRS); do \ 36 | $(MAKE) -C $$dir $@ || exit; \ 37 | done 38 | 39 | # We'd like check operations to run all the subtests before failing. 40 | check installcheck: 41 | @CHECKERR=0; for dir in $(SUBDIRS); do \ 42 | $(MAKE) -C $$dir $@ || CHECKERR=$$?; \ 43 | done; \ 44 | exit $$CHECKERR 45 | 46 | # Prepare the package for PGXN submission 47 | package: dist dist/$(EXTENSION)-$(EXTVERSION).zip 48 | 49 | dist: 50 | mkdir -p dist 51 | 52 | dist/$(EXTENSION)-$(EXTVERSION).zip: 53 | git archive --format zip --prefix=$(EXTENSION)-$(EXTVERSION)/ --output $@ master 54 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | pg_repack -- Reorganize tables in PostgreSQL databases with minimal locks 2 | ========================================================================= 3 | 4 | - Homepage: https://reorg.github.io/pg_repack 5 | - Download: https://pgxn.org/dist/pg_repack/ 6 | - Development: https://github.com/reorg/pg_repack 7 | - Bug Report: https://github.com/reorg/pg_repack/issues 8 | 9 | |GitHub Actions| 10 | 11 | .. |GitHub Actions| image:: https://github.com/reorg/pg_repack/actions/workflows/regression.yml/badge.svg 12 | :target: https://github.com/reorg/pg_repack/actions/workflows/regression.yml 13 | :alt: Linux build status 14 | 15 | pg_repack_ is a PostgreSQL extension which lets you remove bloat from 16 | tables and indexes, and optionally restore the physical order of clustered 17 | indexes. Unlike CLUSTER_ and `VACUUM FULL`_ it works online, without 18 | holding an exclusive lock on the processed tables during processing. 19 | pg_repack is efficient to boot, with performance comparable to using 20 | CLUSTER directly. 21 | 22 | Please check the documentation (in the ``doc`` directory or online_) for 23 | installation and usage instructions. 24 | 25 | .. _pg_repack: https://reorg.github.io/pg_repack 26 | .. _CLUSTER: https://www.postgresql.org/docs/current/static/sql-cluster.html 27 | .. _VACUUM FULL: VACUUM_ 28 | .. _VACUUM: https://www.postgresql.org/docs/current/static/sql-vacuum.html 29 | .. _online: pg_repack_ 30 | .. _issue: https://github.com/reorg/pg_repack/issues/23 31 | 32 | 33 | What about pg_reorg? 34 | -------------------- 35 | 36 | pg_repack is a fork of the pg_reorg_ project, which has proven hugely 37 | successful. Unfortunately new feature development on pg_reorg_ has slowed 38 | or stopped since late 2011. 39 | 40 | pg_repack was initially released as a drop-in replacement for pg_reorg, 41 | addressing some of the shortcomings of the last pg_reorg version (such as 42 | support for PostgreSQL 9.2 and EXTENSION packaging) and known bugs. 43 | 44 | pg_repack 1.2 introduces further new features (parallel index builds, 45 | ability to rebuild only indexes) and bugfixes. In some cases its behaviour 46 | may be different from the 1.1.x release so it shouldn't be considered a 47 | drop-in replacement: you are advised to check the documentation__ before 48 | upgrading from previous versions. 49 | 50 | .. __: pg_repack_ 51 | .. _pg_reorg: https://github.com/reorg/pg_reorg 52 | -------------------------------------------------------------------------------- /bin/.gitignore: -------------------------------------------------------------------------------- 1 | /.deps/ 2 | /pg_repack 3 | /results/ 4 | /sql/init.sql 5 | /sql/init-*.*.sql 6 | -------------------------------------------------------------------------------- /bin/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # pg_repack: bin/Makefile 3 | # 4 | # Portions Copyright (c) 2008-2012, NIPPON TELEGRAPH AND TELEPHONE CORPORATION 5 | # Portions Copyright (c) 2011, Itagaki Takahiro 6 | # Portions Copyright (c) 2012-2020, The Reorg Development Team 7 | # 8 | 9 | PG_CONFIG ?= pg_config 10 | 11 | SRCS = pg_repack.c pgut/pgut.c pgut/pgut-fe.c 12 | OBJS = $(SRCS:.c=.o) 13 | PROGRAM = pg_repack 14 | 15 | 16 | # The version number of the program. It should be the same of the library. 17 | REPACK_VERSION = $(shell grep '"version":' ../META.json | head -1 \ 18 | | sed -e 's/[ ]*"version":[ ]*"\(.*\)",/\1/') 19 | 20 | PG_CPPFLAGS = -I$(libpq_srcdir) -DREPACK_VERSION=$(REPACK_VERSION) 21 | 22 | ifdef DEBUG_REPACK 23 | PG_CPPFLAGS += -DDEBUG_REPACK 24 | endif 25 | 26 | PG_LIBS = $(libpq) 27 | 28 | # libs pgport, pgcommon moved somewhere else in some ubuntu version 29 | # see ticket #179 30 | PG_LIBS += -L$(shell $(PG_CONFIG) --pkglibdir) 31 | 32 | USE_PGXS = 1 # use pgxs if not in contrib directory 33 | PGXS := $(shell $(PG_CONFIG) --pgxs) 34 | include $(PGXS) 35 | 36 | # remove dependency on libxml2, libxslt, and libpam. 37 | # XXX: find a better way to make sure we are linking with libraries 38 | # from pg_config which we actually need. 39 | LIBS := $(filter-out -ledit -lgssapi_krb5 -lpam -lselinux -lxml2 -lxslt, $(LIBS)) 40 | -------------------------------------------------------------------------------- /bin/pgut/pgut-fe.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * pgut-fe.h 3 | * 4 | * Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION 5 | * Portions Copyright (c) 2011, Itagaki Takahiro 6 | * Portions Copyright (c) 2012-2020, The Reorg Development Team 7 | *------------------------------------------------------------------------- 8 | */ 9 | 10 | #ifndef PGUT_FE_H 11 | #define PGUT_FE_H 12 | 13 | #include "pgut.h" 14 | 15 | typedef enum pgut_optsrc 16 | { 17 | SOURCE_DEFAULT, 18 | SOURCE_ENV, 19 | SOURCE_FILE, 20 | SOURCE_CMDLINE, 21 | SOURCE_CONST 22 | } pgut_optsrc; 23 | 24 | /* 25 | * type: 26 | * b: bool (true) 27 | * B: bool (false) 28 | * f: pgut_optfn 29 | * i: 32bit signed integer 30 | * l: StringList 31 | * u: 32bit unsigned integer 32 | * I: 64bit signed integer 33 | * U: 64bit unsigned integer 34 | * s: string 35 | * t: time_t 36 | * y: YesNo (YES) 37 | * Y: YesNo (NO) 38 | */ 39 | typedef struct pgut_option 40 | { 41 | char type; 42 | char sname; /* short name */ 43 | const char *lname; /* long name */ 44 | void *var; /* pointer to variable */ 45 | pgut_optsrc allowed; /* allowed source */ 46 | pgut_optsrc source; /* actual source */ 47 | } pgut_option; 48 | 49 | typedef void (*pgut_optfn) (pgut_option *opt, const char *arg); 50 | 51 | typedef struct worker_conns 52 | { 53 | int max_num_workers; 54 | int num_workers; 55 | PGconn **conns; 56 | } worker_conns; 57 | 58 | 59 | 60 | extern const char *dbname; 61 | extern char *host; 62 | extern char *port; 63 | extern char *username; 64 | extern char *password; 65 | extern YesNo prompt_password; 66 | 67 | extern PGconn *connection; 68 | extern PGconn *conn2; 69 | extern worker_conns workers; 70 | 71 | extern void pgut_help(bool details); 72 | extern void help(bool details); 73 | 74 | extern void disconnect(void); 75 | extern void reconnect(int elevel); 76 | extern void setup_workers(int num_workers); 77 | extern void disconnect_workers(void); 78 | extern PGresult *execute(const char *query, int nParams, const char **params); 79 | extern PGresult *execute_elevel(const char *query, int nParams, const char **params, int elevel); 80 | extern ExecStatusType command(const char *query, int nParams, const char **params); 81 | 82 | extern int pgut_getopt(int argc, char **argv, pgut_option options[]); 83 | extern void pgut_readopt(const char *path, pgut_option options[], int elevel); 84 | extern void pgut_setopt(pgut_option *opt, const char *optarg, pgut_optsrc src); 85 | extern bool pgut_keyeq(const char *lhs, const char *rhs); 86 | 87 | /* So we don't need to fret over multiple calls to PQclear(), e.g. 88 | * in cleanup labels. 89 | */ 90 | #define CLEARPGRES(pgres) do { PQclear(pgres); pgres = NULL; } while (0) 91 | 92 | #endif /* PGUT_FE_H */ 93 | -------------------------------------------------------------------------------- /bin/pgut/pgut.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * pgut.h 3 | * 4 | * Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION 5 | * Portions Copyright (c) 2011, Itagaki Takahiro 6 | * Portions Copyright (c) 2012-2020, The Reorg Development Team 7 | *------------------------------------------------------------------------- 8 | */ 9 | 10 | #ifndef PGUT_H 11 | #define PGUT_H 12 | 13 | #include "c.h" 14 | #include 15 | 16 | #ifndef WIN32 17 | #include 18 | #include 19 | #endif 20 | 21 | #include "libpq-fe.h" 22 | #include "pqexpbuffer.h" 23 | #include "utils/elog.h" 24 | 25 | #define INFINITE_STR "INFINITE" 26 | 27 | #ifdef _MSC_VER 28 | #define __attribute__(x) 29 | #endif 30 | 31 | typedef enum YesNo 32 | { 33 | DEFAULT, 34 | NO, 35 | YES 36 | } YesNo; 37 | 38 | typedef void (*pgut_atexit_callback)(bool fatal, void *userdata); 39 | 40 | /* 41 | * pgut client variables and functions 42 | */ 43 | extern const char *PROGRAM_NAME; 44 | extern const char *PROGRAM_VERSION; 45 | extern const char *PROGRAM_URL; 46 | extern const char *PROGRAM_ISSUES; 47 | 48 | /* 49 | * pgut framework variables and functions 50 | */ 51 | extern bool interrupted; 52 | extern int pgut_log_level; 53 | extern int pgut_abort_level; 54 | extern bool pgut_echo; 55 | 56 | extern void pgut_init(int argc, char **argv); 57 | extern void pgut_atexit_push(pgut_atexit_callback callback, void *userdata); 58 | extern void pgut_atexit_pop(pgut_atexit_callback callback, void *userdata); 59 | extern void pgut_putenv(const char *key, const char *value); 60 | 61 | /* 62 | * Database connections 63 | */ 64 | extern PGconn *pgut_connect(const char *dbname, const char *host, const char *port, 65 | const char *username, const char *password, 66 | YesNo prompt, int elevel); 67 | extern void pgut_disconnect(PGconn *conn); 68 | extern void pgut_disconnect_all(void); 69 | extern PGresult *pgut_execute(PGconn* conn, const char *query, int nParams, const char **params); 70 | PGresult *pgut_execute_elevel(PGconn* conn, const char *query, int nParams, const char **params, int elevel); 71 | extern ExecStatusType pgut_command(PGconn* conn, const char *query, int nParams, const char **params); 72 | extern bool pgut_commit(PGconn *conn); 73 | extern void pgut_rollback(PGconn *conn); 74 | extern bool pgut_send(PGconn* conn, const char *query, int nParams, const char **params); 75 | extern int pgut_wait(int num, PGconn *connections[], struct timeval *timeout); 76 | 77 | /* 78 | * memory allocators 79 | */ 80 | extern void *pgut_malloc(size_t size); 81 | extern void *pgut_realloc(void *p, size_t size); 82 | extern char *pgut_strdup(const char *str); 83 | extern char *strdup_with_len(const char *str, size_t len); 84 | extern char *strdup_trim(const char *str); 85 | 86 | #define pgut_new(type) ((type *) pgut_malloc(sizeof(type))) 87 | #define pgut_newarray(type, n) ((type *) pgut_malloc(sizeof(type) * (n))) 88 | #define pgut_newvar(type, m, n) ((type *) pgut_malloc(offsetof(type, m) + (n))) 89 | 90 | /* 91 | * file operations 92 | */ 93 | extern FILE *pgut_fopen(const char *path, const char *mode); 94 | extern bool pgut_mkdir(const char *path); 95 | 96 | /* 97 | * elog 98 | */ 99 | #define E_PG_CONNECT (-1) /* PostgreSQL connection error */ 100 | #define E_PG_COMMAND (-2) /* PostgreSQL query or command error */ 101 | 102 | #undef elog 103 | #undef ereport 104 | #define ereport(elevel, rest) \ 105 | (pgut_errstart(elevel) ? (pgut_errfinish rest) : (void) 0) 106 | 107 | extern void elog(int elevel, const char *fmt, ...) 108 | __attribute__((format(printf, 2, 3))); 109 | extern const char *format_elevel(int elevel); 110 | extern int parse_elevel(const char *value); 111 | extern int errcode_errno(void); 112 | extern bool log_required(int elevel, int log_min_level); 113 | extern bool pgut_errstart(int elevel); 114 | extern void pgut_errfinish(int dummy, ...); 115 | extern void pgut_error(int elevel, int code, const char *msg, const char *detail); 116 | 117 | /* 118 | * CHECK_FOR_INTERRUPTS 119 | */ 120 | #undef CHECK_FOR_INTERRUPTS 121 | extern void CHECK_FOR_INTERRUPTS(void); 122 | 123 | /* 124 | * Assert 125 | */ 126 | #undef Assert 127 | #undef AssertArg 128 | #undef AssertMacro 129 | 130 | #ifdef USE_ASSERT_CHECKING 131 | #define Assert(x) assert(x) 132 | #define AssertArg(x) assert(x) 133 | #define AssertMacro(x) assert(x) 134 | #else 135 | #define Assert(x) ((void) 0) 136 | #define AssertArg(x) ((void) 0) 137 | #define AssertMacro(x) ((void) 0) 138 | #endif 139 | 140 | /* 141 | * StringInfo and string operations 142 | */ 143 | #define STRINGINFO_H 144 | 145 | #define StringInfoData PQExpBufferData 146 | #define StringInfo PQExpBuffer 147 | #define makeStringInfo createPQExpBuffer 148 | #define initStringInfo initPQExpBuffer 149 | #define freeStringInfo destroyPQExpBuffer 150 | #define termStringInfo termPQExpBuffer 151 | #define resetStringInfo resetPQExpBuffer 152 | #define enlargeStringInfo enlargePQExpBuffer 153 | #define printfStringInfo printfPQExpBuffer /* reset + append */ 154 | #define appendStringInfo appendPQExpBuffer 155 | #define appendStringInfoString appendPQExpBufferStr 156 | #define appendStringInfoChar appendPQExpBufferChar 157 | #define appendBinaryStringInfo appendBinaryPQExpBuffer 158 | 159 | extern bool pgut_appendStringInfoVA(StringInfo str, const char *fmt, va_list args) 160 | __attribute__((format(printf, 2, 0))); 161 | extern int appendStringInfoFile(StringInfo str, FILE *fp); 162 | extern int appendStringInfoFd(StringInfo str, int fd); 163 | 164 | extern bool parse_bool(const char *value, bool *result); 165 | extern bool parse_bool_with_len(const char *value, size_t len, bool *result); 166 | extern bool parse_int32(const char *value, int32 *result); 167 | extern bool parse_uint32(const char *value, uint32 *result); 168 | extern bool parse_int64(const char *value, int64 *result); 169 | extern bool parse_uint64(const char *value, uint64 *result); 170 | extern bool parse_time(const char *value, time_t *time); 171 | 172 | #define IsSpace(c) (isspace((unsigned char)(c))) 173 | #define IsAlpha(c) (isalpha((unsigned char)(c))) 174 | #define IsAlnum(c) (isalnum((unsigned char)(c))) 175 | #define IsIdentHead(c) (IsAlpha(c) || (c) == '_') 176 | #define IsIdentBody(c) (IsAlnum(c) || (c) == '_') 177 | #define ToLower(c) (tolower((unsigned char)(c))) 178 | #define ToUpper(c) (toupper((unsigned char)(c))) 179 | 180 | /* linked list of string values and helper functions, stolen from pg_dump. */ 181 | typedef struct SimpleStringListCell 182 | { 183 | struct SimpleStringListCell *next; 184 | char val[1]; /* VARIABLE LENGTH FIELD */ 185 | } SimpleStringListCell; 186 | 187 | typedef struct SimpleStringList 188 | { 189 | SimpleStringListCell *head; 190 | SimpleStringListCell *tail; 191 | } SimpleStringList; 192 | 193 | extern void simple_string_list_append(SimpleStringList *list, const char *val); 194 | extern bool simple_string_list_member(SimpleStringList *list, const char *val); 195 | extern size_t simple_string_list_size(SimpleStringList list); 196 | 197 | 198 | /* 199 | * socket operations 200 | */ 201 | extern int wait_for_socket(int sock, struct timeval *timeout); 202 | extern int wait_for_sockets(int nfds, fd_set *fds, struct timeval *timeout); 203 | 204 | #ifdef WIN32 205 | extern int sleep(unsigned int seconds); 206 | extern int usleep(unsigned int usec); 207 | #endif 208 | 209 | #endif /* PGUT_H */ 210 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | /*.html 2 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | RST2HTML = $(shell which rst2html || which rst2html.py) 2 | RSTOPTS = --stylesheet-path=style.css,html4css1.css --initial-header-level=2 3 | 4 | HTML = $(patsubst %.rst,%.html,$(wildcard *.rst)) 5 | 6 | .PHONY: clean 7 | 8 | all : html 9 | 10 | html : $(HTML) 11 | 12 | %.html: %.rst style.css 13 | $(RST2HTML) $(RSTOPTS) $< $@ 14 | 15 | clean: 16 | rm -f $(HTML) 17 | -------------------------------------------------------------------------------- /doc/release.rst: -------------------------------------------------------------------------------- 1 | What to do to release pg_repack 2 | =============================== 3 | 4 | This document is the list of operations to do to release a new pg_repack 5 | version. The version number in this document is indicated by ``$VER``: it 6 | should be a three-digit dot-separated version, eventually followed by a 7 | pre-release string: ``1.2.0``, ``1.2.1``, ``1.2-dev0``, ``1.2.0-beta1`` are 8 | valid version numbers. 9 | 10 | In order to release the package you will need accounts on Github and PGXN 11 | with the right privileges: contact Daniele Varrazzo to obtain them. 12 | 13 | - Set the right version number in ``META.json`` (note: it's in two different 14 | places). 15 | - Set the right release_status in ``META.json``: ``testing`` or ``stable``. 16 | - Commit the above metadata changes. 17 | 18 | - Create a package running ``make package``. The package will be called 19 | ``dist/pg_repack-$VER.zip``. 20 | 21 | - Verify the packages installs and passes tests with `pgxn client`__:: 22 | 23 | pgxn install --sudo -- dist/pg_repack-$VER.zip 24 | pgxn check dist/pg_repack-$VER.zip 25 | 26 | (note that ``check`` may require the Postgres bin directory to be added to 27 | the path, e.g. ``PATH=$(pg_config --bindir):$PATH``; check the ``install`` 28 | log to see where ``pg_repack`` executable was installed). 29 | 30 | .. __: https://pgxn.github.io/pgxnclient/ 31 | 32 | - Push the code changes on github:: 33 | 34 | git push 35 | 36 | - Upload the package on http://manager.pgxn.org/. 37 | 38 | - Check the uploaded package works as expected; if not fix and push more:: 39 | 40 | pgxn install --sudo -- pg_repack 41 | pgxn check pg_repack 42 | 43 | - Create a tag, signed if possible:: 44 | 45 | git tag -a -s ver_$VER 46 | 47 | - Push the new tag on github:: 48 | 49 | git push --tags 50 | 51 | - Upload the docs by pushing in the repos at 52 | http://reorg.github.io/pg_repack/. The operations are roughly:: 53 | 54 | git clone --recursive git@github.com:reorg/reorg.github.com.git 55 | cd reorg.github.com 56 | make sm 57 | make 58 | git commit -a -m "Docs upload for release $VER" 59 | git push 60 | 61 | - Check the page http://reorg.github.io/pg_repack/ is right. 62 | 63 | - Announce the package on pgsql-announce@postgresql.org. 64 | -------------------------------------------------------------------------------- /doc/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 3 | Lucida Grande, Verdana, Arial, Helvetica, 4 | 'メイリオ', 5 | 'Meiryo', 6 | 'ヒラギノ角ゴ Pro W3', 7 | 'Hiragino Kaku Gothic Pro', 8 | 'Osaka', 9 | 'MS Pゴシック', 10 | sans-serif; 11 | color: #202020; 12 | } 13 | 14 | h2, h3, h4, h5, h6 { 15 | color: Black; 16 | background: none; 17 | padding-top: 0.5em; 18 | padding-bottom: 0.17em; 19 | border-bottom: 1px solid #aaaaaa; 20 | } 21 | H1 { font-size: x-large; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; } 22 | H2 { font-size: large; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; } 23 | H3 { padding-left: 1em; font-size: medium; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; } 24 | H4 { padding-left: 2em; font-size: small; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; } 25 | H5 { padding-left: 3em; font-size: x-small; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; } 26 | H6 { padding-left: 4em; font-size: xx-small; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; } 27 | 28 | pre { 29 | font-family: courier,sans-serif; 30 | background-color: #FBFBFD; 31 | border: 1px dashed #7E7ECB; 32 | color: black; 33 | line-height: 1.1em; padding: 0.5em; 34 | overflow: auto; 35 | } 36 | 37 | li { 38 | line-height: 1.4em; 39 | } 40 | 41 | div.contents { 42 | float:right; 43 | border:thin solid black; 44 | background-color: white; 45 | padding-top: 0.2em; 46 | padding-bottom: 0.2em; 47 | padding-left: 1em; 48 | padding-right: 1em; 49 | margin-left: 0.5em; 50 | margin-top: 2.5em !important; 51 | } 52 | 53 | div.contents ul { 54 | padding-left: 1em; 55 | } 56 | 57 | dl.diag dt, 58 | dl.ddl dt { 59 | font-weight: bold; 60 | margin-top: 1em; 61 | margin-bottom: 0.5em; 62 | } 63 | -------------------------------------------------------------------------------- /lib/.gitignore: -------------------------------------------------------------------------------- 1 | /.deps/ 2 | /pg_repack.sql 3 | /pg_repack--[0-9.]*.sql 4 | /pg_repack.control 5 | -------------------------------------------------------------------------------- /lib/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # pg_repack: lib/Makefile 3 | # 4 | # Portions Copyright (c) 2008-2012, NIPPON TELEGRAPH AND TELEPHONE CORPORATION 5 | # Portions Copyright (c) 2011, Itagaki Takahiro 6 | # Portions Copyright (c) 2012-2020, The Reorg Development Team 7 | # 8 | 9 | PG_CONFIG ?= pg_config 10 | 11 | # version as a number, e.g. 9.1.4 -> 901 12 | VERSION := $(shell $(PG_CONFIG) --version | sed 's/.* \([[:digit:].]\{1,\}\).*/\1/') 13 | INTVERSION := $(shell echo $$(($$(echo $(VERSION).0 | sed 's/\([[:digit:]]\{1,\}\)\.\([[:digit:]]\{1,\}\).*/\1*100+\2/')))) 14 | 15 | EXTENSION = pg_repack 16 | MODULE_big = $(EXTENSION) 17 | 18 | OBJS = repack.o pgut/pgut-spi.o 19 | 20 | SHLIB_EXPORTS = exports.txt 21 | 22 | 23 | # It is not possible to create tables with OIDs on PostgreSQL 12 or later 24 | ifeq ($(shell echo $$(($(INTVERSION) < 1200))),1) 25 | RELHASOIDS := relhasoids 26 | else 27 | RELHASOIDS := false 28 | endif 29 | 30 | # The version number of the program. It should be the same of the library. 31 | REPACK_VERSION = $(shell grep '"version":' ../META.json | head -1 \ 32 | | sed -e 's/[ ]*"version":[ ]*"\(.*\)",/\1/') 33 | 34 | PG_CPPFLAGS = -DREPACK_VERSION=$(REPACK_VERSION) 35 | 36 | DATA_built = pg_repack--$(REPACK_VERSION).sql pg_repack.control 37 | 38 | USE_PGXS = 1 39 | PGXS := $(shell $(PG_CONFIG) --pgxs) 40 | include $(PGXS) 41 | 42 | # remove dependency on libxml2, libxslt, and libpam. 43 | # XXX: find a better way to make sure we are linking with libraries 44 | # from pg_config which we actually need. 45 | LIBS := $(filter-out -lpam -lxml2 -lxslt, $(LIBS)) 46 | 47 | pg_repack.sql: pg_repack.sql.in 48 | echo "BEGIN;" > $@; \ 49 | sed 's,MODULE_PATHNAME,$$libdir/$(MODULE_big),g' $< \ 50 | | sed 's,REPACK_VERSION,$(REPACK_VERSION),g' >> $@; \ 51 | echo "COMMIT;" >> $@; 52 | 53 | pg_repack--$(REPACK_VERSION).sql: pg_repack.sql.in 54 | sed 's,REPACK_VERSION,$(REPACK_VERSION),g' $< \ 55 | | sed 's,relhasoids,$(RELHASOIDS),g'> $@; 56 | 57 | pg_repack.control: pg_repack.control.in 58 | sed 's,REPACK_VERSION,$(REPACK_VERSION),g' $< > $@ 59 | -------------------------------------------------------------------------------- /lib/exports.txt: -------------------------------------------------------------------------------- 1 | Pg_magic_func 1 2 | pg_finfo_repack_apply 2 3 | pg_finfo_repack_disable_autovacuum 3 4 | pg_finfo_repack_drop 4 5 | pg_finfo_repack_get_order_by 5 6 | pg_finfo_repack_indexdef 6 7 | pg_finfo_repack_swap 7 8 | pg_finfo_repack_trigger 8 9 | pg_finfo_repack_version 9 10 | pg_finfo_repack_index_swap 10 11 | pg_finfo_repack_get_table_and_inheritors 11 12 | repack_apply 12 13 | repack_disable_autovacuum 13 14 | repack_drop 14 15 | repack_get_order_by 15 16 | repack_indexdef 16 17 | repack_swap 17 18 | repack_trigger 18 19 | repack_version 19 20 | repack_index_swap 20 21 | repack_get_table_and_inheritors 21 22 | -------------------------------------------------------------------------------- /lib/pg_repack.control.in: -------------------------------------------------------------------------------- 1 | # pg_repack extension 2 | comment = 'Reorganize tables in PostgreSQL databases with minimal locks' 3 | default_version = 'REPACK_VERSION' 4 | module_pathname = '$libdir/pg_repack' 5 | relocatable = false 6 | -------------------------------------------------------------------------------- /lib/pg_repack.sql.in: -------------------------------------------------------------------------------- 1 | /* 2 | * pg_repack: lib/pg_repack.sql.in 3 | * 4 | * Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION 5 | * Portions Copyright (c) 2011, Itagaki Takahiro 6 | * Portions Copyright (c) 2012-2020, The Reorg Development Team 7 | */ 8 | 9 | CREATE SCHEMA repack; 10 | 11 | CREATE FUNCTION repack.version() RETURNS text AS 12 | 'MODULE_PATHNAME', 'repack_version' 13 | LANGUAGE C IMMUTABLE STRICT; 14 | 15 | CREATE FUNCTION repack.version_sql() RETURNS text AS 16 | $$SELECT 'pg_repack REPACK_VERSION'::text$$ 17 | LANGUAGE SQL IMMUTABLE STRICT; 18 | 19 | -- Always specify search_path to 'pg_catalog' so that we 20 | -- always can get schema-qualified relation name 21 | CREATE FUNCTION repack.oid2text(oid) RETURNS text AS 22 | $$ 23 | SELECT textin(regclassout($1)); 24 | $$ 25 | LANGUAGE sql STABLE STRICT SET search_path to 'pg_catalog'; 26 | 27 | -- Get a comma-separated column list of the index. 28 | -- 29 | -- Columns are quoted as literals because they are going to be passed to 30 | -- the `repack_trigger` function as text arguments. `repack_trigger` will quote 31 | -- them as identifiers later. 32 | CREATE FUNCTION repack.get_index_columns(oid) RETURNS text AS 33 | $$ 34 | SELECT coalesce(string_agg(quote_literal(attname), ', '), '') 35 | FROM pg_attribute, 36 | (SELECT indrelid, 37 | indkey, 38 | generate_series(0, indnatts-1) AS i 39 | FROM pg_index 40 | WHERE indexrelid = $1 41 | ) AS keys 42 | WHERE attrelid = indrelid 43 | AND attnum = indkey[i]; 44 | $$ 45 | LANGUAGE sql STABLE STRICT; 46 | 47 | CREATE FUNCTION repack.get_order_by(oid, oid) RETURNS text AS 48 | 'MODULE_PATHNAME', 'repack_get_order_by' 49 | LANGUAGE C STABLE STRICT; 50 | 51 | CREATE FUNCTION repack.create_log_table(oid) RETURNS void AS 52 | $$ 53 | BEGIN 54 | EXECUTE 'CREATE TABLE repack.log_' || $1 || 55 | ' (id bigserial PRIMARY KEY,' || 56 | ' pk repack.pk_' || $1 || ',' || 57 | ' row ' || repack.oid2text($1) || ')'; 58 | END 59 | $$ 60 | LANGUAGE plpgsql; 61 | 62 | CREATE FUNCTION repack.create_table(oid, name) RETURNS void AS 63 | $$ 64 | BEGIN 65 | EXECUTE 'CREATE TABLE repack.table_' || $1 || 66 | ' WITH (' || repack.get_storage_param($1) || ') ' || 67 | ' TABLESPACE ' || quote_ident($2) || 68 | ' AS SELECT ' || repack.get_columns_for_create_as($1) || 69 | ' FROM ONLY ' || repack.oid2text($1) || ' WITH NO DATA'; 70 | END 71 | $$ 72 | LANGUAGE plpgsql; 73 | 74 | CREATE FUNCTION repack.create_index_type(oid, oid) RETURNS void AS 75 | $$ 76 | BEGIN 77 | EXECUTE repack.get_create_index_type($1, 'repack.pk_' || $2); 78 | END 79 | $$ 80 | LANGUAGE plpgsql; 81 | 82 | CREATE FUNCTION repack.get_create_index_type(oid, name) RETURNS text AS 83 | $$ 84 | SELECT 'CREATE TYPE ' || $2 || ' AS (' || 85 | coalesce(string_agg(quote_ident(attname) || ' ' || 86 | pg_catalog.format_type(atttypid, atttypmod), ', '), '') || ')' 87 | FROM pg_attribute, 88 | (SELECT indrelid, 89 | indkey, 90 | generate_series(0, indnatts-1) AS i 91 | FROM pg_index 92 | WHERE indexrelid = $1 93 | ) AS keys 94 | WHERE attrelid = indrelid 95 | AND attnum = indkey[i]; 96 | $$ 97 | LANGUAGE sql STABLE STRICT; 98 | 99 | CREATE FUNCTION repack.get_create_trigger(relid oid, pkid oid) 100 | RETURNS text AS 101 | $$ 102 | SELECT 'CREATE TRIGGER repack_trigger' || 103 | ' AFTER INSERT OR DELETE OR UPDATE ON ' || repack.oid2text($1) || 104 | ' FOR EACH ROW EXECUTE PROCEDURE repack.repack_trigger(' || 105 | repack.get_index_columns($2) || ')'; 106 | $$ 107 | LANGUAGE sql STABLE STRICT; 108 | 109 | CREATE FUNCTION repack.get_enable_trigger(relid oid) 110 | RETURNS text AS 111 | $$ 112 | SELECT 'ALTER TABLE ' || repack.oid2text($1) || 113 | ' ENABLE ALWAYS TRIGGER repack_trigger'; 114 | $$ 115 | LANGUAGE sql STABLE STRICT; 116 | 117 | CREATE FUNCTION repack.get_assign(oid, text) RETURNS text AS 118 | $$ 119 | SELECT '(' || coalesce(string_agg(quote_ident(attname), ', '), '') || 120 | ') = (' || $2 || '.' || 121 | coalesce(string_agg(quote_ident(attname), ', ' || $2 || '.'), '') || ')' 122 | FROM (SELECT attname FROM pg_attribute 123 | WHERE attrelid = $1 AND attnum > 0 AND NOT attisdropped 124 | ORDER BY attnum) tmp; 125 | $$ 126 | LANGUAGE sql STABLE STRICT; 127 | 128 | CREATE FUNCTION repack.get_compare_pkey(oid, text) 129 | RETURNS text AS 130 | $$ 131 | SELECT '(' || coalesce(string_agg(quote_ident(attname), ', '), '') || 132 | ') = (' || $2 || '.' || 133 | coalesce(string_agg(quote_ident(attname), ', ' || $2 || '.'), '') || ')' 134 | FROM pg_attribute, 135 | (SELECT indrelid, 136 | indkey, 137 | generate_series(0, indnatts-1) AS i 138 | FROM pg_index 139 | WHERE indexrelid = $1 140 | ) AS keys 141 | WHERE attrelid = indrelid 142 | AND attnum = indkey[i]; 143 | $$ 144 | LANGUAGE sql STABLE STRICT; 145 | 146 | -- Get a column list for SELECT all columns including dropped ones. 147 | -- We use NULLs of integer types for dropped columns (types are not important). 148 | CREATE FUNCTION repack.get_columns_for_create_as(oid) 149 | RETURNS text AS 150 | $$ 151 | SELECT coalesce(string_agg(c, ','), '') FROM (SELECT 152 | CASE WHEN attisdropped 153 | THEN 'NULL::integer AS ' || quote_ident(attname) 154 | ELSE quote_ident(attname) 155 | END AS c 156 | FROM pg_attribute 157 | WHERE attrelid = $1 AND attnum > 0 ORDER BY attnum 158 | ) AS COL 159 | $$ 160 | LANGUAGE sql STABLE STRICT; 161 | 162 | -- Get a SQL text to DROP dropped columns for the table, 163 | -- or NULL if it has no dropped columns. 164 | CREATE FUNCTION repack.get_drop_columns(oid, text) 165 | RETURNS text AS 166 | $$ 167 | SELECT 168 | 'ALTER TABLE ' || $2 || ' ' || array_to_string(dropped_columns, ', ') 169 | FROM ( 170 | SELECT 171 | array_agg('DROP COLUMN ' || quote_ident(attname)) AS dropped_columns 172 | FROM ( 173 | SELECT * FROM pg_attribute 174 | WHERE attrelid = $1 AND attnum > 0 AND attisdropped 175 | ORDER BY attnum 176 | ) T 177 | ) T 178 | WHERE 179 | array_upper(dropped_columns, 1) > 0 180 | $$ 181 | LANGUAGE sql STABLE STRICT; 182 | 183 | -- Get a comma-separated storage parameter for the table including 184 | -- parameters for the corresponding TOAST table. 185 | -- Note that since oid setting is always not NULL, this function 186 | -- never returns NULL 187 | CREATE FUNCTION repack.get_storage_param(oid) 188 | RETURNS TEXT AS 189 | $$ 190 | SELECT string_agg(param, ', ') 191 | FROM ( 192 | -- table storage parameter 193 | SELECT unnest(reloptions) as param 194 | FROM pg_class 195 | WHERE oid = $1 196 | UNION ALL 197 | -- TOAST table storage parameter 198 | SELECT ('toast.' || unnest(reloptions)) as param 199 | FROM ( 200 | SELECT reltoastrelid from pg_class where oid = $1 201 | ) as t, 202 | pg_class as c 203 | WHERE c.oid = t.reltoastrelid 204 | UNION ALL 205 | -- table oid 206 | SELECT 'oids = ' || 207 | CASE WHEN relhasoids 208 | THEN 'true' 209 | ELSE 'false' 210 | END 211 | FROM pg_class 212 | WHERE oid = $1 213 | 214 | ) as t 215 | $$ 216 | LANGUAGE sql STABLE STRICT; 217 | 218 | -- GET a SQL text to set column storage option for the table. 219 | CREATE FUNCTION repack.get_alter_col_storage(oid) 220 | RETURNS text AS 221 | $$ 222 | SELECT 'ALTER TABLE repack.table_' || $1 || array_to_string(column_storage, ',') 223 | FROM ( 224 | SELECT 225 | array_agg(' ALTER ' || quote_ident(attname) || 226 | CASE attstorage 227 | WHEN 'p' THEN ' SET STORAGE PLAIN' 228 | WHEN 'm' THEN ' SET STORAGE MAIN' 229 | WHEN 'e' THEN ' SET STORAGE EXTERNAL' 230 | WHEN 'x' THEN ' SET STORAGE EXTENDED' 231 | END) AS column_storage 232 | FROM ( 233 | SELECT * 234 | FROM pg_attribute a 235 | JOIN pg_type t on t.oid = atttypid 236 | JOIN pg_class r on r.oid = a.attrelid 237 | JOIN pg_namespace s on s.oid = r.relnamespace 238 | WHERE typstorage <> attstorage 239 | AND attrelid = $1 240 | AND attnum > 0 241 | AND NOT attisdropped 242 | ORDER BY attnum 243 | ) T 244 | ) T 245 | WHERE array_upper(column_storage , 1) > 0 246 | $$ 247 | LANGUAGE sql STABLE STRICT; 248 | 249 | -- includes not only PRIMARY KEYS but also UNIQUE NOT NULL keys 250 | DO $$ 251 | BEGIN 252 | IF current_setting('server_version_num')::int >= 110000 THEN 253 | CREATE VIEW repack.primary_keys AS 254 | SELECT indrelid, min(indexrelid) AS indexrelid 255 | FROM (SELECT indrelid, indexrelid FROM pg_index 256 | WHERE indisunique 257 | AND indisvalid 258 | AND indpred IS NULL 259 | AND 0 <> ALL(indkey) 260 | AND NOT EXISTS( 261 | SELECT 1 FROM pg_attribute 262 | WHERE attrelid = indrelid 263 | -- indkey is 0-based int2vector 264 | AND attnum = ANY(indkey[0:indnkeyatts - 1]) 265 | AND NOT attnotnull) 266 | ORDER BY indrelid, indisprimary DESC, indnatts, indkey) tmp 267 | GROUP BY indrelid; 268 | ELSE 269 | CREATE VIEW repack.primary_keys AS 270 | SELECT indrelid, min(indexrelid) AS indexrelid 271 | FROM (SELECT indrelid, indexrelid FROM pg_index 272 | WHERE indisunique 273 | AND indisvalid 274 | AND indpred IS NULL 275 | AND 0 <> ALL(indkey) 276 | AND NOT EXISTS( 277 | SELECT 1 FROM pg_attribute 278 | WHERE attrelid = indrelid 279 | AND attnum = ANY(indkey) 280 | AND NOT attnotnull) 281 | ORDER BY indrelid, indisprimary DESC, indnatts, indkey) tmp 282 | GROUP BY indrelid; 283 | END IF; 284 | END; 285 | $$; 286 | 287 | CREATE VIEW repack.tables AS 288 | SELECT repack.oid2text(R.oid) AS relname, 289 | R.oid AS relid, 290 | R.reltoastrelid AS reltoastrelid, 291 | CASE WHEN R.reltoastrelid = 0 THEN 0 ELSE ( 292 | SELECT indexrelid FROM pg_index 293 | WHERE indrelid = R.reltoastrelid 294 | AND indisvalid) END AS reltoastidxid, 295 | N.nspname AS schemaname, 296 | PK.indexrelid AS pkid, 297 | CK.indexrelid AS ckid, 298 | 'SELECT repack.create_index_type(' || PK.indexrelid || ',' || R.oid || ')' AS create_pktype, 299 | 'SELECT repack.create_log_table(' || R.oid || ')' AS create_log, 300 | repack.get_create_trigger(R.oid, PK.indexrelid) AS create_trigger, 301 | repack.get_enable_trigger(R.oid) as enable_trigger, 302 | 'SELECT repack.create_table($1, $2)'::text AS create_table, 303 | coalesce(S.spcname, S2.spcname) AS tablespace_orig, 304 | 'INSERT INTO repack.table_' || R.oid || ' SELECT ' || repack.get_columns_for_create_as(R.oid) || ' FROM ONLY ' || repack.oid2text(R.oid) AS copy_data, 305 | repack.get_alter_col_storage(R.oid) AS alter_col_storage, 306 | repack.get_drop_columns(R.oid, 'repack.table_' || R.oid) AS drop_columns, 307 | 'DELETE FROM repack.log_' || R.oid AS delete_log, 308 | 'LOCK TABLE ' || repack.oid2text(R.oid) || ' IN ACCESS EXCLUSIVE MODE' AS lock_table, 309 | repack.get_order_by(CK.indexrelid, R.oid) AS ckey, 310 | 'SELECT * FROM repack.log_' || R.oid || ' ORDER BY id LIMIT $1' AS sql_peek, 311 | 'INSERT INTO repack.table_' || R.oid || ' VALUES ($1.*)' AS sql_insert, 312 | 'DELETE FROM repack.table_' || R.oid || ' WHERE ' || repack.get_compare_pkey(PK.indexrelid, '$1') AS sql_delete, 313 | 'UPDATE repack.table_' || R.oid || ' SET ' || repack.get_assign(R.oid, '$2') || ' WHERE ' || repack.get_compare_pkey(PK.indexrelid, '$1') AS sql_update, 314 | 'DELETE FROM repack.log_' || R.oid || ' WHERE id IN (' AS sql_pop 315 | FROM pg_class R 316 | LEFT JOIN pg_class T ON R.reltoastrelid = T.oid 317 | LEFT JOIN repack.primary_keys PK 318 | ON R.oid = PK.indrelid 319 | LEFT JOIN (SELECT CKI.* FROM pg_index CKI, pg_class CKT 320 | WHERE CKI.indisvalid 321 | AND CKI.indexrelid = CKT.oid 322 | AND CKI.indisclustered 323 | AND CKT.relam = 403) CK 324 | ON R.oid = CK.indrelid 325 | LEFT JOIN pg_namespace N ON N.oid = R.relnamespace 326 | LEFT JOIN pg_tablespace S ON S.oid = R.reltablespace 327 | CROSS JOIN (SELECT S2.spcname 328 | FROM pg_catalog.pg_database D 329 | JOIN pg_catalog.pg_tablespace S2 ON S2.oid = D.dattablespace 330 | WHERE D.datname = current_database()) S2 331 | WHERE R.relkind = 'r' 332 | AND R.relpersistence = 'p' 333 | AND N.nspname NOT IN ('pg_catalog', 'information_schema') 334 | AND N.nspname NOT LIKE E'pg\\_temp\\_%'; 335 | 336 | CREATE FUNCTION repack.repack_indexdef(oid, oid, name, bool) RETURNS text AS 337 | 'MODULE_PATHNAME', 'repack_indexdef' 338 | LANGUAGE C STABLE; 339 | 340 | CREATE FUNCTION repack.repack_trigger() RETURNS trigger AS 341 | 'MODULE_PATHNAME', 'repack_trigger' 342 | LANGUAGE C VOLATILE STRICT SECURITY DEFINER 343 | SET search_path = pg_catalog, pg_temp; 344 | 345 | CREATE FUNCTION repack.conflicted_triggers(oid) RETURNS SETOF name AS 346 | $$ 347 | SELECT tgname FROM pg_trigger 348 | WHERE tgrelid = $1 AND tgname = 'repack_trigger' 349 | ORDER BY tgname; 350 | $$ 351 | LANGUAGE sql STABLE STRICT; 352 | 353 | CREATE FUNCTION repack.disable_autovacuum(regclass) RETURNS void AS 354 | 'MODULE_PATHNAME', 'repack_disable_autovacuum' 355 | LANGUAGE C VOLATILE STRICT; 356 | 357 | CREATE FUNCTION repack.repack_apply( 358 | sql_peek cstring, 359 | sql_insert cstring, 360 | sql_delete cstring, 361 | sql_update cstring, 362 | sql_pop cstring, 363 | count integer) 364 | RETURNS integer AS 365 | 'MODULE_PATHNAME', 'repack_apply' 366 | LANGUAGE C VOLATILE; 367 | 368 | CREATE FUNCTION repack.repack_swap(oid) RETURNS void AS 369 | 'MODULE_PATHNAME', 'repack_swap' 370 | LANGUAGE C VOLATILE STRICT; 371 | 372 | CREATE FUNCTION repack.repack_drop(oid, int) RETURNS void AS 373 | 'MODULE_PATHNAME', 'repack_drop' 374 | LANGUAGE C VOLATILE STRICT; 375 | 376 | CREATE FUNCTION repack.repack_index_swap(oid) RETURNS void AS 377 | 'MODULE_PATHNAME', 'repack_index_swap' 378 | LANGUAGE C STABLE STRICT; 379 | 380 | CREATE FUNCTION repack.get_table_and_inheritors(regclass) RETURNS regclass[] AS 381 | 'MODULE_PATHNAME', 'repack_get_table_and_inheritors' 382 | LANGUAGE C STABLE STRICT; 383 | -------------------------------------------------------------------------------- /lib/pgut/pgut-be.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * pgut-be.h 4 | * 5 | * Copyright (c) 2009-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION 6 | * Portions Copyright (c) 2012-2020, The Reorg Development Team 7 | * 8 | *------------------------------------------------------------------------- 9 | */ 10 | 11 | #ifndef PGUT_BE_H 12 | #define PGUT_BE_H 13 | 14 | #include "fmgr.h" 15 | #include "utils/tuplestore.h" 16 | 17 | #ifndef WIN32 18 | 19 | #define PGUT_EXPORT 20 | 21 | #else 22 | 23 | #define PGUT_EXPORT __declspec(dllexport) 24 | 25 | /* 26 | * PG_MODULE_MAGIC and PG_FUNCTION_INFO_V1 macros seems to be broken. 27 | * It uses PGDLLIMPORT, but those objects are not imported from postgres 28 | * and exported from the user module. So, it should be always dllexported. 29 | */ 30 | 31 | #undef PG_MODULE_MAGIC 32 | #define PG_MODULE_MAGIC \ 33 | extern PGUT_EXPORT const Pg_magic_struct *PG_MAGIC_FUNCTION_NAME(void); \ 34 | const Pg_magic_struct * \ 35 | PG_MAGIC_FUNCTION_NAME(void) \ 36 | { \ 37 | static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA; \ 38 | return &Pg_magic_data; \ 39 | } \ 40 | extern int no_such_variable 41 | 42 | #undef PG_FUNCTION_INFO_V1 43 | #define PG_FUNCTION_INFO_V1(funcname) \ 44 | extern PGUT_EXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \ 45 | const Pg_finfo_record * \ 46 | CppConcat(pg_finfo_,funcname) (void) \ 47 | { \ 48 | static const Pg_finfo_record my_finfo = { 1 }; \ 49 | return &my_finfo; \ 50 | } \ 51 | extern int no_such_variable 52 | 53 | #endif 54 | 55 | #endif /* PGUT_BE_H */ 56 | -------------------------------------------------------------------------------- /lib/pgut/pgut-spi.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * pgut-spi.c 3 | * 4 | * Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION 5 | * Portions Copyright (c) 2011, Itagaki Takahiro 6 | * Portions Copyright (c) 2012-2020, The Reorg Development Team 7 | *------------------------------------------------------------------------- 8 | */ 9 | 10 | #include "postgres.h" 11 | #include "pgut-spi.h" 12 | #include "lib/stringinfo.h" 13 | 14 | #define EXEC_FAILED(ret, expected) \ 15 | (((expected) > 0 && (ret) != (expected)) || (ret) < 0) 16 | 17 | static void 18 | appendStringInfoVA_s(StringInfo str, const char *fmt, va_list args) 19 | __attribute__((format(printf, 2, 0))); 20 | 21 | static void 22 | termStringInfo(StringInfo str) 23 | { 24 | if (str && str->data) 25 | pfree(str->data); 26 | } 27 | 28 | /* appendStringInfoVA + automatic buffer extension */ 29 | static void 30 | appendStringInfoVA_s(StringInfo str, const char *fmt, va_list args) 31 | { 32 | int needed; 33 | while ((needed = appendStringInfoVA(str, fmt, args)) > 0) 34 | { 35 | /* Double the buffer size and try again. */ 36 | enlargeStringInfo(str, needed); 37 | } 38 | } 39 | 40 | /* simple execute */ 41 | void 42 | execute(int expected, const char *sql) 43 | { 44 | int ret = SPI_execute(sql, false, 0); 45 | if EXEC_FAILED(ret, expected) 46 | elog(ERROR, "query failed: (sql=%s, code=%d, expected=%d)", sql, ret, expected); 47 | } 48 | 49 | /* execute prepared plan */ 50 | void 51 | execute_plan(int expected, SPIPlanPtr plan, Datum *values, const char *nulls) 52 | { 53 | int ret = SPI_execute_plan(plan, values, nulls, false, 0); 54 | if EXEC_FAILED(ret, expected) 55 | elog(ERROR, "query failed: (code=%d, expected=%d)", ret, expected); 56 | } 57 | 58 | /* execute sql with format */ 59 | void 60 | execute_with_format(int expected, const char *format, ...) 61 | { 62 | va_list ap; 63 | StringInfoData sql; 64 | int ret; 65 | 66 | initStringInfo(&sql); 67 | va_start(ap, format); 68 | appendStringInfoVA_s(&sql, format, ap); 69 | va_end(ap); 70 | 71 | if (sql.len == 0) 72 | elog(WARNING, "execute_with_format(%s)", format); 73 | ret = SPI_exec(sql.data, 0); 74 | if EXEC_FAILED(ret, expected) 75 | elog(ERROR, "query failed: (sql=%s, code=%d, expected=%d)", sql.data, ret, expected); 76 | 77 | termStringInfo(&sql); 78 | } 79 | 80 | void 81 | execute_with_args(int expected, const char *src, int nargs, Oid argtypes[], Datum values[], const bool nulls[]) 82 | { 83 | int ret; 84 | int i; 85 | char c_nulls[FUNC_MAX_ARGS] = {0}; 86 | 87 | memset(c_nulls, 0, sizeof(c_nulls)); 88 | 89 | for (i = 0; i < nargs; i++) 90 | c_nulls[i] = (nulls[i] ? 'n' : ' '); 91 | 92 | ret = SPI_execute_with_args(src, nargs, argtypes, values, c_nulls, false, 0); 93 | if EXEC_FAILED(ret, expected) 94 | elog(ERROR, "query failed: (sql=%s, code=%d, expected=%d)", src, ret, expected); 95 | } 96 | 97 | void 98 | execute_with_format_args(int expected, const char *format, int nargs, Oid argtypes[], Datum values[], const bool nulls[], ...) 99 | { 100 | va_list ap; 101 | StringInfoData sql; 102 | 103 | initStringInfo(&sql); 104 | va_start(ap, nulls); 105 | appendStringInfoVA_s(&sql, format, ap); 106 | va_end(ap); 107 | 108 | execute_with_args(expected, sql.data, nargs, argtypes, values, nulls); 109 | 110 | termStringInfo(&sql); 111 | } 112 | -------------------------------------------------------------------------------- /lib/pgut/pgut-spi.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * pgut-spi.h 3 | * 4 | * Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION 5 | * Portions Copyright (c) 2011, Itagaki Takahiro 6 | * Portions Copyright (c) 2012-2020, The Reorg Development Team 7 | *------------------------------------------------------------------------- 8 | */ 9 | 10 | #ifndef PGUT_SPI_H 11 | #define PGUT_SPI_H 12 | 13 | #include "executor/spi.h" 14 | 15 | #ifdef _MSC_VER 16 | #define __attribute__(x) 17 | #endif 18 | 19 | extern void execute(int expected, const char *sql); 20 | extern void execute_plan(int expected, SPIPlanPtr plan, Datum *values, const char *nulls); 21 | extern void execute_with_format(int expected, const char *format, ...) 22 | __attribute__((format(printf, 2, 3))); 23 | extern void execute_with_args(int expected, const char *src, int nargs, Oid argtypes[], Datum values[], const bool nulls[]); 24 | extern void execute_with_format_args(int expected, const char *format, int nargs, Oid argtypes[], Datum values[], const bool nulls[], ...) 25 | __attribute__((format(printf, 2, 7))); 26 | 27 | #endif /* PGUT_SPI_H */ 28 | -------------------------------------------------------------------------------- /msvc/bin.2010.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {5f942836-8862-4aa3-8573-a6b80a4fbe4f} 14 | 15 | 16 | {e0adaf77-900d-4307-9a5f-6be049d0d93b} 17 | 18 | 19 | {5cf8792b-6351-4f2c-88db-784d7d8a425c} 20 | 21 | 22 | {6a46f2b1-6c15-44c2-bf14-500562f0fc30} 23 | 24 | 25 | 26 | 27 | doc 28 | 29 | 30 | doc 31 | 32 | 33 | doc 34 | 35 | 36 | doc 37 | 38 | 39 | doc 40 | 41 | 42 | doc 43 | 44 | 45 | 46 | regress\expected 47 | 48 | 49 | regress\expected 50 | 51 | 52 | regress\sql 53 | 54 | 55 | regress\sql 56 | 57 | 58 | doc 59 | 60 | 61 | 62 | 63 | 64 | src 65 | 66 | 67 | src 68 | 69 | 70 | src 71 | 72 | 73 | 74 | 75 | include 76 | 77 | 78 | include 79 | 80 | 81 | -------------------------------------------------------------------------------- /msvc/bin.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 26 | 29 | 32 | 35 | 38 | 41 | 55 | 58 | 61 | 64 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 96 | 99 | 100 | 101 | 102 | 103 | 104 | 109 | 112 | 113 | 116 | 117 | 120 | 121 | 122 | 127 | 130 | 131 | 134 | 135 | 136 | 139 | 142 | 143 | 146 | 147 | 150 | 151 | 154 | 155 | 156 | 159 | 160 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /msvc/lib.2010.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 8.3 6 | Win32 7 | 8 | 9 | 8.3 10 | x64 11 | 12 | 13 | 8.4 14 | Win32 15 | 16 | 17 | 8.4 18 | x64 19 | 20 | 21 | 9.0 22 | Win32 23 | 24 | 25 | 9.0 26 | x64 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2} 45 | lib 46 | Win32Proj 47 | 48 | 49 | 50 | DynamicLibrary 51 | Unicode 52 | true 53 | Windows7.1SDK 54 | 55 | 56 | DynamicLibrary 57 | Unicode 58 | true 59 | Windows7.1SDK 60 | 61 | 62 | DynamicLibrary 63 | Unicode 64 | true 65 | Windows7.1SDK 66 | 67 | 68 | DynamicLibrary 69 | Unicode 70 | true 71 | Windows7.1SDK 72 | 73 | 74 | DynamicLibrary 75 | Unicode 76 | true 77 | Windows7.1SDK 78 | 79 | 80 | DynamicLibrary 81 | Unicode 82 | true 83 | Windows7.1SDK 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | <_ProjectFileVersion>10.0.30319.1 109 | $(SolutionDir)/bin/x86/$(Configuration)/lib/ 110 | $(SolutionDir)/bin/$(Platform)/$(Configuration)/lib/ 111 | $(SolutionDir)/bin/x86/$(Configuration)/lib/ 112 | $(SolutionDir)/bin/$(Platform)/$(Configuration)/lib/ 113 | $(SolutionDir)/bin/x86/$(Configuration)/lib/ 114 | $(SolutionDir)/bin/$(Platform)/$(Configuration)/lib/ 115 | $(SolutionDir)/obj/x86/$(Configuration)/$(ProjectName)/ 116 | $(SolutionDir)/obj/$(Platform)/$(Configuration)/$(ProjectName)/ 117 | $(SolutionDir)/obj/x86/$(Configuration)/$(ProjectName)/ 118 | $(SolutionDir)/obj/$(Platform)/$(Configuration)/$(ProjectName)/ 119 | $(SolutionDir)/obj/x86/$(Configuration)/$(ProjectName)/ 120 | $(SolutionDir)/obj/$(Platform)/$(Configuration)/$(ProjectName)/ 121 | false 122 | false 123 | false 124 | false 125 | false 126 | false 127 | C:\Program Files %28x86%29\PostgreSQL\9.0\include\server\port\win32_msvc;C:\Program Files %28x86%29\PostgreSQL\9.0\include\server\port\win32;C:\Program Files %28x86%29\PostgreSQL\9.0\include\server;C:\Program Files %28x86%29\PostgreSQL\9.0\include;$(IncludePath) 128 | C:\Program Files\PostgreSQL\9.0\include\server\port\win32_msvc;C:\Program Files\PostgreSQL\9.0\include\server\port\win32;C:\Program Files\PostgreSQL\9.0\include\server;C:\Program Files\PostgreSQL\9.0\include;$(IncludePath) 129 | C:\Program Files %28x86%29\PostgreSQL\8.4\include\server\port\win32_msvc;C:\Program Files %28x86%29\PostgreSQL\8.4\include\server\port\win32;C:\Program Files %28x86%29\PostgreSQL\8.4\include\server;C:\Program Files %28x86%29\PostgreSQL\8.4\include;$(IncludePath) 130 | C:\Program Files %28x86%29\PostgreSQL\8.4\include\server\port\win32_msvc;C:\Program Files %28x86%29\PostgreSQL\8.4\include\server\port\win32;C:\Program Files %28x86%29\PostgreSQL\8.4\include\server;C:\Program Files %28x86%29\PostgreSQL\8.4\include;$(IncludePath) 131 | C:\Program Files %28x86%29\PostgreSQL\8.3\include\server\port\win32_msvc;C:\Program Files %28x86%29\PostgreSQL\8.3\include\server\port\win32;C:\Program Files %28x86%29\PostgreSQL\8.3\include\server;C:\Program Files %28x86%29\PostgreSQL\8.3\include;$(IncludePath) 132 | C:\Program Files %28x86%29\PostgreSQL\8.3\include\server\port\win32_msvc;C:\Program Files %28x86%29\PostgreSQL\8.3\include\server\port\win32;C:\Program Files %28x86%29\PostgreSQL\8.3\include\server;C:\Program Files %28x86%29\PostgreSQL\8.3\include;$(IncludePath) 133 | C:\Program Files %28x86%29\PostgreSQL\9.0\lib;$(LibraryPath) 134 | C:\Program Files\PostgreSQL\9.0\lib;$(LibraryPath) 135 | C:\Program Files %28x86%29\PostgreSQL\8.4\lib;$(LibraryPath) 136 | C:\Program Files %28x86%29\PostgreSQL\8.4\lib;$(LibraryPath) 137 | C:\Program Files %28x86%29\PostgreSQL\8.3\lib;$(LibraryPath) 138 | C:\Program Files %28x86%29\PostgreSQL\8.3\lib;$(LibraryPath) 139 | pg_repack 140 | pg_repack 141 | pg_repack 142 | pg_repack 143 | pg_repack 144 | pg_repack 145 | 146 | 147 | 148 | ../include;%(AdditionalIncludeDirectories) 149 | WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 150 | 151 | 152 | MultiThreadedDLL 153 | 154 | 155 | Level3 156 | false 157 | 158 | 159 | CompileAsC 160 | 4005;4996;4018;%(DisableSpecificWarnings) 161 | 162 | 163 | postgres.lib 164 | $(OutDir)/$(TargetFileName) 165 | false 166 | Console 167 | true 168 | true 169 | MachineX86 170 | 171 | 172 | 173 | 174 | ../include;%(AdditionalIncludeDirectories) 175 | WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 176 | 177 | 178 | MultiThreadedDLL 179 | 180 | 181 | Level3 182 | false 183 | 184 | 185 | CompileAsC 186 | 4005;4996;4018;%(DisableSpecificWarnings) 187 | 188 | 189 | postgres.lib 190 | $(OutDir)/$(TargetFileName) 191 | false 192 | Console 193 | true 194 | true 195 | 196 | 197 | 198 | 199 | ../include;%(AdditionalIncludeDirectories) 200 | WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 201 | 202 | 203 | MultiThreadedDLL 204 | 205 | 206 | Level3 207 | false 208 | 209 | 210 | CompileAsC 211 | 4005;4996;4018;%(DisableSpecificWarnings) 212 | 213 | 214 | postgres.lib 215 | $(OutDir)/$(TargetFileName) 216 | false 217 | Console 218 | true 219 | true 220 | MachineX86 221 | 222 | 223 | 224 | 225 | ../include;%(AdditionalIncludeDirectories) 226 | WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 227 | 228 | 229 | MultiThreadedDLL 230 | 231 | 232 | Level3 233 | false 234 | 235 | 236 | CompileAsC 237 | 4005;4996;4018;%(DisableSpecificWarnings) 238 | 239 | 240 | postgres.lib 241 | $(OutDir)/$(TargetFileName) 242 | false 243 | Console 244 | true 245 | true 246 | 247 | 248 | 249 | 250 | ../include;%(AdditionalIncludeDirectories) 251 | _USE_32BIT_TIME_T;WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 252 | 253 | 254 | MultiThreadedDLL 255 | 256 | 257 | Level3 258 | false 259 | 260 | 261 | CompileAsC 262 | 4005;4996;4018;%(DisableSpecificWarnings) 263 | 264 | 265 | postgres.lib 266 | $(OutDir)/$(TargetFileName) 267 | false 268 | Console 269 | true 270 | true 271 | MachineX86 272 | 273 | 274 | 275 | 276 | ../include;%(AdditionalIncludeDirectories) 277 | _USE_32BIT_TIME_T;WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 278 | 279 | 280 | MultiThreadedDLL 281 | 282 | 283 | Level3 284 | false 285 | 286 | 287 | CompileAsC 288 | 4005;4996;4018;%(DisableSpecificWarnings) 289 | 290 | 291 | postgres.lib 292 | $(OutDir)/$(TargetFileName) 293 | false 294 | Console 295 | true 296 | true 297 | 298 | 299 | 300 | 301 | 302 | -------------------------------------------------------------------------------- /msvc/lib.2010.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | src 21 | 22 | 23 | src 24 | 25 | 26 | src 27 | 28 | 29 | 30 | 31 | include 32 | 33 | 34 | include 35 | 36 | 37 | -------------------------------------------------------------------------------- /msvc/lib.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 26 | 29 | 32 | 35 | 38 | 41 | 55 | 58 | 61 | 64 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 96 | 99 | 100 | 101 | 102 | 103 | 104 | 109 | 112 | 113 | 116 | 117 | 120 | 121 | 122 | 127 | 130 | 131 | 134 | 135 | 136 | 139 | 140 | 143 | 144 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /msvc/pg_repack.2010.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual C++ Express 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin.2010", "bin.2010.vcxproj", "{B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib.2010", "lib.2010.vcxproj", "{B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | 8.3|Win32 = 8.3|Win32 11 | 8.3|x64 = 8.3|x64 12 | 8.4|Win32 = 8.4|Win32 13 | 8.4|x64 = 8.4|x64 14 | 9.0|Win32 = 9.0|Win32 15 | 9.0|x64 = 9.0|x64 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.8.3|Win32.ActiveCfg = 8.3|Win32 19 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.8.3|Win32.Build.0 = 8.3|Win32 20 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.8.3|x64.ActiveCfg = 8.3|x64 21 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.8.3|x64.Build.0 = 8.3|x64 22 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.8.4|Win32.ActiveCfg = 8.4|Win32 23 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.8.4|Win32.Build.0 = 8.4|Win32 24 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.8.4|x64.ActiveCfg = 8.4|x64 25 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.8.4|x64.Build.0 = 8.4|x64 26 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.9.0|Win32.ActiveCfg = 9.0|Win32 27 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.9.0|Win32.Build.0 = 9.0|Win32 28 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.9.0|x64.ActiveCfg = 9.0|x64 29 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.9.0|x64.Build.0 = 9.0|x64 30 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.8.3|Win32.ActiveCfg = 8.3|Win32 31 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.8.3|Win32.Build.0 = 8.3|Win32 32 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.8.3|x64.ActiveCfg = 8.3|x64 33 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.8.3|x64.Build.0 = 8.3|x64 34 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.8.4|Win32.ActiveCfg = 8.4|Win32 35 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.8.4|Win32.Build.0 = 8.4|Win32 36 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.8.4|x64.ActiveCfg = 8.4|x64 37 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.8.4|x64.Build.0 = 8.4|x64 38 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.9.0|Win32.ActiveCfg = 9.0|Win32 39 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.9.0|Win32.Build.0 = 9.0|Win32 40 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.9.0|x64.ActiveCfg = 9.0|x64 41 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.9.0|x64.Build.0 = 9.0|x64 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | EndGlobal 47 | -------------------------------------------------------------------------------- /msvc/pg_repack.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 9.00 3 | # Visual C++ Express 2005 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin", "bin.vcproj", "{B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib", "lib.vcproj", "{B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Release|Win32 = Release|Win32 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.Release|Win32.ActiveCfg = Release|Win32 14 | {B6B37F22-9E44-4240-AAA0-650D4AC2C1E2}.Release|Win32.Build.0 = Release|Win32 15 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.Release|Win32.ActiveCfg = Release|Win32 16 | {B6B37F22-9E44-4240-AAA0-650D4AC2C2E2}.Release|Win32.Build.0 = Release|Win32 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | EndGlobal 22 | -------------------------------------------------------------------------------- /msvc/readme.txt: -------------------------------------------------------------------------------- 1 | How to build with Microsoft Visual C++ Express 2005 2 | 3 | You might need: 4 | 1. Register PostgreSQL directory to your environment. 5 | 2. Resolve redefinitions of ERROR macro. 6 | 7 | ---- 8 | 1. Register PostgreSQL directory to your environment. 9 | 10 | The directory configuration options are found in: 11 | Tool > Option > Projects and Solutions > VC++ directory 12 | 13 | You might need to add the following directories: 14 | into "include files" 15 | - C:\Program Files\PostgreSQL\8.4\include 16 | - C:\Program Files\PostgreSQL\8.4\include\internal 17 | - C:\Program Files\PostgreSQL\8.4\include\server 18 | - C:\Program Files\PostgreSQL\8.4\include\server\port\win32 19 | - C:\Program Files\PostgreSQL\8.4\include\server\port\win32_msvc 20 | into "library files" 21 | - C:\Program Files\PostgreSQL\8.4\lib 22 | 23 | ---- 24 | 2. Resolve redefinitions of ERROR macro. 25 | 26 | It might be a bad manner, but I'll recommend to modify your wingdi.h. 27 | 28 | --- wingdi.h 2008-01-18 22:17:42.000000000 +0900 29 | +++ wingdi.fixed.h 2010-03-03 09:51:43.015625000 +0900 30 | @@ -101,11 +101,10 @@ 31 | #endif // (_WIN32_WINNT >= _WIN32_WINNT_WINXP) 32 | 33 | /* Region Flags */ 34 | -#define ERROR 0 35 | +#define RGN_ERROR 0 36 | #define NULLREGION 1 37 | #define SIMPLEREGION 2 38 | #define COMPLEXREGION 3 39 | -#define RGN_ERROR ERROR 40 | 41 | /* CombineRgn() Styles */ 42 | #define RGN_AND 1 43 | -------------------------------------------------------------------------------- /regress/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # pg_repack: regress/Makefile 3 | # 4 | # Portions Copyright (c) 2008-2012, NIPPON TELEGRAPH AND TELEPHONE CORPORATION 5 | # Portions Copyright (c) 2011, Itagaki Takahiro 6 | # Portions Copyright (c) 2012-2020, The Reorg Development Team 7 | # 8 | 9 | PG_CONFIG ?= pg_config 10 | 11 | # version as a number, e.g. 9.1.4 -> 901 12 | VERSION := $(shell $(PG_CONFIG) --version | sed 's/.* \([[:digit:].]\{1,\}\).*/\1/') 13 | INTVERSION := $(shell echo $$(($$(echo $(VERSION).0 | sed 's/\([[:digit:]]\{1,\}\)\.\([[:digit:]]\{1,\}\).*/\1*100+\2/')))) 14 | 15 | 16 | # 17 | # Test suite 18 | # 19 | 20 | REGRESS := init-extension repack-setup repack-run error-on-invalid-idx no-error-on-invalid-idx after-schema repack-check nosuper tablespace get_order_by trigger 21 | 22 | USE_PGXS = 1 # use pgxs if not in contrib directory 23 | PGXS := $(shell $(PG_CONFIG) --pgxs) 24 | include $(PGXS) 25 | -------------------------------------------------------------------------------- /regress/create_tablespaces.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | sudo -u postgres mkdir /tmp/testts /tmp/1testts /tmp/test\ ts /tmp/test\"ts 4 | 5 | sudo -u postgres psql -c "CREATE TABLESPACE testts LOCATION '/tmp/testts'" 6 | sudo -u postgres psql -c "CREATE TABLESPACE \"1testts\" LOCATION '/tmp/1testts'" 7 | sudo -u postgres psql -c "CREATE TABLESPACE \"test ts\" LOCATION '/tmp/test ts'" 8 | sudo -u postgres psql -c "CREATE TABLESPACE \"test\"\"ts\" LOCATION '/tmp/test\"ts'" 9 | -------------------------------------------------------------------------------- /regress/expected/after-schema.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- tables schema after running repack 3 | -- 4 | \d tbl_cluster 5 | Table "public.tbl_cluster" 6 | Column | Type | Collation | Nullable | Default 7 | --------+-----------------------------+-----------+----------+--------- 8 | col1 | integer | | not null | 9 | time | timestamp without time zone | | | 10 | ,") | text | | not null | 11 | Indexes: 12 | "tbl_cluster_pkey" PRIMARY KEY, btree (","")", col1) WITH (fillfactor='75') 13 | ",") cluster" btree ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor='75') CLUSTER 14 | 15 | \d tbl_gistkey 16 | Table "public.tbl_gistkey" 17 | Column | Type | Collation | Nullable | Default 18 | --------+---------+-----------+----------+--------- 19 | id | integer | | not null | 20 | c | circle | | | 21 | Indexes: 22 | "tbl_gistkey_pkey" PRIMARY KEY, btree (id) 23 | "cidx_circle" gist (c) CLUSTER 24 | 25 | \d tbl_only_ckey 26 | Table "public.tbl_only_ckey" 27 | Column | Type | Collation | Nullable | Default 28 | --------+-----------------------------+-----------+----------+--------- 29 | col1 | integer | | | 30 | col2 | timestamp without time zone | | | 31 | ,") | text | | | 32 | Indexes: 33 | "cidx_only_ckey" btree (col2, ","")") CLUSTER 34 | 35 | \d tbl_only_pkey 36 | Table "public.tbl_only_pkey" 37 | Column | Type | Collation | Nullable | Default 38 | --------+---------+-----------+----------+--------- 39 | col1 | integer | | not null | 40 | ,") | text | | | 41 | Indexes: 42 | "tbl_only_pkey_pkey" PRIMARY KEY, btree (col1) 43 | 44 | \d tbl_incl_pkey 45 | Table "public.tbl_incl_pkey" 46 | Column | Type | Collation | Nullable | Default 47 | --------+-----------------------------+-----------+----------+--------- 48 | col1 | integer | | not null | 49 | col2 | timestamp without time zone | | | 50 | Indexes: 51 | "tbl_incl_pkey_pkey" PRIMARY KEY, btree (col1) INCLUDE (col2) 52 | 53 | \d tbl_with_dropped_column 54 | Table "public.tbl_with_dropped_column" 55 | Column | Type | Collation | Nullable | Default 56 | --------+---------+-----------+----------+--------- 57 | c1 | text | | | 58 | id | integer | | not null | 59 | c2 | text | | | 60 | c3 | text | | | 61 | Indexes: 62 | "tbl_with_dropped_column_pkey" PRIMARY KEY, btree (id) WITH (fillfactor='75') CLUSTER 63 | "idx_c1c2" btree (c1, c2) WITH (fillfactor='75') 64 | "idx_c2c1" btree (c2, c1) 65 | 66 | \d tbl_with_dropped_toast 67 | Table "public.tbl_with_dropped_toast" 68 | Column | Type | Collation | Nullable | Default 69 | --------+---------+-----------+----------+--------- 70 | i | integer | | not null | 71 | j | integer | | not null | 72 | Indexes: 73 | "tbl_with_dropped_toast_pkey" PRIMARY KEY, btree (i, j) CLUSTER 74 | 75 | \d tbl_idxopts 76 | Table "public.tbl_idxopts" 77 | Column | Type | Collation | Nullable | Default 78 | --------+---------+-----------+----------+--------- 79 | i | integer | | not null | 80 | t | text | | | 81 | Indexes: 82 | "tbl_idxopts_pkey" PRIMARY KEY, btree (i) 83 | "idxopts_t" btree (t DESC NULLS LAST) WHERE t <> 'aaa'::text 84 | 85 | -------------------------------------------------------------------------------- /regress/expected/after-schema_1.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- tables schema after running repack 3 | -- 4 | \d tbl_cluster 5 | Table "public.tbl_cluster" 6 | Column | Type | Collation | Nullable | Default 7 | --------+-----------------------------+-----------+----------+--------- 8 | col1 | integer | | not null | 9 | time | timestamp without time zone | | | 10 | ,") | text | | not null | 11 | Indexes: 12 | "tbl_cluster_pkey" PRIMARY KEY, btree (","")", col1) WITH (fillfactor='75') 13 | ",") cluster" btree ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor='75') CLUSTER 14 | 15 | \d tbl_gistkey 16 | Table "public.tbl_gistkey" 17 | Column | Type | Collation | Nullable | Default 18 | --------+---------+-----------+----------+--------- 19 | id | integer | | not null | 20 | c | circle | | | 21 | Indexes: 22 | "tbl_gistkey_pkey" PRIMARY KEY, btree (id) 23 | "cidx_circle" gist (c) CLUSTER 24 | 25 | \d tbl_only_ckey 26 | Table "public.tbl_only_ckey" 27 | Column | Type | Collation | Nullable | Default 28 | --------+-----------------------------+-----------+----------+--------- 29 | col1 | integer | | | 30 | col2 | timestamp without time zone | | | 31 | ,") | text | | | 32 | Indexes: 33 | "cidx_only_ckey" btree (col2, ","")") CLUSTER 34 | 35 | \d tbl_only_pkey 36 | Table "public.tbl_only_pkey" 37 | Column | Type | Collation | Nullable | Default 38 | --------+---------+-----------+----------+--------- 39 | col1 | integer | | not null | 40 | ,") | text | | | 41 | Indexes: 42 | "tbl_only_pkey_pkey" PRIMARY KEY, btree (col1) 43 | 44 | \d tbl_incl_pkey 45 | Table "public.tbl_incl_pkey" 46 | Column | Type | Collation | Nullable | Default 47 | --------+-----------------------------+-----------+----------+--------- 48 | col1 | integer | | | 49 | col2 | timestamp without time zone | | | 50 | 51 | \d tbl_with_dropped_column 52 | Table "public.tbl_with_dropped_column" 53 | Column | Type | Collation | Nullable | Default 54 | --------+---------+-----------+----------+--------- 55 | c1 | text | | | 56 | id | integer | | not null | 57 | c2 | text | | | 58 | c3 | text | | | 59 | Indexes: 60 | "tbl_with_dropped_column_pkey" PRIMARY KEY, btree (id) WITH (fillfactor='75') CLUSTER 61 | "idx_c1c2" btree (c1, c2) WITH (fillfactor='75') 62 | "idx_c2c1" btree (c2, c1) 63 | 64 | \d tbl_with_dropped_toast 65 | Table "public.tbl_with_dropped_toast" 66 | Column | Type | Collation | Nullable | Default 67 | --------+---------+-----------+----------+--------- 68 | i | integer | | not null | 69 | j | integer | | not null | 70 | Indexes: 71 | "tbl_with_dropped_toast_pkey" PRIMARY KEY, btree (i, j) CLUSTER 72 | 73 | \d tbl_idxopts 74 | Table "public.tbl_idxopts" 75 | Column | Type | Collation | Nullable | Default 76 | --------+---------+-----------+----------+--------- 77 | i | integer | | not null | 78 | t | text | | | 79 | Indexes: 80 | "tbl_idxopts_pkey" PRIMARY KEY, btree (i) 81 | "idxopts_t" btree (t DESC NULLS LAST) WHERE t <> 'aaa'::text 82 | 83 | -------------------------------------------------------------------------------- /regress/expected/after-schema_2.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- tables schema after running repack 3 | -- 4 | \d tbl_cluster 5 | Table "public.tbl_cluster" 6 | Column | Type | Modifiers 7 | --------+-----------------------------+----------- 8 | col1 | integer | not null 9 | time | timestamp without time zone | 10 | ,") | text | not null 11 | Indexes: 12 | "tbl_cluster_pkey" PRIMARY KEY, btree (","")", col1) WITH (fillfactor='75') 13 | ",") cluster" btree ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor='75') CLUSTER 14 | 15 | \d tbl_gistkey 16 | Table "public.tbl_gistkey" 17 | Column | Type | Modifiers 18 | --------+---------+----------- 19 | id | integer | not null 20 | c | circle | 21 | Indexes: 22 | "tbl_gistkey_pkey" PRIMARY KEY, btree (id) 23 | "cidx_circle" gist (c) CLUSTER 24 | 25 | \d tbl_only_ckey 26 | Table "public.tbl_only_ckey" 27 | Column | Type | Modifiers 28 | --------+-----------------------------+----------- 29 | col1 | integer | 30 | col2 | timestamp without time zone | 31 | ,") | text | 32 | Indexes: 33 | "cidx_only_ckey" btree (col2, ","")") CLUSTER 34 | 35 | \d tbl_only_pkey 36 | Table "public.tbl_only_pkey" 37 | Column | Type | Modifiers 38 | --------+---------+----------- 39 | col1 | integer | not null 40 | ,") | text | 41 | Indexes: 42 | "tbl_only_pkey_pkey" PRIMARY KEY, btree (col1) 43 | 44 | \d tbl_incl_pkey 45 | Table "public.tbl_incl_pkey" 46 | Column | Type | Modifiers 47 | --------+-----------------------------+----------- 48 | col1 | integer | 49 | col2 | timestamp without time zone | 50 | 51 | \d tbl_with_dropped_column 52 | Table "public.tbl_with_dropped_column" 53 | Column | Type | Modifiers 54 | --------+---------+----------- 55 | c1 | text | 56 | id | integer | not null 57 | c2 | text | 58 | c3 | text | 59 | Indexes: 60 | "tbl_with_dropped_column_pkey" PRIMARY KEY, btree (id) WITH (fillfactor='75') CLUSTER 61 | "idx_c1c2" btree (c1, c2) WITH (fillfactor='75') 62 | "idx_c2c1" btree (c2, c1) 63 | 64 | \d tbl_with_dropped_toast 65 | Table "public.tbl_with_dropped_toast" 66 | Column | Type | Modifiers 67 | --------+---------+----------- 68 | i | integer | not null 69 | j | integer | not null 70 | Indexes: 71 | "tbl_with_dropped_toast_pkey" PRIMARY KEY, btree (i, j) CLUSTER 72 | 73 | \d tbl_idxopts 74 | Table "public.tbl_idxopts" 75 | Column | Type | Modifiers 76 | --------+---------+----------- 77 | i | integer | not null 78 | t | text | 79 | Indexes: 80 | "tbl_idxopts_pkey" PRIMARY KEY, btree (i) 81 | "idxopts_t" btree (t DESC NULLS LAST) WHERE t <> 'aaa'::text 82 | 83 | -------------------------------------------------------------------------------- /regress/expected/error-on-invalid-idx.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- do repack 3 | -- 4 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --error-on-invalid-index 5 | INFO: repacking table "public.tbl_cluster" 6 | \! pg_repack --dbname=contrib_regression --table=tbl_badindex --error-on-invalid-index 7 | INFO: repacking table "public.tbl_badindex" 8 | WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 9 | \! pg_repack --dbname=contrib_regression --error-on-invalid-index 10 | INFO: repacking table "public.tbl_badindex" 11 | WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 12 | INFO: repacking table "public.tbl_cluster" 13 | INFO: repacking table "public.tbl_gistkey" 14 | INFO: repacking table "public.tbl_idxopts" 15 | INFO: repacking table "public.tbl_incl_pkey" 16 | INFO: repacking table "public.tbl_only_pkey" 17 | INFO: repacking table "public.tbl_order" 18 | INFO: repacking table "public.tbl_storage_plain" 19 | INFO: repacking table "public.tbl_with_dropped_column" 20 | INFO: repacking table "public.tbl_with_dropped_toast" 21 | INFO: repacking table "public.tbl_with_mod_column_storage" 22 | INFO: repacking table "public.tbl_with_toast" 23 | -------------------------------------------------------------------------------- /regress/expected/error-on-invalid-idx_1.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- do repack 3 | -- 4 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --error-on-invalid-index 5 | INFO: repacking table "public.tbl_cluster" 6 | \! pg_repack --dbname=contrib_regression --table=tbl_badindex --error-on-invalid-index 7 | INFO: repacking table "public.tbl_badindex" 8 | WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 9 | \! pg_repack --dbname=contrib_regression --error-on-invalid-index 10 | INFO: repacking table "public.tbl_badindex" 11 | WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 12 | INFO: repacking table "public.tbl_cluster" 13 | INFO: repacking table "public.tbl_gistkey" 14 | INFO: repacking table "public.tbl_idxopts" 15 | INFO: repacking table "public.tbl_only_pkey" 16 | INFO: repacking table "public.tbl_order" 17 | INFO: repacking table "public.tbl_storage_plain" 18 | INFO: repacking table "public.tbl_with_dropped_column" 19 | INFO: repacking table "public.tbl_with_dropped_toast" 20 | INFO: repacking table "public.tbl_with_mod_column_storage" 21 | INFO: repacking table "public.tbl_with_toast" 22 | -------------------------------------------------------------------------------- /regress/expected/get_order_by.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- pg_repack issue #3 3 | -- 4 | CREATE TABLE issue3_1 (col1 int NOT NULL, col2 text NOT NULL); 5 | CREATE UNIQUE INDEX issue3_1_idx ON issue3_1 (col1, col2 DESC); 6 | SELECT repack.get_order_by('issue3_1_idx'::regclass::oid, 'issue3_1'::regclass::oid); 7 | get_order_by 8 | ----------------- 9 | col1, col2 DESC 10 | (1 row) 11 | 12 | \! pg_repack --dbname=contrib_regression --table=issue3_1 13 | INFO: repacking table "public.issue3_1" 14 | CREATE TABLE issue3_2 (col1 int NOT NULL, col2 text NOT NULL); 15 | CREATE UNIQUE INDEX issue3_2_idx ON issue3_2 (col1 DESC, col2 text_pattern_ops); 16 | SELECT repack.get_order_by('issue3_2_idx'::regclass::oid, 'issue3_2'::regclass::oid); 17 | get_order_by 18 | --------------------------- 19 | col1 DESC, col2 USING ~<~ 20 | (1 row) 21 | 22 | \! pg_repack --dbname=contrib_regression --table=issue3_2 23 | INFO: repacking table "public.issue3_2" 24 | CREATE TABLE issue3_3 (col1 int NOT NULL, col2 text NOT NULL); 25 | CREATE UNIQUE INDEX issue3_3_idx ON issue3_3 (col1 DESC, col2 DESC); 26 | SELECT repack.get_order_by('issue3_3_idx'::regclass::oid, 'issue3_3'::regclass::oid); 27 | get_order_by 28 | ---------------------- 29 | col1 DESC, col2 DESC 30 | (1 row) 31 | 32 | \! pg_repack --dbname=contrib_regression --table=issue3_3 33 | INFO: repacking table "public.issue3_3" 34 | CREATE TABLE issue3_4 (col1 int NOT NULL, col2 text NOT NULL); 35 | CREATE UNIQUE INDEX issue3_4_idx ON issue3_4 (col1 NULLS FIRST, col2 text_pattern_ops DESC NULLS LAST); 36 | SELECT repack.get_order_by('issue3_4_idx'::regclass::oid, 'issue3_4'::regclass::oid); 37 | get_order_by 38 | -------------------------------------------------- 39 | col1 NULLS FIRST, col2 DESC USING ~<~ NULLS LAST 40 | (1 row) 41 | 42 | \! pg_repack --dbname=contrib_regression --table=issue3_4 43 | INFO: repacking table "public.issue3_4" 44 | CREATE TABLE issue3_5 (col1 int NOT NULL, col2 text NOT NULL); 45 | CREATE UNIQUE INDEX issue3_5_idx ON issue3_5 (col1 DESC NULLS FIRST, col2 COLLATE "POSIX" DESC); 46 | SELECT repack.get_order_by('issue3_5_idx'::regclass::oid, 'issue3_5'::regclass::oid); 47 | get_order_by 48 | -------------------------------------- 49 | col1 DESC, col2 COLLATE "POSIX" DESC 50 | (1 row) 51 | 52 | \! pg_repack --dbname=contrib_regression --table=issue3_5 53 | INFO: repacking table "public.issue3_5" 54 | -- 55 | -- pg_repack issue #321 56 | -- 57 | CREATE TABLE issue321 (col1 int NOT NULL, col2 text NOT NULL); 58 | CREATE UNIQUE INDEX issue321_idx ON issue321 (col1); 59 | SELECT repack.get_order_by('issue321_idx'::regclass::oid, 1); 60 | ERROR: table name not found for OID 1 61 | SELECT repack.get_order_by(1, 1); 62 | ERROR: cache lookup failed for index 1 63 | -------------------------------------------------------------------------------- /regress/expected/init-extension.out: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | CREATE EXTENSION pg_repack; 3 | RESET client_min_messages; 4 | -------------------------------------------------------------------------------- /regress/expected/no-error-on-invalid-idx.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- do repack 3 | -- 4 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-error-on-invalid-index 5 | INFO: repacking table "public.tbl_cluster" 6 | \! pg_repack --dbname=contrib_regression --table=tbl_badindex --no-error-on-invalid-index 7 | INFO: repacking table "public.tbl_badindex" 8 | WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 9 | \! pg_repack --dbname=contrib_regression --no-error-on-invalid-index 10 | INFO: repacking table "public.tbl_badindex" 11 | WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 12 | INFO: repacking table "public.tbl_cluster" 13 | INFO: repacking table "public.tbl_gistkey" 14 | INFO: repacking table "public.tbl_idxopts" 15 | INFO: repacking table "public.tbl_incl_pkey" 16 | INFO: repacking table "public.tbl_only_pkey" 17 | INFO: repacking table "public.tbl_order" 18 | INFO: repacking table "public.tbl_storage_plain" 19 | INFO: repacking table "public.tbl_with_dropped_column" 20 | INFO: repacking table "public.tbl_with_dropped_toast" 21 | INFO: repacking table "public.tbl_with_mod_column_storage" 22 | INFO: repacking table "public.tbl_with_toast" 23 | -------------------------------------------------------------------------------- /regress/expected/no-error-on-invalid-idx_1.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- do repack 3 | -- 4 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-error-on-invalid-index 5 | INFO: repacking table "public.tbl_cluster" 6 | \! pg_repack --dbname=contrib_regression --table=tbl_badindex --no-error-on-invalid-index 7 | INFO: repacking table "public.tbl_badindex" 8 | WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 9 | \! pg_repack --dbname=contrib_regression --no-error-on-invalid-index 10 | INFO: repacking table "public.tbl_badindex" 11 | WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 12 | INFO: repacking table "public.tbl_cluster" 13 | INFO: repacking table "public.tbl_gistkey" 14 | INFO: repacking table "public.tbl_idxopts" 15 | INFO: repacking table "public.tbl_only_pkey" 16 | INFO: repacking table "public.tbl_order" 17 | INFO: repacking table "public.tbl_storage_plain" 18 | INFO: repacking table "public.tbl_with_dropped_column" 19 | INFO: repacking table "public.tbl_with_dropped_toast" 20 | INFO: repacking table "public.tbl_with_mod_column_storage" 21 | INFO: repacking table "public.tbl_with_toast" 22 | -------------------------------------------------------------------------------- /regress/expected/nosuper.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- no superuser check 3 | -- 4 | SET client_min_messages = error; 5 | DROP ROLE IF EXISTS nosuper; 6 | SET client_min_messages = warning; 7 | CREATE ROLE nosuper WITH LOGIN; 8 | -- => OK 9 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-superuser-check 10 | INFO: repacking table "public.tbl_cluster" 11 | -- => ERROR 12 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper 13 | ERROR: pg_repack failed with error: You must be a superuser to use pg_repack 14 | -- => ERROR 15 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check 16 | ERROR: pg_repack failed with error: ERROR: permission denied for schema repack 17 | LINE 1: select repack.version(), repack.version_sql() 18 | ^ 19 | GRANT ALL ON ALL TABLES IN SCHEMA repack TO nosuper; 20 | GRANT USAGE ON SCHEMA repack TO nosuper; 21 | -- => ERROR 22 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check 23 | INFO: repacking table "public.tbl_cluster" 24 | ERROR: query failed: ERROR: current transaction is aborted, commands ignored until end of transaction block 25 | DETAIL: query was: RESET lock_timeout 26 | ERROR: query failed: ERROR: current transaction is aborted, commands ignored until end of transaction block 27 | DETAIL: query was: RESET lock_timeout 28 | ERROR: permission denied for table tbl_cluster 29 | ERROR: permission denied for table tbl_cluster 30 | REVOKE ALL ON ALL TABLES IN SCHEMA repack FROM nosuper; 31 | REVOKE USAGE ON SCHEMA repack FROM nosuper; 32 | DROP ROLE IF EXISTS nosuper; 33 | -------------------------------------------------------------------------------- /regress/expected/nosuper_1.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- no superuser check 3 | -- 4 | SET client_min_messages = error; 5 | DROP ROLE IF EXISTS nosuper; 6 | SET client_min_messages = warning; 7 | CREATE ROLE nosuper WITH LOGIN; 8 | -- => OK 9 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-superuser-check 10 | INFO: repacking table "public.tbl_cluster" 11 | -- => ERROR 12 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper 13 | ERROR: pg_repack failed with error: You must be a superuser to use pg_repack 14 | -- => ERROR 15 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check 16 | ERROR: pg_repack failed with error: ERROR: permission denied for schema repack 17 | LINE 1: select repack.version(), repack.version_sql() 18 | ^ 19 | GRANT ALL ON ALL TABLES IN SCHEMA repack TO nosuper; 20 | GRANT USAGE ON SCHEMA repack TO nosuper; 21 | -- => ERROR 22 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check 23 | INFO: repacking table "public.tbl_cluster" 24 | ERROR: query failed: ERROR: current transaction is aborted, commands ignored until end of transaction block 25 | DETAIL: query was: RESET lock_timeout 26 | ERROR: query failed: ERROR: current transaction is aborted, commands ignored until end of transaction block 27 | DETAIL: query was: RESET lock_timeout 28 | ERROR: permission denied for relation tbl_cluster 29 | ERROR: permission denied for relation tbl_cluster 30 | REVOKE ALL ON ALL TABLES IN SCHEMA repack FROM nosuper; 31 | REVOKE USAGE ON SCHEMA repack FROM nosuper; 32 | DROP ROLE IF EXISTS nosuper; 33 | -------------------------------------------------------------------------------- /regress/expected/repack-run.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- do repack 3 | -- 4 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster 5 | INFO: repacking table "public.tbl_cluster" 6 | \! pg_repack --dbname=contrib_regression --table=tbl_badindex 7 | INFO: repacking table "public.tbl_badindex" 8 | WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 9 | \! pg_repack --dbname=contrib_regression 10 | INFO: repacking table "public.tbl_badindex" 11 | WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 12 | INFO: repacking table "public.tbl_cluster" 13 | INFO: repacking table "public.tbl_gistkey" 14 | INFO: repacking table "public.tbl_idxopts" 15 | INFO: repacking table "public.tbl_incl_pkey" 16 | INFO: repacking table "public.tbl_only_pkey" 17 | INFO: repacking table "public.tbl_order" 18 | INFO: repacking table "public.tbl_storage_plain" 19 | INFO: repacking table "public.tbl_with_dropped_column" 20 | INFO: repacking table "public.tbl_with_dropped_toast" 21 | INFO: repacking table "public.tbl_with_mod_column_storage" 22 | INFO: repacking table "public.tbl_with_toast" 23 | -------------------------------------------------------------------------------- /regress/expected/repack-run_1.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- do repack 3 | -- 4 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster 5 | INFO: repacking table "public.tbl_cluster" 6 | \! pg_repack --dbname=contrib_regression --table=tbl_badindex 7 | INFO: repacking table "public.tbl_badindex" 8 | WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 9 | \! pg_repack --dbname=contrib_regression 10 | INFO: repacking table "public.tbl_badindex" 11 | WARNING: Invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) 12 | INFO: repacking table "public.tbl_cluster" 13 | INFO: repacking table "public.tbl_gistkey" 14 | INFO: repacking table "public.tbl_idxopts" 15 | INFO: repacking table "public.tbl_only_pkey" 16 | INFO: repacking table "public.tbl_order" 17 | INFO: repacking table "public.tbl_storage_plain" 18 | INFO: repacking table "public.tbl_with_dropped_column" 19 | INFO: repacking table "public.tbl_with_dropped_toast" 20 | INFO: repacking table "public.tbl_with_mod_column_storage" 21 | INFO: repacking table "public.tbl_with_toast" 22 | -------------------------------------------------------------------------------- /regress/expected/repack-setup.out: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | -- 3 | -- create table. 4 | -- 5 | CREATE TABLE tbl_cluster ( 6 | col1 int, 7 | "time" timestamp, 8 | ","")" text, 9 | PRIMARY KEY (","")", col1) WITH (fillfactor = 75) 10 | ) WITH (fillfactor = 70); 11 | CREATE INDEX ","") cluster" ON tbl_cluster ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor = 75); 12 | ALTER TABLE tbl_cluster CLUSTER ON ","") cluster"; 13 | CREATE TABLE tbl_only_pkey ( 14 | col1 int PRIMARY KEY, 15 | ","")" text 16 | ); 17 | CREATE TABLE tbl_only_ckey ( 18 | col1 int, 19 | col2 timestamp, 20 | ","")" text 21 | ) WITH (fillfactor = 70); 22 | CREATE INDEX cidx_only_ckey ON tbl_only_ckey (col2, ","")"); 23 | ALTER TABLE tbl_only_ckey CLUSTER ON cidx_only_ckey; 24 | CREATE TABLE tbl_incl_pkey ( 25 | col1 int, 26 | col2 timestamp 27 | ); 28 | -- Covering indexes were added only in PostgreSQL 11 29 | ALTER TABLE tbl_incl_pkey ADD PRIMARY KEY (col1) INCLUDE (col2); 30 | CREATE TABLE tbl_gistkey ( 31 | id integer PRIMARY KEY, 32 | c circle 33 | ); 34 | CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c); 35 | ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle; 36 | CREATE TABLE tbl_with_dropped_column ( 37 | d1 text, 38 | c1 text, 39 | id integer PRIMARY KEY, 40 | d2 text, 41 | c2 text, 42 | d3 text 43 | ); 44 | ALTER INDEX tbl_with_dropped_column_pkey SET (fillfactor = 75); 45 | ALTER TABLE tbl_with_dropped_column CLUSTER ON tbl_with_dropped_column_pkey; 46 | CREATE INDEX idx_c1c2 ON tbl_with_dropped_column (c1, c2) WITH (fillfactor = 75); 47 | CREATE INDEX idx_c2c1 ON tbl_with_dropped_column (c2, c1); 48 | CREATE TABLE tbl_with_dropped_toast ( 49 | i integer, 50 | j integer, 51 | t text, 52 | PRIMARY KEY (i, j) 53 | ); 54 | ALTER TABLE tbl_with_dropped_toast CLUSTER ON tbl_with_dropped_toast_pkey; 55 | CREATE TABLE tbl_badindex ( 56 | id integer PRIMARY KEY, 57 | n integer 58 | ); 59 | CREATE TABLE tbl_idxopts ( 60 | i integer PRIMARY KEY, 61 | t text 62 | ); 63 | CREATE INDEX idxopts_t ON tbl_idxopts (t DESC NULLS LAST) WHERE (t != 'aaa'); 64 | -- Use this table to play with attribute options too 65 | ALTER TABLE tbl_idxopts ALTER i SET STATISTICS 1; 66 | ALTER TABLE tbl_idxopts ALTER t SET (n_distinct = -0.5); 67 | CREATE TABLE tbl_with_toast ( 68 | i integer PRIMARY KEY, 69 | c text 70 | ); 71 | ALTER TABLE tbl_with_toast SET (AUTOVACUUM_VACUUM_SCALE_FACTOR = 30, AUTOVACUUM_VACUUM_THRESHOLD = 300); 72 | ALTER TABLE tbl_with_toast SET (TOAST.AUTOVACUUM_VACUUM_SCALE_FACTOR = 40, TOAST.AUTOVACUUM_VACUUM_THRESHOLD = 400); 73 | CREATE TABLE tbl_with_mod_column_storage ( 74 | id integer PRIMARY KEY, 75 | c text 76 | ); 77 | ALTER TABLE tbl_with_mod_column_storage ALTER c SET STORAGE MAIN; 78 | CREATE TABLE tbl_order (c int primary key); 79 | CREATE TABLE tbl_storage_plain (c1 int primary key, c2 text); 80 | ALTER TABLE tbl_storage_plain ALTER COLUMN c1 SET STORAGE PLAIN; 81 | ALTER TABLE tbl_storage_plain ALTER COLUMN c2 SET STORAGE PLAIN; 82 | -- 83 | -- insert data 84 | -- 85 | INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin'); 86 | INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king'); 87 | INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker'); 88 | INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen'); 89 | INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); 90 | INSERT INTO tbl_only_pkey VALUES(1, 'abc'); 91 | INSERT INTO tbl_only_pkey VALUES(2, 'def'); 92 | INSERT INTO tbl_only_ckey VALUES(1, '2008-01-01 00:00:00', 'abc'); 93 | INSERT INTO tbl_only_ckey VALUES(2, '2008-02-01 00:00:00', 'def'); 94 | INSERT INTO tbl_incl_pkey VALUES(1, '2008-01-01 00:00:00'); 95 | INSERT INTO tbl_incl_pkey VALUES(2, '2008-02-01 00:00:00'); 96 | INSERT INTO tbl_gistkey VALUES(1, '<(1,2),3>'); 97 | INSERT INTO tbl_gistkey VALUES(2, '<(4,5),6>'); 98 | INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 2, 'd2', 'c2', 'd3'); 99 | INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 1, 'd2', 'c2', 'd3'); 100 | ALTER TABLE tbl_with_dropped_column DROP COLUMN d1; 101 | ALTER TABLE tbl_with_dropped_column DROP COLUMN d2; 102 | ALTER TABLE tbl_with_dropped_column DROP COLUMN d3; 103 | ALTER TABLE tbl_with_dropped_column ADD COLUMN c3 text; 104 | CREATE VIEW view_for_dropped_column AS 105 | SELECT * FROM tbl_with_dropped_column; 106 | INSERT INTO tbl_with_dropped_toast VALUES(1, 10, 'abc'); 107 | INSERT INTO tbl_with_dropped_toast VALUES(2, 20, sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); 108 | ALTER TABLE tbl_with_dropped_toast DROP COLUMN t; 109 | INSERT INTO tbl_badindex VALUES(1, 10); 110 | INSERT INTO tbl_badindex VALUES(2, 10); 111 | -- insert data that is always stored into the toast table if column type is extended. 112 | SELECT setseed(0); INSERT INTO tbl_with_mod_column_storage SELECT 1, array_to_string(ARRAY(SELECT chr((random() * (127 - 32) + 32)::int) FROM generate_series(1, 3 * 1024) code), ''); 113 | setseed 114 | --------- 115 | 116 | (1 row) 117 | 118 | --- This will fail 119 | \set VERBOSITY terse 120 | CREATE UNIQUE INDEX CONCURRENTLY idx_badindex_n ON tbl_badindex (n); 121 | ERROR: could not create unique index "idx_badindex_n" 122 | INSERT INTO tbl_idxopts VALUES (0, 'abc'), (1, 'aaa'), (2, NULL), (3, 'bbb'); 123 | -- Insert no-ordered data 124 | INSERT INTO tbl_order SELECT generate_series(100, 51, -1); 125 | CLUSTER tbl_order USING tbl_order_pkey; 126 | INSERT INTO tbl_order SELECT generate_series(50, 1, -1); 127 | -- 128 | -- before 129 | -- 130 | SELECT * FROM tbl_with_dropped_column; 131 | c1 | id | c2 | c3 132 | ----+----+----+---- 133 | c1 | 2 | c2 | 134 | c1 | 1 | c2 | 135 | (2 rows) 136 | 137 | SELECT * FROM view_for_dropped_column; 138 | c1 | id | c2 | c3 139 | ----+----+----+---- 140 | c1 | 2 | c2 | 141 | c1 | 1 | c2 | 142 | (2 rows) 143 | 144 | SELECT * FROM tbl_with_dropped_toast; 145 | i | j 146 | ---+---- 147 | 1 | 10 148 | 2 | 20 149 | (2 rows) 150 | 151 | VACUUM FULL tbl_storage_plain; 152 | -------------------------------------------------------------------------------- /regress/expected/repack-setup_1.out: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | -- 3 | -- create table. 4 | -- 5 | CREATE TABLE tbl_cluster ( 6 | col1 int, 7 | "time" timestamp, 8 | ","")" text, 9 | PRIMARY KEY (","")", col1) WITH (fillfactor = 75) 10 | ) WITH (fillfactor = 70); 11 | CREATE INDEX ","") cluster" ON tbl_cluster ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor = 75); 12 | ALTER TABLE tbl_cluster CLUSTER ON ","") cluster"; 13 | CREATE TABLE tbl_only_pkey ( 14 | col1 int PRIMARY KEY, 15 | ","")" text 16 | ); 17 | CREATE TABLE tbl_only_ckey ( 18 | col1 int, 19 | col2 timestamp, 20 | ","")" text 21 | ) WITH (fillfactor = 70); 22 | CREATE INDEX cidx_only_ckey ON tbl_only_ckey (col2, ","")"); 23 | ALTER TABLE tbl_only_ckey CLUSTER ON cidx_only_ckey; 24 | CREATE TABLE tbl_incl_pkey ( 25 | col1 int, 26 | col2 timestamp 27 | ); 28 | -- Covering indexes were added only in PostgreSQL 11 29 | ALTER TABLE tbl_incl_pkey ADD PRIMARY KEY (col1) INCLUDE (col2); 30 | ERROR: syntax error at or near "INCLUDE" 31 | LINE 1: ALTER TABLE tbl_incl_pkey ADD PRIMARY KEY (col1) INCLUDE (co... 32 | ^ 33 | CREATE TABLE tbl_gistkey ( 34 | id integer PRIMARY KEY, 35 | c circle 36 | ); 37 | CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c); 38 | ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle; 39 | CREATE TABLE tbl_with_dropped_column ( 40 | d1 text, 41 | c1 text, 42 | id integer PRIMARY KEY, 43 | d2 text, 44 | c2 text, 45 | d3 text 46 | ); 47 | ALTER INDEX tbl_with_dropped_column_pkey SET (fillfactor = 75); 48 | ALTER TABLE tbl_with_dropped_column CLUSTER ON tbl_with_dropped_column_pkey; 49 | CREATE INDEX idx_c1c2 ON tbl_with_dropped_column (c1, c2) WITH (fillfactor = 75); 50 | CREATE INDEX idx_c2c1 ON tbl_with_dropped_column (c2, c1); 51 | CREATE TABLE tbl_with_dropped_toast ( 52 | i integer, 53 | j integer, 54 | t text, 55 | PRIMARY KEY (i, j) 56 | ); 57 | ALTER TABLE tbl_with_dropped_toast CLUSTER ON tbl_with_dropped_toast_pkey; 58 | CREATE TABLE tbl_badindex ( 59 | id integer PRIMARY KEY, 60 | n integer 61 | ); 62 | CREATE TABLE tbl_idxopts ( 63 | i integer PRIMARY KEY, 64 | t text 65 | ); 66 | CREATE INDEX idxopts_t ON tbl_idxopts (t DESC NULLS LAST) WHERE (t != 'aaa'); 67 | -- Use this table to play with attribute options too 68 | ALTER TABLE tbl_idxopts ALTER i SET STATISTICS 1; 69 | ALTER TABLE tbl_idxopts ALTER t SET (n_distinct = -0.5); 70 | CREATE TABLE tbl_with_toast ( 71 | i integer PRIMARY KEY, 72 | c text 73 | ); 74 | ALTER TABLE tbl_with_toast SET (AUTOVACUUM_VACUUM_SCALE_FACTOR = 30, AUTOVACUUM_VACUUM_THRESHOLD = 300); 75 | ALTER TABLE tbl_with_toast SET (TOAST.AUTOVACUUM_VACUUM_SCALE_FACTOR = 40, TOAST.AUTOVACUUM_VACUUM_THRESHOLD = 400); 76 | CREATE TABLE tbl_with_mod_column_storage ( 77 | id integer PRIMARY KEY, 78 | c text 79 | ); 80 | ALTER TABLE tbl_with_mod_column_storage ALTER c SET STORAGE MAIN; 81 | CREATE TABLE tbl_order (c int primary key); 82 | CREATE TABLE tbl_storage_plain (c1 int primary key, c2 text); 83 | ALTER TABLE tbl_storage_plain ALTER COLUMN c1 SET STORAGE PLAIN; 84 | ALTER TABLE tbl_storage_plain ALTER COLUMN c2 SET STORAGE PLAIN; 85 | -- 86 | -- insert data 87 | -- 88 | INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin'); 89 | INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king'); 90 | INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker'); 91 | INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen'); 92 | INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); 93 | INSERT INTO tbl_only_pkey VALUES(1, 'abc'); 94 | INSERT INTO tbl_only_pkey VALUES(2, 'def'); 95 | INSERT INTO tbl_only_ckey VALUES(1, '2008-01-01 00:00:00', 'abc'); 96 | INSERT INTO tbl_only_ckey VALUES(2, '2008-02-01 00:00:00', 'def'); 97 | INSERT INTO tbl_incl_pkey VALUES(1, '2008-01-01 00:00:00'); 98 | INSERT INTO tbl_incl_pkey VALUES(2, '2008-02-01 00:00:00'); 99 | INSERT INTO tbl_gistkey VALUES(1, '<(1,2),3>'); 100 | INSERT INTO tbl_gistkey VALUES(2, '<(4,5),6>'); 101 | INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 2, 'd2', 'c2', 'd3'); 102 | INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 1, 'd2', 'c2', 'd3'); 103 | ALTER TABLE tbl_with_dropped_column DROP COLUMN d1; 104 | ALTER TABLE tbl_with_dropped_column DROP COLUMN d2; 105 | ALTER TABLE tbl_with_dropped_column DROP COLUMN d3; 106 | ALTER TABLE tbl_with_dropped_column ADD COLUMN c3 text; 107 | CREATE VIEW view_for_dropped_column AS 108 | SELECT * FROM tbl_with_dropped_column; 109 | INSERT INTO tbl_with_dropped_toast VALUES(1, 10, 'abc'); 110 | INSERT INTO tbl_with_dropped_toast VALUES(2, 20, sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); 111 | ALTER TABLE tbl_with_dropped_toast DROP COLUMN t; 112 | INSERT INTO tbl_badindex VALUES(1, 10); 113 | INSERT INTO tbl_badindex VALUES(2, 10); 114 | -- insert data that is always stored into the toast table if column type is extended. 115 | SELECT setseed(0); INSERT INTO tbl_with_mod_column_storage SELECT 1, array_to_string(ARRAY(SELECT chr((random() * (127 - 32) + 32)::int) FROM generate_series(1, 3 * 1024) code), ''); 116 | setseed 117 | --------- 118 | 119 | (1 row) 120 | 121 | --- This will fail 122 | \set VERBOSITY terse 123 | CREATE UNIQUE INDEX CONCURRENTLY idx_badindex_n ON tbl_badindex (n); 124 | ERROR: could not create unique index "idx_badindex_n" 125 | INSERT INTO tbl_idxopts VALUES (0, 'abc'), (1, 'aaa'), (2, NULL), (3, 'bbb'); 126 | -- Insert no-ordered data 127 | INSERT INTO tbl_order SELECT generate_series(100, 51, -1); 128 | CLUSTER tbl_order USING tbl_order_pkey; 129 | INSERT INTO tbl_order SELECT generate_series(50, 1, -1); 130 | -- 131 | -- before 132 | -- 133 | SELECT * FROM tbl_with_dropped_column; 134 | c1 | id | c2 | c3 135 | ----+----+----+---- 136 | c1 | 2 | c2 | 137 | c1 | 1 | c2 | 138 | (2 rows) 139 | 140 | SELECT * FROM view_for_dropped_column; 141 | c1 | id | c2 | c3 142 | ----+----+----+---- 143 | c1 | 2 | c2 | 144 | c1 | 1 | c2 | 145 | (2 rows) 146 | 147 | SELECT * FROM tbl_with_dropped_toast; 148 | i | j 149 | ---+---- 150 | 1 | 10 151 | 2 | 20 152 | (2 rows) 153 | 154 | VACUUM FULL tbl_storage_plain; 155 | -------------------------------------------------------------------------------- /regress/expected/tablespace.out: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | -- 3 | -- Tablespace features tests 4 | -- 5 | -- Note: in order to pass this test you must create a tablespace called 'testts' 6 | -- 7 | SELECT spcname FROM pg_tablespace WHERE spcname = 'testts'; 8 | spcname 9 | --------- 10 | testts 11 | (1 row) 12 | 13 | -- If the query above failed you must create the 'testts' tablespace; 14 | CREATE TABLE testts1 (id serial primary key, data text); 15 | CREATE INDEX testts1_partial_idx on testts1 (id) where (id > 0); 16 | CREATE INDEX testts1_with_idx on testts1 (id) with (fillfactor=80); 17 | INSERT INTO testts1 (data) values ('a'); 18 | INSERT INTO testts1 (data) values ('b'); 19 | INSERT INTO testts1 (data) values ('c'); 20 | -- check the indexes definitions 21 | SELECT regexp_replace( 22 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, false), 23 | '_[0-9]+', '_OID', 'g') 24 | FROM pg_index i join pg_class c ON c.oid = indexrelid 25 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 26 | regexp_replace 27 | ---------------------------------------------------------------------------------------------------------- 28 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE pg_default WHERE (id > 0) 29 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE pg_default 30 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE pg_default 31 | (3 rows) 32 | 33 | SELECT regexp_replace( 34 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', false), 35 | '_[0-9]+', '_OID', 'g') 36 | FROM pg_index i join pg_class c ON c.oid = indexrelid 37 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 38 | regexp_replace 39 | --------------------------------------------------------------------------------------------------- 40 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo WHERE (id > 0) 41 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo 42 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE foo 43 | (3 rows) 44 | 45 | SELECT regexp_replace( 46 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, true), 47 | '_[0-9]+', '_OID', 'g') 48 | FROM pg_index i join pg_class c ON c.oid = indexrelid 49 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 50 | regexp_replace 51 | -------------------------------------------------------------------------------------------------------------- 52 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) TABLESPACE pg_default WHERE (id > 0) 53 | CREATE UNIQUE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) TABLESPACE pg_default 54 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WITH (fillfactor='80') TABLESPACE pg_default 55 | (3 rows) 56 | 57 | SELECT regexp_replace( 58 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', true), 59 | '_[0-9]+', '_OID', 'g') 60 | FROM pg_index i join pg_class c ON c.oid = indexrelid 61 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 62 | regexp_replace 63 | ------------------------------------------------------------------------------------------------------- 64 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) TABLESPACE foo WHERE (id > 0) 65 | CREATE UNIQUE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) TABLESPACE foo 66 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WITH (fillfactor='80') TABLESPACE foo 67 | (3 rows) 68 | 69 | -- Test that a tablespace is quoted as an identifier 70 | SELECT regexp_replace( 71 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo bar', false), 72 | '_[0-9]+', '_OID', 'g') 73 | FROM pg_index i join pg_class c ON c.oid = indexrelid 74 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 75 | regexp_replace 76 | --------------------------------------------------------------------------------------------------------- 77 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE "foo bar" WHERE (id > 0) 78 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE "foo bar" 79 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE "foo bar" 80 | (3 rows) 81 | 82 | -- can move the tablespace from default 83 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts 84 | INFO: repacking table "public.testts1" 85 | SELECT relname, spcname 86 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 87 | WHERE relname ~ '^testts1' 88 | ORDER BY relname; 89 | relname | spcname 90 | ---------+--------- 91 | testts1 | testts 92 | (1 row) 93 | 94 | SELECT * from testts1 order by id; 95 | id | data 96 | ----+------ 97 | 1 | a 98 | 2 | b 99 | 3 | c 100 | (3 rows) 101 | 102 | -- tablespace stays where it is 103 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 104 | INFO: repacking table "public.testts1" 105 | SELECT relname, spcname 106 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 107 | WHERE relname ~ '^testts1' 108 | ORDER BY relname; 109 | relname | spcname 110 | ---------+--------- 111 | testts1 | testts 112 | (1 row) 113 | 114 | -- can move the ts back to default 115 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -s pg_default 116 | INFO: repacking table "public.testts1" 117 | SELECT relname, spcname 118 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 119 | WHERE relname ~ '^testts1' 120 | ORDER BY relname; 121 | relname | spcname 122 | ---------+--------- 123 | (0 rows) 124 | 125 | -- can move the table together with the indexes 126 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts --moveidx 127 | INFO: repacking table "public.testts1" 128 | SELECT relname, spcname 129 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 130 | WHERE relname ~ '^testts1' 131 | ORDER BY relname; 132 | relname | spcname 133 | ---------------------+--------- 134 | testts1 | testts 135 | testts1_partial_idx | testts 136 | testts1_pkey | testts 137 | testts1_with_idx | testts 138 | (4 rows) 139 | 140 | -- can't specify --moveidx without --tablespace 141 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --moveidx 142 | ERROR: cannot specify --moveidx (-S) without --tablespace (-s) 143 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -S 144 | ERROR: cannot specify --moveidx (-S) without --tablespace (-s) 145 | -- not broken with order 146 | \! pg_repack --dbname=contrib_regression -o id --table=testts1 --tablespace pg_default --moveidx 147 | INFO: repacking table "public.testts1" 148 | --move all indexes of the table to a tablespace 149 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=testts 150 | INFO: repacking indexes of "testts1" 151 | INFO: repacking index "public.testts1_partial_idx" 152 | INFO: repacking index "public.testts1_pkey" 153 | INFO: repacking index "public.testts1_with_idx" 154 | SELECT relname, spcname 155 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 156 | WHERE relname ~ '^testts1' 157 | ORDER BY relname; 158 | relname | spcname 159 | ---------------------+--------- 160 | testts1_partial_idx | testts 161 | testts1_pkey | testts 162 | testts1_with_idx | testts 163 | (3 rows) 164 | 165 | --all indexes of tablespace remain in same tablespace 166 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes 167 | INFO: repacking indexes of "testts1" 168 | INFO: repacking index "public.testts1_partial_idx" 169 | INFO: repacking index "public.testts1_pkey" 170 | INFO: repacking index "public.testts1_with_idx" 171 | SELECT relname, spcname 172 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 173 | WHERE relname ~ '^testts1' 174 | ORDER BY relname; 175 | relname | spcname 176 | ---------------------+--------- 177 | testts1_partial_idx | testts 178 | testts1_pkey | testts 179 | testts1_with_idx | testts 180 | (3 rows) 181 | 182 | --move all indexes of the table to pg_default 183 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=pg_default 184 | INFO: repacking indexes of "testts1" 185 | INFO: repacking index "public.testts1_partial_idx" 186 | INFO: repacking index "public.testts1_pkey" 187 | INFO: repacking index "public.testts1_with_idx" 188 | SELECT relname, spcname 189 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 190 | WHERE relname ~ '^testts1' 191 | ORDER BY relname; 192 | relname | spcname 193 | ---------+--------- 194 | (0 rows) 195 | 196 | --move one index to a tablespace 197 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=testts 198 | INFO: repacking index "public.testts1_pkey" 199 | SELECT relname, spcname 200 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 201 | WHERE relname ~ '^testts1' 202 | ORDER BY relname; 203 | relname | spcname 204 | --------------+--------- 205 | testts1_pkey | testts 206 | (1 row) 207 | 208 | --index tablespace stays as is 209 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey 210 | INFO: repacking index "public.testts1_pkey" 211 | SELECT relname, spcname 212 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 213 | WHERE relname ~ '^testts1' 214 | ORDER BY relname; 215 | relname | spcname 216 | --------------+--------- 217 | testts1_pkey | testts 218 | (1 row) 219 | 220 | --move index to pg_default 221 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=pg_default 222 | INFO: repacking index "public.testts1_pkey" 223 | SELECT relname, spcname 224 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 225 | WHERE relname ~ '^testts1' 226 | ORDER BY relname; 227 | relname | spcname 228 | ---------+--------- 229 | (0 rows) 230 | 231 | --using multiple --index option 232 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --index=testts1_with_idx --tablespace=testts 233 | INFO: repacking index "public.testts1_pkey" 234 | INFO: repacking index "public.testts1_with_idx" 235 | SELECT relname, spcname 236 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 237 | WHERE relname ~ '^testts1' 238 | ORDER BY relname; 239 | relname | spcname 240 | ------------------+--------- 241 | testts1_pkey | testts 242 | testts1_with_idx | testts 243 | (2 rows) 244 | 245 | --using --indexes-only and --index option together 246 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --index=testts1_pkey 247 | ERROR: cannot specify --index (-i) and --table (-t) 248 | --check quote_ident() with 1testts tablespace 249 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace=1testts --moveidx 250 | INFO: repacking table "public.testts1" 251 | SELECT relname, spcname 252 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 253 | WHERE relname ~ '^testts1' 254 | ORDER BY relname; 255 | relname | spcname 256 | ---------------------+--------- 257 | testts1 | 1testts 258 | testts1_partial_idx | 1testts 259 | testts1_pkey | 1testts 260 | testts1_with_idx | 1testts 261 | (4 rows) 262 | 263 | --check quote_ident() with "test ts" tablespace 264 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test ts" --moveidx 265 | INFO: repacking table "public.testts1" 266 | SELECT relname, spcname 267 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 268 | WHERE relname ~ '^testts1' 269 | ORDER BY relname; 270 | relname | spcname 271 | ---------------------+--------- 272 | testts1 | test ts 273 | testts1_partial_idx | test ts 274 | testts1_pkey | test ts 275 | testts1_with_idx | test ts 276 | (4 rows) 277 | 278 | --check quote_ident() with "test""ts" tablespace 279 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test\"ts" --moveidx 280 | INFO: repacking table "public.testts1" 281 | SELECT relname, spcname 282 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 283 | WHERE relname ~ '^testts1' 284 | ORDER BY relname; 285 | relname | spcname 286 | ---------------------+--------- 287 | testts1 | test"ts 288 | testts1_partial_idx | test"ts 289 | testts1_pkey | test"ts 290 | testts1_with_idx | test"ts 291 | (4 rows) 292 | 293 | -------------------------------------------------------------------------------- /regress/expected/tablespace_1.out: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | -- 3 | -- Tablespace features tests 4 | -- 5 | -- Note: in order to pass this test you must create a tablespace called 'testts' 6 | -- 7 | SELECT spcname FROM pg_tablespace WHERE spcname = 'testts'; 8 | spcname 9 | --------- 10 | testts 11 | (1 row) 12 | 13 | -- If the query above failed you must create the 'testts' tablespace; 14 | CREATE TABLE testts1 (id serial primary key, data text); 15 | CREATE INDEX testts1_partial_idx on testts1 (id) where (id > 0); 16 | CREATE INDEX testts1_with_idx on testts1 (id) with (fillfactor=80); 17 | INSERT INTO testts1 (data) values ('a'); 18 | INSERT INTO testts1 (data) values ('b'); 19 | INSERT INTO testts1 (data) values ('c'); 20 | -- check the indexes definitions 21 | SELECT regexp_replace( 22 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, false), 23 | '_[0-9]+', '_OID', 'g') 24 | FROM pg_index i join pg_class c ON c.oid = indexrelid 25 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 26 | regexp_replace 27 | ------------------------------------------------------------------------------------ 28 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WHERE (id > 0) 29 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) 30 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') 31 | (3 rows) 32 | 33 | SELECT regexp_replace( 34 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', false), 35 | '_[0-9]+', '_OID', 'g') 36 | FROM pg_index i join pg_class c ON c.oid = indexrelid 37 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 38 | regexp_replace 39 | --------------------------------------------------------------------------------------------------- 40 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo WHERE (id > 0) 41 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo 42 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE foo 43 | (3 rows) 44 | 45 | SELECT regexp_replace( 46 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, true), 47 | '_[0-9]+', '_OID', 'g') 48 | FROM pg_index i join pg_class c ON c.oid = indexrelid 49 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 50 | regexp_replace 51 | ---------------------------------------------------------------------------------------- 52 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WHERE (id > 0) 53 | CREATE UNIQUE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) 54 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WITH (fillfactor='80') 55 | (3 rows) 56 | 57 | SELECT regexp_replace( 58 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', true), 59 | '_[0-9]+', '_OID', 'g') 60 | FROM pg_index i join pg_class c ON c.oid = indexrelid 61 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 62 | regexp_replace 63 | ------------------------------------------------------------------------------------------------------- 64 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) TABLESPACE foo WHERE (id > 0) 65 | CREATE UNIQUE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) TABLESPACE foo 66 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WITH (fillfactor='80') TABLESPACE foo 67 | (3 rows) 68 | 69 | -- Test that a tablespace is quoted as an identifier 70 | SELECT regexp_replace( 71 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo bar', false), 72 | '_[0-9]+', '_OID', 'g') 73 | FROM pg_index i join pg_class c ON c.oid = indexrelid 74 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 75 | regexp_replace 76 | --------------------------------------------------------------------------------------------------------- 77 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE "foo bar" WHERE (id > 0) 78 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE "foo bar" 79 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE "foo bar" 80 | (3 rows) 81 | 82 | -- can move the tablespace from default 83 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts 84 | INFO: repacking table "public.testts1" 85 | SELECT relname, spcname 86 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 87 | WHERE relname ~ '^testts1' 88 | ORDER BY relname; 89 | relname | spcname 90 | ---------+--------- 91 | testts1 | testts 92 | (1 row) 93 | 94 | SELECT * from testts1 order by id; 95 | id | data 96 | ----+------ 97 | 1 | a 98 | 2 | b 99 | 3 | c 100 | (3 rows) 101 | 102 | -- tablespace stays where it is 103 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 104 | INFO: repacking table "public.testts1" 105 | SELECT relname, spcname 106 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 107 | WHERE relname ~ '^testts1' 108 | ORDER BY relname; 109 | relname | spcname 110 | ---------+--------- 111 | testts1 | testts 112 | (1 row) 113 | 114 | -- can move the ts back to default 115 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -s pg_default 116 | INFO: repacking table "public.testts1" 117 | SELECT relname, spcname 118 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 119 | WHERE relname ~ '^testts1' 120 | ORDER BY relname; 121 | relname | spcname 122 | ---------+--------- 123 | (0 rows) 124 | 125 | -- can move the table together with the indexes 126 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts --moveidx 127 | INFO: repacking table "public.testts1" 128 | SELECT relname, spcname 129 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 130 | WHERE relname ~ '^testts1' 131 | ORDER BY relname; 132 | relname | spcname 133 | ---------------------+--------- 134 | testts1 | testts 135 | testts1_partial_idx | testts 136 | testts1_pkey | testts 137 | testts1_with_idx | testts 138 | (4 rows) 139 | 140 | -- can't specify --moveidx without --tablespace 141 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --moveidx 142 | ERROR: cannot specify --moveidx (-S) without --tablespace (-s) 143 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -S 144 | ERROR: cannot specify --moveidx (-S) without --tablespace (-s) 145 | -- not broken with order 146 | \! pg_repack --dbname=contrib_regression -o id --table=testts1 --tablespace pg_default --moveidx 147 | INFO: repacking table "public.testts1" 148 | --move all indexes of the table to a tablespace 149 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=testts 150 | INFO: repacking indexes of "testts1" 151 | INFO: repacking index "public.testts1_partial_idx" 152 | INFO: repacking index "public.testts1_pkey" 153 | INFO: repacking index "public.testts1_with_idx" 154 | SELECT relname, spcname 155 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 156 | WHERE relname ~ '^testts1' 157 | ORDER BY relname; 158 | relname | spcname 159 | ---------------------+--------- 160 | testts1_partial_idx | testts 161 | testts1_pkey | testts 162 | testts1_with_idx | testts 163 | (3 rows) 164 | 165 | --all indexes of tablespace remain in same tablespace 166 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes 167 | INFO: repacking indexes of "testts1" 168 | INFO: repacking index "public.testts1_partial_idx" 169 | INFO: repacking index "public.testts1_pkey" 170 | INFO: repacking index "public.testts1_with_idx" 171 | SELECT relname, spcname 172 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 173 | WHERE relname ~ '^testts1' 174 | ORDER BY relname; 175 | relname | spcname 176 | ---------------------+--------- 177 | testts1_partial_idx | testts 178 | testts1_pkey | testts 179 | testts1_with_idx | testts 180 | (3 rows) 181 | 182 | --move all indexes of the table to pg_default 183 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=pg_default 184 | INFO: repacking indexes of "testts1" 185 | INFO: repacking index "public.testts1_partial_idx" 186 | INFO: repacking index "public.testts1_pkey" 187 | INFO: repacking index "public.testts1_with_idx" 188 | SELECT relname, spcname 189 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 190 | WHERE relname ~ '^testts1' 191 | ORDER BY relname; 192 | relname | spcname 193 | ---------+--------- 194 | (0 rows) 195 | 196 | --move one index to a tablespace 197 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=testts 198 | INFO: repacking index "public.testts1_pkey" 199 | SELECT relname, spcname 200 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 201 | WHERE relname ~ '^testts1' 202 | ORDER BY relname; 203 | relname | spcname 204 | --------------+--------- 205 | testts1_pkey | testts 206 | (1 row) 207 | 208 | --index tablespace stays as is 209 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey 210 | INFO: repacking index "public.testts1_pkey" 211 | SELECT relname, spcname 212 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 213 | WHERE relname ~ '^testts1' 214 | ORDER BY relname; 215 | relname | spcname 216 | --------------+--------- 217 | testts1_pkey | testts 218 | (1 row) 219 | 220 | --move index to pg_default 221 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=pg_default 222 | INFO: repacking index "public.testts1_pkey" 223 | SELECT relname, spcname 224 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 225 | WHERE relname ~ '^testts1' 226 | ORDER BY relname; 227 | relname | spcname 228 | ---------+--------- 229 | (0 rows) 230 | 231 | --using multiple --index option 232 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --index=testts1_with_idx --tablespace=testts 233 | INFO: repacking index "public.testts1_pkey" 234 | INFO: repacking index "public.testts1_with_idx" 235 | SELECT relname, spcname 236 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 237 | WHERE relname ~ '^testts1' 238 | ORDER BY relname; 239 | relname | spcname 240 | ------------------+--------- 241 | testts1_pkey | testts 242 | testts1_with_idx | testts 243 | (2 rows) 244 | 245 | --using --indexes-only and --index option together 246 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --index=testts1_pkey 247 | ERROR: cannot specify --index (-i) and --table (-t) 248 | --check quote_ident() with 1testts tablespace 249 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace=1testts --moveidx 250 | INFO: repacking table "public.testts1" 251 | SELECT relname, spcname 252 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 253 | WHERE relname ~ '^testts1' 254 | ORDER BY relname; 255 | relname | spcname 256 | ---------------------+--------- 257 | testts1 | 1testts 258 | testts1_partial_idx | 1testts 259 | testts1_pkey | 1testts 260 | testts1_with_idx | 1testts 261 | (4 rows) 262 | 263 | --check quote_ident() with "test ts" tablespace 264 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test ts" --moveidx 265 | INFO: repacking table "public.testts1" 266 | SELECT relname, spcname 267 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 268 | WHERE relname ~ '^testts1' 269 | ORDER BY relname; 270 | relname | spcname 271 | ---------------------+--------- 272 | testts1 | test ts 273 | testts1_partial_idx | test ts 274 | testts1_pkey | test ts 275 | testts1_with_idx | test ts 276 | (4 rows) 277 | 278 | --check quote_ident() with "test""ts" tablespace 279 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test\"ts" --moveidx 280 | INFO: repacking table "public.testts1" 281 | SELECT relname, spcname 282 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 283 | WHERE relname ~ '^testts1' 284 | ORDER BY relname; 285 | relname | spcname 286 | ---------------------+--------- 287 | testts1 | test"ts 288 | testts1_partial_idx | test"ts 289 | testts1_pkey | test"ts 290 | testts1_with_idx | test"ts 291 | (4 rows) 292 | 293 | -------------------------------------------------------------------------------- /regress/expected/tablespace_2.out: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | -- 3 | -- Tablespace features tests 4 | -- 5 | -- Note: in order to pass this test you must create a tablespace called 'testts' 6 | -- 7 | SELECT spcname FROM pg_tablespace WHERE spcname = 'testts'; 8 | spcname 9 | --------- 10 | testts 11 | (1 row) 12 | 13 | -- If the query above failed you must create the 'testts' tablespace; 14 | CREATE TABLE testts1 (id serial primary key, data text); 15 | CREATE INDEX testts1_partial_idx on testts1 (id) where (id > 0); 16 | CREATE INDEX testts1_with_idx on testts1 (id) with (fillfactor=80); 17 | INSERT INTO testts1 (data) values ('a'); 18 | INSERT INTO testts1 (data) values ('b'); 19 | INSERT INTO testts1 (data) values ('c'); 20 | -- check the indexes definitions 21 | SELECT regexp_replace( 22 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, false), 23 | '_[0-9]+', '_OID', 'g') 24 | FROM pg_index i join pg_class c ON c.oid = indexrelid 25 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 26 | regexp_replace 27 | ---------------------------------------------------------------------------------------------------------- 28 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE pg_default WHERE (id > 0) 29 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE pg_default 30 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE pg_default 31 | (3 rows) 32 | 33 | SELECT regexp_replace( 34 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', false), 35 | '_[0-9]+', '_OID', 'g') 36 | FROM pg_index i join pg_class c ON c.oid = indexrelid 37 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 38 | regexp_replace 39 | --------------------------------------------------------------------------------------------------- 40 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo WHERE (id > 0) 41 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo 42 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE foo 43 | (3 rows) 44 | 45 | SELECT regexp_replace( 46 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, true), 47 | '_[0-9]+', '_OID', 'g') 48 | FROM pg_index i join pg_class c ON c.oid = indexrelid 49 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 50 | regexp_replace 51 | --------------------------------------------------------------------------------------------------------------------- 52 | CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) TABLESPACE pg_default WHERE (id > 0) 53 | CREATE UNIQUE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) TABLESPACE pg_default 54 | CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) WITH (fillfactor='80') TABLESPACE pg_default 55 | (3 rows) 56 | 57 | SELECT regexp_replace( 58 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', true), 59 | '_[0-9]+', '_OID', 'g') 60 | FROM pg_index i join pg_class c ON c.oid = indexrelid 61 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 62 | regexp_replace 63 | -------------------------------------------------------------------------------------------------------------- 64 | CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) TABLESPACE foo WHERE (id > 0) 65 | CREATE UNIQUE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) TABLESPACE foo 66 | CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) WITH (fillfactor='80') TABLESPACE foo 67 | (3 rows) 68 | 69 | -- Test that a tablespace is quoted as an identifier 70 | SELECT regexp_replace( 71 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo bar', false), 72 | '_[0-9]+', '_OID', 'g') 73 | FROM pg_index i join pg_class c ON c.oid = indexrelid 74 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 75 | regexp_replace 76 | --------------------------------------------------------------------------------------------------------- 77 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE "foo bar" WHERE (id > 0) 78 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE "foo bar" 79 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE "foo bar" 80 | (3 rows) 81 | 82 | -- can move the tablespace from default 83 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts 84 | INFO: repacking table "public.testts1" 85 | SELECT relname, spcname 86 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 87 | WHERE relname ~ '^testts1' 88 | ORDER BY relname; 89 | relname | spcname 90 | ---------+--------- 91 | testts1 | testts 92 | (1 row) 93 | 94 | SELECT * from testts1 order by id; 95 | id | data 96 | ----+------ 97 | 1 | a 98 | 2 | b 99 | 3 | c 100 | (3 rows) 101 | 102 | -- tablespace stays where it is 103 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 104 | INFO: repacking table "public.testts1" 105 | SELECT relname, spcname 106 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 107 | WHERE relname ~ '^testts1' 108 | ORDER BY relname; 109 | relname | spcname 110 | ---------+--------- 111 | testts1 | testts 112 | (1 row) 113 | 114 | -- can move the ts back to default 115 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -s pg_default 116 | INFO: repacking table "public.testts1" 117 | SELECT relname, spcname 118 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 119 | WHERE relname ~ '^testts1' 120 | ORDER BY relname; 121 | relname | spcname 122 | ---------+--------- 123 | (0 rows) 124 | 125 | -- can move the table together with the indexes 126 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts --moveidx 127 | INFO: repacking table "public.testts1" 128 | SELECT relname, spcname 129 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 130 | WHERE relname ~ '^testts1' 131 | ORDER BY relname; 132 | relname | spcname 133 | ---------------------+--------- 134 | testts1 | testts 135 | testts1_partial_idx | testts 136 | testts1_pkey | testts 137 | testts1_with_idx | testts 138 | (4 rows) 139 | 140 | -- can't specify --moveidx without --tablespace 141 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --moveidx 142 | ERROR: cannot specify --moveidx (-S) without --tablespace (-s) 143 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -S 144 | ERROR: cannot specify --moveidx (-S) without --tablespace (-s) 145 | -- not broken with order 146 | \! pg_repack --dbname=contrib_regression -o id --table=testts1 --tablespace pg_default --moveidx 147 | INFO: repacking table "public.testts1" 148 | --move all indexes of the table to a tablespace 149 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=testts 150 | INFO: repacking indexes of "testts1" 151 | INFO: repacking index "public.testts1_partial_idx" 152 | INFO: repacking index "public.testts1_pkey" 153 | INFO: repacking index "public.testts1_with_idx" 154 | SELECT relname, spcname 155 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 156 | WHERE relname ~ '^testts1' 157 | ORDER BY relname; 158 | relname | spcname 159 | ---------------------+--------- 160 | testts1_partial_idx | testts 161 | testts1_pkey | testts 162 | testts1_with_idx | testts 163 | (3 rows) 164 | 165 | --all indexes of tablespace remain in same tablespace 166 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes 167 | INFO: repacking indexes of "testts1" 168 | INFO: repacking index "public.testts1_partial_idx" 169 | INFO: repacking index "public.testts1_pkey" 170 | INFO: repacking index "public.testts1_with_idx" 171 | SELECT relname, spcname 172 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 173 | WHERE relname ~ '^testts1' 174 | ORDER BY relname; 175 | relname | spcname 176 | ---------------------+--------- 177 | testts1_partial_idx | testts 178 | testts1_pkey | testts 179 | testts1_with_idx | testts 180 | (3 rows) 181 | 182 | --move all indexes of the table to pg_default 183 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=pg_default 184 | INFO: repacking indexes of "testts1" 185 | INFO: repacking index "public.testts1_partial_idx" 186 | INFO: repacking index "public.testts1_pkey" 187 | INFO: repacking index "public.testts1_with_idx" 188 | SELECT relname, spcname 189 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 190 | WHERE relname ~ '^testts1' 191 | ORDER BY relname; 192 | relname | spcname 193 | ---------+--------- 194 | (0 rows) 195 | 196 | --move one index to a tablespace 197 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=testts 198 | INFO: repacking index "public.testts1_pkey" 199 | SELECT relname, spcname 200 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 201 | WHERE relname ~ '^testts1' 202 | ORDER BY relname; 203 | relname | spcname 204 | --------------+--------- 205 | testts1_pkey | testts 206 | (1 row) 207 | 208 | --index tablespace stays as is 209 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey 210 | INFO: repacking index "public.testts1_pkey" 211 | SELECT relname, spcname 212 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 213 | WHERE relname ~ '^testts1' 214 | ORDER BY relname; 215 | relname | spcname 216 | --------------+--------- 217 | testts1_pkey | testts 218 | (1 row) 219 | 220 | --move index to pg_default 221 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=pg_default 222 | INFO: repacking index "public.testts1_pkey" 223 | SELECT relname, spcname 224 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 225 | WHERE relname ~ '^testts1' 226 | ORDER BY relname; 227 | relname | spcname 228 | ---------+--------- 229 | (0 rows) 230 | 231 | --using multiple --index option 232 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --index=testts1_with_idx --tablespace=testts 233 | INFO: repacking index "public.testts1_pkey" 234 | INFO: repacking index "public.testts1_with_idx" 235 | SELECT relname, spcname 236 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 237 | WHERE relname ~ '^testts1' 238 | ORDER BY relname; 239 | relname | spcname 240 | ------------------+--------- 241 | testts1_pkey | testts 242 | testts1_with_idx | testts 243 | (2 rows) 244 | 245 | --using --indexes-only and --index option together 246 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --index=testts1_pkey 247 | ERROR: cannot specify --index (-i) and --table (-t) 248 | --check quote_ident() with 1testts tablespace 249 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace=1testts --moveidx 250 | INFO: repacking table "public.testts1" 251 | SELECT relname, spcname 252 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 253 | WHERE relname ~ '^testts1' 254 | ORDER BY relname; 255 | relname | spcname 256 | ---------------------+--------- 257 | testts1 | 1testts 258 | testts1_partial_idx | 1testts 259 | testts1_pkey | 1testts 260 | testts1_with_idx | 1testts 261 | (4 rows) 262 | 263 | --check quote_ident() with "test ts" tablespace 264 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test ts" --moveidx 265 | INFO: repacking table "public.testts1" 266 | SELECT relname, spcname 267 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 268 | WHERE relname ~ '^testts1' 269 | ORDER BY relname; 270 | relname | spcname 271 | ---------------------+--------- 272 | testts1 | test ts 273 | testts1_partial_idx | test ts 274 | testts1_pkey | test ts 275 | testts1_with_idx | test ts 276 | (4 rows) 277 | 278 | --check quote_ident() with "test""ts" tablespace 279 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test\"ts" --moveidx 280 | INFO: repacking table "public.testts1" 281 | SELECT relname, spcname 282 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 283 | WHERE relname ~ '^testts1' 284 | ORDER BY relname; 285 | relname | spcname 286 | ---------------------+--------- 287 | testts1 | test"ts 288 | testts1_partial_idx | test"ts 289 | testts1_pkey | test"ts 290 | testts1_with_idx | test"ts 291 | (4 rows) 292 | 293 | -------------------------------------------------------------------------------- /regress/expected/tablespace_3.out: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | -- 3 | -- Tablespace features tests 4 | -- 5 | -- Note: in order to pass this test you must create a tablespace called 'testts' 6 | -- 7 | SELECT spcname FROM pg_tablespace WHERE spcname = 'testts'; 8 | spcname 9 | --------- 10 | testts 11 | (1 row) 12 | 13 | -- If the query above failed you must create the 'testts' tablespace; 14 | CREATE TABLE testts1 (id serial primary key, data text); 15 | CREATE INDEX testts1_partial_idx on testts1 (id) where (id > 0); 16 | CREATE INDEX testts1_with_idx on testts1 (id) with (fillfactor=80); 17 | INSERT INTO testts1 (data) values ('a'); 18 | INSERT INTO testts1 (data) values ('b'); 19 | INSERT INTO testts1 (data) values ('c'); 20 | -- check the indexes definitions 21 | SELECT regexp_replace( 22 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, false), 23 | '_[0-9]+', '_OID', 'g') 24 | FROM pg_index i join pg_class c ON c.oid = indexrelid 25 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 26 | regexp_replace 27 | ---------------------------------------------------------------------------------- 28 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WHERE (id > 0) 29 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) 30 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor=80) 31 | (3 rows) 32 | 33 | SELECT regexp_replace( 34 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', false), 35 | '_[0-9]+', '_OID', 'g') 36 | FROM pg_index i join pg_class c ON c.oid = indexrelid 37 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 38 | regexp_replace 39 | ------------------------------------------------------------------------------------------------- 40 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo WHERE (id > 0) 41 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo 42 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor=80) TABLESPACE foo 43 | (3 rows) 44 | 45 | SELECT regexp_replace( 46 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, true), 47 | '_[0-9]+', '_OID', 'g') 48 | FROM pg_index i join pg_class c ON c.oid = indexrelid 49 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 50 | regexp_replace 51 | -------------------------------------------------------------------------------------- 52 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WHERE (id > 0) 53 | CREATE UNIQUE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) 54 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WITH (fillfactor=80) 55 | (3 rows) 56 | 57 | SELECT regexp_replace( 58 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', true), 59 | '_[0-9]+', '_OID', 'g') 60 | FROM pg_index i join pg_class c ON c.oid = indexrelid 61 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 62 | regexp_replace 63 | ----------------------------------------------------------------------------------------------------- 64 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) TABLESPACE foo WHERE (id > 0) 65 | CREATE UNIQUE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) TABLESPACE foo 66 | CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WITH (fillfactor=80) TABLESPACE foo 67 | (3 rows) 68 | 69 | -- Test that a tablespace is quoted as an identifier 70 | SELECT regexp_replace( 71 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo bar', false), 72 | '_[0-9]+', '_OID', 'g') 73 | FROM pg_index i join pg_class c ON c.oid = indexrelid 74 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 75 | regexp_replace 76 | --------------------------------------------------------------------------------------------------------- 77 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE "foo bar" WHERE (id > 0) 78 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE "foo bar" 79 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE "foo bar" 80 | (3 rows) 81 | 82 | -- can move the tablespace from default 83 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts 84 | INFO: repacking table "public.testts1" 85 | SELECT relname, spcname 86 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 87 | WHERE relname ~ '^testts1' 88 | ORDER BY relname; 89 | relname | spcname 90 | ---------+--------- 91 | testts1 | testts 92 | (1 row) 93 | 94 | SELECT * from testts1 order by id; 95 | id | data 96 | ----+------ 97 | 1 | a 98 | 2 | b 99 | 3 | c 100 | (3 rows) 101 | 102 | -- tablespace stays where it is 103 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 104 | INFO: repacking table "public.testts1" 105 | SELECT relname, spcname 106 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 107 | WHERE relname ~ '^testts1' 108 | ORDER BY relname; 109 | relname | spcname 110 | ---------+--------- 111 | testts1 | testts 112 | (1 row) 113 | 114 | -- can move the ts back to default 115 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -s pg_default 116 | INFO: repacking table "public.testts1" 117 | SELECT relname, spcname 118 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 119 | WHERE relname ~ '^testts1' 120 | ORDER BY relname; 121 | relname | spcname 122 | ---------+--------- 123 | (0 rows) 124 | 125 | -- can move the table together with the indexes 126 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts --moveidx 127 | INFO: repacking table "public.testts1" 128 | SELECT relname, spcname 129 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 130 | WHERE relname ~ '^testts1' 131 | ORDER BY relname; 132 | relname | spcname 133 | ---------------------+--------- 134 | testts1 | testts 135 | testts1_partial_idx | testts 136 | testts1_pkey | testts 137 | testts1_with_idx | testts 138 | (4 rows) 139 | 140 | -- can't specify --moveidx without --tablespace 141 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --moveidx 142 | ERROR: cannot specify --moveidx (-S) without --tablespace (-s) 143 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -S 144 | ERROR: cannot specify --moveidx (-S) without --tablespace (-s) 145 | -- not broken with order 146 | \! pg_repack --dbname=contrib_regression -o id --table=testts1 --tablespace pg_default --moveidx 147 | INFO: repacking table "public.testts1" 148 | --move all indexes of the table to a tablespace 149 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=testts 150 | INFO: repacking indexes of "testts1" 151 | INFO: repacking index "public.testts1_partial_idx" 152 | INFO: repacking index "public.testts1_pkey" 153 | INFO: repacking index "public.testts1_with_idx" 154 | SELECT relname, spcname 155 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 156 | WHERE relname ~ '^testts1' 157 | ORDER BY relname; 158 | relname | spcname 159 | ---------------------+--------- 160 | testts1_partial_idx | testts 161 | testts1_pkey | testts 162 | testts1_with_idx | testts 163 | (3 rows) 164 | 165 | --all indexes of tablespace remain in same tablespace 166 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes 167 | INFO: repacking indexes of "testts1" 168 | INFO: repacking index "public.testts1_partial_idx" 169 | INFO: repacking index "public.testts1_pkey" 170 | INFO: repacking index "public.testts1_with_idx" 171 | SELECT relname, spcname 172 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 173 | WHERE relname ~ '^testts1' 174 | ORDER BY relname; 175 | relname | spcname 176 | ---------------------+--------- 177 | testts1_partial_idx | testts 178 | testts1_pkey | testts 179 | testts1_with_idx | testts 180 | (3 rows) 181 | 182 | --move all indexes of the table to pg_default 183 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=pg_default 184 | INFO: repacking indexes of "testts1" 185 | INFO: repacking index "public.testts1_partial_idx" 186 | INFO: repacking index "public.testts1_pkey" 187 | INFO: repacking index "public.testts1_with_idx" 188 | SELECT relname, spcname 189 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 190 | WHERE relname ~ '^testts1' 191 | ORDER BY relname; 192 | relname | spcname 193 | ---------+--------- 194 | (0 rows) 195 | 196 | --move one index to a tablespace 197 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=testts 198 | INFO: repacking index "public.testts1_pkey" 199 | SELECT relname, spcname 200 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 201 | WHERE relname ~ '^testts1' 202 | ORDER BY relname; 203 | relname | spcname 204 | --------------+--------- 205 | testts1_pkey | testts 206 | (1 row) 207 | 208 | --index tablespace stays as is 209 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey 210 | INFO: repacking index "public.testts1_pkey" 211 | SELECT relname, spcname 212 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 213 | WHERE relname ~ '^testts1' 214 | ORDER BY relname; 215 | relname | spcname 216 | --------------+--------- 217 | testts1_pkey | testts 218 | (1 row) 219 | 220 | --move index to pg_default 221 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=pg_default 222 | INFO: repacking index "public.testts1_pkey" 223 | SELECT relname, spcname 224 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 225 | WHERE relname ~ '^testts1' 226 | ORDER BY relname; 227 | relname | spcname 228 | ---------+--------- 229 | (0 rows) 230 | 231 | --using multiple --index option 232 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --index=testts1_with_idx --tablespace=testts 233 | INFO: repacking index "public.testts1_pkey" 234 | INFO: repacking index "public.testts1_with_idx" 235 | SELECT relname, spcname 236 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 237 | WHERE relname ~ '^testts1' 238 | ORDER BY relname; 239 | relname | spcname 240 | ------------------+--------- 241 | testts1_pkey | testts 242 | testts1_with_idx | testts 243 | (2 rows) 244 | 245 | --using --indexes-only and --index option together 246 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --index=testts1_pkey 247 | ERROR: cannot specify --index (-i) and --table (-t) 248 | --check quote_ident() with 1testts tablespace 249 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace=1testts --moveidx 250 | INFO: repacking table "public.testts1" 251 | SELECT relname, spcname 252 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 253 | WHERE relname ~ '^testts1' 254 | ORDER BY relname; 255 | relname | spcname 256 | ---------------------+--------- 257 | testts1 | 1testts 258 | testts1_partial_idx | 1testts 259 | testts1_pkey | 1testts 260 | testts1_with_idx | 1testts 261 | (4 rows) 262 | 263 | --check quote_ident() with "test ts" tablespace 264 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test ts" --moveidx 265 | INFO: repacking table "public.testts1" 266 | SELECT relname, spcname 267 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 268 | WHERE relname ~ '^testts1' 269 | ORDER BY relname; 270 | relname | spcname 271 | ---------------------+--------- 272 | testts1 | test ts 273 | testts1_partial_idx | test ts 274 | testts1_pkey | test ts 275 | testts1_with_idx | test ts 276 | (4 rows) 277 | 278 | --check quote_ident() with "test""ts" tablespace 279 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test\"ts" --moveidx 280 | INFO: repacking table "public.testts1" 281 | SELECT relname, spcname 282 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 283 | WHERE relname ~ '^testts1' 284 | ORDER BY relname; 285 | relname | spcname 286 | ---------------------+--------- 287 | testts1 | test"ts 288 | testts1_partial_idx | test"ts 289 | testts1_pkey | test"ts 290 | testts1_with_idx | test"ts 291 | (4 rows) 292 | 293 | -------------------------------------------------------------------------------- /regress/expected/tablespace_4.out: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | -- 3 | -- Tablespace features tests 4 | -- 5 | -- Note: in order to pass this test you must create a tablespace called 'testts' 6 | -- 7 | SELECT spcname FROM pg_tablespace WHERE spcname = 'testts'; 8 | spcname 9 | --------- 10 | testts 11 | (1 row) 12 | 13 | -- If the query above failed you must create the 'testts' tablespace; 14 | CREATE TABLE testts1 (id serial primary key, data text); 15 | CREATE INDEX testts1_partial_idx on testts1 (id) where (id > 0); 16 | CREATE INDEX testts1_with_idx on testts1 (id) with (fillfactor=80); 17 | INSERT INTO testts1 (data) values ('a'); 18 | INSERT INTO testts1 (data) values ('b'); 19 | INSERT INTO testts1 (data) values ('c'); 20 | -- check the indexes definitions 21 | SELECT regexp_replace( 22 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, false), 23 | '_[0-9]+', '_OID', 'g') 24 | FROM pg_index i join pg_class c ON c.oid = indexrelid 25 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 26 | regexp_replace 27 | ------------------------------------------------------------------------------------ 28 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WHERE (id > 0) 29 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) 30 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') 31 | (3 rows) 32 | 33 | SELECT regexp_replace( 34 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', false), 35 | '_[0-9]+', '_OID', 'g') 36 | FROM pg_index i join pg_class c ON c.oid = indexrelid 37 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 38 | regexp_replace 39 | --------------------------------------------------------------------------------------------------- 40 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo WHERE (id > 0) 41 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo 42 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE foo 43 | (3 rows) 44 | 45 | SELECT regexp_replace( 46 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, true), 47 | '_[0-9]+', '_OID', 'g') 48 | FROM pg_index i join pg_class c ON c.oid = indexrelid 49 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 50 | regexp_replace 51 | ----------------------------------------------------------------------------------------------- 52 | CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) WHERE (id > 0) 53 | CREATE UNIQUE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) 54 | CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) WITH (fillfactor='80') 55 | (3 rows) 56 | 57 | SELECT regexp_replace( 58 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', true), 59 | '_[0-9]+', '_OID', 'g') 60 | FROM pg_index i join pg_class c ON c.oid = indexrelid 61 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 62 | regexp_replace 63 | -------------------------------------------------------------------------------------------------------------- 64 | CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) TABLESPACE foo WHERE (id > 0) 65 | CREATE UNIQUE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) TABLESPACE foo 66 | CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) WITH (fillfactor='80') TABLESPACE foo 67 | (3 rows) 68 | 69 | -- Test that a tablespace is quoted as an identifier 70 | SELECT regexp_replace( 71 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo bar', false), 72 | '_[0-9]+', '_OID', 'g') 73 | FROM pg_index i join pg_class c ON c.oid = indexrelid 74 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 75 | regexp_replace 76 | --------------------------------------------------------------------------------------------------------- 77 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE "foo bar" WHERE (id > 0) 78 | CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE "foo bar" 79 | CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE "foo bar" 80 | (3 rows) 81 | 82 | -- can move the tablespace from default 83 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts 84 | INFO: repacking table "public.testts1" 85 | SELECT relname, spcname 86 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 87 | WHERE relname ~ '^testts1' 88 | ORDER BY relname; 89 | relname | spcname 90 | ---------+--------- 91 | testts1 | testts 92 | (1 row) 93 | 94 | SELECT * from testts1 order by id; 95 | id | data 96 | ----+------ 97 | 1 | a 98 | 2 | b 99 | 3 | c 100 | (3 rows) 101 | 102 | -- tablespace stays where it is 103 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 104 | INFO: repacking table "public.testts1" 105 | SELECT relname, spcname 106 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 107 | WHERE relname ~ '^testts1' 108 | ORDER BY relname; 109 | relname | spcname 110 | ---------+--------- 111 | testts1 | testts 112 | (1 row) 113 | 114 | -- can move the ts back to default 115 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -s pg_default 116 | INFO: repacking table "public.testts1" 117 | SELECT relname, spcname 118 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 119 | WHERE relname ~ '^testts1' 120 | ORDER BY relname; 121 | relname | spcname 122 | ---------+--------- 123 | (0 rows) 124 | 125 | -- can move the table together with the indexes 126 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts --moveidx 127 | INFO: repacking table "public.testts1" 128 | SELECT relname, spcname 129 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 130 | WHERE relname ~ '^testts1' 131 | ORDER BY relname; 132 | relname | spcname 133 | ---------------------+--------- 134 | testts1 | testts 135 | testts1_partial_idx | testts 136 | testts1_pkey | testts 137 | testts1_with_idx | testts 138 | (4 rows) 139 | 140 | -- can't specify --moveidx without --tablespace 141 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --moveidx 142 | ERROR: cannot specify --moveidx (-S) without --tablespace (-s) 143 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -S 144 | ERROR: cannot specify --moveidx (-S) without --tablespace (-s) 145 | -- not broken with order 146 | \! pg_repack --dbname=contrib_regression -o id --table=testts1 --tablespace pg_default --moveidx 147 | INFO: repacking table "public.testts1" 148 | --move all indexes of the table to a tablespace 149 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=testts 150 | INFO: repacking indexes of "testts1" 151 | INFO: repacking index "public.testts1_partial_idx" 152 | INFO: repacking index "public.testts1_pkey" 153 | INFO: repacking index "public.testts1_with_idx" 154 | SELECT relname, spcname 155 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 156 | WHERE relname ~ '^testts1' 157 | ORDER BY relname; 158 | relname | spcname 159 | ---------------------+--------- 160 | testts1_partial_idx | testts 161 | testts1_pkey | testts 162 | testts1_with_idx | testts 163 | (3 rows) 164 | 165 | --all indexes of tablespace remain in same tablespace 166 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes 167 | INFO: repacking indexes of "testts1" 168 | INFO: repacking index "public.testts1_partial_idx" 169 | INFO: repacking index "public.testts1_pkey" 170 | INFO: repacking index "public.testts1_with_idx" 171 | SELECT relname, spcname 172 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 173 | WHERE relname ~ '^testts1' 174 | ORDER BY relname; 175 | relname | spcname 176 | ---------------------+--------- 177 | testts1_partial_idx | testts 178 | testts1_pkey | testts 179 | testts1_with_idx | testts 180 | (3 rows) 181 | 182 | --move all indexes of the table to pg_default 183 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=pg_default 184 | INFO: repacking indexes of "testts1" 185 | INFO: repacking index "public.testts1_partial_idx" 186 | INFO: repacking index "public.testts1_pkey" 187 | INFO: repacking index "public.testts1_with_idx" 188 | SELECT relname, spcname 189 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 190 | WHERE relname ~ '^testts1' 191 | ORDER BY relname; 192 | relname | spcname 193 | ---------+--------- 194 | (0 rows) 195 | 196 | --move one index to a tablespace 197 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=testts 198 | INFO: repacking index "public.testts1_pkey" 199 | SELECT relname, spcname 200 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 201 | WHERE relname ~ '^testts1' 202 | ORDER BY relname; 203 | relname | spcname 204 | --------------+--------- 205 | testts1_pkey | testts 206 | (1 row) 207 | 208 | --index tablespace stays as is 209 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey 210 | INFO: repacking index "public.testts1_pkey" 211 | SELECT relname, spcname 212 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 213 | WHERE relname ~ '^testts1' 214 | ORDER BY relname; 215 | relname | spcname 216 | --------------+--------- 217 | testts1_pkey | testts 218 | (1 row) 219 | 220 | --move index to pg_default 221 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=pg_default 222 | INFO: repacking index "public.testts1_pkey" 223 | SELECT relname, spcname 224 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 225 | WHERE relname ~ '^testts1' 226 | ORDER BY relname; 227 | relname | spcname 228 | ---------+--------- 229 | (0 rows) 230 | 231 | --using multiple --index option 232 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --index=testts1_with_idx --tablespace=testts 233 | INFO: repacking index "public.testts1_pkey" 234 | INFO: repacking index "public.testts1_with_idx" 235 | SELECT relname, spcname 236 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 237 | WHERE relname ~ '^testts1' 238 | ORDER BY relname; 239 | relname | spcname 240 | ------------------+--------- 241 | testts1_pkey | testts 242 | testts1_with_idx | testts 243 | (2 rows) 244 | 245 | --using --indexes-only and --index option together 246 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --index=testts1_pkey 247 | ERROR: cannot specify --index (-i) and --table (-t) 248 | --check quote_ident() with 1testts tablespace 249 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace=1testts --moveidx 250 | INFO: repacking table "public.testts1" 251 | SELECT relname, spcname 252 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 253 | WHERE relname ~ '^testts1' 254 | ORDER BY relname; 255 | relname | spcname 256 | ---------------------+--------- 257 | testts1 | 1testts 258 | testts1_partial_idx | 1testts 259 | testts1_pkey | 1testts 260 | testts1_with_idx | 1testts 261 | (4 rows) 262 | 263 | --check quote_ident() with "test ts" tablespace 264 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test ts" --moveidx 265 | INFO: repacking table "public.testts1" 266 | SELECT relname, spcname 267 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 268 | WHERE relname ~ '^testts1' 269 | ORDER BY relname; 270 | relname | spcname 271 | ---------------------+--------- 272 | testts1 | test ts 273 | testts1_partial_idx | test ts 274 | testts1_pkey | test ts 275 | testts1_with_idx | test ts 276 | (4 rows) 277 | 278 | --check quote_ident() with "test""ts" tablespace 279 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test\"ts" --moveidx 280 | INFO: repacking table "public.testts1" 281 | SELECT relname, spcname 282 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 283 | WHERE relname ~ '^testts1' 284 | ORDER BY relname; 285 | relname | spcname 286 | ---------------------+--------- 287 | testts1 | test"ts 288 | testts1_partial_idx | test"ts 289 | testts1_pkey | test"ts 290 | testts1_with_idx | test"ts 291 | (4 rows) 292 | 293 | -------------------------------------------------------------------------------- /regress/expected/trigger.out: -------------------------------------------------------------------------------- 1 | -- 2 | -- repack.repack_trigger tests 3 | -- 4 | CREATE TABLE trigger_t1 (a int, b int, primary key (a, b)); 5 | CREATE INDEX trigger_t1_idx ON trigger_t1 (a, b); 6 | SELECT create_trigger FROM repack.tables WHERE relname = 'public.trigger_t1'; 7 | create_trigger 8 | ---------------------------------------------------------------------------------------------------------------------------------------------------- 9 | CREATE TRIGGER repack_trigger AFTER INSERT OR DELETE OR UPDATE ON public.trigger_t1 FOR EACH ROW EXECUTE PROCEDURE repack.repack_trigger('a', 'b') 10 | (1 row) 11 | 12 | SELECT oid AS t1_oid FROM pg_catalog.pg_class WHERE relname = 'trigger_t1' 13 | \gset 14 | CREATE TYPE repack.pk_:t1_oid AS (a integer, b integer); 15 | CREATE TABLE repack.log_:t1_oid (id bigserial PRIMARY KEY, pk repack.pk_:t1_oid, row public.trigger_t1); 16 | CREATE TRIGGER repack_trigger AFTER INSERT OR DELETE OR UPDATE ON trigger_t1 17 | FOR EACH ROW EXECUTE PROCEDURE repack.repack_trigger('a', 'b'); 18 | INSERT INTO trigger_t1 VALUES (111, 222); 19 | UPDATE trigger_t1 SET a=333, b=444 WHERE a = 111; 20 | DELETE FROM trigger_t1 WHERE a = 333; 21 | SELECT * FROM repack.log_:t1_oid; 22 | id | pk | row 23 | ----+-----------+----------- 24 | 1 | | (111,222) 25 | 2 | (111,222) | (333,444) 26 | 3 | (333,444) | 27 | (3 rows) 28 | 29 | -------------------------------------------------------------------------------- /regress/sql/after-schema.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- tables schema after running repack 3 | -- 4 | 5 | \d tbl_cluster 6 | \d tbl_gistkey 7 | \d tbl_only_ckey 8 | \d tbl_only_pkey 9 | \d tbl_incl_pkey 10 | \d tbl_with_dropped_column 11 | \d tbl_with_dropped_toast 12 | \d tbl_idxopts 13 | -------------------------------------------------------------------------------- /regress/sql/error-on-invalid-idx.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- do repack 3 | -- 4 | 5 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --error-on-invalid-index 6 | \! pg_repack --dbname=contrib_regression --table=tbl_badindex --error-on-invalid-index 7 | \! pg_repack --dbname=contrib_regression --error-on-invalid-index 8 | -------------------------------------------------------------------------------- /regress/sql/get_order_by.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- pg_repack issue #3 3 | -- 4 | CREATE TABLE issue3_1 (col1 int NOT NULL, col2 text NOT NULL); 5 | CREATE UNIQUE INDEX issue3_1_idx ON issue3_1 (col1, col2 DESC); 6 | SELECT repack.get_order_by('issue3_1_idx'::regclass::oid, 'issue3_1'::regclass::oid); 7 | \! pg_repack --dbname=contrib_regression --table=issue3_1 8 | 9 | CREATE TABLE issue3_2 (col1 int NOT NULL, col2 text NOT NULL); 10 | CREATE UNIQUE INDEX issue3_2_idx ON issue3_2 (col1 DESC, col2 text_pattern_ops); 11 | SELECT repack.get_order_by('issue3_2_idx'::regclass::oid, 'issue3_2'::regclass::oid); 12 | \! pg_repack --dbname=contrib_regression --table=issue3_2 13 | 14 | CREATE TABLE issue3_3 (col1 int NOT NULL, col2 text NOT NULL); 15 | CREATE UNIQUE INDEX issue3_3_idx ON issue3_3 (col1 DESC, col2 DESC); 16 | SELECT repack.get_order_by('issue3_3_idx'::regclass::oid, 'issue3_3'::regclass::oid); 17 | \! pg_repack --dbname=contrib_regression --table=issue3_3 18 | 19 | CREATE TABLE issue3_4 (col1 int NOT NULL, col2 text NOT NULL); 20 | CREATE UNIQUE INDEX issue3_4_idx ON issue3_4 (col1 NULLS FIRST, col2 text_pattern_ops DESC NULLS LAST); 21 | SELECT repack.get_order_by('issue3_4_idx'::regclass::oid, 'issue3_4'::regclass::oid); 22 | \! pg_repack --dbname=contrib_regression --table=issue3_4 23 | 24 | CREATE TABLE issue3_5 (col1 int NOT NULL, col2 text NOT NULL); 25 | CREATE UNIQUE INDEX issue3_5_idx ON issue3_5 (col1 DESC NULLS FIRST, col2 COLLATE "POSIX" DESC); 26 | SELECT repack.get_order_by('issue3_5_idx'::regclass::oid, 'issue3_5'::regclass::oid); 27 | \! pg_repack --dbname=contrib_regression --table=issue3_5 28 | 29 | -- 30 | -- pg_repack issue #321 31 | -- 32 | CREATE TABLE issue321 (col1 int NOT NULL, col2 text NOT NULL); 33 | CREATE UNIQUE INDEX issue321_idx ON issue321 (col1); 34 | SELECT repack.get_order_by('issue321_idx'::regclass::oid, 1); 35 | SELECT repack.get_order_by(1, 1); 36 | -------------------------------------------------------------------------------- /regress/sql/init-extension.sql: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | CREATE EXTENSION pg_repack; 3 | RESET client_min_messages; 4 | -------------------------------------------------------------------------------- /regress/sql/no-error-on-invalid-idx.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- do repack 3 | -- 4 | 5 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-error-on-invalid-index 6 | \! pg_repack --dbname=contrib_regression --table=tbl_badindex --no-error-on-invalid-index 7 | \! pg_repack --dbname=contrib_regression --no-error-on-invalid-index 8 | -------------------------------------------------------------------------------- /regress/sql/nosuper.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- no superuser check 3 | -- 4 | SET client_min_messages = error; 5 | DROP ROLE IF EXISTS nosuper; 6 | SET client_min_messages = warning; 7 | CREATE ROLE nosuper WITH LOGIN; 8 | -- => OK 9 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-superuser-check 10 | -- => ERROR 11 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper 12 | -- => ERROR 13 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check 14 | 15 | GRANT ALL ON ALL TABLES IN SCHEMA repack TO nosuper; 16 | GRANT USAGE ON SCHEMA repack TO nosuper; 17 | 18 | -- => ERROR 19 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check 20 | 21 | REVOKE ALL ON ALL TABLES IN SCHEMA repack FROM nosuper; 22 | REVOKE USAGE ON SCHEMA repack FROM nosuper; 23 | DROP ROLE IF EXISTS nosuper; 24 | -------------------------------------------------------------------------------- /regress/sql/repack-check.sql: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | 3 | SELECT col1, to_char("time", 'YYYY-MM-DD HH24:MI:SS'), ","")" FROM tbl_cluster ORDER BY 1, 2; 4 | SELECT * FROM tbl_only_ckey ORDER BY 1; 5 | SELECT * FROM tbl_only_pkey ORDER BY 1; 6 | SELECT * FROM tbl_incl_pkey ORDER BY 1; 7 | SELECT * FROM tbl_gistkey ORDER BY 1; 8 | 9 | SET enable_seqscan = on; 10 | SET enable_indexscan = off; 11 | SELECT * FROM tbl_with_dropped_column ; 12 | SELECT * FROM view_for_dropped_column ORDER BY 1, 2; 13 | SELECT * FROM tbl_with_dropped_toast; 14 | SET enable_seqscan = off; 15 | SET enable_indexscan = on; 16 | SELECT * FROM tbl_with_dropped_column ORDER BY 1, 2; 17 | SELECT * FROM view_for_dropped_column; 18 | SELECT * FROM tbl_with_dropped_toast; 19 | RESET enable_seqscan; 20 | RESET enable_indexscan; 21 | -- check if storage option for both table and TOAST table didn't go away. 22 | SELECT CASE relkind 23 | WHEN 'r' THEN relname 24 | WHEN 't' THEN 'toast_table' 25 | END as table, 26 | reloptions 27 | FROM pg_class 28 | WHERE relname = 'tbl_with_toast' OR relname = 'pg_toast_' || 'tbl_with_toast'::regclass::oid 29 | ORDER BY 1; 30 | SELECT pg_relation_size(reltoastrelid) = 0 as check_toast_rel_size FROM pg_class WHERE relname = 'tbl_with_mod_column_storage'; 31 | 32 | -- 33 | -- check broken links or orphan toast relations 34 | -- 35 | SELECT oid, relname 36 | FROM pg_class 37 | WHERE relkind = 't' 38 | AND oid NOT IN (SELECT reltoastrelid FROM pg_class WHERE relkind = 'r'); 39 | 40 | SELECT oid, relname 41 | FROM pg_class 42 | WHERE relkind = 'r' 43 | AND reltoastrelid <> 0 44 | AND reltoastrelid NOT IN (SELECT oid FROM pg_class WHERE relkind = 't'); 45 | 46 | -- check columns options 47 | SELECT attname, nullif(attstattarget, -1) as attstattarget, attoptions 48 | FROM pg_attribute 49 | WHERE attrelid = 'tbl_idxopts'::regclass 50 | AND attnum > 0 51 | ORDER BY attnum; 52 | 53 | -- 54 | -- NOT NULL UNIQUE 55 | -- 56 | CREATE TABLE tbl_nn (col1 int NOT NULL, col2 int NOT NULL); 57 | CREATE TABLE tbl_uk (col1 int NOT NULL, col2 int , UNIQUE(col1, col2)); 58 | CREATE TABLE tbl_nn_uk (col1 int NOT NULL, col2 int NOT NULL, UNIQUE(col1, col2)); 59 | CREATE TABLE tbl_pk_uk (col1 int NOT NULL, col2 int NOT NULL, PRIMARY KEY(col1, col2), UNIQUE(col2, col1)); 60 | CREATE TABLE tbl_nn_puk (col1 int NOT NULL, col2 int NOT NULL); 61 | CREATE UNIQUE INDEX tbl_nn_puk_pcol1_idx ON tbl_nn_puk(col1) WHERE col1 < 10; 62 | \! pg_repack --dbname=contrib_regression --table=tbl_nn 63 | -- => WARNING 64 | \! pg_repack --dbname=contrib_regression --table=tbl_uk 65 | -- => WARNING 66 | \! pg_repack --dbname=contrib_regression --table=tbl_nn_uk 67 | -- => OK 68 | \! pg_repack --dbname=contrib_regression --table=tbl_pk_uk 69 | -- => OK 70 | \! pg_repack --dbname=contrib_regression --table=tbl_pk_uk --only-indexes 71 | -- => OK 72 | \! pg_repack --dbname=contrib_regression --table=tbl_nn_puk 73 | -- => WARNING 74 | 75 | -- 76 | -- Triggers handling 77 | -- 78 | CREATE FUNCTION trgtest() RETURNS trigger AS 79 | $$BEGIN RETURN NEW; END$$ 80 | LANGUAGE plpgsql; 81 | CREATE TABLE trg1 (id integer PRIMARY KEY); 82 | CREATE TRIGGER repack_trigger_1 AFTER UPDATE ON trg1 FOR EACH ROW EXECUTE PROCEDURE trgtest(); 83 | \! pg_repack --dbname=contrib_regression --table=trg1 84 | CREATE TABLE trg2 (id integer PRIMARY KEY); 85 | CREATE TRIGGER repack_trigger AFTER UPDATE ON trg2 FOR EACH ROW EXECUTE PROCEDURE trgtest(); 86 | \! pg_repack --dbname=contrib_regression --table=trg2 87 | CREATE TABLE trg3 (id integer PRIMARY KEY); 88 | CREATE TRIGGER repack_trigger_1 BEFORE UPDATE ON trg3 FOR EACH ROW EXECUTE PROCEDURE trgtest(); 89 | \! pg_repack --dbname=contrib_regression --table=trg3 90 | 91 | -- 92 | -- Table re-organization using specific column 93 | -- 94 | 95 | -- reorganize table using cluster key. Sort in ascending order. 96 | \! pg_repack --dbname=contrib_regression --table=tbl_order 97 | SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; 98 | 99 | -- reorganize table using specific column order. Sort in descending order. 100 | \! pg_repack --dbname=contrib_regression --table=tbl_order -o "c DESC" 101 | SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; 102 | 103 | 104 | -- 105 | -- Dry run 106 | -- 107 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --dry-run 108 | 109 | -- Test --schema 110 | -- 111 | CREATE SCHEMA test_schema1; 112 | CREATE TABLE test_schema1.tbl1 (id INTEGER PRIMARY KEY); 113 | CREATE TABLE test_schema1.tbl2 (id INTEGER PRIMARY KEY); 114 | CREATE SCHEMA test_schema2; 115 | CREATE TABLE test_schema2.tbl1 (id INTEGER PRIMARY KEY); 116 | CREATE TABLE test_schema2.tbl2 (id INTEGER PRIMARY KEY); 117 | -- => OK 118 | \! pg_repack --dbname=contrib_regression --schema=test_schema1 119 | -- => OK 120 | \! pg_repack --dbname=contrib_regression --schema=test_schema1 --schema=test_schema2 121 | -- => ERROR 122 | \! pg_repack --dbname=contrib_regression --schema=test_schema1 --table=tbl1 123 | -- => ERROR 124 | \! pg_repack --dbname=contrib_regression --all --schema=test_schema1 125 | 126 | -- 127 | -- don't kill backend 128 | -- 129 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-kill-backend 130 | 131 | -- 132 | -- exclude extension check 133 | -- 134 | CREATE SCHEMA exclude_extension_schema; 135 | CREATE TABLE exclude_extension_schema.tbl(val integer primary key); 136 | -- => ERROR 137 | \! pg_repack --dbname=contrib_regression --table=dummy_table --exclude-extension=dummy_extension 138 | -- => ERROR 139 | \! pg_repack --dbname=contrib_regression --table=dummy_table --exclude-extension=dummy_extension -x 140 | -- => ERROR 141 | \! pg_repack --dbname=contrib_regression --index=dummy_index --exclude-extension=dummy_extension 142 | -- => OK 143 | \! pg_repack --dbname=contrib_regression --schema=exclude_extension_schema --exclude-extension=dummy_extension 144 | -- => OK 145 | \! pg_repack --dbname=contrib_regression --schema=exclude_extension_schema --exclude-extension=dummy_extension --exclude-extension=dummy_extension 146 | 147 | -- 148 | -- table inheritance check 149 | -- 150 | CREATE TABLE parent_a(val integer primary key); 151 | CREATE TABLE child_a_1(val integer primary key) INHERITS(parent_a); 152 | CREATE TABLE child_a_2(val integer primary key) INHERITS(parent_a); 153 | CREATE TABLE parent_b(val integer primary key); 154 | CREATE TABLE child_b_1(val integer primary key) INHERITS(parent_b); 155 | CREATE TABLE child_b_2(val integer primary key) INHERITS(parent_b); 156 | -- => ERROR 157 | \! pg_repack --dbname=contrib_regression --parent-table=dummy_table 158 | -- => ERROR 159 | \! pg_repack --dbname=contrib_regression --parent-table=dummy_index --index=dummy_index 160 | -- => ERROR 161 | \! pg_repack --dbname=contrib_regression --parent-table=dummy_table --schema=dummy_schema 162 | -- => ERROR 163 | \! pg_repack --dbname=contrib_regression --parent-table=dummy_table --all 164 | -- => OK 165 | \! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b 166 | -- => OK 167 | \! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b 168 | -- => OK 169 | \! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b --only-indexes 170 | -- => OK 171 | \! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b --only-indexes 172 | 173 | -- 174 | -- Apply count 175 | -- 176 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --apply-count 1234 177 | -- 178 | -- Switch threshold 179 | -- 180 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster --switch-threshold 200 181 | 182 | -- 183 | -- partitioned table check 184 | -- 185 | CREATE TABLE partitioned_a(val integer NOT NULL) PARTITION BY RANGE (val); 186 | CREATE TABLE partition_a_1 PARTITION OF partitioned_a FOR VALUES FROM (0) TO (1000); 187 | CREATE TABLE partition_a_2 PARTITION OF partitioned_a FOR VALUES FROM (1000) TO (2000); 188 | -- Create indexes separately to support Postgres 10 which doesn't support 189 | -- indexes on a partitioned table itself 190 | CREATE UNIQUE INDEX partition_a_1_val_idx ON partition_a_1 (val); 191 | CREATE UNIQUE INDEX partition_a_2_val_idx ON partition_a_2 (val); 192 | -- These statements will fail on Postgres 10 193 | CREATE UNIQUE INDEX partitioned_a_val_idx ON ONLY partitioned_a (val); 194 | ALTER INDEX partitioned_a_val_idx ATTACH PARTITION partition_a_1_val_idx; 195 | ALTER INDEX partitioned_a_val_idx ATTACH PARTITION partition_a_2_val_idx; 196 | -- => OK 197 | \! pg_repack --dbname=contrib_regression --parent-table=partitioned_a 198 | -- => OK 199 | \! pg_repack --dbname=contrib_regression --parent-table=partitioned_a --only-indexes 200 | -- => OK 201 | \! pg_repack --dbname=contrib_regression --parent-table=partitioned_a --parent-table=parent_a 202 | -- => OK 203 | \! pg_repack --dbname=contrib_regression --parent-table=partitioned_a --parent-table=parent_a --only-indexes 204 | -------------------------------------------------------------------------------- /regress/sql/repack-run.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- do repack 3 | -- 4 | 5 | \! pg_repack --dbname=contrib_regression --table=tbl_cluster 6 | \! pg_repack --dbname=contrib_regression --table=tbl_badindex 7 | \! pg_repack --dbname=contrib_regression 8 | -------------------------------------------------------------------------------- /regress/sql/repack-setup.sql: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | 3 | -- 4 | -- create table. 5 | -- 6 | 7 | CREATE TABLE tbl_cluster ( 8 | col1 int, 9 | "time" timestamp, 10 | ","")" text, 11 | PRIMARY KEY (","")", col1) WITH (fillfactor = 75) 12 | ) WITH (fillfactor = 70); 13 | 14 | CREATE INDEX ","") cluster" ON tbl_cluster ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor = 75); 15 | ALTER TABLE tbl_cluster CLUSTER ON ","") cluster"; 16 | 17 | CREATE TABLE tbl_only_pkey ( 18 | col1 int PRIMARY KEY, 19 | ","")" text 20 | ); 21 | 22 | CREATE TABLE tbl_only_ckey ( 23 | col1 int, 24 | col2 timestamp, 25 | ","")" text 26 | ) WITH (fillfactor = 70); 27 | 28 | CREATE INDEX cidx_only_ckey ON tbl_only_ckey (col2, ","")"); 29 | ALTER TABLE tbl_only_ckey CLUSTER ON cidx_only_ckey; 30 | 31 | CREATE TABLE tbl_incl_pkey ( 32 | col1 int, 33 | col2 timestamp 34 | ); 35 | 36 | -- Covering indexes were added only in PostgreSQL 11 37 | ALTER TABLE tbl_incl_pkey ADD PRIMARY KEY (col1) INCLUDE (col2); 38 | 39 | CREATE TABLE tbl_gistkey ( 40 | id integer PRIMARY KEY, 41 | c circle 42 | ); 43 | 44 | CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c); 45 | ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle; 46 | 47 | CREATE TABLE tbl_with_dropped_column ( 48 | d1 text, 49 | c1 text, 50 | id integer PRIMARY KEY, 51 | d2 text, 52 | c2 text, 53 | d3 text 54 | ); 55 | ALTER INDEX tbl_with_dropped_column_pkey SET (fillfactor = 75); 56 | ALTER TABLE tbl_with_dropped_column CLUSTER ON tbl_with_dropped_column_pkey; 57 | CREATE INDEX idx_c1c2 ON tbl_with_dropped_column (c1, c2) WITH (fillfactor = 75); 58 | CREATE INDEX idx_c2c1 ON tbl_with_dropped_column (c2, c1); 59 | 60 | CREATE TABLE tbl_with_dropped_toast ( 61 | i integer, 62 | j integer, 63 | t text, 64 | PRIMARY KEY (i, j) 65 | ); 66 | ALTER TABLE tbl_with_dropped_toast CLUSTER ON tbl_with_dropped_toast_pkey; 67 | 68 | CREATE TABLE tbl_badindex ( 69 | id integer PRIMARY KEY, 70 | n integer 71 | ); 72 | 73 | CREATE TABLE tbl_idxopts ( 74 | i integer PRIMARY KEY, 75 | t text 76 | ); 77 | CREATE INDEX idxopts_t ON tbl_idxopts (t DESC NULLS LAST) WHERE (t != 'aaa'); 78 | 79 | -- Use this table to play with attribute options too 80 | ALTER TABLE tbl_idxopts ALTER i SET STATISTICS 1; 81 | ALTER TABLE tbl_idxopts ALTER t SET (n_distinct = -0.5); 82 | CREATE TABLE tbl_with_toast ( 83 | i integer PRIMARY KEY, 84 | c text 85 | ); 86 | ALTER TABLE tbl_with_toast SET (AUTOVACUUM_VACUUM_SCALE_FACTOR = 30, AUTOVACUUM_VACUUM_THRESHOLD = 300); 87 | ALTER TABLE tbl_with_toast SET (TOAST.AUTOVACUUM_VACUUM_SCALE_FACTOR = 40, TOAST.AUTOVACUUM_VACUUM_THRESHOLD = 400); 88 | CREATE TABLE tbl_with_mod_column_storage ( 89 | id integer PRIMARY KEY, 90 | c text 91 | ); 92 | ALTER TABLE tbl_with_mod_column_storage ALTER c SET STORAGE MAIN; 93 | 94 | CREATE TABLE tbl_order (c int primary key); 95 | 96 | CREATE TABLE tbl_storage_plain (c1 int primary key, c2 text); 97 | ALTER TABLE tbl_storage_plain ALTER COLUMN c1 SET STORAGE PLAIN; 98 | ALTER TABLE tbl_storage_plain ALTER COLUMN c2 SET STORAGE PLAIN; 99 | -- 100 | -- insert data 101 | -- 102 | 103 | INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin'); 104 | INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king'); 105 | INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker'); 106 | INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen'); 107 | INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); 108 | 109 | INSERT INTO tbl_only_pkey VALUES(1, 'abc'); 110 | INSERT INTO tbl_only_pkey VALUES(2, 'def'); 111 | 112 | INSERT INTO tbl_only_ckey VALUES(1, '2008-01-01 00:00:00', 'abc'); 113 | INSERT INTO tbl_only_ckey VALUES(2, '2008-02-01 00:00:00', 'def'); 114 | 115 | INSERT INTO tbl_incl_pkey VALUES(1, '2008-01-01 00:00:00'); 116 | INSERT INTO tbl_incl_pkey VALUES(2, '2008-02-01 00:00:00'); 117 | 118 | INSERT INTO tbl_gistkey VALUES(1, '<(1,2),3>'); 119 | INSERT INTO tbl_gistkey VALUES(2, '<(4,5),6>'); 120 | 121 | INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 2, 'd2', 'c2', 'd3'); 122 | INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 1, 'd2', 'c2', 'd3'); 123 | ALTER TABLE tbl_with_dropped_column DROP COLUMN d1; 124 | ALTER TABLE tbl_with_dropped_column DROP COLUMN d2; 125 | ALTER TABLE tbl_with_dropped_column DROP COLUMN d3; 126 | ALTER TABLE tbl_with_dropped_column ADD COLUMN c3 text; 127 | CREATE VIEW view_for_dropped_column AS 128 | SELECT * FROM tbl_with_dropped_column; 129 | 130 | INSERT INTO tbl_with_dropped_toast VALUES(1, 10, 'abc'); 131 | INSERT INTO tbl_with_dropped_toast VALUES(2, 20, sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); 132 | ALTER TABLE tbl_with_dropped_toast DROP COLUMN t; 133 | 134 | INSERT INTO tbl_badindex VALUES(1, 10); 135 | INSERT INTO tbl_badindex VALUES(2, 10); 136 | 137 | -- insert data that is always stored into the toast table if column type is extended. 138 | SELECT setseed(0); INSERT INTO tbl_with_mod_column_storage SELECT 1, array_to_string(ARRAY(SELECT chr((random() * (127 - 32) + 32)::int) FROM generate_series(1, 3 * 1024) code), ''); 139 | 140 | --- This will fail 141 | \set VERBOSITY terse 142 | CREATE UNIQUE INDEX CONCURRENTLY idx_badindex_n ON tbl_badindex (n); 143 | 144 | INSERT INTO tbl_idxopts VALUES (0, 'abc'), (1, 'aaa'), (2, NULL), (3, 'bbb'); 145 | 146 | -- Insert no-ordered data 147 | INSERT INTO tbl_order SELECT generate_series(100, 51, -1); 148 | CLUSTER tbl_order USING tbl_order_pkey; 149 | INSERT INTO tbl_order SELECT generate_series(50, 1, -1); 150 | 151 | -- 152 | -- before 153 | -- 154 | 155 | SELECT * FROM tbl_with_dropped_column; 156 | SELECT * FROM view_for_dropped_column; 157 | SELECT * FROM tbl_with_dropped_toast; 158 | VACUUM FULL tbl_storage_plain; 159 | -------------------------------------------------------------------------------- /regress/sql/tablespace.sql: -------------------------------------------------------------------------------- 1 | SET client_min_messages = warning; 2 | 3 | -- 4 | -- Tablespace features tests 5 | -- 6 | -- Note: in order to pass this test you must create a tablespace called 'testts' 7 | -- 8 | 9 | SELECT spcname FROM pg_tablespace WHERE spcname = 'testts'; 10 | -- If the query above failed you must create the 'testts' tablespace; 11 | 12 | CREATE TABLE testts1 (id serial primary key, data text); 13 | CREATE INDEX testts1_partial_idx on testts1 (id) where (id > 0); 14 | CREATE INDEX testts1_with_idx on testts1 (id) with (fillfactor=80); 15 | INSERT INTO testts1 (data) values ('a'); 16 | INSERT INTO testts1 (data) values ('b'); 17 | INSERT INTO testts1 (data) values ('c'); 18 | 19 | -- check the indexes definitions 20 | SELECT regexp_replace( 21 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, false), 22 | '_[0-9]+', '_OID', 'g') 23 | FROM pg_index i join pg_class c ON c.oid = indexrelid 24 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 25 | 26 | SELECT regexp_replace( 27 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', false), 28 | '_[0-9]+', '_OID', 'g') 29 | FROM pg_index i join pg_class c ON c.oid = indexrelid 30 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 31 | 32 | SELECT regexp_replace( 33 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, true), 34 | '_[0-9]+', '_OID', 'g') 35 | FROM pg_index i join pg_class c ON c.oid = indexrelid 36 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 37 | 38 | SELECT regexp_replace( 39 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', true), 40 | '_[0-9]+', '_OID', 'g') 41 | FROM pg_index i join pg_class c ON c.oid = indexrelid 42 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 43 | 44 | -- Test that a tablespace is quoted as an identifier 45 | SELECT regexp_replace( 46 | repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo bar', false), 47 | '_[0-9]+', '_OID', 'g') 48 | FROM pg_index i join pg_class c ON c.oid = indexrelid 49 | WHERE indrelid = 'testts1'::regclass ORDER BY relname; 50 | 51 | -- can move the tablespace from default 52 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts 53 | 54 | SELECT relname, spcname 55 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 56 | WHERE relname ~ '^testts1' 57 | ORDER BY relname; 58 | 59 | SELECT * from testts1 order by id; 60 | 61 | -- tablespace stays where it is 62 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 63 | 64 | SELECT relname, spcname 65 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 66 | WHERE relname ~ '^testts1' 67 | ORDER BY relname; 68 | 69 | -- can move the ts back to default 70 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -s pg_default 71 | 72 | SELECT relname, spcname 73 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 74 | WHERE relname ~ '^testts1' 75 | ORDER BY relname; 76 | 77 | -- can move the table together with the indexes 78 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts --moveidx 79 | 80 | SELECT relname, spcname 81 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 82 | WHERE relname ~ '^testts1' 83 | ORDER BY relname; 84 | 85 | -- can't specify --moveidx without --tablespace 86 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 --moveidx 87 | \! pg_repack --dbname=contrib_regression --no-order --table=testts1 -S 88 | 89 | -- not broken with order 90 | \! pg_repack --dbname=contrib_regression -o id --table=testts1 --tablespace pg_default --moveidx 91 | 92 | --move all indexes of the table to a tablespace 93 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=testts 94 | 95 | SELECT relname, spcname 96 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 97 | WHERE relname ~ '^testts1' 98 | ORDER BY relname; 99 | 100 | --all indexes of tablespace remain in same tablespace 101 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes 102 | 103 | SELECT relname, spcname 104 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 105 | WHERE relname ~ '^testts1' 106 | ORDER BY relname; 107 | 108 | --move all indexes of the table to pg_default 109 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=pg_default 110 | 111 | SELECT relname, spcname 112 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 113 | WHERE relname ~ '^testts1' 114 | ORDER BY relname; 115 | 116 | --move one index to a tablespace 117 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=testts 118 | 119 | SELECT relname, spcname 120 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 121 | WHERE relname ~ '^testts1' 122 | ORDER BY relname; 123 | 124 | --index tablespace stays as is 125 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey 126 | 127 | SELECT relname, spcname 128 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 129 | WHERE relname ~ '^testts1' 130 | ORDER BY relname; 131 | 132 | --move index to pg_default 133 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=pg_default 134 | 135 | SELECT relname, spcname 136 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 137 | WHERE relname ~ '^testts1' 138 | ORDER BY relname; 139 | 140 | --using multiple --index option 141 | \! pg_repack --dbname=contrib_regression --index=testts1_pkey --index=testts1_with_idx --tablespace=testts 142 | 143 | SELECT relname, spcname 144 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 145 | WHERE relname ~ '^testts1' 146 | ORDER BY relname; 147 | 148 | --using --indexes-only and --index option together 149 | \! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --index=testts1_pkey 150 | 151 | --check quote_ident() with 1testts tablespace 152 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace=1testts --moveidx 153 | 154 | SELECT relname, spcname 155 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 156 | WHERE relname ~ '^testts1' 157 | ORDER BY relname; 158 | 159 | --check quote_ident() with "test ts" tablespace 160 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test ts" --moveidx 161 | 162 | SELECT relname, spcname 163 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 164 | WHERE relname ~ '^testts1' 165 | ORDER BY relname; 166 | 167 | --check quote_ident() with "test""ts" tablespace 168 | \! pg_repack --dbname=contrib_regression --table=testts1 --tablespace="test\"ts" --moveidx 169 | 170 | SELECT relname, spcname 171 | FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace 172 | WHERE relname ~ '^testts1' 173 | ORDER BY relname; 174 | -------------------------------------------------------------------------------- /regress/sql/trigger.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- repack.repack_trigger tests 3 | -- 4 | 5 | CREATE TABLE trigger_t1 (a int, b int, primary key (a, b)); 6 | CREATE INDEX trigger_t1_idx ON trigger_t1 (a, b); 7 | 8 | SELECT create_trigger FROM repack.tables WHERE relname = 'public.trigger_t1'; 9 | 10 | SELECT oid AS t1_oid FROM pg_catalog.pg_class WHERE relname = 'trigger_t1' 11 | \gset 12 | 13 | CREATE TYPE repack.pk_:t1_oid AS (a integer, b integer); 14 | CREATE TABLE repack.log_:t1_oid (id bigserial PRIMARY KEY, pk repack.pk_:t1_oid, row public.trigger_t1); 15 | CREATE TRIGGER repack_trigger AFTER INSERT OR DELETE OR UPDATE ON trigger_t1 16 | FOR EACH ROW EXECUTE PROCEDURE repack.repack_trigger('a', 'b'); 17 | 18 | INSERT INTO trigger_t1 VALUES (111, 222); 19 | UPDATE trigger_t1 SET a=333, b=444 WHERE a = 111; 20 | DELETE FROM trigger_t1 WHERE a = 333; 21 | SELECT * FROM repack.log_:t1_oid; 22 | --------------------------------------------------------------------------------