aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/analyze.c4
-rw-r--r--src/backend/parser/gram.y10
-rw-r--r--src/backend/parser/keywords.c3
-rw-r--r--src/backend/parser/parse_clause.c12
-rw-r--r--src/backend/parser/parse_coerce.c56
-rw-r--r--src/backend/parser/parse_expr.c57
-rw-r--r--src/backend/parser/parse_node.c6
-rw-r--r--src/backend/parser/parse_target.c4
8 files changed, 110 insertions, 42 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 30c8e8f15b9..18144f7b941 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.253 2002/10/21 22:06:19 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.254 2002/11/15 02:50:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2401,7 +2401,7 @@ transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt)
Oid expected_type_id,
given_type_id;
- expr = transformExpr(pstate, expr);
+ expr = transformExpr(pstate, expr, NULL);
/* Cannot contain subselects or aggregates */
if (contain_subplans(expr))
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 724424220b6..b3ca71013c9 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.377 2002/11/13 00:44:08 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.378 2002/11/15 02:50:08 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -393,7 +393,7 @@ static void doNegateFloat(Value *v);
UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
UPDATE USAGE USER USING
- VACUUM VALID VALIDATOR VALUES VARCHAR VARYING
+ VACUUM VALID VALIDATOR VALUE VALUES VARCHAR VARYING
VERBOSE VERSION VIEW VOLATILE
WHEN WHERE WITH WITHOUT WORK WRITE
@@ -6406,6 +6406,11 @@ c_expr: columnref { $$ = (Node *) $1; }
n->subselect = $2;
$$ = (Node *)n;
}
+ | VALUE
+ {
+ DomainConstraintValue *n = makeNode(DomainConstraintValue);
+ $$ = (Node *)n;
+ }
;
/*
@@ -7315,6 +7320,7 @@ reserved_keyword:
| UNIQUE
| USER
| USING
+ | VALUE
| WHEN
| WHERE
;
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index b86ffa522e4..de8a6e09b1a 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.130 2002/11/13 00:44:09 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.131 2002/11/15 02:50:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -314,6 +314,7 @@ static const ScanKeyword ScanKeywords[] = {
{"vacuum", VACUUM},
{"valid", VALID},
{"validator", VALIDATOR},
+ {"value", VALUE},
{"values", VALUES},
{"varchar", VARCHAR},
{"varying", VARYING},
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 245c0ba422b..d9638753746 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.98 2002/09/18 21:35:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.99 2002/11/15 02:50:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -283,7 +283,7 @@ transformJoinUsingClause(ParseState *pstate, List *leftVars, List *rightVars)
* transformJoinOnClause() does. Just invoke transformExpr() to fix
* up the operators, and we're done.
*/
- result = transformExpr(pstate, result);
+ result = transformExpr(pstate, result, NULL);
result = coerce_to_boolean(result, "JOIN/USING");
@@ -317,7 +317,7 @@ transformJoinOnClause(ParseState *pstate, JoinExpr *j,
pstate->p_namespace = makeList2(j->larg, j->rarg);
/* This part is just like transformWhereClause() */
- result = transformExpr(pstate, j->quals);
+ result = transformExpr(pstate, j->quals, NULL);
result = coerce_to_boolean(result, "JOIN/ON");
@@ -478,7 +478,7 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r)
save_namespace = pstate->p_namespace;
pstate->p_namespace = NIL;
- funcexpr = transformExpr(pstate, r->funccallnode);
+ funcexpr = transformExpr(pstate, r->funccallnode, NULL);
pstate->p_namespace = save_namespace;
@@ -961,7 +961,7 @@ transformWhereClause(ParseState *pstate, Node *clause)
if (clause == NULL)
return NULL;
- qual = transformExpr(pstate, clause);
+ qual = transformExpr(pstate, clause, NULL);
qual = coerce_to_boolean(qual, "WHERE");
@@ -1104,7 +1104,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
* willing to match a resjunk target here, though the above cases must
* ignore resjunk targets.
*/
- expr = transformExpr(pstate, node);
+ expr = transformExpr(pstate, node, NULL);
foreach(tl, tlist)
{
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 4870b24de07..a24af2de3e1 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -8,13 +8,18 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.85 2002/10/24 22:09:00 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.86 2002/11/15 02:50:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+#include "access/genam.h"
+#include "access/heapam.h"
+#include "catalog/catname.h"
+#include "catalog/indexing.h"
#include "catalog/pg_cast.h"
+#include "catalog/pg_constraint.h"
#include "catalog/pg_proc.h"
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
@@ -405,8 +410,14 @@ coerce_type_constraints(Node *arg, Oid typeId, CoercionForm cformat)
for (;;)
{
HeapTuple tup;
+ HeapTuple conTup;
Form_pg_type typTup;
+ ScanKeyData key[1];
+ int nkeys = 0;
+ SysScanDesc scan;
+ Relation conRel;
+
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typeId),
0, 0, 0);
@@ -419,7 +430,45 @@ coerce_type_constraints(Node *arg, Oid typeId, CoercionForm cformat)
if (typTup->typnotnull && notNull == NULL)
notNull = pstrdup(NameStr(typTup->typname));
- /* TODO: Add CHECK Constraints to domains */
+ /* Add CHECK Constraints to domains */
+ conRel = heap_openr(ConstraintRelationName, RowShareLock);
+
+ ScanKeyEntryInitialize(&key[nkeys++], 0x0,
+ Anum_pg_constraint_contypid, F_OIDEQ,
+ ObjectIdGetDatum(typeId));
+
+ scan = systable_beginscan(conRel, ConstraintTypidIndex, true,
+ SnapshotNow, nkeys, key);
+
+ while (HeapTupleIsValid(conTup = systable_getnext(scan)))
+ {
+ Datum val;
+ bool isNull;
+ ConstraintTest *r = makeNode(ConstraintTest);
+ Form_pg_constraint c = (Form_pg_constraint) GETSTRUCT(conTup);
+
+ /* Not expecting conbin to be NULL, but we'll test for it anyway */
+ val = fastgetattr(conTup,
+ Anum_pg_constraint_conbin,
+ conRel->rd_att, &isNull);
+
+ if (isNull)
+ elog(ERROR, "coerce_type_constraints: domain %s constraint %s has NULL conbin",
+ NameStr(typTup->typname), NameStr(c->conname));
+
+ r->arg = arg;
+ r->testtype = CONSTR_TEST_CHECK;
+ r->name = NameStr(c->conname);
+ r->domname = NameStr(typTup->typname);
+ r->check_expr = stringToNode(MemoryContextStrdup(CacheMemoryContext,
+ DatumGetCString(DirectFunctionCall1(textout,
+ val))));
+
+ arg = (Node *) r;
+ }
+
+ systable_endscan(scan);
+ heap_close(conRel, RowShareLock);
if (typTup->typtype != 'd')
{
@@ -452,7 +501,8 @@ coerce_type_constraints(Node *arg, Oid typeId, CoercionForm cformat)
r->arg = arg;
r->testtype = CONSTR_TEST_NOTNULL;
- r->name = notNull;
+ r->name = "NOT NULL";
+ r->domname = notNull;
r->check_expr = NULL;
arg = (Node *) r;
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 3873fd37f0d..9a4a9c8bc91 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.129 2002/09/18 21:35:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.130 2002/11/15 02:50:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,6 +20,7 @@
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/params.h"
+#include "optimizer/clauses.h"
#include "parser/analyze.h"
#include "parser/gramparse.h"
#include "parser/parse.h"
@@ -83,7 +84,7 @@ parse_expr_init(void)
* input and output of transformExpr; see SubLink for example.
*/
Node *
-transformExpr(ParseState *pstate, Node *expr)
+transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
{
Node *result = NULL;
@@ -152,7 +153,7 @@ transformExpr(ParseState *pstate, Node *expr)
ExprFieldSelect *efs = (ExprFieldSelect *) expr;
List *fields;
- result = transformExpr(pstate, efs->arg);
+ result = transformExpr(pstate, efs->arg, domVal);
/* handle qualification, if any */
foreach(fields, efs->fields)
{
@@ -169,7 +170,7 @@ transformExpr(ParseState *pstate, Node *expr)
case T_TypeCast:
{
TypeCast *tc = (TypeCast *) expr;
- Node *arg = transformExpr(pstate, tc->arg);
+ Node *arg = transformExpr(pstate, tc->arg, domVal);
result = typecast_expression(arg, tc->typename);
break;
@@ -204,14 +205,14 @@ transformExpr(ParseState *pstate, Node *expr)
n->arg = a->lexpr;
result = transformExpr(pstate,
- (Node *) n);
+ (Node *) n, domVal);
}
else
{
Node *lexpr = transformExpr(pstate,
- a->lexpr);
+ a->lexpr, domVal);
Node *rexpr = transformExpr(pstate,
- a->rexpr);
+ a->rexpr, domVal);
result = (Node *) make_op(a->name,
lexpr,
@@ -222,9 +223,9 @@ transformExpr(ParseState *pstate, Node *expr)
case AND:
{
Node *lexpr = transformExpr(pstate,
- a->lexpr);
+ a->lexpr, domVal);
Node *rexpr = transformExpr(pstate,
- a->rexpr);
+ a->rexpr, domVal);
Expr *expr = makeNode(Expr);
lexpr = coerce_to_boolean(lexpr, "AND");
@@ -239,9 +240,9 @@ transformExpr(ParseState *pstate, Node *expr)
case OR:
{
Node *lexpr = transformExpr(pstate,
- a->lexpr);
+ a->lexpr, domVal);
Node *rexpr = transformExpr(pstate,
- a->rexpr);
+ a->rexpr, domVal);
Expr *expr = makeNode(Expr);
lexpr = coerce_to_boolean(lexpr, "OR");
@@ -256,7 +257,7 @@ transformExpr(ParseState *pstate, Node *expr)
case NOT:
{
Node *rexpr = transformExpr(pstate,
- a->rexpr);
+ a->rexpr, domVal);
Expr *expr = makeNode(Expr);
rexpr = coerce_to_boolean(rexpr, "NOT");
@@ -270,9 +271,9 @@ transformExpr(ParseState *pstate, Node *expr)
case DISTINCT:
{
Node *lexpr = transformExpr(pstate,
- a->lexpr);
+ a->lexpr, domVal);
Node *rexpr = transformExpr(pstate,
- a->rexpr);
+ a->rexpr, domVal);
result = (Node *) make_op(a->name,
lexpr,
@@ -293,7 +294,7 @@ transformExpr(ParseState *pstate, Node *expr)
* Will result in a boolean constant node.
*/
Node *lexpr = transformExpr(pstate,
- a->lexpr);
+ a->lexpr, domVal);
ltype = exprType(lexpr);
foreach(telem, (List *) a->rexpr)
@@ -317,7 +318,7 @@ transformExpr(ParseState *pstate, Node *expr)
n->val.val.str = (matched ? "t" : "f");
n->typename = SystemTypeName("bool");
- result = transformExpr(pstate, (Node *) n);
+ result = transformExpr(pstate, (Node *) n, domVal);
}
break;
}
@@ -331,7 +332,7 @@ transformExpr(ParseState *pstate, Node *expr)
/* transform the list of arguments */
foreach(args, fn->args)
lfirst(args) = transformExpr(pstate,
- (Node *) lfirst(args));
+ (Node *) lfirst(args), domVal);
result = ParseFuncOrColumn(pstate,
fn->funcname,
fn->args,
@@ -405,7 +406,7 @@ transformExpr(ParseState *pstate, Node *expr)
List *elist;
foreach(elist, left_list)
- lfirst(elist) = transformExpr(pstate, lfirst(elist));
+ lfirst(elist) = transformExpr(pstate, lfirst(elist), domVal);
Assert(IsA(sublink->oper, A_Expr));
op = ((A_Expr *) sublink->oper)->name;
@@ -504,7 +505,7 @@ transformExpr(ParseState *pstate, Node *expr)
warg = (Node *) makeSimpleA_Expr(OP, "=",
c->arg, warg);
}
- neww->expr = transformExpr(pstate, warg);
+ neww->expr = transformExpr(pstate, warg, domVal);
neww->expr = coerce_to_boolean(neww->expr, "CASE/WHEN");
@@ -520,7 +521,7 @@ transformExpr(ParseState *pstate, Node *expr)
n->val.type = T_Null;
warg = (Node *) n;
}
- neww->result = transformExpr(pstate, warg);
+ neww->result = transformExpr(pstate, warg, domVal);
newargs = lappend(newargs, neww);
typeids = lappendi(typeids, exprType(neww->result));
@@ -544,7 +545,7 @@ transformExpr(ParseState *pstate, Node *expr)
n->val.type = T_Null;
defresult = (Node *) n;
}
- newc->defresult = transformExpr(pstate, defresult);
+ newc->defresult = transformExpr(pstate, defresult, domVal);
/*
* Note: default result is considered the most significant
@@ -580,7 +581,7 @@ transformExpr(ParseState *pstate, Node *expr)
{
NullTest *n = (NullTest *) expr;
- n->arg = transformExpr(pstate, n->arg);
+ n->arg = transformExpr(pstate, n->arg, domVal);
/* the argument can be any type, so don't coerce it */
result = expr;
break;
@@ -617,7 +618,7 @@ transformExpr(ParseState *pstate, Node *expr)
clausename = NULL; /* keep compiler quiet */
}
- b->arg = transformExpr(pstate, b->arg);
+ b->arg = transformExpr(pstate, b->arg, domVal);
b->arg = coerce_to_boolean(b->arg, clausename);
@@ -625,6 +626,13 @@ transformExpr(ParseState *pstate, Node *expr)
break;
}
+ case T_DomainConstraintValue:
+ {
+ result = (Node *) copyObject(domVal);
+
+ break;
+ }
+
/*********************************************
* Quietly accept node types that may be presented when we are
* called on an already-transformed tree.
@@ -936,6 +944,9 @@ exprType(Node *expr)
case T_ConstraintTest:
type = exprType(((ConstraintTest *) expr)->arg);
break;
+ case T_ConstraintTestValue:
+ type = ((ConstraintTestValue *) expr)->typeId;
+ break;
default:
elog(ERROR, "exprType: Do not know how to get type for %d node",
nodeTag(expr));
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index f0bb1856ab3..608a67921c1 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.72 2002/11/13 00:39:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.73 2002/11/15 02:50:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -277,7 +277,7 @@ transformArraySubscripts(ParseState *pstate,
{
if (ai->lidx)
{
- subexpr = transformExpr(pstate, ai->lidx);
+ subexpr = transformExpr(pstate, ai->lidx, NULL);
/* If it's not int4 already, try to coerce */
subexpr = coerce_to_target_type(subexpr, exprType(subexpr),
INT4OID, -1,
@@ -299,7 +299,7 @@ transformArraySubscripts(ParseState *pstate,
}
lowerIndexpr = lappend(lowerIndexpr, subexpr);
}
- subexpr = transformExpr(pstate, ai->uidx);
+ subexpr = transformExpr(pstate, ai->uidx, NULL);
/* If it's not int4 already, try to coerce */
subexpr = coerce_to_target_type(subexpr, exprType(subexpr),
INT4OID, -1,
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index c03db4f8b4b..1a2da6da1eb 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.91 2002/09/28 20:00:19 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.92 2002/11/15 02:50:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -56,7 +56,7 @@ transformTargetEntry(ParseState *pstate,
/* Transform the node if caller didn't do it already */
if (expr == NULL)
- expr = transformExpr(pstate, node);
+ expr = transformExpr(pstate, node, NULL);
if (IsA(expr, RangeVar))
elog(ERROR, "You can't use relation names alone in the target list, try relation.*.");