aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-10-07 00:58:23 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-10-07 00:58:23 +0000
commitfbd26d69846fcbfb69deee45bdddcc692dd59b07 (patch)
tree2aee8f89268d64645b1c4c96958a0e575a12e259 /src/backend/parser
parent4837270be9cbba925a7003de5980918c3de8fb37 (diff)
downloadpostgresql-fbd26d69846fcbfb69deee45bdddcc692dd59b07.tar.gz
postgresql-fbd26d69846fcbfb69deee45bdddcc692dd59b07.zip
Arrange that no database accesses are attempted during parser() --- this
took some rejiggering of typename and ACL parsing, as well as moving parse_analyze call out of parser(). Restructure postgres.c processing so that parse analysis and rewrite are skipped when in abort-transaction state. Only COMMIT and ABORT statements will be processed beyond the raw parser() phase. This addresses problem of parser failing with database access errors while in aborted state (see pghackers discussions around 7/28/00). Also fix some bugs with COMMIT/ABORT statements appearing in the middle of a single query input string. Function, operator, and aggregate arguments/results can now use full TypeName production, in particular foo[] for array types. DROP OPERATOR and COMMENT ON OPERATOR were broken for unary operators. Allow CREATE AGGREGATE to accept unquoted numeric constants for initcond.
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/analyze.c91
-rw-r--r--src/backend/parser/gram.y95
-rw-r--r--src/backend/parser/parse_clause.c4
-rw-r--r--src/backend/parser/parse_expr.c56
-rw-r--r--src/backend/parser/parser.c127
5 files changed, 125 insertions, 248 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index ffedca05ed9..ae1f027e47c 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: analyze.c,v 1.160 2000/10/05 19:11:33 tgl Exp $
+ * $Id: analyze.c,v 1.161 2000/10/07 00:58:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -69,49 +69,45 @@ static List *extras_after;
/*
* parse_analyze -
- * analyze a list of parse trees and transform them if necessary.
- *
- * Returns a list of transformed parse trees. Optimizable statements are
- * all transformed to Query while the rest stays the same.
+ * analyze a raw parse tree and transform it to Query form.
*
+ * The result is a List of Query nodes (we need a list since some commands
+ * produce multiple Queries). Optimizable statements require considerable
+ * transformation, while many utility-type statements are simply hung off
+ * a dummy CMD_UTILITY Query node.
*/
List *
-parse_analyze(List *pl, ParseState *parentParseState)
+parse_analyze(Node *parseTree, ParseState *parentParseState)
{
List *result = NIL;
+ ParseState *pstate = make_parsestate(parentParseState);
+ Query *query;
- while (pl != NIL)
- {
- ParseState *pstate = make_parsestate(parentParseState);
- Query *parsetree;
+ extras_before = extras_after = NIL;
- extras_before = extras_after = NIL;
+ query = transformStmt(pstate, parseTree);
+ release_pstate_resources(pstate);
- parsetree = transformStmt(pstate, lfirst(pl));
+ while (extras_before != NIL)
+ {
+ result = lappend(result,
+ transformStmt(pstate, lfirst(extras_before)));
release_pstate_resources(pstate);
+ extras_before = lnext(extras_before);
+ }
- while (extras_before != NIL)
- {
- result = lappend(result,
- transformStmt(pstate, lfirst(extras_before)));
- release_pstate_resources(pstate);
- extras_before = lnext(extras_before);
- }
-
- result = lappend(result, parsetree);
+ result = lappend(result, query);
- while (extras_after != NIL)
- {
- result = lappend(result,
- transformStmt(pstate, lfirst(extras_after)));
- release_pstate_resources(pstate);
- extras_after = lnext(extras_after);
- }
-
- pfree(pstate);
- pl = lnext(pl);
+ while (extras_after != NIL)
+ {
+ result = lappend(result,
+ transformStmt(pstate, lfirst(extras_after)));
+ release_pstate_resources(pstate);
+ extras_after = lnext(extras_after);
}
+ pfree(pstate);
+
return result;
}
@@ -126,8 +122,7 @@ release_pstate_resources(ParseState *pstate)
/*
* transformStmt -
- * transform a Parse tree. If it is an optimizable statement, turn it
- * into a Query tree.
+ * transform a Parse tree into a Query tree.
*/
static Query *
transformStmt(ParseState *pstate, Node *parseTree)
@@ -353,7 +348,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
* from a stand-alone SELECT. (Indeed, Postgres up through 6.5 had
* bugs of just that nature...)
*/
- selectList = parse_analyze(makeList1(stmt->selectStmt), pstate);
+ selectList = parse_analyze(stmt->selectStmt, pstate);
Assert(length(selectList) == 1);
selectQuery = (Query *) lfirst(selectList);
@@ -1933,7 +1928,7 @@ transformSetOperationTree(ParseState *pstate, Node *node)
*/
save_rtable = pstate->p_rtable;
pstate->p_rtable = NIL;
- selectList = parse_analyze(makeList1(stmt), pstate);
+ selectList = parse_analyze((Node *) stmt, pstate);
pstate->p_rtable = save_rtable;
Assert(length(selectList) == 1);
@@ -2752,6 +2747,7 @@ makeFromExpr(List *fromlist, Node *quals)
static void
transformColumnType(ParseState *pstate, ColumnDef *column)
{
+ TypeName *typename = column->typename;
/*
* If the column doesn't have an explicitly specified typmod, check to
@@ -2760,18 +2756,33 @@ transformColumnType(ParseState *pstate, ColumnDef *column)
* Note that we deliberately do NOT look at array or set information
* here; "numeric[]" needs the same default typmod as "numeric".
*/
- if (column->typename->typmod == -1)
+ if (typename->typmod == -1)
{
- switch (typeTypeId(typenameType(column->typename->name)))
+ switch (typeTypeId(typenameType(typename->name)))
{
- case BPCHAROID:
+ case BPCHAROID:
/* "char" -> "char(1)" */
- column->typename->typmod = VARHDRSZ + 1;
+ typename->typmod = VARHDRSZ + 1;
break;
case NUMERICOID:
- column->typename->typmod = VARHDRSZ +
+ typename->typmod = VARHDRSZ +
((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE);
break;
}
}
+
+ /*
+ * Is this the name of a complex type? If so, implement
+ * it as a set.
+ *
+ * XXX this is a hangover from ancient Berkeley code that probably
+ * doesn't work anymore anyway.
+ */
+ if (typeTypeRelid(typenameType(typename->name)) != InvalidOid)
+ {
+ /* (Eventually add in here that the set can only
+ * contain one element.)
+ */
+ typename->setof = true;
+ }
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index f13b942abd8..a596bd6aba1 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.194 2000/10/05 19:11:33 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.195 2000/10/07 00:58:17 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -59,7 +59,6 @@
extern List *parsetree; /* final parse result is delivered here */
-static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
static bool QueryIsRule = FALSE;
static Oid *param_type_info;
static int pfunc_num_args;
@@ -161,7 +160,7 @@ static void doNegateFloat(Value *v);
%type <str> relation_name, copy_file_name, copy_delimiter, copy_null, def_name,
database_name, access_method_clause, access_method, attr_name,
- class, index_name, name, func_name, file_name, aggr_argtype
+ class, index_name, name, func_name, file_name
%type <str> opt_id,
all_Op, MathOp, opt_name,
@@ -183,7 +182,7 @@ static void doNegateFloat(Value *v);
def_list, opt_indirection, group_clause, TriggerFuncArgs,
opt_select_limit
-%type <typnam> func_arg, func_return
+%type <typnam> func_arg, func_return, aggr_argtype
%type <boolean> opt_arg, TriggerForOpt, TriggerForType, OptTemp
@@ -1541,7 +1540,7 @@ CreateAsStmt: CREATE OptTemp TABLE relation_name OptUnder OptCreateAs AS Select
n->istemp = $2;
n->into = $4;
if ($5 != NIL)
- yyerror("CREATE TABLE/AS SELECT does not support UNDER");
+ elog(ERROR,"CREATE TABLE/AS SELECT does not support UNDER");
if ($6 != NIL)
mapTargetColumns($6, n->targetList);
$$ = $8;
@@ -2009,8 +2008,8 @@ CommentStmt: COMMENT ON comment_type name IS comment_text
CommentStmt *n = makeNode(CommentStmt);
n->objtype = $3;
n->objname = $4;
- n->objproperty = $5;
- n->objlist = NULL;
+ n->objproperty = NULL;
+ n->objlist = makeList1($5);
n->comment = $7;
$$ = (Node *) n;
}
@@ -2309,7 +2308,7 @@ grantee: PUBLIC
opt_with_grant: WITH GRANT OPTION
{
- yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
+ elog(ERROR,"WITH GRANT OPTION is not supported. Only relation owners can set privileges");
}
| /*EMPTY*/
;
@@ -2471,7 +2470,7 @@ ProcedureStmt: CREATE FUNCTION func_name func_args
{
ProcedureStmt *n = makeNode(ProcedureStmt);
n->funcname = $3;
- n->defArgs = $4;
+ n->argTypes = $4;
n->returnType = (Node *)$6;
n->withClause = $11;
n->as = $8;
@@ -2488,29 +2487,12 @@ func_args: '(' func_args_list ')' { $$ = $2; }
;
func_args_list: func_arg
- { $$ = makeList1(makeString($1->name)); }
+ { $$ = makeList1($1); }
| func_args_list ',' func_arg
- { $$ = lappend($1, makeString($3->name)); }
+ { $$ = lappend($1, $3); }
;
-/* Would be nice to use the full Typename production for these fields,
- * but that one sometimes dives into the catalogs looking for valid types.
- * Arguments like "opaque" are valid when defining functions,
- * so that won't work here. The only thing we give up is array notation,
- * which isn't meaningful in this context anyway.
- * - thomas 2000-03-25
- * The following productions are difficult, since it is difficult to
- * distinguish between TokenId and SimpleTypename:
- opt_arg TokenId SimpleTypename
- {
- $$ = $3;
- }
- | TokenId SimpleTypename
- {
- $$ = $2;
- }
- */
-func_arg: opt_arg SimpleTypename
+func_arg: opt_arg Typename
{
/* We can catch over-specified arguments here if we want to,
* but for now better to silently swallow typmod, etc.
@@ -2518,7 +2500,7 @@ func_arg: opt_arg SimpleTypename
*/
$$ = $2;
}
- | SimpleTypename
+ | Typename
{
$$ = $1;
}
@@ -2546,7 +2528,7 @@ func_as: Sconst
{ $$ = makeList2(makeString($1), makeString($3)); }
;
-func_return: SimpleTypename
+func_return: Typename
{
/* We can catch over-specified arguments here if we want to,
* but for now better to silently swallow typmod, etc.
@@ -2554,11 +2536,6 @@ func_return: SimpleTypename
*/
$$ = $1;
}
- | SETOF SimpleTypename
- {
- $$ = $2;
- $$->setof = TRUE;
- }
;
@@ -2599,12 +2576,12 @@ RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
{
RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
n->aggname = $3;
- n->aggtype = $4;
+ n->aggtype = (Node *) $4;
$$ = (Node *)n;
}
;
-aggr_argtype: name { $$ = $1; }
+aggr_argtype: Typename { $$ = $1; }
| '*' { $$ = NULL; }
;
@@ -2628,16 +2605,16 @@ RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
}
;
-oper_argtypes: name
+oper_argtypes: Typename
{
elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
}
- | name ',' name
- { $$ = makeList2(makeString($1), makeString($3)); }
- | NONE ',' name /* left unary */
- { $$ = makeList2(NULL, makeString($3)); }
- | name ',' NONE /* right unary */
- { $$ = makeList2(makeString($1), NULL); }
+ | Typename ',' Typename
+ { $$ = makeList2($1, $3); }
+ | NONE ',' Typename /* left unary */
+ { $$ = makeList2(NULL, $3); }
+ | Typename ',' NONE /* right unary */
+ { $$ = makeList2($1, NULL); }
;
@@ -3832,23 +3809,6 @@ Typename: SimpleTypename opt_array_bounds
{
$$ = $1;
$$->arrayBounds = $2;
-
- /* Is this the name of a complex type? If so, implement
- * it as a set.
- */
- if (strcmp(saved_relname, $$->name) == 0)
- /* This attr is the same type as the relation
- * being defined. The classic example: create
- * emp(name=text,mgr=emp)
- */
- $$->setof = TRUE;
- else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
- /* (Eventually add in here that the set can only
- * contain one element.)
- */
- $$->setof = TRUE;
- else
- $$->setof = FALSE;
}
| SETOF SimpleTypename
{
@@ -3909,7 +3869,7 @@ Numeric: FLOAT opt_float
| DECIMAL opt_decimal
{
$$ = makeNode(TypeName);
- $$->name = xlateSqlType("numeric");
+ $$->name = xlateSqlType("decimal");
$$->typmod = $2;
}
| DEC opt_decimal
@@ -5245,17 +5205,15 @@ update_target_el: ColId opt_indirection '=' a_expr
relation_name: SpecialRuleRelation
{
$$ = $1;
- StrNCpy(saved_relname, $1, NAMEDATALEN);
}
| ColId
{
/* disallow refs to variable system tables */
if (strcmp(LogRelationName, $1) == 0
- || strcmp(VariableRelationName, $1) == 0)
+ || strcmp(VariableRelationName, $1) == 0)
elog(ERROR,"%s cannot be accessed by users",$1);
else
$$ = $1;
- StrNCpy(saved_relname, $1, NAMEDATALEN);
}
;
@@ -5298,7 +5256,7 @@ AexprConst: Iconst
n->val.val.str = $1;
$$ = (Node *)n;
}
- /* The SimpleTypename rule formerly used Typename,
+ /* This rule formerly used Typename,
* but that causes reduce conflicts with subscripted column names.
* Now, separate into ConstTypename and ConstInterval,
* to allow implementing the SQL92 syntax for INTERVAL literals.
@@ -5383,6 +5341,7 @@ ColId: generic { $$ = $1; }
| TokenId { $$ = $1; }
| INTERVAL { $$ = "interval"; }
| NATIONAL { $$ = "national"; }
+ | NONE { $$ = "none"; }
| PATH_P { $$ = "path"; }
| SERIAL { $$ = "serial"; }
| TIME { $$ = "time"; }
@@ -5595,7 +5554,6 @@ ColLabel: ColId { $$ = $1; }
| NATURAL { $$ = "natural"; }
| NCHAR { $$ = "nchar"; }
| NEW { $$ = "new"; }
- | NONE { $$ = "none"; }
| NOT { $$ = "not"; }
| NOTNULL { $$ = "notnull"; }
| NULLIF { $$ = "nullif"; }
@@ -5851,7 +5809,6 @@ xlateSqlType(char *name)
void parser_init(Oid *typev, int nargs)
{
- saved_relname[0] = '\0';
QueryIsRule = FALSE;
/*
* Keep enough information around to fill out the type of param nodes
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 20233ed1950..38dc3ea0976 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.69 2000/10/05 19:11:33 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.70 2000/10/07 00:58:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -375,7 +375,7 @@ transformRangeSubselect(ParseState *pstate, RangeSubselect *r)
save_joinlist = pstate->p_joinlist;
pstate->p_rtable = NIL;
pstate->p_joinlist = NIL;
- parsetrees = parse_analyze(makeList1(r->subquery), pstate);
+ parsetrees = parse_analyze(r->subquery, pstate);
pstate->p_rtable = save_rtable;
pstate->p_joinlist = save_joinlist;
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 7b647124d1f..94ccaa5f69f 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.85 2000/10/05 19:11:33 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.86 2000/10/07 00:58:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -294,8 +294,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
break;
}
pstate->p_hasSubLinks = true;
- qtrees = parse_analyze(makeList1(sublink->subselect),
- pstate);
+ qtrees = parse_analyze(sublink->subselect, pstate);
if (length(qtrees) != 1)
elog(ERROR, "Bad query in subselect");
qtree = (Query *) lfirst(qtrees);
@@ -821,19 +820,21 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
static Node *
parser_typecast_constant(Value *expr, TypeName *typename)
{
- Const *con;
Type tp;
Datum datum;
+ Const *con;
char *const_string = NULL;
bool string_palloced = false;
bool isNull = false;
+ tp = typenameType(TypeNameToInternalName(typename));
+
switch (nodeTag(expr))
{
case T_Integer:
- string_palloced = true;
const_string = DatumGetCString(DirectFunctionCall1(int4out,
Int32GetDatum(expr->val.ival)));
+ string_palloced = true;
break;
case T_Float:
case T_String:
@@ -844,19 +845,9 @@ parser_typecast_constant(Value *expr, TypeName *typename)
break;
default:
elog(ERROR, "Cannot cast this expression to type '%s'",
- typename->name);
+ typeTypeName(tp));
}
- if (typename->arrayBounds != NIL)
- {
- char type_string[NAMEDATALEN + 2];
-
- sprintf(type_string, "_%s", typename->name);
- tp = (Type) typenameType(type_string);
- }
- else
- tp = (Type) typenameType(typename->name);
-
if (isNull)
datum = (Datum) NULL;
else
@@ -892,15 +883,7 @@ parser_typecast_expression(ParseState *pstate,
Type tp;
Oid targetType;
- if (typename->arrayBounds != NIL)
- {
- char type_string[NAMEDATALEN + 2];
-
- sprintf(type_string, "_%s", typename->name);
- tp = (Type) typenameType(type_string);
- }
- else
- tp = (Type) typenameType(typename->name);
+ tp = typenameType(TypeNameToInternalName(typename));
targetType = typeTypeId(tp);
if (inputType == InvalidOid)
@@ -925,3 +908,26 @@ parser_typecast_expression(ParseState *pstate,
return expr;
}
+
+/*
+ * Given a TypeName node as returned by the grammar, generate the internal
+ * name of the corresponding type. Note this does NOT check if the type
+ * exists or not.
+ */
+char *
+TypeNameToInternalName(TypeName *typename)
+{
+ if (typename->arrayBounds != NIL)
+ {
+ /*
+ * By convention, the name of an array type is the name of its
+ * element type with "_" prepended.
+ */
+ char *arrayname = palloc(strlen(typename->name) + 2);
+
+ sprintf(arrayname, "_%s", typename->name);
+ return arrayname;
+ }
+ else
+ return typename->name;
+}
diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c
index 4a6c825498a..84b27549d36 100644
--- a/src/backend/parser/parser.c
+++ b/src/backend/parser/parser.c
@@ -1,14 +1,20 @@
/*-------------------------------------------------------------------------
*
* parser.c
- * Main entry point/driver for PostgreSQL parser
+ * Main entry point/driver for PostgreSQL grammar
+ *
+ * Note that the grammar is not allowed to perform any table access
+ * (since we need to be able to do basic parsing even while inside an
+ * aborted transaction). Therefore, the data structures returned by
+ * the grammar are "raw" parsetrees that still need to be analyzed by
+ * parse_analyze.
*
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.46 2000/09/12 21:07:02 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.47 2000/10/07 00:58:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,8 +22,6 @@
#include "postgres.h"
#include "nodes/parsenodes.h"
-#include "nodes/pg_list.h"
-#include "parser/analyze.h"
#include "parser/gramparse.h"
#include "parser/parse.h"
#include "parser/parser.h"
@@ -35,19 +39,17 @@ List *parsetree; /* result of parsing is left here */
static int lookahead_token; /* one-token lookahead */
static bool have_lookahead; /* lookahead_token set? */
-#ifdef SETS_FIXED
-static void fixupsets();
-static void define_sets();
-
-#endif
/*
- * parser-- returns a list of parse trees
+ * parser
+ * Given a query in string form, and optionally info about
+ * parameter types, do lexical and syntactic analysis.
+ *
+ * Returns a list of raw (un-analyzed) parse trees.
*/
List *
parser(char *str, Oid *typev, int nargs)
{
- List *queryList;
int yyresult;
parseString = str;
@@ -67,28 +69,9 @@ parser(char *str, Oid *typev, int nargs)
clearerr(stdin);
if (yyresult) /* error */
- return (List *) NULL;
-
- queryList = parse_analyze(parsetree, NULL);
+ return NIL;
-#ifdef SETS_FIXED
-
- /*
- * Fixing up sets calls the parser, so it reassigns the global
- * variable parsetree. So save the real parsetree.
- */
- savetree = parsetree;
- foreach(parse, savetree)
- { /* savetree is really a list of parses */
-
- /* find set definitions embedded in query */
- fixupsets((Query *) lfirst(parse));
-
- }
- return savetree;
-#endif
-
- return queryList;
+ return parsetree;
}
@@ -135,83 +118,3 @@ yylex(void)
return cur_token;
}
-
-
-#ifdef SETS_FIXED
-static void
-fixupsets(Query *parse)
-{
- if (parse == NULL)
- return;
- if (parse->commandType == CMD_UTILITY) /* utility */
- return;
- if (parse->commandType != CMD_INSERT)
- return;
- define_sets(parse);
-}
-
-/* Recursively find all of the Consts in the parsetree. Some of
- * these may represent a set. The value of the Const will be the
- * query (a string) which defines the set. Call SetDefine to define
- * the set, and store the OID of the new set in the Const instead.
- */
-static void
-define_sets(Node *clause)
-{
- Oid setoid;
- Type t = typeidType(OIDOID);
- Oid typeoid = typeTypeId(t);
- Size oidsize = typeLen(t);
- bool oidbyval = typeByVal(t);
-
- if (clause == NULL)
- return;
- else if (IsA(clause, LispList))
- {
- define_sets(lfirst(clause));
- define_sets(lnext(clause));
- }
- else if (IsA(clause, Const))
- {
- if (get_constisnull((Const) clause) ||
- !get_constisset((Const) clause))
- return;
- setoid = SetDefine(((Const *) clause)->constvalue,
- typeidTypeName(((Const *) clause)->consttype));
- set_constvalue((Const) clause, setoid);
- set_consttype((Const) clause, typeoid);
- set_constlen((Const) clause, oidsize);
- set_constypeByVal((Const) clause, oidbyval);
- }
- else if (IsA(clause, Iter))
- define_sets(((Iter *) clause)->iterexpr);
- else if (single_node(clause))
- return;
- else if (or_clause(clause) || and_clause(clause))
- {
- List *temp;
-
- /* mapcan */
- foreach(temp, ((Expr *) clause)->args)
- define_sets(lfirst(temp));
- }
- else if (is_funcclause(clause))
- {
- List *temp;
-
- /* mapcan */
- foreach(temp, ((Expr *) clause)->args)
- define_sets(lfirst(temp));
- }
- else if (IsA(clause, ArrayRef))
- define_sets(((ArrayRef *) clause)->refassgnexpr);
- else if (not_clause(clause))
- define_sets(get_notclausearg(clause));
- else if (is_opclause(clause))
- {
- define_sets(get_leftop(clause));
- define_sets(get_rightop(clause));
- }
-}
-
-#endif