summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAbbas2011-12-20 14:00:51 +0000
committerAbbas2011-12-20 14:00:51 +0000
commitef0e9f95e51e4828f69da452f0eb97b413bbc2c9 (patch)
tree970729cfc2cfad7085a23aed25a48a9bca9b73c1 /src
parentda267bcdda5995604f1a7d5503485bc48333e45d (diff)
parent9394b60405c43e7da174bcf6bafb42335e9d2ad3 (diff)
Merge branch 'master' of ssh://postgres-xc.git.sourceforge.net/gitroot/postgres-xc/postgres-xc
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/heap.c24
-rw-r--r--src/backend/libpq/be-fsstubs.c105
-rw-r--r--src/backend/parser/parse_expr.c23
-rw-r--r--src/backend/parser/parse_func.c97
-rw-r--r--src/backend/pgxc/plan/planner.c52
-rw-r--r--src/backend/pgxc/pool/postgresql_fdw.c5
-rw-r--r--src/backend/tcop/utility.c44
-rw-r--r--src/gtm/proxy/proxy_main.c2
-rw-r--r--src/include/parser/parse_expr.h4
-rw-r--r--src/include/parser/parse_func.h3
-rw-r--r--src/test/regress/expected/dependency_1.out2
-rw-r--r--src/test/regress/expected/domain_1.out7
-rw-r--r--src/test/regress/expected/uuid_1.out153
-rw-r--r--src/test/regress/output/constraints_1.source218
-rw-r--r--src/test/regress/output/largeobject_3.source264
15 files changed, 605 insertions, 398 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index ed08015d9c..00d12e05e1 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -80,6 +80,8 @@
#include "catalog/pgxc_class.h"
#include "catalog/pgxc_node.h"
#include "pgxc/locator.h"
+#include "pgxc/pgxc.h"
+#include "pgxc/postgresql_fdw.h"
#endif
@@ -2729,28 +2731,6 @@ cookDefault(ParseState *pstate,
Assert(raw_default != NULL);
-#ifdef PGXC
- /*
- * Block use of non-immutable functions as DEFAULT.
- *
- * Support of nextval(), currval(), now() as DEFAULT value in XC needs a special support
- * like SERIAL, so block it for the time being
- *
- * PGXCTODO: As possible implementation, a constraint with non-immutable functions
- * is just created on Coordinator and when an INSERT query needs a default value
- * Coordinator feeds it, rewrite the query, and distributes it to Datanodes
- *
- * Sequence (currval, nextval) and timestamp values (now()...) have
- * to be taken from GTM.
- */
- if (IsA(raw_default,FuncCall))
- if (!IsFuncImmutable(pstate, (FuncCall *) raw_default))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("Postgres-XC does not support DEFAULT with non-immutable functions yet"),
- errdetail("The feature is not currently supported")));
-#endif
-
/*
* Transform raw parsetree to executable expression.
*/
diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c
index 155385f0b9..070e1451e8 100644
--- a/src/backend/libpq/be-fsstubs.c
+++ b/src/backend/libpq/be-fsstubs.c
@@ -101,6 +101,13 @@ lo_open(PG_FUNCTION_ARGS)
LargeObjectDesc *lobjDesc;
int fd;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
#if FSDB
elog(DEBUG4, "lo_open(%u,%d)", lobjId, mode);
#endif
@@ -127,6 +134,13 @@ lo_close(PG_FUNCTION_ARGS)
{
int32 fd = PG_GETARG_INT32(0);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -157,6 +171,13 @@ lo_read(int fd, char *buf, int len)
{
int status;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -183,6 +204,13 @@ lo_write(int fd, const char *buf, int len)
{
int status;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -219,6 +247,13 @@ lo_lseek(PG_FUNCTION_ARGS)
int32 whence = PG_GETARG_INT32(2);
int status;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -234,6 +269,13 @@ lo_creat(PG_FUNCTION_ARGS)
{
Oid lobjId;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
/*
* We don't actually need to store into fscxt, but create it anyway to
* ensure that AtEOXact_LargeObject knows there is state to clean up
@@ -250,6 +292,13 @@ lo_create(PG_FUNCTION_ARGS)
{
Oid lobjId = PG_GETARG_OID(0);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
/*
* We don't actually need to store into fscxt, but create it anyway to
* ensure that AtEOXact_LargeObject knows there is state to clean up
@@ -266,6 +315,13 @@ lo_tell(PG_FUNCTION_ARGS)
{
int32 fd = PG_GETARG_INT32(0);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -279,6 +335,13 @@ lo_unlink(PG_FUNCTION_ARGS)
{
Oid lobjId = PG_GETARG_OID(0);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
/* Must be owner of the largeobject */
if (!lo_compat_privileges &&
!pg_largeobject_ownercheck(lobjId, GetUserId()))
@@ -322,6 +385,13 @@ loread(PG_FUNCTION_ARGS)
bytea *retval;
int totalread;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (len < 0)
len = 0;
@@ -340,6 +410,13 @@ lowrite(PG_FUNCTION_ARGS)
int bytestowrite;
int totalwritten;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
bytestowrite = VARSIZE(wbuf) - VARHDRSZ;
totalwritten = lo_write(fd, VARDATA(wbuf), bytestowrite);
PG_RETURN_INT32(totalwritten);
@@ -358,6 +435,13 @@ lo_import(PG_FUNCTION_ARGS)
{
text *filename = PG_GETARG_TEXT_PP(0);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
PG_RETURN_OID(lo_import_internal(filename, InvalidOid));
}
@@ -371,6 +455,13 @@ lo_import_with_oid(PG_FUNCTION_ARGS)
text *filename = PG_GETARG_TEXT_PP(0);
Oid oid = PG_GETARG_OID(1);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
PG_RETURN_OID(lo_import_internal(filename, oid));
}
@@ -451,6 +542,13 @@ lo_export(PG_FUNCTION_ARGS)
LargeObjectDesc *lobj;
mode_t oumask;
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
#ifndef ALLOW_DANGEROUS_LO_FUNCTIONS
if (!superuser())
ereport(ERROR,
@@ -513,6 +611,13 @@ lo_truncate(PG_FUNCTION_ARGS)
int32 fd = PG_GETARG_INT32(0);
int32 len = PG_GETARG_INT32(1);
+#ifdef PGXC
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("Postgres-XC does not support large object yet"),
+ errdetail("The feature is not currently supported")));
+#endif
+
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 125bfd5eff..fe66137280 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -1248,29 +1248,6 @@ transformFuncCall(ParseState *pstate, FuncCall *fn)
fn->location);
}
-#ifdef PGXC
-/*
- * IsFuncImmutable
- *
- * Check if given function is immutable or not
- * based on the function name and on its arguments
- */
-bool
-IsFuncImmutable(ParseState *pstate, FuncCall *fn)
-{
- ListCell *args;
- List *targs = NIL;
-
- /* Transform list of arguments */
- foreach(args, fn->args)
- {
- targs = lappend(targs, transformExpr(pstate,
- (Node *) lfirst(args)));
- }
-
- return IsParseFuncImmutable(pstate, targs, fn->funcname, fn->func_variadic);
-}
-#endif
static Node *
transformCaseExpr(ParseState *pstate, CaseExpr *c)
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index cfa3f5179f..75f1e20475 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -1619,100 +1619,3 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
return oid;
}
-
-
-#ifdef PGXC
-/*
- * IsParseFuncImmutable
- *
- * Check if given function is immutable or not
- * based on the function name and on its arguments
- * This functionnality will be extended to support functions in constraints
- */
-bool
-IsParseFuncImmutable(ParseState *pstate, List *targs, List *funcname, bool func_variadic)
-{
- ListCell *l;
- ListCell *nextl;
- FuncDetailCode fdresult;
- Oid actual_arg_types[FUNC_MAX_ARGS];
- List *argnames;
- int nargs;
- /* Return results */
- Oid funcid, rettype;
- Oid *declared_arg_types;
- bool retset;
- int nvargs;
- List *argdefaults;
-
- /* Get detailed argument information */
- nargs = 0;
- for (l = list_head(targs); l != NULL; l = nextl)
- {
- Node *arg = lfirst(l);
- Oid argtype = exprType(arg);
-
- nextl = lnext(l);
-
- if (argtype == VOIDOID && IsA(arg, Param))
- {
- targs = list_delete_ptr(targs, arg);
- continue;
- }
- actual_arg_types[nargs++] = argtype;
- }
- argnames = NIL;
-
- foreach(l, targs)
- {
- Node *arg = lfirst(l);
-
- if (IsA(arg, NamedArgExpr))
- {
- NamedArgExpr *na = (NamedArgExpr *) arg;
- ListCell *lc;
-
- /* Reject duplicate arg names */
- foreach(lc, argnames)
- {
- if (strcmp(na->name, (char *) lfirst(lc)) == 0)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("argument name \"%s\" used more than once",
- na->name),
- parser_errposition(pstate, na->location)));
- }
- argnames = lappend(argnames, na->name);
- }
- else
- {
- if (argnames != NIL)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("positional argument cannot follow named argument"),
- parser_errposition(pstate, exprLocation(arg))));
- }
- }
-
- fdresult = func_get_detail(funcname,
- targs,
- argnames,
- nargs,
- actual_arg_types,
- !func_variadic,
- true,
- &funcid, &rettype, &retset, &nvargs,
- &declared_arg_types, &argdefaults);
-
- /*
- * Now only the function ID is used to check if function is immutable or not,
- * but for function support in DEFAULT values, this function can be easily extended
- * for other analysis purposes.
- */
- if (func_volatile(funcid) == PROVOLATILE_IMMUTABLE)
- return true;
- else
- return false;
-}
-#endif
-
diff --git a/src/backend/pgxc/plan/planner.c b/src/backend/pgxc/plan/planner.c
index add9b3a119..5a21bb273d 100644
--- a/src/backend/pgxc/plan/planner.c
+++ b/src/backend/pgxc/plan/planner.c
@@ -560,6 +560,38 @@ get_plan_nodes_insert(PlannerInfo *root, RemoteQuery *step)
(errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
(errmsg("Could not find relation for oid = %d", rte->relid))));
+ /*
+ * Evaluate expressions in target list before trying any optimisations.
+ * The following flow is respected depending on table distribution,
+ * target column (distribution column or not) and expression shippability.
+ * For a hash-distributed table:
+ * - Non-shippable expression whatever the target column, return exec_nodes
+ * as NULL and go through standard planner
+ * - Shippable expression on a distribution column, go through optimization
+ * In this case if target column is distributable, node is determined
+ * from expression if constant can be obtained. An expression can be used
+ * also to determine a safe node list a execution time.
+ * For replicated or round robin tables (no distribution column):
+ * - Non-shippable expression, return exec_nodes as NULL and go through
+ * standard planner
+ * - Shippable expression, go through the optimization process
+ * PGXCTODO: for the time being query goes through standard planner if at least
+ * one non-shippable expression is found, we should be able to partially push
+ * down foreign expressions.
+ */
+ foreach(lc, query->targetList)
+ {
+ TargetEntry *tle = (TargetEntry *) lfirst(lc);
+ Expr *expr = tle->expr;
+
+ /* If expression is not shippable, go through standard planner */
+ if (!is_foreign_expr((Node *) expr, NULL))
+ {
+ step->exec_nodes = NULL;
+ return;
+ }
+ }
+
/* Optimization is only done for distributed tables */
if (query->jointree != NULL
&& query->jointree->fromlist != NULL
@@ -604,10 +636,13 @@ get_plan_nodes_insert(PlannerInfo *root, RemoteQuery *step)
*/
}
-
- if ( (rel_loc_info->partAttrName != NULL) &&
- ( (rel_loc_info->locatorType == LOCATOR_TYPE_HASH) ||
- (rel_loc_info->locatorType == LOCATOR_TYPE_MODULO) ))
+ /*
+ * Search for an expression value that can be used for
+ * distribute table optimisation.
+ */
+ if ((rel_loc_info->partAttrName != NULL) &&
+ ((rel_loc_info->locatorType == LOCATOR_TYPE_HASH) ||
+ (rel_loc_info->locatorType == LOCATOR_TYPE_MODULO)))
{
Expr *checkexpr;
TargetEntry *tle = NULL;
@@ -667,14 +702,11 @@ get_plan_nodes_insert(PlannerInfo *root, RemoteQuery *step)
(errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
(errmsg("Could not find relation for oid = %d", rte->relid))));
- if ( col_base->colname != NULL &&
+ if (col_base->colname != NULL &&
source_rel_loc_info->partAttrName != NULL &&
strcmp(col_base->colname, source_rel_loc_info->partAttrName) == 0 &&
- (
- source_rel_loc_info->locatorType == LOCATOR_TYPE_HASH ||
- source_rel_loc_info->locatorType == LOCATOR_TYPE_MODULO
- )
- )
+ (source_rel_loc_info->locatorType == LOCATOR_TYPE_HASH ||
+ source_rel_loc_info->locatorType == LOCATOR_TYPE_MODULO))
{
/*
* Partition columns match, we have a "single-step INSERT SELECT".
diff --git a/src/backend/pgxc/pool/postgresql_fdw.c b/src/backend/pgxc/pool/postgresql_fdw.c
index 0a42426ab0..2aef35632b 100644
--- a/src/backend/pgxc/pool/postgresql_fdw.c
+++ b/src/backend/pgxc/pool/postgresql_fdw.c
@@ -20,6 +20,7 @@
#include "nodes/nodeFuncs.h"
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
+#include "optimizer/planmain.h"
#include "parser/scansup.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
@@ -143,7 +144,11 @@ foreign_qual_walker(Node *node, foreign_qual_context *context)
* foreign server . It is not necessary to worry about oprrest
* and oprjoin here because they are invoked by planner but not
* executor. DistinctExpr is a typedef of OpExpr.
+ * We need also to be sure that function id is correctly set
+ * before evaluation.
*/
+ set_opfuncid((OpExpr *) node);
+
if (!is_immutable_func(((OpExpr*) node)->opfuncid))
return true;
break;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index ee619b21dd..5194af279c 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1258,8 +1258,7 @@ standard_ProcessUtility(Node *parsetree,
/* Launch GRANT on Coordinator if object is a sequence */
if ((stmt->objtype == ACL_OBJECT_RELATION &&
- stmt->targtype == ACL_TARGET_OBJECT) ||
- stmt->objtype == ACL_OBJECT_SEQUENCE)
+ stmt->targtype == ACL_TARGET_OBJECT))
{
/*
* In case object is a relation, differenciate the case
@@ -1289,7 +1288,7 @@ standard_ProcessUtility(Node *parsetree,
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("PGXC does not support GRANT on multiple object types"),
- errdetail("Grant VIEW/SEQUENCE/TABLE with separate queries")));
+ errdetail("Grant VIEW/TABLE with separate queries")));
}
}
}
@@ -1510,14 +1509,14 @@ standard_ProcessUtility(Node *parsetree,
#ifdef PGXC
if (IS_PGXC_COORDINATOR)
{
- /*
- * If sequence is temporary, no need to send this query to other
- * remote Coordinators.
- */
CreateSeqStmt *stmt = (CreateSeqStmt *) parsetree;
+ bool is_temp = stmt->sequence->relpersistence == RELPERSISTENCE_TEMP;
- if (stmt->sequence->relpersistence != RELPERSISTENCE_TEMP)
- ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_COORDS, false);
+ /* Set temporary object flag in pooler */
+ if (is_temp)
+ PoolManagerSetCommand(POOL_CMD_TEMP, NULL);
+
+ ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, is_temp);
}
#endif
break;
@@ -1527,15 +1526,15 @@ standard_ProcessUtility(Node *parsetree,
#ifdef PGXC
if (IS_PGXC_COORDINATOR)
{
- /*
- * If sequence is temporary, no need to send this query to other
- * remote Coordinators.
- */
AlterSeqStmt *stmt = (AlterSeqStmt *) parsetree;
- Oid relid = RangeVarGetRelid(stmt->sequence, false);
+ bool is_temp;
+ RemoteQueryExecType exec_type;
- if (!IsTempSequence(relid))
- ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_COORDS, false);
+ exec_type = ExecUtilityFindNodes(OBJECT_SEQUENCE,
+ RangeVarGetRelid(stmt->sequence, false),
+ &is_temp);
+
+ ExecUtilityStmtOnNodes(queryString, NULL, false, exec_type, is_temp);
}
#endif
break;
@@ -2168,11 +2167,8 @@ ExecUtilityFindNodes(ObjectType object_type,
switch (object_type)
{
case OBJECT_SEQUENCE:
- /* Check if object is a temporary sequence */
- if ((*is_temp = IsTempSequence(relid)))
- exec_type = EXEC_ON_NONE;
- else
- exec_type = EXEC_ON_COORDS;
+ *is_temp = IsTempTable(relid);
+ exec_type = EXEC_ON_ALL_NODES;
break;
case OBJECT_TABLE:
@@ -2220,10 +2216,8 @@ ExecUtilityFindNodesRelkind(Oid relid, bool *is_temp)
switch (relkind_str)
{
case RELKIND_SEQUENCE:
- if ((*is_temp = IsTempSequence(relid)))
- exec_type = EXEC_ON_NONE;
- else
- exec_type = EXEC_ON_COORDS;
+ *is_temp = IsTempTable(relid);
+ exec_type = EXEC_ON_ALL_NODES;
break;
case RELKIND_RELATION:
diff --git a/src/gtm/proxy/proxy_main.c b/src/gtm/proxy/proxy_main.c
index 85166ec70d..1586fd7d13 100644
--- a/src/gtm/proxy/proxy_main.c
+++ b/src/gtm/proxy/proxy_main.c
@@ -200,6 +200,8 @@ MainThreadInit()
exit(1);
}
+ memset((char *)thrinfo, 0, sizeof(GTMProxy_ThreadInfo));
+
if (SetMyThreadInfo(thrinfo))
{
fprintf(stderr, "SetMyThreadInfo failed: %d", errno);
diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h
index 56b1b4284d..f3edf702ec 100644
--- a/src/include/parser/parse_expr.h
+++ b/src/include/parser/parse_expr.h
@@ -19,8 +19,4 @@
extern bool Transform_null_equals;
extern Node *transformExpr(ParseState *pstate, Node *expr);
-#ifdef PGXC
-extern bool IsFuncImmutable(ParseState *pstate, FuncCall *fn);
-#endif
-
#endif /* PARSE_EXPR_H */
diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h
index 05e88968a6..d28c473ebe 100644
--- a/src/include/parser/parse_func.h
+++ b/src/include/parser/parse_func.h
@@ -83,7 +83,4 @@ extern Oid LookupAggNameTypeNames(List *aggname, List *argtypes,
bool noError);
extern void check_pg_get_expr_args(ParseState *pstate, Oid fnoid, List *args);
-#ifdef PGXC
-extern bool IsParseFuncImmutable(ParseState *pstate, List *fn_args, List *funcname, bool func_variadic);
-#endif
#endif /* PARSE_FUNC_H */
diff --git a/src/test/regress/expected/dependency_1.out b/src/test/regress/expected/dependency_1.out
index 827f442672..eeb2a1c110 100644
--- a/src/test/regress/expected/dependency_1.out
+++ b/src/test/regress/expected/dependency_1.out
@@ -102,8 +102,6 @@ CREATE TABLE deptest2 (f1 int);
-- make a serial column the hard way
CREATE SEQUENCE ss1;
ALTER TABLE deptest2 ALTER f1 SET DEFAULT nextval('ss1');
-ERROR: Postgres-XC does not support DEFAULT with non-immutable functions yet
-DETAIL: The feature is not currently supported
ALTER SEQUENCE ss1 OWNED BY deptest2.f1;
RESET SESSION AUTHORIZATION;
REASSIGN OWNED BY regression_user1 TO regression_user2;
diff --git a/src/test/regress/expected/domain_1.out b/src/test/regress/expected/domain_1.out
index f2f45379d6..e3a6127396 100644
--- a/src/test/regress/expected/domain_1.out
+++ b/src/test/regress/expected/domain_1.out
@@ -246,8 +246,6 @@ create domain ddef2 oid DEFAULT '12';
create domain ddef3 text DEFAULT 5;
create sequence ddef4_seq;
create domain ddef4 int4 DEFAULT nextval('ddef4_seq');
-ERROR: Postgres-XC does not support DEFAULT with non-immutable functions yet
-DETAIL: The feature is not currently supported
create domain ddef5 numeric(8,2) NOT NULL DEFAULT '12.12';
create table defaulttest
( col1 ddef1
@@ -259,9 +257,7 @@ create table defaulttest
, col7 ddef4 DEFAULT 8000
, col8 ddef5
);
-ERROR: type "ddef4" does not exist
-LINE 5: , col4 ddef4 PRIMARY KEY
- ^
+ERROR: Column col4 is not a hash distributable data type
insert into defaulttest(col4) values(0); -- fails, col5 defaults to null
ERROR: relation "defaulttest" does not exist
LINE 1: insert into defaulttest(col4) values(0);
@@ -410,7 +406,6 @@ drop domain ddef1 restrict;
drop domain ddef2 restrict;
drop domain ddef3 restrict;
drop domain ddef4 restrict;
-ERROR: type "ddef4" does not exist
drop domain ddef5 restrict;
drop sequence ddef4_seq;
-- Test domains over domains
diff --git a/src/test/regress/expected/uuid_1.out b/src/test/regress/expected/uuid_1.out
index 39ea1e952d..982f1dd7b2 100644
--- a/src/test/regress/expected/uuid_1.out
+++ b/src/test/regress/expected/uuid_1.out
@@ -5,147 +5,144 @@ CREATE TABLE guid1
guid_field UUID,
text_field TEXT DEFAULT(now())
);
-ERROR: Postgres-XC does not support DEFAULT with non-immutable functions yet
-DETAIL: The feature is not currently supported
CREATE TABLE guid2
(
guid_field UUID,
text_field TEXT DEFAULT(now())
);
-ERROR: Postgres-XC does not support DEFAULT with non-immutable functions yet
-DETAIL: The feature is not currently supported
-- inserting invalid data tests
-- too long
INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111F');
-ERROR: relation "guid1" does not exist
+ERROR: invalid input syntax for uuid: "11111111-1111-1111-1111-111111111111F"
LINE 1: INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-111...
- ^
+ ^
-- too short
INSERT INTO guid1(guid_field) VALUES('{11111111-1111-1111-1111-11111111111}');
-ERROR: relation "guid1" does not exist
+ERROR: invalid input syntax for uuid: "{11111111-1111-1111-1111-11111111111}"
LINE 1: INSERT INTO guid1(guid_field) VALUES('{11111111-1111-1111-11...
- ^
+ ^
-- valid data but invalid format
INSERT INTO guid1(guid_field) VALUES('111-11111-1111-1111-1111-111111111111');
-ERROR: relation "guid1" does not exist
+ERROR: invalid input syntax for uuid: "111-11111-1111-1111-1111-111111111111"
LINE 1: INSERT INTO guid1(guid_field) VALUES('111-11111-1111-1111-11...
- ^
+ ^
INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222 ');
-ERROR: relation "guid1" does not exist
+ERROR: invalid input syntax for uuid: "{22222222-2222-2222-2222-222222222222 "
LINE 1: INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-22...
- ^
+ ^
-- invalid data
INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-G111-111111111111');
-ERROR: relation "guid1" does not exist
+ERROR: invalid input syntax for uuid: "11111111-1111-1111-G111-111111111111"
LINE 1: INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-G11...
- ^
+ ^
INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-1111-111111111111');
-ERROR: relation "guid1" does not exist
+ERROR: invalid input syntax for uuid: "11+11111-1111-1111-1111-111111111111"
LINE 1: INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-111...
- ^
+ ^
--inserting three input formats
INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
-ERROR: relation "guid1" does not exist
-LINE 1: INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-111...
- ^
INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}');
-ERROR: relation "guid1" does not exist
-LINE 1: INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-22...
- ^
INSERT INTO guid1(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e');
-ERROR: relation "guid1" does not exist
-LINE 1: INSERT INTO guid1(guid_field) VALUES('3f3e3c3b3a303938373635...
- ^
-- retrieving the inserted data
SELECT guid_field FROM guid1 ORDER BY guid_field;
-ERROR: relation "guid1" does not exist
-LINE 1: SELECT guid_field FROM guid1 ORDER BY guid_field;
- ^
+ guid_field
+--------------------------------------
+ 11111111-1111-1111-1111-111111111111
+ 22222222-2222-2222-2222-222222222222
+ 3f3e3c3b-3a30-3938-3736-353433a2313e
+(3 rows)
+
-- ordering test
SELECT guid_field FROM guid1 ORDER BY guid_field ASC;
-ERROR: relation "guid1" does not exist
-LINE 1: SELECT guid_field FROM guid1 ORDER BY guid_field ASC;
- ^
+ guid_field
+--------------------------------------
+ 11111111-1111-1111-1111-111111111111
+ 22222222-2222-2222-2222-222222222222
+ 3f3e3c3b-3a30-3938-3736-353433a2313e
+(3 rows)
+
SELECT guid_field FROM guid1 ORDER BY guid_field DESC;
-ERROR: relation "guid1" does not exist
-LINE 1: SELECT guid_field FROM guid1 ORDER BY guid_field DESC;
- ^
+ guid_field
+--------------------------------------
+ 3f3e3c3b-3a30-3938-3736-353433a2313e
+ 22222222-2222-2222-2222-222222222222
+ 11111111-1111-1111-1111-111111111111
+(3 rows)
+
-- = operator test
SELECT COUNT(*) FROM guid1 WHERE guid_field = '3f3e3c3b-3a30-3938-3736-353433a2313e';
-ERROR: relation "guid1" does not exist
-LINE 1: SELECT COUNT(*) FROM guid1 WHERE guid_field = '3f3e3c3b-3a30...
- ^
+ count
+-------
+ 1
+(1 row)
+
-- <> operator test
SELECT COUNT(*) FROM guid1 WHERE guid_field <> '11111111111111111111111111111111';
-ERROR: relation "guid1" does not exist
-LINE 1: SELECT COUNT(*) FROM guid1 WHERE guid_field <> '111111111111...
- ^
+ count
+-------
+ 2
+(1 row)
+
-- < operator test
SELECT COUNT(*) FROM guid1 WHERE guid_field < '22222222-2222-2222-2222-222222222222';
-ERROR: relation "guid1" does not exist
-LINE 1: SELECT COUNT(*) FROM guid1 WHERE guid_field < '22222222-2222...
- ^
+ count
+-------
+ 1
+(1 row)
+
-- <= operator test
SELECT COUNT(*) FROM guid1 WHERE guid_field <= '22222222-2222-2222-2222-222222222222';
-ERROR: relation "guid1" does not exist
-LINE 1: SELECT COUNT(*) FROM guid1 WHERE guid_field <= '22222222-222...
- ^
+ count
+-------
+ 2
+(1 row)
+
-- > operator test
SELECT COUNT(*) FROM guid1 WHERE guid_field > '22222222-2222-2222-2222-222222222222';
-ERROR: relation "guid1" does not exist
-LINE 1: SELECT COUNT(*) FROM guid1 WHERE guid_field > '22222222-2222...
- ^
+ count
+-------
+ 1
+(1 row)
+
-- >= operator test
SELECT COUNT(*) FROM guid1 WHERE guid_field >= '22222222-2222-2222-2222-222222222222';
-ERROR: relation "guid1" does not exist
-LINE 1: SELECT COUNT(*) FROM guid1 WHERE guid_field >= '22222222-222...
- ^
+ count
+-------
+ 2
+(1 row)
+
-- btree and hash index creation test
CREATE INDEX guid1_btree ON guid1 USING BTREE (guid_field);
-ERROR: relation "guid1" does not exist
CREATE INDEX guid1_hash ON guid1 USING HASH (guid_field);
-ERROR: relation "guid1" does not exist
-- unique index test
CREATE UNIQUE INDEX guid1_unique_BTREE ON guid1 USING BTREE (guid_field);
-ERROR: relation "guid1" does not exist
+ERROR: Unique index of partitioned table must contain the hash/modulo distribution column.
-- should fail
INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
-ERROR: relation "guid1" does not exist
-LINE 1: INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-111...
- ^
-- check to see whether the new indexes are actually there
SELECT count(*) FROM pg_class WHERE relkind='i' AND relname LIKE 'guid%';
count
-------
- 0
+ 2
(1 row)
-- populating the test tables with additional records
INSERT INTO guid1(guid_field) VALUES('44444444-4444-4444-4444-444444444444');
-ERROR: relation "guid1" does not exist
-LINE 1: INSERT INTO guid1(guid_field) VALUES('44444444-4444-4444-444...
- ^
INSERT INTO guid2(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
-ERROR: relation "guid2" does not exist
-LINE 1: INSERT INTO guid2(guid_field) VALUES('11111111-1111-1111-111...
- ^
INSERT INTO guid2(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}');
-ERROR: relation "guid2" does not exist
-LINE 1: INSERT INTO guid2(guid_field) VALUES('{22222222-2222-2222-22...
- ^
INSERT INTO guid2(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e');
-ERROR: relation "guid2" does not exist
-LINE 1: INSERT INTO guid2(guid_field) VALUES('3f3e3c3b3a303938373635...
- ^
-- join test
SELECT COUNT(*) FROM guid1 g1 INNER JOIN guid2 g2 ON g1.guid_field = g2.guid_field;
-ERROR: relation "guid1" does not exist
-LINE 1: SELECT COUNT(*) FROM guid1 g1 INNER JOIN guid2 g2 ON g1.guid...
- ^
+ count
+-------
+ 4
+(1 row)
+
SELECT COUNT(*) FROM guid1 g1 LEFT JOIN guid2 g2 ON g1.guid_field = g2.guid_field WHERE g2.guid_field IS NULL;
-ERROR: relation "guid1" does not exist
-LINE 1: SELECT COUNT(*) FROM guid1 g1 LEFT JOIN guid2 g2 ON g1.guid_...
- ^
+ count
+-------
+ 1
+(1 row)
+
-- clean up
DROP TABLE guid1, guid2 CASCADE;
-ERROR: table "guid1" does not exist
diff --git a/src/test/regress/output/constraints_1.source b/src/test/regress/output/constraints_1.source
index bd04188535..e6af9d80f5 100644
--- a/src/test/regress/output/constraints_1.source
+++ b/src/test/regress/output/constraints_1.source
@@ -30,28 +30,19 @@ SELECT '' AS five, * FROM DEFAULT_TBL ORDER BY i,x,f;
CREATE SEQUENCE DEFAULT_SEQ;
CREATE TABLE DEFAULTEXPR_TBL (i1 int DEFAULT 100 + (200-199) * 2,
i2 int DEFAULT nextval('default_seq'));
-ERROR: Postgres-XC does not support DEFAULT with non-immutable functions yet
-DETAIL: The feature is not currently supported
INSERT INTO DEFAULTEXPR_TBL VALUES (-1, -2);
-ERROR: relation "defaultexpr_tbl" does not exist
-LINE 1: INSERT INTO DEFAULTEXPR_TBL VALUES (-1, -2);
- ^
INSERT INTO DEFAULTEXPR_TBL (i1) VALUES (-3);
-ERROR: relation "defaultexpr_tbl" does not exist
-LINE 1: INSERT INTO DEFAULTEXPR_TBL (i1) VALUES (-3);
- ^
INSERT INTO DEFAULTEXPR_TBL (i2) VALUES (-4);
-ERROR: relation "defaultexpr_tbl" does not exist
-LINE 1: INSERT INTO DEFAULTEXPR_TBL (i2) VALUES (-4);
- ^
INSERT INTO DEFAULTEXPR_TBL (i2) VALUES (NULL);
-ERROR: relation "defaultexpr_tbl" does not exist
-LINE 1: INSERT INTO DEFAULTEXPR_TBL (i2) VALUES (NULL);
- ^
SELECT '' AS four, * FROM DEFAULTEXPR_TBL ORDER BY i1,i2;
-ERROR: relation "defaultexpr_tbl" does not exist
-LINE 1: SELECT '' AS four, * FROM DEFAULTEXPR_TBL ORDER BY i1,i2;
- ^
+ four | i1 | i2
+------+-----+----
+ | -3 | 1
+ | -1 | -2
+ | 102 | -4
+ | 102 |
+(4 rows)
+
-- syntax errors
-- test for extraneous comma
CREATE TABLE error_tbl (i int DEFAULT (100, ));
@@ -120,16 +111,13 @@ CREATE TABLE INSERT_TBL (x INT DEFAULT nextval('insert_seq'),
z INT DEFAULT -1 * currval('insert_seq'),
CONSTRAINT INSERT_CON CHECK (x >= 3 AND y <> 'check failed' AND x < 8),
CHECK (x + z = 0));
-ERROR: Postgres-XC does not support DEFAULT with non-immutable functions yet
-DETAIL: The feature is not currently supported
INSERT INTO INSERT_TBL(x,z) VALUES (2, -2);
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(x,z) VALUES (2, -2);
- ^
+ERROR: new row for relation "insert_tbl" violates check constraint "insert_con"
SELECT '' AS zero, * FROM INSERT_TBL order by x,y,z;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: SELECT '' AS zero, * FROM INSERT_TBL order by x,y,z;
- ^
+ zero | x | y | z
+------+---+---+---
+(0 rows)
+
SELECT 'one' AS one, nextval('insert_seq');
one | nextval
-----+---------
@@ -137,173 +125,147 @@ SELECT 'one' AS one, nextval('insert_seq');
(1 row)
INSERT INTO INSERT_TBL(y) VALUES ('Y');
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(y) VALUES ('Y');
- ^
+ERROR: new row for relation "insert_tbl" violates check constraint "insert_con"
INSERT INTO INSERT_TBL(y) VALUES ('Y');
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(y) VALUES ('Y');
- ^
INSERT INTO INSERT_TBL(x,z) VALUES (1, -2);
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(x,z) VALUES (1, -2);
- ^
+ERROR: new row for relation "insert_tbl" violates check constraint "insert_tbl_check"
INSERT INTO INSERT_TBL(z,x) VALUES (-7, 7);
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(z,x) VALUES (-7, 7);
- ^
INSERT INTO INSERT_TBL VALUES (5, 'check failed', -5);
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL VALUES (5, 'check failed', -5);
- ^
+ERROR: new row for relation "insert_tbl" violates check constraint "insert_con"
INSERT INTO INSERT_TBL VALUES (7, '!check failed', -7);
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL VALUES (7, '!check failed', -7);
- ^
INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-');
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-');
- ^
SELECT '' AS four, * FROM INSERT_TBL order by x,y,z;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: SELECT '' AS four, * FROM INSERT_TBL order by x,y,z;
- ^
+ four | x | y | z
+------+---+---------------+----
+ | 3 | Y | -3
+ | 4 | -!NULL- | -4
+ | 7 | !check failed | -7
+ | 7 | -NULL- | -7
+(4 rows)
+
INSERT INTO INSERT_TBL(y,z) VALUES ('check failed', 4);
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(y,z) VALUES ('check failed', 4);
- ^
+ERROR: new row for relation "insert_tbl" violates check constraint "insert_tbl_check"
INSERT INTO INSERT_TBL(x,y) VALUES (5, 'check failed');
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(x,y) VALUES (5, 'check failed');
- ^
+ERROR: new row for relation "insert_tbl" violates check constraint "insert_con"
INSERT INTO INSERT_TBL(x,y) VALUES (5, '!check failed');
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(x,y) VALUES (5, '!check failed');
- ^
INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-');
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-');
- ^
SELECT '' AS six, * FROM INSERT_TBL order by x,y,z;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: SELECT '' AS six, * FROM INSERT_TBL order by x,y,z;
- ^
+ six | x | y | z
+-----+---+---------------+----
+ | 3 | Y | -3
+ | 4 | -!NULL- | -4
+ | 5 | !check failed | -5
+ | 6 | -!NULL- | -6
+ | 7 | !check failed | -7
+ | 7 | -NULL- | -7
+(6 rows)
+
SELECT 'seven' AS one, nextval('insert_seq');
one | nextval
-------+---------
- seven | 2
+ seven | 7
(1 row)
INSERT INTO INSERT_TBL(y) VALUES ('Y');
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(y) VALUES ('Y');
- ^
+ERROR: new row for relation "insert_tbl" violates check constraint "insert_con"
SELECT 'eight' AS one, currval('insert_seq');
one | currval
-------+---------
- eight | 2
+ eight | 8
(1 row)
-- According to SQL92, it is OK to insert a record that gives rise to NULL
-- constraint-condition results. Postgres used to reject this, but it
-- was wrong:
INSERT INTO INSERT_TBL VALUES (null, null, null);
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL VALUES (null, null, null);
- ^
SELECT '' AS nine, * FROM INSERT_TBL order by x,y,z;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: SELECT '' AS nine, * FROM INSERT_TBL order by x,y,z;
- ^
+ nine | x | y | z
+------+---+---------------+----
+ | 3 | Y | -3
+ | 4 | -!NULL- | -4
+ | 5 | !check failed | -5
+ | 6 | -!NULL- | -6
+ | 7 | !check failed | -7
+ | 7 | -NULL- | -7
+ | | |
+(7 rows)
+
--
-- Check inheritance of defaults and constraints
--
CREATE TABLE INSERT_CHILD (cx INT default 42,
cy INT CHECK (cy > x))
INHERITS (INSERT_TBL);
-ERROR: relation "insert_tbl" does not exist
INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,11);
-ERROR: relation "insert_child" does not exist
-LINE 1: INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,11);
- ^
INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,6);
-ERROR: relation "insert_child" does not exist
-LINE 1: INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,6);
- ^
+ERROR: new row for relation "insert_child" violates check constraint "insert_child_check"
INSERT INTO INSERT_CHILD(x,z,cy) VALUES (6,-7,7);
-ERROR: relation "insert_child" does not exist
-LINE 1: INSERT INTO INSERT_CHILD(x,z,cy) VALUES (6,-7,7);
- ^
+ERROR: new row for relation "insert_child" violates check constraint "insert_tbl_check"
INSERT INTO INSERT_CHILD(x,y,z,cy) VALUES (6,'check failed',-6,7);
-ERROR: relation "insert_child" does not exist
-LINE 1: INSERT INTO INSERT_CHILD(x,y,z,cy) VALUES (6,'check failed',...
- ^
+ERROR: new row for relation "insert_child" violates check constraint "insert_con"
SELECT * FROM INSERT_CHILD order by 1,2,3;
-ERROR: relation "insert_child" does not exist
-LINE 1: SELECT * FROM INSERT_CHILD order by 1,2,3;
- ^
+ x | y | z | cx | cy
+---+--------+----+----+----
+ 7 | -NULL- | -7 | 42 | 11
+(1 row)
+
DROP TABLE INSERT_CHILD;
-ERROR: table "insert_child" does not exist
--
-- Check constraints on INSERT INTO
--
DELETE FROM INSERT_TBL;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: DELETE FROM INSERT_TBL;
- ^
ALTER SEQUENCE INSERT_SEQ RESTART WITH 4;
CREATE TABLE tmp (xd INT, yd TEXT, zd INT);
INSERT INTO tmp VALUES (null, 'Y', null);
INSERT INTO tmp VALUES (5, '!check failed', null);
INSERT INTO tmp VALUES (null, 'try again', null);
INSERT INTO INSERT_TBL(y) select yd from tmp;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(y) select yd from tmp;
- ^
SELECT '' AS three, * FROM INSERT_TBL order by x,y,z;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: SELECT '' AS three, * FROM INSERT_TBL order by x,y,z;
- ^
+ three | x | y | z
+-------+---+---------------+----
+ | 4 | Y | -4
+ | 5 | !check failed | -5
+ | 6 | try again | -6
+(3 rows)
+
INSERT INTO INSERT_TBL SELECT * FROM tmp WHERE yd = 'try again';
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL SELECT * FROM tmp WHERE yd = 'try aga...
- ^
INSERT INTO INSERT_TBL(y,z) SELECT yd, -7 FROM tmp WHERE yd = 'try again';
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(y,z) SELECT yd, -7 FROM tmp WHERE yd ...
- ^
INSERT INTO INSERT_TBL(y,z) SELECT yd, -8 FROM tmp WHERE yd = 'try again';
-ERROR: relation "insert_tbl" does not exist
-LINE 1: INSERT INTO INSERT_TBL(y,z) SELECT yd, -8 FROM tmp WHERE yd ...
- ^
+ERROR: new row for relation "insert_tbl" violates check constraint "insert_con"
SELECT '' AS four, * FROM INSERT_TBL order by x,y,z;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: SELECT '' AS four, * FROM INSERT_TBL order by x,y,z;
- ^
+ four | x | y | z
+------+---+---------------+----
+ | 4 | Y | -4
+ | 5 | !check failed | -5
+ | 6 | try again | -6
+ | 7 | try again | -7
+ | | try again |
+ | | try again |
+(6 rows)
+
DROP TABLE tmp;
--
-- Check constraints on UPDATE
--
UPDATE INSERT_TBL SET x = NULL WHERE x = 5;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: UPDATE INSERT_TBL SET x = NULL WHERE x = 5;
- ^
+ERROR: Partition column can't be updated in current version
UPDATE INSERT_TBL SET x = 6 WHERE x = 6;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: UPDATE INSERT_TBL SET x = 6 WHERE x = 6;
- ^
+ERROR: Partition column can't be updated in current version
UPDATE INSERT_TBL SET x = -z, z = -x;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: UPDATE INSERT_TBL SET x = -z, z = -x;
- ^
+ERROR: Partition column can't be updated in current version
UPDATE INSERT_TBL SET x = z, z = x;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: UPDATE INSERT_TBL SET x = z, z = x;
- ^
+ERROR: Partition column can't be updated in current version
SELECT * FROM INSERT_TBL order by x,y,z;
-ERROR: relation "insert_tbl" does not exist
-LINE 1: SELECT * FROM INSERT_TBL order by x,y,z;
- ^
+ x | y | z
+---+---------------+----
+ 4 | Y | -4
+ 5 | !check failed | -5
+ 6 | try again | -6
+ 7 | try again | -7
+ | try again |
+ | try again |
+(6 rows)
+
-- DROP TABLE INSERT_TBL;
--
-- Check constraints on COPY FROM
diff --git a/src/test/regress/output/largeobject_3.source b/src/test/regress/output/largeobject_3.source
new file mode 100644
index 0000000000..5c350f37a4
--- /dev/null
+++ b/src/test/regress/output/largeobject_3.source
@@ -0,0 +1,264 @@
+--
+-- Test large object support
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- Load a file
+CREATE TABLE lotest_stash_values (loid oid, junk integer, fd integer);
+-- lo_creat(mode integer) returns oid
+-- The mode arg to lo_creat is unused, some vestigal holdover from ancient times
+-- returns the large object id
+INSERT INTO lotest_stash_values (loid) VALUES( lo_creat(42) );
+ERROR: Postgres-XC does not support large object yet
+DETAIL: The feature is not currently supported
+-- NOTE: large objects require transactions
+BEGIN;
+-- lo_open(lobjId oid, mode integer) returns integer
+-- The mode parameter to lo_open uses two constants:
+-- INV_READ = 0x20000
+-- INV_WRITE = 0x40000
+-- The return value is a file descriptor-like value which remains valid for the
+-- transaction.
+UPDATE lotest_stash_values SET fd = lo_open(loid, CAST(x'20000' | x'40000' AS integer));
+-- loread/lowrite names are wonky, different from other functions which are lo_*
+-- lowrite(fd integer, data bytea) returns integer
+-- the integer is the number of bytes written
+SELECT lowrite(fd, '
+Whose woods these are I think I know,
+His house is in the village though.
+He will not see me stopping here,
+To watch his woods fill up with snow.
+
+My little horse must think it queer,
+To stop without a farmhouse near,
+Between the woods and frozen lake,
+The darkest evening of the year.
+
+He gives his harness bells a shake,
+To ask if there is some mistake.
+The only other sound''s the sweep,
+Of easy wind and downy flake.
+
+The woods are lovely, dark and deep,
+But I have promises to keep,
+And miles to go before I sleep,
+And miles to go before I sleep.
+
+ -- Robert Frost
+') FROM lotest_stash_values;
+ lowrite
+---------
+(0 rows)
+
+-- lo_close(fd integer) returns integer
+-- return value is 0 for success, or <0 for error (actually only -1, but...)
+SELECT lo_close(fd) FROM lotest_stash_values;
+ lo_close
+----------
+(0 rows)
+
+END;
+-- Read out a portion
+BEGIN;
+UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));
+-- lo_lseek(fd integer, offset integer, whence integer) returns integer
+-- offset is in bytes, whence is one of three values:
+-- SEEK_SET (= 0) meaning relative to beginning
+-- SEEK_CUR (= 1) meaning relative to current position
+-- SEEK_END (= 2) meaning relative to end (offset better be negative)
+-- returns current position in file
+SELECT lo_lseek(fd, 422, 0) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+-- loread/lowrite names are wonky, different from other functions which are lo_*
+-- loread(fd integer, len integer) returns bytea
+SELECT loread(fd, 35) FROM lotest_stash_values;
+ loread
+--------
+(0 rows)
+
+SELECT lo_lseek(fd, -19, 1) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT lowrite(fd, 'n') FROM lotest_stash_values;
+ lowrite
+---------
+(0 rows)
+
+SELECT lo_tell(fd) FROM lotest_stash_values;
+ lo_tell
+---------
+(0 rows)
+
+SELECT lo_lseek(fd, -156, 2) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT loread(fd, 35) FROM lotest_stash_values;
+ loread
+--------
+(0 rows)
+
+SELECT lo_close(fd) FROM lotest_stash_values;
+ lo_close
+----------
+(0 rows)
+
+END;
+-- Test resource management
+BEGIN;
+SELECT lo_open(loid, x'40000'::int) from lotest_stash_values;
+ lo_open
+---------
+(0 rows)
+
+ABORT;
+-- Test truncation.
+BEGIN;
+UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));
+SELECT lo_truncate(fd, 10) FROM lotest_stash_values;
+ lo_truncate
+-------------
+(0 rows)
+
+SELECT loread(fd, 15) FROM lotest_stash_values;
+ loread
+--------
+(0 rows)
+
+SELECT lo_truncate(fd, 10000) FROM lotest_stash_values;
+ lo_truncate
+-------------
+(0 rows)
+
+SELECT loread(fd, 10) FROM lotest_stash_values;
+ loread
+--------
+(0 rows)
+
+SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT lo_tell(fd) FROM lotest_stash_values;
+ lo_tell
+---------
+(0 rows)
+
+SELECT lo_truncate(fd, 5000) FROM lotest_stash_values;
+ lo_truncate
+-------------
+(0 rows)
+
+SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT lo_tell(fd) FROM lotest_stash_values;
+ lo_tell
+---------
+(0 rows)
+
+SELECT lo_close(fd) FROM lotest_stash_values;
+ lo_close
+----------
+(0 rows)
+
+END;
+-- lo_unlink(lobjId oid) returns integer
+-- return value appears to always be 1
+SELECT lo_unlink(loid) from lotest_stash_values;
+ lo_unlink
+-----------
+(0 rows)
+
+TRUNCATE lotest_stash_values;
+INSERT INTO lotest_stash_values (loid) VALUES( lo_import('@abs_srcdir@/data/tenk.data') );
+ERROR: Postgres-XC does not support large object yet
+DETAIL: The feature is not currently supported
+BEGIN;
+UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer));
+-- with the default BLKSZ, LOBLKSZ = 2048, so this positions us for a block
+-- edge case
+SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+-- this should get half of the value from page 0 and half from page 1 of the
+-- large object
+SELECT loread(fd, 36) FROM lotest_stash_values;
+ loread
+--------
+(0 rows)
+
+SELECT lo_tell(fd) FROM lotest_stash_values;
+ lo_tell
+---------
+(0 rows)
+
+SELECT lo_lseek(fd, -26, 1) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT lowrite(fd, 'abcdefghijklmnop') FROM lotest_stash_values;
+ lowrite
+---------
+(0 rows)
+
+SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values;
+ lo_lseek
+----------
+(0 rows)
+
+SELECT loread(fd, 36) FROM lotest_stash_values;
+ loread
+--------
+(0 rows)
+
+SELECT lo_close(fd) FROM lotest_stash_values;
+ lo_close
+----------
+(0 rows)
+
+END;
+SELECT lo_export(loid, '@abs_builddir@/results/lotest.txt') FROM lotest_stash_values;
+ lo_export
+-----------
+(0 rows)
+
+\lo_import '@abs_builddir@/results/lotest.txt'
+ERROR: Postgres-XC does not support large object yet
+DETAIL: The feature is not currently supported
+\set newloid :LASTOID
+-- just make sure \lo_export does not barf
+\lo_export :newloid '@abs_builddir@/results/lotest2.txt'
+ERROR: Postgres-XC does not support large object yet
+DETAIL: The feature is not currently supported
+-- This is a hack to test that export/import are reversible
+-- This uses knowledge about the inner workings of large object mechanism
+-- which should not be used outside it. This makes it a HACK
+SELECT pageno, data FROM pg_largeobject WHERE loid = (SELECT loid from lotest_stash_values)
+EXCEPT
+SELECT pageno, data FROM pg_largeobject WHERE loid = :newloid;
+ pageno | data
+--------+------
+(0 rows)
+
+SELECT lo_unlink(loid) FROM lotest_stash_values;
+ lo_unlink
+-----------
+(0 rows)
+
+\lo_unlink :newloid
+ERROR: Postgres-XC does not support large object yet
+DETAIL: The feature is not currently supported
+TRUNCATE lotest_stash_values;