summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeikki Linnakangas2009-02-23 07:53:26 +0000
committerHeikki Linnakangas2009-02-23 07:53:26 +0000
commit30f96acd1a4ca704100c7b836a58e9ef3dc17b95 (patch)
treef4011ddafe610f4a9898962ab4785093629607b5
parent4fd212090fd1bbdb5631001f9e96564f8fffe9fd (diff)
parente05ec7efd152c05691510e72c19b3326710e61f9 (diff)
Merge commit 'origin/master' into recoveryinfra
Conflicts: src/backend/access/transam/xlog.c src/backend/postmaster/postmaster.c src/include/storage/pmsignal.h
-rw-r--r--doc/src/sgml/config.sgml14
-rw-r--r--doc/src/sgml/ref/vacuumdb.sgml12
-rw-r--r--src/Makefile.global.in3
-rw-r--r--src/backend/access/transam/xlog.c2
-rw-r--r--src/backend/optimizer/path/joinrels.c26
-rw-r--r--src/backend/optimizer/plan/initsplan.c40
-rw-r--r--src/backend/utils/adt/float.c19
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.c1
-rw-r--r--src/bin/pg_dump/pg_dump.c40
-rw-r--r--src/bin/pg_dump/pg_dump.h1
-rw-r--r--src/bin/pg_dump/pg_dumpall.c35
-rw-r--r--src/bin/scripts/vacuumdb.c24
-rw-r--r--src/include/storage/proc.h6
-rw-r--r--src/pl/plperl/expected/plperl.out16
-rw-r--r--src/pl/plperl/nls.mk4
-rw-r--r--src/pl/plperl/plperl.c22
-rw-r--r--src/pl/plpgsql/src/gram.y22
-rw-r--r--src/pl/plpgsql/src/pl_comp.c8
-rw-r--r--src/pl/plpgsql/src/pl_exec.c48
-rw-r--r--src/pl/plpgsql/src/pl_funcs.c4
-rw-r--r--src/pl/plpgsql/src/pl_handler.c4
-rw-r--r--src/pl/plpgsql/src/scan.l4
-rw-r--r--src/test/regress/expected/numerology.out4
-rw-r--r--src/test/regress/expected/numerology_1.out136
-rw-r--r--src/test/regress/expected/plpgsql.out8
25 files changed, 352 insertions, 151 deletions
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 5cc395efa2..223911c7c6 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -3361,11 +3361,19 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
<listitem>
<para>
Enables tracking of function call counts and time used. Specify
- <literal>pl</literal> to count only procedural language functions,
+ <literal>pl</literal> to track only procedural-language functions,
<literal>all</literal> to also track SQL and C language functions.
- The default is <literal>none</literal>.
- Only superusers can change this setting.
+ The default is <literal>none</literal>, which disables function
+ statistics tracking. Only superusers can change this setting.
</para>
+
+ <note>
+ <para>
+ SQL-language functions that are simple enough to be <quote>inlined</>
+ into the calling query will not be tracked, regardless of this
+ setting.
+ </para>
+ </note>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml
index 6a00946827..bd44f71c25 100644
--- a/doc/src/sgml/ref/vacuumdb.sgml
+++ b/doc/src/sgml/ref/vacuumdb.sgml
@@ -26,6 +26,7 @@ PostgreSQL documentation
<group><arg>--full</arg><arg>-f</arg></group>
<group><arg>--verbose</arg><arg>-v</arg></group>
<group><arg>--analyze</arg><arg>-z</arg></group>
+ <group><arg>--freeze</arg><arg>-F</arg></group>
<arg>--table | -t <replaceable>table</replaceable>
<arg>( <replaceable class="parameter">column</replaceable> [,...] )</arg>
</arg>
@@ -37,6 +38,7 @@ PostgreSQL documentation
<group><arg>--full</arg><arg>-f</arg></group>
<group><arg>--verbose</arg><arg>-v</arg></group>
<group><arg>--analyze</arg><arg>-z</arg></group>
+ <group><arg>--freeze</arg><arg>-F</arg></group>
</cmdsynopsis>
</refsynopsisdiv>
@@ -161,6 +163,16 @@ PostgreSQL documentation
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><option>-F</option></term>
+ <term><option>--freeze</option></term>
+ <listitem>
+ <para>
+ Aggressively <quote>freeze</quote> tuples.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index ff27dd903d..829ce7218d 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -468,6 +468,9 @@ TAS = @TAS@
#
# Global targets and rules
+%.i: %.c
+ $(CPP) $(CPPFLAGS) -o $@ $<
+
%.gz: %
$(GZIP) -f --best $<
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 747379f61e..bc8372ce3a 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2818,7 +2818,7 @@ RestoreArchivedFile(char *path, const char *xlogfname,
* On SIGTERM, assume we have received a fast shutdown request, and exit
* cleanly. It's pure chance whether we receive the SIGTERM first, or the
* child process. If we receive it first, the signal handler will call
- * proc_exit(1), otherwise we do it here. If we or the child process
+ * proc_exit, otherwise we do it here. If we or the child process
* received SIGTERM for any other reason than a fast shutdown request,
* postmaster will perform an immediate shutdown when it sees us exiting
* unexpectedly.
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 1f1309771f..fdf322a386 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -424,9 +424,27 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
create_unique_path(root, rel2, rel2->cheapest_total_path,
sjinfo) != NULL)
{
- /*
+ /*----------
* For a semijoin, we can join the RHS to anything else by
* unique-ifying the RHS (if the RHS can be unique-ified).
+ * We will only get here if we have the full RHS but less
+ * than min_lefthand on the LHS.
+ *
+ * The reason to consider such a join path is exemplified by
+ * SELECT ... FROM a,b WHERE (a.x,b.y) IN (SELECT c1,c2 FROM c)
+ * If we insist on doing this as a semijoin we will first have
+ * to form the cartesian product of A*B. But if we unique-ify
+ * C then the semijoin becomes a plain innerjoin and we can join
+ * in any order, eg C to A and then to B. When C is much smaller
+ * than A and B this can be a huge win. So we allow C to be
+ * joined to just A or just B here, and then make_join_rel has
+ * to handle the case properly.
+ *
+ * Note that actually we'll allow unique-ified C to be joined to
+ * some other relation D here, too. That is legal, if usually not
+ * very sane, and this routine is only concerned with legality not
+ * with whether the join is good strategy.
+ *----------
*/
if (match_sjinfo)
return false; /* invalid join path */
@@ -648,8 +666,10 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
break;
case JOIN_SEMI:
/*
- * Do these steps only if we actually have a regular semijoin,
- * as opposed to a case where we should unique-ify the RHS.
+ * We might have a normal semijoin, or a case where we don't have
+ * enough rels to do the semijoin but can unique-ify the RHS and
+ * then do an innerjoin (see comments in join_is_legal). In the
+ * latter case we can't apply JOIN_SEMI joining.
*/
if (bms_is_subset(sjinfo->min_lefthand, rel1->relids) &&
bms_is_subset(sjinfo->min_righthand, rel2->relids))
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index b4dc2ed62f..1e126a5a12 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -725,6 +725,9 @@ make_outerjoininfo(PlannerInfo *root,
* 'qualscope' identifies what level of JOIN the qual came from syntactically.
* 'ojscope' is needed if we decide to force the qual up to the outer-join
* level, which will be ojscope not necessarily qualscope.
+ *
+ * At the time this is called, root->join_info_list must contain entries for
+ * all and only those special joins that are syntactically below this qual.
*/
static void
distribute_qual_to_rels(PlannerInfo *root, Node *clause,
@@ -1209,7 +1212,6 @@ check_redundant_nullability_qual(PlannerInfo *root, Node *clause)
{
Var *forced_null_var;
Index forced_null_rel;
- SpecialJoinInfo *match_sjinfo = NULL;
ListCell *lc;
/* Check for IS NULL, and identify the Var forced to NULL */
@@ -1219,47 +1221,19 @@ check_redundant_nullability_qual(PlannerInfo *root, Node *clause)
forced_null_rel = forced_null_var->varno;
/*
- * Search to see if there's a matching antijoin that is not masked by
- * a higher outer join. Because we have to scan the join info bottom-up,
- * we have to continue looking after finding a match to check for masking
- * joins. This logic should agree with reduce_outer_joins's code
- * to detect antijoins on the basis of IS NULL clauses. (It's tempting
- * to consider adding some data structures to avoid redundant work,
- * but in practice this code shouldn't get executed often enough to
- * make it worth the trouble.)
+ * If the Var comes from the nullable side of a lower antijoin, the
+ * IS NULL condition is necessarily true.
*/
foreach(lc, root->join_info_list)
{
SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc);
- /* Check for match ... */
if (sjinfo->jointype == JOIN_ANTI &&
bms_is_member(forced_null_rel, sjinfo->syn_righthand))
- {
- List *nonnullable_vars;
-
- nonnullable_vars = find_nonnullable_vars((Node *) sjinfo->join_quals);
- if (list_member(nonnullable_vars, forced_null_var))
- {
- match_sjinfo = sjinfo;
- continue;
- }
- }
- /*
- * Else, if we had a lower match, check to see if the target var is
- * from the nullable side of this OJ. If so, this OJ masks the
- * lower one and we can no longer consider the IS NULL as redundant
- * with the lower antijoin.
- */
- if (!match_sjinfo)
- continue;
- if (bms_is_member(forced_null_rel, sjinfo->syn_righthand) ||
- (sjinfo->jointype == JOIN_FULL &&
- bms_is_member(forced_null_rel, sjinfo->syn_lefthand)))
- match_sjinfo = NULL;
+ return true;
}
- return (match_sjinfo != NULL);
+ return false;
}
/*
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index bd3601c608..19b570d9c4 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -576,9 +576,7 @@ float4um(PG_FUNCTION_ARGS)
float4 arg1 = PG_GETARG_FLOAT4(0);
float4 result;
- result = ((arg1 != 0) ? -(arg1) : arg1);
-
- CHECKFLOATVAL(result, isinf(arg1), true);
+ result = -arg1;
PG_RETURN_FLOAT4(result);
}
@@ -645,9 +643,7 @@ float8um(PG_FUNCTION_ARGS)
float8 arg1 = PG_GETARG_FLOAT8(0);
float8 result;
- result = ((arg1 != 0) ? -(arg1) : arg1);
-
- CHECKFLOATVAL(result, isinf(arg1), true);
+ result = -arg1;
PG_RETURN_FLOAT8(result);
}
@@ -703,16 +699,16 @@ float8smaller(PG_FUNCTION_ARGS)
Datum
float4pl(PG_FUNCTION_ARGS)
{
- float8 arg1 = PG_GETARG_FLOAT4(0);
- float8 arg2 = PG_GETARG_FLOAT4(1);
+ float4 arg1 = PG_GETARG_FLOAT4(0);
+ float4 arg2 = PG_GETARG_FLOAT4(1);
float4 result;
result = arg1 + arg2;
/*
* There isn't any way to check for underflow of addition/subtraction
- * because numbers near the underflow value have been already been to the
- * point where we can't detect the that the two values were originally
+ * because numbers near the underflow value have already been rounded to
+ * the point where we can't detect that the two values were originally
* different, e.g. on x86, '1e-45'::float4 == '2e-45'::float4 ==
* 1.4013e-45.
*/
@@ -757,7 +753,6 @@ float4div(PG_FUNCTION_ARGS)
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero")));
- /* Do division in float8, then check for overflow */
result = arg1 / arg2;
CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0);
@@ -2693,7 +2688,7 @@ width_bucket_float8(PG_FUNCTION_ARGS)
errmsg("operand, lower bound and upper bound cannot be NaN")));
/* Note that we allow "operand" to be infinite */
- if (is_infinite(bound1) || is_infinite(bound2))
+ if (isinf(bound1) || isinf(bound2))
ereport(ERROR,
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
errmsg("lower and upper bounds must be finite")));
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 6cf171d455..5eda359a3e 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -487,6 +487,7 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te,
{
ahlog(AH, 1, "connecting to new database \"%s\"\n", te->tag);
_reconnectToDB(AH, te->tag);
+ ropt->dbname = strdup(te->tag);
}
}
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 43843c97ed..32a8ae6c2f 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -1585,6 +1585,7 @@ dumpDatabase(Archive *AH)
i_encoding,
i_collate,
i_ctype,
+ i_frozenxid,
i_tablespace;
CatalogId dbCatId;
DumpId dbDumpId;
@@ -1594,6 +1595,7 @@ dumpDatabase(Archive *AH)
*collate,
*ctype,
*tablespace;
+ uint32 frozenxid;
datname = PQdb(g_conn);
@@ -1609,7 +1611,7 @@ dumpDatabase(Archive *AH)
appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
"(%s datdba) AS dba, "
"pg_encoding_to_char(encoding) AS encoding, "
- "datcollate, datctype, "
+ "datcollate, datctype, datfrozenxid, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
"shobj_description(oid, 'pg_database') AS description "
@@ -1623,7 +1625,7 @@ dumpDatabase(Archive *AH)
appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
"(%s datdba) AS dba, "
"pg_encoding_to_char(encoding) AS encoding, "
- "NULL AS datcollate, NULL AS datctype, "
+ "NULL AS datcollate, NULL AS datctype, datfrozenxid, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
"shobj_description(oid, 'pg_database') AS description "
@@ -1637,7 +1639,7 @@ dumpDatabase(Archive *AH)
appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
"(%s datdba) AS dba, "
"pg_encoding_to_char(encoding) AS encoding, "
- "NULL AS datcollate, NULL AS datctype, "
+ "NULL AS datcollate, NULL AS datctype, datfrozenxid, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace "
"FROM pg_database "
"WHERE datname = ",
@@ -1650,6 +1652,7 @@ dumpDatabase(Archive *AH)
"(%s datdba) AS dba, "
"pg_encoding_to_char(encoding) AS encoding, "
"NULL AS datcollate, NULL AS datctype, "
+ "0 AS datfrozenxid, "
"NULL AS tablespace "
"FROM pg_database "
"WHERE datname = ",
@@ -1664,6 +1667,7 @@ dumpDatabase(Archive *AH)
"(%s datdba) AS dba, "
"pg_encoding_to_char(encoding) AS encoding, "
"NULL AS datcollate, NULL AS datctype, "
+ "0 AS datfrozenxid, "
"NULL AS tablespace "
"FROM pg_database "
"WHERE datname = ",
@@ -1696,6 +1700,7 @@ dumpDatabase(Archive *AH)
i_encoding = PQfnumber(res, "encoding");
i_collate = PQfnumber(res, "datcollate");
i_ctype = PQfnumber(res, "datctype");
+ i_frozenxid = PQfnumber(res, "datfrozenxid");
i_tablespace = PQfnumber(res, "tablespace");
dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
@@ -1704,6 +1709,7 @@ dumpDatabase(Archive *AH)
encoding = PQgetvalue(res, 0, i_encoding);
collate = PQgetvalue(res, 0, i_collate);
ctype = PQgetvalue(res, 0, i_ctype);
+ frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
tablespace = PQgetvalue(res, 0, i_tablespace);
appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
@@ -1728,6 +1734,15 @@ dumpDatabase(Archive *AH)
fmtId(tablespace));
appendPQExpBuffer(creaQry, ";\n");
+ if (binary_upgrade)
+ {
+ appendPQExpBuffer(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n");
+ appendPQExpBuffer(creaQry, "UPDATE pg_database\n"
+ "SET datfrozenxid = '%u'\n"
+ "WHERE datname = '%s';\n",
+ frozenxid, datname);
+ }
+
appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
fmtId(datname));
@@ -3114,6 +3129,7 @@ getTables(int *numTables)
int i_relhasindex;
int i_relhasrules;
int i_relhasoids;
+ int i_relfrozenxid;
int i_owning_tab;
int i_owning_col;
int i_reltablespace;
@@ -3155,6 +3171,7 @@ getTables(int *numTables)
"(%s c.relowner) AS rolname, "
"c.relchecks, c.relhastriggers, "
"c.relhasindex, c.relhasrules, c.relhasoids, "
+ "c.relfrozenxid, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
@@ -3186,6 +3203,7 @@ getTables(int *numTables)
"(%s relowner) AS rolname, "
"relchecks, (reltriggers <> 0) AS relhastriggers, "
"relhasindex, relhasrules, relhasoids, "
+ "relfrozenxid, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
@@ -3216,6 +3234,7 @@ getTables(int *numTables)
"(%s relowner) AS rolname, "
"relchecks, (reltriggers <> 0) AS relhastriggers, "
"relhasindex, relhasrules, relhasoids, "
+ "0 AS relfrozenxid, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
@@ -3246,6 +3265,7 @@ getTables(int *numTables)
"(%s relowner) AS rolname, "
"relchecks, (reltriggers <> 0) AS relhastriggers, "
"relhasindex, relhasrules, relhasoids, "
+ "0 AS relfrozenxid, "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"NULL AS reltablespace, "
@@ -3272,6 +3292,7 @@ getTables(int *numTables)
"(%s relowner) AS rolname, "
"relchecks, (reltriggers <> 0) AS relhastriggers, "
"relhasindex, relhasrules, relhasoids, "
+ "0 AS relfrozenxid, "
"NULL::oid AS owning_tab, "
"NULL::int4 AS owning_col, "
"NULL AS reltablespace, "
@@ -3293,6 +3314,7 @@ getTables(int *numTables)
"relchecks, (reltriggers <> 0) AS relhastriggers, "
"relhasindex, relhasrules, "
"'t'::bool AS relhasoids, "
+ "0 AS relfrozenxid, "
"NULL::oid AS owning_tab, "
"NULL::int4 AS owning_col, "
"NULL AS reltablespace, "
@@ -3324,6 +3346,7 @@ getTables(int *numTables)
"relchecks, (reltriggers <> 0) AS relhastriggers, "
"relhasindex, relhasrules, "
"'t'::bool AS relhasoids, "
+ "0 as relfrozenxid, "
"NULL::oid AS owning_tab, "
"NULL::int4 AS owning_col, "
"NULL AS reltablespace, "
@@ -3367,6 +3390,7 @@ getTables(int *numTables)
i_relhasindex = PQfnumber(res, "relhasindex");
i_relhasrules = PQfnumber(res, "relhasrules");
i_relhasoids = PQfnumber(res, "relhasoids");
+ i_relfrozenxid = PQfnumber(res, "relfrozenxid");
i_owning_tab = PQfnumber(res, "owning_tab");
i_owning_col = PQfnumber(res, "owning_col");
i_reltablespace = PQfnumber(res, "reltablespace");
@@ -3404,6 +3428,7 @@ getTables(int *numTables)
tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
+ tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
if (PQgetisnull(res, i, i_owning_tab))
{
@@ -9860,6 +9885,15 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
tbinfo->dobj.name);
}
}
+ appendPQExpBuffer(q, "\n-- For binary upgrade, set relfrozenxid.\n");
+ appendPQExpBuffer(q, "UPDATE pg_class\n"
+ "SET relfrozenxid = '%u'\n"
+ "WHERE relname = '%s'\n"
+ " AND relnamespace = "
+ "(SELECT oid FROM pg_namespace "
+ "WHERE nspname = CURRENT_SCHEMA);\n",
+ tbinfo->frozenxid,
+ tbinfo->dobj.name);
}
/* Loop dumping statistics and storage statements */
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 8869a5146a..8949f01482 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -226,6 +226,7 @@ typedef struct _tableInfo
bool hasrules; /* does it have any rules? */
bool hastriggers; /* does it have any triggers? */
bool hasoids; /* does it have OIDs? */
+ uint32 frozenxid; /* for restore frozen xid */
int ncheck; /* # of CHECK expressions */
/* these two are set only if table is a sequence owned by a column: */
Oid owning_tab; /* OID of table owning sequence */
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 55d15e9e18..2255a6716b 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -27,7 +27,7 @@ int optreset;
#endif
#include "dumputils.h"
-
+#include "pg_backup.h"
/* version string we expect back from pg_dump */
#define PGDUMP_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"
@@ -71,6 +71,8 @@ static int server_version;
static FILE *OPF;
static char *filename = NULL;
+static int binary_upgrade = 0;
+
int
main(int argc, char *argv[])
{
@@ -90,7 +92,6 @@ main(int argc, char *argv[])
const char *std_strings;
int c,
ret;
- int binary_upgrade = 0;
struct option long_options[] = {
{"binary-upgrade", no_argument, &binary_upgrade, 1}, /* not documented */
@@ -937,7 +938,7 @@ dumpCreateDB(PGconn *conn)
"SELECT datname, "
"coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
- "datcollate, datctype, "
+ "datcollate, datctype, datfrozenxid, "
"datistemplate, datacl, datconnlimit, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
"FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
@@ -947,7 +948,7 @@ dumpCreateDB(PGconn *conn)
"SELECT datname, "
"coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
- "null::text AS datcollate, null::text AS datctype, "
+ "null::text AS datcollate, null::text AS datctype, datfrozenxid, "
"datistemplate, datacl, datconnlimit, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
"FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
@@ -957,7 +958,7 @@ dumpCreateDB(PGconn *conn)
"SELECT datname, "
"coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
- "null::text AS datcollate, null::text AS datctype, "
+ "null::text AS datcollate, null::text AS datctype, datfrozenxid, "
"datistemplate, datacl, -1 as datconnlimit, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
"FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
@@ -967,7 +968,7 @@ dumpCreateDB(PGconn *conn)
"SELECT datname, "
"coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
- "null::text AS datcollate, null::text AS datctype, "
+ "null::text AS datcollate, null::text AS datctype, datfrozenxid, "
"datistemplate, datacl, -1 as datconnlimit, "
"'pg_default' AS dattablespace "
"FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
@@ -979,7 +980,7 @@ dumpCreateDB(PGconn *conn)
"(select usename from pg_shadow where usesysid=datdba), "
"(select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
- "null::text AS datcollate, null::text AS datctype, "
+ "null::text AS datcollate, null::text AS datctype, 0 AS datfrozenxid"
"datistemplate, '' as datacl, -1 as datconnlimit, "
"'pg_default' AS dattablespace "
"FROM pg_database d "
@@ -994,7 +995,7 @@ dumpCreateDB(PGconn *conn)
"SELECT datname, "
"(select usename from pg_shadow where usesysid=datdba), "
"pg_encoding_to_char(d.encoding), "
- "null::text AS datcollate, null::text AS datctype, "
+ "null::text AS datcollate, null::text AS datctype, 0 AS datfrozenxid"
"'f' as datistemplate, "
"'' as datacl, -1 as datconnlimit, "
"'pg_default' AS dattablespace "
@@ -1009,10 +1010,11 @@ dumpCreateDB(PGconn *conn)
char *dbencoding = PQgetvalue(res, i, 2);
char *dbcollate = PQgetvalue(res, i, 3);
char *dbctype = PQgetvalue(res, i, 4);
- char *dbistemplate = PQgetvalue(res, i, 5);
- char *dbacl = PQgetvalue(res, i, 6);
- char *dbconnlimit = PQgetvalue(res, i, 7);
- char *dbtablespace = PQgetvalue(res, i, 8);
+ uint32 dbfrozenxid = atooid(PQgetvalue(res, i, 5));
+ char *dbistemplate = PQgetvalue(res, i, 6);
+ char *dbacl = PQgetvalue(res, i, 7);
+ char *dbconnlimit = PQgetvalue(res, i, 8);
+ char *dbtablespace = PQgetvalue(res, i, 9);
char *fdbname;
fdbname = strdup(fmtId(dbname));
@@ -1076,6 +1078,15 @@ dumpCreateDB(PGconn *conn)
appendStringLiteralConn(buf, dbname, conn);
appendPQExpBuffer(buf, ";\n");
}
+
+ if (binary_upgrade)
+ {
+ appendPQExpBuffer(buf, "\n-- For binary upgrade, set datfrozenxid.\n");
+ appendPQExpBuffer(buf, "UPDATE pg_database\n"
+ "SET datfrozenxid = '%u'\n"
+ "WHERE datname = '%s';\n",
+ dbfrozenxid, fdbname);
+ }
}
if (!skip_acls &&
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
index c0f78a1e05..55f1f415dd 100644
--- a/src/bin/scripts/vacuumdb.c
+++ b/src/bin/scripts/vacuumdb.c
@@ -15,11 +15,11 @@
static void vacuum_one_database(const char *dbname, bool full, bool verbose, bool analyze,
- const char *table,
+ bool freeze, const char *table,
const char *host, const char *port,
const char *username, bool password,
const char *progname, bool echo);
-static void vacuum_all_databases(bool full, bool verbose, bool analyze,
+static void vacuum_all_databases(bool full, bool verbose, bool analyze, bool freeze,
const char *host, const char *port,
const char *username, bool password,
const char *progname, bool echo, bool quiet);
@@ -39,6 +39,7 @@ main(int argc, char *argv[])
{"quiet", no_argument, NULL, 'q'},
{"dbname", required_argument, NULL, 'd'},
{"analyze", no_argument, NULL, 'z'},
+ {"freeze", no_argument, NULL, 'F'},
{"all", no_argument, NULL, 'a'},
{"table", required_argument, NULL, 't'},
{"full", no_argument, NULL, 'f'},
@@ -58,6 +59,7 @@ main(int argc, char *argv[])
bool echo = false;
bool quiet = false;
bool analyze = false;
+ bool freeze = false;
bool alldb = false;
char *table = NULL;
bool full = false;
@@ -68,7 +70,7 @@ main(int argc, char *argv[])
handle_help_version_opts(argc, argv, "vacuumdb", help);
- while ((c = getopt_long(argc, argv, "h:p:U:Weqd:zat:fv", long_options, &optindex)) != -1)
+ while ((c = getopt_long(argc, argv, "h:p:U:Weqd:zaFt:fv", long_options, &optindex)) != -1)
{
switch (c)
{
@@ -96,6 +98,9 @@ main(int argc, char *argv[])
case 'z':
analyze = true;
break;
+ case 'F':
+ freeze = true;
+ break;
case 'a':
alldb = true;
break;
@@ -145,7 +150,7 @@ main(int argc, char *argv[])
exit(1);
}
- vacuum_all_databases(full, verbose, analyze,
+ vacuum_all_databases(full, verbose, analyze, freeze,
host, port, username, password,
progname, echo, quiet);
}
@@ -161,7 +166,7 @@ main(int argc, char *argv[])
dbname = get_user_name(progname);
}
- vacuum_one_database(dbname, full, verbose, analyze, table,
+ vacuum_one_database(dbname, full, verbose, analyze, freeze, table,
host, port, username, password,
progname, echo);
}
@@ -172,7 +177,7 @@ main(int argc, char *argv[])
static void
vacuum_one_database(const char *dbname, bool full, bool verbose, bool analyze,
- const char *table,
+ bool freeze, const char *table,
const char *host, const char *port,
const char *username, bool password,
const char *progname, bool echo)
@@ -190,6 +195,8 @@ vacuum_one_database(const char *dbname, bool full, bool verbose, bool analyze,
appendPQExpBuffer(&sql, " VERBOSE");
if (analyze)
appendPQExpBuffer(&sql, " ANALYZE");
+ if (freeze)
+ appendPQExpBuffer(&sql, " FREEZE");
if (table)
appendPQExpBuffer(&sql, " %s", table);
appendPQExpBuffer(&sql, ";\n");
@@ -212,7 +219,7 @@ vacuum_one_database(const char *dbname, bool full, bool verbose, bool analyze,
static void
-vacuum_all_databases(bool full, bool verbose, bool analyze,
+vacuum_all_databases(bool full, bool verbose, bool analyze, bool freeze,
const char *host, const char *port,
const char *username, bool password,
const char *progname, bool echo, bool quiet)
@@ -235,7 +242,7 @@ vacuum_all_databases(bool full, bool verbose, bool analyze,
fflush(stdout);
}
- vacuum_one_database(dbname, full, verbose, analyze, NULL,
+ vacuum_one_database(dbname, full, verbose, analyze, freeze, NULL,
host, port, username, password,
progname, echo);
}
@@ -256,6 +263,7 @@ help(const char *progname)
printf(_(" -t, --table='TABLE[(COLUMNS)]' vacuum specific table only\n"));
printf(_(" -f, --full do full vacuuming\n"));
printf(_(" -z, --analyze update optimizer hints\n"));
+ printf(_(" -F, --freeze freeze row transaction information\n"));
printf(_(" -e, --echo show the commands being sent to the server\n"));
printf(_(" -q, --quiet don't write any messages\n"));
printf(_(" -v, --verbose write a lot of output\n"));
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 7509332d59..53a5c055ad 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -138,8 +138,12 @@ typedef struct PROC_HDR
/*
* We set aside some extra PGPROC structures for auxiliary processes,
* ie things that aren't full-fledged backends but need shmem access.
+ *
+ * Background writer, WAL writer, and autovacuum launcher run during
+ * normal operation. When recovery has just finished, the startup
+ * process can co-exist with them for a brief period before it exits.
*/
-#define NUM_AUXILIARY_PROCS 3
+#define NUM_AUXILIARY_PROCS 4
/* configurable options */
diff --git a/src/pl/plperl/expected/plperl.out b/src/pl/plperl/expected/plperl.out
index 708723d3e5..e1b0c75108 100644
--- a/src/pl/plperl/expected/plperl.out
+++ b/src/pl/plperl/expected/plperl.out
@@ -121,9 +121,9 @@ CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
];
$$ LANGUAGE plperl;
SELECT perl_set();
-ERROR: setof-composite-returning Perl function must call return_next with reference to hash
+ERROR: SETOF-composite-returning PL/Perl function must call return_next with reference to hash
SELECT * FROM perl_set();
-ERROR: setof-composite-returning Perl function must call return_next with reference to hash
+ERROR: SETOF-composite-returning PL/Perl function must call return_next with reference to hash
CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
return [
{ f1 => 1, f2 => 'Hello', f3 => 'World' },
@@ -209,7 +209,7 @@ ERROR: a column definition list is required for functions returning "record"
LINE 1: SELECT * FROM perl_record_set();
^
SELECT * FROM perl_record_set() AS (f1 integer, f2 text, f3 text);
-ERROR: setof-composite-returning Perl function must call return_next with reference to hash
+ERROR: SETOF-composite-returning PL/Perl function must call return_next with reference to hash
CREATE OR REPLACE FUNCTION perl_record_set() RETURNS SETOF record AS $$
return [
{ f1 => 1, f2 => 'Hello', f3 => 'World' },
@@ -312,7 +312,7 @@ CREATE OR REPLACE FUNCTION foo_bad() RETURNS footype AS $$
return 42;
$$ LANGUAGE plperl;
SELECT * FROM foo_bad();
-ERROR: composite-returning Perl function must return reference to hash
+ERROR: composite-returning PL/Perl function must return reference to hash
CREATE OR REPLACE FUNCTION foo_bad() RETURNS footype AS $$
return [
[1, 2],
@@ -320,17 +320,17 @@ return [
];
$$ LANGUAGE plperl;
SELECT * FROM foo_bad();
-ERROR: composite-returning Perl function must return reference to hash
+ERROR: composite-returning PL/Perl function must return reference to hash
CREATE OR REPLACE FUNCTION foo_set_bad() RETURNS SETOF footype AS $$
return 42;
$$ LANGUAGE plperl;
SELECT * FROM foo_set_bad();
-ERROR: set-returning Perl function must return reference to array or use return_next
+ERROR: set-returning PL/Perl function must return reference to array or use return_next
CREATE OR REPLACE FUNCTION foo_set_bad() RETURNS SETOF footype AS $$
return {y => 3, z => 4};
$$ LANGUAGE plperl;
SELECT * FROM foo_set_bad();
-ERROR: set-returning Perl function must return reference to array or use return_next
+ERROR: set-returning PL/Perl function must return reference to array or use return_next
CREATE OR REPLACE FUNCTION foo_set_bad() RETURNS SETOF footype AS $$
return [
[1, 2],
@@ -338,7 +338,7 @@ return [
];
$$ LANGUAGE plperl;
SELECT * FROM foo_set_bad();
-ERROR: setof-composite-returning Perl function must call return_next with reference to hash
+ERROR: SETOF-composite-returning PL/Perl function must call return_next with reference to hash
CREATE OR REPLACE FUNCTION foo_set_bad() RETURNS SETOF footype AS $$
return [
{y => 3, z => 4}
diff --git a/src/pl/plperl/nls.mk b/src/pl/plperl/nls.mk
index 0064ff8d4f..84891d2f53 100644
--- a/src/pl/plperl/nls.mk
+++ b/src/pl/plperl/nls.mk
@@ -1,5 +1,5 @@
# $PostgreSQL$
CATALOG_NAME := plperl
AVAIL_LANGUAGES :=
-GETTEXT_FILES := plperl.c SPI.xs
-GETTEXT_TRIGGERS:= _ errmsg errdetail errdetail_log errhint errcontext croak Perl_croak
+GETTEXT_FILES := plperl.c SPI.c
+GETTEXT_TRIGGERS:= errmsg errdetail errdetail_log errhint errcontext
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 5f33ca6e47..2127a2369f 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -199,7 +199,7 @@ _PG_init(void)
pg_bindtextdomain(TEXTDOMAIN);
DefineCustomBoolVariable("plperl.use_strict",
- gettext_noop("If true, will compile trusted and untrusted perl code in strict mode"),
+ gettext_noop("If true, trusted and untrusted Perl code will be compiled in strict mode."),
NULL,
&plperl_use_strict,
false,
@@ -913,7 +913,7 @@ plperl_validator(PG_FUNCTION_ARGS)
proc->prorettype != VOIDOID)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("plperl functions cannot return type %s",
+ errmsg("PL/Perl functions cannot return type %s",
format_type_be(proc->prorettype))));
}
@@ -925,7 +925,7 @@ plperl_validator(PG_FUNCTION_ARGS)
if (get_typtype(argtypes[i]) == TYPTYPE_PSEUDO)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("plperl functions cannot take type %s",
+ errmsg("PL/Perl functions cannot accept type %s",
format_type_be(argtypes[i]))));
}
@@ -1280,7 +1280,7 @@ plperl_func_handler(PG_FUNCTION_ARGS)
{
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("set-returning Perl function must return "
+ errmsg("set-returning PL/Perl function must return "
"reference to array or use return_next")));
}
@@ -1313,7 +1313,7 @@ plperl_func_handler(PG_FUNCTION_ARGS)
{
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("composite-returning Perl function "
+ errmsg("composite-returning PL/Perl function "
"must return reference to hash")));
}
@@ -1438,7 +1438,7 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
{
ereport(WARNING,
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
- errmsg("ignoring modified tuple in DELETE trigger")));
+ errmsg("ignoring modified row in DELETE trigger")));
trv = NULL;
}
}
@@ -1446,8 +1446,8 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
{
ereport(ERROR,
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
- errmsg("result of Perl trigger function must be undef, "
- "\"SKIP\" or \"MODIFY\"")));
+ errmsg("result of PL/Perl trigger function must be undef, "
+ "\"SKIP\", or \"MODIFY\"")));
trv = NULL;
}
retval = PointerGetDatum(trv);
@@ -1612,7 +1612,7 @@ compile_plperl_function(Oid fn_oid, bool is_trigger)
free(prodesc);
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("plperl functions cannot return type %s",
+ errmsg("PL/Perl functions cannot return type %s",
format_type_be(procStruct->prorettype))));
}
}
@@ -1659,7 +1659,7 @@ compile_plperl_function(Oid fn_oid, bool is_trigger)
free(prodesc);
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("plperl functions cannot take type %s",
+ errmsg("PL/Perl functions cannot accept type %s",
format_type_be(procStruct->proargtypes.values[i]))));
}
@@ -1902,7 +1902,7 @@ plperl_return_next(SV *sv)
!(SvOK(sv) && SvTYPE(sv) == SVt_RV && SvTYPE(SvRV(sv)) == SVt_PVHV))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("setof-composite-returning Perl function "
+ errmsg("SETOF-composite-returning PL/Perl function "
"must call return_next with reference to hash")));
if (!current_call_data->ret_tdesc)
diff --git a/src/pl/plpgsql/src/gram.y b/src/pl/plpgsql/src/gram.y
index 5599a4bd90..b8815c5dd1 100644
--- a/src/pl/plpgsql/src/gram.y
+++ b/src/pl/plpgsql/src/gram.y
@@ -1043,7 +1043,7 @@ for_control :
if ($2.scalar && $2.row)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("cursor FOR loop must have just one target variable")));
+ errmsg("cursor FOR loop must have only one target variable")));
/* create loop's private RECORD variable */
plpgsql_convert_ident($2.name, &varname, 1);
@@ -1131,7 +1131,7 @@ for_control :
if ($2.scalar && $2.row)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("integer FOR loop must have just one target variable")));
+ errmsg("integer FOR loop must have only one target variable")));
/* create loop's private variable */
plpgsql_convert_ident($2.name, &varname, 1);
@@ -1570,7 +1570,7 @@ stmt_open : K_OPEN lno cursor_variable
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error at \"%s\"",
yytext),
- errdetail("Expected FOR to open a reference cursor.")));
+ errdetail("Expected \"FOR\", to open a reference cursor.")));
}
tok = yylex();
@@ -1664,7 +1664,7 @@ cursor_variable : T_SCALAR
plpgsql_error_lineno = plpgsql_scanner_lineno();
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("\"%s\" must be of type cursor or refcursor",
+ errmsg("variable \"%s\" must be of type cursor or refcursor",
((PLpgSQL_var *) yylval.scalar)->refname)));
}
$$ = (PLpgSQL_var *) yylval.scalar;
@@ -2094,7 +2094,7 @@ read_datatype(int tok)
if (parenlevel != 0)
yyerror("mismatched parentheses");
else
- yyerror("incomplete datatype declaration");
+ yyerror("incomplete data type declaration");
}
/* Possible followers for datatype in a declaration */
if (tok == K_NOT || tok == K_ASSIGN || tok == K_DEFAULT)
@@ -2119,7 +2119,7 @@ read_datatype(int tok)
type_name = plpgsql_dstring_get(&ds);
if (type_name[0] == '\0')
- yyerror("missing datatype declaration");
+ yyerror("missing data type declaration");
plpgsql_error_lineno = lno; /* in case of error in parse_datatype */
@@ -2375,11 +2375,11 @@ make_return_stmt(int lineno)
break;
default:
- yyerror("RETURN must specify a record or row variable in function returning tuple");
+ yyerror("RETURN must specify a record or row variable in function returning row");
break;
}
if (yylex() != ';')
- yyerror("RETURN must specify a record or row variable in function returning tuple");
+ yyerror("RETURN must specify a record or row variable in function returning row");
}
else
{
@@ -2428,11 +2428,11 @@ make_return_next_stmt(int lineno)
break;
default:
- yyerror("RETURN NEXT must specify a record or row variable in function returning tuple");
+ yyerror("RETURN NEXT must specify a record or row variable in function returning row");
break;
}
if (yylex() != ';')
- yyerror("RETURN NEXT must specify a record or row variable in function returning tuple");
+ yyerror("RETURN NEXT must specify a record or row variable in function returning row");
}
else
new->expr = plpgsql_read_expression(';', ";");
@@ -2745,7 +2745,7 @@ check_label(const char *yytxt)
plpgsql_convert_ident(yytxt, &label_name, 1);
if (plpgsql_ns_lookup_label(label_name) == NULL)
- yyerror("no such label");
+ yyerror("label does not exist");
return label_name;
}
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 768daf98f1..9f9d30eb3f 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -415,7 +415,7 @@ do_compile(FunctionCallInfo fcinfo,
argdtype->ttype != PLPGSQL_TTYPE_ROW)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("plpgsql functions cannot take type %s",
+ errmsg("PL/pgSQL functions cannot accept type %s",
format_type_be(argtypeid))));
/* Build variable and add to datum list */
@@ -534,7 +534,7 @@ do_compile(FunctionCallInfo fcinfo,
else
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("plpgsql functions cannot return type %s",
+ errmsg("PL/pgSQL functions cannot return type %s",
format_type_be(rettypeid))));
}
@@ -576,7 +576,7 @@ do_compile(FunctionCallInfo fcinfo,
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("trigger functions cannot have declared arguments"),
- errhint("You probably want to use TG_NARGS and TG_ARGV instead.")));
+ errhint("The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead.")));
/* Add the record for referencing NEW */
rec = plpgsql_build_record("new", 0, true);
@@ -766,7 +766,7 @@ plpgsql_compile_error_callback(void *arg)
}
if (plpgsql_error_funcname)
- errcontext("compile of PL/pgSQL function \"%s\" near line %d",
+ errcontext("compilation of PL/pgSQL function \"%s\" near line %d",
plpgsql_error_funcname, plpgsql_error_lineno);
}
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 21e76020cc..538efc6e30 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -706,7 +706,7 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
{
validate_tupdesc_compat(trigdata->tg_relation->rd_att,
estate.rettupdesc,
- "returned tuple structure does not match table of trigger event");
+ "returned row structure does not match the structure of the triggering table");
/* Copy tuple to upper executor memory */
rettup = SPI_copytuple((HeapTuple) DatumGetPointer(estate.retval));
}
@@ -765,24 +765,18 @@ plpgsql_exec_error_callback(void *arg)
*/
if (estate->err_stmt != NULL)
{
- /*
- * translator: last %s is a phrase such as "during statement block
- * local variable initialization"
- */
+ /* translator: last %s is a phrase such as "during statement block local variable initialization" */
errcontext("PL/pgSQL function \"%s\" line %d %s",
estate->err_func->fn_name,
estate->err_stmt->lineno,
- gettext(estate->err_text));
+ _(estate->err_text));
}
else
{
- /*
- * translator: last %s is a phrase such as "while storing call
- * arguments into local variables"
- */
+ /* translator: last %s is a phrase such as "while storing call arguments into local variables" */
errcontext("PL/pgSQL function \"%s\" %s",
estate->err_func->fn_name,
- gettext(estate->err_text));
+ _(estate->err_text));
}
}
else if (estate->err_stmt != NULL)
@@ -1677,7 +1671,7 @@ exec_stmt_fori(PLpgSQL_execstate *estate, PLpgSQL_stmt_fori *stmt)
if (isnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("lower bound of FOR loop cannot be NULL")));
+ errmsg("lower bound of FOR loop cannot be null")));
loop_value = DatumGetInt32(value);
exec_eval_cleanup(estate);
@@ -1692,7 +1686,7 @@ exec_stmt_fori(PLpgSQL_execstate *estate, PLpgSQL_stmt_fori *stmt)
if (isnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("upper bound of FOR loop cannot be NULL")));
+ errmsg("upper bound of FOR loop cannot be null")));
end_value = DatumGetInt32(value);
exec_eval_cleanup(estate);
@@ -1709,7 +1703,7 @@ exec_stmt_fori(PLpgSQL_execstate *estate, PLpgSQL_stmt_fori *stmt)
if (isnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("BY value of FOR loop cannot be NULL")));
+ errmsg("BY value of FOR loop cannot be null")));
step_value = DatumGetInt32(value);
exec_eval_cleanup(estate);
if (step_value <= 0)
@@ -2470,7 +2464,7 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
if (optionisnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("RAISE statement option cannot be NULL")));
+ errmsg("RAISE statement option cannot be null")));
extval = convert_value_to_string(optionvalue, optiontypeid);
@@ -2916,7 +2910,7 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate,
if (isnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("cannot EXECUTE a null querystring")));
+ errmsg("query string argument of EXECUTE is null")));
/* Get the C-String representation */
querystr = convert_value_to_string(query, restype);
@@ -2981,7 +2975,7 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate,
if (*ptr == 'S' || *ptr == 's')
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("EXECUTE of SELECT ... INTO is not implemented yet")));
+ errmsg("EXECUTE of SELECT ... INTO is not implemented")));
break;
}
@@ -3166,7 +3160,7 @@ exec_stmt_open(PLpgSQL_execstate *estate, PLpgSQL_stmt_open *stmt)
if (isnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("cannot EXECUTE a null querystring")));
+ errmsg("query string argument of EXECUTE is null")));
/* Get the C-String representation */
querystr = convert_value_to_string(queryD, restype);
@@ -3300,7 +3294,7 @@ exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt)
if (curvar->isnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("cursor variable \"%s\" is NULL", curvar->refname)));
+ errmsg("cursor variable \"%s\" is null", curvar->refname)));
curname = TextDatumGetCString(curvar->value);
portal = SPI_cursor_find(curname);
@@ -3321,7 +3315,7 @@ exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt)
if (isnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("relative or absolute cursor position is NULL")));
+ errmsg("relative or absolute cursor position is null")));
exec_eval_cleanup(estate);
}
@@ -3396,7 +3390,7 @@ exec_stmt_close(PLpgSQL_execstate *estate, PLpgSQL_stmt_close *stmt)
if (curvar->isnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("cursor variable \"%s\" is NULL", curvar->refname)));
+ errmsg("cursor variable \"%s\" is null", curvar->refname)));
curname = TextDatumGetCString(curvar->value);
portal = SPI_cursor_find(curname);
@@ -3463,7 +3457,7 @@ exec_assign_value(PLpgSQL_execstate *estate,
if (*isNull && var->notnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("NULL cannot be assigned to variable \"%s\" declared NOT NULL",
+ errmsg("null value cannot be assigned to variable \"%s\" declared NOT NULL",
var->refname)));
/*
@@ -3720,8 +3714,8 @@ exec_assign_value(PLpgSQL_execstate *estate,
if (nsubscripts >= MAXDIM)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("number of array dimensions exceeds the maximum allowed, %d",
- MAXDIM)));
+ errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
+ nsubscripts, MAXDIM)));
subscripts[nsubscripts++] = arrayelem->subscript;
target = estate->datums[arrayelem->arrayparentno];
} while (target->dtype == PLPGSQL_DTYPE_ARRAYELEM);
@@ -3757,7 +3751,7 @@ exec_assign_value(PLpgSQL_execstate *estate,
if (subisnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("array subscript in assignment must not be NULL")));
+ errmsg("array subscript in assignment must not be null")));
}
/* Coerce source value to match array element type. */
@@ -5129,7 +5123,7 @@ static void
validate_tupdesc_compat(TupleDesc expected, TupleDesc returned, const char *msg)
{
int i;
- const char *dropped_column_type = gettext_noop("n/a (dropped column)");
+ const char *dropped_column_type = gettext_noop("N/A (dropped column)");
if (!expected || !returned)
ereport(ERROR,
@@ -5402,7 +5396,7 @@ exec_dynquery_with_params(PLpgSQL_execstate *estate, PLpgSQL_expr *dynquery,
if (isnull)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
- errmsg("cannot EXECUTE a null querystring")));
+ errmsg("query string argument of EXECUTE is null")));
/* Get the C-String representation */
querystr = convert_value_to_string(query, restype);
diff --git a/src/pl/plpgsql/src/pl_funcs.c b/src/pl/plpgsql/src/pl_funcs.c
index c91bd6b8d9..c64c22c625 100644
--- a/src/pl/plpgsql/src/pl_funcs.c
+++ b/src/pl/plpgsql/src/pl_funcs.c
@@ -356,7 +356,7 @@ plpgsql_ns_rename(char *oldname, char *newname)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("there is no variable \"%s\" in the current block",
+ errmsg("variable \"%s\" does not exist in the current block",
oldname)));
}
@@ -412,7 +412,7 @@ plpgsql_convert_ident(const char *s, char **output, int numidents)
if (*s != '"') /* should not happen if lexer checked */
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("unterminated \" in name: %s", sstart)));
+ errmsg("unterminated \" in identifier: %s", sstart)));
s++;
*cp = '\0';
/* Truncate to NAMEDATALEN */
diff --git a/src/pl/plpgsql/src/pl_handler.c b/src/pl/plpgsql/src/pl_handler.c
index 9d21fbdf82..ec8c02d7a1 100644
--- a/src/pl/plpgsql/src/pl_handler.c
+++ b/src/pl/plpgsql/src/pl_handler.c
@@ -159,7 +159,7 @@ plpgsql_validator(PG_FUNCTION_ARGS)
!IsPolymorphicType(proc->prorettype))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("plpgsql functions cannot return type %s",
+ errmsg("PL/pgSQL functions cannot return type %s",
format_type_be(proc->prorettype))));
}
@@ -174,7 +174,7 @@ plpgsql_validator(PG_FUNCTION_ARGS)
if (!IsPolymorphicType(argtypes[i]))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("plpgsql functions cannot take type %s",
+ errmsg("PL/pgSQL functions cannot accept type %s",
format_type_be(argtypes[i]))));
}
}
diff --git a/src/pl/plpgsql/src/scan.l b/src/pl/plpgsql/src/scan.l
index b5b0adb16d..99eb934dfc 100644
--- a/src/pl/plpgsql/src/scan.l
+++ b/src/pl/plpgsql/src/scan.l
@@ -254,7 +254,7 @@ dump { return O_DUMP; }
plpgsql_error_lineno = start_lineno;
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("unterminated comment")));
+ errmsg("unterminated /* comment")));
}
/* ----------
@@ -293,7 +293,7 @@ dump { return O_DUMP; }
plpgsql_error_lineno = start_lineno;
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("unterminated string")));
+ errmsg("unterminated quoted string")));
}
{dolqdelim} {
diff --git a/src/test/regress/expected/numerology.out b/src/test/regress/expected/numerology.out
index d404d9db68..0a2e66e919 100644
--- a/src/test/regress/expected/numerology.out
+++ b/src/test/regress/expected/numerology.out
@@ -92,7 +92,7 @@ SELECT f1 AS two, max(f3) AS max_float, min(f3) as min_float
ORDER BY two, max_float, min_float;
two | max_float | min_float
-----+----------------------+-----------------------
- 1 | 1.2345678901234e+200 | 0
+ 1 | 1.2345678901234e+200 | -0
2 | 0 | -1.2345678901234e+200
(2 rows)
@@ -104,7 +104,7 @@ SELECT f1 AS two, max(f3) AS max_float, min(f3) AS min_float
ORDER BY two, max_float, min_float;
two | max_float | min_float
-----+----------------------+-----------------------
- 1 | 1.2345678901234e+200 | 0
+ 1 | 1.2345678901234e+200 | -0
2 | 0 | -1.2345678901234e+200
(2 rows)
diff --git a/src/test/regress/expected/numerology_1.out b/src/test/regress/expected/numerology_1.out
new file mode 100644
index 0000000000..d404d9db68
--- /dev/null
+++ b/src/test/regress/expected/numerology_1.out
@@ -0,0 +1,136 @@
+--
+-- NUMEROLOGY
+-- Test various combinations of numeric types and functions.
+--
+--
+-- Test implicit type conversions
+-- This fails for Postgres v6.1 (and earlier?)
+-- so let's try explicit conversions for now - tgl 97/05/07
+--
+CREATE TABLE TEMP_FLOAT (f1 FLOAT8);
+INSERT INTO TEMP_FLOAT (f1)
+ SELECT float8(f1) FROM INT4_TBL;
+INSERT INTO TEMP_FLOAT (f1)
+ SELECT float8(f1) FROM INT2_TBL;
+SELECT '' AS ten, f1 FROM TEMP_FLOAT
+ ORDER BY f1;
+ ten | f1
+-----+-------------
+ | -2147483647
+ | -123456
+ | -32767
+ | -1234
+ | 0
+ | 0
+ | 1234
+ | 32767
+ | 123456
+ | 2147483647
+(10 rows)
+
+-- int4
+CREATE TABLE TEMP_INT4 (f1 INT4);
+INSERT INTO TEMP_INT4 (f1)
+ SELECT int4(f1) FROM FLOAT8_TBL
+ WHERE (f1 > -2147483647) AND (f1 < 2147483647);
+INSERT INTO TEMP_INT4 (f1)
+ SELECT int4(f1) FROM INT2_TBL;
+SELECT '' AS nine, f1 FROM TEMP_INT4
+ ORDER BY f1;
+ nine | f1
+------+--------
+ | -32767
+ | -1234
+ | -1004
+ | -35
+ | 0
+ | 0
+ | 0
+ | 1234
+ | 32767
+(9 rows)
+
+-- int2
+CREATE TABLE TEMP_INT2 (f1 INT2);
+INSERT INTO TEMP_INT2 (f1)
+ SELECT int2(f1) FROM FLOAT8_TBL
+ WHERE (f1 >= -32767) AND (f1 <= 32767);
+INSERT INTO TEMP_INT2 (f1)
+ SELECT int2(f1) FROM INT4_TBL
+ WHERE (f1 >= -32767) AND (f1 <= 32767);
+SELECT '' AS five, f1 FROM TEMP_INT2
+ ORDER BY f1;
+ five | f1
+------+-------
+ | -1004
+ | -35
+ | 0
+ | 0
+ | 0
+(5 rows)
+
+--
+-- Group-by combinations
+--
+CREATE TABLE TEMP_GROUP (f1 INT4, f2 INT4, f3 FLOAT8);
+INSERT INTO TEMP_GROUP
+ SELECT 1, (- i.f1), (- f.f1)
+ FROM INT4_TBL i, FLOAT8_TBL f;
+INSERT INTO TEMP_GROUP
+ SELECT 2, i.f1, f.f1
+ FROM INT4_TBL i, FLOAT8_TBL f;
+SELECT DISTINCT f1 AS two FROM TEMP_GROUP ORDER BY 1;
+ two
+-----
+ 1
+ 2
+(2 rows)
+
+SELECT f1 AS two, max(f3) AS max_float, min(f3) as min_float
+ FROM TEMP_GROUP
+ GROUP BY f1
+ ORDER BY two, max_float, min_float;
+ two | max_float | min_float
+-----+----------------------+-----------------------
+ 1 | 1.2345678901234e+200 | 0
+ 2 | 0 | -1.2345678901234e+200
+(2 rows)
+
+-- GROUP BY a result column name is not legal per SQL92, but we accept it
+-- anyway (if the name is not the name of any column exposed by FROM).
+SELECT f1 AS two, max(f3) AS max_float, min(f3) AS min_float
+ FROM TEMP_GROUP
+ GROUP BY two
+ ORDER BY two, max_float, min_float;
+ two | max_float | min_float
+-----+----------------------+-----------------------
+ 1 | 1.2345678901234e+200 | 0
+ 2 | 0 | -1.2345678901234e+200
+(2 rows)
+
+SELECT f1 AS two, (max(f3) + 1) AS max_plus_1, (min(f3) - 1) AS min_minus_1
+ FROM TEMP_GROUP
+ GROUP BY f1
+ ORDER BY two, min_minus_1;
+ two | max_plus_1 | min_minus_1
+-----+----------------------+-----------------------
+ 1 | 1.2345678901234e+200 | -1
+ 2 | 1 | -1.2345678901234e+200
+(2 rows)
+
+SELECT f1 AS two,
+ max(f2) + min(f2) AS max_plus_min,
+ min(f3) - 1 AS min_minus_1
+ FROM TEMP_GROUP
+ GROUP BY f1
+ ORDER BY two, min_minus_1;
+ two | max_plus_min | min_minus_1
+-----+--------------+-----------------------
+ 1 | 0 | -1
+ 2 | 0 | -1.2345678901234e+200
+(2 rows)
+
+DROP TABLE TEMP_INT2;
+DROP TABLE TEMP_INT4;
+DROP TABLE TEMP_FLOAT;
+DROP TABLE TEMP_GROUP;
diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out
index 0fe279493f..66bd895f70 100644
--- a/src/test/regress/expected/plpgsql.out
+++ b/src/test/regress/expected/plpgsql.out
@@ -2700,7 +2700,7 @@ begin
end loop flbl1;
end;
$$ language plpgsql;
-ERROR: no such label at or near "flbl1"
+ERROR: label does not exist at or near "flbl1"
LINE 5: end loop flbl1;
^
-- should fail: end label does not match start label
@@ -2714,7 +2714,7 @@ begin
end;
$$ language plpgsql;
ERROR: end label "outer_label" differs from block's label "inner_label"
-CONTEXT: compile of PL/pgSQL function "end_label3" near line 6
+CONTEXT: compilation of PL/pgSQL function "end_label3" near line 6
-- should fail: end label on a block without a start label
create function end_label4() returns void as $$
<<outer_label>>
@@ -2725,7 +2725,7 @@ begin
end;
$$ language plpgsql;
ERROR: end label "outer_label" specified for unlabelled block
-CONTEXT: compile of PL/pgSQL function "end_label4" near line 5
+CONTEXT: compilation of PL/pgSQL function "end_label4" near line 5
-- using list of scalars in fori and fore stmts
create function for_vect() returns void as $proc$
<<lbl>>declare a integer; b varchar; c varchar; r record;
@@ -3266,7 +3266,7 @@ begin
end;
$$ language plpgsql;
ERROR: cursor FOR loop must use a bound cursor variable
-CONTEXT: compile of PL/pgSQL function "forc_bad" near line 4
+CONTEXT: compilation of PL/pgSQL function "forc_bad" near line 4
-- test RETURN QUERY EXECUTE
create or replace function return_dquery()
returns setof int as $$